suite.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package integration
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "net"
  7. "net/http"
  8. "os"
  9. "github.com/sirupsen/logrus"
  10. "github.com/imgproxy/imgproxy/v3"
  11. "github.com/imgproxy/imgproxy/v3/httpheaders"
  12. "github.com/imgproxy/imgproxy/v3/testutil"
  13. )
  14. type TestServer struct {
  15. Addr net.Addr
  16. Shutdown context.CancelFunc
  17. }
  18. // Suite is a test suite for integration tests.
  19. //
  20. // It lazily initializes [imgproxy.Config] and [imgproxy.Imgproxy] when they are accessed.
  21. //
  22. // It provides the [Suite.GET] method that lazily initializes a test imgproxy server
  23. // and performs a GET request against it.
  24. //
  25. // Take note that Suite utilizes SetupSuite and TearDownSuite for setup and cleanup.
  26. // If you define them for your test suite, make sure to call the base methods.
  27. type Suite struct {
  28. testutil.LazySuite
  29. TestData *testutil.TestDataProvider
  30. Config testutil.LazyObj[*imgproxy.Config]
  31. Imgproxy testutil.LazyObj[*imgproxy.Imgproxy]
  32. Server testutil.LazyObj[*TestServer]
  33. }
  34. func (s *Suite) SetupSuite() {
  35. // Silence all the logs
  36. logrus.SetOutput(io.Discard)
  37. // Initialize test data provider (local test files)
  38. s.TestData = testutil.NewTestDataProvider(s.T)
  39. s.Config, _ = testutil.NewLazySuiteObj(s, func() (*imgproxy.Config, error) {
  40. // TODO: replace with NewDefaultConfig when we get rid of global config
  41. c, err := imgproxy.LoadConfigFromEnv(nil)
  42. s.Require().NoError(err)
  43. c.Server.Bind = ":0"
  44. c.Fetcher.Transport.Local.Root = s.TestData.Root()
  45. c.Fetcher.Transport.HTTP.ClientKeepAliveTimeout = 0
  46. return c, nil
  47. })
  48. s.Imgproxy, _ = testutil.NewLazySuiteObj(s, func() (*imgproxy.Imgproxy, error) {
  49. return imgproxy.New(s.T().Context(), s.Config())
  50. })
  51. s.Server, _ = testutil.NewLazySuiteObj(
  52. s,
  53. func() (*TestServer, error) {
  54. return s.startServer(s.Imgproxy()), nil
  55. },
  56. func(s *TestServer) error {
  57. s.Shutdown()
  58. return nil
  59. },
  60. )
  61. }
  62. func (s *Suite) TearDownSuite() {
  63. logrus.SetOutput(os.Stdout)
  64. }
  65. // startServer starts imgproxy instance's server for the tests.
  66. // Returns [TestServer] that contains the server address and shutdown function
  67. func (s *Suite) startServer(i *imgproxy.Imgproxy) *TestServer {
  68. ctx, cancel := context.WithCancel(s.T().Context())
  69. addrCh := make(chan net.Addr)
  70. go func() {
  71. err := i.StartServer(ctx, addrCh)
  72. if err != nil {
  73. s.T().Errorf("Imgproxy stopped with error: %v", err)
  74. }
  75. }()
  76. return &TestServer{
  77. Addr: <-addrCh,
  78. Shutdown: cancel,
  79. }
  80. }
  81. // GET performs a GET request to the imageproxy real server
  82. func (s *Suite) GET(path string, header ...http.Header) *http.Response {
  83. url := fmt.Sprintf("http://%s%s", s.Server().Addr, path)
  84. // Perform GET request to an url
  85. req, err := http.NewRequest("GET", url, nil)
  86. s.Require().NoError(err)
  87. // Copy headers from the provided http.Header to the request
  88. for _, h := range header {
  89. httpheaders.CopyAll(h, req.Header, true)
  90. }
  91. // Do the request
  92. resp, err := http.DefaultClient.Do(req)
  93. s.Require().NoError(err)
  94. return resp
  95. }