knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/reconciler/testing/tracker.go (about)

     1  /*
     2  Copyright 2019 The Knative Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package testing
    18  
    19  import (
    20  	"sync"
    21  
    22  	corev1 "k8s.io/api/core/v1"
    23  	"k8s.io/apimachinery/pkg/types"
    24  	"knative.dev/pkg/kmeta"
    25  	"knative.dev/pkg/tracker"
    26  )
    27  
    28  // NullTracker implements Tracker
    29  //
    30  // Alias is preserved for backwards compatibility
    31  type NullTracker = FakeTracker
    32  
    33  // FakeTracker implements Tracker.
    34  type FakeTracker struct {
    35  	sync.Mutex
    36  	references map[tracker.Reference]map[types.NamespacedName]struct{}
    37  }
    38  
    39  var _ tracker.Interface = (*FakeTracker)(nil)
    40  
    41  // OnChanged implements OnChanged.
    42  func (*FakeTracker) OnChanged(interface{}) {}
    43  
    44  // GetObservers implements GetObservers.
    45  func (n *FakeTracker) GetObservers(obj interface{}) []types.NamespacedName {
    46  	item, err := kmeta.DeletionHandlingAccessor(obj)
    47  	if err != nil {
    48  		return nil
    49  	}
    50  
    51  	or := kmeta.ObjectReference(item)
    52  	ref := tracker.Reference{
    53  		APIVersion: or.APIVersion,
    54  		Kind:       or.Kind,
    55  		Namespace:  or.Namespace,
    56  		Name:       or.Name,
    57  	}
    58  
    59  	n.Lock()
    60  	defer n.Unlock()
    61  
    62  	keys := make([]types.NamespacedName, 0, len(n.references[ref]))
    63  	for key := range n.references[ref] {
    64  		keys = append(keys, key)
    65  	}
    66  	return keys
    67  }
    68  
    69  // OnDeletedObserver implements OnDeletedObserver.
    70  func (n *FakeTracker) OnDeletedObserver(obj interface{}) {
    71  	item, err := kmeta.DeletionHandlingAccessor(obj)
    72  	if err != nil {
    73  		return
    74  	}
    75  	key := types.NamespacedName{Namespace: item.GetNamespace(), Name: item.GetName()}
    76  
    77  	n.Lock()
    78  	defer n.Unlock()
    79  
    80  	for ref, objs := range n.references {
    81  		delete(objs, key)
    82  		if len(objs) == 0 {
    83  			delete(n.references, ref)
    84  		}
    85  	}
    86  }
    87  
    88  // Track implements tracker.Interface.
    89  func (n *FakeTracker) Track(ref corev1.ObjectReference, obj interface{}) error {
    90  	return n.TrackReference(tracker.Reference{
    91  		APIVersion: ref.APIVersion,
    92  		Kind:       ref.Kind,
    93  		Namespace:  ref.Namespace,
    94  		Name:       ref.Name,
    95  	}, obj)
    96  }
    97  
    98  // TrackReference implements tracker.Interface.
    99  func (n *FakeTracker) TrackReference(ref tracker.Reference, obj interface{}) error {
   100  	item, err := kmeta.DeletionHandlingAccessor(obj)
   101  	if err != nil {
   102  		return err
   103  	}
   104  	key := types.NamespacedName{Namespace: item.GetNamespace(), Name: item.GetName()}
   105  
   106  	n.Lock()
   107  	defer n.Unlock()
   108  
   109  	if n.references == nil {
   110  		n.references = make(map[tracker.Reference]map[types.NamespacedName]struct{}, 1)
   111  	}
   112  
   113  	objs := n.references[ref]
   114  	if objs == nil {
   115  		objs = make(map[types.NamespacedName]struct{}, 1)
   116  	}
   117  	objs[key] = struct{}{}
   118  	n.references[ref] = objs
   119  
   120  	return nil
   121  }
   122  
   123  // References returns the list of objects being tracked
   124  func (n *FakeTracker) References() []tracker.Reference {
   125  	n.Lock()
   126  	defer n.Unlock()
   127  
   128  	refs := make([]tracker.Reference, 0, len(n.references))
   129  	for ref := range n.references {
   130  		refs = append(refs, ref)
   131  	}
   132  
   133  	return refs
   134  }