@@ -3568,4 +3568,250 @@ func TestDevcontainerDiscovery(t *testing.T) {
3568
3568
// This is implicitly handled by `testutil.Logger` failing when it
3569
3569
// detects an error has been logged.
3570
3570
})
3571
+
3572
+ t .Run ("AutoStart" , func (t * testing.T ) {
3573
+ t .Parallel ()
3574
+
3575
+ tests := []struct {
3576
+ name string
3577
+ agentDir string
3578
+ fs map [string ]string
3579
+ expectDevcontainerCount int
3580
+ setupMocks func (mDCCLI * acmock.MockDevcontainerCLI )
3581
+ }{
3582
+ {
3583
+ name : "SingleEnabled" ,
3584
+ agentDir : "/home/coder" ,
3585
+ expectDevcontainerCount : 1 ,
3586
+ fs : map [string ]string {
3587
+ "/home/coder/.git/HEAD" : "" ,
3588
+ "/home/coder/.devcontainer/devcontainer.json" : "" ,
3589
+ },
3590
+ setupMocks : func (mDCCLI * acmock.MockDevcontainerCLI ) {
3591
+ gomock .InOrder (
3592
+ // Given: This dev container has auto start enabled.
3593
+ mDCCLI .EXPECT ().ReadConfig (gomock .Any (),
3594
+ "/home/coder" ,
3595
+ "/home/coder/.devcontainer/devcontainer.json" ,
3596
+ []string {},
3597
+ ).Return (agentcontainers.DevcontainerConfig {
3598
+ Configuration : agentcontainers.DevcontainerConfiguration {
3599
+ Customizations : agentcontainers.DevcontainerCustomizations {
3600
+ Coder : agentcontainers.CoderCustomization {
3601
+ AutoStart : true ,
3602
+ },
3603
+ },
3604
+ },
3605
+ }, nil ),
3606
+
3607
+ // Then: We expect it to be started.
3608
+ mDCCLI .EXPECT ().Up (gomock .Any (),
3609
+ "/home/coder" ,
3610
+ "/home/coder/.devcontainer/devcontainer.json" ,
3611
+ gomock .Any (),
3612
+ ).Return ("" , nil ),
3613
+ )
3614
+ },
3615
+ },
3616
+ {
3617
+ name : "SingleDisabled" ,
3618
+ agentDir : "/home/coder" ,
3619
+ expectDevcontainerCount : 1 ,
3620
+ fs : map [string ]string {
3621
+ "/home/coder/.git/HEAD" : "" ,
3622
+ "/home/coder/.devcontainer/devcontainer.json" : "" ,
3623
+ },
3624
+ setupMocks : func (mDCCLI * acmock.MockDevcontainerCLI ) {
3625
+ gomock .InOrder (
3626
+ // Given: This dev container has auto start disabled.
3627
+ mDCCLI .EXPECT ().ReadConfig (gomock .Any (),
3628
+ "/home/coder" ,
3629
+ "/home/coder/.devcontainer/devcontainer.json" ,
3630
+ []string {},
3631
+ ).Return (agentcontainers.DevcontainerConfig {
3632
+ Configuration : agentcontainers.DevcontainerConfiguration {
3633
+ Customizations : agentcontainers.DevcontainerCustomizations {
3634
+ Coder : agentcontainers.CoderCustomization {
3635
+ AutoStart : false ,
3636
+ },
3637
+ },
3638
+ },
3639
+ }, nil ),
3640
+
3641
+ // Then: We expect it to _not_ be started.
3642
+ mDCCLI .EXPECT ().Up (gomock .Any (),
3643
+ "/home/coder" ,
3644
+ "/home/coder/.devcontainer/devcontainer.json" ,
3645
+ gomock .Any (),
3646
+ ).Return ("" , nil ).Times (0 ),
3647
+ )
3648
+ },
3649
+ },
3650
+ {
3651
+ name : "OneEnabledOneDisabled" ,
3652
+ agentDir : "/home/coder" ,
3653
+ expectDevcontainerCount : 2 ,
3654
+ fs : map [string ]string {
3655
+ "/home/coder/.git/HEAD" : "" ,
3656
+ "/home/coder/.devcontainer/devcontainer.json" : "" ,
3657
+ "/home/coder/project/.devcontainer.json" : "" ,
3658
+ },
3659
+ setupMocks : func (mDCCLI * acmock.MockDevcontainerCLI ) {
3660
+ gomock .InOrder (
3661
+ // Given: This dev container has auto start enabled.
3662
+ mDCCLI .EXPECT ().ReadConfig (gomock .Any (),
3663
+ "/home/coder" ,
3664
+ "/home/coder/.devcontainer/devcontainer.json" ,
3665
+ []string {},
3666
+ ).Return (agentcontainers.DevcontainerConfig {
3667
+ Configuration : agentcontainers.DevcontainerConfiguration {
3668
+ Customizations : agentcontainers.DevcontainerCustomizations {
3669
+ Coder : agentcontainers.CoderCustomization {
3670
+ AutoStart : true ,
3671
+ },
3672
+ },
3673
+ },
3674
+ }, nil ),
3675
+
3676
+ // Then: We expect it to be started.
3677
+ mDCCLI .EXPECT ().Up (gomock .Any (),
3678
+ "/home/coder" ,
3679
+ "/home/coder/.devcontainer/devcontainer.json" ,
3680
+ gomock .Any (),
3681
+ ).Return ("" , nil ),
3682
+ )
3683
+
3684
+ gomock .InOrder (
3685
+ // Given: This dev container has auto start disabled.
3686
+ mDCCLI .EXPECT ().ReadConfig (gomock .Any (),
3687
+ "/home/coder/project" ,
3688
+ "/home/coder/project/.devcontainer.json" ,
3689
+ []string {},
3690
+ ).Return (agentcontainers.DevcontainerConfig {
3691
+ Configuration : agentcontainers.DevcontainerConfiguration {
3692
+ Customizations : agentcontainers.DevcontainerCustomizations {
3693
+ Coder : agentcontainers.CoderCustomization {
3694
+ AutoStart : false ,
3695
+ },
3696
+ },
3697
+ },
3698
+ }, nil ),
3699
+
3700
+ // Then: We expect it to _not_ be started.
3701
+ mDCCLI .EXPECT ().Up (gomock .Any (),
3702
+ "/home/coder/project" ,
3703
+ "/home/coder/project/.devcontainer.json" ,
3704
+ gomock .Any (),
3705
+ ).Return ("" , nil ).Times (0 ),
3706
+ )
3707
+ },
3708
+ },
3709
+ {
3710
+ name : "MultipleEnabled" ,
3711
+ agentDir : "/home/coder" ,
3712
+ expectDevcontainerCount : 2 ,
3713
+ fs : map [string ]string {
3714
+ "/home/coder/.git/HEAD" : "" ,
3715
+ "/home/coder/.devcontainer/devcontainer.json" : "" ,
3716
+ "/home/coder/project/.devcontainer.json" : "" ,
3717
+ },
3718
+ setupMocks : func (mDCCLI * acmock.MockDevcontainerCLI ) {
3719
+ gomock .InOrder (
3720
+ // Given: This dev container has auto start enabled.
3721
+ mDCCLI .EXPECT ().ReadConfig (gomock .Any (),
3722
+ "/home/coder" ,
3723
+ "/home/coder/.devcontainer/devcontainer.json" ,
3724
+ []string {},
3725
+ ).Return (agentcontainers.DevcontainerConfig {
3726
+ Configuration : agentcontainers.DevcontainerConfiguration {
3727
+ Customizations : agentcontainers.DevcontainerCustomizations {
3728
+ Coder : agentcontainers.CoderCustomization {
3729
+ AutoStart : true ,
3730
+ },
3731
+ },
3732
+ },
3733
+ }, nil ),
3734
+
3735
+ // Then: We expect it to be started.
3736
+ mDCCLI .EXPECT ().Up (gomock .Any (),
3737
+ "/home/coder" ,
3738
+ "/home/coder/.devcontainer/devcontainer.json" ,
3739
+ gomock .Any (),
3740
+ ).Return ("" , nil ),
3741
+ )
3742
+
3743
+ gomock .InOrder (
3744
+ // Given: This dev container has auto start enabled.
3745
+ mDCCLI .EXPECT ().ReadConfig (gomock .Any (),
3746
+ "/home/coder/project" ,
3747
+ "/home/coder/project/.devcontainer.json" ,
3748
+ []string {},
3749
+ ).Return (agentcontainers.DevcontainerConfig {
3750
+ Configuration : agentcontainers.DevcontainerConfiguration {
3751
+ Customizations : agentcontainers.DevcontainerCustomizations {
3752
+ Coder : agentcontainers.CoderCustomization {
3753
+ AutoStart : true ,
3754
+ },
3755
+ },
3756
+ },
3757
+ }, nil ),
3758
+
3759
+ // Then: We expect it to be started.
3760
+ mDCCLI .EXPECT ().Up (gomock .Any (),
3761
+ "/home/coder/project" ,
3762
+ "/home/coder/project/.devcontainer.json" ,
3763
+ gomock .Any (),
3764
+ ).Return ("" , nil ),
3765
+ )
3766
+ },
3767
+ },
3768
+ }
3769
+
3770
+ for _ , tt := range tests {
3771
+ t .Run (tt .name , func (t * testing.T ) {
3772
+ t .Parallel ()
3773
+
3774
+ var (
3775
+ ctx = testutil .Context (t , testutil .WaitShort )
3776
+ logger = testutil .Logger (t )
3777
+ mClock = quartz .NewMock (t )
3778
+ mDCCLI = acmock .NewMockDevcontainerCLI (gomock .NewController (t ))
3779
+
3780
+ r = chi .NewRouter ()
3781
+ )
3782
+
3783
+ // Given: We setup our mocks. These mocks handle our expectations for these
3784
+ // tests. If there are missing/unexpected mock calls, the test will fail.
3785
+ tt .setupMocks (mDCCLI )
3786
+
3787
+ api := agentcontainers .NewAPI (logger ,
3788
+ agentcontainers .WithClock (mClock ),
3789
+ agentcontainers .WithWatcher (watcher .NewNoop ()),
3790
+ agentcontainers .WithFileSystem (initFS (t , tt .fs )),
3791
+ agentcontainers .WithManifestInfo ("owner" , "workspace" , "parent-agent" , "/home/coder" ),
3792
+ agentcontainers .WithContainerCLI (& fakeContainerCLI {}),
3793
+ agentcontainers .WithDevcontainerCLI (mDCCLI ),
3794
+ agentcontainers .WithProjectDiscovery (true ),
3795
+ )
3796
+ api .Start ()
3797
+ defer api .Close ()
3798
+ r .Mount ("/" , api .Routes ())
3799
+
3800
+ // When: All expected dev containers have been found.
3801
+ require .Eventuallyf (t , func () bool {
3802
+ req := httptest .NewRequest (http .MethodGet , "/" , nil ).WithContext (ctx )
3803
+ rec := httptest .NewRecorder ()
3804
+ r .ServeHTTP (rec , req )
3805
+
3806
+ got := codersdk.WorkspaceAgentListContainersResponse {}
3807
+ err := json .NewDecoder (rec .Body ).Decode (& got )
3808
+ require .NoError (t , err )
3809
+
3810
+ return len (got .Devcontainers ) >= tt .expectDevcontainerCount
3811
+ }, testutil .WaitShort , testutil .IntervalFast , "dev containers never found" )
3812
+
3813
+ // Then: We expect the mock infra to not fail.
3814
+ })
3815
+ }
3816
+ })
3571
3817
}
0 commit comments