@@ -4,10 +4,12 @@ import (
4
4
"context"
5
5
"errors"
6
6
7
+ ngxclient "github.com/nginxinc/nginx-plus-go-client/client"
7
8
. "github.com/onsi/ginkgo/v2"
8
9
. "github.com/onsi/gomega"
9
10
"go.uber.org/zap"
10
11
v1 "k8s.io/api/core/v1"
12
+ discoveryV1 "k8s.io/api/discovery/v1"
11
13
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12
14
"k8s.io/apimachinery/pkg/types"
13
15
"k8s.io/client-go/tools/record"
@@ -27,6 +29,7 @@ import (
27
29
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file"
28
30
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file/filefakes"
29
31
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime/runtimefakes"
32
+ "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state"
30
33
staticConds "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/conditions"
31
34
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane"
32
35
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/graph"
@@ -64,6 +67,7 @@ var _ = Describe("eventHandler", func() {
64
67
65
68
BeforeEach (func () {
66
69
fakeProcessor = & statefakes.FakeChangeProcessor {}
70
+ fakeProcessor .ProcessReturns (state .NoChange , & graph.Graph {})
67
71
fakeGenerator = & configfakes.FakeGenerator {}
68
72
fakeNginxFileMgr = & filefakes.FakeManager {}
69
73
fakeNginxRuntimeMgr = & runtimefakes.FakeManager {}
@@ -112,7 +116,7 @@ var _ = Describe("eventHandler", func() {
112
116
}
113
117
114
118
BeforeEach (func () {
115
- fakeProcessor .ProcessReturns (true /* changed */ , & graph.Graph {})
119
+ fakeProcessor .ProcessReturns (state . ClusterStateChange /* changed */ , & graph.Graph {})
116
120
117
121
fakeGenerator .GenerateReturns (fakeCfgFiles )
118
122
})
@@ -280,11 +284,129 @@ var _ = Describe("eventHandler", func() {
280
284
})
281
285
})
282
286
287
+ When ("receiving an EndpointsOnlyChange update" , func () {
288
+ e := & events.UpsertEvent {Resource : & discoveryV1.EndpointSlice {
289
+ ObjectMeta : metav1.ObjectMeta {
290
+ Name : "nginx-gateway" ,
291
+ Namespace : "nginx-gateway" ,
292
+ },
293
+ }}
294
+ batch := []interface {}{e }
295
+
296
+ BeforeEach (func () {
297
+ fakeProcessor .ProcessReturns (state .EndpointsOnlyChange , & graph.Graph {})
298
+ upstreams := ngxclient.Upstreams {
299
+ "one" : ngxclient.Upstream {
300
+ Peers : []ngxclient.Peer {
301
+ {Server : "server1" },
302
+ },
303
+ },
304
+ }
305
+ fakeNginxRuntimeMgr .GetUpstreamsReturns (upstreams , nil )
306
+ })
307
+
308
+ When ("running NGINX Plus" , func () {
309
+ It ("should call the NGINX Plus API" , func () {
310
+ fakeNginxRuntimeMgr .IsPlusReturns (true )
311
+
312
+ handler .HandleEventBatch (context .Background (), ctlrZap .New (), batch )
313
+ Expect (fakeGenerator .GenerateCallCount ()).To (Equal (1 ))
314
+ Expect (fakeNginxFileMgr .ReplaceFilesCallCount ()).To (Equal (1 ))
315
+ Expect (fakeNginxRuntimeMgr .GetUpstreamsCallCount ()).To (Equal (1 ))
316
+ })
317
+ })
318
+
319
+ When ("not running NGINX Plus" , func () {
320
+ It ("should not call the NGINX Plus API" , func () {
321
+ handler .HandleEventBatch (context .Background (), ctlrZap .New (), batch )
322
+ Expect (fakeGenerator .GenerateCallCount ()).To (Equal (1 ))
323
+ Expect (fakeNginxFileMgr .ReplaceFilesCallCount ()).To (Equal (1 ))
324
+ Expect (fakeNginxRuntimeMgr .GetUpstreamsCallCount ()).To (Equal (0 ))
325
+ Expect (fakeNginxRuntimeMgr .ReloadCallCount ()).To (Equal (1 ))
326
+ })
327
+ })
328
+ })
329
+
330
+ When ("updating upstream servers" , func () {
331
+ conf := dataplane.Configuration {
332
+ Upstreams : []dataplane.Upstream {
333
+ {
334
+ Name : "one" ,
335
+ },
336
+ },
337
+ }
338
+
339
+ type callCounts struct {
340
+ generate int
341
+ update int
342
+ reload int
343
+ }
344
+
345
+ assertCallCounts := func (cc callCounts ) {
346
+ Expect (fakeGenerator .GenerateCallCount ()).To (Equal (cc .generate ))
347
+ Expect (fakeNginxFileMgr .ReplaceFilesCallCount ()).To (Equal (cc .generate ))
348
+ Expect (fakeNginxRuntimeMgr .UpdateHTTPServersCallCount ()).To (Equal (cc .update ))
349
+ Expect (fakeNginxRuntimeMgr .ReloadCallCount ()).To (Equal (cc .reload ))
350
+ }
351
+
352
+ BeforeEach (func () {
353
+ upstreams := ngxclient.Upstreams {
354
+ "one" : ngxclient.Upstream {
355
+ Peers : []ngxclient.Peer {
356
+ {Server : "server1" },
357
+ },
358
+ },
359
+ }
360
+ fakeNginxRuntimeMgr .GetUpstreamsReturns (upstreams , nil )
361
+ })
362
+
363
+ When ("running NGINX Plus" , func () {
364
+ BeforeEach (func () {
365
+ fakeNginxRuntimeMgr .IsPlusReturns (true )
366
+ })
367
+
368
+ It ("should update servers using the NGINX Plus API" , func () {
369
+ Expect (handler .updateUpstreamServers (context .Background (), ctlrZap .New (), conf )).To (Succeed ())
370
+
371
+ assertCallCounts (callCounts {generate : 1 , update : 1 , reload : 0 })
372
+ })
373
+
374
+ It ("should reload when GET API returns an error" , func () {
375
+ fakeNginxRuntimeMgr .GetUpstreamsReturns (nil , errors .New ("error" ))
376
+ Expect (handler .updateUpstreamServers (context .Background (), ctlrZap .New (), conf )).To (Succeed ())
377
+
378
+ assertCallCounts (callCounts {generate : 1 , update : 0 , reload : 1 })
379
+ })
380
+
381
+ It ("should reload when POST API returns an error" , func () {
382
+ fakeNginxRuntimeMgr .UpdateHTTPServersReturns (errors .New ("error" ))
383
+ Expect (handler .updateUpstreamServers (context .Background (), ctlrZap .New (), conf )).To (Succeed ())
384
+
385
+ assertCallCounts (callCounts {generate : 1 , update : 1 , reload : 1 })
386
+ })
387
+ })
388
+
389
+ When ("not running NGINX Plus" , func () {
390
+ It ("should update servers by reloading" , func () {
391
+ Expect (handler .updateUpstreamServers (context .Background (), ctlrZap .New (), conf )).To (Succeed ())
392
+
393
+ assertCallCounts (callCounts {generate : 1 , update : 0 , reload : 1 })
394
+ })
395
+
396
+ It ("should return an error when reloading fails" , func () {
397
+ fakeNginxRuntimeMgr .ReloadReturns (errors .New ("error" ))
398
+ Expect (handler .updateUpstreamServers (context .Background (), ctlrZap .New (), conf )).ToNot (Succeed ())
399
+
400
+ assertCallCounts (callCounts {generate : 1 , update : 0 , reload : 1 })
401
+ })
402
+ })
403
+ })
404
+
283
405
It ("should set the health checker status properly when there are changes" , func () {
284
406
e := & events.UpsertEvent {Resource : & gatewayv1.HTTPRoute {}}
285
407
batch := []interface {}{e }
286
408
287
- fakeProcessor .ProcessReturns (true , & graph.Graph {})
409
+ fakeProcessor .ProcessReturns (state . ClusterStateChange , & graph.Graph {})
288
410
289
411
Expect (handler .cfg .healthChecker .readyCheck (nil )).ToNot (Succeed ())
290
412
handler .HandleEventBatch (context .Background (), ctlrZap .New (), batch )
@@ -304,22 +426,22 @@ var _ = Describe("eventHandler", func() {
304
426
e := & events.UpsertEvent {Resource : & gatewayv1.HTTPRoute {}}
305
427
batch := []interface {}{e }
306
428
307
- fakeProcessor .ProcessReturns (true , & graph.Graph {})
429
+ fakeProcessor .ProcessReturns (state . ClusterStateChange , & graph.Graph {})
308
430
fakeNginxRuntimeMgr .ReloadReturns (errors .New ("reload error" ))
309
431
310
432
handler .HandleEventBatch (context .Background (), ctlrZap .New (), batch )
311
433
312
434
Expect (handler .cfg .healthChecker .readyCheck (nil )).ToNot (Succeed ())
313
435
314
436
// now send an update with no changes; should still return an error
315
- fakeProcessor .ProcessReturns (false , & graph.Graph {})
437
+ fakeProcessor .ProcessReturns (state . NoChange , & graph.Graph {})
316
438
317
439
handler .HandleEventBatch (context .Background (), ctlrZap .New (), batch )
318
440
319
441
Expect (handler .cfg .healthChecker .readyCheck (nil )).ToNot (Succeed ())
320
442
321
443
// error goes away
322
- fakeProcessor .ProcessReturns (true , & graph.Graph {})
444
+ fakeProcessor .ProcessReturns (state . ClusterStateChange , & graph.Graph {})
323
445
fakeNginxRuntimeMgr .ReloadReturns (nil )
324
446
325
447
handler .HandleEventBatch (context .Background (), ctlrZap .New (), batch )
@@ -339,6 +461,46 @@ var _ = Describe("eventHandler", func() {
339
461
})
340
462
})
341
463
464
+ var _ = Describe ("serversEqual" , func () {
465
+ DescribeTable ("determines if server lists are equal" ,
466
+ func (newServers []ngxclient.UpstreamServer , oldServers []ngxclient.Peer , equal bool ) {
467
+ Expect (serversEqual (newServers , oldServers )).To (Equal (equal ))
468
+ },
469
+ Entry ("different length" ,
470
+ []ngxclient.UpstreamServer {
471
+ {Server : "server1" },
472
+ },
473
+ []ngxclient.Peer {
474
+ {Server : "server1" },
475
+ {Server : "server2" },
476
+ },
477
+ false ,
478
+ ),
479
+ Entry ("differing elements" ,
480
+ []ngxclient.UpstreamServer {
481
+ {Server : "server1" },
482
+ {Server : "server2" },
483
+ },
484
+ []ngxclient.Peer {
485
+ {Server : "server1" },
486
+ {Server : "server3" },
487
+ },
488
+ false ,
489
+ ),
490
+ Entry ("same elements" ,
491
+ []ngxclient.UpstreamServer {
492
+ {Server : "server1" },
493
+ {Server : "server2" },
494
+ },
495
+ []ngxclient.Peer {
496
+ {Server : "server1" },
497
+ {Server : "server2" },
498
+ },
499
+ true ,
500
+ ),
501
+ )
502
+ })
503
+
342
504
var _ = Describe ("getGatewayAddresses" , func () {
343
505
It ("gets gateway addresses from a Service" , func () {
344
506
fakeClient := fake .NewFakeClient ()
0 commit comments