istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/kube/controllers/common_test.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package controllers
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  
    21  	"go.uber.org/atomic"
    22  	appsv1 "k8s.io/api/apps/v1"
    23  	corev1 "k8s.io/api/core/v1"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/types"
    26  	"k8s.io/client-go/tools/cache"
    27  
    28  	"istio.io/istio/pkg/config/schema/gvk"
    29  	"istio.io/istio/pkg/test"
    30  	"istio.io/istio/pkg/test/util/assert"
    31  	"istio.io/istio/pkg/test/util/retry"
    32  )
    33  
    34  func TestEnqueueForParentHandler(t *testing.T) {
    35  	var written atomic.String
    36  	q := NewQueue("test", WithReconciler(func(key types.NamespacedName) error {
    37  		t.Logf("got event %v", key)
    38  		written.Store(key.String())
    39  		return nil
    40  	}))
    41  	go q.Run(test.NewStop(t))
    42  	handler := EnqueueForParentHandler(q, gvk.Deployment)
    43  	handler(&corev1.Pod{
    44  		ObjectMeta: metav1.ObjectMeta{
    45  			Name:            "pod",
    46  			Namespace:       "ns",
    47  			OwnerReferences: []metav1.OwnerReference{},
    48  		},
    49  	})
    50  	if got := written.Load(); got != "" {
    51  		t.Fatalf("unexpectedly enqueued %v", got)
    52  	}
    53  
    54  	handler(&corev1.Pod{
    55  		ObjectMeta: metav1.ObjectMeta{
    56  			Name:      "pod",
    57  			Namespace: "ns",
    58  			OwnerReferences: []metav1.OwnerReference{{
    59  				APIVersion: gvk.Deployment.GroupVersion(),
    60  				Kind:       gvk.Deployment.Kind,
    61  				Name:       "deployment",
    62  				UID:        "1234",
    63  			}},
    64  		},
    65  	})
    66  	retry.UntilOrFail(t, func() bool {
    67  		return written.Load() == "ns/deployment"
    68  	}, retry.Timeout(time.Second*5))
    69  	written.Store("")
    70  
    71  	handler(&corev1.Pod{
    72  		ObjectMeta: metav1.ObjectMeta{
    73  			Name:      "pod",
    74  			Namespace: "ns",
    75  			OwnerReferences: []metav1.OwnerReference{{
    76  				APIVersion: gvk.ReferenceGrant.GroupVersion(),
    77  				Kind:       gvk.ReferenceGrant.Kind,
    78  				Name:       "wrong-type",
    79  				UID:        "1234",
    80  			}},
    81  		},
    82  	})
    83  	if got := written.Load(); got != "" {
    84  		t.Fatalf("unexpectedly enqueued %v", got)
    85  	}
    86  
    87  	handler = EnqueueForParentHandler(q, gvk.KubernetesGateway)
    88  	handler(&appsv1.Deployment{
    89  		ObjectMeta: metav1.ObjectMeta{
    90  			Name:      "gateway-deployment",
    91  			Namespace: "ns",
    92  			OwnerReferences: []metav1.OwnerReference{{
    93  				APIVersion: gvk.KubernetesGateway.GroupVersion(),
    94  				Kind:       gvk.KubernetesGateway.Kind,
    95  				Name:       "gateway",
    96  				UID:        "1234",
    97  			}},
    98  		},
    99  	})
   100  	retry.UntilOrFail(t, func() bool {
   101  		return written.Load() == "ns/gateway"
   102  	}, retry.Timeout(time.Second*5))
   103  	written.Store("")
   104  
   105  	gatewayv1alpha2 := gvk.KubernetesGateway
   106  	gatewayv1alpha2.Version = "v1alpha2"
   107  	handler = EnqueueForParentHandler(q, gvk.KubernetesGateway)
   108  	handler(&appsv1.Deployment{
   109  		ObjectMeta: metav1.ObjectMeta{
   110  			Name:      "gateway-deployment",
   111  			Namespace: "ns",
   112  			OwnerReferences: []metav1.OwnerReference{{
   113  				APIVersion: gatewayv1alpha2.GroupVersion(),
   114  				Kind:       gatewayv1alpha2.Kind,
   115  				Name:       "gateway",
   116  				UID:        "1234",
   117  			}},
   118  		},
   119  	})
   120  	retry.UntilOrFail(t, func() bool {
   121  		return written.Load() == "ns/gateway"
   122  	}, retry.Timeout(time.Second*5))
   123  }
   124  
   125  func TestExtract(t *testing.T) {
   126  	obj := &corev1.Pod{}
   127  	tombstone := cache.DeletedFinalStateUnknown{
   128  		Obj: obj,
   129  	}
   130  	random := time.Time{}
   131  
   132  	t.Run("extract typed", func(t *testing.T) {
   133  		assert.Equal(t, Extract[*corev1.Pod](obj), obj)
   134  		assert.Equal(t, Extract[*corev1.Pod](random), nil)
   135  		assert.Equal(t, Extract[*corev1.Pod](tombstone), obj)
   136  	})
   137  
   138  	t.Run("extract object", func(t *testing.T) {
   139  		assert.Equal(t, Extract[Object](obj), Object(obj))
   140  		assert.Equal(t, Extract[Object](obj), Object(obj))
   141  		assert.Equal(t, Extract[Object](random), nil)
   142  	})
   143  
   144  	t.Run("extract mismatch", func(t *testing.T) {
   145  		assert.Equal(t, Extract[*corev1.Service](random), nil)
   146  		assert.Equal(t, Extract[*corev1.Service](tombstone), nil)
   147  		assert.Equal(t, Extract[*corev1.Service](tombstone), nil)
   148  	})
   149  }