@@ -32,29 +32,13 @@ func TestClusterExtensionAfterOLMUpgrade(t *testing.T) {
3232 ctx := context .Background ()
3333 defer utils .CollectTestArtifacts (t , artifactName , c , cfg )
3434
35- managerLabelSelector := labels.Set {"control-plane" : "operator-controller-controller-manager" }
35+ // wait for catalogd deployment to finish
36+ t .Log ("Wait for catalogd deployment to be ready" )
37+ catalogdManagerPod := waitForDeployment (t , ctx , "catalogd-controller-manager" )
3638
37- t .Log ("Checking that the controller-manager deployment is updated" )
38- require .EventuallyWithT (t , func (ct * assert.CollectT ) {
39- var managerDeployments appsv1.DeploymentList
40- assert .NoError (ct , c .List (ctx , & managerDeployments , client.MatchingLabelsSelector {Selector : managerLabelSelector .AsSelector ()}))
41- assert .Len (ct , managerDeployments .Items , 1 )
42- managerDeployment := managerDeployments .Items [0 ]
43-
44- assert .True (ct ,
45- managerDeployment .Status .UpdatedReplicas == * managerDeployment .Spec .Replicas &&
46- managerDeployment .Status .Replicas == * managerDeployment .Spec .Replicas &&
47- managerDeployment .Status .AvailableReplicas == * managerDeployment .Spec .Replicas &&
48- managerDeployment .Status .ReadyReplicas == * managerDeployment .Spec .Replicas ,
49- )
50- }, time .Minute , time .Second )
51-
52- var managerPods corev1.PodList
53- t .Log ("Waiting for only one controller-manager Pod to remain" )
54- require .EventuallyWithT (t , func (ct * assert.CollectT ) {
55- assert .NoError (ct , c .List (ctx , & managerPods , client.MatchingLabelsSelector {Selector : managerLabelSelector .AsSelector ()}))
56- assert .Len (ct , managerPods .Items , 1 )
57- }, time .Minute , time .Second )
39+ // wait for operator-controller deployment to finish
40+ t .Log ("Wait for operator-controller deployment to be ready" )
41+ managerPod := waitForDeployment (t , ctx , "operator-controller-controller-manager" )
5842
5943 t .Log ("Reading logs to make sure that ClusterExtension was reconciled by operator-controller before we update it" )
6044 // Make sure that after we upgrade OLM itself we can still reconcile old objects without any changes
@@ -64,28 +48,42 @@ func TestClusterExtensionAfterOLMUpgrade(t *testing.T) {
6448 "reconcile ending" ,
6549 fmt .Sprintf (`ClusterExtension=%q` , testClusterExtensionName ),
6650 }
67- found , err := watchPodLogsForSubstring (logCtx , & managerPods . Items [ 0 ] , "manager" , substrings ... )
51+ found , err := watchPodLogsForSubstring (logCtx , managerPod , "manager" , substrings ... )
6852 require .NoError (t , err )
6953 require .True (t , found )
7054
71- t .Log ("Checking that the ClusterCatalog is serving " )
55+ t .Log ("Checking that the ClusterCatalog is unpacked " )
7256 require .EventuallyWithT (t , func (ct * assert.CollectT ) {
7357 var clusterCatalog catalogd.ClusterCatalog
7458 assert .NoError (ct , c .Get (ctx , types.NamespacedName {Name : testClusterCatalogName }, & clusterCatalog ))
59+
60+ // check serving condition
7561 cond := apimeta .FindStatusCondition (clusterCatalog .Status .Conditions , catalogd .TypeServing )
76- if ! assert .NotNil (ct , cond ) {
62+ if assert .Nil (ct , cond ) {
7763 return
7864 }
7965 assert .Equal (ct , metav1 .ConditionTrue , cond .Status )
8066 assert .Equal (ct , catalogd .ReasonAvailable , cond .Reason )
67+
68+ // mitigation for upgrade-e2e flakiness caused by the following bug
69+ // https://github.com/operator-framework/operator-controller/issues/1626
70+ // wait until the unpack time > than the catalogd controller pod creation time
71+ cond = apimeta .FindStatusCondition (clusterCatalog .Status .Conditions , catalogd .TypeProgressing )
72+ if assert .Nil (ct , cond ) {
73+ return
74+ }
75+ assert .Equal (ct , metav1 .ConditionTrue , cond .Status )
76+ assert .Equal (ct , catalogd .ReasonSucceeded , cond .Reason )
77+
78+ assert .True (ct , clusterCatalog .Status .LastUnpacked .After (catalogdManagerPod .CreationTimestamp .Time ))
8179 }, time .Minute , time .Second )
8280
8381 t .Log ("Checking that the ClusterExtension is installed" )
8482 var clusterExtension ocv1.ClusterExtension
8583 require .EventuallyWithT (t , func (ct * assert.CollectT ) {
8684 assert .NoError (ct , c .Get (ctx , types.NamespacedName {Name : testClusterExtensionName }, & clusterExtension ))
8785 cond := apimeta .FindStatusCondition (clusterExtension .Status .Conditions , ocv1 .TypeInstalled )
88- if ! assert .NotNil (ct , cond ) {
86+ if assert .Nil (ct , cond ) {
8987 return
9088 }
9189 assert .Equal (ct , metav1 .ConditionTrue , cond .Status )
@@ -107,7 +105,7 @@ func TestClusterExtensionAfterOLMUpgrade(t *testing.T) {
107105 require .EventuallyWithT (t , func (ct * assert.CollectT ) {
108106 assert .NoError (ct , c .Get (ctx , types.NamespacedName {Name : testClusterExtensionName }, & clusterExtension ))
109107 cond := apimeta .FindStatusCondition (clusterExtension .Status .Conditions , ocv1 .TypeInstalled )
110- if ! assert .NotNil (ct , cond ) {
108+ if assert .Nil (ct , cond ) {
111109 return
112110 }
113111 assert .Equal (ct , ocv1 .ReasonSucceeded , cond .Reason )
@@ -117,6 +115,39 @@ func TestClusterExtensionAfterOLMUpgrade(t *testing.T) {
117115 }, time .Minute , time .Second )
118116}
119117
118+ // waitForDeployment checks that the updated deployment with the given control-plane label
119+ // has reached the desired number of replicas and that the number pods matches that number
120+ // i.e. no old pods remain. It will return a pointer to the first pod. This is only necessary
121+ // to facilitate the mitigation put in place for https://github.com/operator-framework/operator-controller/issues/1626
122+ func waitForDeployment (t * testing.T , ctx context.Context , controlPlaneLabel string ) * corev1.Pod {
123+ deploymentLabelSelector := labels.Set {"control-plane" : controlPlaneLabel }.AsSelector ()
124+
125+ t .Log ("Checking that the deployment is updated" )
126+ var desiredNumReplicas int32
127+ require .EventuallyWithT (t , func (ct * assert.CollectT ) {
128+ var managerDeployments appsv1.DeploymentList
129+ assert .NoError (ct , c .List (ctx , & managerDeployments , client.MatchingLabelsSelector {Selector : deploymentLabelSelector }))
130+ assert .Len (ct , managerDeployments .Items , 1 )
131+ managerDeployment := managerDeployments .Items [0 ]
132+
133+ assert .True (ct ,
134+ managerDeployment .Status .UpdatedReplicas == * managerDeployment .Spec .Replicas &&
135+ managerDeployment .Status .Replicas == * managerDeployment .Spec .Replicas &&
136+ managerDeployment .Status .AvailableReplicas == * managerDeployment .Spec .Replicas &&
137+ managerDeployment .Status .ReadyReplicas == * managerDeployment .Spec .Replicas ,
138+ )
139+ desiredNumReplicas = * managerDeployment .Spec .Replicas
140+ }, time .Minute , time .Second )
141+
142+ var managerPods corev1.PodList
143+ t .Logf ("Ensure the number of remaining pods equal the desired number of replicas (%d)" , desiredNumReplicas )
144+ require .EventuallyWithT (t , func (ct * assert.CollectT ) {
145+ assert .NoError (ct , c .List (ctx , & managerPods , client.MatchingLabelsSelector {Selector : deploymentLabelSelector }))
146+ assert .Len (ct , managerPods .Items , 1 )
147+ }, time .Minute , time .Second )
148+ return & managerPods .Items [0 ]
149+ }
150+
120151func watchPodLogsForSubstring (ctx context.Context , pod * corev1.Pod , container string , substrings ... string ) (bool , error ) {
121152 podLogOpts := corev1.PodLogOptions {
122153 Follow : true ,
0 commit comments