load_test.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. //go:build integration
  2. // +build integration
  3. package integration
  4. import (
  5. "bytes"
  6. "fmt"
  7. "image/png"
  8. "os"
  9. "path"
  10. "path/filepath"
  11. "strings"
  12. "testing"
  13. "github.com/corona10/goimagehash"
  14. "github.com/imgproxy/imgproxy/v3/imagetype"
  15. "github.com/imgproxy/imgproxy/v3/vips"
  16. "github.com/stretchr/testify/assert"
  17. "github.com/stretchr/testify/require"
  18. )
  19. const (
  20. similarityThreshold = 5 // Distance between images to be considered similar
  21. )
  22. // testLoadFolder fetches images iterates over images in the specified folder,
  23. // runs imgproxy on each image, and compares the result with the reference image
  24. // which is expected to be in the `integration` folder with the same name
  25. // but with `.png` extension.
  26. func testLoadFolder(t *testing.T, cs, sourcePath, folder string) {
  27. t.Logf("Testing folder: %s", folder)
  28. walkPath := path.Join(sourcePath, folder)
  29. // Iterate over the files in the source folder
  30. err := filepath.Walk(walkPath, func(path string, info os.FileInfo, err error) error {
  31. require.NoError(t, err)
  32. // Skip directories
  33. if info.IsDir() {
  34. return nil
  35. }
  36. // get the base name of the file (8-bpp.png)
  37. basePath := filepath.Base(path)
  38. // Replace the extension with .png
  39. referencePath := strings.TrimSuffix(basePath, filepath.Ext(basePath)) + ".png"
  40. // Construct the full path to the reference image (integration/ folder)
  41. referencePath = filepath.Join(sourcePath, "integration", folder, referencePath)
  42. // Construct the source URL for imgproxy (no processing)
  43. sourceUrl := fmt.Sprintf("insecure/plain/local:///%s/%s@png", folder, basePath)
  44. imgproxyImageBytes := fetchImage(t, cs, sourceUrl)
  45. imgproxyImage, err := png.Decode(bytes.NewReader(imgproxyImageBytes))
  46. require.NoError(t, err, "Failed to decode PNG image from imgproxy for %s", basePath)
  47. referenceFile, err := os.Open(referencePath)
  48. require.NoError(t, err)
  49. defer referenceFile.Close()
  50. referenceImage, err := png.Decode(referenceFile)
  51. require.NoError(t, err, "Failed to decode PNG reference image for %s", referencePath)
  52. hash1, err := goimagehash.DifferenceHash(imgproxyImage)
  53. require.NoError(t, err)
  54. hash2, err := goimagehash.DifferenceHash(referenceImage)
  55. require.NoError(t, err)
  56. distance, err := hash1.Distance(hash2)
  57. require.NoError(t, err)
  58. assert.LessOrEqual(t, distance, similarityThreshold,
  59. "Image %s differs from reference image %s by %d, which is greater than the allowed threshold of %d",
  60. basePath, referencePath, distance, similarityThreshold)
  61. return nil
  62. })
  63. require.NoError(t, err)
  64. }
  65. // TestLoadSaveToPng ensures that our load pipeline works,
  66. // including standard and custom loaders. For each source image
  67. // in the folder, it does the passthrough request through imgproxy:
  68. // no processing, just convert format of the source file to png.
  69. // Then, it compares the result with the reference image.
  70. func TestLoadSaveToPng(t *testing.T) {
  71. ctx := t.Context()
  72. // TODO: Will be moved to test suite (like in processing_test.go)
  73. // Since we use SupportsLoad, we need to initialize vips
  74. defer vips.Shutdown() // either way it needs to be deinitialized
  75. err := vips.Init()
  76. require.NoError(t, err, "Failed to initialize vips")
  77. path, err := testImagesPath(t)
  78. require.NoError(t, err)
  79. cs := startImgproxy(t, ctx, path)
  80. if vips.SupportsLoad(imagetype.GIF) {
  81. testLoadFolder(t, cs, path, "gif")
  82. }
  83. if vips.SupportsLoad(imagetype.JPEG) {
  84. testLoadFolder(t, cs, path, "jpg")
  85. }
  86. if vips.SupportsLoad(imagetype.HEIC) {
  87. testLoadFolder(t, cs, path, "heif")
  88. }
  89. if vips.SupportsLoad(imagetype.JXL) {
  90. testLoadFolder(t, cs, path, "jxl")
  91. }
  92. if vips.SupportsLoad(imagetype.SVG) {
  93. testLoadFolder(t, cs, path, "svg")
  94. }
  95. if vips.SupportsLoad(imagetype.TIFF) {
  96. testLoadFolder(t, cs, path, "tiff")
  97. }
  98. if vips.SupportsLoad(imagetype.WEBP) {
  99. testLoadFolder(t, cs, path, "webp")
  100. }
  101. if vips.SupportsLoad(imagetype.BMP) {
  102. testLoadFolder(t, cs, path, "bmp")
  103. }
  104. if vips.SupportsLoad(imagetype.ICO) {
  105. testLoadFolder(t, cs, path, "ico")
  106. }
  107. }