Skip to content

Commit 84c8914

Browse files
author
Jeff Peeler
committed
fix(unit): operator group test flakes
This forces TestSyncOperatorGroups to allow the cache to catch up as the number of resources that are checked here is high. The additional ignoreCopyError parameter in the tests have been added to handle the scenario where syncCopyCSV would never be executed in a production workflow, but for testing it's being called explicitly.
1 parent ae5ef05 commit 84c8914

File tree

2 files changed

+105
-14
lines changed

2 files changed

+105
-14
lines changed

pkg/controller/operators/olm/operator_test.go

Lines changed: 94 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ func NewFakeOperator(clientObjs []runtime.Object, k8sObjs []runtime.Object, extO
231231
op.lister.APIRegistrationV1().RegisterAPIServiceLister(apiServiceInformer.Lister())
232232
op.lister.APIExtensionsV1beta1().RegisterCustomResourceDefinitionLister(customResourceDefinitionInformer.Lister())
233233

234+
// TODO: are there other resources that query all namespaces?
235+
csvInformerAll := externalversions.NewSharedInformerFactory(clientFake, wakeupInterval).Operators().V1alpha1().ClusterServiceVersions()
236+
op.lister.OperatorsV1alpha1().RegisterClusterServiceVersionLister(metav1.NamespaceAll, csvInformerAll.Lister())
237+
234238
var hasSyncedCheckFns []cache.InformerSynced
235239
for _, informer := range informerList {
236240
op.RegisterInformer(informer)
@@ -3470,11 +3474,12 @@ func TestSyncOperatorGroups(t *testing.T) {
34703474
objects map[string][]runtime.Object
34713475
}
34723476
tests := []struct {
3473-
initial initial
3474-
name string
3475-
expectedEqual bool
3476-
expectedStatus v1.OperatorGroupStatus
3477-
final final
3477+
initial initial
3478+
name string
3479+
expectedEqual bool
3480+
expectedStatus v1.OperatorGroupStatus
3481+
final final
3482+
ignoreCopyError bool
34783483
}{
34793484
{
34803485
name: "NoMatchingNamespace/NoCSVs",
@@ -3546,6 +3551,7 @@ func TestSyncOperatorGroups(t *testing.T) {
35463551
withAnnotations(operatorCSVFailedNoTargetNS.DeepCopy(), map[string]string{v1.OperatorGroupAnnotationKey: "operator-group-1", v1.OperatorGroupNamespaceAnnotationKey: operatorNamespace}),
35473552
},
35483553
}},
3554+
ignoreCopyError: true,
35493555
},
35503556
{
35513557
name: "MatchingNamespace/NoCSVs",
@@ -4147,25 +4153,67 @@ func TestSyncOperatorGroups(t *testing.T) {
41474153
err = op.syncOperatorGroups(tt.initial.operatorGroup)
41484154
require.NoError(t, err)
41494155

4156+
// wait on operator group updated status to be in the cache as it is required for later CSV operations
4157+
err = wait.PollImmediate(1*time.Millisecond, 5*time.Second, func() (bool, error) {
4158+
operatorGroup, err := op.lister.OperatorsV1().OperatorGroupLister().OperatorGroups(tt.initial.operatorGroup.GetNamespace()).Get(tt.initial.operatorGroup.GetName())
4159+
if err != nil {
4160+
return false, err
4161+
}
4162+
sort.Strings(tt.expectedStatus.Namespaces)
4163+
sort.Strings(operatorGroup.Status.Namespaces)
4164+
if !reflect.DeepEqual(tt.expectedStatus, operatorGroup.Status) {
4165+
return false, err
4166+
}
4167+
return true, nil
4168+
})
4169+
require.NoError(t, err)
4170+
4171+
// this must be done twice to have annotateCSVs run in syncOperatorGroups
4172+
// and to catch provided API changes
4173+
err = op.syncOperatorGroups(tt.initial.operatorGroup)
4174+
require.NoError(t, err)
4175+
41504176
// Sync csvs enough to get them back to succeeded state
41514177
for i := 0; i < 8; i++ {
41524178
opGroupCSVs, err := op.client.OperatorsV1alpha1().ClusterServiceVersions(operatorNamespace).List(metav1.ListOptions{})
41534179
require.NoError(t, err)
41544180

4155-
for _, obj := range opGroupCSVs.Items {
4181+
for i, obj := range opGroupCSVs.Items {
41564182

41574183
err = op.syncClusterServiceVersion(&obj)
41584184
require.NoError(t, err, "%#v", obj)
41594185

41604186
err = op.syncCopyCSV(&obj)
4161-
require.NoError(t, err, "%#v", obj)
4187+
if !tt.ignoreCopyError {
4188+
require.NoError(t, err, "%#v", obj)
4189+
}
4190+
4191+
if i == 0 {
4192+
err = wait.PollImmediate(1*time.Millisecond, 5*time.Second, func() (bool, error) {
4193+
for namespace, objects := range tt.final.objects {
4194+
if err := RequireObjectsInCache(t, op.lister, namespace, objects, false); err != nil {
4195+
return false, nil
4196+
}
4197+
}
4198+
return true, nil
4199+
})
4200+
require.NoError(t, err)
4201+
}
4202+
4203+
if i == 8 {
4204+
err = wait.PollImmediate(1*time.Millisecond, 5*time.Second, func() (bool, error) {
4205+
for namespace, objects := range tt.final.objects {
4206+
if err := RequireObjectsInCache(t, op.lister, namespace, objects, true); err != nil {
4207+
return false, nil
4208+
}
4209+
}
4210+
return true, nil
4211+
})
4212+
require.NoError(t, err)
4213+
}
41624214
}
41634215
}
41644216

4165-
// Sync again to catch provided API changes
4166-
err = op.syncOperatorGroups(tt.initial.operatorGroup)
4167-
require.NoError(t, err)
4168-
41694217
operatorGroup, err := op.GetClient().OperatorsV1().OperatorGroups(tt.initial.operatorGroup.GetNamespace()).Get(tt.initial.operatorGroup.GetName(), metav1.GetOptions{})
41704218
require.NoError(t, err)
41714219
sort.Strings(tt.expectedStatus.Namespaces)
@@ -4179,6 +4227,41 @@ func TestSyncOperatorGroups(t *testing.T) {
41794227
}
41804228
}
41814229

4230+
func RequireObjectsInCache(t *testing.T, lister operatorlister.OperatorLister, namespace string, objects []runtime.Object, doCompare bool) error {
4231+
for _, object := range objects {
4232+
var err error
4233+
var fetched runtime.Object
4234+
switch o := object.(type) {
4235+
case *appsv1.Deployment:
4236+
fetched, err = lister.AppsV1().DeploymentLister().Deployments(namespace).Get(o.GetName())
4237+
case *rbacv1.ClusterRole:
4238+
fetched, err = lister.RbacV1().ClusterRoleLister().Get(o.GetName())
4239+
case *rbacv1.Role:
4240+
fetched, err = lister.RbacV1().RoleLister().Roles(namespace).Get(o.GetName())
4241+
case *rbacv1.ClusterRoleBinding:
4242+
fetched, err = lister.RbacV1().ClusterRoleBindingLister().Get(o.GetName())
4243+
case *rbacv1.RoleBinding:
4244+
fetched, err = lister.RbacV1().RoleBindingLister().RoleBindings(namespace).Get(o.GetName())
4245+
case *v1alpha1.ClusterServiceVersion:
4246+
fetched, err = lister.OperatorsV1alpha1().ClusterServiceVersionLister().ClusterServiceVersions(namespace).Get(o.GetName())
4247+
case *v1.OperatorGroup:
4248+
fetched, err = lister.OperatorsV1().OperatorGroupLister().OperatorGroups(namespace).Get(o.GetName())
4249+
default:
4250+
require.Failf(t, "couldn't find expected object", "%#v", object)
4251+
}
4252+
if err != nil {
4253+
return fmt.Errorf("namespace: %v, error: %v", namespace, err)
4254+
}
4255+
if doCompare {
4256+
if !reflect.DeepEqual(object, fetched) {
4257+
diff.ObjectDiff(object, fetched)
4258+
return fmt.Errorf("expected object didn't match %v", object)
4259+
}
4260+
}
4261+
}
4262+
return nil
4263+
}
4264+
41824265
func RequireObjectsInNamespace(t *testing.T, opClient operatorclient.ClientInterface, client versioned.Interface, namespace string, objects []runtime.Object) {
41834266
for _, object := range objects {
41844267
var err error

pkg/controller/operators/olm/operatorgroup.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ func (a *Operator) ensureTenantRBAC(operatorNamespace, targetNamespace string, c
468468
if !ownerutil.IsOwnedBy(ownedRoleBinding, csv) {
469469
continue
470470
}
471-
_, ok := targetRolesByName[ownedRoleBinding.GetName()]
471+
_, ok := targetRoleBindingsByName[ownedRoleBinding.GetName()]
472472

473473
// role binding exists
474474
if ok {
@@ -520,6 +520,7 @@ func (a *Operator) ensureCSVsInNamespaces(csv *v1alpha1.ClusterServiceVersion, o
520520
var targetCSV *v1alpha1.ClusterServiceVersion
521521
if targetCSV, err = a.copyToNamespace(csv, ns.GetName()); err != nil {
522522
a.Log.WithError(err).Debug("error copying to target")
523+
continue
523524
}
524525
targetCSVs[ns.GetName()] = targetCSV
525526
} else {
@@ -534,6 +535,10 @@ func (a *Operator) ensureCSVsInNamespaces(csv *v1alpha1.ClusterServiceVersion, o
534535
a.Log.Errorf("operatorgroup '%v' should have non-nil status", operatorGroup.GetName())
535536
return nil
536537
}
538+
if len(targetNamespaces) == 1 && targetNamespaces[0] == corev1.NamespaceAll {
539+
// global operator group handled by ensureRBACInTargetNamespace
540+
return nil
541+
}
537542
for _, ns := range targetNamespaces {
538543
// create roles/rolebindings for each target namespace
539544
permMet, _, err := a.permissionStatus(strategyDetailsDeployment, ruleChecker, ns, csv.GetNamespace())
@@ -547,6 +552,8 @@ func (a *Operator) ensureCSVsInNamespaces(csv *v1alpha1.ClusterServiceVersion, o
547552
if permMet {
548553
logger.Debug("operator has access")
549554
continue
555+
} else {
556+
logger.Debug("operator needs access, going to create permissions")
550557
}
551558

552559
targetCSV, ok := targetCSVs[ns]
@@ -557,6 +564,7 @@ func (a *Operator) ensureCSVsInNamespaces(csv *v1alpha1.ClusterServiceVersion, o
557564
logger.WithError(err).Debug("ensuring tenant rbac")
558565
return err
559566
}
567+
logger.Debug("permissions created")
560568
}
561569

562570
return nil
@@ -583,7 +591,7 @@ func (a *Operator) copyToNamespace(csv *v1alpha1.ClusterServiceVersion, namespac
583591
fetchedCSV.SetLabels(utillabels.AddLabel(fetchedCSV.GetLabels(), v1alpha1.CopiedLabelKey, csv.GetNamespace()))
584592
// CRs don't support strategic merge patching, but in the future if they do this should be updated to patch
585593
logger.Debug("updating target CSV")
586-
if _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).Update(fetchedCSV); err != nil {
594+
if fetchedCSV, err = a.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).Update(fetchedCSV); err != nil {
587595
logger.WithError(err).Error("update target CSV failed")
588596
return nil, err
589597
}
@@ -599,7 +607,7 @@ func (a *Operator) copyToNamespace(csv *v1alpha1.ClusterServiceVersion, namespac
599607
// Must use fetchedCSV because UpdateStatus(...) checks resource UID.
600608
fetchedCSV.Status = newCSV.Status
601609
fetchedCSV.Status.LastUpdateTime = timeNow()
602-
if _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).UpdateStatus(fetchedCSV); err != nil {
610+
if fetchedCSV, err = a.client.OperatorsV1alpha1().ClusterServiceVersions(namespace).UpdateStatus(fetchedCSV); err != nil {
603611
logger.WithError(err).Error("status update for target CSV failed")
604612
return nil, err
605613
}

0 commit comments

Comments
 (0)