@@ -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
}
@@ -1249,7 +1250,8 @@ func TestAPI(t *testing.T) {
1249
1250
deleteErrC : make (chan error , 1 ),
1250
1251
}
1251
1252
fakeDCCLI = & fakeDevcontainerCLI {
1252
- execErrC : make (chan func (cmd string , args ... string ) error , 1 ),
1253
+ execErrC : make (chan func (cmd string , args ... string ) error , 1 ),
1254
+ readConfigErrC : make (chan func (envs []string ) (agentcontainers.DevcontainerConfig , error ), 1 ),
1253
1255
}
1254
1256
1255
1257
testContainer = codersdk.WorkspaceAgentContainer {
@@ -1289,13 +1291,16 @@ func TestAPI(t *testing.T) {
1289
1291
agentcontainers .WithSubAgentClient (fakeSAC ),
1290
1292
agentcontainers .WithSubAgentURL ("test-subagent-url" ),
1291
1293
agentcontainers .WithDevcontainerCLI (fakeDCCLI ),
1294
+ agentcontainers .WithUserName ("test-user" ),
1295
+ agentcontainers .WithWorkspaceName ("test-workspace" ),
1292
1296
)
1293
1297
apiClose := func () {
1294
1298
closeOnce .Do (func () {
1295
1299
// Close before api.Close() defer to avoid deadlock after test.
1296
1300
close (fakeSAC .createErrC )
1297
1301
close (fakeSAC .deleteErrC )
1298
1302
close (fakeDCCLI .execErrC )
1303
+ defer close (fakeDCCLI .readConfigErrC )
1299
1304
1300
1305
_ = api .Close ()
1301
1306
})
@@ -1309,6 +1314,13 @@ func TestAPI(t *testing.T) {
1309
1314
assert .Empty (t , args )
1310
1315
return nil
1311
1316
}) // Exec pwd.
1317
+ testutil .RequireSend (ctx , t , fakeDCCLI .readConfigErrC , func (envs []string ) (agentcontainers.DevcontainerConfig , error ) {
1318
+ assert .Contains (t , envs , "CODER_AGENT_NAME=test-container" )
1319
+ assert .Contains (t , envs , "CODER_WORKSPACE_NAME=test-workspace" )
1320
+ assert .Contains (t , envs , "CODER_USER_NAME=test-user" )
1321
+ assert .Contains (t , envs , "CODER_DEPLOYMENT_URL=test-subagent-url" )
1322
+ return agentcontainers.DevcontainerConfig {}, nil
1323
+ })
1312
1324
1313
1325
// Make sure the ticker function has been registered
1314
1326
// before advancing the clock.
@@ -1413,6 +1425,13 @@ func TestAPI(t *testing.T) {
1413
1425
assert .Empty (t , args )
1414
1426
return nil
1415
1427
}) // Exec pwd.
1428
+ testutil .RequireSend (ctx , t , fakeDCCLI .readConfigErrC , func (envs []string ) (agentcontainers.DevcontainerConfig , error ) {
1429
+ assert .Contains (t , envs , "CODER_AGENT_NAME=test-container" )
1430
+ assert .Contains (t , envs , "CODER_WORKSPACE_NAME=test-workspace" )
1431
+ assert .Contains (t , envs , "CODER_USER_NAME=test-user" )
1432
+ assert .Contains (t , envs , "CODER_DEPLOYMENT_URL=test-subagent-url" )
1433
+ return agentcontainers.DevcontainerConfig {}, nil
1434
+ })
1416
1435
1417
1436
// Advance the clock to run updaterLoop.
1418
1437
for i := range 3 {
@@ -1566,6 +1585,74 @@ func TestAPI(t *testing.T) {
1566
1585
assert .Contains (t , subAgent .DisplayApps , codersdk .DisplayAppPortForward )
1567
1586
},
1568
1587
},
1588
+ {
1589
+ name : "WithApps" ,
1590
+ customization : []agentcontainers.CoderCustomization {
1591
+ {
1592
+ Apps : []agentcontainers.SubAgentApp {
1593
+ {
1594
+ Slug : "web-app" ,
1595
+ DisplayName : ptr .Ref ("Web Application" ),
1596
+ URL : ptr .Ref ("http://localhost:8080" ),
1597
+ OpenIn : codersdk .WorkspaceAppOpenInTab ,
1598
+ Share : codersdk .WorkspaceAppSharingLevelOwner ,
1599
+ Icon : ptr .Ref ("/icons/web.svg" ),
1600
+ Order : ptr .Ref (int32 (1 )),
1601
+ },
1602
+ {
1603
+ Slug : "api-server" ,
1604
+ DisplayName : ptr .Ref ("API Server" ),
1605
+ URL : ptr .Ref ("http://localhost:3000" ),
1606
+ OpenIn : codersdk .WorkspaceAppOpenInSlimWindow ,
1607
+ Share : codersdk .WorkspaceAppSharingLevelAuthenticated ,
1608
+ Icon : ptr .Ref ("/icons/api.svg" ),
1609
+ Order : ptr .Ref (int32 (2 )),
1610
+ Hidden : ptr .Ref (true ),
1611
+ },
1612
+ {
1613
+ Slug : "docs" ,
1614
+ DisplayName : ptr .Ref ("Documentation" ),
1615
+ URL : ptr .Ref ("http://localhost:4000" ),
1616
+ OpenIn : codersdk .WorkspaceAppOpenInTab ,
1617
+ Share : codersdk .WorkspaceAppSharingLevelPublic ,
1618
+ Icon : ptr .Ref ("/icons/book.svg" ),
1619
+ Order : ptr .Ref (int32 (3 )),
1620
+ },
1621
+ },
1622
+ },
1623
+ },
1624
+ afterCreate : func (t * testing.T , subAgent agentcontainers.SubAgent ) {
1625
+ require .Len (t , subAgent .Apps , 3 )
1626
+
1627
+ // Verify first app
1628
+ assert .Equal (t , "web-app" , subAgent .Apps [0 ].Slug )
1629
+ assert .Equal (t , "Web Application" , * subAgent .Apps [0 ].DisplayName )
1630
+ assert .Equal (t , "http://localhost:8080" , * subAgent .Apps [0 ].URL )
1631
+ assert .Equal (t , codersdk .WorkspaceAppOpenInTab , subAgent .Apps [0 ].OpenIn )
1632
+ assert .Equal (t , codersdk .WorkspaceAppSharingLevelOwner , subAgent .Apps [0 ].Share )
1633
+ assert .Equal (t , "/icons/web.svg" , * subAgent .Apps [0 ].Icon )
1634
+ assert .Equal (t , int32 (1 ), * subAgent .Apps [0 ].Order )
1635
+
1636
+ // Verify second app
1637
+ assert .Equal (t , "api-server" , subAgent .Apps [1 ].Slug )
1638
+ assert .Equal (t , "API Server" , * subAgent .Apps [1 ].DisplayName )
1639
+ assert .Equal (t , "http://localhost:3000" , * subAgent .Apps [1 ].URL )
1640
+ assert .Equal (t , codersdk .WorkspaceAppOpenInSlimWindow , subAgent .Apps [1 ].OpenIn )
1641
+ assert .Equal (t , codersdk .WorkspaceAppSharingLevelAuthenticated , subAgent .Apps [1 ].Share )
1642
+ assert .Equal (t , "/icons/api.svg" , * subAgent .Apps [1 ].Icon )
1643
+ assert .Equal (t , int32 (2 ), * subAgent .Apps [1 ].Order )
1644
+ assert .Equal (t , true , * subAgent .Apps [1 ].Hidden )
1645
+
1646
+ // Verify third app
1647
+ assert .Equal (t , "docs" , subAgent .Apps [2 ].Slug )
1648
+ assert .Equal (t , "Documentation" , * subAgent .Apps [2 ].DisplayName )
1649
+ assert .Equal (t , "http://localhost:4000" , * subAgent .Apps [2 ].URL )
1650
+ assert .Equal (t , codersdk .WorkspaceAppOpenInTab , subAgent .Apps [2 ].OpenIn )
1651
+ assert .Equal (t , codersdk .WorkspaceAppSharingLevelPublic , subAgent .Apps [2 ].Share )
1652
+ assert .Equal (t , "/icons/book.svg" , * subAgent .Apps [2 ].Icon )
1653
+ assert .Equal (t , int32 (3 ), * subAgent .Apps [2 ].Order )
1654
+ },
1655
+ },
1569
1656
}
1570
1657
1571
1658
for _ , tt := range tests {
0 commit comments