load_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package integration
  2. import (
  3. "fmt"
  4. "net/http"
  5. "os"
  6. "path"
  7. "path/filepath"
  8. "testing"
  9. "github.com/imgproxy/imgproxy/v3/imagetype"
  10. "github.com/imgproxy/imgproxy/v3/testutil"
  11. "github.com/imgproxy/imgproxy/v3/vips"
  12. "github.com/stretchr/testify/suite"
  13. )
  14. const (
  15. maxDistance = 0 // maximum image distance
  16. )
  17. type LoadTestSuite struct {
  18. Suite
  19. matcher *testutil.ImageHashMatcher
  20. testImagesPath string
  21. saveTmpImagesPath string
  22. }
  23. func (s *LoadTestSuite) SetupTest() {
  24. s.testImagesPath = s.TestData.Path("test-images")
  25. s.saveTmpImagesPath = os.Getenv("TEST_SAVE_TMP_IMAGES")
  26. s.matcher = testutil.NewImageHashMatcher(s.TestData)
  27. s.Config().Security.DefaultOptions.MaxAnimationFrames = 999
  28. s.Config().Server.DevelopmentErrorsMode = true
  29. s.Config().Fetcher.Transport.Local.Root = s.testImagesPath
  30. }
  31. // testLoadFolder fetches images iterates over images in the specified folder,
  32. // runs imgproxy on each image, and compares the result with the reference image
  33. // which is expected to be in the `integration` folder with the same name
  34. // but with `.png` extension.
  35. func (s *LoadTestSuite) testLoadFolder(folder string) {
  36. walkPath := path.Join(s.testImagesPath, folder)
  37. // Iterate over the files in the source folder
  38. err := filepath.Walk(walkPath, func(path string, info os.FileInfo, err error) error {
  39. s.Require().NoError(err)
  40. // Skip directories
  41. if info.IsDir() {
  42. return nil
  43. }
  44. // get the base name of the file (8-bpp.png)
  45. baseName := filepath.Base(path)
  46. // Construct the source URL for imgproxy (no processing)
  47. sourceUrl := fmt.Sprintf("/insecure/plain/local:///%s/%s@bmp", folder, baseName)
  48. // Read source image from imgproxy
  49. resp := s.GET(sourceUrl)
  50. defer resp.Body.Close()
  51. s.Require().Equal(http.StatusOK, resp.StatusCode, "expected status code 200 OK, got %d, path: %s", resp.StatusCode, path)
  52. // Match image to precalculated hash
  53. s.matcher.ImageMatches(s.T(), resp.Body, baseName, maxDistance)
  54. return nil
  55. })
  56. s.Require().NoError(err)
  57. }
  58. // TestLoadSaveToPng ensures that our load pipeline works,
  59. // including standard and custom loaders. For each source image
  60. // in the folder, it does the passthrough request through imgproxy:
  61. // no processing, just convert format of the source file to png.
  62. // Then, it compares the result with the reference image.
  63. func (s *LoadTestSuite) TestLoadSaveToPng() {
  64. testCases := []struct {
  65. name string
  66. imageType imagetype.Type
  67. folderName string
  68. }{
  69. {"GIF", imagetype.GIF, "gif"},
  70. {"JPEG", imagetype.JPEG, "jpg"},
  71. {"HEIC", imagetype.HEIC, "heif"},
  72. {"JXL", imagetype.JXL, "jxl"},
  73. {"SVG", imagetype.SVG, "svg"},
  74. {"TIFF", imagetype.TIFF, "tiff"},
  75. {"WEBP", imagetype.WEBP, "webp"},
  76. {"BMP", imagetype.BMP, "bmp"},
  77. {"ICO", imagetype.ICO, "ico"},
  78. }
  79. for _, tc := range testCases {
  80. s.T().Run(tc.name, func(t *testing.T) {
  81. if vips.SupportsLoad(tc.imageType) {
  82. s.testLoadFolder(tc.folderName)
  83. } else {
  84. t.Skipf("%s format not supported by VIPS", tc.name)
  85. }
  86. })
  87. }
  88. }
  89. func TestIntegration(t *testing.T) {
  90. suite.Run(t, new(LoadTestSuite))
  91. }