@@ -90,7 +90,7 @@ func startProxy(t *testing.T, ctx context.Context, infisicalURL string, config P
9090}
9191
9292// setupProxyTest sets up the common test
93- func setupProxyTest (t * testing.T , ctx context.Context , proxyConfig ProxyTestConfig ) (* helpers.InfisicalService , * proxyHelpers.ProxyTestHelper , * helpers.Command , string , string ) {
93+ func setupProxyTest (t * testing.T , ctx context.Context , proxyConfig ProxyTestConfig ) (* helpers.InfisicalService , * proxyHelpers.ProxyTestHelper , * helpers.Command , string , string , helpers. MachineIdentity ) {
9494 infisical := helpers .NewInfisicalService ().Up (t , ctx )
9595
9696 // create machine identity with token auth (and universal auth if SSE is enabled)
@@ -145,14 +145,14 @@ func setupProxyTest(t *testing.T, ctx context.Context, proxyConfig ProxyTestConf
145145 // create test helper with both proxy and direct API clients
146146 helper := proxyHelpers .NewProxyTestHelper (t , proxyURL , infisical .ApiUrl (t ), identityToken , projectID )
147147
148- return infisical , helper , proxyCmd , identityToken , proxyURL
148+ return infisical , helper , proxyCmd , identityToken , proxyURL , identity
149149}
150150
151151func TestProxy_CacheHitMiss (t * testing.T ) {
152152 ctx , cancel := context .WithCancel (context .Background ())
153153 t .Cleanup (cancel )
154154
155- _ , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
155+ _ , helper , proxyCmd , _ , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
156156
157157 // create a test secret
158158 secret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
@@ -209,7 +209,7 @@ func TestProxy_MutationPurging(t *testing.T) {
209209 ctx , cancel := context .WithCancel (context .Background ())
210210 t .Cleanup (cancel )
211211
212- _ , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
212+ _ , helper , proxyCmd , _ , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
213213
214214 initialSecret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
215215 Prefix : "MUTATION_TEST_" ,
@@ -281,7 +281,7 @@ func TestProxy_DeleteMutationPurging(t *testing.T) {
281281 ctx , cancel := context .WithCancel (context .Background ())
282282 t .Cleanup (cancel )
283283
284- _ , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
284+ _ , helper , proxyCmd , _ , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
285285
286286 // create a test secret
287287 secret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
@@ -338,7 +338,7 @@ func TestProxy_TokenInvalidation(t *testing.T) {
338338 config := DefaultProxyTestConfig ()
339339 config .AccessTokenCheckInterval = "2s"
340340
341- _ , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , config )
341+ _ , helper , proxyCmd , _ , _ , _ := setupProxyTest (t , ctx , config )
342342
343343 // create and cache a secret
344344 secret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
@@ -377,7 +377,7 @@ func TestProxy_HighAvailability(t *testing.T) {
377377 ctx , cancel := context .WithCancel (context .Background ())
378378 t .Cleanup (cancel )
379379
380- infisical , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
380+ infisical , helper , proxyCmd , _ , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
381381
382382 // create and cache a secret
383383 secret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
@@ -451,7 +451,7 @@ func TestProxy_BackgroundRefresh(t *testing.T) {
451451 ctx , cancel := context .WithCancel (context .Background ())
452452 t .Cleanup (cancel )
453453
454- _ , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
454+ _ , helper , proxyCmd , _ , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
455455
456456 // create a test initialSecret
457457 initialSecret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
@@ -520,7 +520,7 @@ func TestProxy_MultipleSecrets(t *testing.T) {
520520 ctx , cancel := context .WithCancel (context .Background ())
521521 t .Cleanup (cancel )
522522
523- _ , helper , _ , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
523+ _ , helper , _ , _ , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
524524
525525 var secrets []proxyHelpers.Secret
526526 for i := 0 ; i < 3 ; i ++ {
@@ -557,7 +557,7 @@ func TestProxy_SingleSecretEndpoint(t *testing.T) {
557557 ctx , cancel := context .WithCancel (context .Background ())
558558 t .Cleanup (cancel )
559559
560- _ , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
560+ _ , helper , proxyCmd , _ , _ , _ := setupProxyTest (t , ctx , DefaultProxyTestConfig ())
561561
562562 // create a test secret
563563 secret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
@@ -591,7 +591,7 @@ func TestProxy_SSECacheUpdate(t *testing.T) {
591591 ctx , cancel := context .WithCancel (context .Background ())
592592 t .Cleanup (cancel )
593593
594- _ , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , SSEProxyTestConfig ())
594+ _ , helper , proxyCmd , _ , _ , _ := setupProxyTest (t , ctx , SSEProxyTestConfig ())
595595
596596 // wait for SSE manager initialization
597597 result := helpers .WaitForStderr (t , helpers.WaitForStderrOptions {
@@ -687,7 +687,7 @@ func TestProxy_SSEConnectionRecovery(t *testing.T) {
687687 ctx , cancel := context .WithCancel (context .Background ())
688688 t .Cleanup (cancel )
689689
690- infisical , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , SSEProxyTestConfig ())
690+ infisical , helper , proxyCmd , _ , _ , _ := setupProxyTest (t , ctx , SSEProxyTestConfig ())
691691
692692 // create and cache a secret to trigger SSE subscription
693693 secret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
@@ -777,7 +777,7 @@ func TestProxy_SSEMultipleProjects(t *testing.T) {
777777 ctx , cancel := context .WithCancel (context .Background ())
778778 t .Cleanup (cancel )
779779
780- infisical , helper1 , proxyCmd , identityToken , proxyURL := setupProxyTest (t , ctx , SSEProxyTestConfig ())
780+ infisical , helper1 , proxyCmd , identityToken , proxyURL , _ := setupProxyTest (t , ctx , SSEProxyTestConfig ())
781781
782782 // create a second project using the same identity
783783 bearerAuth , err := securityprovider .NewSecurityProviderBearerToken (identityToken )
@@ -889,85 +889,76 @@ func TestProxy_SSEPollingFallbackRecovery(t *testing.T) {
889889 ctx , cancel := context .WithCancel (context .Background ())
890890 t .Cleanup (cancel )
891891
892- infisical , helper , proxyCmd , _ , _ := setupProxyTest (t , ctx , SSEProxyTestConfig ())
892+ infisical , helper , proxyCmd , _ , _ , identity := setupProxyTest (t , ctx , SSEProxyTestConfig ())
893893
894- // create and cache a secret to trigger SSE subscription
895- secret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
896- Prefix : "SSE_POLLING_RECOVERY_" ,
897- })
898- helper .CreateSecretWithApi (ctx , secret )
899-
900- slog .Info ("Caching secret via proxy" )
901- resp1 := helper .GetSecretsWithProxy (ctx )
902- require .Equal (t , http .StatusOK , resp1 .StatusCode ())
903- require .NotEmpty (t , resp1 .JSON200 .Secrets )
904-
905- // wait for SSE connection established
906894 result := helpers .WaitForStderr (t , helpers.WaitForStderrOptions {
907895 EnsureCmdRunning : proxyCmd ,
908- ExpectedString : "SSE connection established " ,
896+ ExpectedString : "SSE manager initialized " ,
909897 Timeout : 30 * time .Second ,
910898 })
911899 require .Equal (t , helpers .WaitSuccess , result )
912900
913- // stop the Infisical backend to break SSE connection
914- slog .Info ("Stopping Infisical backend to break SSE connection" )
915- backendContainer , err := infisical .Compose ().ServiceContainer (ctx , "backend" )
916- require .NoError (t , err )
917- err = backendContainer .Stop (ctx , nil )
918- require .NoError (t , err )
901+ // create secret via API (not proxy)
902+ initialSecret := helper .GenerateSecret (proxyHelpers.GenerateSecretOptions {
903+ Prefix : "SSE_POLLING_FALLBACK_RECOVERY_" ,
904+ })
905+ helper .CreateSecretWithApi (ctx , initialSecret )
919906
920- require .Eventually (t , func () bool {
921- state , err := backendContainer .State (ctx )
922- if err != nil {
923- return false
907+ // fetch via proxy -> cache miss, now cached
908+ slog .Info ("Fetching secret via proxy (expecting cache miss)" )
909+ resp1 := helper .GetSecretsWithProxy (ctx )
910+ require .Equal (t , http .StatusOK , resp1 .StatusCode ())
911+ require .NotNil (t , resp1 .JSON200 )
912+
913+ var foundInitial bool
914+ for _ , s := range resp1 .JSON200 .Secrets {
915+ if s .SecretKey == initialSecret .SecretKey {
916+ assert .Equal (t , initialSecret .SecretValue , s .SecretValue )
917+ foundInitial = true
918+ break
924919 }
925- return ! state .Running
926- }, 60 * time .Second , 200 * time .Millisecond , "Backend container should have stopped" )
927- slog .Info ("Backend stopped" )
920+ }
921+ require .True (t , foundInitial , "Initial secret not found in response" )
928922
929- // wait for SSE connection loss
923+ // wait for SSE connection (demand-driven, triggered by first fetch)
930924 result = helpers .WaitForStderr (t , helpers.WaitForStderrOptions {
931925 EnsureCmdRunning : proxyCmd ,
932- ExpectedString : "SSE connection lost " ,
926+ ExpectedString : "SSE connection established " ,
933927 Timeout : 30 * time .Second ,
928+ Interval : 200 * time .Millisecond ,
934929 })
935- require .Equal (t , helpers .WaitSuccess , result , "SSE connection loss should be detected" )
930+ require .Equal (t , helpers .WaitSuccess , result )
931+
932+ // change identity role to no-access to break SSE connection with auth errors
933+ slog .Info ("Changing identity role to no-access to break SSE connection" )
934+ infisical .UpdateMachineIdentityRole (t , ctx , identity .Id , "no-access" )
936935
937- // wait for SSE retries to exhaust and polling fallback to start (~62s worst case with backoff)
936+ // wait for SSE retries to exhaust and polling fallback to start
938937 slog .Info ("Waiting for SSE retries to exhaust and polling fallback to start" )
939938 result = helpers .WaitForStderr (t , helpers.WaitForStderrOptions {
940939 EnsureCmdRunning : proxyCmd ,
941940 ExpectedString : "transitioning to polling fallback" ,
942- Timeout : 180 * time .Second ,
941+ Timeout : 120 * time .Second ,
942+ Interval : 200 * time .Millisecond ,
943943 })
944944 require .Equal (t , helpers .WaitSuccess , result , "Should transition to polling fallback after retries exhausted" )
945945
946946 result = helpers .WaitForStderr (t , helpers.WaitForStderrOptions {
947947 EnsureCmdRunning : proxyCmd ,
948948 ExpectedString : "Starting polling fallback for project" ,
949949 Timeout : 10 * time .Second ,
950+ Interval : 200 * time .Millisecond ,
950951 })
951952 require .Equal (t , helpers .WaitSuccess , result , "Polling fallback loop should start" )
952953
953- // restart the Infisical backend
954- slog .Info ("Restarting Infisical backend" )
955- err = backendContainer .Start (ctx )
956- require .NoError (t , err )
957-
958- require .Eventually (t , func () bool {
959- state , err := backendContainer .State (ctx )
960- if err != nil {
961- return false
962- }
963- return state .Running
964- }, 60 * time .Second , 200 * time .Millisecond , "Backend container should have restarted" )
965- slog .Info ("Backend restarted" )
954+ // restore identity role to member to allow SSE reconnection
955+ slog .Info ("Restoring identity role to member" )
956+ infisical .UpdateMachineIdentityRole (t , ctx , identity .Id , "member" )
966957
967958 // trigger EnsureSubscription by making a request — detects polling, attempts SSE reconnection
968959 slog .Info ("Fetching secrets to trigger SSE reconnection from polling mode" )
969- respAfterRestart := helper .GetSecretsWithProxy (ctx )
970- require .Equal (t , http .StatusOK , respAfterRestart .StatusCode ())
960+ respAfterRestore := helper .GetSecretsWithProxy (ctx )
961+ require .Equal (t , http .StatusOK , respAfterRestore .StatusCode ())
971962
972963 // wait for SSE to re-establish (second occurrence after reconnection from polling)
973964 slog .Info ("Waiting for SSE reconnection from polling mode" )
@@ -987,7 +978,7 @@ func TestProxy_SSEPollingFallbackRecovery(t *testing.T) {
987978 // verify polling was cancelled after SSE recovery
988979 result = helpers .WaitForStderr (t , helpers.WaitForStderrOptions {
989980 EnsureCmdRunning : proxyCmd ,
990- ExpectedString : "cancelled polling fallback" ,
981+ ExpectedString : "Cancelled polling fallback" ,
991982 Timeout : 30 * time .Second ,
992983 })
993984 require .Equal (t , helpers .WaitSuccess , result , "Polling should be cancelled after SSE recovery" )
@@ -997,9 +988,4 @@ func TestProxy_SSEPollingFallbackRecovery(t *testing.T) {
997988 respFinal := helper .GetSecretsWithProxy (ctx )
998989 require .Equal (t , http .StatusOK , respFinal .StatusCode ())
999990 require .True (t , proxyCmd .IsRunning (), "Proxy should still be running" )
1000-
1001- // tear down compose stack for clean state in subsequent tests
1002- slog .Info ("Tearing down compose stack for clean state" )
1003- err = infisical .DownWithForce (ctx )
1004- require .NoError (t , err , "Failed to tear down compose stack" )
1005991}
0 commit comments