From e9c075a4a575165a88de52bcb6e6cf38197e8ad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 8 Oct 2024 23:23:53 +0200 Subject: [PATCH] feat: add build tag to skip Watcher support (#1076) * feat: add build tag to skip Watcher support * fix * fix * cleanup --- .github/workflows/docker.yaml | 2 +- .github/workflows/tests.yaml | 4 +- CONTRIBUTING.md | 4 +- Dockerfile | 2 +- alpine.Dockerfile | 2 +- build-static.sh | 2 +- caddy/caddy_test.go | 37 +++--------------- caddy/watcher_test.go | 38 +++++++++++++++++++ dev.Dockerfile | 2 +- docs/cn/CONTRIBUTING.md | 4 +- docs/compile.md | 11 +++--- docs/fr/CONTRIBUTING.md | 4 +- docs/tr/CONTRIBUTING.md | 4 +- internal/watcher/watch_pattern.go | 5 ++- internal/watcher/watch_pattern_test.go | 5 ++- internal/watcher/watcher-skip.go | 14 +++++++ internal/watcher/watcher.c | 3 ++ internal/watcher/watcher.go | 5 ++- ...hp_with_watcher_test.go => watcher_test.go | 20 ++-------- worker.go | 5 ++- 20 files changed, 101 insertions(+), 72 deletions(-) create mode 100644 caddy/watcher_test.go create mode 100644 internal/watcher/watcher-skip.go rename frankenphp_with_watcher_test.go => watcher_test.go (88%) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index f98fbb0d..61f9929a 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -213,7 +213,7 @@ jobs: run: | docker run --platform=${{ matrix.platform }} --rm \ "$(jq -r '."builder-${{ matrix.variant }}"."containerimage.config.digest"' <<< "${METADATA}")" \ - sh -c 'go test ${{ matrix.race }} -v ./... && cd caddy && go test ${{ matrix.race }} -v ./...' + sh -c 'go test -tags watcher ${{ matrix.race }} -v ./... && cd caddy && go test -tags watcher ${{ matrix.race }} -v ./...' env: METADATA: ${{ steps.build.outputs.metadata }} # Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/ diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 64c9f7be..94e93d71 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -71,11 +71,11 @@ jobs: run: go build - name: Run library tests - run: go test -race -v ./... + run: go test -tags watcher -race -v ./... - name: Run Caddy module tests working-directory: caddy/ - run: go test -race -v ./... + run: go test -tags watcher -race -v ./... - name: Build the server working-directory: caddy/frankenphp/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 850229dd..aae94acf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ If docker version is lower than 23.0, build is failed by dockerignore [pattern i ## Running the test suite ```console -go test -race -v ./... +go test -tags watcher -race -v ./... ``` ## Caddy module @@ -171,7 +171,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push 8. In the container, you can use GDB and the like: ```console - go test -c -ldflags=-w + go test -tags watcher -c -ldflags=-w gdb --args ./frankenphp.test -test.run ^MyTest$ ``` diff --git a/Dockerfile b/Dockerfile index 3c39264f..5bb52a69 100644 --- a/Dockerfile +++ b/Dockerfile @@ -101,7 +101,7 @@ ENV CGO_CPPFLAGS=$PHP_CPPFLAGS ENV CGO_LDFLAGS="-lssl -lcrypto -lreadline -largon2 -lcurl -lonig -lz $PHP_LDFLAGS" WORKDIR /go/src/app/caddy/frankenphp -RUN GOBIN=/usr/local/bin go install -tags 'brotli' -ldflags "-w -s -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \ +RUN GOBIN=/usr/local/bin go install -tags 'brotli watcher' -ldflags "-w -s -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \ setcap cap_net_bind_service=+ep /usr/local/bin/frankenphp && \ cp Caddyfile /etc/caddy/Caddyfile && \ frankenphp version diff --git a/alpine.Dockerfile b/alpine.Dockerfile index c87dd5ff..64bb47ff 100644 --- a/alpine.Dockerfile +++ b/alpine.Dockerfile @@ -122,7 +122,7 @@ ENV CGO_CPPFLAGS=$PHP_CPPFLAGS ENV CGO_LDFLAGS="-lssl -lcrypto -lreadline -largon2 -lcurl -lonig -lz $PHP_LDFLAGS" WORKDIR /go/src/app/caddy/frankenphp -RUN GOBIN=/usr/local/bin go install -tags 'brotli' -ldflags "-w -s -extldflags '-Wl,-z,stack-size=0x80000' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \ +RUN GOBIN=/usr/local/bin go install -tags 'brotli watcher' -ldflags "-w -s -extldflags '-Wl,-z,stack-size=0x80000' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \ setcap cap_net_bind_service=+ep /usr/local/bin/frankenphp && \ upx --best /usr/local/bin/frankenphp && \ frankenphp version diff --git a/build-static.sh b/build-static.sh index 2e656ce5..5b3461ed 100755 --- a/build-static.sh +++ b/build-static.sh @@ -249,7 +249,7 @@ fi cd caddy/frankenphp/ go env -go build -buildmode=pie -tags "cgo netgo osusergo static_build brotli" -ldflags "-linkmode=external -extldflags '-static-pie ${extraExtldflags}' ${extraLdflags} -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ${FRANKENPHP_VERSION} PHP ${LIBPHP_VERSION} Caddy'" -o "../../dist/${bin}" +go build -buildmode=pie -tags "cgo netgo osusergo static_build brotli watcher" -ldflags "-linkmode=external -extldflags '-static-pie ${extraExtldflags}' ${extraLdflags} -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ${FRANKENPHP_VERSION} PHP ${LIBPHP_VERSION} Caddy'" -o "../../dist/${bin}" cd ../.. if [ -d "${EMBED}" ]; then diff --git a/caddy/caddy_test.go b/caddy/caddy_test.go index 51bd86a1..fe586ccd 100644 --- a/caddy/caddy_test.go +++ b/caddy/caddy_test.go @@ -3,15 +3,16 @@ package caddy_test import ( "bytes" "fmt" - "github.com/dunglas/frankenphp" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/testutil" - "github.com/stretchr/testify/require" "net/http" "strings" "sync" "testing" + "github.com/dunglas/frankenphp" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/require" + "github.com/caddyserver/caddy/v2/caddytest" ) @@ -574,31 +575,3 @@ func TestAutoWorkerConfig(t *testing.T) { "frankenphp_testdata_index_php_ready_workers", )) } - -func TestWorkerWithInactiveWatcher(t *testing.T) { - tester := caddytest.NewTester(t) - tester.InitServer(` - { - skip_install_trust - admin localhost:2999 - http_port 9080 - - frankenphp { - worker { - file ../testdata/worker-with-watcher.php - num 1 - watch ./**/*.php - } - } - } - - localhost:9080 { - root ../testdata - rewrite worker-with-watcher.php - php - } - `, "caddyfile") - - tester.AssertGetResponse("http://localhost:9080", http.StatusOK, "requests:1") - tester.AssertGetResponse("http://localhost:9080", http.StatusOK, "requests:2") -} diff --git a/caddy/watcher_test.go b/caddy/watcher_test.go new file mode 100644 index 00000000..581f23cf --- /dev/null +++ b/caddy/watcher_test.go @@ -0,0 +1,38 @@ +//go:build watcher + +package caddy_test + +import ( + "net/http" + "testing" + + "github.com/caddyserver/caddy/v2/caddytest" +) + +func TestWorkerWithInactiveWatcher(t *testing.T) { + tester := caddytest.NewTester(t) + tester.InitServer(` + { + skip_install_trust + admin localhost:2999 + http_port 9080 + + frankenphp { + worker { + file ../testdata/worker-with-watcher.php + num 1 + watch ./**/*.php + } + } + } + + localhost:9080 { + root ../testdata + rewrite worker-with-watcher.php + php + } + `, "caddyfile") + + tester.AssertGetResponse("http://localhost:9080", http.StatusOK, "requests:1") + tester.AssertGetResponse("http://localhost:9080", http.StatusOK, "requests:2") +} diff --git a/dev.Dockerfile b/dev.Dockerfile index 4b95f42f..455f447b 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -78,7 +78,7 @@ WORKDIR /go/src/app COPY . . WORKDIR /go/src/app/caddy/frankenphp -RUN go build -buildvcs=false -tags 'brotli' +RUN go build -buildvcs=false -tags 'brotli watcher' WORKDIR /go/src/app CMD [ "zsh" ] diff --git a/docs/cn/CONTRIBUTING.md b/docs/cn/CONTRIBUTING.md index a7887983..fc4f0c6b 100644 --- a/docs/cn/CONTRIBUTING.md +++ b/docs/cn/CONTRIBUTING.md @@ -29,7 +29,7 @@ docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 8080:8080 - ## 运行测试套件 ```console -go test -race -v ./... +go test -tags watcher -race -v ./... ``` ## Caddy 模块 @@ -171,7 +171,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push 8. 在容器中,可以使用 GDB 和以下: ```console - go test -c -ldflags=-w + go test -tags watcher -c -ldflags=-w gdb --args ./frankenphp.test -test.run ^MyTest$ ``` diff --git a/docs/compile.md b/docs/compile.md index 0f624897..68be5392 100644 --- a/docs/compile.md +++ b/docs/compile.md @@ -101,18 +101,19 @@ xcaddy build \ Additional features can be enabled if the required C libraries are installed by passing additional build tags to the Go compiler: -| Tag | Dependencies | Description | -|--------|--------------------------------------------|--------------------------------------------------| -| brotli | [Brotli](https://github.com/google/brotli) | Add a Caddy module supporting Brotli compression | +| Tag | Dependencies | Description | +|---------|----------------------------------------------|--------------------------------| +| brotli | [Brotli](https://github.com/google/brotli) | Brotli compression | +| watcher | [Watcher](https://github.com/e-dant/watcher) | Restart workers on file change | When using `go build` directly, pass the additional `-tags` option followed by the comma-separated list of tags: ```console -go build -tags brotli +go build -tags 'brotli watcher' ``` When using `xcaddy`, set the `-tags` option in the `XCADDY_GO_BUILD_FLAGS` environment variable: ```console -XCADDY_GO_BUILD_FLAGS="-tags brotli" +XCADDY_GO_BUILD_FLAGS="-tags 'brotli watcher'" ``` diff --git a/docs/fr/CONTRIBUTING.md b/docs/fr/CONTRIBUTING.md index 7f997396..2df7bc8e 100644 --- a/docs/fr/CONTRIBUTING.md +++ b/docs/fr/CONTRIBUTING.md @@ -29,7 +29,7 @@ Si la version de Docker est inférieure à 23.0, la construction échoue à caus ## Exécution de la suite de tests ```console -go test -race -v ./... +go test -tags watcher -race -v ./... ``` ## Module Caddy @@ -145,7 +145,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push 8. Dans le conteneur, vous pouvez utiliser GDB et similaires : ```console - go test -c -ldflags=-w + go test -tags watcher -c -ldflags=-w gdb --args ./frankenphp.test -test.run ^MyTest$ ``` diff --git a/docs/tr/CONTRIBUTING.md b/docs/tr/CONTRIBUTING.md index a7b09376..30295f54 100644 --- a/docs/tr/CONTRIBUTING.md +++ b/docs/tr/CONTRIBUTING.md @@ -29,7 +29,7 @@ Docker sürümü 23.0'dan düşükse, derleme dockerignore [pattern issue](https ## Test senaryolarını çalıştırma ```console -go test -race -v ./... +go test -tags watcher -race -v ./... ``` ## Caddy modülü @@ -171,7 +171,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push 8. Konteynerde GDB ve benzerlerini kullanabilirsiniz: ```console - go test -c -ldflags=-w + go test -tags watcher -c -ldflags=-w gdb --args ./frankenphp.test -test.run ^MyTest$ ``` diff --git a/internal/watcher/watch_pattern.go b/internal/watcher/watch_pattern.go index 0da197bc..333f1bfe 100644 --- a/internal/watcher/watch_pattern.go +++ b/internal/watcher/watch_pattern.go @@ -1,9 +1,12 @@ +//go:build watcher + package watcher import ( - "go.uber.org/zap" "path/filepath" "strings" + + "go.uber.org/zap" ) type watchPattern struct { diff --git a/internal/watcher/watch_pattern_test.go b/internal/watcher/watch_pattern_test.go index 8b15afea..ead1c031 100644 --- a/internal/watcher/watch_pattern_test.go +++ b/internal/watcher/watch_pattern_test.go @@ -1,9 +1,12 @@ +//go:build watcher + package watcher import ( - "github.com/stretchr/testify/assert" "path/filepath" "testing" + + "github.com/stretchr/testify/assert" ) func TestDisallowOnEventTypeBiggerThan3(t *testing.T) { diff --git a/internal/watcher/watcher-skip.go b/internal/watcher/watcher-skip.go new file mode 100644 index 00000000..8f59dba3 --- /dev/null +++ b/internal/watcher/watcher-skip.go @@ -0,0 +1,14 @@ +//go:build !watcher + +package watcher + +import "go.uber.org/zap" + +func InitWatcher(filePatterns []string, callback func(), zapLogger *zap.Logger) error { + zapLogger.Error("watcher support is not enabled") + + return nil +} + +func DrainWatcher() { +} diff --git a/internal/watcher/watcher.c b/internal/watcher/watcher.c index 3d215612..efb3f642 100644 --- a/internal/watcher/watcher.c +++ b/internal/watcher/watcher.c @@ -1,3 +1,6 @@ +// clang-format off +//go:build watcher +// clang-format on #include "_cgo_export.h" #include "watcher-c.h" diff --git a/internal/watcher/watcher.go b/internal/watcher/watcher.go index 93737036..e5aea475 100644 --- a/internal/watcher/watcher.go +++ b/internal/watcher/watcher.go @@ -1,3 +1,5 @@ +//go:build watcher + package watcher // #cgo LDFLAGS: -lwatcher -lstdc++ @@ -8,11 +10,12 @@ package watcher import "C" import ( "errors" - "go.uber.org/zap" "runtime/cgo" "sync" "time" "unsafe" + + "go.uber.org/zap" ) type watcher struct { diff --git a/frankenphp_with_watcher_test.go b/watcher_test.go similarity index 88% rename from frankenphp_with_watcher_test.go rename to watcher_test.go index 0829e22e..bddbb68a 100644 --- a/frankenphp_with_watcher_test.go +++ b/watcher_test.go @@ -1,15 +1,17 @@ +//go:build watcher + package frankenphp_test import ( - "github.com/stretchr/testify/assert" "io" "net/http" "net/http/httptest" "os" "path/filepath" - "strings" "testing" "time" + + "github.com/stretchr/testify/assert" ) // we have to wait a few milliseconds for the watcher debounce to take effect @@ -22,10 +24,6 @@ const minTimesToPollForChanges = 3 const maxTimesToPollForChanges = 60 func TestWorkersShouldReloadOnMatchingPattern(t *testing.T) { - if isRunningInMsanMode() { - t.Skip("Skipping watcher tests in memory sanitizer mode") - return - } watch := []string{"./testdata/**/*.txt"} runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) { @@ -35,11 +33,6 @@ func TestWorkersShouldReloadOnMatchingPattern(t *testing.T) { } func TestWorkersShouldNotReloadOnExcludingPattern(t *testing.T) { - if isRunningInMsanMode() { - t.Skip("Skipping watcher tests in memory sanitizer mode") - - return - } watch := []string{"./testdata/**/*.php"} runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) { @@ -58,11 +51,6 @@ func fetchBody(method string, url string, handler func(http.ResponseWriter, *htt return string(body) } -func isRunningInMsanMode() bool { - cflags := os.Getenv("CFLAGS") - return strings.Contains(cflags, "-fsanitize=memory") -} - func pollForWorkerReset(t *testing.T, handler func(http.ResponseWriter, *http.Request), limit int) bool { // first we make an initial request to start the request counter body := fetchBody("GET", "http://example.com/worker-with-watcher.php", handler) diff --git a/worker.go b/worker.go index f1c34be9..5c91fecf 100644 --- a/worker.go +++ b/worker.go @@ -225,11 +225,14 @@ func restartWorkersOnFileChanges(workerOpts []workerOpt) error { for _, w := range workerOpts { directoriesToWatch = append(directoriesToWatch, w.watch...) } + if len(directoriesToWatch) == 0 { + return nil + } + restartWorkers := func() { restartWorkers(workerOpts) } if err := watcher.InitWatcher(directoriesToWatch, restartWorkers, getLogger()); err != nil { - return err }