Skip to content

OCPBUGS-99696: Add extension verification failure test cases OCP-89090 and OCP-89095 - #6333

Open
ptalgulk01 wants to merge 1 commit into
openshift:mainfrom
ptalgulk01:ppt/ocp-89095-89090
Open

OCPBUGS-99696: Add extension verification failure test cases OCP-89090 and OCP-89095#6333
ptalgulk01 wants to merge 1 commit into
openshift:mainfrom
ptalgulk01:ppt/ocp-89095-89090

Conversation

@ptalgulk01

@ptalgulk01 ptalgulk01 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • OCP-89090: Tests that MCD detects missing staged deployment when rpm-ostree silently succeeds on extension install (fake binary via bind mount). Verifies MCP degrades with "no staged
    deployment found after applying extensions" error.
  • OCP-89095: Tests that MCD detects extension packages missing from RPM database after reboot. Uses fake rpm binary that reports usbguard as not installed. Verifies MCP degrades with
    "extension package verification failed" error.

Both tests use a custom MCP with 1 node, bind-mount fake binaries via nsenter, and validate degradation via checkDegraded. Cleanup restores original binaries, deletes MC, recovers MCP, and
deletes custom MCP — all in defer.

Test plan

  • Run OCP-89090 on a cluster and verify MCP degrades with staged deployment error
  • Run OCP-89095 on a cluster and verify MCP degrades with extension verification error
  • Verify cleanup restores cluster to healthy state after each test

Summary by CodeRabbit

  • Tests
    • Added disruptive end-to-end coverage for MCO extensions, including degraded outcomes when staged deployments are missing and when extension package verification fails.
    • Enhanced failure scenarios by introducing more realistic simulations for system command behavior (including package query failure and no-op install/override).
    • Added validations to ensure the node MCD daemon surfaces the same failure reason, along with dependable cleanup and recovery back to a healthy state.
  • Chores
    • Centralized the temporary command override/restore behavior to make node rebases and extension checks more consistent.

@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: LGTM mode

@openshift-ci

openshift-ci Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ptalgulk01

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

The pull request process is described 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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Walkthrough

Adds reusable node command replacement helpers and two disruptive extension tests that simulate staged deployment and package verification failures, verify MachineConfigPool degradation and MCD logs, and recover the affected pool during cleanup.

Changes

Extension failure testing

Layer / File(s) Summary
Command replacement helpers
test/extended-priv/node.go, test/extended-priv/testdata/files/rpm-ostree-fake-install-noop.sh, test/extended-priv/testdata/files/rpm-fake-usbguard-missing.sh
Centralizes bind-mounted replacement and restoration of rpm-ostree and rpm, and adds fake command behavior for extension failure scenarios.
Extension failure-path tests
test/extended-priv/mco_extensions.go
Adds tests for missing staged deployments and failed extension package verification, including MCP condition checks, MCD log validation, and cleanup recovery.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ExtensionTest
  participant Node
  participant MCD
  participant MCP
  ExtensionTest->>Node: replace rpm-ostree or rpm
  ExtensionTest->>MCD: apply extension MachineConfig
  ExtensionTest->>MCD: delete daemon pod
  MCD->>MCP: report NodeDegraded condition
  ExtensionTest->>MCP: verify failure message
  ExtensionTest->>MCD: verify failure log
Loading

Possibly related PRs

