@@ -27,6 +27,7 @@ import (
2727 apiextensionsfake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
2828 aextv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions"
2929 "k8s.io/apimachinery/pkg/api/equality"
30+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
3031 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3132 "k8s.io/apimachinery/pkg/labels"
3233 "k8s.io/apimachinery/pkg/runtime"
@@ -231,6 +232,10 @@ func NewFakeOperator(clientObjs []runtime.Object, k8sObjs []runtime.Object, extO
231232 op .lister .APIRegistrationV1 ().RegisterAPIServiceLister (apiServiceInformer .Lister ())
232233 op .lister .APIExtensionsV1beta1 ().RegisterCustomResourceDefinitionLister (customResourceDefinitionInformer .Lister ())
233234
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+
234239 var hasSyncedCheckFns []cache.InformerSynced
235240 for _ , informer := range informerList {
236241 op .RegisterInformer (informer )
@@ -3244,6 +3249,9 @@ func TestUpdates(t *testing.T) {
32443249 if expectedCurrent != expectedPrevious {
32453250 err = wait .PollImmediate (1 * time .Millisecond , 5 * time .Second , func () (bool , error ) {
32463251 updated , err := op .lister .OperatorsV1alpha1 ().ClusterServiceVersionLister ().ClusterServiceVersions (namespace ).Get (csv .GetName ())
3252+ if k8serrors .IsNotFound (err ) {
3253+ return false , nil
3254+ }
32473255 return ! equality .Semantic .DeepEqual (updated , fetched ), err
32483256 })
32493257 require .NoError (t , err )
@@ -3470,11 +3478,12 @@ func TestSyncOperatorGroups(t *testing.T) {
34703478 objects map [string ][]runtime.Object
34713479 }
34723480 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
34783487 }{
34793488 {
34803489 name : "NoMatchingNamespace/NoCSVs" ,
@@ -3546,6 +3555,7 @@ func TestSyncOperatorGroups(t *testing.T) {
35463555 withAnnotations (operatorCSVFailedNoTargetNS .DeepCopy (), map [string ]string {v1 .OperatorGroupAnnotationKey : "operator-group-1" , v1 .OperatorGroupNamespaceAnnotationKey : operatorNamespace }),
35473556 },
35483557 }},
3558+ ignoreCopyError : true ,
35493559 },
35503560 {
35513561 name : "MatchingNamespace/NoCSVs" ,
@@ -4151,25 +4161,67 @@ func TestSyncOperatorGroups(t *testing.T) {
41514161 err = op .syncOperatorGroups (tt .initial .operatorGroup )
41524162 require .NoError (t , err )
41534163
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+
41544184 // Sync csvs enough to get them back to succeeded state
41554185 for i := 0 ; i < 8 ; i ++ {
41564186 opGroupCSVs , err := op .client .OperatorsV1alpha1 ().ClusterServiceVersions (operatorNamespace ).List (metav1.ListOptions {})
41574187 require .NoError (t , err )
41584188
4159- for _ , obj := range opGroupCSVs .Items {
4189+ for i , obj := range opGroupCSVs .Items {
41604190
41614191 err = op .syncClusterServiceVersion (& obj )
41624192 require .NoError (t , err , "%#v" , obj )
41634193
41644194 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+ }
41664222 }
41674223 }
41684224
4169- // Sync again to catch provided API changes
4170- err = op .syncOperatorGroups (tt .initial .operatorGroup )
4171- require .NoError (t , err )
4172-
41734225 operatorGroup , err := op .GetClient ().OperatorsV1 ().OperatorGroups (tt .initial .operatorGroup .GetNamespace ()).Get (tt .initial .operatorGroup .GetName (), metav1.GetOptions {})
41744226 require .NoError (t , err )
41754227 sort .Strings (tt .expectedStatus .Namespaces )
@@ -4183,6 +4235,41 @@ func TestSyncOperatorGroups(t *testing.T) {
41834235 }
41844236}
41854237
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+
41864273func RequireObjectsInNamespace (t * testing.T , opClient operatorclient.ClientInterface , client versioned.Interface , namespace string , objects []runtime.Object ) {
41874274 for _ , object := range objects {
41884275 var err error
0 commit comments