@@ -37,9 +37,12 @@ func Test_ResolveRequest(t *testing.T) {
37
37
appNameAuthed = "app-authed"
38
38
appNamePublic = "app-public"
39
39
appNameInvalidURL = "app-invalid-url"
40
- appNameUnhealthy = "app-unhealthy"
40
+ // Users can access unhealthy and initializing apps (as of 2024-02).
41
+ appNameUnhealthy = "app-unhealthy"
42
+ appNameInitializing = "app-initializing"
41
43
42
44
// This agent will never connect, so it will never become "connected".
45
+ // Users cannot access unhealthy agents.
43
46
agentNameUnhealthy = "agent-unhealthy"
44
47
appNameAgentUnhealthy = "app-agent-unhealthy"
45
48
@@ -55,6 +58,15 @@ func Test_ResolveRequest(t *testing.T) {
55
58
w .WriteHeader (http .StatusInternalServerError )
56
59
_ , _ = w .Write ([]byte ("unhealthy" ))
57
60
}))
61
+ t .Cleanup (unhealthySrv .Close )
62
+
63
+ // Start a listener for a server that never responds.
64
+ initializingServer , err := net .Listen ("tcp" , "localhost:0" )
65
+ require .NoError (t , err )
66
+ t .Cleanup (func () {
67
+ _ = initializingServer .Close ()
68
+ })
69
+ initializingURL := fmt .Sprintf ("http://%s" , initializingServer .Addr ().String ())
58
70
59
71
deploymentValues := coderdtest .DeploymentValues (t )
60
72
deploymentValues .DisablePathApps = false
@@ -82,7 +94,7 @@ func Test_ResolveRequest(t *testing.T) {
82
94
})
83
95
84
96
ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitMedium )
85
- defer cancel ( )
97
+ t . Cleanup ( cancel )
86
98
87
99
firstUser := coderdtest .CreateFirstUser (t , client )
88
100
me , err := client .User (ctx , codersdk .Me )
@@ -143,6 +155,17 @@ func Test_ResolveRequest(t *testing.T) {
143
155
Threshold : 1 ,
144
156
},
145
157
},
158
+ {
159
+ Slug : appNameInitializing ,
160
+ DisplayName : appNameInitializing ,
161
+ SharingLevel : proto .AppSharingLevel_PUBLIC ,
162
+ Url : appURL ,
163
+ Healthcheck : & proto.Healthcheck {
164
+ Url : initializingURL ,
165
+ Interval : 30 ,
166
+ Threshold : 1000 ,
167
+ },
168
+ },
146
169
},
147
170
},
148
171
{
@@ -805,7 +828,55 @@ func Test_ResolveRequest(t *testing.T) {
805
828
require .Contains (t , bodyStr , `Agent state is "` )
806
829
})
807
830
808
- t .Run ("UnhealthyApp" , func (t * testing.T ) {
831
+ // Initializing apps are now permitted to connect anyways. This wasn't
832
+ // always the case, but we're testing the behavior to ensure it doesn't
833
+ // change back accidentally.
834
+ t .Run ("InitializingAppPermitted" , func (t * testing.T ) {
835
+ t .Parallel ()
836
+
837
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitShort )
838
+ defer cancel ()
839
+
840
+ agent , err := client .WorkspaceAgent (ctx , agentID )
841
+ require .NoError (t , err )
842
+
843
+ for _ , app := range agent .Apps {
844
+ if app .Slug == appNameInitializing {
845
+ t .Log ("app is" , app .Health )
846
+ require .Equal (t , codersdk .WorkspaceAppHealthInitializing , app .Health )
847
+ break
848
+ }
849
+ }
850
+
851
+ req := (workspaceapps.Request {
852
+ AccessMethod : workspaceapps .AccessMethodPath ,
853
+ BasePath : "/app" ,
854
+ UsernameOrID : me .Username ,
855
+ WorkspaceNameOrID : workspace .Name ,
856
+ AgentNameOrID : agentName ,
857
+ AppSlugOrPort : appNameInitializing ,
858
+ }).Normalize ()
859
+
860
+ rw := httptest .NewRecorder ()
861
+ r := httptest .NewRequest ("GET" , "/app" , nil )
862
+ r .Header .Set (codersdk .SessionTokenHeader , client .SessionToken ())
863
+
864
+ token , ok := workspaceapps .ResolveRequest (rw , r , workspaceapps.ResolveRequestOptions {
865
+ Logger : api .Logger ,
866
+ SignedTokenProvider : api .WorkspaceAppsProvider ,
867
+ DashboardURL : api .AccessURL ,
868
+ PathAppBaseURL : api .AccessURL ,
869
+ AppHostname : api .AppHostname ,
870
+ AppRequest : req ,
871
+ })
872
+ require .True (t , ok , "ResolveRequest failed, should pass even though app is initializing" )
873
+ require .NotNil (t , token )
874
+ })
875
+
876
+ // Unhealthy apps are now permitted to connect anyways. This wasn't always
877
+ // the case, but we're testing the behavior to ensure it doesn't change back
878
+ // accidentally.
879
+ t .Run ("UnhealthyAppPermitted" , func (t * testing.T ) {
809
880
t .Parallel ()
810
881
811
882
require .Eventually (t , func () bool {
@@ -850,17 +921,7 @@ func Test_ResolveRequest(t *testing.T) {
850
921
AppHostname : api .AppHostname ,
851
922
AppRequest : req ,
852
923
})
853
- require .False (t , ok , "request succeeded even though app is unhealthy" )
854
- require .Nil (t , token )
855
-
856
- w := rw .Result ()
857
- defer w .Body .Close ()
858
- require .Equal (t , http .StatusBadGateway , w .StatusCode )
859
-
860
- body , err := io .ReadAll (w .Body )
861
- require .NoError (t , err )
862
- bodyStr := string (body )
863
- bodyStr = strings .ReplaceAll (bodyStr , """ , `"` )
864
- require .Contains (t , bodyStr , `App health is "unhealthy"` )
924
+ require .True (t , ok , "ResolveRequest failed, should pass even though app is unhealthy" )
925
+ require .NotNil (t , token )
865
926
})
866
927
}
0 commit comments