From 434b54657a4a1e89f50aca50b7334a97ca7646ce Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Wed, 25 Jun 2025 14:06:20 +0300 Subject: [PATCH] fix(agent/agentcontainers): filter out "is test run" devcontainers (#18568) --- agent/agentcontainers/api.go | 3 ++- agent/agentcontainers/api_test.go | 26 ++++++++++++++++++++++++++ agent/agentcontainers/devcontainer.go | 3 +++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/agent/agentcontainers/api.go b/agent/agentcontainers/api.go index 27a29bd535..7ba29e45df 100644 --- a/agent/agentcontainers/api.go +++ b/agent/agentcontainers/api.go @@ -591,7 +591,8 @@ func (api *API) processUpdatedContainersLocked(ctx context.Context, updated code slog.F("config_file", configFile), ) - if len(api.containerLabelIncludeFilter) > 0 { + // Filter out devcontainer tests, unless explicitly set in include filters. + if len(api.containerLabelIncludeFilter) > 0 || container.Labels[DevcontainerIsTestRunLabel] == "true" { var ok bool for label, value := range api.containerLabelIncludeFilter { if v, found := container.Labels[label]; found && v == value { diff --git a/agent/agentcontainers/api_test.go b/agent/agentcontainers/api_test.go index 446bb472ed..7c4988630e 100644 --- a/agent/agentcontainers/api_test.go +++ b/agent/agentcontainers/api_test.go @@ -749,6 +749,7 @@ func TestAPI(t *testing.T) { knownDevcontainers []codersdk.WorkspaceAgentDevcontainer wantStatus int wantCount int + wantTestContainer bool verify func(t *testing.T, devcontainers []codersdk.WorkspaceAgentDevcontainer) }{ { @@ -995,6 +996,13 @@ func TestAPI(t *testing.T) { assert.Len(t, names, 4, "should have four unique devcontainer names") }, }, + { + name: "Include test containers", + lister: &fakeContainerCLI{}, + wantStatus: http.StatusOK, + wantTestContainer: true, + wantCount: 1, // Will be appended. + }, } for _, tt := range tests { @@ -1007,6 +1015,18 @@ func TestAPI(t *testing.T) { mClock.Set(time.Now()).MustWait(testutil.Context(t, testutil.WaitShort)) tickerTrap := mClock.Trap().TickerFunc("updaterLoop") + // This container should be ignored unless explicitly included. + tt.lister.containers.Containers = append(tt.lister.containers.Containers, codersdk.WorkspaceAgentContainer{ + ID: "test-container-1", + FriendlyName: "test-container-1", + Running: true, + Labels: map[string]string{ + agentcontainers.DevcontainerLocalFolderLabel: "/workspace/test1", + agentcontainers.DevcontainerConfigFileLabel: "/workspace/test1/.devcontainer/devcontainer.json", + agentcontainers.DevcontainerIsTestRunLabel: "true", + }, + }) + // Setup router with the handler under test. r := chi.NewRouter() apiOptions := []agentcontainers.Option{ @@ -1016,6 +1036,12 @@ func TestAPI(t *testing.T) { agentcontainers.WithWatcher(watcher.NewNoop()), } + if tt.wantTestContainer { + apiOptions = append(apiOptions, agentcontainers.WithContainerLabelIncludeFilter( + agentcontainers.DevcontainerIsTestRunLabel, "true", + )) + } + // Generate matching scripts for the known devcontainers // (required to extract log source ID). var scripts []codersdk.WorkspaceAgentScript diff --git a/agent/agentcontainers/devcontainer.go b/agent/agentcontainers/devcontainer.go index e5f2361348..555e406e0b 100644 --- a/agent/agentcontainers/devcontainer.go +++ b/agent/agentcontainers/devcontainer.go @@ -18,6 +18,9 @@ const ( // DevcontainerConfigFileLabel is the label that contains the path to // the devcontainer.json configuration file. DevcontainerConfigFileLabel = "devcontainer.config_file" + // DevcontainerIsTestRunLabel is set if the devcontainer is part of a test + // and should be excluded. + DevcontainerIsTestRunLabel = "devcontainer.is_test_run" // The default workspace folder inside the devcontainer. DevcontainerDefaultContainerWorkspaceFolder = "/workspaces" )