Skip to content

Commit 8429cb3

Browse files
authored
Merge pull request #603 from jpeeler/operator-group-robust
fix(e2e): make operator group test more robust
2 parents 7afcd1e + 42a4912 commit 8429cb3

File tree

3 files changed

+76
-33
lines changed

3 files changed

+76
-33
lines changed

pkg/controller/operators/olm/operator_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2522,9 +2522,12 @@ func TestSyncOperatorGroups(t *testing.T) {
25222522

25232523
stopCh := make(chan struct{})
25242524
defer func() { stopCh <- struct{}{} }()
2525-
op, _, err := NewFakeOperator(tt.initial.clientObjs, tt.initial.k8sObjs, tt.initial.crds, tt.initial.apis, &install.StrategyResolver{}, namespaces, stopCh)
2525+
op, hasSyncedFns, err := NewFakeOperator(tt.initial.clientObjs, tt.initial.k8sObjs, tt.initial.crds, tt.initial.apis, &install.StrategyResolver{}, namespaces, stopCh)
25262526
require.NoError(t, err)
25272527

2528+
ok := cache.WaitForCacheSync(stopCh, hasSyncedFns...)
2529+
require.True(t, ok, "wait for cache sync failed")
2530+
25282531
err = op.syncOperatorGroups(tt.initial.operatorGroup)
25292532
require.NoError(t, err)
25302533

pkg/controller/operators/olm/operatorgroup.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,16 @@ func (a *Operator) copyCsvToTargetNamespace(csv *v1alpha1.ClusterServiceVersion,
251251
newCSV := csv.DeepCopy()
252252
newCSV.SetNamespace(ns)
253253
newCSV.SetResourceVersion("")
254-
newCSV.Status.Reason = v1alpha1.CSVReasonCopied
255-
newCSV.Status.Message = fmt.Sprintf("The operator is running in %s but is managing this namespace", csv.GetNamespace())
256-
newCSV.Status.LastUpdateTime = timeNow()
257254

258255
log.Debugf("Copying CSV %v to namespace %v", csv.GetName(), ns)
259256
createdCSV, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(ns).Create(newCSV)
260257
if err != nil {
261258
log.Errorf("Create for new CSV failed: %v", err)
262259
return err
263260
}
261+
createdCSV.Status.Reason = v1alpha1.CSVReasonCopied
262+
createdCSV.Status.Message = fmt.Sprintf("The operator is running in %s but is managing this namespace", csv.GetNamespace())
263+
createdCSV.Status.LastUpdateTime = timeNow()
264264
if _, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(ns).UpdateStatus(createdCSV); err != nil {
265265
log.Errorf("Status update for CSV failed: %v", err)
266266
return err
@@ -388,6 +388,7 @@ func (a *Operator) ensureClusterRoles(op *v1alpha2.OperatorGroup) error {
388388
},
389389
Rules: apiEditPolicyRules,
390390
}
391+
//ownerutil.AddNonBlockingOwner(operatorGroupEditClusterRole, csv)
391392
_, err = a.OpClient.KubernetesInterface().RbacV1().ClusterRoles().Create(operatorGroupEditClusterRole)
392393
if k8serrors.IsAlreadyExists(err) {
393394
if _, err = a.OpClient.UpdateClusterRole(operatorGroupEditClusterRole); err != nil {
@@ -404,6 +405,7 @@ func (a *Operator) ensureClusterRoles(op *v1alpha2.OperatorGroup) error {
404405
},
405406
Rules: apiViewPolicyRules,
406407
}
408+
//ownerutil.AddNonBlockingOwner(operatorGroupViewClusterRole, csv)
407409
_, err = a.OpClient.KubernetesInterface().RbacV1().ClusterRoles().Create(operatorGroupViewClusterRole)
408410
if k8serrors.IsAlreadyExists(err) {
409411
if _, err = a.OpClient.UpdateClusterRole(operatorGroupViewClusterRole); err != nil {

test/e2e/operator_groups_e2e_test.go

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,11 @@ func TestOperatorGroup(t *testing.T) {
116116
require.NoError(t, err)
117117

118118
t.Log("Creating CRD")
119-
mainCRDPlural := genName("ins")
120-
apiGroup := "cluster.com"
119+
mainCRDPlural := genName("opgroup")
120+
apiGroup := "opcluster.com"
121121
mainCRDName := mainCRDPlural + "." + apiGroup
122122
mainCRD := newCRD(mainCRDName, mainCRDPlural)
123+
mainCRD.Spec.Group = apiGroup
123124
cleanupCRD, err := createCRD(c, mainCRD)
124125
require.NoError(t, err)
125126
defer cleanupCRD()
@@ -129,6 +130,10 @@ func TestOperatorGroup(t *testing.T) {
129130
createdCSV, err := crc.OperatorsV1alpha1().ClusterServiceVersions(testNamespace).Create(&aCSV)
130131
require.NoError(t, err)
131132

133+
t.Log("wait for CSV to succeed")
134+
_, err = fetchCSV(t, crc, createdCSV.GetName(), csvSucceededChecker)
135+
require.NoError(t, err)
136+
132137
t.Log("Creating operator group")
133138
operatorGroup := v1alpha2.OperatorGroup{
134139
ObjectMeta: metav1.ObjectMeta{
@@ -145,7 +150,7 @@ func TestOperatorGroup(t *testing.T) {
145150
_, err = crc.OperatorsV1alpha2().OperatorGroups(testNamespace).Create(&operatorGroup)
146151
require.NoError(t, err)
147152
expectedOperatorGroupStatus := v1alpha2.OperatorGroupStatus{
148-
Namespaces: []string{createdOtherNamespace.GetName()},
153+
Namespaces: []string{createdOtherNamespace.GetName(), testNamespace},
149154
}
150155

151156
t.Log("Waiting on operator group to have correct status")
@@ -161,30 +166,51 @@ func TestOperatorGroup(t *testing.T) {
161166
return false, nil
162167
})
163168

164-
t.Log("Checking for proper generated operator-group RBAC roles")
165-
roleList, err := c.KubernetesInterface().RbacV1().ClusterRoles().List(metav1.ListOptions{})
166-
for _, item := range roleList.Items {
167-
role, err := c.GetClusterRole(item.GetName())
168-
require.NoError(t, err)
169-
switch roleName := item.GetName(); roleName {
170-
case "owned-crd-manager-another-csv":
171-
managerPolicyRules := []rbacv1.PolicyRule{
172-
{Verbs: []string{"*"}, APIGroups: []string{apiGroup}, Resources: []string{mainCRDPlural}},
173-
}
174-
require.Equal(t, managerPolicyRules, role.Rules)
175-
case "e2e-operator-group-edit":
176-
editPolicyRules := []rbacv1.PolicyRule{
177-
{Verbs: []string{"create", "update", "patch", "delete"}, APIGroups: []string{apiGroup}, Resources: []string{mainCRDPlural}},
169+
t.Log("Waiting for expected operator group test APIGroup from CSV")
170+
err = wait.Poll(pollInterval, pollDuration, func() (bool, error) {
171+
// (view role is the last role created, so the rest should exist as well by this point)
172+
viewRole, fetchErr := c.KubernetesInterface().RbacV1().ClusterRoles().Get("e2e-operator-group-view", metav1.GetOptions{})
173+
if fetchErr != nil {
174+
if errors.IsNotFound(fetchErr) {
175+
return false, nil
178176
}
179-
t.Log(role)
180-
require.Equal(t, editPolicyRules, role.Rules)
181-
case "e2e-operator-group-view":
182-
viewPolicyRules := []rbacv1.PolicyRule{
183-
{Verbs: []string{"get", "list", "watch"}, APIGroups: []string{apiGroup}, Resources: []string{mainCRDPlural}},
177+
t.Logf("Unable to fetch view role: %v", fetchErr.Error())
178+
return false, fetchErr
179+
}
180+
for _, rule := range viewRole.Rules {
181+
for _, group := range rule.APIGroups {
182+
if group == apiGroup {
183+
return true, nil
184+
}
184185
}
185-
require.Equal(t, viewPolicyRules, role.Rules)
186186
}
187+
return false, nil
188+
})
189+
190+
t.Log("Checking for proper generated operator group RBAC roles")
191+
editRole, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get("e2e-operator-group-edit", metav1.GetOptions{})
192+
require.NoError(t, err)
193+
editPolicyRules := []rbacv1.PolicyRule{
194+
{Verbs: []string{"create", "update", "patch", "delete"}, APIGroups: []string{apiGroup}, Resources: []string{mainCRDPlural}},
195+
}
196+
t.Log(editRole)
197+
require.Equal(t, editPolicyRules, editRole.Rules)
198+
199+
viewRole, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get("e2e-operator-group-view", metav1.GetOptions{})
200+
require.NoError(t, err)
201+
viewPolicyRules := []rbacv1.PolicyRule{
202+
{Verbs: []string{"get", "list", "watch"}, APIGroups: []string{apiGroup}, Resources: []string{mainCRDPlural}},
203+
}
204+
t.Log(viewRole)
205+
require.Equal(t, viewPolicyRules, viewRole.Rules)
206+
207+
managerRole, err := c.KubernetesInterface().RbacV1().ClusterRoles().Get("owned-crd-manager-another-csv", metav1.GetOptions{})
208+
require.NoError(t, err)
209+
managerPolicyRules := []rbacv1.PolicyRule{
210+
{Verbs: []string{"*"}, APIGroups: []string{apiGroup}, Resources: []string{mainCRDPlural}},
187211
}
212+
t.Log(managerRole)
213+
require.Equal(t, managerPolicyRules, managerRole.Rules)
188214

189215
t.Log("Waiting for operator namespace csv to have annotations")
190216
err = wait.Poll(pollInterval, pollDuration, func() (bool, error) {
@@ -203,7 +229,10 @@ func TestOperatorGroup(t *testing.T) {
203229
err = wait.Poll(pollInterval, pollDuration, func() (bool, error) {
204230
fetchedCSV, fetchErr := crc.OperatorsV1alpha1().ClusterServiceVersions(otherNamespaceName).Get(csvName, metav1.GetOptions{})
205231
if fetchErr != nil {
206-
t.Log(fetchErr.Error())
232+
if errors.IsNotFound(fetchErr) {
233+
return false, nil
234+
}
235+
t.Logf("Error (in %v): %v", otherNamespaceName, fetchErr.Error())
207236
return false, fetchErr
208237
}
209238
if checkOperatorGroupAnnotations(fetchedCSV, &operatorGroup, bothNamespaceNames) == nil {
@@ -214,12 +243,21 @@ func TestOperatorGroup(t *testing.T) {
214243
})
215244
// since annotations are set along with status, no reason to poll for this check as done above
216245
t.Log("Checking status on csv in target namespace")
217-
fetchedCSV, err := crc.OperatorsV1alpha1().ClusterServiceVersions(otherNamespaceName).Get(csvName, metav1.GetOptions{})
246+
err = wait.Poll(pollInterval, pollDuration, func() (bool, error) {
247+
fetchedCSV, fetchErr := crc.OperatorsV1alpha1().ClusterServiceVersions(otherNamespaceName).Get(csvName, metav1.GetOptions{})
248+
if fetchErr != nil {
249+
if errors.IsNotFound(fetchErr) {
250+
return false, nil
251+
}
252+
t.Logf("Error (in %v): %v", otherNamespaceName, fetchErr.Error())
253+
return false, fetchErr
254+
}
255+
if fetchedCSV.Status.Reason == v1alpha1.CSVReasonCopied {
256+
return true, nil
257+
}
258+
return false, nil
259+
})
218260
require.NoError(t, err)
219-
require.EqualValues(t, v1alpha1.CSVReasonCopied, fetchedCSV.Status.Reason)
220-
// also check name and spec
221-
require.EqualValues(t, createdCSV.Name, fetchedCSV.Name)
222-
require.EqualValues(t, createdCSV.Spec, fetchedCSV.Spec)
223261

224262
t.Log("Waiting on deployment to have correct annotations")
225263
err = wait.Poll(pollInterval, pollDuration, func() (bool, error) {

0 commit comments

Comments
 (0)