@@ -3,6 +3,7 @@ package agentcontainers
3
3
import (
4
4
"fmt"
5
5
"os"
6
+ "path/filepath"
6
7
"slices"
7
8
"strconv"
8
9
"strings"
@@ -11,6 +12,7 @@ import (
11
12
12
13
"go.uber.org/mock/gomock"
13
14
15
+ "github.com/google/go-cmp/cmp"
14
16
"github.com/google/uuid"
15
17
"github.com/ory/dockertest/v3"
16
18
"github.com/ory/dockertest/v3/docker"
@@ -412,6 +414,216 @@ func TestConvertDockerVolume(t *testing.T) {
412
414
}
413
415
}
414
416
417
+ // TestConvertDockerInspect tests the convertDockerInspect function using
418
+ // fixtures from ./testdata.
419
+ func TestConvertDockerInspect (t * testing.T ) {
420
+ t .Parallel ()
421
+
422
+ for _ , tt := range []struct {
423
+ name string
424
+ expect []codersdk.WorkspaceAgentDevcontainer
425
+ expectWarns []string
426
+ expectError string
427
+ }{
428
+ {
429
+ name : "container_simple" ,
430
+ expect : []codersdk.WorkspaceAgentDevcontainer {
431
+ {
432
+ CreatedAt : time .Date (2025 , 3 , 11 , 17 , 55 , 58 , 91280203 , time .UTC ),
433
+ ID : "6b539b8c60f5230b8b0fde2502cd2332d31c0d526a3e6eb6eef1cc39439b3286" ,
434
+ FriendlyName : "eloquent_kowalevski" ,
435
+ Image : "debian:bookworm" ,
436
+ Labels : map [string ]string {},
437
+ Running : true ,
438
+ Status : "running" ,
439
+ Ports : []codersdk.WorkspaceAgentListeningPort {},
440
+ Volumes : map [string ]string {},
441
+ },
442
+ },
443
+ },
444
+ {
445
+ name : "container_labels" ,
446
+ expect : []codersdk.WorkspaceAgentDevcontainer {
447
+ {
448
+ CreatedAt : time .Date (2025 , 3 , 11 , 20 , 3 , 28 , 71706536 , time .UTC ),
449
+ ID : "bd8818e670230fc6f36145b21cf8d6d35580355662aa4d9fe5ae1b188a4c905f" ,
450
+ FriendlyName : "fervent_bardeen" ,
451
+ Image : "debian:bookworm" ,
452
+ Labels : map [string ]string {"baz" : "zap" , "foo" : "bar" },
453
+ Running : true ,
454
+ Status : "running" ,
455
+ Ports : []codersdk.WorkspaceAgentListeningPort {},
456
+ Volumes : map [string ]string {},
457
+ },
458
+ },
459
+ },
460
+ {
461
+ name : "container_binds" ,
462
+ expect : []codersdk.WorkspaceAgentDevcontainer {
463
+ {
464
+ CreatedAt : time .Date (2025 , 3 , 11 , 17 , 58 , 43 , 522505027 , time .UTC ),
465
+ ID : "fdc75ebefdc0243c0fce959e7685931691ac7aede278664a0e2c23af8a1e8d6a" ,
466
+ FriendlyName : "silly_beaver" ,
467
+ Image : "debian:bookworm" ,
468
+ Labels : map [string ]string {},
469
+ Running : true ,
470
+ Status : "running" ,
471
+ Ports : []codersdk.WorkspaceAgentListeningPort {},
472
+ Volumes : map [string ]string {
473
+ "/tmp/test/a" : "/var/coder/a" ,
474
+ "/tmp/test/b" : "/var/coder/b" ,
475
+ },
476
+ },
477
+ },
478
+ },
479
+ {
480
+ name : "container_sameport" ,
481
+ expect : []codersdk.WorkspaceAgentDevcontainer {
482
+ {
483
+ CreatedAt : time .Date (2025 , 3 , 11 , 17 , 56 , 34 , 842164541 , time .UTC ),
484
+ ID : "4eac5ce199d27b2329d0ff0ce1a6fc595612ced48eba3669aadb6c57ebef3fa2" ,
485
+ FriendlyName : "modest_varahamihira" ,
486
+ Image : "debian:bookworm" ,
487
+ Labels : map [string ]string {},
488
+ Running : true ,
489
+ Status : "running" ,
490
+ Ports : []codersdk.WorkspaceAgentListeningPort {
491
+ {
492
+ Network : "tcp" ,
493
+ Port : 12345 ,
494
+ },
495
+ },
496
+ Volumes : map [string ]string {},
497
+ },
498
+ },
499
+ },
500
+ {
501
+ name : "container_differentport" ,
502
+ expect : []codersdk.WorkspaceAgentDevcontainer {
503
+ {
504
+ CreatedAt : time .Date (2025 , 3 , 11 , 17 , 57 , 8 , 862545133 , time .UTC ),
505
+ ID : "3090de8b72b1224758a94a11b827c82ba2b09c45524f1263dc4a2d83e19625ea" ,
506
+ FriendlyName : "boring_ellis" ,
507
+ Image : "debian:bookworm" ,
508
+ Labels : map [string ]string {},
509
+ Running : true ,
510
+ Status : "running" ,
511
+ Ports : []codersdk.WorkspaceAgentListeningPort {
512
+ {
513
+ Network : "tcp" ,
514
+ Port : 23456 ,
515
+ },
516
+ },
517
+ Volumes : map [string ]string {},
518
+ },
519
+ },
520
+ },
521
+ {
522
+ name : "container_volume" ,
523
+ expect : []codersdk.WorkspaceAgentDevcontainer {
524
+ {
525
+ CreatedAt : time .Date (2025 , 3 , 11 , 17 , 59 , 42 , 39484134 , time .UTC ),
526
+ ID : "b3688d98c007f53402a55e46d803f2f3ba9181d8e3f71a2eb19b392cf0377b4e" ,
527
+ FriendlyName : "upbeat_carver" ,
528
+ Image : "debian:bookworm" ,
529
+ Labels : map [string ]string {},
530
+ Running : true ,
531
+ Status : "running" ,
532
+ Ports : []codersdk.WorkspaceAgentListeningPort {},
533
+ Volumes : map [string ]string {
534
+ "/var/lib/docker/volumes/testvol/_data" : "/testvol" ,
535
+ },
536
+ },
537
+ },
538
+ },
539
+ {
540
+ name : "devcontainer_simple" ,
541
+ expect : []codersdk.WorkspaceAgentDevcontainer {
542
+ {
543
+ CreatedAt : time .Date (2025 , 3 , 11 , 17 , 1 , 5 , 751972661 , time .UTC ),
544
+ ID : "0b2a9fcf5727d9562943ce47d445019f4520e37a2aa7c6d9346d01af4f4f9aed" ,
545
+ FriendlyName : "optimistic_hopper" ,
546
+ Image : "debian:bookworm" ,
547
+ Labels : map [string ]string {
548
+ "devcontainer.config_file" : "/home/coder/src/coder/coder/agent/agentcontainers/testdata/devcontainer_simple.json" ,
549
+ "devcontainer.metadata" : "[]" ,
550
+ },
551
+ Running : true ,
552
+ Status : "running" ,
553
+ Ports : []codersdk.WorkspaceAgentListeningPort {},
554
+ Volumes : map [string ]string {},
555
+ },
556
+ },
557
+ },
558
+ {
559
+ name : "devcontainer_forwardport" ,
560
+ expect : []codersdk.WorkspaceAgentDevcontainer {
561
+ {
562
+ CreatedAt : time .Date (2025 , 3 , 11 , 17 , 3 , 55 , 22053072 , time .UTC ),
563
+ ID : "4a16af2293fb75dc827a6949a3905dd57ea28cc008823218ce24fab1cb66c067" ,
564
+ FriendlyName : "serene_khayyam" ,
565
+ Image : "debian:bookworm" ,
566
+ Labels : map [string ]string {
567
+ "devcontainer.config_file" : "/home/coder/src/coder/coder/agent/agentcontainers/testdata/devcontainer_forwardport.json" ,
568
+ "devcontainer.metadata" : "[]" ,
569
+ },
570
+ Running : true ,
571
+ Status : "running" ,
572
+ Ports : []codersdk.WorkspaceAgentListeningPort {},
573
+ Volumes : map [string ]string {},
574
+ },
575
+ },
576
+ },
577
+ {
578
+ name : "devcontainer_appport" ,
579
+ expect : []codersdk.WorkspaceAgentDevcontainer {
580
+ {
581
+ CreatedAt : time .Date (2025 , 3 , 11 , 17 , 2 , 42 , 613747761 , time .UTC ),
582
+ ID : "52d23691f4b954d083f117358ea763e20f69af584e1c08f479c5752629ee0be3" ,
583
+ FriendlyName : "suspicious_margulis" ,
584
+ Image : "debian:bookworm" ,
585
+ Labels : map [string ]string {
586
+ "devcontainer.config_file" : "/home/coder/src/coder/coder/agent/agentcontainers/testdata/devcontainer_appport.json" ,
587
+ "devcontainer.metadata" : "[]" ,
588
+ },
589
+ Running : true ,
590
+ Status : "running" ,
591
+ Ports : []codersdk.WorkspaceAgentListeningPort {
592
+ {
593
+ Network : "tcp" ,
594
+ Port : 8080 ,
595
+ },
596
+ },
597
+ Volumes : map [string ]string {},
598
+ },
599
+ },
600
+ },
601
+ } {
602
+ // nolint:paralleltest // variable recapture no longer required
603
+ t .Run (tt .name , func (t * testing.T ) {
604
+ t .Parallel ()
605
+ bs , err := os .ReadFile (filepath .Join ("testdata" , tt .name + ".json" ))
606
+ require .NoError (t , err , "failed to read testdata file" )
607
+ actual , warns , err := convertDockerInspect (string (bs ))
608
+ if len (tt .expectWarns ) > 0 {
609
+ assert .Len (t , warns , len (tt .expectWarns ), "expected warnings" )
610
+ for _ , warn := range tt .expectWarns {
611
+ assert .Contains (t , warns , warn )
612
+ }
613
+ }
614
+ if tt .expectError != "" {
615
+ assert .Empty (t , actual , "expected no data" )
616
+ assert .ErrorContains (t , err , tt .expectError )
617
+ return
618
+ }
619
+ require .NoError (t , err , "expected no error" )
620
+ if diff := cmp .Diff (tt .expect , actual ); diff != "" {
621
+ t .Errorf ("unexpected diff (-want +got):\n %s" , diff )
622
+ }
623
+ })
624
+ }
625
+ }
626
+
415
627
// TestDockerEnvInfoer tests the ability of EnvInfo to extract information from
416
628
// running containers. Containers are deleted after the test is complete.
417
629
// As this test creates containers, it is skipped by default.
0 commit comments