Skip to content

Commit 8d9a655

Browse files
committed
Don't assume there is only one replica in e2e tests
For the upgrade e2e tests, don't assume there is onle one replica. Get the number of replicas from the deployment and wait for the deployment to have that many available. Use the lease to determine the leader pod and reference that. Note that the name format of leases for operator-controller and catalogd are quite different; this doesn't change that, as it may have an impact on the upgrade test itself. Signed-off-by: Todd Short <tshort@redhat.com> Assisted-by: Claude Code
1 parent e4a633e commit 8d9a655

1 file changed

Lines changed: 41 additions & 3 deletions

File tree

test/upgrade-e2e/post_upgrade_test.go

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/stretchr/testify/assert"
1212
"github.com/stretchr/testify/require"
1313
appsv1 "k8s.io/api/apps/v1"
14+
coordinationv1 "k8s.io/api/coordination/v1"
1415
corev1 "k8s.io/api/core/v1"
1516
apimeta "k8s.io/apimachinery/pkg/api/meta"
1617
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -195,13 +196,14 @@ func TestClusterExtensionAfterOLMUpgrade(t *testing.T) {
195196

196197
// waitForDeployment checks that the updated deployment with the given app.kubernetes.io/name label
197198
// has reached the desired number of replicas and that the number pods matches that number
198-
// i.e. no old pods remain. It will return a pointer to the first pod. This is only necessary
199+
// i.e. no old pods remain. It will return a pointer to the leader pod. This is only necessary
199200
// to facilitate the mitigation put in place for https://github.com/operator-framework/operator-controller/issues/1626
200201
func waitForDeployment(t *testing.T, ctx context.Context, controlPlaneLabel string) *corev1.Pod {
201202
deploymentLabelSelector := labels.Set{"app.kubernetes.io/name": controlPlaneLabel}.AsSelector()
202203

203204
t.Log("Checking that the deployment is updated")
204205
var desiredNumReplicas int32
206+
var deploymentNamespace string
205207
require.EventuallyWithT(t, func(ct *assert.CollectT) {
206208
var managerDeployments appsv1.DeploymentList
207209
require.NoError(ct, c.List(ctx, &managerDeployments, client.MatchingLabelsSelector{Selector: deploymentLabelSelector}))
@@ -215,15 +217,51 @@ func waitForDeployment(t *testing.T, ctx context.Context, controlPlaneLabel stri
215217
managerDeployment.Status.ReadyReplicas == *managerDeployment.Spec.Replicas,
216218
)
217219
desiredNumReplicas = *managerDeployment.Spec.Replicas
220+
deploymentNamespace = managerDeployment.Namespace
218221
}, time.Minute, time.Second)
219222

220223
var managerPods corev1.PodList
221224
t.Logf("Ensure the number of remaining pods equal the desired number of replicas (%d)", desiredNumReplicas)
222225
require.EventuallyWithT(t, func(ct *assert.CollectT) {
223226
require.NoError(ct, c.List(ctx, &managerPods, client.MatchingLabelsSelector{Selector: deploymentLabelSelector}))
224-
require.Len(ct, managerPods.Items, 1)
227+
require.Len(ct, managerPods.Items, int(desiredNumReplicas))
225228
}, time.Minute, time.Second)
226-
return &managerPods.Items[0]
229+
230+
// Find the leader pod by checking the lease
231+
t.Log("Finding the leader pod")
232+
// Map component labels to their leader election lease names
233+
leaseNames := map[string]string{
234+
"catalogd": "catalogd-operator-lock",
235+
"operator-controller": "9c4404e7.operatorframework.io",
236+
}
237+
238+
leaseName, ok := leaseNames[controlPlaneLabel]
239+
if !ok {
240+
t.Fatalf("Unknown control plane component: %s", controlPlaneLabel)
241+
}
242+
243+
var leaderPod *corev1.Pod
244+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
245+
var lease coordinationv1.Lease
246+
require.NoError(ct, c.Get(ctx, types.NamespacedName{Name: leaseName, Namespace: deploymentNamespace}, &lease))
247+
require.NotNil(ct, lease.Spec.HolderIdentity)
248+
249+
leaderIdentity := *lease.Spec.HolderIdentity
250+
// The lease holder identity format is: <pod-name>_<leader-election-id-suffix>
251+
// Extract just the pod name by splitting on '_'
252+
podName := strings.Split(leaderIdentity, "_")[0]
253+
254+
// Find the pod with matching name
255+
for i := range managerPods.Items {
256+
if managerPods.Items[i].Name == podName {
257+
leaderPod = &managerPods.Items[i]
258+
break
259+
}
260+
}
261+
require.NotNil(ct, leaderPod, "leader pod not found with identity: %s (pod name: %s)", leaderIdentity, podName)
262+
}, time.Minute, time.Second)
263+
264+
return leaderPod
227265
}
228266

229267
func watchPodLogsForSubstring(ctx context.Context, pod *corev1.Pod, substrings ...string) (bool, error) {

0 commit comments

Comments
 (0)