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