Skip to content

OCPNODE-4505: Automation creation of OCP-57401#31142

Open
asahay19 wants to merge 2 commits into
openshift:mainfrom
asahay19:4505
Open

OCPNODE-4505: Automation creation of OCP-57401#31142
asahay19 wants to merge 2 commits into
openshift:mainfrom
asahay19:4505

Conversation

@asahay19
Copy link
Copy Markdown
Contributor

@asahay19 asahay19 commented May 7, 2026

PR Summary

This test automates manual test case OCP-57401 by verifying end-to-end creation of both ImageDigestMirrorSet (IDMS) and ImageTagMirrorSet (ITMS) resources. It creates an IDMS and ITMS with both AllowContactingSource and NeverContactSource mirror policies, waits for MachineConfigPool rollouts, and then validates that /etc/containers/registries.conf on a worker node contains the correct digest-only and tag-only mirror entries along with blocked = true for NeverContactSource registries.

This test is already present in openshift-test-private. As part of migrating test cases , I am automating it origin.
Polarian Link: https://polarion.engineering.redhat.com/polarion/#/project/OSE/workitem?id=OCP-57401
Jira task : https://redhat.atlassian.net/browse/OCPNODE-4505

Output
Tested locally on 4.22 openshift cluster and it got passed.

./openshift-tests run-test '[sig-node][Suite:openshift/disruptive-longrunning][Disruptive][Serial] ImageTagMirrorSet and ImageDigestMirrorSet [OTP] Create ImageDigestMirrorSet and ImageTagMirrorSet and verify registries.conf [OCP-57401]'

  Ran 1 of 1 Specs in 1274.887 seconds
  SUCCESS! -- 1 Passed | 0 Failed | 0 Pending | 0 Skipped
