Skip to content

Commit 41fa6c3

Browse files
committed
refactor weight test into shared function and fix nits
1 parent db524ae commit 41fa6c3

File tree

4 files changed

+203
-175
lines changed

4 files changed

+203
-175
lines changed

conformance/tests/grpcroute-weight.go

Lines changed: 11 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2024 The Kubernetes Authors.
2+
Copyright 2025 The Kubernetes Authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -17,16 +17,8 @@ limitations under the License.
1717
package tests
1818

1919
import (
20-
"cmp"
21-
"errors"
22-
"fmt"
23-
"math"
24-
"slices"
25-
"strings"
26-
"sync"
2720
"testing"
2821

29-
"golang.org/x/sync/errgroup"
3022
"google.golang.org/grpc/codes"
3123
"k8s.io/apimachinery/pkg/types"
3224

@@ -65,11 +57,19 @@ var GRPCRouteWeight = suite.ConformanceTest{
6557
Namespace: "gateway-conformance-infra",
6658
}
6759

68-
// Assert request succeeds before doing our distribution check
60+
// Assert request succeeds before doing our distribution check
6961
grpc.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.GRPCClient, suite.TimeoutConfig, gwAddr, expected)
7062

63+
expectedWeights := map[string]float64{
64+
"grpc-infra-backend-v1": 0.7,
65+
"grpc-infra-backend-v2": 0.3,
66+
"grpc-infra-backend-v3": 0.0,
67+
}
68+
69+
sender := newGRPCRequestSender(t, suite, gwAddr, expected)
70+
7171
for i := 0; i < 10; i++ {
72-
if err := testGRPCDistribution(t, suite, gwAddr, expected); err != nil {
72+
if err := testWeightedDistribution(sender, expectedWeights); err != nil {
7373
t.Logf("Traffic distribution test failed (%d/10): %s", i+1, err)
7474
} else {
7575
return
@@ -79,80 +79,3 @@ var GRPCRouteWeight = suite.ConformanceTest{
7979
})
8080
},
8181
}
82-
83-
func testGRPCDistribution(t *testing.T, suite *suite.ConformanceTestSuite, gwAddr string, expected grpc.ExpectedResponse) error {
84-
const (
85-
concurrentRequests = 10
86-
tolerancePercentage = 0.05
87-
totalRequests = 500.0
88-
)
89-
var (
90-
g errgroup.Group
91-
seenMutex sync.Mutex
92-
seen = make(map[string]float64, 3 /* number of backends */)
93-
expectedWeights = map[string]float64{
94-
"grpc-infra-backend-v1": 0.7,
95-
"grpc-infra-backend-v2": 0.3,
96-
"grpc-infra-backend-v3": 0.0,
97-
}
98-
grpcClient = &grpc.DefaultClient{}
99-
)
100-
g.SetLimit(concurrentRequests)
101-
for i := 0.0; i < totalRequests; i++ {
102-
g.Go(func() error {
103-
resp, err := grpcClient.SendRPC(t, gwAddr, expected, suite.TimeoutConfig.MaxTimeToConsistency)
104-
if err != nil {
105-
return fmt.Errorf("failed to send gRPC request: %w", err)
106-
}
107-
if resp.Code != codes.OK {
108-
return fmt.Errorf("expected OK response, got %v", resp.Code)
109-
}
110-
111-
seenMutex.Lock()
112-
defer seenMutex.Unlock()
113-
114-
podName := resp.Response.GetAssertions().GetContext().GetPod()
115-
for expectedBackend := range expectedWeights {
116-
if strings.HasPrefix(podName, expectedBackend) {
117-
seen[expectedBackend]++
118-
return nil
119-
}
120-
}
121-
122-
return fmt.Errorf("request was handled by an unexpected pod %q", podName)
123-
})
124-
}
125-
126-
if err := g.Wait(); err != nil {
127-
return fmt.Errorf("error while sending requests: %w", err)
128-
}
129-
130-
var errs []error
131-
if len(seen) != 2 {
132-
errs = append(errs, fmt.Errorf("expected only two backends to receive traffic"))
133-
}
134-
135-
for wantBackend, wantPercent := range expectedWeights {
136-
gotCount, ok := seen[wantBackend]
137-
138-
if !ok && wantPercent != 0.0 {
139-
errs = append(errs, fmt.Errorf("expect traffic to hit backend %q - but none was received", wantBackend))
140-
continue
141-
}
142-
143-
gotPercent := gotCount / totalRequests
144-
145-
if math.Abs(gotPercent-wantPercent) > tolerancePercentage {
146-
errs = append(errs, fmt.Errorf("backend %q weighted traffic of %v not within tolerance %v (+/-%f)",
147-
wantBackend,
148-
gotPercent,
149-
wantPercent,
150-
tolerancePercentage,
151-
))
152-
}
153-
}
154-
slices.SortFunc(errs, func(a, b error) int {
155-
return cmp.Compare(a.Error(), b.Error())
156-
})
157-
return errors.Join(errs...)
158-
}

