@@ -2,32 +2,73 @@ package reconciler
2
2
3
3
import (
4
4
"fmt"
5
+ "reflect"
5
6
"testing"
6
7
"time"
7
8
8
9
"github.com/ghodss/yaml"
9
- "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
10
- "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
11
- "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
12
- "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
13
10
"github.com/stretchr/testify/require"
14
11
corev1 "k8s.io/api/core/v1"
12
+ rbacv1 "k8s.io/api/rbac/v1"
15
13
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
14
+ "k8s.io/apimachinery/pkg/api/meta"
16
15
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16
+ "k8s.io/apimachinery/pkg/labels"
17
17
"k8s.io/apimachinery/pkg/runtime"
18
18
"k8s.io/apimachinery/pkg/types"
19
19
"k8s.io/client-go/informers"
20
- k8sfake "k8s.io/client-go/kubernetes/fake"
21
20
"k8s.io/client-go/tools/cache"
21
+ k8slabels "k8s.io/kubernetes/pkg/util/labels"
22
+
23
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
24
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
25
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/clientfake"
26
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
27
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
22
28
)
23
29
24
30
const (
25
31
registryImageName = "test:image"
26
32
testNamespace = "testns"
27
33
)
28
34
29
- func cmReconciler (t * testing.T , k8sObjs []runtime.Object , stopc <- chan struct {}) (* ConfigMapRegistryReconciler , operatorclient.ClientInterface ) {
30
- opClientFake := operatorclient .NewClient (k8sfake .NewSimpleClientset (k8sObjs ... ), nil , nil )
35
+ type fakeReconcilerConfig struct {
36
+ k8sObjs []runtime.Object
37
+ k8sClientOptions []clientfake.Option
38
+ configMapServerImage string
39
+ }
40
+
41
+ type fakeReconcilerOption func (* fakeReconcilerConfig )
42
+
43
+ func withK8sObjs (k8sObjs ... runtime.Object ) fakeReconcilerOption {
44
+ return func (config * fakeReconcilerConfig ) {
45
+ config .k8sObjs = k8sObjs
46
+ }
47
+ }
48
+
49
+ func withK8sClientOptions (options ... clientfake.Option ) fakeReconcilerOption {
50
+ return func (config * fakeReconcilerConfig ) {
51
+ config .k8sClientOptions = options
52
+ }
53
+ }
54
+
55
+ func withConfigMapServerImage (configMapServerImage string ) fakeReconcilerOption {
56
+ return func (config * fakeReconcilerConfig ) {
57
+ config .configMapServerImage = configMapServerImage
58
+ }
59
+ }
60
+
61
+ func fakeReconcilerFactory (t * testing.T , stopc <- chan struct {}, options ... fakeReconcilerOption ) (RegistryReconcilerFactory , operatorclient.ClientInterface ) {
62
+ config := & fakeReconcilerConfig {
63
+ configMapServerImage : registryImageName ,
64
+ }
65
+
66
+ // Apply all config options
67
+ for _ , option := range options {
68
+ option (config )
69
+ }
70
+
71
+ opClientFake := operatorclient .NewClient (clientfake .NewReactionForwardingClientsetDecorator (config .k8sObjs , config .k8sClientOptions ... ), nil , nil )
31
72
32
73
// Creates registry pods in response to configmaps
33
74
informerFactory := informers .NewSharedInformerFactory (opClientFake .KubernetesInterface (), 5 * time .Second )
@@ -55,10 +96,10 @@ func cmReconciler(t *testing.T, k8sObjs []runtime.Object, stopc <-chan struct{})
55
96
lister .CoreV1 ().RegisterPodLister (testNamespace , podInformer .Lister ())
56
97
lister .CoreV1 ().RegisterConfigMapLister (testNamespace , configMapInformer .Lister ())
57
98
58
- rec := & ConfigMapRegistryReconciler {
59
- Image : registryImageName ,
60
- OpClient : opClientFake ,
61
- Lister : lister ,
99
+ rec := & registryReconcilerFactory {
100
+ OpClient : opClientFake ,
101
+ Lister : lister ,
102
+ ConfigMapServerImage : config . configMapServerImage ,
62
103
}
63
104
64
105
var hasSyncedCheckFns []cache.InformerSynced
@@ -137,14 +178,27 @@ func validConfigMapCatalogSource(configMap *corev1.ConfigMap) *v1alpha1.CatalogS
137
178
}
138
179
139
180
func objectsForCatalogSource (catsrc * v1alpha1.CatalogSource ) []runtime.Object {
140
- decorated := configMapCatalogSourceDecorator {catsrc }
141
- objs := []runtime.Object {
142
- decorated .Pod (registryImageName ),
143
- decorated .Service (),
144
- decorated .ServiceAccount (),
145
- decorated .Role (),
146
- decorated .RoleBinding (),
181
+ var objs []runtime.Object
182
+ switch catsrc .Spec .SourceType {
183
+ case v1alpha1 .SourceTypeInternal , v1alpha1 .SourceTypeConfigmap :
184
+ decorated := configMapCatalogSourceDecorator {catsrc }
185
+ objs = clientfake .AddSimpleGeneratedNames (
186
+ clientfake .AddSimpleGeneratedName (decorated .Pod (registryImageName )),
187
+ decorated .Service (),
188
+ decorated .ServiceAccount (),
189
+ decorated .Role (),
190
+ decorated .RoleBinding (),
191
+ )
192
+ case v1alpha1 .SourceTypeGrpc :
193
+ if catsrc .Spec .Image != "" {
194
+ decorated := grpcCatalogSourceDecorator {catsrc }
195
+ objs = clientfake .AddSimpleGeneratedNames (
196
+ decorated .Pod (),
197
+ decorated .Service (),
198
+ )
199
+ }
147
200
}
201
+
148
202
blockOwnerDeletion := false
149
203
isController := false
150
204
for _ , o := range objs {
@@ -161,14 +215,30 @@ func objectsForCatalogSource(catsrc *v1alpha1.CatalogSource) []runtime.Object {
161
215
return objs
162
216
}
163
217
164
- func modifyObjName (objs []runtime.Object , kind , newName string ) []runtime.Object {
218
+ func modifyObjName (objs []runtime.Object , kind runtime. Object , newName string ) []runtime.Object {
165
219
out := []runtime.Object {}
166
- for _ , o := range objs {
167
- if o .GetObjectKind ().GroupVersionKind ().Kind == kind {
168
- mo := o .(metav1.Object )
169
- mo .SetName (newName )
170
- out = append (out , mo .(runtime.Object ))
171
- continue
220
+ t := reflect .TypeOf (kind )
221
+ for _ , obj := range objs {
222
+ o := obj .DeepCopyObject ()
223
+ if reflect .TypeOf (o ) == t {
224
+ if accessor , err := meta .Accessor (o ); err == nil {
225
+ accessor .SetName (newName )
226
+ }
227
+ }
228
+ out = append (out , o )
229
+ }
230
+ return out
231
+ }
232
+
233
+ func setLabel (objs []runtime.Object , kind runtime.Object , label , value string ) []runtime.Object {
234
+ out := []runtime.Object {}
235
+ t := reflect .TypeOf (kind )
236
+ for _ , obj := range objs {
237
+ o := obj .DeepCopyObject ()
238
+ if reflect .TypeOf (o ) == t {
239
+ if accessor , err := meta .Accessor (o ); err == nil {
240
+ k8slabels .AddLabel (accessor .GetLabels (), label , value )
241
+ }
172
242
}
173
243
out = append (out , o )
174
244
}
@@ -235,7 +305,7 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
235
305
testName : "ExistingRegistry/BadServiceAccount" ,
236
306
in : in {
237
307
cluster : cluster {
238
- k8sObjs : append (modifyObjName (objectsForCatalogSource (validCatalogSource ), " ServiceAccount" , "badName" ), validConfigMap ),
308
+ k8sObjs : append (modifyObjName (objectsForCatalogSource (validCatalogSource ), & corev1. ServiceAccount {} , "badName" ), validConfigMap ),
239
309
},
240
310
catsrc : validCatalogSource ,
241
311
},
@@ -253,7 +323,7 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
253
323
testName : "ExistingRegistry/BadService" ,
254
324
in : in {
255
325
cluster : cluster {
256
- k8sObjs : append (modifyObjName (objectsForCatalogSource (validCatalogSource ), " Service" , "badName" ), validConfigMap ),
326
+ k8sObjs : append (modifyObjName (objectsForCatalogSource (validCatalogSource ), & corev1. Service {} , "badName" ), validConfigMap ),
257
327
},
258
328
catsrc : validCatalogSource ,
259
329
},
@@ -271,7 +341,7 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
271
341
testName : "ExistingRegistry/BadPod" ,
272
342
in : in {
273
343
cluster : cluster {
274
- k8sObjs : append (modifyObjName (objectsForCatalogSource (validCatalogSource ), " Pod" , "badName " ), validConfigMap ),
344
+ k8sObjs : append (setLabel (objectsForCatalogSource (validCatalogSource ), & corev1. Pod {}, CatalogSourceLabelKey , "badValue " ), validConfigMap ),
275
345
},
276
346
catsrc : validCatalogSource ,
277
347
},
@@ -289,7 +359,7 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
289
359
testName : "ExistingRegistry/BadRole" ,
290
360
in : in {
291
361
cluster : cluster {
292
- k8sObjs : append (modifyObjName (objectsForCatalogSource (validCatalogSource ), " Role" , "badName" ), validConfigMap ),
362
+ k8sObjs : append (modifyObjName (objectsForCatalogSource (validCatalogSource ), & rbacv1. Role {} , "badName" ), validConfigMap ),
293
363
},
294
364
catsrc : validCatalogSource ,
295
365
},
@@ -307,7 +377,7 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
307
377
testName : "ExistingRegistry/BadRoleBinding" ,
308
378
in : in {
309
379
cluster : cluster {
310
- k8sObjs : append (modifyObjName (objectsForCatalogSource (validCatalogSource ), " RoleBinding" , "badName" ), validConfigMap ),
380
+ k8sObjs : append (modifyObjName (objectsForCatalogSource (validCatalogSource ), & rbacv1. RoleBinding {} , "badName" ), validConfigMap ),
311
381
},
312
382
catsrc : validCatalogSource ,
313
383
},
@@ -345,7 +415,8 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
345
415
stopc := make (chan struct {})
346
416
defer close (stopc )
347
417
348
- rec , client := cmReconciler (t , tt .in .cluster .k8sObjs , stopc )
418
+ factory , client := fakeReconcilerFactory (t , stopc , withK8sObjs (tt .in .cluster .k8sObjs ... ), withK8sClientOptions (clientfake .WithNameGeneration (t )))
419
+ rec := factory .ReconcilerForSource (tt .in .catsrc )
349
420
350
421
err := rec .EnsureRegistryServer (tt .in .catsrc )
351
422
@@ -360,9 +431,14 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
360
431
decorated := configMapCatalogSourceDecorator {tt .in .catsrc }
361
432
362
433
pod := decorated .Pod (registryImageName )
363
- outPod , err := client .KubernetesInterface ().CoreV1 ().Pods (pod .GetNamespace ()).Get (pod .GetName (), metav1.GetOptions {})
434
+ listOptions := metav1.ListOptions {LabelSelector : labels .SelectorFromSet (labels.Set {CatalogSourceLabelKey : tt .in .catsrc .GetName ()}).String ()}
435
+ outPods , err := client .KubernetesInterface ().CoreV1 ().Pods (pod .GetNamespace ()).List (listOptions )
364
436
require .NoError (t , err )
365
- require .Equal (t , pod , outPod )
437
+ require .Len (t , outPods .Items , 1 )
438
+ outPod := outPods .Items [0 ]
439
+ require .Equal (t , pod .GetGenerateName (), outPod .GetGenerateName ())
440
+ require .Equal (t , pod .GetLabels (), outPod .GetLabels ())
441
+ require .Equal (t , pod .Spec , outPod .Spec )
366
442
367
443
service := decorated .Service ()
368
444
outService , err := client .KubernetesInterface ().CoreV1 ().Services (service .GetNamespace ()).Get (service .GetName (), metav1.GetOptions {})
0 commit comments