4
4
"context"
5
5
"fmt"
6
6
"io"
7
+ "io/ioutil"
7
8
"net"
8
9
"sort"
9
10
"testing"
@@ -13,6 +14,7 @@ import (
13
14
"github.com/Nitro/sidecar/config"
14
15
"github.com/Nitro/sidecar/envoy/adapter"
15
16
"github.com/Nitro/sidecar/service"
17
+
16
18
api "github.com/envoyproxy/go-control-plane/envoy/api/v2"
17
19
core "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
18
20
hcm "github.com/envoyproxy/go-control-plane/envoy/config/filter/network/http_connection_manager/v2"
@@ -22,11 +24,15 @@ import (
22
24
"github.com/envoyproxy/go-control-plane/pkg/resource/v2"
23
25
xds "github.com/envoyproxy/go-control-plane/pkg/server/v2"
24
26
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
27
+
25
28
"github.com/golang/protobuf/ptypes"
26
29
"github.com/golang/protobuf/ptypes/any"
30
+ "google.golang.org/grpc"
31
+
27
32
"github.com/relistan/go-director"
33
+ log "github.com/sirupsen/logrus"
34
+
28
35
. "github.com/smartystreets/goconvey/convey"
29
- "google.golang.org/grpc"
30
36
)
31
37
32
38
const (
@@ -53,7 +59,8 @@ func validateListener(serialisedListener *any.Any, svc service.Service) {
53
59
filters := filterChains [0 ].GetFilters ()
54
60
So (filters , ShouldHaveLength , 1 )
55
61
56
- if svc .ProxyMode == "http" {
62
+ switch svc .ProxyMode {
63
+ case "http" :
57
64
So (filters [0 ].GetName (), ShouldEqual , wellknown .HTTPConnectionManager )
58
65
connectionManager := & hcm.HttpConnectionManager {}
59
66
err = ptypes .UnmarshalAny (filters [0 ].GetTypedConfig (), connectionManager )
@@ -68,13 +75,33 @@ func validateListener(serialisedListener *any.Any, svc service.Service) {
68
75
So (route , ShouldNotBeNil )
69
76
So (route .GetCluster (), ShouldEqual , adapter .SvcName (svc .Name , svc .Ports [0 ].ServicePort ))
70
77
So (route .GetTimeout (), ShouldNotBeNil )
71
- } else { // tcp
78
+ case " tcp" :
72
79
So (filters [0 ].GetName (), ShouldEqual , wellknown .TCPProxy )
73
80
connectionManager := & tcpp.TcpProxy {}
74
81
err = ptypes .UnmarshalAny (filters [0 ].GetTypedConfig (), connectionManager )
75
82
So (err , ShouldBeNil )
76
83
So (connectionManager .GetStatPrefix (), ShouldEqual , "ingress_tcp" )
77
84
So (connectionManager .GetCluster (), ShouldEqual , adapter .SvcName (svc .Name , svc .Ports [0 ].ServicePort ))
85
+ case "ws" :
86
+ So (filters [0 ].GetName (), ShouldEqual , wellknown .HTTPConnectionManager )
87
+ connectionManager := & hcm.HttpConnectionManager {}
88
+ err = ptypes .UnmarshalAny (filters [0 ].GetTypedConfig (), connectionManager )
89
+ So (err , ShouldBeNil )
90
+ So (connectionManager .GetStatPrefix (), ShouldEqual , "ingress_http" )
91
+ So (connectionManager .GetRouteConfig (), ShouldNotBeNil )
92
+ So (connectionManager .GetRouteConfig ().GetVirtualHosts (), ShouldHaveLength , 1 )
93
+ virtualHost := connectionManager .GetRouteConfig ().GetVirtualHosts ()[0 ]
94
+ So (virtualHost .GetName (), ShouldEqual , svc .Name )
95
+ So (virtualHost .GetRoutes (), ShouldHaveLength , 1 )
96
+ route := virtualHost .GetRoutes ()[0 ].GetRoute ()
97
+ So (route , ShouldNotBeNil )
98
+ So (route .GetCluster (), ShouldEqual , adapter .SvcName (svc .Name , svc .Ports [0 ].ServicePort ))
99
+ So (route .GetTimeout (), ShouldNotBeNil )
100
+
101
+ // websocket stuff
102
+ upgradeConfigs := connectionManager .GetUpgradeConfigs ()
103
+ So (len (upgradeConfigs ), ShouldEqual , 1 )
104
+ So (upgradeConfigs [0 ].UpgradeType , ShouldEqual , "websocket" )
78
105
}
79
106
}
80
107
@@ -137,7 +164,8 @@ func (sv *EnvoyMock) GetResource(stream envoy_discovery.AggregatedDiscoveryServi
137
164
So (err , ShouldBeNil )
138
165
}
139
166
140
- // Recv() blocks until the stream ctx expires if the message sent via Send() is not recognised / valid
167
+ // Recv() blocks until the stream ctx expires if the message sent via
168
+ // Send() is not recognised / valid
141
169
response , err := stream .Recv ()
142
170
143
171
So (err , ShouldBeNil )
@@ -155,8 +183,8 @@ func (sv *EnvoyMock) ValidateResources(stream envoy_discovery.AggregatedDiscover
155
183
}
156
184
}
157
185
158
- // SnapshotCache is a light wrapper around cache.SnapshotCache which lets
159
- // us get a notification after calling SetSnapshot via the Waiter chan
186
+ // SnapshotCache is a light wrapper around cache.SnapshotCache which lets us
187
+ // get a notification after calling SetSnapshot via the Waiter chan
160
188
type SnapshotCache struct {
161
189
cache.SnapshotCache
162
190
Waiter chan struct {}
@@ -184,6 +212,8 @@ func Test_PortForServicePort(t *testing.T) {
184
212
BindIP : bindIP ,
185
213
}
186
214
215
+ log .SetOutput (ioutil .Discard )
216
+
187
217
state := catalog .NewServicesState ()
188
218
189
219
dummyHostname := "carcasone"
@@ -227,6 +257,19 @@ func Test_PortForServicePort(t *testing.T) {
227
257
},
228
258
}
229
259
260
+ wsSvc := service.Service {
261
+ ID : "deadbeef666" ,
262
+ Name : "kafka" ,
263
+ Created : baseTime ,
264
+ Hostname : dummyHostname ,
265
+ Updated : baseTime ,
266
+ Status : service .ALIVE ,
267
+ ProxyMode : "ws" ,
268
+ Ports : []service.Port {
269
+ {IP : "127.0.0.1" , Port : 6666 , ServicePort : 10102 },
270
+ },
271
+ }
272
+
230
273
ctx , cancel := context .WithCancel (context .Background ())
231
274
Reset (func () {
232
275
cancel ()
@@ -242,14 +285,14 @@ func Test_PortForServicePort(t *testing.T) {
242
285
xdsServer : xds .NewServer (ctx , snapshotCache , & xdsCallbacks {}),
243
286
}
244
287
245
- // The gRPC listener will be assigned a random port and will be owned and managed
246
- // by the gRPC server
288
+ // The gRPC listener will be assigned a random port and will be owned
289
+ // and managed by the gRPC server
247
290
lis , err := net .Listen ("tcp" , ":0" )
248
291
So (err , ShouldBeNil )
249
292
So (lis .Addr (), ShouldHaveSameTypeAs , & net.TCPAddr {})
250
293
251
- // Using a FreeLooper instead would make it run too often, triggering spurious
252
- // locking on the state, which can cause the tests to time out
294
+ // Using a FreeLooper instead would make it run too often, triggering
295
+ // spurious locking on the state, which can cause the tests to time out
253
296
go server .Run (ctx , director .NewTimedLooper (director .FOREVER , 10 * time .Millisecond , make (chan error )), lis )
254
297
255
298
Convey ("sends the Envoy state via gRPC" , func () {
@@ -317,6 +360,13 @@ func Test_PortForServicePort(t *testing.T) {
317
360
envoyMock .ValidateResources (stream , tcpSvc , state .Hostname )
318
361
})
319
362
363
+ Convey ("for a Websocket service" , func () {
364
+ state .AddServiceEntry (wsSvc )
365
+ <- snapshotCache .Waiter
366
+
367
+ envoyMock .ValidateResources (stream , wsSvc , state .Hostname )
368
+ })
369
+
320
370
Convey ("and skips tombstones" , func () {
321
371
httpSvc .Tombstone ()
322
372
state .AddServiceEntry (httpSvc )
0 commit comments