conformance/tests/grpcroute-weight.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ spec:
1616
weight: 30
1717
- name: grpc-infra-backend-v3
1818
port: 8080
19-
weight: 0
19+
weight: 0

conformance/tests/httproute-weight.go

Lines changed: 9 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,8 @@ limitations under the License.
1717
package tests
1818

1919
import (
20-
"cmp"
21-
"errors"
22-
"fmt"
23-
"math"
24-
"slices"
25-
"strings"
26-
"sync"
2720
"testing"
2821

29-
"golang.org/x/sync/errgroup"
3022
"k8s.io/apimachinery/pkg/types"
3123

3224
"sigs.k8s.io/gateway-api/conformance/utils/http"
@@ -67,8 +59,16 @@ var HTTPRouteWeight = suite.ConformanceTest{
6759
// Assert request succeeds before doing our distribution check
6860
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expected)
6961

62+
expectedWeights := map[string]float64{
63+
"infra-backend-v1": 0.7,
64+
"infra-backend-v2": 0.3,
65+
"infra-backend-v3": 0.0,
66+
}
67+
68+
sender := newHTTPRequestSender(t, suite, gwAddr, expected)
69+
7070
for i := 0; i < 10; i++ {
71-
if err := testDistribution(t, suite, gwAddr, expected); err != nil {
71+
if err := testWeightedDistribution(sender, expectedWeights); err != nil {
7272
t.Logf("Traffic distribution test failed (%d/10): %s", i+1, err)
7373
} else {
7474
return
@@ -79,80 +79,3 @@ var HTTPRouteWeight = suite.ConformanceTest{
7979
},
8080
}
8181

82-
func testDistribution(t *testing.T, suite *suite.ConformanceTestSuite, gwAddr string, expected http.ExpectedResponse) error {
83-
const (
84-
concurrentRequests = 10
85-
tolerancePercentage = 0.05
86-
totalRequests = 500.0
87-
)
88-
var (
89-
roundTripper = suite.RoundTripper
90-
91-
g errgroup.Group
92-
seenMutex sync.Mutex
93-
seen = make(map[string]float64, 3 /* number of backends */)
94-
req = http.MakeRequest(t, &expected, gwAddr, "HTTP", "http")
95-
expectedWeights = map[string]float64{
96-
"infra-backend-v1": 0.7,
97-
"infra-backend-v2": 0.3,
98-
"infra-backend-v3": 0.0,
99-
}
100-
)
101-
g.SetLimit(concurrentRequests)
102-
for i := 0.0; i < totalRequests; i++ {
103-
g.Go(func() error {
104-
cReq, cRes, err := roundTripper.CaptureRoundTrip(req)
105-
if err != nil {
106-
return fmt.Errorf("failed to roundtrip request: %w", err)
107-
}
108-
if err := http.CompareRoundTrip(t, &req, cReq, cRes, expected); err != nil {
109-
return fmt.Errorf("response expectation failed for request: %w", err)
110-
}
111-
112-
seenMutex.Lock()
113-
defer seenMutex.Unlock()
114-
115-
for expectedBackend := range expectedWeights {
116-
if strings.HasPrefix(cReq.Pod, expectedBackend) {
117-
seen[expectedBackend]++
118-
return nil
119-
}
120-
}
121-
122-
return fmt.Errorf("request was handled by an unexpected pod %q", cReq.Pod)
123-
})
124-
}
125-
126-
if err := g.Wait(); err != nil {
127-
return fmt.Errorf("error while sending requests: %w", err)
128-
}
129-
130-
var errs []error
131-
if len(seen) != 2 {
132-
errs = append(errs, fmt.Errorf("expected only two backends to receive traffic"))
133-
}
134-
135-
for wantBackend, wantPercent := range expectedWeights {
136-
gotCount, ok := seen[wantBackend]
137-
138-
if !ok && wantPercent != 0.0 {
139-
errs = append(errs, fmt.Errorf("expect traffic to hit backend %q - but none was received", wantBackend))
140-
continue
141-
}
142-
143-
gotPercent := gotCount / totalRequests
144-
145-
if math.Abs(gotPercent-wantPercent) > tolerancePercentage {
146-
errs = append(errs, fmt.Errorf("backend %q weighted traffic of %v not within tolerance %v (+/-%f)",
147-
wantBackend,
148-
gotPercent,
149-
wantPercent,
150-
tolerancePercentage,
151-
))
152-
}
153-
}
154-
slices.SortFunc(errs, func(a, b error) int {
155-
return cmp.Compare(a.Error(), b.Error())
156-
})
157-
return errors.Join(errs...)
158-
}

0 commit comments

Comments
 (0)