@@ -1610,63 +1610,77 @@ func TestWorkspaceAgentRecreateDevcontainer(t *testing.T) {
16101610)
16111611
16121612for _ ,tc := range []struct {
1613- name string
1614- devcontainerID string
1615- setupDevcontainers []codersdk.WorkspaceAgentDevcontainer
1616- setupMock func (mccli * acmock.MockContainerCLI ,mdccli * acmock.MockDevcontainerCLI ) (status int )
1613+ name string
1614+ devcontainerID string
1615+ devcontainers []codersdk.WorkspaceAgentDevcontainer
1616+ containers []codersdk.WorkspaceAgentContainer
1617+ expectRecreate bool
1618+ expectErrorCode int
16171619}{
16181620{
1619- name :"Recreate" ,
1620- devcontainerID :devcontainerID .String (),
1621- setupDevcontainers : []codersdk.WorkspaceAgentDevcontainer {devcontainer },
1622- setupMock :func (mccli * acmock.MockContainerCLI ,mdccli * acmock.MockDevcontainerCLI )int {
1623- mccli .EXPECT ().List (gomock .Any ()).Return (codersdk.WorkspaceAgentListContainersResponse {
1624- Containers : []codersdk.WorkspaceAgentContainer {devContainer },
1625- },nil ).AnyTimes ()
1626- // DetectArchitecture always returns "<none>" for this test to disable agent injection.
1627- mccli .EXPECT ().DetectArchitecture (gomock .Any (),devContainer .ID ).Return ("<none>" ,nil ).AnyTimes ()
1628- mdccli .EXPECT ().ReadConfig (gomock .Any (),workspaceFolder ,configFile ,gomock .Any ()).Return (agentcontainers.DevcontainerConfig {},nil ).AnyTimes ()
1629- mdccli .EXPECT ().Up (gomock .Any (),workspaceFolder ,configFile ,gomock .Any ()).Return ("someid" ,nil ).Times (1 )
1630- return 0
1631- },
1621+ name :"Recreate" ,
1622+ devcontainerID :devcontainerID .String (),
1623+ devcontainers : []codersdk.WorkspaceAgentDevcontainer {devcontainer },
1624+ containers : []codersdk.WorkspaceAgentContainer {devContainer },
1625+ expectRecreate :true ,
16321626},
16331627{
1634- name :"Devcontainer does not exist" ,
1635- devcontainerID :uuid .NewString (),
1636- setupDevcontainers :nil ,
1637- setupMock :func (mccli * acmock.MockContainerCLI ,mdccli * acmock.MockDevcontainerCLI )int {
1638- mccli .EXPECT ().List (gomock .Any ()).Return (codersdk.WorkspaceAgentListContainersResponse {},nil ).AnyTimes ()
1639- return http .StatusNotFound
1640- },
1628+ name :"Devcontainer does not exist" ,
1629+ devcontainerID :uuid .NewString (),
1630+ devcontainers :nil ,
1631+ containers : []codersdk.WorkspaceAgentContainer {},
1632+ expectErrorCode :http .StatusNotFound ,
16411633},
16421634} {
16431635t .Run (tc .name ,func (t * testing.T ) {
16441636t .Parallel ()
16451637
1646- ctrl := gomock .NewController (t )
1647- mccli := acmock .NewMockContainerCLI (ctrl )
1648- mdccli := acmock .NewMockDevcontainerCLI (ctrl )
1649- wantStatus := tc .setupMock (mccli ,mdccli )
1650- logger := slogtest .Make (t ,& slogtest.Options {IgnoreErrors :true }).Leveled (slog .LevelDebug )
1651- client ,db := coderdtest .NewWithDatabase (t ,& coderdtest.Options {
1652- Logger :& logger ,
1653- })
1654- user := coderdtest .CreateFirstUser (t ,client )
1655- r := dbfake .WorkspaceBuild (t ,db , database.WorkspaceTable {
1656- OrganizationID :user .OrganizationID ,
1657- OwnerID :user .UserID ,
1658- }).WithAgent (func (agents []* proto.Agent ) []* proto.Agent {
1659- return agents
1660- }).Do ()
1638+ var (
1639+ ctx = testutil .Context (t ,testutil .WaitLong )
1640+ mCtrl = gomock .NewController (t )
1641+ mCCLI = acmock .NewMockContainerCLI (mCtrl )
1642+ mDCCLI = acmock .NewMockDevcontainerCLI (mCtrl )
1643+ logger = slogtest .Make (t ,& slogtest.Options {IgnoreErrors :true }).Leveled (slog .LevelDebug )
1644+ client ,db = coderdtest .NewWithDatabase (t ,& coderdtest.Options {
1645+ Logger :& logger ,
1646+ })
1647+ user = coderdtest .CreateFirstUser (t ,client )
1648+ r = dbfake .WorkspaceBuild (t ,db , database.WorkspaceTable {
1649+ OrganizationID :user .OrganizationID ,
1650+ OwnerID :user .UserID ,
1651+ }).WithAgent (func (agents []* proto.Agent ) []* proto.Agent {
1652+ return agents
1653+ }).Do ()
1654+ )
1655+
1656+ mCCLI .EXPECT ().List (gomock .Any ()).Return (codersdk.WorkspaceAgentListContainersResponse {
1657+ Containers :tc .containers ,
1658+ },nil ).AnyTimes ()
1659+
1660+ var upCalled chan struct {}
1661+
1662+ if tc .expectRecreate {
1663+ upCalled = make (chan struct {})
1664+
1665+ // DetectArchitecture always returns "<none>" for this test to disable agent injection.
1666+ mCCLI .EXPECT ().DetectArchitecture (gomock .Any (),devContainer .ID ).Return ("<none>" ,nil ).AnyTimes ()
1667+ mDCCLI .EXPECT ().ReadConfig (gomock .Any (),workspaceFolder ,configFile ,gomock .Any ()).Return (agentcontainers.DevcontainerConfig {},nil ).AnyTimes ()
1668+ mDCCLI .EXPECT ().Up (gomock .Any (),workspaceFolder ,configFile ,gomock .Any ()).
1669+ DoAndReturn (func (_ context.Context ,_ ,_ string ,_ ... agentcontainers.DevcontainerCLIUpOptions ) (string ,error ) {
1670+ close (upCalled )
1671+
1672+ return "someid" ,nil
1673+ }).Times (1 )
1674+ }
16611675
16621676devcontainerAPIOptions := []agentcontainers.Option {
1663- agentcontainers .WithContainerCLI (mccli ),
1664- agentcontainers .WithDevcontainerCLI (mdccli ),
1677+ agentcontainers .WithContainerCLI (mCCLI ),
1678+ agentcontainers .WithDevcontainerCLI (mDCCLI ),
16651679agentcontainers .WithWatcher (watcher .NewNoop ()),
16661680}
1667- if tc .setupDevcontainers != nil {
1681+ if tc .devcontainers != nil {
16681682devcontainerAPIOptions = append (devcontainerAPIOptions ,
1669- agentcontainers .WithDevcontainers (tc .setupDevcontainers ,nil ))
1683+ agentcontainers .WithDevcontainers (tc .devcontainers ,nil ))
16701684}
16711685
16721686_ = agenttest .New (t ,client .URL ,r .AgentToken ,func (o * agent.Options ) {
@@ -1679,15 +1693,14 @@ func TestWorkspaceAgentRecreateDevcontainer(t *testing.T) {
16791693require .Len (t ,resources [0 ].Agents ,1 ,"expected one agent" )
16801694agentID := resources [0 ].Agents [0 ].ID
16811695
1682- ctx := testutil .Context (t ,testutil .WaitLong )
1683-
16841696_ ,err := client .WorkspaceAgentRecreateDevcontainer (ctx ,agentID ,tc .devcontainerID )
1685- if wantStatus > 0 {
1697+ if tc . expectErrorCode > 0 {
16861698cerr ,ok := codersdk .AsError (err )
16871699require .True (t ,ok ,"expected error to be a coder error" )
1688- assert .Equal (t ,wantStatus ,cerr .StatusCode ())
1700+ assert .Equal (t ,tc . expectErrorCode ,cerr .StatusCode ())
16891701}else {
16901702require .NoError (t ,err ,"failed to recreate devcontainer" )
1703+ testutil .TryReceive (ctx ,t ,upCalled )
16911704}
16921705})
16931706}