mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
feat(agent/agentcontainers): add feature options as envs (#18576)
This commit is contained in:
committed by
GitHub
parent
688d2ee3eb
commit
3c4d9206bc
@ -2060,6 +2060,122 @@ func TestAPI(t *testing.T) {
|
||||
require.Len(t, fSAC.created, 1)
|
||||
})
|
||||
|
||||
t.Run("ReadConfigWithFeatureOptions", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("Dev Container tests are not supported on Windows (this test uses mocks but fails due to Windows paths)")
|
||||
}
|
||||
|
||||
var (
|
||||
ctx = testutil.Context(t, testutil.WaitMedium)
|
||||
logger = testutil.Logger(t)
|
||||
mClock = quartz.NewMock(t)
|
||||
mCCLI = acmock.NewMockContainerCLI(gomock.NewController(t))
|
||||
fSAC = &fakeSubAgentClient{
|
||||
logger: logger.Named("fakeSubAgentClient"),
|
||||
createErrC: make(chan error, 1),
|
||||
}
|
||||
fDCCLI = &fakeDevcontainerCLI{
|
||||
readConfig: agentcontainers.DevcontainerConfig{
|
||||
MergedConfiguration: agentcontainers.DevcontainerMergedConfiguration{
|
||||
Features: agentcontainers.DevcontainerFeatures{
|
||||
"./code-server": map[string]any{
|
||||
"port": 9090,
|
||||
},
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": map[string]any{
|
||||
"moby": "false",
|
||||
},
|
||||
},
|
||||
},
|
||||
Workspace: agentcontainers.DevcontainerWorkspace{
|
||||
WorkspaceFolder: "/workspaces/coder",
|
||||
},
|
||||
},
|
||||
readConfigErrC: make(chan func(envs []string) error, 2),
|
||||
}
|
||||
|
||||
testContainer = codersdk.WorkspaceAgentContainer{
|
||||
ID: "test-container-id",
|
||||
FriendlyName: "test-container",
|
||||
Image: "test-image",
|
||||
Running: true,
|
||||
CreatedAt: time.Now(),
|
||||
Labels: map[string]string{
|
||||
agentcontainers.DevcontainerLocalFolderLabel: "/workspaces/coder",
|
||||
agentcontainers.DevcontainerConfigFileLabel: "/workspaces/coder/.devcontainer/devcontainer.json",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
coderBin, err := os.Executable()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Mock the `List` function to always return our test container.
|
||||
mCCLI.EXPECT().List(gomock.Any()).Return(codersdk.WorkspaceAgentListContainersResponse{
|
||||
Containers: []codersdk.WorkspaceAgentContainer{testContainer},
|
||||
}, nil).AnyTimes()
|
||||
|
||||
// Mock the steps used for injecting the coder agent.
|
||||
gomock.InOrder(
|
||||
mCCLI.EXPECT().DetectArchitecture(gomock.Any(), testContainer.ID).Return(runtime.GOARCH, nil),
|
||||
mCCLI.EXPECT().ExecAs(gomock.Any(), testContainer.ID, "root", "mkdir", "-p", "/.coder-agent").Return(nil, nil),
|
||||
mCCLI.EXPECT().Copy(gomock.Any(), testContainer.ID, coderBin, "/.coder-agent/coder").Return(nil),
|
||||
mCCLI.EXPECT().ExecAs(gomock.Any(), testContainer.ID, "root", "chmod", "0755", "/.coder-agent", "/.coder-agent/coder").Return(nil, nil),
|
||||
)
|
||||
|
||||
mClock.Set(time.Now()).MustWait(ctx)
|
||||
tickerTrap := mClock.Trap().TickerFunc("updaterLoop")
|
||||
|
||||
api := agentcontainers.NewAPI(logger,
|
||||
agentcontainers.WithClock(mClock),
|
||||
agentcontainers.WithContainerCLI(mCCLI),
|
||||
agentcontainers.WithDevcontainerCLI(fDCCLI),
|
||||
agentcontainers.WithSubAgentClient(fSAC),
|
||||
agentcontainers.WithSubAgentURL("test-subagent-url"),
|
||||
agentcontainers.WithWatcher(watcher.NewNoop()),
|
||||
agentcontainers.WithManifestInfo("test-user", "test-workspace"),
|
||||
)
|
||||
api.Init()
|
||||
defer api.Close()
|
||||
|
||||
// Close before api.Close() defer to avoid deadlock after test.
|
||||
defer close(fSAC.createErrC)
|
||||
defer close(fDCCLI.readConfigErrC)
|
||||
|
||||
// Allow agent creation and injection to succeed.
|
||||
testutil.RequireSend(ctx, t, fSAC.createErrC, nil)
|
||||
|
||||
testutil.RequireSend(ctx, t, fDCCLI.readConfigErrC, func(envs []string) error {
|
||||
assert.Contains(t, envs, "CODER_WORKSPACE_AGENT_NAME=coder")
|
||||
assert.Contains(t, envs, "CODER_WORKSPACE_NAME=test-workspace")
|
||||
assert.Contains(t, envs, "CODER_WORKSPACE_OWNER_NAME=test-user")
|
||||
assert.Contains(t, envs, "CODER_URL=test-subagent-url")
|
||||
// First call should not have feature envs.
|
||||
assert.NotContains(t, envs, "FEATURE_CODE_SERVER_OPTION_PORT=9090")
|
||||
assert.NotContains(t, envs, "FEATURE_DOCKER_IN_DOCKER_OPTION_MOBY=false")
|
||||
return nil
|
||||
})
|
||||
|
||||
testutil.RequireSend(ctx, t, fDCCLI.readConfigErrC, func(envs []string) error {
|
||||
assert.Contains(t, envs, "CODER_WORKSPACE_AGENT_NAME=coder")
|
||||
assert.Contains(t, envs, "CODER_WORKSPACE_NAME=test-workspace")
|
||||
assert.Contains(t, envs, "CODER_WORKSPACE_OWNER_NAME=test-user")
|
||||
assert.Contains(t, envs, "CODER_URL=test-subagent-url")
|
||||
// Second call should have feature envs from the first config read.
|
||||
assert.Contains(t, envs, "FEATURE_CODE_SERVER_OPTION_PORT=9090")
|
||||
assert.Contains(t, envs, "FEATURE_DOCKER_IN_DOCKER_OPTION_MOBY=false")
|
||||
return nil
|
||||
})
|
||||
|
||||
// Wait until the ticker has been registered.
|
||||
tickerTrap.MustWait(ctx).MustRelease(ctx)
|
||||
tickerTrap.Close()
|
||||
|
||||
// Verify agent was created successfully
|
||||
require.Len(t, fSAC.created, 1)
|
||||
})
|
||||
|
||||
t.Run("CommandEnv", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
Reference in New Issue
Block a user