@@ -26,6 +26,7 @@ import (
26
26
"github.com/coder/coder/v2/agent/agentcontainers"
27
27
"github.com/coder/coder/v2/agent/agentcontainers/acmock"
28
28
"github.com/coder/coder/v2/agent/agentcontainers/watcher"
29
+ "github.com/coder/coder/v2/coderd/util/ptr"
29
30
"github.com/coder/coder/v2/codersdk"
30
31
"github.com/coder/coder/v2/testutil"
31
32
"github.com/coder/quartz"
@@ -68,7 +69,7 @@ type fakeDevcontainerCLI struct {
68
69
execErrC chan func (cmd string , args ... string ) error // If set, send fn to return err, nil or close to return execErr.
69
70
readConfig agentcontainers.DevcontainerConfig
70
71
readConfigErr error
71
- readConfigErrC chan error
72
+ readConfigErrC chan func ( envs [] string ) (agentcontainers. DevcontainerConfig , error )
72
73
}
73
74
74
75
func (f * fakeDevcontainerCLI ) Up (ctx context.Context , _ , _ string , _ ... agentcontainers.DevcontainerCLIUpOptions ) (string , error ) {
@@ -99,14 +100,14 @@ func (f *fakeDevcontainerCLI) Exec(ctx context.Context, _, _ string, cmd string,
99
100
return f .execErr
100
101
}
101
102
102
- func (f * fakeDevcontainerCLI ) ReadConfig (ctx context.Context , _ , _ string , _ ... agentcontainers.DevcontainerCLIReadConfigOptions ) (agentcontainers.DevcontainerConfig , error ) {
103
+ func (f * fakeDevcontainerCLI ) ReadConfig (ctx context.Context , _ , _ string , envs [] string , _ ... agentcontainers.DevcontainerCLIReadConfigOptions ) (agentcontainers.DevcontainerConfig , error ) {
103
104
if f .readConfigErrC != nil {
104
105
select {
105
106
case <- ctx .Done ():
106
107
return agentcontainers.DevcontainerConfig {}, ctx .Err ()
107
- case err , ok := <- f .readConfigErrC :
108
+ case fn , ok := <- f .readConfigErrC :
108
109
if ok {
109
- return f . readConfig , err
110
+ return fn ( envs )
110
111
}
111
112
}
112
113
}
@@ -1253,7 +1254,8 @@ func TestAPI(t *testing.T) {
1253
1254
deleteErrC : make (chan error , 1 ),
1254
1255
}
1255
1256
fakeDCCLI = & fakeDevcontainerCLI {
1256
- execErrC : make (chan func (cmd string , args ... string ) error , 1 ),
1257
+ execErrC : make (chan func (cmd string , args ... string ) error , 1 ),
1258
+ readConfigErrC : make (chan func (envs []string ) (agentcontainers.DevcontainerConfig , error ), 1 ),
1257
1259
}
1258
1260
1259
1261
testContainer = codersdk.WorkspaceAgentContainer {
@@ -1293,13 +1295,16 @@ func TestAPI(t *testing.T) {
1293
1295
agentcontainers .WithSubAgentClient (fakeSAC ),
1294
1296
agentcontainers .WithSubAgentURL ("test-subagent-url" ),
1295
1297
agentcontainers .WithDevcontainerCLI (fakeDCCLI ),
1298
+ agentcontainers .WithUserName ("test-user" ),
1299
+ agentcontainers .WithWorkspaceName ("test-workspace" ),
1296
1300
)
1297
1301
apiClose := func () {
1298
1302
closeOnce .Do (func () {
1299
1303
// Close before api.Close() defer to avoid deadlock after test.
1300
1304
close (fakeSAC .createErrC )
1301
1305
close (fakeSAC .deleteErrC )
1302
1306
close (fakeDCCLI .execErrC )
1307
+ defer close (fakeDCCLI .readConfigErrC )
1303
1308
1304
1309
_ = api .Close ()
1305
1310
})
@@ -1313,6 +1318,13 @@ func TestAPI(t *testing.T) {
1313
1318
assert .Empty (t , args )
1314
1319
return nil
1315
1320
}) // Exec pwd.
1321
+ testutil .RequireSend (ctx , t , fakeDCCLI .readConfigErrC , func (envs []string ) (agentcontainers.DevcontainerConfig , error ) {
1322
+ assert .Contains (t , envs , "CODER_AGENT_NAME=test-container" )
1323
+ assert .Contains (t , envs , "CODER_WORKSPACE_NAME=test-workspace" )
1324
+ assert .Contains (t , envs , "CODER_USER_NAME=test-user" )
1325
+ assert .Contains (t , envs , "CODER_DEPLOYMENT_URL=test-subagent-url" )
1326
+ return agentcontainers.DevcontainerConfig {}, nil
1327
+ })
1316
1328
1317
1329
// Make sure the ticker function has been registered
1318
1330
// before advancing the clock.
@@ -1453,6 +1465,13 @@ func TestAPI(t *testing.T) {
1453
1465
assert .Empty (t , args )
1454
1466
return nil
1455
1467
}) // Exec pwd.
1468
+ testutil .RequireSend (ctx , t , fakeDCCLI .readConfigErrC , func (envs []string ) (agentcontainers.DevcontainerConfig , error ) {
1469
+ assert .Contains (t , envs , "CODER_AGENT_NAME=test-container" )
1470
+ assert .Contains (t , envs , "CODER_WORKSPACE_NAME=test-workspace" )
1471
+ assert .Contains (t , envs , "CODER_USER_NAME=test-user" )
1472
+ assert .Contains (t , envs , "CODER_DEPLOYMENT_URL=test-subagent-url" )
1473
+ return agentcontainers.DevcontainerConfig {}, nil
1474
+ })
1456
1475
1457
1476
err = api .RefreshContainers (ctx )
1458
1477
require .NoError (t , err , "refresh containers should not fail" )
@@ -1603,6 +1622,74 @@ func TestAPI(t *testing.T) {
1603
1622
assert .Contains (t , subAgent .DisplayApps , codersdk .DisplayAppPortForward )
1604
1623
},
1605
1624
},
1625
+ {
1626
+ name : "WithApps" ,
1627
+ customization : []agentcontainers.CoderCustomization {
1628
+ {
1629
+ Apps : []agentcontainers.SubAgentApp {
1630
+ {
1631
+ Slug : "web-app" ,
1632
+ DisplayName : ptr .Ref ("Web Application" ),
1633
+ URL : ptr .Ref ("http://localhost:8080" ),
1634
+ OpenIn : codersdk .WorkspaceAppOpenInTab ,
1635
+ Share : codersdk .WorkspaceAppSharingLevelOwner ,
1636
+ Icon : ptr .Ref ("/icons/web.svg" ),
1637
+ Order : ptr .Ref (int32 (1 )),
1638
+ },
1639
+ {
1640
+ Slug : "api-server" ,
1641
+ DisplayName : ptr .Ref ("API Server" ),
1642
+ URL : ptr .Ref ("http://localhost:3000" ),
1643
+ OpenIn : codersdk .WorkspaceAppOpenInSlimWindow ,
1644
+ Share : codersdk .WorkspaceAppSharingLevelAuthenticated ,
1645
+ Icon : ptr .Ref ("/icons/api.svg" ),
1646
+ Order : ptr .Ref (int32 (2 )),
1647
+ Hidden : ptr .Ref (true ),
1648
+ },
1649
+ {
1650
+ Slug : "docs" ,
1651
+ DisplayName : ptr .Ref ("Documentation" ),
1652
+ URL : ptr .Ref ("http://localhost:4000" ),
1653
+ OpenIn : codersdk .WorkspaceAppOpenInTab ,
1654
+ Share : codersdk .WorkspaceAppSharingLevelPublic ,
1655
+ Icon : ptr .Ref ("/icons/book.svg" ),
1656
+ Order : ptr .Ref (int32 (3 )),
1657
+ },
1658
+ },
1659
+ },
1660
+ },
1661
+ afterCreate : func (t * testing.T , subAgent agentcontainers.SubAgent ) {
1662
+ require .Len (t , subAgent .Apps , 3 )
1663
+
1664
+ // Verify first app
1665
+ assert .Equal (t , "web-app" , subAgent .Apps [0 ].Slug )
1666
+ assert .Equal (t , "Web Application" , * subAgent .Apps [0 ].DisplayName )
1667
+ assert .Equal (t , "http://localhost:8080" , * subAgent .Apps [0 ].URL )
1668
+ assert .Equal (t , codersdk .WorkspaceAppOpenInTab , subAgent .Apps [0 ].OpenIn )
1669
+ assert .Equal (t , codersdk .WorkspaceAppSharingLevelOwner , subAgent .Apps [0 ].Share )
1670
+ assert .Equal (t , "/icons/web.svg" , * subAgent .Apps [0 ].Icon )
1671
+ assert .Equal (t , int32 (1 ), * subAgent .Apps [0 ].Order )
1672
+
1673
+ // Verify second app
1674
+ assert .Equal (t , "api-server" , subAgent .Apps [1 ].Slug )
1675
+ assert .Equal (t , "API Server" , * subAgent .Apps [1 ].DisplayName )
1676
+ assert .Equal (t , "http://localhost:3000" , * subAgent .Apps [1 ].URL )
1677
+ assert .Equal (t , codersdk .WorkspaceAppOpenInSlimWindow , subAgent .Apps [1 ].OpenIn )
1678
+ assert .Equal (t , codersdk .WorkspaceAppSharingLevelAuthenticated , subAgent .Apps [1 ].Share )
1679
+ assert .Equal (t , "/icons/api.svg" , * subAgent .Apps [1 ].Icon )
1680
+ assert .Equal (t , int32 (2 ), * subAgent .Apps [1 ].Order )
1681
+ assert .Equal (t , true , * subAgent .Apps [1 ].Hidden )
1682
+
1683
+ // Verify third app
1684
+ assert .Equal (t , "docs" , subAgent .Apps [2 ].Slug )
1685
+ assert .Equal (t , "Documentation" , * subAgent .Apps [2 ].DisplayName )
1686
+ assert .Equal (t , "http://localhost:4000" , * subAgent .Apps [2 ].URL )
1687
+ assert .Equal (t , codersdk .WorkspaceAppOpenInTab , subAgent .Apps [2 ].OpenIn )
1688
+ assert .Equal (t , codersdk .WorkspaceAppSharingLevelPublic , subAgent .Apps [2 ].Share )
1689
+ assert .Equal (t , "/icons/book.svg" , * subAgent .Apps [2 ].Icon )
1690
+ assert .Equal (t , int32 (3 ), * subAgent .Apps [2 ].Order )
1691
+ },
1692
+ },
1606
1693
}
1607
1694
1608
1695
for _ , tt := range tests {
0 commit comments