This is an automated email from the ASF dual-hosted git repository.

pbacsko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/yunikorn-k8shim.git


The following commit(s) were added to refs/heads/master by this push:
     new d5d70e3e [YUNIKORN-2623] Create unit tests for Clients (#839)
d5d70e3e is described below

commit d5d70e3e4d076e0c62925ced8c716256d4c928b6
Author: Peter Bacsko <[email protected]>
AuthorDate: Tue May 14 12:20:16 2024 +0200

    [YUNIKORN-2623] Create unit tests for Clients (#839)
    
    Closes: #839
    
    Signed-off-by: Peter Bacsko <[email protected]>
---
 pkg/client/apifactory_mock.go                  | 61 ++++++++++++++---
 pkg/client/clients_test.go                     | 86 +++++++++++++++++++++++
 pkg/common/test/configmap_informer_mock.go     | 12 ++--
 pkg/common/test/namespaceinformer_mock.go      |  8 ++-
 pkg/common/test/nodeinformer_mock.go           |  4 +-
 pkg/common/test/podinformer_mock.go            |  4 +-
 pkg/common/test/priorityclass_informer_mock.go |  8 ++-
 pkg/common/test/shared_informer_mock.go        | 94 ++++++++++++++++++++++++++
 8 files changed, 255 insertions(+), 22 deletions(-)

diff --git a/pkg/client/apifactory_mock.go b/pkg/client/apifactory_mock.go
index 35decd4c..73392390 100644
--- a/pkg/client/apifactory_mock.go
+++ b/pkg/client/apifactory_mock.go
@@ -85,12 +85,13 @@ func NewMockedAPIProvider(showError bool) 
*MockedAPIProvider {
                        PodInformer:           test.NewMockedPodInformer(),
                        NodeInformer:          test.NewMockedNodeInformer(),
                        ConfigMapInformer:     
test.NewMockedConfigMapInformer(),
-                       PVInformer:            
&MockedPersistentVolumeInformer{},
-                       PVCInformer:           
&MockedPersistentVolumeClaimInformer{},
-                       StorageInformer:       &MockedStorageClassInformer{},
+                       PVInformer:            
NewMockedPersistentVolumeInformer(),
+                       PVCInformer:           
NewMockedPersistentVolumeClaimInformer(),
+                       StorageInformer:       NewMockedStorageClassInformer(),
                        VolumeBinder:          test.NewVolumeBinderMock(),
                        NamespaceInformer:     
test.NewMockNamespaceInformer(false),
                        PriorityClassInformer: 
test.NewMockPriorityClassInformer(),
+                       CSINodeInformer:       NewMockedCSINodeInformer(),
                        InformerFactory:       
informers.NewSharedInformerFactory(k8fake.NewSimpleClientset(), time.Second*60),
                },
                events:       make(chan informerEvent),
@@ -416,10 +417,18 @@ func (m *MockedAPIProvider) GetBoundPods(clear bool) 
[]BoundPod {
 }
 
 // MockedPersistentVolumeInformer implements PersistentVolumeInformer interface
-type MockedPersistentVolumeInformer struct{}
+type MockedPersistentVolumeInformer struct {
+       informer cache.SharedIndexInformer
+}
+
+func NewMockedPersistentVolumeInformer() *MockedPersistentVolumeInformer {
+       return &MockedPersistentVolumeInformer{
+               informer: &test.SharedInformerMock{},
+       }
+}
 
 func (m *MockedPersistentVolumeInformer) Informer() cache.SharedIndexInformer {
-       return nil
+       return m.informer
 }
 
 func (m *MockedPersistentVolumeInformer) Lister() 
corev1.PersistentVolumeLister {
@@ -427,10 +436,18 @@ func (m *MockedPersistentVolumeInformer) Lister() 
corev1.PersistentVolumeLister
 }
 
 // MockedPersistentVolumeClaimInformer implements 
PersistentVolumeClaimInformer interface
-type MockedPersistentVolumeClaimInformer struct{}
+type MockedPersistentVolumeClaimInformer struct {
+       informer cache.SharedIndexInformer
+}
+
+func NewMockedPersistentVolumeClaimInformer() 
*MockedPersistentVolumeClaimInformer {
+       return &MockedPersistentVolumeClaimInformer{
+               informer: &test.SharedInformerMock{},
+       }
+}
 
 func (m *MockedPersistentVolumeClaimInformer) Informer() 
cache.SharedIndexInformer {
-       return nil
+       return m.informer
 }
 
 func (m *MockedPersistentVolumeClaimInformer) Lister() 
corev1.PersistentVolumeClaimLister {
@@ -438,16 +455,42 @@ func (m *MockedPersistentVolumeClaimInformer) Lister() 
corev1.PersistentVolumeCl
 }
 
 // MockedStorageClassInformer implements StorageClassInformer interface
-type MockedStorageClassInformer struct{}
+type MockedStorageClassInformer struct {
+       informer cache.SharedIndexInformer
+}
+
+func NewMockedStorageClassInformer() *MockedStorageClassInformer {
+       return &MockedStorageClassInformer{
+               informer: &test.SharedInformerMock{},
+       }
+}
 
 func (m *MockedStorageClassInformer) Informer() cache.SharedIndexInformer {
-       return nil
+       return m.informer
 }
 
 func (m *MockedStorageClassInformer) Lister() storagev1.StorageClassLister {
        return nil
 }
 
+type MockedCSINodeInformer struct {
+       informer cache.SharedIndexInformer
+}
+
+func NewMockedCSINodeInformer() *MockedCSINodeInformer {
+       return &MockedCSINodeInformer{
+               informer: &test.SharedInformerMock{},
+       }
+}
+
+func (m *MockedCSINodeInformer) Informer() cache.SharedIndexInformer {
+       return m.informer
+}
+
+func (m *MockedCSINodeInformer) Lister() storagev1.CSINodeLister {
+       return nil
+}
+
 func (m *MockedAPIProvider) SetVolumeBinder(binder 
volumebinding.SchedulerVolumeBinder) {
        m.clients.VolumeBinder = binder
 }
diff --git a/pkg/client/clients_test.go b/pkg/client/clients_test.go
new file mode 100644
index 00000000..4d7715dc
--- /dev/null
+++ b/pkg/client/clients_test.go
@@ -0,0 +1,86 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package client
+
+import (
+       "testing"
+       "time"
+
+       "gotest.tools/v3/assert"
+
+       "github.com/apache/yunikorn-core/pkg/common"
+       "github.com/apache/yunikorn-k8shim/pkg/common/test"
+)
+
+const (
+       noOfInformers = 9 // total number of active informers
+)
+
+func TestWaitForSync(t *testing.T) {
+       clients := getClients()
+       test.SyncDone.Store(false)
+       go func() {
+               time.Sleep(500 * time.Millisecond)
+               test.SyncDone.Store(true)
+       }()
+
+       start := time.Now()
+       clients.WaitForSync()
+       diff := time.Since(start)
+       assert.Equal(t, int64(1000), diff.Truncate(time.Second).Milliseconds(), 
"WaitForSync() didn't block for 1 second")
+}
+
+func TestRun(t *testing.T) {
+       stopped := false
+       clients := getClients()
+       test.RunningInformers.Store(0)
+       stop := make(chan struct{})
+       defer func() {
+               if !stopped {
+                       close(stop)
+               }
+       }()
+
+       clients.Run(stop)
+       err := common.WaitForCondition(func() bool {
+               return test.RunningInformers.Load() == noOfInformers
+       }, 10*time.Millisecond, time.Second)
+       assert.NilError(t, err, "number of running informers: expected %d got 
%d", noOfInformers, test.RunningInformers.Load())
+
+       close(stop)
+       stopped = true
+       err = common.WaitForCondition(func() bool {
+               return test.RunningInformers.Load() == 0
+       }, 10*time.Millisecond, time.Second)
+       assert.NilError(t, err, "no. of informers still running: %d", 
test.RunningInformers.Load())
+}
+
+func getClients() *Clients {
+       return &Clients{
+               PodInformer:           test.NewMockedPodInformer(),
+               NodeInformer:          test.NewMockedNodeInformer(),
+               ConfigMapInformer:     test.NewMockedConfigMapInformer(),
+               PVInformer:            NewMockedPersistentVolumeInformer(),
+               PVCInformer:           NewMockedPersistentVolumeClaimInformer(),
+               StorageInformer:       NewMockedStorageClassInformer(),
+               CSINodeInformer:       NewMockedCSINodeInformer(),
+               NamespaceInformer:     test.NewMockNamespaceInformer(false),
+               PriorityClassInformer: test.NewMockPriorityClassInformer(),
+       }
+}
diff --git a/pkg/common/test/configmap_informer_mock.go 
b/pkg/common/test/configmap_informer_mock.go
index c1b0e616..66823d35 100644
--- a/pkg/common/test/configmap_informer_mock.go
+++ b/pkg/common/test/configmap_informer_mock.go
@@ -24,19 +24,21 @@ import (
 )
 
 type ConfigMapInformerMock struct {
-       lister v1.ConfigMapLister
+       lister   v1.ConfigMapLister
+       informer cache.SharedIndexInformer
 }
 
 func NewMockedConfigMapInformer() *ConfigMapInformerMock {
        return &ConfigMapInformerMock{
-               lister: NewConfigMapListerMock(),
+               lister:   NewConfigMapListerMock(),
+               informer: &SharedInformerMock{},
        }
 }
 
-func (c ConfigMapInformerMock) Informer() cache.SharedIndexInformer {
-       return nil
+func (c *ConfigMapInformerMock) Informer() cache.SharedIndexInformer {
+       return c.informer
 }
 
-func (c ConfigMapInformerMock) Lister() v1.ConfigMapLister {
+func (c *ConfigMapInformerMock) Lister() v1.ConfigMapLister {
        return c.lister
 }
diff --git a/pkg/common/test/namespaceinformer_mock.go 
b/pkg/common/test/namespaceinformer_mock.go
index 432ac976..26bc1ca3 100644
--- a/pkg/common/test/namespaceinformer_mock.go
+++ b/pkg/common/test/namespaceinformer_mock.go
@@ -25,17 +25,19 @@ import (
 )
 
 type MockNamespaceInformer struct {
-       lister listersV1.NamespaceLister
+       lister   listersV1.NamespaceLister
+       informer cache.SharedIndexInformer
 }
 
 func NewMockNamespaceInformer(errIfNotFound bool) 
informersV1.NamespaceInformer {
        return &MockNamespaceInformer{
-               lister: NewMockNamespaceLister(errIfNotFound),
+               lister:   NewMockNamespaceLister(errIfNotFound),
+               informer: &SharedInformerMock{},
        }
 }
 
 func (nsi *MockNamespaceInformer) Informer() cache.SharedIndexInformer {
-       return nil
+       return nsi.informer
 }
 
 func (nsi *MockNamespaceInformer) Lister() listersV1.NamespaceLister {
diff --git a/pkg/common/test/nodeinformer_mock.go 
b/pkg/common/test/nodeinformer_mock.go
index 9f9a7b83..d3d42b46 100644
--- a/pkg/common/test/nodeinformer_mock.go
+++ b/pkg/common/test/nodeinformer_mock.go
@@ -25,16 +25,18 @@ import (
 
 type MockedNodeInformer struct {
        nodeLister v1.NodeLister
+       informer   cache.SharedIndexInformer
 }
 
 func NewMockedNodeInformer() *MockedNodeInformer {
        return &MockedNodeInformer{
                nodeLister: NewNodeListerMock(),
+               informer:   &SharedInformerMock{},
        }
 }
 
 func (m *MockedNodeInformer) Informer() cache.SharedIndexInformer {
-       return nil
+       return m.informer
 }
 
 func (m *MockedNodeInformer) Lister() v1.NodeLister {
diff --git a/pkg/common/test/podinformer_mock.go 
b/pkg/common/test/podinformer_mock.go
index 0862697f..00d261f4 100644
--- a/pkg/common/test/podinformer_mock.go
+++ b/pkg/common/test/podinformer_mock.go
@@ -25,16 +25,18 @@ import (
 
 type MockedPodInformer struct {
        podLister v1.PodLister
+       informer  cache.SharedIndexInformer
 }
 
 func NewMockedPodInformer() *MockedPodInformer {
        return &MockedPodInformer{
                podLister: NewPodListerMock(),
+               informer:  &SharedInformerMock{},
        }
 }
 
 func (m *MockedPodInformer) Informer() cache.SharedIndexInformer {
-       return nil
+       return m.informer
 }
 
 func (m *MockedPodInformer) Lister() v1.PodLister {
diff --git a/pkg/common/test/priorityclass_informer_mock.go 
b/pkg/common/test/priorityclass_informer_mock.go
index 3abec303..7bb16e26 100644
--- a/pkg/common/test/priorityclass_informer_mock.go
+++ b/pkg/common/test/priorityclass_informer_mock.go
@@ -25,17 +25,19 @@ import (
 )
 
 type MockPriorityClassInformer struct {
-       lister listersV1.PriorityClassLister
+       lister   listersV1.PriorityClassLister
+       informer cache.SharedIndexInformer
 }
 
 func NewMockPriorityClassInformer() informersV1.PriorityClassInformer {
        return &MockPriorityClassInformer{
-               lister: NewMockPriorityClassLister(),
+               lister:   NewMockPriorityClassLister(),
+               informer: &SharedInformerMock{},
        }
 }
 
 func (nsi *MockPriorityClassInformer) Informer() cache.SharedIndexInformer {
-       return nil
+       return nsi.informer
 }
 
 func (nsi *MockPriorityClassInformer) Lister() listersV1.PriorityClassLister {
diff --git a/pkg/common/test/shared_informer_mock.go 
b/pkg/common/test/shared_informer_mock.go
new file mode 100644
index 00000000..ce887497
--- /dev/null
+++ b/pkg/common/test/shared_informer_mock.go
@@ -0,0 +1,94 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package test
+
+import (
+       "sync/atomic"
+       "time"
+
+       "k8s.io/client-go/tools/cache"
+)
+
+func init() {
+       SyncDone.Store(true) // shouldn't block by default
+}
+
+var (
+       SyncDone         atomic.Bool
+       RunningInformers atomic.Int64
+
+       _ cache.SharedIndexInformer = &SharedInformerMock{}
+)
+
+type SharedInformerMock struct {
+}
+
+func (s *SharedInformerMock) AddEventHandler(_ cache.ResourceEventHandler) 
(cache.ResourceEventHandlerRegistration, error) {
+       return nil, nil
+}
+
+func (s *SharedInformerMock) AddEventHandlerWithResyncPeriod(_ 
cache.ResourceEventHandler, _ time.Duration) 
(cache.ResourceEventHandlerRegistration, error) {
+       return nil, nil
+}
+
+func (s *SharedInformerMock) RemoveEventHandler(handle 
cache.ResourceEventHandlerRegistration) error {
+       return nil
+}
+
+func (s *SharedInformerMock) GetStore() cache.Store {
+       return nil
+}
+
+func (s *SharedInformerMock) GetController() cache.Controller {
+       return nil
+}
+
+func (s *SharedInformerMock) Run(stopCh <-chan struct{}) {
+       RunningInformers.Add(1)
+       <-stopCh
+       RunningInformers.Add(-1)
+}
+
+func (s *SharedInformerMock) HasSynced() bool {
+       return SyncDone.Load()
+}
+
+func (s *SharedInformerMock) LastSyncResourceVersion() string {
+       return ""
+}
+
+func (s *SharedInformerMock) SetWatchErrorHandler(_ cache.WatchErrorHandler) 
error {
+       return nil
+}
+
+func (s *SharedInformerMock) SetTransform(_ cache.TransformFunc) error {
+       return nil
+}
+
+func (s *SharedInformerMock) IsStopped() bool {
+       return false
+}
+
+func (s *SharedInformerMock) AddIndexers(_ cache.Indexers) error {
+       return nil
+}
+
+func (s *SharedInformerMock) GetIndexer() cache.Indexer {
+       return nil
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to