Skip to content

e2e: Fix broken assertions - #1571

Open
oblau wants to merge 3 commits into
openshift:mainfrom
oblau:fix/e2e-broken-assertions
Open

e2e: Fix broken assertions#1571
oblau wants to merge 3 commits into
openshift:mainfrom
oblau:fix/e2e-broken-assertions

Conversation

@oblau

@oblau oblau commented Jul 23, 2026

Copy link
Copy Markdown
Member

Split into 3 commits by bug pattern — each fixes a distinct class of broken assertion across different test files.

  1. Add missing matcher to offlined CPU Expect() calls (5 sites)
    Expect(cpuSet.Equals(other)) without a matcher is a gomega no-op — always passes.
    Added .To(BeTrue()) so the comparison is actually asserted.

  2. Add missing error check to mixedcpus Get() calls (3 sites)
    Expect(client.Get(...)) without a matcher silently swallows errors.
    Captured the error and added Expect(err).ToNot(HaveOccurred()).

  3. PPC: replace no-op log-on-match with actual assertions (4 sites)
    if ok { testlog.Info(...) } after regexp.MatchString only logged on success — never failed the test when the expected error was missing from output.
    Replaced with Expect(ok).To(BeTrue()).

Summary by CodeRabbit

  • Tests
    • Improved end-to-end test validation for performance profile scenarios (including offlined CPU API checks).
    • Enhanced failure messages now clearly report expected vs. actual CPU sets, plus command output when applicable.
    • Standardized success/failure assertions across mixed-CPU and negative test cases for more consistent, reliable results.
    • Corrected a related log message to report the correct CPU set during revert steps.

Expect(bool) without .To() is a Gomega no-op; these tests never fail on these assertions.
@qodo-for-rh-openshift

Copy link
Copy Markdown

PR Summary by Qodo

E2E: Fix no-op Gomega assertions in performance profile tests

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Fix Gomega no-op assertions by adding missing matchers to boolean expectations.
• Ensure Kubernetes client Get() calls fail tests on API errors instead of silently passing.
• Make PPC output validation assert on missing expected error messages (not just log).
Diagram

graph TD
  A["E2E test cases"] --> B["Gomega Expect()"] --> C["Assert: BeTrue / NoError"]
  A --> D["K8s client Get()"] --> E[("PerformanceProfile CR")]
  A --> F["CLI output"] --> C
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use Gomega string/regex matchers directly
  • ➕ More idiomatic: Expect(output).To(MatchRegexp(...)) or ContainSubstring(...) avoids manual ok boolean plumbing
  • ➕ Failure messages can be more consistent and expressive with matcher output
  • ➖ May require small refactors where output is a []byte or needs specific formatting/context
  • ➖ Some existing tests may prefer explicit MatchString patterns for readability
2. Introduce a small helper to wrap client.Get + error assertion
  • ➕ Reduces repetition and prevents reintroducing Expect(client.Get(...)) no-ops
  • ➕ Centralizes consistent error messages/log context
  • ➖ Adds indirection for a small number of call sites
  • ➖ May be overkill unless this pattern appears broadly across the suite

Recommendation: The PR’s approach is correct and minimal-risk for fixing broken tests: add missing matchers and explicit error assertions at the call sites. If this pattern continues to appear elsewhere, consider a follow-up to use Gomega’s MatchRegexp/ContainSubstring matchers for output checks and/or a small helper for Get()+assertion to prevent future no-op expectations.

Files changed (3) +15 / -21

Bug fix (1) +6 / -3
mixedcpus.goCheck errors from ControlPlaneClient.Get() calls +6/-3

Check errors from ControlPlaneClient.Get() calls

• Captures the return value from 'ControlPlaneClient.Get(...)' into 'err' and asserts 'Expect(err).ToNot(HaveOccurred())'. Prevents silent passes where 'Expect(Get(...))' previously had no matcher and thus never failed on API errors.

test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go

Tests (2) +9 / -18
ppc.goAssert on expected error text presence in PPC tests +4/-13

Assert on expected error text presence in PPC tests

