Add NHC operator Ginkgo suite with post-deployment smoke tests#35
Conversation
📝 WalkthroughWalkthroughAdds NHC post-deployment coverage and expands SBR system tests with remediation, split-brain, and watchdog parsing changes. ChangesNHC Operator Post-Deployment Tests
SBR Operator System Tests
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/nhc-operator/tests/post_deployment.go (1)
78-90: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winRemove unused unstructured object declarations.
The
nhcCRD(lines 78-83) andcrdObj(lines 85-90) variables are declared but never used. OnlynhcList(lines 92-97) is actually used in the test. Removing the unused declarations will improve code clarity.♻️ Suggested cleanup
- nhcCRD := &unstructured.Unstructured{} - nhcCRD.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "apiextensions.k8s.io", - Version: "v1", - Kind: "CustomResourceDefinition", - }) - - crdObj := &unstructured.Unstructured{} - crdObj.SetGroupVersionKind(schema.GroupVersionKind{ - Group: nhcparams.CRDGroup, - Version: nhcparams.CRDVersion, - Kind: "NodeHealthCheck", - }) - nhcList := &unstructured.UnstructuredList{} nhcList.SetGroupVersionKind(schema.GroupVersionKind{ Group: nhcparams.CRDGroup,🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/nhc-operator/tests/post_deployment.go` around lines 78 - 90, Remove the unused variable declarations in the post_deployment test. The nhcCRD variable (declared with GroupVersionKind for apiextensions.k8s.io CustomResourceDefinition) and the crdObj variable (declared with GroupVersionKind for NodeHealthCheck) are both declared but never used anywhere in the test logic. Delete both of these unstructured object declaration blocks, keeping only the nhcList variable which is actually utilized in the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/nhc-operator/tests/post_deployment.go`:
- Around line 78-90: Remove the unused variable declarations in the
post_deployment test. The nhcCRD variable (declared with GroupVersionKind for
apiextensions.k8s.io CustomResourceDefinition) and the crdObj variable (declared
with GroupVersionKind for NodeHealthCheck) are both declared but never used
anywhere in the test logic. Delete both of these unstructured object declaration
blocks, keeping only the nhcList variable which is actually utilized in the
test.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 1de87b48-f139-4c73-acb1-ddcc111da616
📒 Files selected for processing (4)
tests/nhc-operator/internal/nhcparams/const.gotests/nhc-operator/internal/nhcparams/nhcvars.gotests/nhc-operator/nhc_suite_test.gotests/nhc-operator/tests/post_deployment.go
Add weekly periodic job for NHC (Node Health Check) E2E tests, matching the existing FAR, SBR, and SNR periodic job pattern. - Job: e2e-nhc-weekly-aws - Schedule: Sundays at 10:00 UTC (2h after SNR at 08:00) - Workflow: ipi-aws with Konflux FBC catalog - Operator: node-healthcheck-operator via stable channel - Tests: make run-tests with ECO_TEST_FEATURES=nhc-operator Depends on medik8s/system-tests#35 (NHC suite + smoke tests) which must merge before this PR to avoid a red periodic. Jira: RHWA-1141 Co-Authored-By: Claude <noreply@anthropic.com>
Add weekly periodic job for NHC (Node Health Check) E2E tests, matching the existing FAR, SBR, and SNR periodic job pattern. - Job: e2e-nhc-weekly-aws - Schedule: Sundays at 10:00 UTC (2h after SNR at 08:00) - Workflow: ipi-aws with Konflux FBC catalog - Operator: node-healthcheck-operator via stable channel - Tests: make run-tests with ECO_TEST_FEATURES=nhc-operator Depends on medik8s/system-tests#35 (NHC suite + smoke tests) which must merge before this PR to avoid a red periodic. Jira: RHWA-1141 Co-Authored-By: Claude <noreply@anthropic.com>
Add the NHC operator test suite and smoke tests following the established SNR pattern. This unblocks RHWA-1141 (NHC periodic job) by providing a runnable Ginkgo suite. Files added/modified: - nhc_suite_test.go: Ginkgo suite entry point with JUnit and reportxml reporting - tests/post_deployment.go: Three smoke tests verifying NHC deployment health, CSV annotations, and CSV metadata - internal/nhcparams/const.go: NHC-specific constants (CRD group, CSV pattern, replicas, timeouts) - internal/nhcparams/nhcvars.go: Reporter config, deployment name, pod label selector, required CSV annotations Smoke tests verify: - Controller deployment is ready and pods are running - NodeHealthCheck CRD is installed and listable - CSV is in Succeeded phase with required annotations - Replica count matches expectations (with SNO skip) Co-Authored-By: Claude <noreply@anthropic.com>
a53eefb to
f9e4cb7
Compare
* medik8s system-tests: add NHC weekly periodic job config Add weekly periodic job for NHC (Node Health Check) E2E tests, matching the existing FAR, SBR, and SNR periodic job pattern. - Job: e2e-nhc-weekly-aws - Schedule: Sundays at 10:00 UTC (2h after SNR at 08:00) - Workflow: ipi-aws with Konflux FBC catalog - Operator: node-healthcheck-operator via stable channel - Tests: make run-tests with ECO_TEST_FEATURES=nhc-operator Depends on medik8s/system-tests#35 (NHC suite + smoke tests) which must merge before this PR to avoid a red periodic. Jira: RHWA-1141 Co-Authored-By: Claude <noreply@anthropic.com> * Adjust NHC periodic cron to 14:00 UTC to avoid NMO conflict Stagger: FAR 04:00, SBR 06:00, SNR 08:00, MDR 10:00, NMO 12:00, NHC 14:00 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Add 4th post-deployment test verifying NHC container runs as non-root user with restricted security posture. Checks pod-level RunAsNonRoot, manager container AllowPrivilegeEscalation, Capabilities.Drop ALL, ReadOnlyRootFilesystem, and SeccompProfile RuntimeDefault. Add ManagerContainerName constant and filterRunningPods helper. Jira: RHWA-1142
72010b9 to
b481a83
Compare
|
/test pull-ci-medik8s-system-tests-main-4.22-konflux-e2e-nhc-aws |
|
/test 4.22-konflux-e2e-nhc-aws |
Replace placeholder IDs with actual Polarion test cases: - OCP-89629: Verify NHC resources are installed and running - OCP-89630: Verify NHC CSV has required annotations - OCP-89631: Verify NHC CSV metadata and controller replicas - OCP-89632: Verify NHC container runs with restricted security context Jira: RHWA-1142
b481a83 to
ef0bfce
Compare
|
/test 4.22-konflux-e2e-nhc-aws |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/nhc-operator/tests/post_deployment.go (1)
118-123: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winUse explicit
Eventually(... timeout, poll)for pod readiness waits in specs.Both waits currently route through
pod.WaitForAllPodsInNamespaceRunning(...), so poll cadence is not explicit in the spec body. The test guideline requires explicit timeout + poll interval from params in each wait path.Proposed change pattern
- _, err = pod.WaitForAllPodsInNamespaceRunning( - APIClient, - medik8sparams.OperatorNs, - medik8sparams.DefaultTimeout, - ctrlListOptions, - ) - Expect(err).ToNot(HaveOccurred(), "NHC controller pods are not running") + Eventually(func() error { + pods, listErr := pod.List(APIClient, medik8sparams.OperatorNs, ctrlListOptions) + if listErr != nil { + return listErr + } + if len(pods) == 0 { + return fmt.Errorf("no NHC controller pods found") + } + if len(filterRunningPods(pods)) != len(pods) { + return fmt.Errorf("not all NHC controller pods are running and ready") + } + return nil + }, medik8sparams.DefaultTimeout, nhcparams.DefaultPollInterval).Should(Succeed(), + "NHC controller pods are not running")Apply the same pattern to the wait in the non-root test block.
As per coding guidelines,
Use Eventually/Consistently with explicit timeout + poll interval from <op>params/medik8sparams — never use time.Sleep.Also applies to: 261-266
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/nhc-operator/tests/post_deployment.go` around lines 118 - 123, The pod readiness wait in the spec is routed through pod.WaitForAllPodsInNamespaceRunning, which hides the polling cadence from the test body; replace it with an explicit Eventually-based wait using the timeout and poll interval from medik8sparams in this block, and apply the same pattern to the non-root test wait as well. Keep the wait logic in the relevant post_deployment test cases and ensure the readiness condition is expressed directly with explicit timeout + poll rather than via the helper.Source: Coding guidelines
🧹 Nitpick comments (1)
tests/sbr-operator/tests/watchdog.go (1)
128-134: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRedundant empty-token guard.
strings.Fieldsnever returns empty tokens, so theif token == ""check is dead code. The equivalent parsing insbr.go(Lines 126-128) already omits it; aligning the two keeps the discovery logic consistent.♻️ Proposed simplification
- for _, token := range strings.Fields(line) { - if token == "" { - continue - } - - devices = append(devices, strings.TrimPrefix(token, "/proc/1/root")) - } + for _, token := range strings.Fields(line) { + devices = append(devices, strings.TrimPrefix(token, "/proc/1/root")) + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/sbr-operator/tests/watchdog.go` around lines 128 - 134, The token loop in the watchdog parsing logic has a redundant empty-string check because strings.Fields never returns empty tokens. Remove the dead if token == "" guard from the loop in the watchdog test helper so it matches the parsing approach used in sbr.go, and keep the device extraction logic centered on strings.Fields and strings.TrimPrefix.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/nhc-operator/tests/post_deployment.go`:
- Around line 405-416: The filterRunningPods readiness check is treating pods
with an empty ContainerStatuses list as ready because allReady starts true and
never flips. Update filterRunningPods so it only appends a candidate when it has
at least one ContainerStatus and every status is Ready, using the existing
candidate.Object.Status.ContainerStatuses loop to guard against empty slices and
false-positive readiness.
---
Outside diff comments:
In `@tests/nhc-operator/tests/post_deployment.go`:
- Around line 118-123: The pod readiness wait in the spec is routed through
pod.WaitForAllPodsInNamespaceRunning, which hides the polling cadence from the
test body; replace it with an explicit Eventually-based wait using the timeout
and poll interval from medik8sparams in this block, and apply the same pattern
to the non-root test wait as well. Keep the wait logic in the relevant
post_deployment test cases and ensure the readiness condition is expressed
directly with explicit timeout + poll rather than via the helper.
---
Nitpick comments:
In `@tests/sbr-operator/tests/watchdog.go`:
- Around line 128-134: The token loop in the watchdog parsing logic has a
redundant empty-string check because strings.Fields never returns empty tokens.
Remove the dead if token == "" guard from the loop in the watchdog test helper
so it matches the parsing approach used in sbr.go, and keep the device
extraction logic centered on strings.Fields and strings.TrimPrefix.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 4ccb63fa-4b4b-453b-b370-68f058513c5a
📒 Files selected for processing (7)
tests/nhc-operator/internal/nhcparams/const.gotests/nhc-operator/tests/post_deployment.gotests/sbr-operator/internal/sbrparams/const.gotests/sbr-operator/tests/remediation.gotests/sbr-operator/tests/sbr.gotests/sbr-operator/tests/split_brain.gotests/sbr-operator/tests/watchdog.go
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/nhc-operator/internal/nhcparams/const.go
Resolve conflicts in SBR files by accepting upstream/main versions. The split-brain test PR (PR medik8s#29) was merged to main while this NHC PR was open. All conflicts were in SBR files which this PR does not modify.
|
/test 4.22-konflux-e2e-nhc-aws |
razo7
left a comment
There was a problem hiding this comment.
Can we avoid code duplication between operaotrs?
| }) | ||
| }) | ||
|
|
||
| func filterRunningPods(pods []*pod.Builder) []*pod.Builder { |
There was a problem hiding this comment.
Duplicated helper — extract to tests/internal/
filterRunningPods() is copy-pasted verbatim in FAR (far.go), MDR (mdr.go), and NMO (nmo.go). All four implementations are identical — only the loop variable name changes (farPod/mdrPod/nmoPod/candidate).
Move this to a shared package (e.g. tests/internal/helpers/pod_helpers.go) so all operators reuse one implementation.
There was a problem hiding this comment.
The duplication currently exists in FAR (far.go), SBR (sbr.go), and NHC (three copies total). MDR and NMO do not implement this pod-filtering logic - their suites are simpler.
I will extract FilterRunningPods into tests/internal/helpers/ and switch all six operator suites to use it in a follow-up PR (mechanical refactor, no behavior change).
There was a problem hiding this comment.
follow-up PR
Please link the new PR to this commit after it is created
| It("Verify NHC container runs as non-root user", | ||
| reportxml.ID("89632"), | ||
| Label(labels.OperatorNHC, labels.TierSmoke, labels.DisruptionNonDestructive, | ||
| labels.PlatformAny, labels.FrequencyPresubmit, | ||
| labels.ComponentController), func() { | ||
| By("Waiting for NHC controller pods to be running") | ||
|
|
||
| listOptions := metav1.ListOptions{ | ||
| LabelSelector: nhcparams.OperatorControllerPodLabelSelector, | ||
| } | ||
|
|
||
| _, err := pod.WaitForAllPodsInNamespaceRunning( | ||
| APIClient, | ||
| medik8sparams.OperatorNs, | ||
| medik8sparams.DefaultTimeout, | ||
| listOptions, | ||
| ) | ||
| Expect(err).ToNot(HaveOccurred(), "NHC controller pods are not ready") | ||
|
|
||
| By("Listing NHC controller pods") | ||
|
|
||
| nhcPods, err := pod.List(APIClient, medik8sparams.OperatorNs, listOptions) | ||
| Expect(err).ToNot(HaveOccurred(), "Failed to list NHC controller pods") | ||
|
|
||
| runningPods := filterRunningPods(nhcPods) | ||
| Expect(runningPods).ToNot(BeEmpty(), "No running NHC controller pods found") | ||
|
|
||
| var errorMessages []string | ||
|
|
||
| for _, nhcPod := range runningPods { | ||
| By(fmt.Sprintf("Verifying security context for pod %s", nhcPod.Object.Name)) |
There was a problem hiding this comment.
Security context validation block is duplicated across all operators
This ~80-line block (runAsNonRoot → AllowPrivilegeEscalation → Capabilities → ReadOnlyRootFilesystem → SeccompProfile) is nearly identical in FAR, MDR, and NMO tests.
Consider extracting a shared helper like:
func ValidateNonRootSecurityContext(pods []*pod.Builder, containerName string) []stringThis would return the error messages list, letting each operator's It block just call it and Fail() if non-empty.
There was a problem hiding this comment.
Agreed on extracting this. The validation block currently exists only in FAR (far.go), SBR (sbr.go), and NHC. MDR and NMO do not have security context checks yet.
One detail to preserve: SBR does not validate ReadOnlyRootFilesystem, while FAR and NHC do. The shared helper should make that difference explicit via a parameter rather than hiding it in duplicated logic.
This will be part of the same follow-up refactoring PR as filterRunningPods, extracting shared test helpers into tests/internal/helpers/.
There was a problem hiding this comment.
follow-up PR
Please link the new PR to this commit after it is created
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: razo7, ugreener The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
* medik8s system-tests: add NHC weekly periodic job config Add weekly periodic job for NHC (Node Health Check) E2E tests, matching the existing FAR, SBR, and SNR periodic job pattern. - Job: e2e-nhc-weekly-aws - Schedule: Sundays at 10:00 UTC (2h after SNR at 08:00) - Workflow: ipi-aws with Konflux FBC catalog - Operator: node-healthcheck-operator via stable channel - Tests: make run-tests with ECO_TEST_FEATURES=nhc-operator Depends on medik8s/system-tests#35 (NHC suite + smoke tests) which must merge before this PR to avoid a red periodic. Jira: RHWA-1141 Co-Authored-By: Claude <noreply@anthropic.com> * Adjust NHC periodic cron to 14:00 UTC to avoid NMO conflict Stagger: FAR 04:00, SBR 06:00, SNR 08:00, MDR 10:00, NMO 12:00, NHC 14:00 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* medik8s system-tests: add NHC weekly periodic job config Add weekly periodic job for NHC (Node Health Check) E2E tests, matching the existing FAR, SBR, and SNR periodic job pattern. - Job: e2e-nhc-weekly-aws - Schedule: Sundays at 10:00 UTC (2h after SNR at 08:00) - Workflow: ipi-aws with Konflux FBC catalog - Operator: node-healthcheck-operator via stable channel - Tests: make run-tests with ECO_TEST_FEATURES=nhc-operator Depends on medik8s/system-tests#35 (NHC suite + smoke tests) which must merge before this PR to avoid a red periodic. Jira: RHWA-1141 Co-Authored-By: Claude <noreply@anthropic.com> * Adjust NHC periodic cron to 14:00 UTC to avoid NMO conflict Stagger: FAR 04:00, SBR 06:00, SNR 08:00, MDR 10:00, NMO 12:00, NHC 14:00 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* medik8s system-tests: add NHC weekly periodic job config Add weekly periodic job for NHC (Node Health Check) E2E tests, matching the existing FAR, SBR, and SNR periodic job pattern. - Job: e2e-nhc-weekly-aws - Schedule: Sundays at 10:00 UTC (2h after SNR at 08:00) - Workflow: ipi-aws with Konflux FBC catalog - Operator: node-healthcheck-operator via stable channel - Tests: make run-tests with ECO_TEST_FEATURES=nhc-operator Depends on medik8s/system-tests#35 (NHC suite + smoke tests) which must merge before this PR to avoid a red periodic. Jira: RHWA-1141 Co-Authored-By: Claude <noreply@anthropic.com> * Adjust NHC periodic cron to 14:00 UTC to avoid NMO conflict Stagger: FAR 04:00, SBR 06:00, SNR 08:00, MDR 10:00, NMO 12:00, NHC 14:00 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* medik8s system-tests: add NHC weekly periodic job config Add weekly periodic job for NHC (Node Health Check) E2E tests, matching the existing FAR, SBR, and SNR periodic job pattern. - Job: e2e-nhc-weekly-aws - Schedule: Sundays at 10:00 UTC (2h after SNR at 08:00) - Workflow: ipi-aws with Konflux FBC catalog - Operator: node-healthcheck-operator via stable channel - Tests: make run-tests with ECO_TEST_FEATURES=nhc-operator Depends on medik8s/system-tests#35 (NHC suite + smoke tests) which must merge before this PR to avoid a red periodic. Jira: RHWA-1141 Co-Authored-By: Claude <noreply@anthropic.com> * Adjust NHC periodic cron to 14:00 UTC to avoid NMO conflict Stagger: FAR 04:00, SBR 06:00, SNR 08:00, MDR 10:00, NMO 12:00, NHC 14:00 Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Summary
Add the NHC operator Ginkgo test suite with four post-deployment smoke tests, following the established SNR/SBR pattern.
Changes
nhc_suite_test.gowith JUnit and reportxml reporting (mirrorssnr_suite_test.go)tests/post_deployment.gowith four smoke specs:internal/nhcparams/const.gowith NHC-specific constants (CRD group, CSV pattern, timeouts, ManagerContainerName)internal/nhcparams/nhcvars.gowith reporter config, deployment name, pod label selector, and required annotationsfilterRunningPodshelper for security context test (follows per-suite duplication pattern from SBR/FAR/NMO)Jira: RHWA-1142
Summary by CodeRabbit
New Features
Bug Fixes