Suggested reviewers: dkhater-redhat, harshwardhanpatil07


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error New Infof logs print node/pod names and MCP/node identifiers, exposing internal hostnames in test output. Remove or redact these logs; avoid logging node/pod names or other host-identifying values in Infof/echo output.
Microshift Test Compatibility ⚠️ Warning No MicroShift guard is present, and the new tests use MachineConfig/MachineConfigPool and openshift-machine-config-operator, which MicroShift doesn't serve. Add [apigroup:machineconfiguration.openshift.io] or [Skipped:MicroShift], or gate the tests with exutil.IsMicroShiftCluster() and g.Skip().
✅ Passed checks (13 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: new extension verification failure test cases for OCP-89090 and OCP-89095.
Docstring Coverage ✅ Passed Docstring coverage is 100.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 titles in the changed files are static strings; the new 89090/89095 test names contain no dynamic data or generated identifiers.
Test Structure And Quality ✅ Passed Both new It blocks focus on one failure mode, clean up with defers, and use bounded Eventually calls for cluster waits; assertions include context.
Single Node Openshift (Sno) Test Compatibility ✅ Passed Both new tests use GetCompactCompatibleOrCustomPool(...,1), which returns the master pool on compact/SNO, and they only operate on one node; no multi-node/HA assumptions found.
Topology-Aware Scheduling Compatibility ✅ Passed Only test helpers and shell scripts changed; no deployment manifests, operator code, or controllers were added, so no scheduling constraints were introduced.
Ote Binary Stdout Contract ✅ Passed No stdout writes were added in main/init/TestMain/suite setup; logger output goes to GinkgoWriter and shell-script echoes are test helpers, not the binary process.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed New Ginkgo tests only use cluster-internal MCP/node ops and local bind-mounted helper scripts; no IPv4 literals, host formatting, or external network calls found.
No-Weak-Crypto ✅ Passed No weak crypto primitives, custom crypto, or secret comparisons were added in the changed files; only test helpers and MCO extension tests were introduced.
Container-Privileges ✅ Passed The PR only changes Go test helpers and shell scripts; no container/K8s manifests or privileged settings like hostPID, allowPrivilegeEscalation:true, or SYS_ADMIN were added.
✨ 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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-priv/mco_extensions.go`:
- Line 156: The informational logs in test/extended-priv/mco_extensions.go at
lines 156-156 and 212-212 expose node hostnames through node.GetName(). Update
both logger.Infof calls to log only the customMCPName identifier; retain node
names only in assertion or error messages.
- Around line 159-180: Make fake-binary lifecycle cleanup failure-safe at
test/extended-priv/mco_extensions.go:159-180 and
test/extended-priv/mco_extensions.go:215-236: register rollback before mutating
rpm-ostree or rpm, ensure setup failures trigger restoration, and assert every
restoration command succeeds. Update the cleanup callbacks to check
DebugNodeWithChroot errors and avoid masking umount failures with trailing
commands; do not ignore any Go error returns.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: efcbdd0c-0d7c-4447-950f-23f8a5fbaefe

📥 Commits

Reviewing files that changed from the base of the PR and between 2c2abc8 and 38deb8f.

📒 Files selected for processing (1)
  • test/extended-priv/mco_extensions.go

Comment thread test/extended-priv/mco_extensions.go Outdated
Comment thread test/extended-priv/mco_extensions.go Outdated
@ptalgulk01

Copy link
Copy Markdown
Contributor Author

/test bootstrap-unit

Comment thread test/extended-priv/mco_extensions.go Outdated
Comment on lines +152 to +156
customMCPName := fmt.Sprintf("test-%s-infra", testID)
customMCP, err := CreateCustomMCP(oc.AsAdmin(), customMCPName, 1)
o.Expect(err).NotTo(o.HaveOccurred(), "Could not create a new custom MCP")
node := customMCP.GetSortedNodesOrFail()[0]
logger.Infof("Custom MCP: %s, node: %s", customMCPName, node.GetName())

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.

We can use GetCompactCompatibleOrCustomPool instead, so that the test is compatible with SNO and Compact clusters too.

Comment thread test/extended-priv/mco_extensions.go Outdated
Comment on lines +160 to +166
fakeRpmOstreeScript := `printf '#!/bin/bash\nif [[ "$@" == *"install"* ]] || [[ "$@" == *"override"* ]]; then\n echo "Installing package (fake)"\n exit 0\nfi\nexec /var/tmp/rpm-ostree "$@"\n' > /var/tmp/rpm-ostree-fake.sh && ` +
`chmod +x /var/tmp/rpm-ostree-fake.sh && ` +
`cp /usr/bin/rpm-ostree /var/tmp/rpm-ostree && ` +
`nsenter --mount=/proc/1/ns/mnt mount --bind /var/tmp/rpm-ostree-fake.sh /usr/bin/rpm-ostree && ` +
`restorecon -v /usr/bin/rpm-ostree && echo done`
out, err := node.DebugNodeWithChroot("bash", "-c", fakeRpmOstreeScript)
o.Expect(err).NotTo(o.HaveOccurred(), "Failed to setup fake rpm-ostree on node %s: %s", node.GetName(), out)

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.

We already have similar code in the method node.BreakRebaseInNode

It seems that several test cases need this action, and likely more test cases will need it in the future.

I think it would be a good idea to create a function ReplaceRpmostree() accepting an existing script in the node and replacing the rpm-ostree with it

We would need a RestoreRpmostree() too, to rever the changes executed by ReplaceRpmostree().

Like that all tests can reuse the same code. We need to refactor BreakRebaseInNode so that it uses the new RestoreRpmostree fucntion too.

Optionally, we can store the script itself as a template, the same way BreakRebaseInNode does. If you prefer to leave it as a string I'm ok too, ti is a very short script.

Comment thread test/extended-priv/mco_extensions.go Outdated
Comment on lines +175 to +176
restoreScript := `nsenter --mount=/proc/1/ns/mnt umount -l /usr/bin/rpm-ostree 2>/dev/null; ` +
`rm -f /var/tmp/rpm-ostree-fake.sh /var/tmp/rpm-ostree; echo done`

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.

We shold encapsulate this in a RestoreRpmostree fucntion.

Use the node.FixRebaseInNode method as a model.

Note the "kill -9" statement in this method. We need to kill the running rpm-ostree before undoing the ReplaceRpmostree actions.

We need to do it to avoid a "devide busy" error when unmounting.

Comment thread test/extended-priv/mco_extensions.go Outdated

exutil.By("Wait for MCP to degrade with missing staged deployment error")
expectedNDMessage := regexp.QuoteMeta("no staged deployment found after applying extensions")
checkDegraded(customMCP, expectedNDMessage, "", "NodeDegraded", false, 1)

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.

I think it would be simpler to avoid using this function. Jut check the status and the message in the mcp.

I think it would be easier to read. We can check the machine-config co status

Comment thread test/extended-priv/mco_extensions.go Outdated
Comment on lines +208 to +210
customMCPName := fmt.Sprintf("test-%s-infra", testID)
customMCP, err := CreateCustomMCP(oc.AsAdmin(), customMCPName, 1)
o.Expect(err).NotTo(o.HaveOccurred(), "Could not create a new custom MCP")

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.

Same, we can use the function to make it compatible with SNO and Compact clusters.

Comment thread test/extended-priv/mco_extensions.go Outdated
Comment on lines +230 to +233
exutil.By("Restore rpm, delete MC, recover MCP, and delete custom MCP")
restoreScript := `nsenter --mount=/proc/1/ns/mnt umount -l /usr/bin/rpm 2>/dev/null; ` +
`rm -f /var/tmp/rpm-fake.sh /var/tmp/rpm-real; echo done`
node.DebugNodeWithChroot("bash", "-c", restoreScript)

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.

Same, let's encapsulate it in a recover function so that we can reuse it. Let's not forget the "kill -9" part.

The test should test the recover. We have 2 options: we can add the recover code as steps and make the defer section best effort. Or we can test it in the defer section and then we need to check all errors in the defer so that it fails if we can't recover.

Same in the previous test, I guess.

Actually the defer sections are all different. We should reach an agreement in the team and define how do we want the defer sections to be coded exactly.

Comment on lines +185 to +190
exutil.By("Restart MCD pod on the node to pick up fake rpm-ostree")
mcdPod := node.GetMachineConfigDaemon()
err = NewNamespacedResource(oc.AsAdmin(), "pod", MachineConfigNamespace, mcdPod).Delete()
o.Expect(err).NotTo(o.HaveOccurred(), "Failed to delete MCD pod %s", mcdPod)
logger.Infof("Deleted MCD pod %s to trigger re-sync with fake rpm-ostree", mcdPod)
logger.Infof("OK!\n")

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.

Why do we restart the pod in both tests?

I remember it was only necessary in only one of the, wasn't it?

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.

in early version I had to delete MCD pod to reproduce the issue, without deleting the restart used to not trigger and MCP not used to get degrade So here we need to delete the pod for both the TC.

Comment on lines +253 to +258
exutil.By("Restart MCD pod on the node to pick up fake rpm")
mcdPod := node.GetMachineConfigDaemon()
err = NewNamespacedResource(oc.AsAdmin(), "pod", MachineConfigNamespace, mcdPod).Delete()
o.Expect(err).NotTo(o.HaveOccurred(), "Failed to delete MCD pod %s", mcdPod)
logger.Infof("Deleted MCD pod %s to trigger re-sync", mcdPod)
logger.Infof("OK!\n")

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.

Do we need to restart the pod in both tests? or only in one of them?

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.

It depends, in early version I had to delete MCD pod to reproduce the issue. So here we need to delete the pod for both the TC.

Comment thread test/extended-priv/mco_extensions.go Outdated

exutil.By("Wait for MCP to degrade with extension verification error")
expectedNDMessage := "extension package verification failed"
checkDegraded(customMCP, expectedNDMessage, "", "NodeDegraded", false, 1)

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.

Same. Checking the mcp with eventually and HaveCondition should be enough.

Comment thread test/extended-priv/mco_extensions.go Outdated
Comment on lines +247 to +248
reapplyScript := `nsenter --mount=/proc/1/ns/mnt mount --bind /var/tmp/rpm-fake.sh /usr/bin/rpm && ` +
`restorecon -v /usr/bin/rpm && echo done`

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.

Let's try to keep this logic encapsulated if possible. If possible, I don't know if we can reapply it without breaking the encapsulation, but let's try. If not possible, or too ugly, we break the encapsulation.

@ptalgulk01
ptalgulk01 force-pushed the ppt/ocp-89095-89090 branch from 38deb8f to c8df918 Compare July 24, 2026 09:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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-priv/node.go (1)

1617-1624: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Unquoted scriptPath concatenated into shell command string.

scriptPath is spliced directly into the sh -c command in ReplaceRpmOstree/ReplaceRpm without quoting. Currently all call sites use hardcoded literal paths, so this isn't exploitable today, but it's a fragile pattern that path instructions flag for injection prevention — any future caller passing a path with whitespace or shell metacharacters would break or hijack the command.

🔒 Proposed fix
-			"nsenter --mount=/proc/1/ns/mnt mount --bind "+scriptPath+" /usr/bin/rpm-ostree && "+
+			"nsenter --mount=/proc/1/ns/mnt mount --bind '"+scriptPath+"' /usr/bin/rpm-ostree && "+

Apply the equivalent quoting in ReplaceRpm.

As per path instructions, injection prevention guidance states "Command: no shell=True, os.system, or backtick exec with user input" — unquoted string concatenation into a shell command is the same anti-pattern.

Also applies to: 1638-1645

🤖 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-priv/node.go` around lines 1617 - 1624, Update ReplaceRpmOstree
and ReplaceRpm to safely quote or escape scriptPath before interpolating it into
the sh -c command, preserving paths containing whitespace and preventing shell
interpretation of metacharacters. Keep the existing command behavior and
hardcoded call-site paths unchanged.

Source: Path instructions

🤖 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-priv/node.go`:
- Around line 1617-1624: Update the shell command chains in both
ReplaceRpmOstree and ReplaceRpm to join cp, mount --bind, and restorecon with &&
instead of semicolons, ensuring any failed setup step short-circuits and its
error is returned to the caller.

---

Nitpick comments:
In `@test/extended-priv/node.go`:
- Around line 1617-1624: Update ReplaceRpmOstree and ReplaceRpm to safely quote
or escape scriptPath before interpolating it into the sh -c command, preserving
paths containing whitespace and preventing shell interpretation of
metacharacters. Keep the existing command behavior and hardcoded call-site paths
unchanged.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: df6f3dd6-1510-4042-816d-05b218147844

📥 Commits

Reviewing files that changed from the base of the PR and between 38deb8f and c8df918.

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

Comment thread test/extended-priv/node.go Outdated
@ptalgulk01
ptalgulk01 force-pushed the ppt/ocp-89095-89090 branch from c8df918 to df566f6 Compare July 24, 2026 10:21
@ptalgulk01 ptalgulk01 changed the title Add extension verification failure test cases OCP-89090 and OCP-89095 OCPBUGS-65645: Add extension verification failure test cases OCP-89090 and OCP-89095 Jul 24, 2026
@openshift-ci-robot openshift-ci-robot added jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. labels Jul 24, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@ptalgulk01: This pull request references Jira Issue OCPBUGS-65645, which is invalid:

  • expected the bug to be in one of the following states: NEW, ASSIGNED, POST, but it is Verified instead

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Summary

  • OCP-89090: Tests that MCD detects missing staged deployment when rpm-ostree silently succeeds on extension install (fake binary via bind mount). Verifies MCP degrades with "no staged
    deployment found after applying extensions" error.
  • OCP-89095: Tests that MCD detects extension packages missing from RPM database after reboot. Uses fake rpm binary that reports usbguard as not installed. Verifies MCP degrades with
    "extension package verification failed" error.

Both tests use a custom MCP with 1 node, bind-mount fake binaries via nsenter, and validate degradation via checkDegraded. Cleanup restores original binaries, deletes MC, recovers MCP, and
deletes custom MCP — all in defer.

Test plan

  • Run OCP-89090 on a cluster and verify MCP degrades with staged deployment error
  • Run OCP-89095 on a cluster and verify MCP degrades with extension verification error
  • Verify cleanup restores cluster to healthy state after each test

Summary by CodeRabbit

  • Tests
  • Added disruptive coverage for MCO extensions behavior under failure scenarios, including degraded states for missing staged deployments and extension package verification failures.
  • Strengthened failure simulations by improving how system command behavior is temporarily overridden and then restored during node rebase/extension validation.
  • Added log assertions to confirm the same failure reason appears in the node MCD daemon output, with consistent cleanup and recovery verification.

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.

@openshift-ci-robot openshift-ci-robot added the jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. label Jul 24, 2026
@ptalgulk01

Copy link
Copy Markdown
Contributor Author

/jira refresh

@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@ptalgulk01: This pull request references Jira Issue OCPBUGS-65645, which is invalid:

  • expected the bug to be in one of the following states: NEW, ASSIGNED, POST, but it is Verified instead

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

Details

In response to this:

/jira refresh

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.

@ptalgulk01 ptalgulk01 changed the title OCPBUGS-65645: Add extension verification failure test cases OCP-89090 and OCP-89095 OCPBUGS-99696: Add extension verification failure test cases OCP-89090 and OCP-89095 Jul 24, 2026
@openshift-ci-robot openshift-ci-robot added jira/severity-low Referenced Jira bug's severity is low for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. and removed jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Jul 24, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@ptalgulk01: This pull request references Jira Issue OCPBUGS-99696, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Summary

  • OCP-89090: Tests that MCD detects missing staged deployment when rpm-ostree silently succeeds on extension install (fake binary via bind mount). Verifies MCP degrades with "no staged
    deployment found after applying extensions" error.
  • OCP-89095: Tests that MCD detects extension packages missing from RPM database after reboot. Uses fake rpm binary that reports usbguard as not installed. Verifies MCP degrades with
    "extension package verification failed" error.

Both tests use a custom MCP with 1 node, bind-mount fake binaries via nsenter, and validate degradation via checkDegraded. Cleanup restores original binaries, deletes MC, recovers MCP, and
deletes custom MCP — all in defer.

Test plan

  • Run OCP-89090 on a cluster and verify MCP degrades with staged deployment error
  • Run OCP-89095 on a cluster and verify MCP degrades with extension verification error
  • Verify cleanup restores cluster to healthy state after each test

Summary by CodeRabbit

  • Tests
  • Added disruptive coverage for MCO extensions behavior under failure scenarios, including degraded states for missing staged deployments and extension package verification failures.
  • Strengthened failure simulations by improving how system command behavior is temporarily overridden and then restored during node rebase/extension validation.
  • Added log assertions to confirm the same failure reason appears in the node MCD daemon output, with consistent cleanup and recovery verification.

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.

@ptalgulk01

Copy link
Copy Markdown
Contributor Author

/test bootstrap-unit

@ptalgulk01

Copy link
Copy Markdown
Contributor Author

/test security

@ptalgulk01

Copy link
Copy Markdown
Contributor Author

/cherry-pick release-4.22

@openshift-cherrypick-robot

Copy link
Copy Markdown

@ptalgulk01: once the present PR merges, I will cherry-pick it on top of release-4.22 in a new PR and assign it to you.

Details

In response to this:

/cherry-pick release-4.22

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.

@ptalgulk01

Copy link
Copy Markdown
Contributor Author

/test bootstrap-unit

Comment thread test/extended-priv/mco_extensions.go Outdated
o.Expect(err).NotTo(o.HaveOccurred(), "Failed to create fake rpm-ostree script on node %s: %s", node.GetName(), out)

exutil.By("Replace rpm-ostree with fake script")
o.Expect(ReplaceRpmOstree(node, fakeRpmOstreePath)).To(o.Succeed(),

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.

Let's encapsulate it even more.

We can use

node.ReplaceRpmOstree(node, fakeRpmOstreeScript)

Let the ReplaceRpmOstree handle the copy of the file to the node, so that it is easier to use by someone creating a test. Use a constant in the node file to define the path were the fake rpmostree will be copied.

Using print can interfere whit the special characters too. We can copy the string to a local file and copy the local file to the node.

Or we can store the script in a template, and make the node.RpelaceRmpOstree accept a node and a local file instead.

Comment thread test/extended-priv/mco_extensions.go Outdated
defer func() {
exutil.By("Restore rpm-ostree, delete MC, and recover MCP")
RestoreRpmOstree(node)
node.DebugNodeWithChroot("sh", "-c", "rm -f "+fakeRpmOstreePath)

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.

No need to do that, I think, it's just temp file.

But if you want to do it we should do it in the RestoreRpmOstree function.

Comment thread test/extended-priv/mco_extensions.go Outdated
mc.skipWaitForMcp = true
defer func() {
exutil.By("Restore rpm-ostree, delete MC, and recover MCP")
RestoreRpmOstree(node)

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.

Let's o.Expect(RestoreRpmOstree).To(o.Succeed()...

Comment thread test/extended-priv/mco_extensions.go Outdated
o.Expect(err).NotTo(o.HaveOccurred(), "Failed to create fake rpm script on node %s: %s", node.GetName(), out)

exutil.By("Replace rpm with fake script")
o.Expect(ReplaceRpm(node, fakeRpmPath)).To(o.Succeed(),

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.

Same, let's encapsulate the file creation inside the function too.

Using print to create the file will give problems in the future if we need to use special characters, since we will have to escape them. It is better to create a local file with the string, or directly provide a template name to the function. Like that no escape has to bee done to create the script.

Comment thread test/extended-priv/mco_extensions.go Outdated
defer func() {
exutil.By("Restore rpm, delete MC, and recover MCP")
RestoreRpm(node)
node.DebugNodeWithChroot("sh", "-c", "rm -f "+fakeRpmPath)

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.

Same

Comment thread test/extended-priv/node.go Outdated
func ReplaceRpmOstree(node *Node, scriptPath string) error {
logger.Infof("Replacing rpm-ostree with %s on node %s", scriptPath, node.GetName())
_, err := node.DebugNodeWithChroot("sh", "-c",
"cp /usr/bin/rpm-ostree /var/tmp/rpm-ostree && "+

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.

No "chmod +x" command?

Comment thread test/extended-priv/node.go Outdated
func ReplaceRpm(node *Node, scriptPath string) error {
logger.Infof("Replacing rpm with %s on node %s", scriptPath, node.GetName())
_, err := node.DebugNodeWithChroot("sh", "-c",
"cp /usr/bin/rpm /var/tmp/rpm-real && "+

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.

no "chmod +x" command?

@ptalgulk01
ptalgulk01 force-pushed the ppt/ocp-89095-89090 branch from df566f6 to 273cd5e Compare July 27, 2026 07:04
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@ptalgulk01: This pull request references Jira Issue OCPBUGS-99696, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

Summary

  • OCP-89090: Tests that MCD detects missing staged deployment when rpm-ostree silently succeeds on extension install (fake binary via bind mount). Verifies MCP degrades with "no staged
    deployment found after applying extensions" error.
  • OCP-89095: Tests that MCD detects extension packages missing from RPM database after reboot. Uses fake rpm binary that reports usbguard as not installed. Verifies MCP degrades with
    "extension package verification failed" error.

Both tests use a custom MCP with 1 node, bind-mount fake binaries via nsenter, and validate degradation via checkDegraded. Cleanup restores original binaries, deletes MC, recovers MCP, and
deletes custom MCP — all in defer.

Test plan

  • Run OCP-89090 on a cluster and verify MCP degrades with staged deployment error
  • Run OCP-89095 on a cluster and verify MCP degrades with extension verification error
  • Verify cleanup restores cluster to healthy state after each test

Summary by CodeRabbit

  • Tests
  • Added disruptive end-to-end coverage for MCO extensions, including degraded outcomes when staged deployments are missing and when extension package verification fails.
  • Enhanced failure scenarios by introducing more realistic simulations for system command behavior (including package query failure and no-op install/override).
  • Added validations to ensure the node MCD daemon surfaces the same failure reason, along with dependable cleanup and recovery back to a healthy state.
  • Chores
  • Centralized the temporary command override/restore behavior to make node rebases and extension checks more consistent.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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-priv/testdata/files/rpm-ostree-fake-install-noop.sh`:
- Around line 5-8: Update the command detection in the fake rpm-ostree script to
inspect exact argument tokens rather than joining "$@" and using substring
matching. Only treat invocations whose command token is exactly “install” or
“override” as successful fake operations, while leaving unrelated commands and
package names on the failure path.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0ae9c87b-20ce-4c0b-8ac1-548cfb9d7f2d

📥 Commits

Reviewing files that changed from the base of the PR and between df566f6 and 273cd5e.

📒 Files selected for processing (4)
  • test/extended-priv/mco_extensions.go
  • test/extended-priv/node.go
  • test/extended-priv/testdata/files/rpm-fake-usbguard-missing.sh
  • test/extended-priv/testdata/files/rpm-ostree-fake-install-noop.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/extended-priv/mco_extensions.go
  • test/extended-priv/node.go

Comment thread test/extended-priv/testdata/files/rpm-ostree-fake-install-noop.sh
@openshift-ci

openshift-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

@ptalgulk01: 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.

@isabella-janssen

Copy link
Copy Markdown
Member

/hold

Holding to allow the Kube rebase to land in #6321. Please ensure this will not cause merge conflicts for the Kube rebase before unholding this PR.

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. jira/severity-low Referenced Jira bug's severity is low for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants