@@ -65,6 +65,7 @@ import (
65
65
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer"
66
66
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/scoped"
67
67
opregistry "github.com/operator-framework/operator-registry/pkg/registry"
68
+ clienttesting "k8s.io/client-go/testing"
68
69
)
69
70
70
71
type TestStrategy struct {}
@@ -166,6 +167,7 @@ type fakeOperatorConfig struct {
166
167
k8sObjs []runtime.Object
167
168
extObjs []runtime.Object
168
169
regObjs []runtime.Object
170
+ actionLog * []clienttesting.Action
169
171
}
170
172
171
173
// fakeOperatorOption applies an option to the given fake operator configuration.
@@ -214,6 +216,7 @@ func withClientObjs(clientObjs ...runtime.Object) fakeOperatorOption {
214
216
func withK8sObjs (k8sObjs ... runtime.Object ) fakeOperatorOption {
215
217
return func (config * fakeOperatorConfig ) {
216
218
config .k8sObjs = k8sObjs
219
+
217
220
}
218
221
}
219
222
@@ -229,6 +232,12 @@ func withRegObjs(regObjs ...runtime.Object) fakeOperatorOption {
229
232
}
230
233
}
231
234
235
+ func withActionLog (log * []clienttesting.Action ) fakeOperatorOption {
236
+ return func (config * fakeOperatorConfig ) {
237
+ config .actionLog = log
238
+ }
239
+ }
240
+
232
241
// NewFakeOperator creates and starts a new operator using fake clients.
233
242
func NewFakeOperator (ctx context.Context , options ... fakeOperatorOption ) (* Operator , error ) {
234
243
// Apply options to default config
@@ -247,6 +256,7 @@ func NewFakeOperator(ctx context.Context, options ...fakeOperatorOption) (*Opera
247
256
recorder : & record.FakeRecorder {},
248
257
// default expected namespaces
249
258
namespaces : []string {"default" , "kube-system" , "kube-public" },
259
+ actionLog : & []clienttesting.Action {},
250
260
}
251
261
for _ , option := range options {
252
262
option (config )
@@ -258,6 +268,10 @@ func NewFakeOperator(ctx context.Context, options ...fakeOperatorOption) (*Opera
258
268
// For now, directly use a SimpleClientset instead.
259
269
k8sClientFake := k8sfake .NewSimpleClientset (config .k8sObjs ... )
260
270
k8sClientFake .Resources = apiResourcesForObjects (append (config .extObjs , config .regObjs ... ))
271
+ k8sClientFake .PrependReactor ("*" , "*" , clienttesting .ReactionFunc (func (action clienttesting.Action ) (bool , runtime.Object , error ) {
272
+ * config .actionLog = append (* config .actionLog , action )
273
+ return false , nil , nil
274
+ }))
261
275
config .operatorClient = operatorclient .NewClient (k8sClientFake , apiextensionsfake .NewSimpleClientset (config .extObjs ... ), apiregistrationfake .NewSimpleClientset (config .regObjs ... ))
262
276
config .configClient = configfake .NewSimpleClientset ()
263
277
@@ -3936,6 +3950,170 @@ func TestUpdates(t *testing.T) {
3936
3950
}
3937
3951
}
3938
3952
3953
+ type tDotLogWriter struct {
3954
+ * testing.T
3955
+ }
3956
+
3957
+ func (w tDotLogWriter ) Write (p []byte ) (int , error ) {
3958
+ w .T .Logf ("%s" , string (p ))
3959
+ return len (p ), nil
3960
+ }
3961
+
3962
+ func testLogrusLogger (t * testing.T ) * logrus.Logger {
3963
+ l := logrus .New ()
3964
+ l .SetOutput (tDotLogWriter {t })
3965
+ return l
3966
+ }
3967
+
3968
+ func TestSyncNamespace (t * testing.T ) {
3969
+ namespace := func (name string , labels map [string ]string ) corev1.Namespace {
3970
+ return corev1.Namespace {
3971
+ ObjectMeta : metav1.ObjectMeta {
3972
+ Name : name ,
3973
+ Labels : labels ,
3974
+ },
3975
+ }
3976
+ }
3977
+
3978
+ operatorgroup := func (name string , targets []string ) operatorsv1.OperatorGroup {
3979
+ return operatorsv1.OperatorGroup {
3980
+ ObjectMeta : metav1.ObjectMeta {
3981
+ Name : name ,
3982
+ UID : types .UID (fmt .Sprintf ("%s-uid" , name )),
3983
+ },
3984
+ Status : operatorsv1.OperatorGroupStatus {
3985
+ Namespaces : targets ,
3986
+ },
3987
+ }
3988
+ }
3989
+
3990
+ for _ , tc := range []struct {
3991
+ name string
3992
+ before corev1.Namespace
3993
+ operatorgroups []operatorsv1.OperatorGroup
3994
+ noop bool
3995
+ expected []string
3996
+ }{
3997
+ {
3998
+ name : "adds missing labels" ,
3999
+ before : namespace ("test-namespace" , map [string ]string {"unrelated" : "" }),
4000
+ operatorgroups : []operatorsv1.OperatorGroup {
4001
+ operatorgroup ("test-group-1" , []string {"test-namespace" }),
4002
+ operatorgroup ("test-group-2" , []string {"test-namespace" }),
4003
+ },
4004
+ expected : []string {
4005
+ "olm.operatorgroup.uid/test-group-1-uid" ,
4006
+ "olm.operatorgroup.uid/test-group-2-uid" ,
4007
+ "unrelated" ,
4008
+ },
4009
+ },
4010
+ {
4011
+ name : "removes stale labels" ,
4012
+ before : namespace ("test-namespace" , map [string ]string {
4013
+ "olm.operatorgroup.uid/test-group-1-uid" : "" ,
4014
+ "olm.operatorgroup.uid/test-group-2-uid" : "" ,
4015
+ }),
4016
+ operatorgroups : []operatorsv1.OperatorGroup {
4017
+ operatorgroup ("test-group-2" , []string {"test-namespace" }),
4018
+ },
4019
+ expected : []string {
4020
+ "olm.operatorgroup.uid/test-group-2-uid" ,
4021
+ },
4022
+ },
4023
+ {
4024
+ name : "does not add label if namespace is not a target namespace" ,
4025
+ before : namespace ("test-namespace" , nil ),
4026
+ operatorgroups : []operatorsv1.OperatorGroup {
4027
+ operatorgroup ("test-group-1" , []string {"test-namespace" }),
4028
+ operatorgroup ("test-group-2" , []string {"not-test-namespace" }),
4029
+ },
4030
+ expected : []string {
4031
+ "olm.operatorgroup.uid/test-group-1-uid" ,
4032
+ },
4033
+ },
4034
+ {
4035
+ name : "no update if labels are in sync" ,
4036
+ before : namespace ("test-namespace" , map [string ]string {
4037
+ "olm.operatorgroup.uid/test-group-1-uid" : "" ,
4038
+ "olm.operatorgroup.uid/test-group-2-uid" : "" ,
4039
+ }),
4040
+ operatorgroups : []operatorsv1.OperatorGroup {
4041
+ operatorgroup ("test-group-1" , []string {"test-namespace" }),
4042
+ operatorgroup ("test-group-2" , []string {"test-namespace" }),
4043
+ },
4044
+ noop : true ,
4045
+ expected : []string {
4046
+ "olm.operatorgroup.uid/test-group-1-uid" ,
4047
+ "olm.operatorgroup.uid/test-group-2-uid" ,
4048
+ },
4049
+ },
4050
+ } {
4051
+ t .Run (tc .name , func (t * testing.T ) {
4052
+ ctx , cancel := context .WithCancel (context .Background ())
4053
+ defer cancel ()
4054
+
4055
+ var ogs []runtime.Object
4056
+ for i := range tc .operatorgroups {
4057
+ ogs = append (ogs , & tc .operatorgroups [i ])
4058
+ }
4059
+
4060
+ var actions []clienttesting.Action
4061
+
4062
+ o , err := NewFakeOperator (
4063
+ ctx ,
4064
+ withClientObjs (ogs ... ),
4065
+ withK8sObjs (& tc .before ),
4066
+ withActionLog (& actions ),
4067
+ )
4068
+ if err != nil {
4069
+ t .Fatalf ("setup failed: %v" , err )
4070
+ }
4071
+
4072
+ actions = actions [:0 ]
4073
+
4074
+ err = o .syncNamespace (& tc .before )
4075
+ if err != nil {
4076
+ t .Fatalf ("unexpected error: %v" , err )
4077
+ }
4078
+
4079
+ if tc .noop {
4080
+ for _ , action := range actions {
4081
+ if action .GetResource ().Resource != "namespaces" {
4082
+ continue
4083
+ }
4084
+ if namer , ok := action .(interface { GetName () string }); ok {
4085
+ if namer .GetName () != tc .before .Name {
4086
+ continue
4087
+ }
4088
+ } else if objer , ok := action .(interface { GetObject () runtime.Object }); ok {
4089
+ if namer , ok := objer .GetObject ().(interface { GetName () string }); ok {
4090
+ if namer .GetName () != tc .before .Name {
4091
+ continue
4092
+ }
4093
+ }
4094
+ }
4095
+ t .Errorf ("unexpected client operation: %v" , action )
4096
+ }
4097
+ }
4098
+
4099
+ after , err := o .opClient .KubernetesInterface ().CoreV1 ().Namespaces ().Get (ctx , tc .before .Name , metav1.GetOptions {})
4100
+ if err != nil {
4101
+ t .Fatalf ("unexpected error: %v" , err )
4102
+ }
4103
+
4104
+ if len (after .Labels ) != len (tc .expected ) {
4105
+ t .Errorf ("expected %d labels, got %d" , len (tc .expected ), len (after .Labels ))
4106
+ }
4107
+
4108
+ for _ , l := range tc .expected {
4109
+ if _ , ok := after .Labels [l ]; ! ok {
4110
+ t .Errorf ("missing expected label %q" , l )
4111
+ }
4112
+ }
4113
+ })
4114
+ }
4115
+ }
4116
+
3939
4117
func TestSyncOperatorGroups (t * testing.T ) {
3940
4118
logrus .SetLevel (logrus .WarnLevel )
3941
4119
clockFake := utilclocktesting .NewFakeClock (time .Date (2006 , time .January , 2 , 15 , 4 , 5 , 0 , time .FixedZone ("MST" , - 7 * 3600 )))
0 commit comments