Skip to content

Sort incompatible CSVs in the Upgradeable condition message - #3952

Open
haklein wants to merge 1 commit into
operator-framework:masterfrom
haklein:OCPBUGS-129618-sort-upgradeable-skews
Open

haklein wants to merge 1 commit into
operator-framework:masterfrom
haklein:OCPBUGS-129618-sort-upgradeable-skews

Conversation

@haklein

@haklein haklein commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Description of the change:

skews.String() sorts a copy of the skews before it builds the Upgradeable condition message of the operator-lifecycle-manager ClusterOperator: skews with a property error first, then by namespace and name. A regression test feeds three skews in three orders and expects one message.

Motivation for the change:

incompatibleOperators lists the CSVs from the informer cache, which returns them in map order. The old String() kept that order, so the same set of blocking CSVs produced different messages between reconciles. conditionsEqual compares the message, so each reorder counted as a transition: the controller rewrote the ClusterOperator status and moved lastTransitionTime although nothing had changed. With two blocking CSVs on OCP 4.22 the message alternated between the two orders every one to two minutes.

Fixes https://issues.redhat.com/browse/OCPBUGS-129618

Architectural changes:

None.

Testing remarks:

  • TestSkewsStringIsDeterministic fails on the previous implementation, which filled the non-error entries from the end of the slice, and passes with the change.
  • make lint and make unit pass locally.
  • Reproduced and verified on an OCP 4.22.20 cluster with two CSVs that carry olm.maxOpenShiftVersion: "4.22". Before the change, 142 samples of the condition over 300 s showed two distinct messages and six distinct lastTransitionTime values. With the patched olm-operator, 141 samples over 300 s showed one message and one lastTransitionTime. Removing the CSVs set Upgradeable back to True.
  • The OLM v0 extended suite olmv0/extended/candidate/function ran against the patched operator on the same cluster: 203 specs, 163 passed, 39 skipped (topology filters), 1 failed. The failed spec (opm supports creating a catalog using semver veneer) exercises the opm CLI and died with exit status 127 because jq is missing in the test runner. It is unrelated to this change.

Reviewer Checklist

  • Implementation matches the proposed design, or proposal is updated to match implementation
  • Sufficient unit test coverage
  • Sufficient end-to-end test coverage
  • Bug fixes are accompanied by regression test(s)
  • e2e tests and flake fixes are accompanied evidence of flake testing, e.g. executing the test 100(0) times
  • tech debt/todo is accompanied by issue link(s) in comments in the surrounding code
  • Tests are comprehensible, e.g. Ginkgo DSL is being used appropriately
  • Docs updated or added to /doc
  • Commit messages sensible and descriptive
  • Tests marked as [FLAKE] are truly flaky and have an issue
  • Code is properly formatted

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Diagnostic summaries now display entries with errors first, followed by other entries sorted by namespace and name. The ordering remains consistent even when the entries are provided in a different order, making the summary easier to scan and compare across runs.

incompatibleOperators lists the CSVs from the informer cache. The cache
returns them in map order, which changes between reconciles.
skews.String() kept that order, so the same set of blocking CSVs
produced different messages. conditionsEqual compares the message, so
each reorder counted as a condition transition: the controller rewrote
the ClusterOperator status and moved lastTransitionTime although
nothing had changed. With two blocking CSVs on OCP 4.22 the message
alternated between the two orders every one to two minutes.

skews.String() now sorts a copy of the skews before it builds the
message: skews with a property error first, as before, then by
namespace and name. The same set of CSVs gives the same message in any
input order, so the condition only transitions when the set changes.

The regression test feeds three skews in three orders and expects one
message. It fails on the previous implementation, which filled the
non-error entries from the end of the slice.

Fixes OCPBUGS-129618

Signed-off-by: Harald Klein <hklein@redhat.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@openshift-ci
openshift-ci Bot requested review from joelanford and oceanc80 October 28, 2026 17:58
@openshift-ci

openshift-ci Bot commented Oct 28, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

@openshift-ci openshift-ci Bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Oct 28, 2026
@openshift-ci

openshift-ci Bot commented Oct 28, 2026

Copy link
Copy Markdown

Hi @haklein. Thanks for your PR.

I'm waiting for a operator-framework member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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.

@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f0592f30-c0ed-4d79-b477-a75f3d2f1a02
Commits

Reviewing files that changed from the base of the PR and between e046b5c and 52765af.

Files selected for processing: 2
  • pkg/controller/operators/openshift/helpers.go
  • pkg/controller/operators/openshift/helpers_test.go

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Walkthrough

skews.String now formats entries in a deterministic order. The function sorts a copy of the entries, and a test checks that three input orderings produce the same message.

Changes: Skew formatting

Layer / File(s) Summary
Sort skews before formatting
pkg/controller/operators/openshift/helpers.go, pkg/controller/operators/openshift/helpers_test.go
skews.String sorts a copy of the entries, placing entries with errors first and sorting by namespace and name. A test checks that three permutations produce the same output.

Priority: Normal

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

Change: Bug fix

Suggested reviewers: njhale

Merge Risk: Minimal · up to 52765

No merge-blocking risk was identified in this deterministic formatting change.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: sorting incompatible CSVs in the Upgradeable condition message.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
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.
Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 2 files.

Finishing Touches: 💡 1
🧪 Generate unit tests (beta)
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

golangci-lint (2.14.0)

golangci-lint (2.14.0) skipped for .golangci.yaml: configuration requires version: "2". Migrate older configurations using golangci-lint migrate and review the result; see https://golangci-lint.run/docs/product/migration-guide/.

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

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

Labels

needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant