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]