@@ -27,6 +27,7 @@ import (
27
27
apiextensionsfake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
28
28
aextv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
29
29
"k8s.io/apimachinery/pkg/api/equality"
30
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
30
31
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31
32
"k8s.io/apimachinery/pkg/labels"
32
33
"k8s.io/apimachinery/pkg/runtime"
@@ -231,6 +232,10 @@ func NewFakeOperator(clientObjs []runtime.Object, k8sObjs []runtime.Object, extO
231
232
op .lister .APIRegistrationV1 ().RegisterAPIServiceLister (apiServiceInformer .Lister ())
232
233
op .lister .APIExtensionsV1beta1 ().RegisterCustomResourceDefinitionLister (customResourceDefinitionInformer .Lister ())
233
234
235
+ // TODO: are there other resources that query all namespaces?
236
+ csvInformerAll := externalversions .NewSharedInformerFactory (clientFake , wakeupInterval ).Operators ().V1alpha1 ().ClusterServiceVersions ()
237
+ op .lister .OperatorsV1alpha1 ().RegisterClusterServiceVersionLister (metav1 .NamespaceAll , csvInformerAll .Lister ())
238
+
234
239
var hasSyncedCheckFns []cache.InformerSynced
235
240
for _ , informer := range informerList {
236
241
op .RegisterInformer (informer )
@@ -3244,6 +3249,9 @@ func TestUpdates(t *testing.T) {
3244
3249
if expectedCurrent != expectedPrevious {
3245
3250
err = wait .PollImmediate (1 * time .Millisecond , 5 * time .Second , func () (bool , error ) {
3246
3251
updated , err := op .lister .OperatorsV1alpha1 ().ClusterServiceVersionLister ().ClusterServiceVersions (namespace ).Get (csv .GetName ())
3252
+ if k8serrors .IsNotFound (err ) {
3253
+ return false , nil
3254
+ }
3247
3255
return ! equality .Semantic .DeepEqual (updated , fetched ), err
3248
3256
})
3249
3257
require .NoError (t , err )
@@ -3470,11 +3478,12 @@ func TestSyncOperatorGroups(t *testing.T) {
3470
3478
objects map [string ][]runtime.Object
3471
3479
}
3472
3480
tests := []struct {
3473
- initial initial
3474
- name string
3475
- expectedEqual bool
3476
- expectedStatus v1.OperatorGroupStatus
3477
- final final
3481
+ initial initial
3482
+ name string
3483
+ expectedEqual bool
3484
+ expectedStatus v1.OperatorGroupStatus
3485
+ final final
3486
+ ignoreCopyError bool
3478
3487
}{
3479
3488
{
3480
3489
name : "NoMatchingNamespace/NoCSVs" ,
@@ -3546,6 +3555,7 @@ func TestSyncOperatorGroups(t *testing.T) {
3546
3555
withAnnotations (operatorCSVFailedNoTargetNS .DeepCopy (), map [string ]string {v1 .OperatorGroupAnnotationKey : "operator-group-1" , v1 .OperatorGroupNamespaceAnnotationKey : operatorNamespace }),
3547
3556
},
3548
3557
}},
3558
+ ignoreCopyError : true ,
3549
3559
},
3550
3560
{
3551
3561
name : "MatchingNamespace/NoCSVs" ,
@@ -4151,25 +4161,67 @@ func TestSyncOperatorGroups(t *testing.T) {
4151
4161
err = op .syncOperatorGroups (tt .initial .operatorGroup )
4152
4162
require .NoError (t , err )
4153
4163
4164
+ // wait on operator group updated status to be in the cache as it is required for later CSV operations
4165
+ err = wait .PollImmediate (1 * time .Millisecond , 5 * time .Second , func () (bool , error ) {
4166
+ operatorGroup , err := op .lister .OperatorsV1 ().OperatorGroupLister ().OperatorGroups (tt .initial .operatorGroup .GetNamespace ()).Get (tt .initial .operatorGroup .GetName ())
4167
+ if err != nil {
4168
+ return false , err
4169
+ }
4170
+ sort .Strings (tt .expectedStatus .Namespaces )
4171
+ sort .Strings (operatorGroup .Status .Namespaces )
4172
+ if ! reflect .DeepEqual (tt .expectedStatus , operatorGroup .Status ) {
4173
+ return false , err
4174
+ }
4175
+ return true , nil
4176
+ })
4177
+ require .NoError (t , err )
4178
+
4179
+ // this must be done twice to have annotateCSVs run in syncOperatorGroups
4180
+ // and to catch provided API changes
4181
+ err = op .syncOperatorGroups (tt .initial .operatorGroup )
4182
+ require .NoError (t , err )
4183
+
4154
4184
// Sync csvs enough to get them back to succeeded state
4155
4185
for i := 0 ; i < 8 ; i ++ {
4156
4186
opGroupCSVs , err := op .client .OperatorsV1alpha1 ().ClusterServiceVersions (operatorNamespace ).List (metav1.ListOptions {})
4157
4187
require .NoError (t , err )
4158
4188
4159
- for _ , obj := range opGroupCSVs .Items {
4189
+ for i , obj := range opGroupCSVs .Items {
4160
4190
4161
4191
err = op .syncClusterServiceVersion (& obj )
4162
4192
require .NoError (t , err , "%#v" , obj )
4163
4193
4164
4194
err = op .syncCopyCSV (& obj )
4165
- require .NoError (t , err , "%#v" , obj )
4195
+ if ! tt .ignoreCopyError {
4196
+ require .NoError (t , err , "%#v" , obj )
4197
+ }
4198
+
4199
+ if i == 0 {
4200
+ err = wait .PollImmediate (1 * time .Millisecond , 5 * time .Second , func () (bool , error ) {
4201
+ for namespace , objects := range tt .final .objects {
4202
+ if err := RequireObjectsInCache (t , op .lister , namespace , objects , false ); err != nil {
4203
+ return false , nil
4204
+ }
4205
+ }
4206
+ return true , nil
4207
+ })
4208
+ require .NoError (t , err )
4209
+ }
4210
+
4211
+ if i == 8 {
4212
+ err = wait .PollImmediate (1 * time .Millisecond , 5 * time .Second , func () (bool , error ) {
4213
+ for namespace , objects := range tt .final .objects {
4214
+ if err := RequireObjectsInCache (t , op .lister , namespace , objects , true ); err != nil {
4215
+ return false , nil
4216
+ }
4217
+ }
4218
+ return true , nil
4219
+ })
4220
+ require .NoError (t , err )
4221
+ }
4166
4222
}
4167
4223
}
4168
4224
4169
- // Sync again to catch provided API changes
4170
- err = op .syncOperatorGroups (tt .initial .operatorGroup )
4171
- require .NoError (t , err )
4172
-
4173
4225
operatorGroup , err := op .GetClient ().OperatorsV1 ().OperatorGroups (tt .initial .operatorGroup .GetNamespace ()).Get (tt .initial .operatorGroup .GetName (), metav1.GetOptions {})
4174
4226
require .NoError (t , err )
4175
4227
sort .Strings (tt .expectedStatus .Namespaces )
@@ -4183,6 +4235,41 @@ func TestSyncOperatorGroups(t *testing.T) {
4183
4235
}
4184
4236
}
4185
4237
4238
+ func RequireObjectsInCache (t * testing.T , lister operatorlister.OperatorLister , namespace string , objects []runtime.Object , doCompare bool ) error {
4239
+ for _ , object := range objects {
4240
+ var err error
4241
+ var fetched runtime.Object
4242
+ switch o := object .(type ) {
4243
+ case * appsv1.Deployment :
4244
+ fetched , err = lister .AppsV1 ().DeploymentLister ().Deployments (namespace ).Get (o .GetName ())
4245
+ case * rbacv1.ClusterRole :
4246
+ fetched , err = lister .RbacV1 ().ClusterRoleLister ().Get (o .GetName ())
4247
+ case * rbacv1.Role :
4248
+ fetched , err = lister .RbacV1 ().RoleLister ().Roles (namespace ).Get (o .GetName ())
4249
+ case * rbacv1.ClusterRoleBinding :
4250
+ fetched , err = lister .RbacV1 ().ClusterRoleBindingLister ().Get (o .GetName ())
4251
+ case * rbacv1.RoleBinding :
4252
+ fetched , err = lister .RbacV1 ().RoleBindingLister ().RoleBindings (namespace ).Get (o .GetName ())
4253
+ case * v1alpha1.ClusterServiceVersion :
4254
+ fetched , err = lister .OperatorsV1alpha1 ().ClusterServiceVersionLister ().ClusterServiceVersions (namespace ).Get (o .GetName ())
4255
+ case * v1.OperatorGroup :
4256
+ fetched , err = lister .OperatorsV1 ().OperatorGroupLister ().OperatorGroups (namespace ).Get (o .GetName ())
4257
+ default :
4258
+ require .Failf (t , "couldn't find expected object" , "%#v" , object )
4259
+ }
4260
+ if err != nil {
4261
+ return fmt .Errorf ("namespace: %v, error: %v" , namespace , err )
4262
+ }
4263
+ if doCompare {
4264
+ if ! reflect .DeepEqual (object , fetched ) {
4265
+ diff .ObjectDiff (object , fetched )
4266
+ return fmt .Errorf ("expected object didn't match %v" , object )
4267
+ }
4268
+ }
4269
+ }
4270
+ return nil
4271
+ }
4272
+
4186
4273
func RequireObjectsInNamespace (t * testing.T , opClient operatorclient.ClientInterface , client versioned.Interface , namespace string , objects []runtime.Object ) {
4187
4274
for _ , object := range objects {
4188
4275
var err error
0 commit comments