@@ -26,8 +26,8 @@ import (
26
26
"time"
27
27
28
28
"github.com/stretchr/testify/require"
29
- appsv1 "k8s.io/api/apps/v1"
30
29
corev1 "k8s.io/api/core/v1"
30
+ discoveryv1 "k8s.io/api/discovery/v1"
31
31
apierrors "k8s.io/apimachinery/pkg/api/errors"
32
32
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
33
33
"k8s.io/apimachinery/pkg/types"
@@ -38,6 +38,7 @@ import (
38
38
gatewayk8sutils "sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
39
39
40
40
inferenceapi "sigs.k8s.io/gateway-api-inference-extension/api/v1"
41
+ "sigs.k8s.io/gateway-api-inference-extension/conformance/resources"
41
42
"sigs.k8s.io/gateway-api-inference-extension/conformance/utils/config"
42
43
)
43
44
@@ -328,42 +329,74 @@ func GetPodsWithLabel(t *testing.T, c client.Reader, namespace string, labels ma
328
329
return pods .Items , waitErr
329
330
}
330
331
331
- // DeleteDeployment deletes the specified Deployment and waits until it is no longer
332
- // present in the cluster .
333
- func DeleteDeployment (t * testing.T , c client.Client , timeoutConfig gatewayapiconfig. TimeoutConfig , deploymentRef types. NamespacedName ) error {
332
+ // MakeServiceUnavailable modifies a Service's selector to make it temporarily unavailable.
333
+ // It returns a cleanup function to restore the original selector and ensure the test state is clean .
334
+ func MakeServiceUnavailable (t * testing.T , c client.Client , serviceRef types. NamespacedName , timeout time. Duration ) ( func (), error ) {
334
335
t .Helper ()
335
336
336
- deploymentToDelete := & appsv1.Deployment {
337
- ObjectMeta : metav1.ObjectMeta {
338
- Name : deploymentRef .Name ,
339
- Namespace : deploymentRef .Namespace ,
340
- },
337
+ ctx := context .Background ()
338
+ svc := & corev1.Service {}
339
+
340
+ t .Logf ("Making Service %s/%s unavailable by modifying its selector..." , serviceRef .Namespace , serviceRef .Name )
341
+ if err := c .Get (ctx , serviceRef , svc ); err != nil {
342
+ return nil , fmt .Errorf ("failed to get Service %s/%s: %w" , serviceRef .Namespace , serviceRef .Name , err )
343
+ }
344
+ originalSelector := svc .Spec .Selector
345
+ svc .Spec .Selector = map [string ]string {"app" : "do-not-match-for-testing" }
346
+ if err := c .Update (ctx , svc ); err != nil {
347
+ return nil , fmt .Errorf ("failed to update selector for Service %s/%s: %w" , serviceRef .Namespace , serviceRef .Name , err )
341
348
}
342
349
343
- t .Logf ("Deleting Deployment %s/%s..." , deploymentRef .Namespace , deploymentRef .Name )
344
- if err := c .Delete (context .Background (), deploymentToDelete ); err != nil {
345
- // If the resource is already gone, we don't consider it an error.
346
- if ! apierrors .IsNotFound (err ) {
347
- return fmt .Errorf ("failed to delete Deployment %s/%s: %w" , deploymentRef .Namespace , deploymentRef .Name , err )
348
- }
350
+ t .Logf ("Waiting for EndpointSlices of Service %s/%s to become empty..." , serviceRef .Namespace , serviceRef .Name )
351
+ err := waitNumberOfEndpointsForService (ctx , c , serviceRef , 0 , timeout )
352
+ if err != nil {
353
+ return nil , fmt .Errorf ("timed out waiting for EndpointSlices of Service %s/%s to become empty: %w" , serviceRef .Namespace , serviceRef .Name , err )
349
354
}
355
+ t .Logf ("Successfully modified selector for Service %s/%s" , serviceRef .Namespace , serviceRef .Name )
350
356
351
- // Wait for the Deployment to be fully removed.
352
- waitErr := wait .PollUntilContextTimeout (context .Background (), 1 * time .Second , timeoutConfig .DeleteTimeout , true , func (ctx context.Context ) (bool , error ) {
353
- var dep appsv1.Deployment
354
- err := c .Get (ctx , deploymentRef , & dep )
355
- if apierrors .IsNotFound (err ) {
356
- return true , nil
357
+ cleanupFunc := func () {
358
+ t .Helper ()
359
+ t .Logf ("Restoring original selector for Service %s/%s..." , serviceRef .Namespace , serviceRef .Name )
360
+
361
+ restorationCtx := context .Background ()
362
+ svcToRestore := & corev1.Service {}
363
+
364
+ if err := c .Get (restorationCtx , serviceRef , svcToRestore ); err != nil {
365
+ t .Fatalf ("Cleanup failed: could not get Service %s/%s for restoration: %v" , serviceRef .Namespace , serviceRef .Name , err )
357
366
}
367
+
368
+ svcToRestore .Spec .Selector = originalSelector
369
+ if err := c .Update (restorationCtx , svcToRestore ); err != nil {
370
+ t .Fatalf ("Cleanup failed: could not restore original selector for Service %s/%s: %v" , serviceRef .Namespace , serviceRef .Name , err )
371
+ }
372
+
373
+ t .Logf ("Waiting for EndpointSlices of Service %s/%s to be restored..." , serviceRef .Namespace , serviceRef .Name )
374
+ err := waitNumberOfEndpointsForService (restorationCtx , c , serviceRef , resources .EndPointPickerPodReplicas , timeout )
358
375
if err != nil {
359
- return false , fmt .Errorf ("error waiting for Deployment %s/%s to be deleted: %w" , deploymentRef .Namespace , deploymentRef .Name , err )
376
+ t .Fatalf ("Cleanup failed: timed out waiting for EndpointSlices of Service %s/%s to be restored: %v" , serviceRef .Namespace , serviceRef .Name , err )
377
+ }
378
+ t .Logf ("Successfully restored selector for Service %s/%s" , serviceRef .Namespace , serviceRef .Name )
379
+ }
380
+ return cleanupFunc , nil
381
+ }
382
+
383
+ func waitNumberOfEndpointsForService (ctx context.Context , c client.Client , serviceRef types.NamespacedName , wantNum int , timeout time.Duration ) error {
384
+ err := wait .PollUntilContextTimeout (ctx , 1 * time .Second , timeout , true , func (ctx context.Context ) (bool , error ) {
385
+ endpointSliceList := & discoveryv1.EndpointSliceList {}
386
+ if err := c .List (ctx , endpointSliceList ,
387
+ client .InNamespace (serviceRef .Namespace ),
388
+ client.MatchingLabels {discoveryv1 .LabelServiceName : serviceRef .Name },
389
+ ); err != nil {
390
+ return false , fmt .Errorf ("failed to list EndpointSlices for Service %s: %w" , serviceRef .Name , err )
391
+ }
392
+ totalEndpoints := 0
393
+ for _ , slice := range endpointSliceList .Items {
394
+ totalEndpoints += len (slice .Endpoints )
395
+ }
396
+ if totalEndpoints == wantNum {
397
+ return true , nil
360
398
}
361
399
return false , nil
362
400
})
363
-
364
- if waitErr != nil {
365
- return fmt .Errorf ("timed out waiting for Deployment %s/%s to be deleted: %w" , deploymentRef .Namespace , deploymentRef .Name , waitErr )
366
- }
367
- t .Logf ("Successfully deleted Deployment %s/%s" , deploymentRef .Namespace , deploymentRef .Name )
368
- return nil
401
+ return err
369
402
}
0 commit comments