github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/monitor/internal/k8s/helpers_test.go (about) 1 package k8smonitor 2 3 import ( 4 "context" 5 "sync" 6 "time" 7 8 "github.com/golang/mock/gomock" 9 10 "go.aporeto.io/enforcerd/internal/extractors/containermetadata" 11 "go.aporeto.io/enforcerd/trireme-lib/monitor/config" 12 "go.aporeto.io/enforcerd/trireme-lib/monitor/external" 13 "go.aporeto.io/enforcerd/trireme-lib/monitor/external/mockexternal" 14 "go.aporeto.io/enforcerd/trireme-lib/policy/mockpolicy" 15 "go.aporeto.io/enforcerd/trireme-lib/utils/cri/mockcri" 16 17 corev1 "k8s.io/api/core/v1" 18 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 19 "k8s.io/apimachinery/pkg/fields" 20 "k8s.io/client-go/informers" 21 "k8s.io/client-go/kubernetes" 22 listersv1 "k8s.io/client-go/listers/core/v1" 23 "k8s.io/client-go/tools/cache" 24 ) 25 26 type unitTestMonitorMocks struct { 27 podCache *MockpodCacheInterface 28 runtimeCache *MockruntimeCacheInterface 29 policy *mockpolicy.MockResolver 30 externalEventSender *mockexternal.MockReceiverRegistration 31 cri *mockcri.MockExtendedRuntimeService 32 } 33 34 func newUnitTestMonitor(ctrl *gomock.Controller) (*K8sMonitor, *unitTestMonitorMocks) { 35 podCache := NewMockpodCacheInterface(ctrl) 36 runtimeCache := NewMockruntimeCacheInterface(ctrl) 37 policyResolver := mockpolicy.NewMockResolver(ctrl) 38 externalEventSender := mockexternal.NewMockReceiverRegistration(ctrl) 39 cri := mockcri.NewMockExtendedRuntimeService(ctrl) 40 41 mocks := &unitTestMonitorMocks{ 42 podCache: podCache, 43 runtimeCache: runtimeCache, 44 policy: policyResolver, 45 externalEventSender: externalEventSender, 46 cri: cri, 47 } 48 49 return &K8sMonitor{ 50 nodename: "test", 51 startEventRetry: func(containermetadata.CommonKubernetesContainerMetadata, uint) {}, 52 podCache: podCache, 53 runtimeCache: runtimeCache, 54 handlers: &config.ProcessorConfig{ 55 Policy: policyResolver, 56 ExternalEventSender: []external.ReceiverRegistration{externalEventSender}, 57 ResyncLock: &sync.RWMutex{}, 58 }, 59 criRuntimeService: cri, 60 cniInstalledOrRuncProxyStartedCh: make(chan struct{}), 61 }, mocks 62 } 63 64 func setupInformerForUnitTests(ctx context.Context, kubeClient kubernetes.Interface, nodeName string) listersv1.PodLister { 65 // get the pod informer from the default factory 66 // add a field selector to narrow down our results 67 fieldSelector := fields.OneTermEqualSelector(nodeNameKeyIndex, nodeName).String() 68 factory := informers.NewSharedInformerFactoryWithOptions(kubeClient, time.Hour*24, informers.WithTweakListOptions(func(opts *metav1.ListOptions) { 69 opts.FieldSelector = fieldSelector 70 })) 71 informer := factory.Core().V1().Pods().Informer() 72 73 // add an indexer so that our field selector by node name will work 74 informer.AddIndexers(cache.Indexers{ // nolint: errcheck 75 nodeNameKeyIndex: func(obj interface{}) ([]string, error) { 76 // this is essentially exactly what the node lifecycel controller uses as well 77 pod, ok := obj.(*corev1.Pod) 78 if !ok { 79 return []string{}, nil 80 } 81 if len(pod.Spec.NodeName) == 0 { 82 return []string{}, nil 83 } 84 return []string{pod.Spec.NodeName}, nil 85 }, 86 }) 87 88 // now start the informer 89 go informer.Run(ctx.Done()) 90 91 // wait for the caches to sync before we return 92 // if this fails, we can print a log, but this is not a 93 if !cache.WaitForNamedCacheSync("pods", ctx.Done(), informer.HasSynced) { 94 panic("K8sMonitor: setupInformer: waiting for caches timed out") 95 } 96 97 // return with a lister of the cache of this informer 98 return listersv1.NewPodLister(informer.GetIndexer()) 99 }