• Replaces log-only handling after 'regexp.MatchString' with 'Expect(ok).To(BeTrue(...))', ensuring the test fails when the expected error message is absent. Also drops an unused test logging import after removing the log-on-match pattern.

test/e2e/performanceprofile/functests/10_performance_ppc/ppc.go

updating_profile.goMake offlined CPU set equality checks actually assert +5/-5

Make offlined CPU set equality checks actually assert

• Adds '.To(BeTrue())' to 'Expect(offlinedCPUSet.Equals(...))' at multiple sites, converting previously no-op boolean expectations into real assertions. Includes clearer mismatch messages with expected vs actual CPU sets.

test/e2e/performanceprofile/functests/2_performance_update/updating_profile.go

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3dc54424-fc83-4504-ae8c-e5e2bd121b3a

📥 Commits

Reviewing files that changed from the base of the PR and between b138108 and 9c24e1d.

📒 Files selected for processing (2)
  • test/e2e/performanceprofile/functests/10_performance_ppc/ppc.go
  • test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e/performanceprofile/functests/10_performance_ppc/ppc.go

Walkthrough

Performance profile end-to-end tests now use explicit Gomega assertions, remove conditional PPC error logging, correct mixed CPU diagnostics, and include expected-versus-actual details for PPC and offline CPU-set failures.

Changes

Performance test assertion diagnostics

Layer / File(s) Summary
PPC error-match assertions
test/e2e/performanceprofile/functests/10_performance_ppc/ppc.go
Negative tests explicitly validate expected error regex matches and report the expected pattern and command output on failure.
Mixed CPU profile checks
test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go
Profile retrieval calls use explicit success assertions, and the shared CPU log reports the shared CPU set.
Offline CPU-set diagnostics
test/e2e/performanceprofile/functests/2_performance_update/updating_profile.go
Offline CPU checks explicitly assert CPU-set equality and report expected and actual sets on mismatch.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: ok-to-test

Suggested reviewers: jmencak, mrniranjan

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: fixing broken e2e test assertions across multiple files.
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 The touched Ginkgo titles are all static strings; the PR only changes assertions and logging, not test names.
Test Structure And Quality ✅ Passed Touched Ginkgo tests keep one-behavior-per-It, have cleanup, bounded waits, and improved assertion messages consistent with repo patterns.
Microshift Test Compatibility ✅ Passed PASS: The PR only tightens assertions in existing e2e tests; it adds no new Ginkgo test blocks or MicroShift-unsupported APIs/features.
Single Node Openshift (Sno) Test Compatibility ✅ Passed Only assertion fixes in existing tests; no new Ginkgo blocks or added multi-node/HA assumptions, and one multi-NUMA case already skips explicitly.
Topology-Aware Scheduling Compatibility ✅ Passed Only e2e test assertion fixes changed; no deployment manifests, operator/controller code, or scheduling constraints were added.
Ote Binary Stdout Contract ✅ Passed The patch only changes test assertions inside It/BeforeEach/AfterAll blocks; no stdout writes were added in main/BeforeSuite/RunSpecs, and the existing fmt.Printf is only used from It blocks.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The PR only tightens existing assertions; no new Ginkgo tests, IPv4-only literals, or external connectivity were added in the touched files.
No-Weak-Crypto ✅ Passed Touched test files only adjust assertions; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token comparisons found.
Container-Privileges ✅ Passed Diff only changes PPC test assertions; no privileged/container manifest fields are added.
No-Sensitive-Data-In-Logs ✅ Passed The PR removes a log-on-match PPC path and only adds assertion messages for CPU sets/error text; no secrets, PII, or tokens are logged.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="Running error: context loading failed: failed to load packages: failed to load packages: failed to load with go/packages: err: exit status 1: stderr: go: inconsistent vendoring in :\n\tgithub.com/RHsyseng/operator-utils@v1.4.13: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/coreos/go-systemd@v0.0.0-20191104093116-d3cd4ed1dbcf: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/coreos/ignition@v0.35.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/coreos/ignition/v2@v2.26.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/docker/go-units@v0.5.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/go-logr/stdr@v1.2.2: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/google/go-cmp@v0.7.0

... [truncated 19340 characters] ...

