watcher_test.go 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //go:build !nowatcher
  2. package frankenphp_test
  3. import (
  4. "io"
  5. "net/http"
  6. "net/http/httptest"
  7. "os"
  8. "path/filepath"
  9. "testing"
  10. "time"
  11. "github.com/stretchr/testify/assert"
  12. )
  13. // we have to wait a few milliseconds for the watcher debounce to take effect
  14. const pollingTime = 250
  15. // in tests checking for no reload: we will poll 3x250ms = 0.75s
  16. const minTimesToPollForChanges = 3
  17. // in tests checking for a reload: we will poll a maximum of 60x250ms = 15s
  18. const maxTimesToPollForChanges = 60
  19. func TestWorkersShouldReloadOnMatchingPattern(t *testing.T) {
  20. watch := []string{"./testdata/**/*.txt"}
  21. runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
  22. requestBodyHasReset := pollForWorkerReset(t, handler, maxTimesToPollForChanges)
  23. assert.True(t, requestBodyHasReset)
  24. }, &testOptions{nbParrallelRequests: 1, nbWorkers: 1, workerScript: "worker-with-watcher.php", watch: watch})
  25. }
  26. func TestWorkersShouldNotReloadOnExcludingPattern(t *testing.T) {
  27. watch := []string{"./testdata/**/*.php"}
  28. runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
  29. requestBodyHasReset := pollForWorkerReset(t, handler, minTimesToPollForChanges)
  30. assert.False(t, requestBodyHasReset)
  31. }, &testOptions{nbParrallelRequests: 1, nbWorkers: 1, workerScript: "worker-with-watcher.php", watch: watch})
  32. }
  33. func fetchBody(method string, url string, handler func(http.ResponseWriter, *http.Request)) string {
  34. req := httptest.NewRequest(method, url, nil)
  35. w := httptest.NewRecorder()
  36. handler(w, req)
  37. resp := w.Result()
  38. body, _ := io.ReadAll(resp.Body)
  39. return string(body)
  40. }
  41. func pollForWorkerReset(t *testing.T, handler func(http.ResponseWriter, *http.Request), limit int) bool {
  42. // first we make an initial request to start the request counter
  43. body := fetchBody("GET", "http://example.com/worker-with-watcher.php", handler)
  44. assert.Equal(t, "requests:1", body)
  45. // now we spam file updates and check if the request counter resets
  46. for i := 0; i < limit; i++ {
  47. updateTestFile("./testdata/files/test.txt", "updated", t)
  48. time.Sleep(pollingTime * time.Millisecond)
  49. body := fetchBody("GET", "http://example.com/worker-with-watcher.php", handler)
  50. if body == "requests:1" {
  51. return true
  52. }
  53. }
  54. return false
  55. }
  56. func updateTestFile(fileName string, content string, t *testing.T) {
  57. absFileName, err := filepath.Abs(fileName)
  58. assert.NoError(t, err)
  59. dirName := filepath.Dir(absFileName)
  60. if _, err := os.Stat(dirName); os.IsNotExist(err) {
  61. err = os.MkdirAll(dirName, 0700)
  62. assert.NoError(t, err)
  63. }
  64. bytes := []byte(content)
  65. err = os.WriteFile(absFileName, bytes, 0644)
  66. assert.NoError(t, err)
  67. }