From 67e6664de9e2f3f0b67dfaf3827b53b03ff5210b Mon Sep 17 00:00:00 2001 From: Michael Li Date: Fri, 26 Apr 2024 15:36:11 -0400 Subject: [PATCH] test(e2e): Close http requests in rate limit test (#4733) * test(e2e): Close http requests * test(e2e): Address timing flakiness --- .../e2e/tests/base_plus/rate_limit_test.go | 121 +++++++++++------- 1 file changed, 73 insertions(+), 48 deletions(-) diff --git a/testing/internal/e2e/tests/base_plus/rate_limit_test.go b/testing/internal/e2e/tests/base_plus/rate_limit_test.go index 26142c3f49..fcfc26dd4a 100644 --- a/testing/internal/e2e/tests/base_plus/rate_limit_test.go +++ b/testing/internal/e2e/tests/base_plus/rate_limit_test.go @@ -50,16 +50,18 @@ func TestHttpRateLimit(t *testing.T) { require.NoError(t, err) // Authenticate over HTTP - res, err := boundary.AuthenticateHttp(t, ctx, bc.Address, bc.AuthMethodId, bc.AdminLoginName, bc.AdminLoginPassword) + resAuth, err := boundary.AuthenticateHttp(t, ctx, bc.Address, bc.AuthMethodId, bc.AdminLoginName, bc.AdminLoginPassword) require.NoError(t, err) - require.Equal(t, http.StatusOK, res.StatusCode) - body, err := io.ReadAll(res.Body) + t.Cleanup(func() { + resAuth.Body.Close() + }) + require.Equal(t, http.StatusOK, resAuth.StatusCode) + body, err := io.ReadAll(resAuth.Body) require.NoError(t, err) var r boundary.HttpResponseBody err = json.Unmarshal(body, &r) require.NoError(t, err) tokenAdmin := r.Attributes.Token - res.Body.Close() // Make initial API request t.Log("Sending API requests until quota is hit...") @@ -67,24 +69,25 @@ func TestHttpRateLimit(t *testing.T) { req, err := http.NewRequest(http.MethodGet, requestURL, nil) require.NoError(t, err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenAdmin)) - res, err = http.DefaultClient.Do(req) + resInitial, err := http.DefaultClient.Do(req) require.NoError(t, err) - require.Equal(t, http.StatusOK, res.StatusCode) - - body, err = io.ReadAll(res.Body) + t.Cleanup(func() { + resInitial.Body.Close() + }) + require.Equal(t, http.StatusOK, resInitial.StatusCode) + body, err = io.ReadAll(resInitial.Body) require.NoError(t, err) - res.Body.Close() require.NotEmpty(t, body) require.Contains(t, string(body), hostId) // Check that the limit from the policy matches the actual limit - rateLimitPolicyHeader := res.Header.Get("Ratelimit-Policy") + rateLimitPolicyHeader := resInitial.Header.Get("Ratelimit-Policy") require.NotEmpty(t, rateLimitPolicyHeader) - policyLimit, policyPeriod, err := getRateLimitPolicyStat(res.Header.Get("Ratelimit-Policy"), "auth-token") + policyLimit, policyPeriod, err := getRateLimitPolicyStat(resInitial.Header.Get("Ratelimit-Policy"), "auth-token") require.NoError(t, err) t.Log(rateLimitPolicyHeader) - rateLimitHeader := res.Header.Get("Ratelimit") + rateLimitHeader := resInitial.Header.Get("Ratelimit") require.NotEmpty(t, rateLimitHeader) t.Log(rateLimitHeader) limit, err := getRateLimitStat(rateLimitHeader, "limit") @@ -100,8 +103,11 @@ func TestHttpRateLimit(t *testing.T) { req, err = http.NewRequest(http.MethodGet, requestURL, nil) require.NoError(t, err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenAdmin)) - res, err = http.DefaultClient.Do(req) + res, err := http.DefaultClient.Do(req) require.NoError(t, err) + t.Cleanup(func() { + res.Body.Close() + }) require.Equal(t, http.StatusOK, res.StatusCode) rateLimitHeader := res.Header.Get("Ratelimit") @@ -121,17 +127,18 @@ func TestHttpRateLimit(t *testing.T) { req, err = http.NewRequest(http.MethodGet, requestURL, nil) require.NoError(t, err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenAdmin)) - res, err = http.DefaultClient.Do(req) + resAfter, err := http.DefaultClient.Do(req) require.NoError(t, err) - require.Equal(t, http.StatusTooManyRequests, res.StatusCode) - - body, err = io.ReadAll(res.Body) + t.Cleanup(func() { + resAfter.Body.Close() + }) + require.Equal(t, http.StatusTooManyRequests, resAfter.StatusCode) + body, err = io.ReadAll(resAfter.Body) require.NoError(t, err) - res.Body.Close() require.Empty(t, body) // Wait for "Retry-After" time - retryAfterHeader := res.Header.Get("Retry-After") + retryAfterHeader := resAfter.Header.Get("Retry-After") require.NotEmpty(t, retryAfterHeader) retryAfter, err := strconv.Atoi(retryAfterHeader) require.NoError(t, err) @@ -144,13 +151,14 @@ func TestHttpRateLimit(t *testing.T) { req, err = http.NewRequest(http.MethodGet, requestURL, nil) require.NoError(t, err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenAdmin)) - res, err = http.DefaultClient.Do(req) + resRetry, err := http.DefaultClient.Do(req) require.NoError(t, err) - require.Equal(t, http.StatusOK, res.StatusCode) - - body, err = io.ReadAll(res.Body) + t.Cleanup(func() { + resRetry.Body.Close() + }) + require.Equal(t, http.StatusOK, resRetry.StatusCode) + body, err = io.ReadAll(resRetry.Body) require.NoError(t, err) - res.Body.Close() require.NotEmpty(t, body) require.Contains(t, string(body), hostId) @@ -186,15 +194,17 @@ func TestHttpRateLimit(t *testing.T) { require.NoError(t, err) // Get auth token for second user - res, err = boundary.AuthenticateHttp(t, ctx, bc.Address, bc.AuthMethodId, acctName, acctPassword) + resAuth2, err := boundary.AuthenticateHttp(t, ctx, bc.Address, bc.AuthMethodId, acctName, acctPassword) require.NoError(t, err) - require.Equal(t, http.StatusOK, res.StatusCode) - body, err = io.ReadAll(res.Body) + t.Cleanup(func() { + resAuth2.Body.Close() + }) + require.Equal(t, http.StatusOK, resAuth2.StatusCode) + body, err = io.ReadAll(resAuth2.Body) require.NoError(t, err) err = json.Unmarshal(body, &r) require.NoError(t, err) tokenUser := r.Attributes.Token - res.Body.Close() // Make request until quota is hit again using the first user t.Log("Sending API requests until quota is hit...") @@ -202,13 +212,13 @@ func TestHttpRateLimit(t *testing.T) { req, err = http.NewRequest(http.MethodGet, requestURL, nil) require.NoError(t, err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenAdmin)) - res, err = http.DefaultClient.Do(req) + resQuota, err := http.DefaultClient.Do(req) require.NoError(t, err) t.Cleanup(func() { - res.Body.Close() + resQuota.Body.Close() }) - require.Equal(t, http.StatusOK, res.StatusCode) - rateLimitHeader = res.Header.Get("Ratelimit") + require.Equal(t, http.StatusOK, resQuota.StatusCode) + rateLimitHeader = resQuota.Header.Get("Ratelimit") require.NotEmpty(t, rateLimitHeader) t.Log(rateLimitHeader) quota, err = getRateLimitStat(rateLimitHeader, "remaining") @@ -243,13 +253,14 @@ func TestHttpRateLimit(t *testing.T) { req, err = http.NewRequest(http.MethodGet, requestURL, nil) require.NoError(t, err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenUser)) - res, err = http.DefaultClient.Do(req) + resReject, err := http.DefaultClient.Do(req) require.NoError(t, err) - require.Equal(t, http.StatusServiceUnavailable, res.StatusCode) - - body, err = io.ReadAll(res.Body) + t.Cleanup(func() { + resReject.Body.Close() + }) + require.Equal(t, http.StatusServiceUnavailable, resReject.StatusCode) + body, err = io.ReadAll(resReject.Body) require.NoError(t, err) - res.Body.Close() require.Empty(t, body) // Wait for "Retry-After" time @@ -268,9 +279,12 @@ func TestHttpRateLimit(t *testing.T) { req, err = http.NewRequest(http.MethodGet, requestURL, nil) require.NoError(t, err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenUser)) - res, err = http.DefaultClient.Do(req) + resSuccess, err := http.DefaultClient.Do(req) require.NoError(t, err) - require.Equal(t, http.StatusOK, res.StatusCode) + t.Cleanup(func() { + resSuccess.Body.Close() + }) + require.Equal(t, http.StatusOK, resSuccess.StatusCode) t.Log("Successfully sent request after waiting") time.Sleep(time.Duration(policyPeriod) * time.Second) @@ -338,16 +352,18 @@ func TestCliRateLimit(t *testing.T) { require.NoError(t, err) // Authenticate over HTTP - res, err := boundary.AuthenticateHttp(t, ctx, bc.Address, bc.AuthMethodId, bc.AdminLoginName, bc.AdminLoginPassword) + resAuth, err := boundary.AuthenticateHttp(t, ctx, bc.Address, bc.AuthMethodId, bc.AdminLoginName, bc.AdminLoginPassword) require.NoError(t, err) - require.Equal(t, http.StatusOK, res.StatusCode) - body, err := io.ReadAll(res.Body) + t.Cleanup(func() { + resAuth.Body.Close() + }) + require.Equal(t, http.StatusOK, resAuth.StatusCode) + body, err := io.ReadAll(resAuth.Body) require.NoError(t, err) var r boundary.HttpResponseBody err = json.Unmarshal(body, &r) require.NoError(t, err) tokenAdmin := r.Attributes.Token - res.Body.Close() // Make initial API request t.Log("Getting rate limit info...") @@ -355,16 +371,25 @@ func TestCliRateLimit(t *testing.T) { req, err := http.NewRequest(http.MethodGet, requestURL, nil) require.NoError(t, err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenAdmin)) - res, err = http.DefaultClient.Do(req) + resInitial, err := http.DefaultClient.Do(req) require.NoError(t, err) - require.Equal(t, http.StatusOK, res.StatusCode) + t.Cleanup(func() { + resInitial.Body.Close() + }) + require.Equal(t, http.StatusOK, resInitial.StatusCode) - rateLimitPolicyHeader := res.Header.Get("Ratelimit-Policy") + rateLimitPolicyHeader := resInitial.Header.Get("Ratelimit-Policy") + t.Log(rateLimitPolicyHeader) require.NotEmpty(t, rateLimitPolicyHeader) - policyLimit, policyPeriod, err := getRateLimitPolicyStat(res.Header.Get("Ratelimit-Policy"), "auth-token") + policyLimit, policyPeriod, err := getRateLimitPolicyStat(resInitial.Header.Get("Ratelimit-Policy"), "auth-token") require.NoError(t, err) + + rateLimitHeader := resInitial.Header.Get("Ratelimit") + t.Log(rateLimitHeader) + // Wait for ratelimit to reset - time.Sleep(time.Duration(policyPeriod) * time.Second) + t.Logf("Waiting for %d seconds to reset rate limit...", policyPeriod+1) + time.Sleep(time.Duration(policyPeriod+1) * time.Second) // Run tests until rate limit is hit. Expect to see a HTTP 429 when rate limited t.Log("Sending multiple CLI requests to hit rate limit...")