is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/legacy-cloud-providers: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/metrics: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/mount-utils: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/pod-security-admission: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/sample-apiserver: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tgithub.com/onsi/ginkgo/v2: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\n\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor\n"


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.

@openshift-ci
openshift-ci Bot requested review from Tal-or and jmencak July 23, 2026 10:34
@openshift-ci

openshift-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: oblau
Once this PR has been reviewed and has the lgtm label, please assign marsik 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

@qodo-for-rh-openshift

qodo-for-rh-openshift Bot commented Jul 23, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Misleading CPU-set log ✓ Resolved 🐞 Bug ◔ Observability
Description
In mixedcpus.go, the log line meant to print both the new isolated and new shared CPU sets prints
the isolated value twice, so the test output can misreport the applied shared CPU set. This reduces
debuggability when investigating profile-update failures in this scenario.
Code

test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go[325]

				testlog.Infof("new isolated CPU set=%q\nnew shared CPU set=%q", string(*profile.Spec.CPU.Isolated), string(*profile.Spec.CPU.Isolated))
Relevance

⭐⭐⭐ High

Trivial correctness fix: log currently misreports values; team has accepted similar
debuggability/typo log fixes in tests.

PR-#1324
PR-#1361

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The log format string contains both “new isolated” and “new shared”, but the arguments pass
profile.Spec.CPU.Isolated twice; elsewhere in the same block the code updates/uses
profile.Spec.CPU.Shared, showing the shared value is available and intended to be reported.

test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go[323-326]
test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go[309-313]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
A log statement prints the isolated CPU set for both the “isolated” and “shared” fields, making the output misleading.

### Issue Context
This happens right after re-fetching the updated PerformanceProfile, so the log is expected to reflect both updated fields.

### Fix Focus Areas
- test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go[323-326]

### Suggested change
Update the second argument to use `profile.Spec.CPU.Shared`:
```go
testlog.Infof("new isolated CPU set=%q\nnew shared CPU set=%q",
 string(*profile.Spec.CPU.Isolated),
 string(*profile.Spec.CPU.Shared),
)
```

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go Outdated

@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/e2e/performanceprofile/functests/10_performance_ppc/ppc.go`:
- Around line 164-167: Update the error matching in the test around errString
and regexp.MatchString to escape the literal CPU range before regex evaluation,
using regexp.QuoteMeta or an equivalent approach. Preserve the existing expected
message and assertions while ensuring the output comparison matches the literal
“[1,3]” text.
🪄 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: ff43d9d3-90fb-489e-be11-f312db4d9f15

📥 Commits

Reviewing files that changed from the base of the PR and between a9d25d5 and b138108.

📒 Files selected for processing (3)
  • test/e2e/performanceprofile/functests/10_performance_ppc/ppc.go
  • test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go
  • test/e2e/performanceprofile/functests/2_performance_update/updating_profile.go

Comment on lines 164 to +167
errString := "Error: failed to compute the reserved and isolated CPUs: please specify the reserved CPU count in the range [1,3]"
ok, err := regexp.MatchString(errString, string(output))
Expect(err).ToNot(HaveOccurred(), "did not fail with Expected:%s failure", errString)
if ok {
testlog.Info(errString)
}
Expect(ok).To(BeTrue(), "expected error %q not found in output: %s", errString, output)

@coderabbitai coderabbitai Bot Jul 23, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'test/e2e/performanceprofile/functests/10_performance_ppc/ppc.go' || true

echo "== relevant source =="
if [ -f test/e2e/performanceprofile/functests/10_performance_ppc/ppc.go ]; then
  sed -n '130,190p' test/e2e/performanceprofile/functests/10_performance_ppc/ppc.go
fi

echo "== deterministic regex behavior probe =="
python3 - <<'PY'
import re

errString = "Error: failed to compute the reserved and isolated CPUs: please specify the reserved CPU count in the range [1,3]"
output_same = errString
output_differed = "Error: failed to compute the reserved and isolated CPUs: please specify the reserved CPU count in the range [4,5]"
quoted = re.escape(errString)

for name, pat in [("errString", errString), ("regexp.QuoteMeta(errString)", quoted)]:
    print(name)
    try:
        print(" same matches:", bool(re.search(pat, output_same)))
        print(" differed matches:", bool(re.search(pat, output_differed)))
    except Exception as e:
        print(" regex error:", repr(e))
PY

Repository: openshift/cluster-node-tuning-operator

Length of output: 3438


Escape the literal CPU range before regex matching.

errString contains [1,3], but regexp.MatchString treats that as a character-class token, so it won't match the literal range: [1,3] text in the command output reliably.

Proposed fix
-			ok, err := regexp.MatchString(errString, string(output))
+			ok, err := regexp.MatchString(regexp.QuoteMeta(errString), string(output))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
errString := "Error: failed to compute the reserved and isolated CPUs: please specify the reserved CPU count in the range [1,3]"
ok, err := regexp.MatchString(errString, string(output))
Expect(err).ToNot(HaveOccurred(), "did not fail with Expected:%s failure", errString)
if ok {
testlog.Info(errString)
}
Expect(ok).To(BeTrue(), "expected error %q not found in output: %s", errString, output)
errString := "Error: failed to compute the reserved and isolated CPUs: please specify the reserved CPU count in the range [1,3]"
ok, err := regexp.MatchString(regexp.QuoteMeta(errString), string(output))
Expect(err).ToNot(HaveOccurred(), "did not fail with Expected:%s failure", errString)
Expect(ok).To(BeTrue(), "expected error %q not found in output: %s", errString, output)
🤖 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/e2e/performanceprofile/functests/10_performance_ppc/ppc.go` around lines
164 - 167, Update the error matching in the test around errString and
regexp.MatchString to escape the literal CPU range before regex evaluation,
using regexp.QuoteMeta or an equivalent approach. Preserve the existing expected
message and assertions while ensuring the output comparison matches the literal
“[1,3]” text.

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.

