@@ -1884,6 +1884,111 @@ func TestAPI(t *testing.T) {
1884
1884
})
1885
1885
}
1886
1886
})
1887
+
1888
+ t .Run ("CreateReadsConfigTwice" , func (t * testing.T ) {
1889
+ t .Parallel ()
1890
+
1891
+ if runtime .GOOS == "windows" {
1892
+ t .Skip ("Dev Container tests are not supported on Windows (this test uses mocks but fails due to Windows paths)" )
1893
+ }
1894
+
1895
+ var (
1896
+ ctx = testutil .Context (t , testutil .WaitMedium )
1897
+ logger = testutil .Logger (t )
1898
+ mClock = quartz .NewMock (t )
1899
+ mCCLI = acmock .NewMockContainerCLI (gomock .NewController (t ))
1900
+ fSAC = & fakeSubAgentClient {
1901
+ logger : logger .Named ("fakeSubAgentClient" ),
1902
+ createErrC : make (chan error , 1 ),
1903
+ }
1904
+ fDCCLI = & fakeDevcontainerCLI {
1905
+ readConfig : agentcontainers.DevcontainerConfig {
1906
+ Configuration : agentcontainers.DevcontainerConfiguration {
1907
+ Customizations : agentcontainers.DevcontainerCustomizations {
1908
+ Coder : agentcontainers.CoderCustomization {
1909
+ // We want to specify a custom name for this agent.
1910
+ Name : "custom-name" ,
1911
+ },
1912
+ },
1913
+ },
1914
+ },
1915
+ readConfigErrC : make (chan func (envs []string ) error , 2 ),
1916
+ execErrC : make (chan func (cmd string , args ... string ) error , 1 ),
1917
+ }
1918
+
1919
+ testContainer = codersdk.WorkspaceAgentContainer {
1920
+ ID : "test-container-id" ,
1921
+ FriendlyName : "test-container" ,
1922
+ Image : "test-image" ,
1923
+ Running : true ,
1924
+ CreatedAt : time .Now (),
1925
+ Labels : map [string ]string {
1926
+ agentcontainers .DevcontainerLocalFolderLabel : "/workspaces" ,
1927
+ agentcontainers .DevcontainerConfigFileLabel : "/workspace/.devcontainer/devcontainer.json" ,
1928
+ },
1929
+ }
1930
+ )
1931
+
1932
+ coderBin , err := os .Executable ()
1933
+ require .NoError (t , err )
1934
+
1935
+ // Mock the `List` function to always return out test container.
1936
+ mCCLI .EXPECT ().List (gomock .Any ()).Return (codersdk.WorkspaceAgentListContainersResponse {
1937
+ Containers : []codersdk.WorkspaceAgentContainer {testContainer },
1938
+ }, nil ).AnyTimes ()
1939
+
1940
+ // Mock the steps used for injecting the coder agent.
1941
+ gomock .InOrder (
1942
+ mCCLI .EXPECT ().DetectArchitecture (gomock .Any (), testContainer .ID ).Return (runtime .GOARCH , nil ),
1943
+ mCCLI .EXPECT ().ExecAs (gomock .Any (), testContainer .ID , "root" , "mkdir" , "-p" , "/.coder-agent" ).Return (nil , nil ),
1944
+ mCCLI .EXPECT ().Copy (gomock .Any (), testContainer .ID , coderBin , "/.coder-agent/coder" ).Return (nil ),
1945
+ mCCLI .EXPECT ().ExecAs (gomock .Any (), testContainer .ID , "root" , "chmod" , "0755" , "/.coder-agent" , "/.coder-agent/coder" ).Return (nil , nil ),
1946
+ )
1947
+
1948
+ mClock .Set (time .Now ()).MustWait (ctx )
1949
+ tickerTrap := mClock .Trap ().TickerFunc ("updaterLoop" )
1950
+
1951
+ api := agentcontainers .NewAPI (logger ,
1952
+ agentcontainers .WithClock (mClock ),
1953
+ agentcontainers .WithContainerCLI (mCCLI ),
1954
+ agentcontainers .WithDevcontainerCLI (fDCCLI ),
1955
+ agentcontainers .WithSubAgentClient (fSAC ),
1956
+ agentcontainers .WithSubAgentURL ("test-subagent-url" ),
1957
+ agentcontainers .WithWatcher (watcher .NewNoop ()),
1958
+ )
1959
+ defer api .Close ()
1960
+
1961
+ // Close before api.Close() defer to avoid deadlock after test.
1962
+ defer close (fSAC .createErrC )
1963
+ defer close (fDCCLI .execErrC )
1964
+ defer close (fDCCLI .readConfigErrC )
1965
+
1966
+ // Given: We allow agent creation and injection to succeed.
1967
+ testutil .RequireSend (ctx , t , fSAC .createErrC , nil )
1968
+ testutil .RequireSend (ctx , t , fDCCLI .execErrC , func (cmd string , args ... string ) error {
1969
+ assert .Equal (t , "pwd" , cmd )
1970
+ assert .Empty (t , args )
1971
+ return nil
1972
+ })
1973
+ testutil .RequireSend (ctx , t , fDCCLI .readConfigErrC , func (env []string ) error {
1974
+ // We expect the wrong workspace agent name passed in first.
1975
+ assert .Contains (t , env , "CODER_WORKSPACE_AGENT_NAME=test-container" )
1976
+ return nil
1977
+ })
1978
+ testutil .RequireSend (ctx , t , fDCCLI .readConfigErrC , func (env []string ) error {
1979
+ // We then expect the agent name passed here to have been read from the config.
1980
+ assert .Contains (t , env , "CODER_WORKSPACE_AGENT_NAME=custom-name" )
1981
+ assert .NotContains (t , env , "CODER_WORKSPACE_AGENT_NAME=test-container" )
1982
+ return nil
1983
+ })
1984
+
1985
+ // Wait until the ticker has been registered.
1986
+ tickerTrap .MustWait (ctx ).MustRelease (ctx )
1987
+ tickerTrap .Close ()
1988
+
1989
+ // Then: We expected it to succeed
1990
+ require .Len (t , fSAC .created , 1 )
1991
+ })
1887
1992
}
1888
1993
1889
1994
// mustFindDevcontainerByPath returns the devcontainer with the given workspace
0 commit comments