@@ -25,6 +25,7 @@ import (
25
25
"github.com/coder/coder/v2/agent/agentcontainers"
26
26
"github.com/coder/coder/v2/agent/agentcontainers/acmock"
27
27
"github.com/coder/coder/v2/agent/agentcontainers/watcher"
28
+ "github.com/coder/coder/v2/coderd/util/ptr"
28
29
"github.com/coder/coder/v2/codersdk"
29
30
"github.com/coder/coder/v2/testutil"
30
31
"github.com/coder/quartz"
@@ -67,7 +68,7 @@ type fakeDevcontainerCLI struct {
67
68
execErrC chan func (cmd string , args ... string ) error // If set, send fn to return err, nil or close to return execErr.
68
69
readConfig agentcontainers.DevcontainerConfig
69
70
readConfigErr error
70
- readConfigErrC chan error
71
+ readConfigErrC chan func ( envs [] string ) (agentcontainers. DevcontainerConfig , error )
71
72
}
72
73
73
74
func (f * fakeDevcontainerCLI ) Up (ctx context.Context , _ , _ string , _ ... agentcontainers.DevcontainerCLIUpOptions ) (string , error ) {
@@ -98,14 +99,14 @@ func (f *fakeDevcontainerCLI) Exec(ctx context.Context, _, _ string, cmd string,
98
99
return f .execErr
99
100
}
100
101
101
- func (f * fakeDevcontainerCLI ) ReadConfig (ctx context.Context , _ , _ string , _ ... agentcontainers.DevcontainerCLIReadConfigOptions ) (agentcontainers.DevcontainerConfig , error ) {
102
+ func (f * fakeDevcontainerCLI ) ReadConfig (ctx context.Context , _ , _ string , envs [] string , _ ... agentcontainers.DevcontainerCLIReadConfigOptions ) (agentcontainers.DevcontainerConfig , error ) {
102
103
if f .readConfigErrC != nil {
103
104
select {
104
105
case <- ctx .Done ():
105
106
return agentcontainers.DevcontainerConfig {}, ctx .Err ()
106
- case err , ok := <- f .readConfigErrC :
107
+ case fn , ok := <- f .readConfigErrC :
107
108
if ok {
108
- return f . readConfig , err
109
+ return fn ( envs )
109
110
}
110
111
}
111
112
}
@@ -1268,7 +1269,8 @@ func TestAPI(t *testing.T) {
1268
1269
deleteErrC : make (chan error , 1 ),
1269
1270
}
1270
1271
fakeDCCLI = & fakeDevcontainerCLI {
1271
- execErrC : make (chan func (cmd string , args ... string ) error , 1 ),
1272
+ execErrC : make (chan func (cmd string , args ... string ) error , 1 ),
1273
+ readConfigErrC : make (chan func (envs []string ) (agentcontainers.DevcontainerConfig , error ), 1 ),
1272
1274
}
1273
1275
1274
1276
testContainer = codersdk.WorkspaceAgentContainer {
@@ -1307,13 +1309,16 @@ func TestAPI(t *testing.T) {
1307
1309
agentcontainers .WithSubAgentClient (fakeSAC ),
1308
1310
agentcontainers .WithSubAgentURL ("test-subagent-url" ),
1309
1311
agentcontainers .WithDevcontainerCLI (fakeDCCLI ),
1312
+ agentcontainers .WithUserName ("test-user" ),
1313
+ agentcontainers .WithWorkspaceName ("test-workspace" ),
1310
1314
)
1311
1315
defer api .Close ()
1312
1316
1313
1317
// Close before api.Close() defer to avoid deadlock after test.
1314
1318
defer close (fakeSAC .createErrC )
1315
1319
defer close (fakeSAC .deleteErrC )
1316
1320
defer close (fakeDCCLI .execErrC )
1321
+ defer close (fakeDCCLI .readConfigErrC )
1317
1322
1318
1323
// Allow initial agent creation and injection to succeed.
1319
1324
testutil .RequireSend (ctx , t , fakeSAC .createErrC , nil )
@@ -1322,6 +1327,13 @@ func TestAPI(t *testing.T) {
1322
1327
assert .Empty (t , args )
1323
1328
return nil
1324
1329
}) // Exec pwd.
1330
+ testutil .RequireSend (ctx , t , fakeDCCLI .readConfigErrC , func (envs []string ) (agentcontainers.DevcontainerConfig , error ) {
1331
+ assert .Contains (t , envs , "CODER_AGENT_NAME=test-container" )
1332
+ assert .Contains (t , envs , "CODER_WORKSPACE_NAME=test-workspace" )
1333
+ assert .Contains (t , envs , "CODER_USER_NAME=test-user" )
1334
+ assert .Contains (t , envs , "CODER_DEPLOYMENT_URL=test-subagent-url" )
1335
+ return agentcontainers.DevcontainerConfig {}, nil
1336
+ })
1325
1337
1326
1338
// Make sure the ticker function has been registered
1327
1339
// before advancing the clock.
@@ -1374,6 +1386,13 @@ func TestAPI(t *testing.T) {
1374
1386
assert .Empty (t , args )
1375
1387
return nil
1376
1388
}) // Exec pwd.
1389
+ testutil .RequireSend (ctx , t , fakeDCCLI .readConfigErrC , func (envs []string ) (agentcontainers.DevcontainerConfig , error ) {
1390
+ assert .Contains (t , envs , "CODER_AGENT_NAME=test-container" )
1391
+ assert .Contains (t , envs , "CODER_WORKSPACE_NAME=test-workspace" )
1392
+ assert .Contains (t , envs , "CODER_USER_NAME=test-user" )
1393
+ assert .Contains (t , envs , "CODER_DEPLOYMENT_URL=test-subagent-url" )
1394
+ return agentcontainers.DevcontainerConfig {}, nil
1395
+ })
1377
1396
1378
1397
// Wait until the agent recreation is started.
1379
1398
for len (fakeSAC .createErrC ) > 0 {
@@ -1473,6 +1492,72 @@ func TestAPI(t *testing.T) {
1473
1492
assert .Equal (t , codersdk .DisplayAppVSCodeInsiders , subAgent .DisplayApps [2 ])
1474
1493
},
1475
1494
},
1495
+ {
1496
+ name : "WithApps" ,
1497
+ customization : & agentcontainers.CoderCustomization {
1498
+ Apps : []agentcontainers.SubAgentApp {
1499
+ {
1500
+ Slug : "web-app" ,
1501
+ DisplayName : ptr .Ref ("Web Application" ),
1502
+ URL : ptr .Ref ("http://localhost:8080" ),
1503
+ OpenIn : codersdk .WorkspaceAppOpenInTab ,
1504
+ Share : codersdk .WorkspaceAppSharingLevelOwner ,
1505
+ Icon : ptr .Ref ("/icons/web.svg" ),
1506
+ Order : ptr .Ref (int32 (1 )),
1507
+ },
1508
+ {
1509
+ Slug : "api-server" ,
1510
+ DisplayName : ptr .Ref ("API Server" ),
1511
+ URL : ptr .Ref ("http://localhost:3000" ),
1512
+ OpenIn : codersdk .WorkspaceAppOpenInSlimWindow ,
1513
+ Share : codersdk .WorkspaceAppSharingLevelAuthenticated ,
1514
+ Icon : ptr .Ref ("/icons/api.svg" ),
1515
+ Order : ptr .Ref (int32 (2 )),
1516
+ Hidden : ptr .Ref (true ),
1517
+ },
1518
+ {
1519
+ Slug : "docs" ,
1520
+ DisplayName : ptr .Ref ("Documentation" ),
1521
+ URL : ptr .Ref ("http://localhost:4000" ),
1522
+ OpenIn : codersdk .WorkspaceAppOpenInTab ,
1523
+ Share : codersdk .WorkspaceAppSharingLevelPublic ,
1524
+ Icon : ptr .Ref ("/icons/book.svg" ),
1525
+ Order : ptr .Ref (int32 (3 )),
1526
+ },
1527
+ },
1528
+ },
1529
+ afterCreate : func (t * testing.T , subAgent agentcontainers.SubAgent ) {
1530
+ require .Len (t , subAgent .Apps , 3 )
1531
+
1532
+ // Verify first app
1533
+ assert .Equal (t , "web-app" , subAgent .Apps [0 ].Slug )
1534
+ assert .Equal (t , "Web Application" , * subAgent .Apps [0 ].DisplayName )
1535
+ assert .Equal (t , "http://localhost:8080" , * subAgent .Apps [0 ].URL )
1536
+ assert .Equal (t , codersdk .WorkspaceAppOpenInTab , subAgent .Apps [0 ].OpenIn )
1537
+ assert .Equal (t , codersdk .WorkspaceAppSharingLevelOwner , subAgent .Apps [0 ].Share )
1538
+ assert .Equal (t , "/icons/web.svg" , * subAgent .Apps [0 ].Icon )
1539
+ assert .Equal (t , int32 (1 ), * subAgent .Apps [0 ].Order )
1540
+
1541
+ // Verify second app
1542
+ assert .Equal (t , "api-server" , subAgent .Apps [1 ].Slug )
1543
+ assert .Equal (t , "API Server" , * subAgent .Apps [1 ].DisplayName )
1544
+ assert .Equal (t , "http://localhost:3000" , * subAgent .Apps [1 ].URL )
1545
+ assert .Equal (t , codersdk .WorkspaceAppOpenInSlimWindow , subAgent .Apps [1 ].OpenIn )
1546
+ assert .Equal (t , codersdk .WorkspaceAppSharingLevelAuthenticated , subAgent .Apps [1 ].Share )
1547
+ assert .Equal (t , "/icons/api.svg" , * subAgent .Apps [1 ].Icon )
1548
+ assert .Equal (t , int32 (2 ), * subAgent .Apps [1 ].Order )
1549
+ assert .Equal (t , true , * subAgent .Apps [1 ].Hidden )
1550
+
1551
+ // Verify third app
1552
+ assert .Equal (t , "docs" , subAgent .Apps [2 ].Slug )
1553
+ assert .Equal (t , "Documentation" , * subAgent .Apps [2 ].DisplayName )
1554
+ assert .Equal (t , "http://localhost:4000" , * subAgent .Apps [2 ].URL )
1555
+ assert .Equal (t , codersdk .WorkspaceAppOpenInTab , subAgent .Apps [2 ].OpenIn )
1556
+ assert .Equal (t , codersdk .WorkspaceAppSharingLevelPublic , subAgent .Apps [2 ].Share )
1557
+ assert .Equal (t , "/icons/book.svg" , * subAgent .Apps [2 ].Icon )
1558
+ assert .Equal (t , int32 (3 ), * subAgent .Apps [2 ].Order )
1559
+ },
1560
+ },
1476
1561
}
1477
1562
1478
1563
for _ , tt := range tests {
0 commit comments