interesting catch @oblau worth looking into that

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Is the intention that the output will contain explicitly [1,3]?
If so im not sure regexp.MatchString is the right tool to begin with.
Would Expect(string(output)).To(ContainSubstring(errString)) be better here? we already use Expect(ppcErrorString).To(ContainSubstring("...") on test_id:41420

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping 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.

@oblau sounds good. if you're running it locally, it's worth printing string(output) and see the full error message.

@oblau

oblau commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

/retest

Comment thread test/e2e/performanceprofile/functests/11_mixedcpus/mixedcpus.go Outdated
errString := "Error: failed to obtain data from flags not appropriate to split reserved CPUs in case of topology-manager-policy: single-numa-node"
ok, err := regexp.MatchString(errString, string(output))
Expect(err).ToNot(HaveOccurred())
if ok {

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.

That's a change in the behavior. it makes the test more restrict. is that what we want here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is changing behavior - but isn't this the intention here?
If we are not asserting on ok then i fail to see why we need the errString
and regexp.MatchString(errString, string(output)) to begin with.
Maybe im missing something here.

Is the goal to make sure the correct error message appears, or that PPC script fails in general?

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.

After reevaluation I think this change is ok.
the only change I would add is in the message to make it more clear:

Expect(ok).To(BeTrue(), "expected error %q to be found in output: %s", errString, output)

oblau added 2 commits July 27, 2026 16:33
Expect(Get(...)) without .ToNot(HaveOccurred()) is a Gomega no-op;
API errors were silently swallowed. Split into err assignment +
Expect(err) to match the prevailing style in the file.
The `if ok { testlog.Info(...) }` pattern after regexp.MatchString
never failed the test when the expected error was absent from output.
Replace with Expect(ok).To(BeTrue()) so a missing error message
actually fails the test case.
@oblau
oblau force-pushed the fix/e2e-broken-assertions branch from b138108 to 9c24e1d Compare July 27, 2026 13:49
@openshift-ci

openshift-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

@oblau: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-hypershift-pao 9c24e1d link true /test e2e-hypershift-pao
ci/prow/e2e-hypershift 9c24e1d link true /test e2e-hypershift
ci/prow/e2e-gcp-pao 9c24e1d link true /test e2e-gcp-pao
ci/prow/e2e-aws-ovn 9c24e1d link true /test e2e-aws-ovn

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants