Skip to content

CNTRLPLANE-3306: add ExternalOIDCWithUpstreamParity e2e tests#8287

Open
ehearne-redhat wants to merge 9 commits into
openshift:mainfrom
ehearne-redhat:external-oidc-test-featuregate-externaloidcwithupstreamparity
Open

CNTRLPLANE-3306: add ExternalOIDCWithUpstreamParity e2e tests#8287
ehearne-redhat wants to merge 9 commits into
openshift:mainfrom
ehearne-redhat:external-oidc-test-featuregate-externaloidcwithupstreamparity

Conversation

@ehearne-redhat

@ehearne-redhat ehearne-redhat commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

This change:

  • Adds extensive testing for the ExternalOIDCWithUpstreamParity feature gate in control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go.

    • Includes testing the discoveryUrl, userValidationRules, claimValidationRules, and claimMappings.
  • Tests the feature gate in a HyperShift cluster in test/e2e/external_oidc_test.go.

  • Provides basic auth config testing of the feature gate in test/e2e/util/external_oidc.go .

  • Configures the control plane operator feature sets in hypershift-operator.

    • This change is required as hypershift-operator re-uses control-plane-operator
      auth config validation code, which checks specifically for control-plane-operator
      feature set enablement.

      Without this change, if we try to enable feature set such as TechPreviewNoUpgrade,
      validation will fail as hypershift-operator does not configure control-plane-operator
      feature sets.

This change will allow us to test feature gates behind TechPreviewNoUpgrade and
others that are present in control-plane-operator, throughout HyperShift.

This should allow us to progress in promotion of the feature from TechPreview to GA.

Which issue(s) this PR fixes:

https://redhat.atlassian.net/browse/CNTRLPLANE-3306.

Allows us to progress in promotion of the ExternalOIDCWithUpstreamParity feature from TechPreview to GA.

Special notes for your reviewer:

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

  • New Features

    • Added External OIDC with upstream parity (feature-gated): supports differing discovery URLs, CEL-based claim→username/groups mappings, multiple claim validation rules, and user validation rules (reject system: usernames).
  • Tests

    • Expanded unit and end-to-end tests covering discovery URL propagation, complex CEL claim mappings (nested/conditional/orValue/defaults/filter/map), claim and user validation behaviors, error case for empty CEL claim expression, and runtime username/groups resolution.

@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-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Apr 20, 2026
@openshift-ci-robot

openshift-ci-robot commented Apr 20, 2026

Copy link
Copy Markdown

@ehearne-redhat: This pull request references CNTRLPLANE-3306 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 story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

What this PR does / why we need it:

This change:

  • Adds extensive testing for the ExternalOIDCWithUpstreamParity feature gate in control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go.

  • Includes testing the discoveryUrl, userValidationRules, claimValidationRules, and claimMappings.

  • Tests the feature gate in a HyperShift cluster in test/e2e/external_oidc_test.go.

  • Provides basic auth config testing of the feature gate in test/e2e/util/external_oidc.go .

This should allow us to progress in promotion of the feature from TechPreview to GA.

Which issue(s) this PR fixes:

https://redhat.atlassian.net/browse/CNTRLPLANE-3306.

Allows us to progress in promotion of the ExternalOIDCWithUpstreamParity feature from TechPreview to GA.

Special notes for your reviewer:

Currently a work in progress. Must check if tests pass at present, and will move PR into working state for review.

Checklist:

  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

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 commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added unit and e2e tests and updated a test utility to exercise the ExternalOIDCWithUpstreamParity feature gate. Tests and the utility now emit and verify CEL-based claim mappings for username and groups, add CEL claim validation rules (email presence/non-empty and email_verified == true), and add a CEL user validation rule preventing usernames with the system: prefix. Tests also cover discovery URL handling when it differs from the issuer. All changes are limited to tests and the test helper that builds the AuthenticationConfiguration.

Sequence Diagram(s)

sequenceDiagram
  actor TestRunner
  participant HostedClusterSpec as "HostedCluster Spec"
  participant Controller as "Control Plane Operator"
  participant KAS as "Kube API Server (KAS)"
  participant SSR as "SelfSubjectReview"
  participant OIDC as "External OIDC Provider"

  TestRunner->>HostedClusterSpec: create spec with ExternalOIDCWithUpstreamParity enabled
  HostedClusterSpec->>Controller: reconcile spec
  Controller->>KAS: produce AuthenticationConfiguration (DiscoveryURL, CEL claim mappings, claim/user validation rules)
  KAS->>OIDC: use DiscoveryURL to fetch metadata / validate tokens
  OIDC-->>KAS: return token and user claims
  KAS->>SSR: evaluate ClaimMappings and UserValidationRules (CEL)
  SSR-->>TestRunner: return UserInfo (username, groups) and validation result
