Skip to content

Commit ac5b0bb

Browse files
authored
Merge pull request #2017 from keithmattix/mesh-conformance-fixes
Fixes for mesh conformance tests
2 parents 2f86450 + 0e082d8 commit ac5b0bb

File tree

2 files changed

+56
-24
lines changed

2 files changed

+56
-24
lines changed

conformance/tests/mesh-split.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ var MeshTrafficSplit = suite.ConformanceTest{
6666
// reuse issues across parallel tests.
6767
tc := cases[i]
6868
t.Run(tc.GetTestCaseName(i), func(t *testing.T) {
69-
client.SendRequest(t, tc)
69+
client.MakeRequestAndExpectEventuallyConsistentResponse(t, tc, s.TimeoutConfig)
7070
})
7171
}
7272
},

conformance/utils/echo/pod.go

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ import (
2222
"fmt"
2323
"strings"
2424
"testing"
25+
"time"
2526

2627
v1 "k8s.io/api/core/v1"
27-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28-
"k8s.io/apimachinery/pkg/runtime/schema"
28+
klabels "k8s.io/apimachinery/pkg/labels"
2929
"k8s.io/client-go/kubernetes/scheme"
3030
"k8s.io/client-go/rest"
3131
"k8s.io/client-go/tools/remotecommand"
3232
"sigs.k8s.io/controller-runtime/pkg/client"
3333

34+
"sigs.k8s.io/gateway-api/conformance/utils/config"
3435
"sigs.k8s.io/gateway-api/conformance/utils/http"
3536
"sigs.k8s.io/gateway-api/conformance/utils/suite"
3637
)
@@ -40,6 +41,7 @@ import (
4041
type MeshPod struct {
4142
Name string
4243
Namespace string
44+
Address string
4345
rc *rest.RESTClient
4446
rcfg *rest.Config
4547
}
@@ -51,42 +53,73 @@ const (
5153
MeshAppEchoV2 MeshApplication = "app=echo,version=v2"
5254
)
5355

54-
func (m *MeshPod) SendRequest(t *testing.T, exp http.ExpectedResponse) {
55-
r := exp.Request
56+
func (m *MeshPod) MakeRequestAndExpectEventuallyConsistentResponse(t *testing.T, exp http.ExpectedResponse, timeoutConfig config.TimeoutConfig) {
57+
t.Helper()
58+
59+
req := makeRequest(exp.Request)
60+
61+
http.AwaitConvergence(t, timeoutConfig.RequiredConsecutiveSuccesses, timeoutConfig.MaxTimeToConsistency, func(elapsed time.Duration) bool {
62+
resp, err := m.request(makeRequest(exp.Request))
63+
if err != nil {
64+
t.Logf("Request failed, not ready yet: %v (after %v)", err.Error(), elapsed)
65+
return false
66+
}
67+
t.Logf("Got resp %v", resp)
68+
if err := compareRequest(exp, resp); err != nil {
69+
t.Logf("Response expectation failed for request: %v not ready yet: %v (after %v)", req, err, elapsed)
70+
return false
71+
}
72+
return true
73+
})
74+
75+
t.Logf("Request passed")
76+
}
77+
78+
func makeRequest(r http.Request) []string {
5679
protocol := strings.ToLower(r.Protocol)
5780
if protocol == "" {
5881
protocol = "http"
5982
}
60-
args := []string{"client", fmt.Sprintf("%s://%s/%s", protocol, r.Host, r.Path)}
83+
args := []string{"client", fmt.Sprintf("%s://%s%s", protocol, r.Host, r.Path)}
6184
if r.Method != "" {
6285
args = append(args, "--method="+r.Method)
6386
}
64-
if !r.UnfollowRedirect {
65-
args = append(args, "--follow-redirects")
66-
}
6787
for k, v := range r.Headers {
6888
args = append(args, "-H", fmt.Sprintf("%v: %v", k, v))
6989
}
90+
return args
91+
}
7092

71-
resp, err := m.request(args)
93+
func (m *MeshPod) SendRequest(t *testing.T, exp http.ExpectedResponse) {
94+
resp, err := m.request(makeRequest(exp.Request))
7295
if err != nil {
7396
t.Fatalf("Got error: %v", err)
7497
}
7598
t.Logf("Got resp %v", resp)
99+
if err := compareRequest(exp, resp); err != nil {
100+
t.Fatalf("expectations failed: %v", err)
101+
}
102+
}
103+
104+
func compareRequest(exp http.ExpectedResponse, resp Response) error {
76105
want := exp.Response
77106
if fmt.Sprint(want.StatusCode) != resp.Code {
78-
t.Errorf("wanted status code %v, got %v", want.StatusCode, resp.Code)
107+
return fmt.Errorf("wanted status code %v, got %v", want.StatusCode, resp.Code)
79108
}
80109
for _, name := range want.AbsentHeaders {
81110
if v := resp.ResponseHeaders.Values(name); len(v) != 0 {
82-
t.Errorf("expected no header %q, got %v", name, v)
111+
return fmt.Errorf("expected no header %q, got %v", name, v)
83112
}
84113
}
85114
for k, v := range want.Headers {
86-
if got := resp.RequestHeaders.Get(k); got != v {
87-
t.Errorf("expected header %v=%v, got %v", k, v, got)
115+
if got := resp.ResponseHeaders.Get(k); got != v {
116+
return fmt.Errorf("expected header %v=%v, got %v", k, v, got)
88117
}
89118
}
119+
if !strings.HasPrefix(resp.Hostname, exp.Backend) {
120+
return fmt.Errorf("expected pod name to start with %s, got %s", exp.Backend, resp.Hostname)
121+
}
122+
return nil
90123
}
91124

92125
func (m *MeshPod) request(args []string) (Response, error) {
@@ -129,26 +162,25 @@ func (m *MeshPod) request(args []string) (Response, error) {
129162
func ConnectToApp(t *testing.T, s *suite.ConformanceTestSuite, app MeshApplication) MeshPod {
130163
// hardcoded, for now
131164
ns := "gateway-conformance-mesh"
132-
metaList := &metav1.PartialObjectMetadataList{}
133-
metaList.SetGroupVersionKind(schema.GroupVersionKind{
134-
Group: "",
135-
Version: "v1",
136-
Kind: "PodList",
137-
})
138165

139-
err := s.Client.List(context.Background(), metaList, client.InNamespace(ns), client.HasLabels(strings.Split(string(app), ",")))
166+
lbls, _ := klabels.Parse(string(app))
167+
168+
podsList := v1.PodList{}
169+
err := s.Client.List(context.Background(), &podsList, client.InNamespace(ns), client.MatchingLabelsSelector{Selector: lbls})
140170
if err != nil {
141171
t.Fatalf("failed to query pods in app %v", app)
142172
}
143-
if len(metaList.Items) == 0 {
173+
if len(podsList.Items) == 0 {
144174
t.Fatalf("no pods found in app %v", app)
145175
}
146-
podName := metaList.Items[0].Name
147-
podNamespace := metaList.Items[0].Namespace
176+
pod := podsList.Items[0]
177+
podName := pod.Name
178+
podNamespace := pod.Namespace
148179

149180
return MeshPod{
150181
Name: podName,
151182
Namespace: podNamespace,
183+
Address: pod.Status.PodIP,
152184
rc: s.RESTClient,
153185
rcfg: s.RestConfig,
154186
}

0 commit comments

Comments
 (0)