@@ -28,6 +28,7 @@ import (
28
28
29
29
"github.com/onsi/ginkgo"
30
30
v1 "k8s.io/api/core/v1"
31
+ discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
31
32
policyv1beta1 "k8s.io/api/policy/v1beta1"
32
33
apierrors "k8s.io/apimachinery/pkg/api/errors"
33
34
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -352,6 +353,8 @@ func (j *TestJig) waitForAvailableEndpoint(timeout time.Duration) error {
352
353
endpointSelector := fields .OneTermEqualSelector ("metadata.name" , j .Name )
353
354
stopCh := make (chan struct {})
354
355
endpointAvailable := false
356
+ endpointSliceAvailable := false
357
+
355
358
var controller cache.Controller
356
359
_ , controller = cache .NewInformer (
357
360
& cache.ListWatch {
@@ -390,8 +393,54 @@ func (j *TestJig) waitForAvailableEndpoint(timeout time.Duration) error {
390
393
391
394
go controller .Run (stopCh )
392
395
396
+ // If EndpointSlice API is enabled, then validate if appropriate EndpointSlice objects were also create/updated/deleted.
397
+ if _ , err := j .Client .Discovery ().ServerResourcesForGroupVersion (discoveryv1beta1 .SchemeGroupVersion .String ()); err == nil {
398
+ var esController cache.Controller
399
+ _ , esController = cache .NewInformer (
400
+ & cache.ListWatch {
401
+ ListFunc : func (options metav1.ListOptions ) (runtime.Object , error ) {
402
+ options .LabelSelector = "kubernetes.io/service-name=" + j .Name
403
+ obj , err := j .Client .DiscoveryV1beta1 ().EndpointSlices (j .Namespace ).List (context .TODO (), options )
404
+ return runtime .Object (obj ), err
405
+ },
406
+ WatchFunc : func (options metav1.ListOptions ) (watch.Interface , error ) {
407
+ options .LabelSelector = "kubernetes.io/service-name=" + j .Name
408
+ return j .Client .DiscoveryV1beta1 ().EndpointSlices (j .Namespace ).Watch (context .TODO (), options )
409
+ },
410
+ },
411
+ & discoveryv1beta1.EndpointSlice {},
412
+ 0 ,
413
+ cache.ResourceEventHandlerFuncs {
414
+ AddFunc : func (obj interface {}) {
415
+ if es , ok := obj .(* discoveryv1beta1.EndpointSlice ); ok {
416
+ // TODO: currently we only consider addreses in 1 slice, but services with
417
+ // a large number of endpoints (>1000) may have multiple slices. Some slices
418
+ // with only a few addresses. We should check the addresses in all slices.
419
+ if len (es .Endpoints ) > 0 && len (es .Endpoints [0 ].Addresses ) > 0 {
420
+ endpointSliceAvailable = true
421
+ }
422
+ }
423
+ },
424
+ UpdateFunc : func (old , cur interface {}) {
425
+ if es , ok := cur .(* discoveryv1beta1.EndpointSlice ); ok {
426
+ // TODO: currently we only consider addreses in 1 slice, but services with
427
+ // a large number of endpoints (>1000) may have multiple slices. Some slices
428
+ // with only a few addresses. We should check the addresses in all slices.
429
+ if len (es .Endpoints ) > 0 && len (es .Endpoints [0 ].Addresses ) > 0 {
430
+ endpointSliceAvailable = true
431
+ }
432
+ }
433
+ },
434
+ },
435
+ )
436
+
437
+ go esController .Run (stopCh )
438
+
439
+ } else {
440
+ endpointSliceAvailable = true
441
+ }
393
442
err := wait .Poll (1 * time .Second , timeout , func () (bool , error ) {
394
- return endpointAvailable , nil
443
+ return endpointAvailable && endpointSliceAvailable , nil
395
444
})
396
445
if err != nil {
397
446
return fmt .Errorf ("no subset of available IP address found for the endpoint %s within timeout %v" , j .Name , timeout )
0 commit comments