[
  {
    "name": "[sig-node][Suite:openshift/disruptive-longrunning][Disruptive][Serial] ImageTagMirrorSet and ImageDigestMirrorSet [OTP] Create ImageDigestMirrorSet and ImageTagMirrorSet and verify registries.conf [OCP-57401]",
    "lifecycle": "blocking",
    "duration": 1274888,
    "startTime": "2026-05-07 07:50:46.647072 UTC",
    "endTime": "2026-05-07 08:12:01.535488 UTC",
    "result": "passed",
    "output": "  STEP:

PTAL @cpmeadors @BhargaviGudi

Summary by CodeRabbit

  • Tests
    • Added an end-to-end test suite validating ImageTagMirrorSet and ImageDigestMirrorSet behavior: ensures mirror entries and pull-from-mirror modes (digest-only, tag-only), verifies non-mirrored sources are blocked, confirms registry configuration appears on a ready worker node, and checks Machine Config Pool rollout and cleanup complete successfully.
    • Added test utilities to locate a ready worker node and validate registry blocking in configuration files.

@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 3eb5359a-569c-40b9-b8c6-58f12789c040

📥 Commits

Reviewing files that changed from the base of the PR and between b5e2e80 and ea3e829.

📒 Files selected for processing (1)
  • test/extended/node/node_e2e/node.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/extended/node/node_e2e/node.go

Walkthrough

Adds a Ginkgo serial disruptive-longrunning e2e that creates ImageDigestMirrorSet and ImageTagMirrorSet, waits for worker/master MCP rollouts, reads /etc/containers/registries.conf on a ready worker, asserts digest-vs-tag mirror semantics and blocked NeverContactSource entries, and adds two node helper utilities.

Changes

ImageMirrorSet E2E Test & Node Helpers

Layer / File(s) Summary
Test suite and flow
test/extended/node/node_e2e/node.go
New Disruptive/Serial Ginkgo Describe/It: skips MicroShift, creates ImageDigestMirrorSet and ImageTagMirrorSet, waits for MCP rollout completion for worker and master, reads /etc/containers/registries.conf from the first ready worker, asserts location and pull-from-mirror semantics for digest-only vs tag-only mappings, checks NeverContactSource-backed registries are blocked, and defers deletion plus MCP-spec revert waits.
Node helpers used by the test
test/extended/node/node_utils.go
Adds GetFirstReadyWorkerNode(oc *exutil.CLI) string to select the first worker node with Ready==True via oc JSONPath queries, and VerifyRegistryBlocked(registriesConf string, registrySource string) to find a location = "<registrySource>" stanza in registries.conf and assert blocked = true within that stanza.
Imports / wiring for test
test/extended/node/node_e2e/node.go
Updates imports to include context, configv1, imagepolicy, and utilrand (plus other standard imports) to support resource creation, waiting logic, and verification in the new test.
sequenceDiagram
    participant Test as Test Runner
    participant API as API Server
    participant MCP as MachineConfigPool
    participant Node as Worker Node
    participant FS as Node Filesystem

    Test->>API: create ImageDigestMirrorSet & ImageTagMirrorSet
    API->>MCP: MCP spec updated (worker, master)
    MCP->>Node: trigger config rollout
    Node->>FS: write /etc/containers/registries.conf
    Test->>Node: oc exec/read /etc/containers/registries.conf
    Test->>Test: verify locations, pull-from-mirror, and blocked entries
    Test->>API: delete mirror sets (DeferCleanup)
    API->>MCP: MCP spec revert triggers
    MCP->>Node: revert config, rollout complete
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 11 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Single Node Openshift (Sno) Test Compatibility ⚠️ Warning Test lacks SNO protection. No [Skipped:SingleReplicaTopology] label, exutil.IsSingleNode() check, or skipOnSingleNodeTopology() call present. Add [Skipped:SingleReplicaTopology] label to line 170 test name, or add exutil.IsSingleNode() check with g.Skip() in test body. See custom check instructions for code examples.
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title references a Jira issue (OCPNODE-4505) and mentions it's automating an OCP test case (OCP-57401), which directly aligns with the PR's main objective of adding an end-to-end test implementation for OCP-57401.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All Ginkgo test names are stable and deterministic. The new test title "[OTP] Create ImageDigestMirrorSet... [OCP-57401]" is static, with dynamic suffixes correctly confined to test body only.
Test Structure And Quality ✅ Passed Test meets all 5 quality requirements: single responsibility, proper setup/cleanup with DeferCleanup, 20-minute timeouts, meaningful assertion messages, and codebase consistency.
Microshift Test Compatibility ✅ Passed Test uses OpenShift APIs not available on MicroShift but includes BeforeEach hook with exutil.IsMicroShiftCluster() check that skips on MicroShift—an acceptable protection mechanism.
Topology-Aware Scheduling Compatibility ✅ Passed This PR adds only end-to-end test code in test/extended/node/. The Topology-Aware Scheduling check applies to deployment manifests, operator code, or controllers—none are present here. Not applicable.
Ote Binary Stdout Contract ✅ Passed All code in Ginkgo structures. No process-level code. All logging uses safe e2e.Logf/framework.Logf. Zero stdout violations. OTE Binary Stdout Contract preserved.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Test contains no IPv4 assumptions or external connectivity requirements. Registry names are used as configuration data only, not as connection targets. All operations are cluster-internal.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci Bot requested review from cpmeadors and mrunalp May 7, 2026 08:31
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@test/extended/node/node_e2e/node.go`:
- Around line 331-332: In verifyRegistryBlocked, replace the fixed "j >= i-5"
backward line-limit with a scan that continues until you hit the previous
registry boundary or start of file: starting from j := i-1 loop while j >= 0 and
!strings.Contains(lines[j], "[[registry]]") (stop before the prior
"[[registry]]") and check for strings.Contains(lines[j], "blocked = true"); do
the same for the symmetric forward scan (the other occurrence around lines
340-341) so both searches stop at the neighboring "[[registry]]" block marker
instead of a hard ±5 line window.
- Around line 182-183: The test uses fixed cluster-scoped mirror-set names
"digest-mirror" and "tag-mirror" which can collide between runs; change the code
that constructs those mirror-set resource Names to append a unique suffix (e.g.,
test run id, timestamp, or random string) so each invocation creates
uniquely-named mirror-sets, and propagate that generated name to all places that
reference "digest-mirror" and "tag-mirror" (the mirror-set creation structs and
any subsequent lookups/assertions) so tests no longer fail with AlreadyExists
from leftover artifacts.
🪄 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: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 2dc75fc1-8480-42ae-b540-eab4ad3c4e55

📥 Commits

Reviewing files that changed from the base of the PR and between 65324f7 and e5944f9.

📒 Files selected for processing (1)
  • test/extended/node/node_e2e/node.go

Comment thread test/extended/node/node_e2e/node.go Outdated
Comment thread test/extended/node/node_e2e/node.go Outdated
Comment thread test/extended/node/node_e2e/node.go Outdated
@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e-aws-csi
/test e2e-aws-ovn-fips
/test e2e-aws-ovn-microshift
/test e2e-aws-ovn-microshift-serial
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-gcp-csi
/test e2e-gcp-ovn
/test e2e-gcp-ovn-upgrade
/test e2e-metal-ipi-ovn-ipv6
/test e2e-vsphere-ovn
/test e2e-vsphere-ovn-upi

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 7, 2026
Comment thread test/extended/node/node_e2e/node.go Outdated
initialWorkerSpec := imagepolicy.GetMCPCurrentSpecConfigName(oc, "worker")
initialMasterSpec := imagepolicy.GetMCPCurrentSpecConfigName(oc, "master")

createdIDMS, err := configClient.ImageDigestMirrorSets().Create(ctx, idms, metav1.CreateOptions{})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coderabbit pointed out that this could fail with AlreadExists. Why not use Apply() rather than create? or you need to check it if exists first before create.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I addressed CodeRabbit comments. Resource names now include a random suffix via utilrand.String(5) (e.g., digest-mirror-xk4qz), so AlreadyExists collisions from leftover artifacts won't happen.
Using Apply() would work too, but it could silently overwrite a resource from a concurrent test run rather than failing explicitly, which is less safe. With unique names + Create(), we get a clean resource every time and would catch genuine conflicts.

@openshift-merge-bot openshift-merge-bot Bot added the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label May 8, 2026
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 8, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 8, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: asahay19
Once this PR has been reviewed and has the lgtm label, please assign haircommander for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/extended/node/node_utils.go (1)

746-764: ⚡ Quick win

GetFirstReadyWorkerNode is inconsistent with the rest of the file: no context, N+1 subprocess calls

Every other function in this file takes a context.Context and uses the Kubernetes client directly. GetFirstReadyWorkerNode instead:

  1. Takes no context — callers cannot propagate cancellation or timeouts.
  2. Issues one subprocess call to list node names, then one more per node to read its Ready condition — the existing getNodesByLabel + isNodeInReadyState helpers already cover this in a single API round-trip.

Consider implementing it with the existing helpers:

♻️ Proposed refactor
-func GetFirstReadyWorkerNode(oc *exutil.CLI) string {
-	nodeNames, err := oc.AsAdmin().WithoutNamespace().Run("get").Args(
-		"nodes", "-l", "node-role.kubernetes.io/worker",
-		"-o=jsonpath={.items[*].metadata.name}",
-	).Output()
-	o.Expect(err).NotTo(o.HaveOccurred())
-	workers := strings.Fields(nodeNames)
-	o.Expect(workers).NotTo(o.BeEmpty(), "no worker nodes found")
-
-	for _, w := range workers {
-		status, statusErr := oc.AsAdmin().WithoutNamespace().Run("get").Args(
-			"nodes", w,
-			"-o=jsonpath={.status.conditions[?(@.type=='Ready')].status}",
-		).Output()
-		if statusErr == nil && status == "True" {
-			return w
-		}
-	}
-	return ""
-}
+func GetFirstReadyWorkerNode(ctx context.Context, oc *exutil.CLI) string {
+	workers, err := getNodesByLabel(ctx, oc, "node-role.kubernetes.io/worker")
+	o.Expect(err).NotTo(o.HaveOccurred())
+	o.Expect(workers).NotTo(o.BeEmpty(), "no worker nodes found")
+
+	for _, w := range workers {
+		if isNodeInReadyState(&w) {
+			return w.Name
+		}
+	}
+	o.Expect(false).To(o.BeTrue(), "no Ready worker node found")
+	return "" // unreachable
+}
🤖 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 `@test/extended/node/node_utils.go` around lines 746 - 764,
GetFirstReadyWorkerNode should accept a context.Context and use the existing
Kubernetes client helpers instead of spawning kubectl per-node: change the
signature of GetFirstReadyWorkerNode to take ctx context.Context, call
getNodesByLabel(ctx, oc, "node-role.kubernetes.io/worker") to get nodes, then
iterate and call isNodeInReadyState(ctx, oc, node) (or the equivalent helper
names present) to find the first Ready node and return its name; remove the
subprocess Run("get") calls and preserve the same return semantics (empty string
if none found).
🤖 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 `@test/extended/node/node_utils.go`:
- Around line 755-764: GetFirstReadyWorkerNode currently returns an empty string
when no worker with Ready=True is found, causing downstream cryptic failures;
change the post-loop behavior in GetFirstReadyWorkerNode (the function that
iterates workers and calls oc.AsAdmin().WithoutNamespace().Run("get").Args(...))
to fail the test immediately with a clear message (e.g. call the test
framework's fail/assert function or t.Fatalf/Failf) indicating "no ready worker
node found" instead of returning "" so callers never receive an invalid node
name.

---

Nitpick comments:
In `@test/extended/node/node_utils.go`:
- Around line 746-764: GetFirstReadyWorkerNode should accept a context.Context
and use the existing Kubernetes client helpers instead of spawning kubectl
per-node: change the signature of GetFirstReadyWorkerNode to take ctx
context.Context, call getNodesByLabel(ctx, oc, "node-role.kubernetes.io/worker")
to get nodes, then iterate and call isNodeInReadyState(ctx, oc, node) (or the
equivalent helper names present) to find the first Ready node and return its
name; remove the subprocess Run("get") calls and preserve the same return
semantics (empty string if none found).
🪄 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: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: ef32c950-ef14-4009-bfa5-3caf3802f43c

📥 Commits

Reviewing files that changed from the base of the PR and between e5944f9 and 9b247db.

📒 Files selected for processing (2)
  • test/extended/node/node_e2e/node.go
  • test/extended/node/node_utils.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/extended/node/node_e2e/node.go

Comment thread test/extended/node/node_utils.go Outdated
@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e-aws-csi
/test e2e-aws-ovn-fips
/test e2e-aws-ovn-microshift
/test e2e-aws-ovn-microshift-serial
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-gcp-csi
/test e2e-gcp-ovn
/test e2e-gcp-ovn-upgrade
/test e2e-metal-ipi-ovn-ipv6
/test e2e-vsphere-ovn
/test e2e-vsphere-ovn-upi

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 12, 2026
@asahay19 asahay19 changed the title [OCPNODE-4505]: Automation creation of OCP-57401 OCPNODE-4505: Automation creation of OCP-57401 May 12, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label May 12, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented May 12, 2026

@asahay19: This pull request references OCPNODE-4505 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the sub-task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

PR Summary

This test automates manual test case OCP-57401 by verifying end-to-end creation of both ImageDigestMirrorSet (IDMS) and ImageTagMirrorSet (ITMS) resources. It creates an IDMS and ITMS with both AllowContactingSource and NeverContactSource mirror policies, waits for MachineConfigPool rollouts, and then validates that /etc/containers/registries.conf on a worker node contains the correct digest-only and tag-only mirror entries along with blocked = true for NeverContactSource registries.

This test is already present in openshift-test-private. As part of migrating test cases , I am automating it origin.
Polarian Link: https://polarion.engineering.redhat.com/polarion/#/project/OSE/workitem?id=OCP-57401
Jira task : https://redhat.atlassian.net/browse/OCPNODE-4505

Output
Tested locally on 4.22 openshift cluster and it got passed.

./openshift-tests run-test '[sig-node][Suite:openshift/disruptive-longrunning][Disruptive][Serial] ImageTagMirrorSet and ImageDigestMirrorSet [OTP] Create ImageDigestMirrorSet and ImageTagMirrorSet and verify registries.conf [OCP-57401]'

 Ran 1 of 1 Specs in 1274.887 seconds
 SUCCESS! -- 1 Passed | 0 Failed | 0 Pending | 0 Skipped
[
 {
   "name": "[sig-node][Suite:openshift/disruptive-longrunning][Disruptive][Serial] ImageTagMirrorSet and ImageDigestMirrorSet [OTP] Create ImageDigestMirrorSet and ImageTagMirrorSet and verify registries.conf [OCP-57401]",
   "lifecycle": "blocking",
   "duration": 1274888,
   "startTime": "2026-05-07 07:50:46.647072 UTC",
   "endTime": "2026-05-07 08:12:01.535488 UTC",
   "result": "passed",
   "output": "  STEP:

PTAL @cpmeadors @BhargaviGudi

Summary by CodeRabbit

  • Tests
  • Added a new end-to-end test suite validating ImageTagMirrorSet and ImageDigestMirrorSet behavior: ensures mirror entries and pull-from-mirror modes (digest-only, tag-only), verifies non-mirrored sources are blocked, confirms registry configuration is present on a ready worker node, and checks Machine Config Pool rollout and cleanup occur successfully.
  • Tests
  • Added test utilities to locate a ready worker node and to validate registry blocking in configuration files.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

# Conflicts:
#	test/extended/node/node_e2e/node.go
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 12, 2026
@openshift-merge-bot
Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e-aws-csi
/test e2e-aws-ovn-fips
/test e2e-aws-ovn-microshift
/test e2e-aws-ovn-microshift-serial
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-gcp-csi
/test e2e-gcp-ovn
/test e2e-gcp-ovn-upgrade
/test e2e-metal-ipi-ovn-ipv6
/test e2e-vsphere-ovn
/test e2e-vsphere-ovn-upi

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 12, 2026

@asahay19: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants