Skip to content

Commit 393a89e

Browse files
committed
add e2e
Signed-off-by: zirain <[email protected]>
1 parent 137e358 commit 393a89e

2 files changed

Lines changed: 109 additions & 12 deletions

File tree

test/e2e/testdata/circuitbreaker.yaml

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ metadata:
55
namespace: gateway-conformance-infra
66
spec:
77
targetRefs:
8-
- group: gateway.networking.k8s.io
9-
kind: HTTPRoute
10-
name: http-with-circuitbreaker
8+
- group: gateway.networking.k8s.io
9+
kind: HTTPRoute
10+
name: http-with-circuitbreaker
1111
circuitBreaker:
1212
maxConnections: 0
1313
maxParallelRequests: 0
@@ -20,12 +20,49 @@ metadata:
2020
namespace: gateway-conformance-infra
2121
spec:
2222
parentRefs:
23-
- name: same-namespace
23+
- name: same-namespace
2424
rules:
25-
- matches:
26-
- path:
27-
type: PathPrefix
28-
value: /circuitbreaker
29-
backendRefs:
30-
- name: infra-backend-v1
31-
port: 8080
25+
- matches:
26+
- path:
27+
type: PathPrefix
28+
value: /circuitbreaker
29+
backendRefs:
30+
- name: infra-backend-v1
31+
port: 8080
32+
---
33+
apiVersion: gateway.envoyproxy.io/v1alpha1
34+
kind: BackendTrafficPolicy
35+
metadata:
36+
name: circuitbreaker-retry-budget
37+
namespace: gateway-conformance-infra
38+
spec:
39+
targetRefs:
40+
- group: gateway.networking.k8s.io
41+
kind: HTTPRoute
42+
name: http-with-retry-budget
43+
retry:
44+
retryOn:
45+
httpStatusCodes:
46+
- 503
47+
circuitBreaker:
48+
retryBudget:
49+
percent:
50+
numerator: 0
51+
minRetryConcurrency: 0
52+
---
53+
apiVersion: gateway.networking.k8s.io/v1
54+
kind: HTTPRoute
55+
metadata:
56+
name: http-with-retry-budget
57+
namespace: gateway-conformance-infra
58+
spec:
59+
parentRefs:
60+
- name: same-namespace
61+
rules:
62+
- matches:
63+
- path:
64+
type: PathPrefix
65+
value: /
66+
backendRefs:
67+
- name: infra-backend-v2
68+
port: 8080

test/e2e/tests/circuitbreaker.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,20 @@
88
package tests
99

1010
import (
11+
"context"
1112
"testing"
13+
"time"
1214

15+
"github.com/stretchr/testify/require"
1316
"k8s.io/apimachinery/pkg/types"
17+
"k8s.io/apimachinery/pkg/util/wait"
1418
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
1519
"sigs.k8s.io/gateway-api/conformance/utils/http"
1620
"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
1721
"sigs.k8s.io/gateway-api/conformance/utils/suite"
22+
"sigs.k8s.io/gateway-api/conformance/utils/tlog"
23+
24+
"github.com/envoyproxy/gateway/test/utils/prometheus"
1825
)
1926

2027
func init() {
@@ -23,7 +30,7 @@ func init() {
2330

2431
var CircuitBreakerTest = suite.ConformanceTest{
2532
ShortName: "CircuitBreaker",
26-
Description: "Deny All Requests",
33+
Description: "Test circuit breaker functionality",
2734
Manifests: []string{"testdata/circuitbreaker.yaml"},
2835
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
2936
t.Run("Deny All Requests", func(t *testing.T) {
@@ -47,5 +54,58 @@ var CircuitBreakerTest = suite.ConformanceTest{
4754

4855
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
4956
})
57+
58+
t.Run("Retry budget worked", func(t *testing.T) {
59+
ns := "gateway-conformance-infra"
60+
routeNN := types.NamespacedName{Name: "http-with-retry-budget", Namespace: ns}
61+
gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
62+
gwAddr := kubernetes.GatewayAndRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), &gwapiv1.HTTPRoute{}, false, routeNN)
63+
64+
// make sure that the backend is healthy.
65+
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, http.ExpectedResponse{
66+
Request: http.Request{
67+
Path: "/retry-budget",
68+
},
69+
Response: http.Response{
70+
StatusCodes: []int{200},
71+
},
72+
Namespace: ns,
73+
})
74+
75+
promClient, err := prometheus.NewClient(suite.Client,
76+
types.NamespacedName{Name: "prometheus", Namespace: "monitoring"},
77+
)
78+
require.NoError(t, err)
79+
80+
promQL := `envoy_cluster_upstream_rq_retry_overflow{app_kubernetes_io_name="envoy",app_kubernetes_io_managed_by="envoy-gateway"}`
81+
82+
// expect 503 since the policy applies a retry budget with 0% success rate
83+
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, http.ExpectedResponse{
84+
Request: http.Request{
85+
Path: "/status/503",
86+
},
87+
Response: http.Response{
88+
StatusCodes: []int{503},
89+
},
90+
Namespace: ns,
91+
})
92+
93+
err = wait.PollUntilContextTimeout(t.Context(), time.Second, time.Minute, true, func(ctx context.Context) (bool, error) {
94+
v, err := promClient.QuerySum(ctx, promQL)
95+
if err != nil {
96+
tlog.Logf(t, "failed to query prometheus: %v", err)
97+
return false, nil
98+
}
99+
100+
if v > 0 {
101+
tlog.Logf(t, "got expected retry overflow metric: %v", v)
102+
return true, nil
103+
}
104+
105+
tlog.Logf(t, "retry overflow metric not updated yet: %v", v)
106+
return false, nil
107+
})
108+
require.NoError(t, err)
109+
})
50110
},
51111
}

0 commit comments

Comments
 (0)