diff --git a/tests/e2e/framework/common.go b/tests/e2e/framework/common.go index 72b4d97099..d24885d8dd 100644 --- a/tests/e2e/framework/common.go +++ b/tests/e2e/framework/common.go @@ -1662,6 +1662,31 @@ func (f *Framework) GetPodsForScan(scanName string) ([]core.Pod, error) { return pods.Items, nil } +// Helper function to verify pod count matches node count +func (f *Framework) VerifyPodCountMatchesNodeCount(scanName, namespace string, nodeSelector map[string]string) error { + pods, err := f.GetPodsForScan(scanName) + if err != nil { + return fmt.Errorf("failed to get pods for scan %s: %w", scanName, err) + } + + nodeScanPods := []core.Pod{} + for _, pod := range pods { + if _, hasTargetNode := pod.Labels["targetNode"]; hasTargetNode { + nodeScanPods = append(nodeScanPods, pod) + } + } + + nodes, err := f.GetNodesWithSelector(nodeSelector) + if err != nil { + return fmt.Errorf("failed to get nodes with selector: %w", err) + } + + if len(nodeScanPods) != len(nodes) { + return fmt.Errorf("pod count (%d) does not match node count (%d) for scan %s", len(nodeScanPods), len(nodes), scanName) + } + return nil +} + // WaitForRemediationState will poll until the complianceRemediation that we're lookingfor gets applied, or until // a timeout is reached. func (f *Framework) WaitForRemediationState(name, namespace string, state compv1alpha1.RemediationApplicationState) error { diff --git a/tests/e2e/serial/main_test.go b/tests/e2e/serial/main_test.go index 152910bcbe..a40a125bee 100644 --- a/tests/e2e/serial/main_test.go +++ b/tests/e2e/serial/main_test.go @@ -620,6 +620,62 @@ func TestTolerations(t *testing.T) { if err != nil { t.Fatal(err) } + + // Test tolerations with TolerationOpEqual operator on all worker nodes + scanNameEquals := framework.GetObjNameFromTest(t) + "-equals" + scan := &compv1alpha1.ComplianceScan{ + ObjectMeta: metav1.ObjectMeta{ + Name: scanNameEquals, + Namespace: f.OperatorNamespace, + }, + Spec: compv1alpha1.ComplianceScanSpec{ + ContentImage: contentImagePath, + Profile: "xccdf_org.ssgproject.content_profile_moderate", + Rule: "xccdf_org.ssgproject.content_rule_no_netrc_files", + Content: framework.RhcosContentFile, + NodeSelector: map[string]string{ + "node-role.kubernetes.io/worker": "", + }, + ComplianceScanSettings: compv1alpha1.ComplianceScanSettings{ + Debug: true, + ScanTolerations: []corev1.Toleration{ + { + Key: taintKey, + Value: taintVal, + Operator: corev1.TolerationOpEqual, + Effect: corev1.TaintEffectNoSchedule, + }, + }, + }, + }, + } + + if err = f.Client.Create(context.TODO(), scan, nil); err != nil { + t.Fatalf("failed to create scan %s: %s", scanNameEquals, err) + } + defer f.Client.Delete(context.TODO(), scan) + + err = f.WaitForScanStatus(f.OperatorNamespace, scanNameEquals, compv1alpha1.PhaseDone) + if err != nil { + t.Fatal(err) + } + + err = f.AssertScanIsCompliant(scanNameEquals, f.OperatorNamespace) + if err != nil { + t.Fatal(err) + } + + exitCode, _, err := f.GetScanExitCodeAndErrorMsg(scanNameEquals, f.OperatorNamespace) + if err != nil { + t.Fatal(err) + } + if exitCode != "0" { + t.Fatalf("Expected ConfigMap exit-code to be '0', but got: '%s'", exitCode) + } + + if err := f.VerifyPodCountMatchesNodeCount(scanNameEquals, f.OperatorNamespace, map[string]string{"node-role.kubernetes.io/worker": ""}); err != nil { + t.Fatalf("Pod count does not match node count for scan %s: %s", scanNameEquals, err) + } } func TestAutoRemediate(t *testing.T) {