Better RAM usage (#200)

* Manually close image for GC

* Remove config

* Handle error by os.Stat

* Add more test on fetchRemoteImage

* refine TestGenOptimizedAbsPath

* Bump version to 0.8.1
This commit is contained in:
Nova Kwok 2023-05-19 17:07:58 +08:00 committed by GitHub
parent 651ae512a3
commit e64ded7f47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 15 deletions

View File

@ -31,7 +31,7 @@ var (
prefetch, proxyMode bool
remoteRaw = "remote-raw"
config Config
version = "0.8.0"
version = "0.8.1"
)
const (

View File

@ -144,6 +144,7 @@ func avifEncoder(p1, p2 string, quality int, extraParams ExtraParams) error {
log.Error(err)
return err
}
img.Close()
convertLog("AVIF", p1, p2, quality)
return nil
@ -191,14 +192,24 @@ func webpEncoder(p1, p2 string, quality int, extraParams ExtraParams) error {
log.Error(err)
return err
}
img.Close()
convertLog("WebP", p1, p2, quality)
return nil
}
func convertLog(itype, p1 string, p2 string, quality int) {
oldf, _ := os.Stat(p1)
newf, _ := os.Stat(p2)
oldf, err := os.Stat(p1)
if err != nil {
log.Error(err)
return
}
newf, err := os.Stat(p2)
if err != nil {
log.Error(err)
return
}
log.Infof("%s@%d%%: %s->%s %d->%d %.2f%% deflated", itype, quality,
p1, p2, oldf.Size(), newf.Size(), float32(newf.Size())/float32(oldf.Size())*100)
}

View File

@ -1,6 +1,10 @@
package main
import (
"fmt"
"path"
"time"
log "github.com/sirupsen/logrus"
"github.com/valyala/fasthttp"
@ -8,7 +12,6 @@ import (
"os"
"path/filepath"
"sort"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@ -45,16 +48,71 @@ func TestImageExists(t *testing.T) {
}
func TestGenWebpAbs(t *testing.T) {
cwd, cooked := genOptimizedAbsPath("./pics/webp_server.png", "/tmp",
"test", "a", ExtraParams{Width: 0, Height: 0})
if !strings.Contains(cwd, "webp_server_go") {
t.Logf("Result: [%v], Expected: [%v]", cwd, "webp_server_go")
func TestGenOptimizedAbsPath(t *testing.T) {
// Create a temporary file for testing
tempFile, err := os.CreateTemp("", "test_image.*")
if err != nil {
t.Fatalf("Failed to create temporary file: %v", err)
}
var parts = strings.Split(cooked, ".")
defer os.Remove(tempFile.Name())
assert.Equalf(t, parts[0], "/tmp/test", "Result: [%v], Expected: [%v]", cooked, "/tmp/test.<ts>.webp")
assert.Equalf(t, parts[2], "webp", "Result: [%v], Expected: [%v]", cooked, "/tmp/test.<ts>.webp")
// Set the modification time for the temporary file
modTime := time.Now()
if err := os.Chtimes(tempFile.Name(), modTime, modTime); err != nil {
t.Fatalf("Failed to set modification time for the temporary file: %v", err)
}
rawImagePath := tempFile.Name()
exhaustPath := "/path/to/exhaust"
imageName := "tsuki.jpg"
reqURI := "/path/to/tsuki.jpg"
extraParams := ExtraParams{Width: 200, Height: 0}
// Test if config.EnableExtraParams is false
config.EnableExtraParams = false
avifAbsolutePath, webpAbsolutePath := genOptimizedAbsPath(rawImagePath, exhaustPath, imageName, reqURI, extraParams)
expectedAvifPath := path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.avif", imageName, modTime.Unix())))
expectedWebpPath := path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.webp", imageName, modTime.Unix())))
if avifAbsolutePath != expectedAvifPath {
t.Errorf("Avif absolute path is incorrect. Expected: %s, Got: %s", expectedAvifPath, avifAbsolutePath)
}
if webpAbsolutePath != expectedWebpPath {
t.Errorf("Webp absolute path is incorrect. Expected: %s, Got: %s", expectedWebpPath, webpAbsolutePath)
}
// Test if config.EnableExtraParams is true and extraParams is not 0
config.EnableExtraParams = true
avifAbsolutePath, webpAbsolutePath = genOptimizedAbsPath(rawImagePath, exhaustPath, imageName, reqURI, extraParams)
expectedAvifPath = path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.avif_width=%d&height=%d", imageName, modTime.Unix(), extraParams.Width, extraParams.Height)))
expectedWebpPath = path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.webp_width=%d&height=%d", imageName, modTime.Unix(), extraParams.Width, extraParams.Height)))
if avifAbsolutePath != expectedAvifPath {
t.Errorf("Avif absolute path is incorrect. Expected: %s, Got: %s", expectedAvifPath, avifAbsolutePath)
}
if webpAbsolutePath != expectedWebpPath {
t.Errorf("Webp absolute path is incorrect. Expected: %s, Got: %s", expectedWebpPath, webpAbsolutePath)
}
// Test if config.EnableExtraParams is true and extraParams is 0
config.EnableExtraParams = true
extraParams = ExtraParams{Width: 200, Height: 0}
avifAbsolutePath, webpAbsolutePath = genOptimizedAbsPath(rawImagePath, exhaustPath, imageName, reqURI, extraParams)
expectedAvifPath = path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.avif_width=%d&height=%d", imageName, modTime.Unix(), extraParams.Width, extraParams.Height)))
expectedWebpPath = path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.webp_width=%d&height=%d", imageName, modTime.Unix(), extraParams.Width, extraParams.Height)))
if avifAbsolutePath != expectedAvifPath {
t.Errorf("Avif absolute path is incorrect. Expected: %s, Got: %s", expectedAvifPath, avifAbsolutePath)
}
if webpAbsolutePath != expectedWebpPath {
t.Errorf("Webp absolute path is incorrect. Expected: %s, Got: %s", expectedWebpPath, webpAbsolutePath)
}
}
func TestGenEtag(t *testing.T) {
@ -142,19 +200,23 @@ func TestGetRemoteImageInfo(t *testing.T) {
func TestFetchRemoteImage(t *testing.T) {
// test the normal one
fp := filepath.Join("./exhaust", "test.ico")
url := "http://github.com/favicon.ico"
err := fetchRemoteImage(fp, url)
err := fetchRemoteImage(fp, "http://github.com/favicon.ico")
assert.Equal(t, err, nil)
data, _ := os.ReadFile(fp)
assert.Equal(t, "image/vnd.microsoft.icon", getFileContentType(data))
// test can't create file
err = fetchRemoteImage("/", url)
err = fetchRemoteImage("/", "http://github.com/favicon.ico")
assert.NotNil(t, err)
// test bad url
err = fetchRemoteImage(fp, "http://ahjdsgdsghja.cya")
assert.NotNil(t, err)
// test when returned is not image
err = fetchRemoteImage(fp, "https://github.com/")
assert.Equal(t, err.Error(), "remote file https://github.com/ is not image, remote returned text/html; charset=utf-8")
}
func TestCleanProxyCache(t *testing.T) {