@@ -22,15 +22,16 @@ import (
22
22
"fmt"
23
23
"strings"
24
24
"testing"
25
+ "time"
25
26
26
27
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"
29
29
"k8s.io/client-go/kubernetes/scheme"
30
30
"k8s.io/client-go/rest"
31
31
"k8s.io/client-go/tools/remotecommand"
32
32
"sigs.k8s.io/controller-runtime/pkg/client"
33
33
34
+ "sigs.k8s.io/gateway-api/conformance/utils/config"
34
35
"sigs.k8s.io/gateway-api/conformance/utils/http"
35
36
"sigs.k8s.io/gateway-api/conformance/utils/suite"
36
37
)
@@ -40,6 +41,7 @@ import (
40
41
type MeshPod struct {
41
42
Name string
42
43
Namespace string
44
+ Address string
43
45
rc * rest.RESTClient
44
46
rcfg * rest.Config
45
47
}
@@ -51,42 +53,73 @@ const (
51
53
MeshAppEchoV2 MeshApplication = "app=echo,version=v2"
52
54
)
53
55
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 {
56
79
protocol := strings .ToLower (r .Protocol )
57
80
if protocol == "" {
58
81
protocol = "http"
59
82
}
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 )}
61
84
if r .Method != "" {
62
85
args = append (args , "--method=" + r .Method )
63
86
}
64
- if ! r .UnfollowRedirect {
65
- args = append (args , "--follow-redirects" )
66
- }
67
87
for k , v := range r .Headers {
68
88
args = append (args , "-H" , fmt .Sprintf ("%v: %v" , k , v ))
69
89
}
90
+ return args
91
+ }
70
92
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 ))
72
95
if err != nil {
73
96
t .Fatalf ("Got error: %v" , err )
74
97
}
75
98
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 {
76
105
want := exp .Response
77
106
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 )
79
108
}
80
109
for _ , name := range want .AbsentHeaders {
81
110
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 )
83
112
}
84
113
}
85
114
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 )
88
117
}
89
118
}
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
90
123
}
91
124
92
125
func (m * MeshPod ) request (args []string ) (Response , error ) {
@@ -129,26 +162,25 @@ func (m *MeshPod) request(args []string) (Response, error) {
129
162
func ConnectToApp (t * testing.T , s * suite.ConformanceTestSuite , app MeshApplication ) MeshPod {
130
163
// hardcoded, for now
131
164
ns := "gateway-conformance-mesh"
132
- metaList := & metav1.PartialObjectMetadataList {}
133
- metaList .SetGroupVersionKind (schema.GroupVersionKind {
134
- Group : "" ,
135
- Version : "v1" ,
136
- Kind : "PodList" ,
137
- })
138
165
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 })
140
170
if err != nil {
141
171
t .Fatalf ("failed to query pods in app %v" , app )
142
172
}
143
- if len (metaList .Items ) == 0 {
173
+ if len (podsList .Items ) == 0 {
144
174
t .Fatalf ("no pods found in app %v" , app )
145
175
}
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
148
179
149
180
return MeshPod {
150
181
Name : podName ,
151
182
Namespace : podNamespace ,
183
+ Address : pod .Status .PodIP ,
152
184
rc : s .RESTClient ,
153
185
rcfg : s .RestConfig ,
154
186
}
0 commit comments