Loading
🚥 Pre-merge checks | ✅ 10 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ❓ Inconclusive Test files referenced in PR summary are not present in repository, preventing verification of test structure quality against Ginkgo patterns. Verify test files are accessible and assess: single responsibility per It() block, proper cleanup in AfterEach(), timeouts on Eventually/Consistently, meaningful assertion messages, and consistency with repository patterns.
✅ Passed checks (10 passed)
Check name Status Explanation
Title check ✅ Passed The title 'CNTRLPLANE-3306: add ExternalOIDCWithUpstreamParity e2e tests' directly and clearly describes the main change: adding e2e tests for the ExternalOIDCWithUpstreamParity feature gate promotion.
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 test names in the PR use stable, deterministic patterns with static string literals and no dynamic values like timestamps, UUIDs, or random suffixes.
Microshift Test Compatibility ✅ Passed New e2e tests for HyperShift's external OIDC feature are guarded by ExternalOIDCWithUpstreamParity feature gate, which is HyperShift-specific and does not apply to MicroShift.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The new e2e test validates OIDC authentication configuration and claim mapping through control-plane APIs without requiring multi-node cluster topology.
Topology-Aware Scheduling Compatibility ✅ Passed PR contains exclusively test-file modifications with no deployment manifests, operator code, or scheduling constraint definitions.
Ote Binary Stdout Contract ✅ Passed The pull request adds only test code and test utility functions with no process-level code that could violate the OTE Binary Stdout Contract.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The new e2e tests do not contain IPv4 assumptions or external connectivity requirements. Tests validate internal Kubernetes OIDC configuration without external service calls.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

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

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

@openshift-ci openshift-ci Bot added do-not-merge/needs-area do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. labels Apr 20, 2026
@openshift-ci openshift-ci Bot requested review from bryan-cox and csrwng April 20, 2026 13:10
@openshift-ci openshift-ci Bot added the area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release label Apr 20, 2026
@openshift-ci

openshift-ci Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: ehearne-redhat
Once this PR has been reviewed and has the lgtm label, please assign enxebre 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 area/testing Indicates the PR includes changes for e2e testing and removed do-not-merge/needs-area labels Apr 20, 2026
@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from 423d933 to 67f1e85 Compare April 20, 2026 13:15

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go (1)

1964-1996: Tighten this negative case by asserting error reason.

This case currently checks only that an error occurs. Please assert an expected error substring (e.g., empty CEL expression) so unrelated failures can’t satisfy the test.

🔧 Suggested pattern
 type testCase struct {
   name                                string
   client                              crclient.Reader
   expectedAuthenticationConfiguration *AuthenticationConfiguration
   hcpAuthenticationSpec               *configv1.AuthenticationSpec
   shouldError                         bool
+  expectedErrContains                 string
   featureGates                        []featuregate.Feature
 }

 // in negative test case:
 shouldError: true,
