From 10d5fc6184671555b8e0d72285e9d1695fd5502a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sat, 17 Aug 2024 17:48:06 +0300 Subject: [PATCH] test: no location header in response (#8441) # Which Problems Are Solved Sometimes integrations tests are failing with an error `http: no location header in response`. The underlying cause was hidden, as in some tests we assumed a 3xx range response but got a 4xx response instead. No assertion on the status code was made, resulting in the above error message on calling `resp.Location()`. The underlying issue, the application not found in the projection, is also fixed. # How the Problems Are Solved This change adds a check for the status code and returns the response body if the response is not in the 3xx status code range. Helper function that create applications now do an additional `GetAppByID` in a retry loop to ensure consitency in the projection before proceeding with tests. # Additional Changes - none # Additional Context - Pipline failures were observed, no issue was created - Cherry-picked form WIP #8407 Co-authored-by: Livio Spring --- internal/integration/integration.go | 16 ++++++++++++++++ internal/integration/oidc.go | 29 +++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/internal/integration/integration.go b/internal/integration/integration.go index 18836be8f..20af65993 100644 --- a/internal/integration/integration.go +++ b/internal/integration/integration.go @@ -431,3 +431,19 @@ func (s *Tester) updateInstanceAndOrg(ctx context.Context, domain string) contex logging.OnError(err).Fatal("query organisation") return ctx } + +func await(af func() error) error { + maxTimer := time.NewTimer(15 * time.Minute) + for { + err := af() + if err == nil { + return nil + } + select { + case <-maxTimer.C: + return err + case <-time.After(time.Second / 10): + continue + } + } +} diff --git a/internal/integration/oidc.go b/internal/integration/oidc.go index 3e90cb685..1d15d25f2 100644 --- a/internal/integration/oidc.go +++ b/internal/integration/oidc.go @@ -3,6 +3,7 @@ package integration import ( "context" "fmt" + "io" "net/http" "net/url" "strings" @@ -27,7 +28,7 @@ func (s *Tester) CreateOIDCClient(ctx context.Context, redirectURI, logoutRedire if len(grantTypes) == 0 { grantTypes = []app.OIDCGrantType{app.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE, app.OIDCGrantType_OIDC_GRANT_TYPE_REFRESH_TOKEN} } - return s.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ + resp, err := s.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ ProjectId: projectID, Name: fmt.Sprintf("app-%d", time.Now().UnixNano()), RedirectUris: []string{redirectURI}, @@ -46,6 +47,16 @@ func (s *Tester) CreateOIDCClient(ctx context.Context, redirectURI, logoutRedire AdditionalOrigins: nil, SkipNativeAppSuccessPage: false, }) + if err != nil { + return nil, err + } + return resp, await(func() error { + _, err := s.Client.Mgmt.GetAppByID(ctx, &management.GetAppByIDRequest{ + ProjectId: projectID, + AppId: resp.GetAppId(), + }) + return err + }) } func (s *Tester) CreateOIDCNativeClient(ctx context.Context, redirectURI, logoutRedirectURI, projectID string, devMode bool) (*management.AddOIDCAppResponse, error) { @@ -95,7 +106,7 @@ func (s *Tester) CreateOIDCImplicitFlowClient(ctx context.Context, redirectURI s if err != nil { return nil, err } - return s.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ + resp, err := s.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ ProjectId: project.GetId(), Name: fmt.Sprintf("app-%d", time.Now().UnixNano()), RedirectUris: []string{redirectURI}, @@ -114,6 +125,16 @@ func (s *Tester) CreateOIDCImplicitFlowClient(ctx context.Context, redirectURI s AdditionalOrigins: nil, SkipNativeAppSuccessPage: false, }) + if err != nil { + return nil, err + } + return resp, await(func() error { + _, err := s.Client.Mgmt.GetAppByID(ctx, &management.GetAppByIDRequest{ + ProjectId: project.GetId(), + AppId: resp.GetAppId(), + }) + return err + }) } func (s *Tester) CreateOIDCTokenExchangeClient(ctx context.Context) (client *management.AddOIDCAppResponse, keyData []byte, err error) { @@ -284,6 +305,10 @@ func CheckRedirect(req *http.Request) (*url.URL, error) { return nil, err } defer resp.Body.Close() + if resp.StatusCode < 300 || resp.StatusCode >= 400 { + body, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("check redirect unexpected status: %q; body: %q", resp.Status, body) + } return resp.Location() }