From 987d87c4f7a9e74ff1412fbc9ca7d0b67e6751df Mon Sep 17 00:00:00 2001 From: maxpetrusenkoagent Date: Sun, 21 Jun 2026 11:41:52 -0400 Subject: [PATCH] test: cover watch rebuild with watched dependency Signed-off-by: maxpetrusenkoagent --- pkg/e2e/fixtures/watch/rebuild-deps.yaml | 4 ++++ pkg/e2e/watch_test.go | 27 +++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/pkg/e2e/fixtures/watch/rebuild-deps.yaml b/pkg/e2e/fixtures/watch/rebuild-deps.yaml index 48b1b45cb0..23d88adf02 100644 --- a/pkg/e2e/fixtures/watch/rebuild-deps.yaml +++ b/pkg/e2e/fixtures/watch/rebuild-deps.yaml @@ -6,6 +6,10 @@ services: RUN echo "backend_build_marker" > /built command: sleep infinity init: true + develop: + watch: + - path: backend-trigger + action: restart frontend: build: dockerfile_inline: | diff --git a/pkg/e2e/watch_test.go b/pkg/e2e/watch_test.go index f4f7861728..d21f7cb0f0 100644 --- a/pkg/e2e/watch_test.go +++ b/pkg/e2e/watch_test.go @@ -19,6 +19,7 @@ package e2e import ( "bytes" "crypto/rand" + "encoding/json" "fmt" "os" "path/filepath" @@ -370,12 +371,12 @@ func TestWatchMultiServices(t *testing.T) { // TestWatchRebuildIgnoresDependencies verifies that when `compose up --watch` // rebuilds a service after a file change, the rebuild does NOT cascade to its -// `depends_on` dependencies. +// `depends_on` dependencies, even if those dependencies also have watch rules. // -// Reproduces docker/compose#13853: `up --build` sets BuildOptions.Deps=true to -// build images for dependencies on initial startup; the watch rebuild path -// reused those BuildOptions without resetting Deps, so a single watched -// service triggered builds for the whole dependency chain. +// Reproduces docker/compose#13717 and docker/compose#13853: `up --build` sets +// BuildOptions.Deps=true to build images for dependencies on initial startup; +// the watch rebuild path reused those BuildOptions without resetting Deps, so +// a single watched service triggered builds for the whole dependency chain. // // The test scans build progress output between the "Rebuilding service(s)" and // "successfully built" markers and asserts only the watched service appears. @@ -391,6 +392,8 @@ func TestWatchRebuildIgnoresDependencies(t *testing.T) { testFile := filepath.Join(tmpdir, "test") assert.NilError(t, os.WriteFile(testFile, []byte("initial"), 0o600)) + backendTrigger := filepath.Join(tmpdir, "backend-trigger") + assert.NilError(t, os.WriteFile(backendTrigger, []byte("initial"), 0o600)) cmd := c.NewDockerComposeCmd(t, "-p", projectName, "-f", composeFilePath, "up", "--build", "--watch") buffer := bytes.NewBuffer(nil) @@ -414,6 +417,16 @@ func TestWatchRebuildIgnoresDependencies(t *testing.T) { return poll.Continue("waiting for watch to start: %v", buffer.String()) }, poll.WithTimeout(120*time.Second)) + inspectBackend := func() map[string]any { + psRes := c.RunDockerComposeCmd(t, "-p", projectName, "-f", composeFilePath, "ps", "--all", "--format=json", "backend") + var backend map[string]any + assert.NilError(t, json.Unmarshal([]byte(psRes.Stdout()), &backend), + "Invalid `compose ps` JSON: command output: %s", psRes.Combined()) + return backend + } + backendBefore := inspectBackend() + assert.Equal(t, strings.ToLower(backendBefore["State"].(string)), "running") + // Record the cutoff point in the log buffer so we only inspect output // produced AFTER the file change triggers the rebuild. logCutoff := buffer.Len() @@ -444,6 +457,10 @@ func TestWatchRebuildIgnoresDependencies(t *testing.T) { assert.Assert(t, !strings.Contains(rebuildLog, "backend Built"), "backend was unexpectedly rebuilt; got:\n%s", rebuildLog) + backendAfter := inspectBackend() + assert.Equal(t, backendAfter["ID"], backendBefore["ID"], "backend container was unexpectedly recreated") + assert.Equal(t, strings.ToLower(backendAfter["State"].(string)), "running") + c.RunDockerComposeCmdNoCheck(t, "-p", projectName, "kill", "-s", "9") }