+expectedErrContains: "expression is not set",

 // in assertion block:
 if tc.shouldError {
   if err == nil {
     t.Fatal("expected an error to have occurred but got none")
   }
+  if tc.expectedErrContains != "" && !strings.Contains(err.Error(), tc.expectedErrContains) {
+    t.Fatalf("expected error containing %q, got: %v", tc.expectedErrContains, err)
+  }
   return
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go`
around lines 1964 - 1996, The test case "claimValidationRule with CEL - empty
expression, error" currently only sets shouldError = true; tighten it by adding
an expected error substring (e.g., expectedErrorSubstring: "empty" or "CEL
expression") and changing the test assertions in the test loop to assert the
returned error string contains that substring rather than merely checking
shouldError; update the test harness code that reads shouldError (the test loop
in auth_test.go) to look for expectedErrorSubstring when an error is returned
(and fail if no substring match) so unrelated failures cannot satisfy the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go`:
- Around line 1964-1996: The test case "claimValidationRule with CEL - empty
expression, error" currently only sets shouldError = true; tighten it by adding
an expected error substring (e.g., expectedErrorSubstring: "empty" or "CEL
expression") and changing the test assertions in the test loop to assert the
returned error string contains that substring rather than merely checking
shouldError; update the test harness code that reads shouldError (the test loop
in auth_test.go) to look for expectedErrorSubstring when an error is returned
(and fail if no substring match) so unrelated failures cannot satisfy the test.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 829cd042-7de5-4a8b-9700-9504081ff9a9

📥 Commits

Reviewing files that changed from the base of the PR and between 5c06422 and 423d933.

📒 Files selected for processing (3)
  • control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go
  • test/e2e/external_oidc_test.go
  • test/e2e/util/external_oidc.go

@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from 67f1e85 to 92c4197 Compare April 20, 2026 13:17
@codecov

codecov Bot commented Apr 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 41.79%. Comparing base (712ba58) to head (d87d42a).
⚠️ Report is 34 commits behind head on main.

Files with missing lines Patch % Lines
hypershift-operator/main.go 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8287      +/-   ##
==========================================
+ Coverage   41.66%   41.79%   +0.13%     
==========================================
  Files         758      759       +1     
  Lines       93929    94040     +111     
==========================================
+ Hits        39135    39304     +169     
+ Misses      52046    51986      -60     
- Partials     2748     2750       +2     
Files with missing lines Coverage Δ
hypershift-operator/main.go 0.00% <0.00%> (ø)

... and 11 files with indirect coverage changes

Flag Coverage Δ
cmd-support 35.11% <ø> (+0.15%) ⬆️
cpo-hostedcontrolplane 44.10% <ø> (+0.09%) ⬆️
cpo-other 43.45% <ø> (ø)
hypershift-operator 51.87% <0.00%> (+0.21%) ⬆️
other 31.56% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ehearne-redhat ehearne-redhat changed the title [WIP] CNTRLPLANE-3306: add ExternalOIDCWithUpstreamParity e2e tests CNTRLPLANE-3306: add ExternalOIDCWithUpstreamParity e2e tests Apr 20, 2026
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 20, 2026
Comment thread control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go Outdated
Comment thread control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go Outdated
Comment thread test/e2e/util/external_oidc.go Outdated
Comment thread test/e2e/util/external_oidc.go
Comment thread test/e2e/external_oidc_test.go Outdated
g.Expect(selfSubjectReview.Status.UserInfo.Username).NotTo(BeEmpty())
// Username should be the email prefix (before @) since we configured expression: claims.email.split('@')[0]
g.Expect(selfSubjectReview.Status.UserInfo.Username).NotTo(ContainSubstring("@"))
t.Logf("CEL username expression successfully mapped to: %s", selfSubjectReview.Status.UserInfo.Username)

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.

Should also make sure the actual username matches what we expect?

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.

Yes, that makes sense. I have looked into how to do that. We can use userInfo.extra["claims.email"] and string parsing to ensure that the username matches what we expect i.e. if email is [email protected] then username should be foo .

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.

Is there a more deterministic way for us to have a set of expected output data based on the input data?

Relying on a separate feature to test the output of this feature feels like a bit of an unnecessary dependency if we have a way to be more deterministic.

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.

I did try to ponder on how we could do this. I wanted a different way to this but this was the one that jumped out to me. It was the only way I could see to ensure an absolute verification of the username.

I will investigate further and see.

Comment thread test/e2e/external_oidc_test.go Outdated
g := NewWithT(t)
t.Logf("begin to test CEL groups expression mapping")
// Groups expression uses: has(claims.groups) && type(claims.groups) == list ? claims.groups : []
// If the token has groups, they should be present without prefix (no prefix in CEL expression)

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.

For this test case, do we guarantee that the user will have groups configured?

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.

I believe so - I'm looking at this script here.

https://github.com/openshift/release/blob/main/ci-operator/step-registry/idp/external-oidc/keycloak/server/idp-external-oidc-keycloak-server-commands.sh#L189-L245

I'm thinking it wouldn't be a bad idea to have more reference to this script since there is this line that references a variable from this script.

https://github.com/openshift/hypershift/blob/main/test/e2e/util/external_oidc.go#L233-L234

That way we know exactly where this is all coming from. WDYT?

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 wonder if we should do away with the automatic setup of users and groups within Keycloak via that script?

Or at the very least have a deterministic set of users/groups that get created so that we can have more deterministic test behaviors?

Ideally, our test cases are self-sufficient and fully encompass the scope of what needs to be done.

Maybe this is better suited as a follow up though to prevent the scope of this work from getting blown up.

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.

We would need to look into it, definitely. From what I could tell, the users/groups had to be deployed in this way because of the nature of HyperShift itself. We can't do CRUD for the users/groups here because Keycloak is run externally here - we rely on it being set up alongside HyperShift, and it would be different to us having access to a cluster to just spin up keycloak/modify on the fly in our origin test suites.

I think realistically we would need to modify that script so the environment can match our expectations. However, it would also need to match the other test expectations too since these changes would impact those tests too.

I think we should definitely aim to figure that out sooner rather than later before we have too many tests that "commit" or conform to the script expectations.

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't do CRUD for the users/groups here because Keycloak is run externally here - we rely on it being set up alongside HyperShift, and it would be different to us having access to a cluster to just spin up keycloak/modify on the fly in our origin test suites

The running Keycloak instance has to be accessible to the HostedCluster that is created. Makes me think it would inherently be accessible to us as well. We would just need to make sure we know where we need to make the requests to configure it on the fly.

I wonder if we could even go so far as deploying Keycloak on the fly to have full control in the test setup like we do in the standalone openshift tests.

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.

I think you're right - we have access to admin creds from the script in keycloak ns.

https://github.com/openshift/release/blob/main/ci-operator/step-registry/idp/external-oidc/keycloak/server/idp-external-oidc-keycloak-server-commands.sh#L30

With these creds we could control the users/groups by making api calls via ExtOIDCConfig.IssuerURL .

And on that same thread, we could actually deploy Keycloak here. We probably have everything we need. I could convert the script deployment into go code here.

This way we would have full control over testing username concretely.

I'll work on a potential way of doing this and re-ping when ready. Thanks for thinking this one out! :)

Comment thread test/e2e/external_oidc_test.go
@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from 92c4197 to cfa62cb Compare April 22, 2026 16:36
Comment thread test/e2e/external_oidc_test.go Outdated
g.Expect(selfSubjectReview.Status.UserInfo.Username).NotTo(ContainSubstring("@"))
// equals the actual email prefix
// e2eutil.ExternalOIDCExtraKeyFoo --> claims.email expression
emailValues := selfSubjectReview.Status.UserInfo.Extra[e2eutil.ExternalOIDCExtraKeyFoo]

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.

@everettraven do we know if this field is feature gate dependent?

So if ExternalOIDCWithUIDAndExtraClaimMappings feature gate was disabled in the future what impact does it have on accessing this field for email verification?

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.

Since I have ensured the field can accessible on either feature gate enablement this shouldn't be an issue. :)

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 feature gate should already be enabled by default for a couple releases and therefore should never be disabled in the future. We actually need to remove it in the near future.

I don't think we need to check the UserInfo.Extra field as part of these tests though because that is functionality from an entirely different feature.

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.

Ah OK - thanks for clarifying! In that case we would need to use another mechanism as you rightfully pointed out in #8287 (comment) .

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

♻️ Duplicate comments (1)
control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go (1)

2220-2221: ⚠️ Potential issue | 🟠 Major

Use optional claim access before calling orValue here.

These two cases still use claims.groups.orValue([])..., but orValue([]) only works on an optional value. The earlier parity case already uses the correct form: claims.?groups.orValue([]). As written, these "shouldError: false" cases are asserting invalid CEL as a supported mapping.

Suggested fix
-								Expression: "claims.groups.orValue([]).filter(g, g.startsWith('ocp-'))",
+								Expression: "claims.?groups.orValue([]).filter(g, g.startsWith('ocp-'))",
-								Expression: "claims.groups.orValue([]).filter(g, g.startsWith('ocp-'))",
+								Expression: "claims.?groups.orValue([]).filter(g, g.startsWith('ocp-'))",

Also applies to: 2258-2260, 2311-2312, 2356-2358

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go`
around lines 2220 - 2221, The test cases are using non-optional access
`claims.groups.orValue([])...`, which is invalid because `orValue` requires an
optional; update each offending expression to use optional access
`claims.?groups.orValue([]).filter(g, g.startsWith('ocp-'))` (i.e., change
`claims.groups.orValue([])` to `claims.?groups.orValue([])` in the test
vectors). Locate and fix the same pattern occurrences referenced in the file
(the similar expressions around the other test cases that currently use
`claims.groups.orValue([])`).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/e2e/external_oidc_test.go`:
- Around line 124-128: The username assertion currently reads the expected value
from the extra claim key e2eutil.ExternalOIDCExtraKeyFoo which only exists when
the ExternalOIDCWithUIDAndExtraClaimMappings feature is enabled; update the test
in external_oidc_test.go so it first checks whether
ExternalOIDCWithUIDAndExtraClaimMappings is enabled and only then asserts the
username from
selfSubjectReview.Status.UserInfo.Extra[e2eutil.ExternalOIDCExtraKeyFoo],
otherwise derive the expectedUserName from the test’s chosen upstream user (use
the variable that holds the selected test user/email used to create the upstream
identity) and assert that selfSubjectReview.Status.UserInfo.Username equals that
derived username.

---

Duplicate comments:
In `@control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go`:
- Around line 2220-2221: The test cases are using non-optional access
`claims.groups.orValue([])...`, which is invalid because `orValue` requires an
optional; update each offending expression to use optional access
`claims.?groups.orValue([]).filter(g, g.startsWith('ocp-'))` (i.e., change
`claims.groups.orValue([])` to `claims.?groups.orValue([])` in the test
vectors). Locate and fix the same pattern occurrences referenced in the file
(the similar expressions around the other test cases that currently use
`claims.groups.orValue([])`).
🪄 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: Pro Plus

Run ID: 0971fdb6-6682-4fe9-b2fd-40b3d5169afd

📥 Commits

Reviewing files that changed from the base of the PR and between 92c4197 and cfa62cb.

📒 Files selected for processing (3)
  • control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go
  • test/e2e/external_oidc_test.go
  • test/e2e/util/external_oidc.go

Comment thread test/e2e/external_oidc_test.go Outdated
@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from cfa62cb to ac11bf0 Compare April 23, 2026 12:22

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/e2e/external_oidc_test.go (1)

132-139: Consider verifying actual groups mapping, not just configuration.

This subtest only validates that the groups expression is configured but doesn't verify the actual selfSubjectReview.Status.UserInfo.Groups contains expected values. If the Keycloak test users have groups configured, asserting their presence would strengthen this test.

💡 Suggested enhancement
 t.Run("[OCPFeatureGate:ExternalOIDCWithUpstreamParity] Test CEL groups expression mapping", func(t *testing.T) {
     g := NewWithT(t)
     t.Logf("begin to test CEL groups expression mapping")
     // Groups expression uses: has(claims.groups) && type(claims.groups) == list ? claims.groups : []
     // If the token has groups, they should be present without prefix (no prefix in CEL expression)
     g.Expect(hostedCluster.Spec.Configuration.Authentication.OIDCProviders[0].ClaimMappings.Groups.Expression).NotTo(BeEmpty())
+    // Verify groups are actually present in the response if user has groups configured
+    g.Expect(selfSubjectReview.Status.UserInfo.Groups).NotTo(BeEmpty())
     t.Logf("CEL groups expression configured: %s", hostedCluster.Spec.Configuration.Authentication.OIDCProviders[0].ClaimMappings.Groups.Expression)
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/e2e/external_oidc_test.go` around lines 132 - 139, The test currently
only asserts the CEL groups expression is configured; instead, after confirming
hostedCluster.Spec.Configuration.Authentication.OIDCProviders[0].ClaimMappings.Groups.Expression
is not empty, call the same code path that performs a self-subject review
(inspect the SelfSubjectReview object used in this test) and assert that
selfSubjectReview.Status.UserInfo.Groups contains the expected group names for
the Keycloak test user(s). Locate the subtest block (the t.Run with label "Test
CEL groups expression mapping") and add an assertion using the existing test
helper that retrieves the SelfSubjectReview (or create one via the API client
used elsewhere in the test suite) to verify the groups slice is non-empty and
includes the known group(s) for the test account.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go`:
- Around line 2219-2221: The CEL expressions in test fixtures using
PrefixedClaimOrExpression.Expression wrongly call orValue() on possibly-missing
fields (e.g. "claims.groups.orValue([])") which requires optional access; update
each Expression string to use the optional operator before the field (e.g.
"claims.?groups.orValue([])") and do the same for roles (use
"claims.?roles.orValue([])"); apply this change to all occurrences of
PrefixedClaimOrExpression where Expression references claims.groups or
claims.roles (the instances noted around the test cases at the four groups lines
and the two roles lines).

---

Nitpick comments:
In `@test/e2e/external_oidc_test.go`:
- Around line 132-139: The test currently only asserts the CEL groups expression
is configured; instead, after confirming
hostedCluster.Spec.Configuration.Authentication.OIDCProviders[0].ClaimMappings.Groups.Expression
is not empty, call the same code path that performs a self-subject review
(inspect the SelfSubjectReview object used in this test) and assert that
selfSubjectReview.Status.UserInfo.Groups contains the expected group names for
the Keycloak test user(s). Locate the subtest block (the t.Run with label "Test
CEL groups expression mapping") and add an assertion using the existing test
helper that retrieves the SelfSubjectReview (or create one via the API client
used elsewhere in the test suite) to verify the groups slice is non-empty and
includes the known group(s) for the test account.
🪄 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: Pro Plus

Run ID: 66e94f4c-86ef-48ad-9645-5acece62f594

📥 Commits

Reviewing files that changed from the base of the PR and between cfa62cb and ac11bf0.

📒 Files selected for processing (3)
  • control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go
  • test/e2e/external_oidc_test.go
  • test/e2e/util/external_oidc.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e/util/external_oidc.go

@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from ac11bf0 to 842e4e3 Compare April 23, 2026 15:18

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (2)
test/e2e/external_oidc_test.go (2)

132-139: Outdated comment contradicts actual implementation.

The comment on line 135 states:

// Groups expression uses: has(claims.groups) && type(claims.groups) == list ? claims.groups : []

However, the actual expression set in test/e2e/util/external_oidc.go line 172 is claims.?groups.orValue([]). Please update the comment to reflect the correct expression.

Additionally, this test only verifies configuration was applied (checking Expression is non-empty), not actual behavior. Consider strengthening the test by verifying selfSubjectReview.Status.UserInfo.Groups matches expected values, similar to how username is verified.

📝 Proposed fix for the comment
-			// Groups expression uses: has(claims.groups) && type(claims.groups) == list ? claims.groups : []
-			// If the token has groups, they should be present without prefix (no prefix in CEL expression)
+			// Groups expression uses: claims.?groups.orValue([])
+			// Groups are returned as-is when present, or empty list when absent
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/e2e/external_oidc_test.go` around lines 132 - 139, The comment inside
the Test CEL groups expression mapping test is stale and should be updated to
match the actual CEL expression used (claims.?groups.orValue([])) — locate the
test (t.Run "[OCPFeatureGate:ExternalOIDCWithUpstreamParity] Test CEL groups
expression mapping") and replace the old comment with the correct expression
string referencing
hostedCluster.Spec.Configuration.Authentication.OIDCProviders[0].ClaimMappings.Groups.Expression;
additionally, strengthen the test by fetching the SelfSubjectReview and
asserting selfSubjectReview.Status.UserInfo.Groups contains the expected group
values (similar to the existing username assertion) to verify behavior, not just
configuration presence.

141-156: Test assertions are tightly coupled to implementation details.

The tests hard-code the exact CEL expressions being verified. If the implementation changes these expressions, the tests will fail even if the new expressions are functionally equivalent.

Consider extracting these to constants shared between external_oidc.go and this test file, or using more behavioral assertions where possible.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/e2e/external_oidc_test.go` around lines 141 - 156, The test hard-codes
exact CEL strings from ClaimValidationRules
(hostedCluster.Spec.Configuration.Authentication.OIDCProviders[0].ClaimValidationRules)
which couples the test to implementation; extract the two CEL expressions into
exported constants (e.g., ClaimExprEmailExists and ClaimExprEmailVerified) in
the package that defines external_oidc.go and reference those constants in this
test, or replace the exact-string assertions with behavioral checks (e.g.,
assert the rule Type is TokenValidationRuleTypeCEL and the CEL expression
contains/semantically matches the expected predicate) so the test verifies
intent not exact syntax.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/e2e/external_oidc_test.go`:
- Around line 132-139: The comment inside the Test CEL groups expression mapping
test is stale and should be updated to match the actual CEL expression used
(claims.?groups.orValue([])) — locate the test (t.Run
"[OCPFeatureGate:ExternalOIDCWithUpstreamParity] Test CEL groups expression
mapping") and replace the old comment with the correct expression string
referencing
hostedCluster.Spec.Configuration.Authentication.OIDCProviders[0].ClaimMappings.Groups.Expression;
additionally, strengthen the test by fetching the SelfSubjectReview and
asserting selfSubjectReview.Status.UserInfo.Groups contains the expected group
values (similar to the existing username assertion) to verify behavior, not just
configuration presence.
- Around line 141-156: The test hard-codes exact CEL strings from
ClaimValidationRules
(hostedCluster.Spec.Configuration.Authentication.OIDCProviders[0].ClaimValidationRules)
which couples the test to implementation; extract the two CEL expressions into
exported constants (e.g., ClaimExprEmailExists and ClaimExprEmailVerified) in
the package that defines external_oidc.go and reference those constants in this
test, or replace the exact-string assertions with behavioral checks (e.g.,
assert the rule Type is TokenValidationRuleTypeCEL and the CEL expression
contains/semantically matches the expected predicate) so the test verifies
intent not exact syntax.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 98f452a1-8817-4b7c-898f-55d646f9551c

📥 Commits

Reviewing files that changed from the base of the PR and between ac11bf0 and 842e4e3.

📒 Files selected for processing (3)
  • control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go
  • test/e2e/external_oidc_test.go
  • test/e2e/util/external_oidc.go

@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from 842e4e3 to 7870823 Compare April 23, 2026 16:16
Comment thread test/e2e/util/external_oidc.go Outdated
Comment thread test/e2e/util/external_oidc.go Outdated
Comment thread test/e2e/external_oidc_test.go Outdated
g.Expect(selfSubjectReview.Status.UserInfo.Username).NotTo(ContainSubstring("@"))
// equals the actual email prefix
// e2eutil.ExternalOIDCExtraKeyFoo --> claims.email expression
emailValues := selfSubjectReview.Status.UserInfo.Extra[e2eutil.ExternalOIDCExtraKeyFoo]

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 feature gate should already be enabled by default for a couple releases and therefore should never be disabled in the future. We actually need to remove it in the near future.

I don't think we need to check the UserInfo.Extra field as part of these tests though because that is functionality from an entirely different feature.

Comment thread test/e2e/external_oidc_test.go Outdated
g.Expect(selfSubjectReview.Status.UserInfo.Username).NotTo(BeEmpty())
// Username should be the email prefix (before @) since we configured expression: claims.email.split('@')[0]
g.Expect(selfSubjectReview.Status.UserInfo.Username).NotTo(ContainSubstring("@"))
t.Logf("CEL username expression successfully mapped to: %s", selfSubjectReview.Status.UserInfo.Username)

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.

Is there a more deterministic way for us to have a set of expected output data based on the input data?

Relying on a separate feature to test the output of this feature feels like a bit of an unnecessary dependency if we have a way to be more deterministic.

Comment thread test/e2e/external_oidc_test.go Outdated
g := NewWithT(t)
t.Logf("begin to test CEL groups expression mapping")
// Groups expression uses: has(claims.groups) && type(claims.groups) == list ? claims.groups : []
// If the token has groups, they should be present without prefix (no prefix in CEL expression)

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 wonder if we should do away with the automatic setup of users and groups within Keycloak via that script?

Or at the very least have a deterministic set of users/groups that get created so that we can have more deterministic test behaviors?

Ideally, our test cases are self-sufficient and fully encompass the scope of what needs to be done.

Maybe this is better suited as a follow up though to prevent the scope of this work from getting blown up.

Comment thread test/e2e/external_oidc_test.go
@bryan-cox

Copy link
Copy Markdown
Member

/uncc

This change:

+ Adds extensive testing for the ExternalOIDCWithUpstreamParity feature gate
  in `control-plane-operator/controllers/hostedcontrolplane/v2/kas/auth_test.go`.
  + includes testing the discoveryUrl, userValidationRules, claimValidationRules,
    and claimMappings.

+ Tests the feature gate in a HyperShift cluster in `test/e2e/external_oidc_test.go`.

+ Provides basic auth config testing of the feature gate in `test/e2e/util/external_oidc.go` .

This should allow us to progress in promotion of the feature from TechPreview to GA.
…instance

This commit adds the necessary functions to interact with the externally deployed Keycloak instance.

The Keycloak instance is deployed at the link below.

https://github.com/openshift/release/blob/main/ci-operator/step-registry/idp
/external-oidc/keycloak/server/idp-external-oidc-keycloak-server-commands.sh

Also adds user/group CRUD functionality to tests.
This commit configures the control plane operator feature sets in hypershift-operator.
This change is required as hypershift-operator re-uses control-plane-operator
auth config validation code, which checks specifically for control-plane-operator
feature set enablement.

Without this change, if we try to enable feature set such as TechPreviewNoUpgrade,
validation will fail as hypershift-operator does not configure control-plane-operator
feature sets.

This change will allow us to test feature gates behind TechPreviewNoUpgrade and
others that are present in control-plane-operator, throughout HyperShift.
This commit fixes failing tests for ExternalOIDCWithUpstreamParity and
ExternalOIDCWithUIDAndExtraClaimMappings feature gates by wrapping feature
gate specific test expectations behind if-statements.

Also reworks ExternalOIDCWithUpstreamParity tests with new
user/group CRUD framework. It also adds negative testing to existing
tests.

Additionally, AWS and AKS e2e support is added. Keycloak is deployed
differently on both clusters and credentials are also stored
differently.

TryAuthenticateUser() now uses AnonymousClientConfig() instead of
using clientcfg on its own, which effectively copied
over admin token that was able to authenticate with
kube-apiserver whenever it was used.

This caused KAS logs to show selfsubjectreviews being successful
for system:admin, because these weren't cleared. Now, only the
specified user token should be used to identify the user for
validation rule testing.

It also adds check for `Unauthorized` to be present in error message,
rather than relying on a more detailed error message to be thrown.
This change moves keycloak api code from `external_oidc.go` to
its own file, `keycloak.go` . Also adds check for admin token
expiry + refreshes if needed.
This change adds the ability to specify custom auth config for testing
ExternalOIDC functionality, which will prove useful for when features
behind feature gates graduate to default feature set.
@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from 8d410fb to b52e639 Compare June 15, 2026 12:14
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from b52e639 to f5e0572 Compare June 15, 2026 12:39
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from f5e0572 to 45acd6f Compare June 15, 2026 13:22
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test verify

@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from 45acd6f to aaf89c7 Compare June 15, 2026 15:16
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from aaf89c7 to 03f8952 Compare June 16, 2026 08:25
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from 03f8952 to 2aec511 Compare June 16, 2026 11:46
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from 2aec511 to f5986c8 Compare June 16, 2026 16:05
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

@openshift-ci

openshift-ci Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

@ehearne-redhat: The following test 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-aws b8543b2 link true /test e2e-aws

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.

This change experiments with custom auth config chage from
previous commit by adding new NHT.Execute() with custom
auth config specified.
@ehearne-redhat ehearne-redhat force-pushed the external-oidc-test-featuregate-externaloidcwithupstreamparity branch from f5986c8 to b3b2a84 Compare June 16, 2026 21:53
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

This change moves from having to write out a complete auth spec per
test, instead only modifying a baseline auth spec as needed per test.

This is currently being tested on one test. If successful, next commits
will look to migrate over all tests to custom auth spec pattern.
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

This change refactors the external oidc tests so that they
use the auth config spec, modifying as needed for their use case.

The change also lifts feature gate checks for feature sets that
have graduated to default, and allows for easier modification of
default auth config when this occurs in the future.

When feature gate checks are needed for feature sets, we can now
specify auth config modifications to be used in test execution.
@ehearne-redhat

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-aks-external-oidc-techpreview
/test e2e-aws-external-oidc-techpreview

@hypershift-jira-solve-ci

hypershift-jira-solve-ci Bot commented Jun 17, 2026

Copy link
Copy Markdown

Now I have the complete picture. The diff shows exactly 4 additions (1 import + 1 comment + 1 function call + 1 blank line), of which 3 are executable/trackable lines. Let me produce the final report.

Test Failure Analysis Complete

Job Information

  • Prow Job: codecov/patch (Codecov GitHub integration)
  • Build ID: Check Run 81921434184
  • PR: #8287CNTRLPLANE-3306: add ExternalOIDCWithUpstreamParity e2e tests
  • Commit: d87d42a (head) vs 712ba58 (base)

Test Failure Analysis

Error

Patch coverage is 0.00% with 3 lines in your changes missing coverage (target 41.66%).
File: hypershift-operator/main.go — 0.00% patch coverage, 3 lines missing.

Summary

The codecov/patch check failed because the PR adds 3 new executable lines to hypershift-operator/main.go — a file with 0% overall unit test coverage — and none of those lines are hit by any test. Codecov's patch-coverage gate requires new/modified lines to have non-zero coverage (target: 41.66%). The 3 lines are an import of cpofeaturegate, a comment, and a cpofeaturegate.ConfigureFeatureSet(featureSet) call, all inside the NewStartCommand() CLI entrypoint which is never invoked in unit tests. This is not a product bug — overall project coverage actually improved (+0.13%) with this PR.

Root Cause

The PR adds the following lines to hypershift-operator/main.go (lines ~28, ~212-213):

// import block:
cpofeaturegate "github.com/openshift/hypershift/control-plane-operator/featuregates"

// inside NewStartCommand(), after featuregate.Gate().AddFlag(cmd.Flags()):
// Configure feature set from CPO (needed to propagate feature gates like TechPreviewNoUpgrade)
cpofeaturegate.ConfigureFeatureSet(featureSet)

These live inside NewStartCommand(), which constructs the root cobra.Command for the hypershift-operator binary. The entire hypershift-operator/main.go file has 0% unit test coverage — this is a pre-existing condition because CLI entrypoint files wire up the full operator runtime and are inherently difficult to unit-test in isolation.

Codecov's codecov/patch check evaluates only the changed lines in the diff. Since 0 of the 3 trackable added lines are exercised by any test, patch coverage is 0%, which falls below the 41.66% target and fails the check.

The remaining ~2,585 lines added across the other 5 files (e2e tests in test/e2e/ and unit tests in auth_test.go) are properly excluded from patch coverage by the repo's codecov.yml ignore rules (test/**, **/*_test.go).

Recommendations
  1. Check if codecov/patch is a required status check. In most openshift/hypershift configurations, this check is informational (not required for merge). If so, this failure can be safely ignored.

  2. If the check must pass, consider these options:

    • Add hypershift-operator/main.go to the ignore list in codecov.yml, alongside other already-ignored entrypoint files. CLI main files are inherently unsuitable for unit test coverage.
    • Add a minimal unit test that calls NewStartCommand() and asserts the returned *cobra.Command is non-nil. This trivially covers the added lines without requiring full integration setup.
  3. Focus on the other failing checks first. The lint / Lint and verify / Verify checks are also failing on this PR and are more likely to be required status checks.

Evidence
Evidence Detail
Codecov report 0.00% of diff hit (target 41.66%)
Failing file hypershift-operator/main.go — 3 lines missing, 0% patch coverage
File baseline coverage 0.00% — entire file has zero unit test coverage (pre-existing)
Exact lines added +cpofeaturegate "github.com/openshift/hypershift/control-plane-operator/featuregates" (import), +// Configure feature set from CPO... (comment), +cpofeaturegate.ConfigureFeatureSet(featureSet) (call)
Total PR diff 4 additions, 0 deletions in main.go; ~2,589 total additions across 6 files
Project coverage impact +0.13% (41.66% → 41.79%) — coverage improved overall
Unit test suites All pass: cpo-hostedcontrolplane, cpo-other, hypershift-operator, cmd-support, other
Test files properly excluded test/e2e/external_oidc_test.go, test/e2e/util/external_oidc.go, test/e2e/util/external_oidc_test_helpers.go, test/e2e/util/keycloak.go, auth_test.go

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

Labels

area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/testing Indicates the PR includes changes for e2e testing 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.

4 participants