Skip to content

TRT-2769: WIP: Rework feature gate test filtering to cover component owned jobs#3731

Open
dgoodwin wants to merge 1 commit into
openshift:mainfrom
dgoodwin:fg-filter-logic
Open

TRT-2769: WIP: Rework feature gate test filtering to cover component owned jobs#3731
dgoodwin wants to merge 1 commit into
openshift:mainfrom
dgoodwin:fg-filter-logic

Conversation

@dgoodwin

@dgoodwin dgoodwin commented Jul 3, 2026

Copy link
Copy Markdown
Contributor
  • Centralizes the logic for how to find test results for a featuregate
    for re-use in the openshift/api verification job.
  • Feature Gate API now returns hateoas links clients can follow.
  • Includes a link to the tests tagged for the feature gate name.
  • Includes a link to the synthetic "openshift-tests should work" as an
    indicator the job fully passed, for any jobs tied to a Capability.
  • Replaces the hack for featuregates containing Install to automatically
    route to all install results and exclude actual tests for the FG.
  • Adds feature gate seed data and e2e tests.

Summary by CodeRabbit

  • New Features

    • Added a dedicated Feature Gates detail view with tabs for tests by annotation and capability.
    • Feature gate results now include helpful navigation links to related tests and the detail page.
    • Feature gate seeding now covers additional feature-gated scenarios and releases.
  • Bug Fixes

    • Improved navigation from the Feature Gates list so it opens the correct detail page.
    • Feature gate data (including generated links) is now populated consistently even when seed data already exists.
  • Tests

    • Added end-to-end coverage for Feature Gates API responses, server-side filtering, and link follow-through.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

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

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

This repository is configured in: automatic mode

@openshift-ci openshift-ci Bot requested review from petr-muller and sosiouxme July 3, 2026 17:23
@openshift-ci

openshift-ci Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dgoodwin

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

@dgoodwin dgoodwin changed the title Rework feature gate test filtering to cover component owned jobs WIP: Rework feature gate test filtering to cover component owned jobs Jul 3, 2026
@openshift-ci openshift-ci Bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. labels Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds seeded feature-gate scenarios, HATEOAS links in API responses, a frontend feature-gate detail page with linked test-result tabs, updated list navigation, and end-to-end API coverage.

Changes

Feature Gate Detail Flow

Layer / File(s) Summary
Seed feature-gate data
cmd/sippy/seed_data.go
Adds synthetic feature-gated jobs and tests, and ensures configured feature-gate records are created during both seeding paths.
Expose feature-gate links
pkg/apis/api/types.go, pkg/sippyserver/server.go
Adds a non-persistent Links field and injects annotation, capability, and UI detail URLs into feature-gate responses.
Render feature-gate details
sippy-ng/src/App.js, sippy-ng/src/tests/FeatureGateDetail.js
Routes feature-gate URLs to a detail page that loads metadata and displays linked test results in annotation and capability tabs.
Link list entries and validate APIs
sippy-ng/src/tests/FeatureGates.js, test/e2e/feature_gates_test.go, test/e2e/util/e2erequest.go
Updates list navigation and adds end-to-end coverage for fields, links, followable URLs, filtering, and absolute requests.

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

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant FeatureGates
  participant FeatureGateDetail
  participant SippyServer
  participant TestResultsAPI
  Browser->>FeatureGates: Load feature gates
  FeatureGates->>SippyServer: GET /api/feature_gates
  SippyServer-->>FeatureGates: Return gates with links
  Browser->>FeatureGateDetail: Navigate to ui_detail
  FeatureGateDetail->>SippyServer: Fetch filtered feature gate
  SippyServer-->>FeatureGateDetail: Return gate metadata and links
  FeatureGateDetail->>TestResultsAPI: Fetch annotation or capability results
  TestResultsAPI-->>FeatureGateDetail: Return test rows
  FeatureGateDetail-->>Browser: Render details and selected tab
Loading

Suggested reviewers: petr-muller, sosiouxme, xueqzhan, neisw, smg247


Caution

Pre-merge checks failed

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

  • Ignore

❌ Failed checks (1 error, 3 warnings)

Check name Status Explanation Resolution
Stable And Deterministic Test Names ❌ Error t.Run(fg.FeatureGate+" has HATEOAS links", ...) makes the subtest title depend on runtime data, so it isn't stable across data changes. Use a static title like feature gate has HATEOAS links and keep fg.FeatureGate in the test body/assertions.
Docstring Coverage ⚠️ Warning Docstring coverage is 6.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Go Error Handling ⚠️ Warning New seedSyntheticData error paths use pkg/errors.WithMessage instead of fmt.Errorf(...%w), so the PR doesn't follow the requested Go wrapping pattern. Change both feature-gate seeding error returns to fmt.Errorf("failed to seed feature gates: %w", err) (and keep future new error paths on fmt.Errorf/%w).
Test Coverage For New Features ⚠️ Warning Added e2e coverage exists, but the new Go helpers and non-trivial React components have no unit/component tests; only test/e2e exercises feature gates. Add Go unit tests for seedFeatureGates/injectFeatureGateHATEOASLinks and React tests for FeatureGateDetail/FeatureGates, including the empty-link/loading-state case.
✅ Passed checks (17 passed)
Check name Status Explanation
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.
Sql Injection Prevention ✅ Passed New DB paths use placeholders (Where("... ?", ...)) and quoted identifiers; no user input is concatenated into SQL.
Excessive Css In React Should Use Styles ✅ Passed FeatureGateDetail/FeatureGates only add small sx objects (2-3 props); no large or repeated inline style blocks were introduced.
Single Responsibility And Clear Naming ✅ Passed The new feature-gate code stays cohesive: seeding, API links, UI detail view, and e2e coverage are split into focused helpers/components with descriptive names.
Feature Documentation ✅ Passed PASS: No feature-gate doc exists under docs/features; the only doc there is job-analysis-symptoms, and the commit adds no docs files.
Test Structure And Quality ✅ Passed PASS — New e2e tests are API-only, use existing SippyGet helpers, have focused subtests, and contain no cluster waits or cleanup risks.
Microshift Test Compatibility ✅ Passed The added tests only query the Sippy HTTP API; I found no OpenShift API use, unsupported namespaces, or MicroShift-sensitive assumptions.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The added e2e tests only call Sippy APIs and assert JSON/link contents; they don’t inspect node counts, scheduling, or HA behavior.
Topology-Aware Scheduling Compatibility ✅ Passed No deployment manifests or controllers were changed; diffs only add feature-gate data/API/UI and generated snapshots, with no affinity, selectors, replicas, or topology rules.
Ote Binary Stdout Contract ✅ Passed No stdout writes were added in process-level code; the touched Go files lack fmt.Print/println, klog stdout setup, and TestMain/BeforeSuite hooks.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Added e2e tests only hit the local Sippy API via localhost/JoinHostPort and internal API links; no hardcoded IPv4 literals or public internet calls.
No-Weak-Crypto ✅ Passed Touched files only add feature-gate API/UI and seed data; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token comparisons were introduced.
Container-Privileges ✅ Passed No changed file adds privileged/host* settings, SYS_ADMIN, or allowPrivilegeEscalation; the YAML diffs only adjust generated config and seeding/test code.
No-Sensitive-Data-In-Logs ✅ Passed Added logs only report counts/debug UI clicks; no new logging of passwords, tokens, PII, session IDs, or hostnames appears in the changed files.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: reworking feature gate test filtering to support component-owned jobs.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 4

🧹 Nitpick comments (4)
sippy-ng/src/tests/FeatureGateDetail.js (2)

136-154: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider reusing existing filter helpers instead of hand-building the payload.

This manually builds a filter object with JSON.stringify + safeEncodeURIComponent. The repo provides filterFor/single/multiple/multiple_or for building filter payloads and pathForAPIWithFilter for appending the encoded filters= query param — reusing these would keep encoding consistent with the rest of the codebase and reduce duplicated logic.

As per path instructions, "Build filter payloads with filterFor(column, operator, value) plus single()/multiple()/multiple_or()" and "use pathForAPIWithFilter(apiPath, filter) to append the encoded filters=... query param".

🤖 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 `@sippy-ng/src/tests/FeatureGateDetail.js` around lines 136 - 154, The
FeatureGateDetail test is manually constructing and encoding a filter payload
instead of using the shared filter helpers. Update the fetch URL-building logic
to create the filter with filterFor plus single/multiple/multiple_or as
appropriate, and append it with pathForAPIWithFilter rather than JSON.stringify
and safeEncodeURIComponent. Use the existing FeatureGateDetail fetch call and
the API path construction there as the place to swap in the shared helpers so
encoding stays consistent.

Source: Path instructions


148-154: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

release isn't URL-encoded in the fetch URL.

release is concatenated directly into the query string without encodeURIComponent/safeEncodeURIComponent. Low risk given release names are typically simple version strings, but worth guarding for consistency with the rest of the file (which does encode the filter).

🤖 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 `@sippy-ng/src/tests/FeatureGateDetail.js` around lines 148 - 154, The fetch
URL construction in FeatureGateDetail’s request builder concatenates release
directly into the query string, unlike filterParam which is encoded. Update the
URL assembly in the fetch call to pass release through encodeURIComponent or
safeEncodeURIComponent before appending it, so the query string is consistently
encoded and safe.
pkg/sippyserver/server.go (1)

693-698: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Undocumented trailing ] anchor; also release is interpolated unescaped into generated URLs.

The "FeatureGate:%s]" trick is non-obvious and has no comment explaining why the bracket is there — worth a one-line comment for future maintainers. Separately, release is embedded via plain %s in tests_by_annotation, tests_by_capability, and ui_detail without url.QueryEscape/url.PathEscape (unlike fg.FeatureGate), which is inconsistent even though current risk is low since an invalid release value would simply fail to match any DB rows upstream.

As per coding guidelines, "Keep comments minimal and helpful, and make them explain the 'why' rather than the 'what'."

♻️ Suggested tweak
+	// Trailing "]" anchors the match to the annotation's closing bracket so a shorter
+	// gate name can't match as a prefix of a longer, similarly-named gate.
 	annotationFilter := url.QueryEscape(fmt.Sprintf(
 		`{"items":[{"columnField":"name","operatorValue":"contains","value":"FeatureGate:%s]"}]}`,
 		fg.FeatureGate))
 	fg.Links["tests_by_annotation"] = fmt.Sprintf(
 		"%s/api/tests?release=%s&filter=%s",
-		baseAPIURL, release, annotationFilter)
+		baseAPIURL, url.QueryEscape(release), annotationFilter)
🤖 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 `@pkg/sippyserver/server.go` around lines 693 - 698, Add a brief explanatory
comment near the FeatureGate annotation filter in server.go to document why the
trailing ] is intentionally included in the value, and make the generated URLs
consistent by escaping release before interpolating it into tests_by_annotation,
tests_by_capability, and ui_detail in the same code path that already uses
url.QueryEscape for fg.FeatureGate.

Source: Coding guidelines

test/e2e/util/e2erequest.go (1)

42-48: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Stale nolint justification for the new exported signature.

The #nosec/nolint comment on the client.Get(url) call says the URL is "constructed from test helper's hardcoded localhost base URL," but SippyGetAbsolute is now also invoked directly with server-returned HATEOAS links (see feature_gates_test.go), not just BuildE2EURL output. Low risk given this is e2e test code targeting the same server, but worth updating the comment so the suppression rationale stays accurate.

🤖 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/util/e2erequest.go` around lines 42 - 48, The suppression comment on
SippyGetAbsolute’s client.Get(url) call is outdated because this exported helper
can now receive direct HATEOAS links, not only BuildE2EURL output. Update the
nolint/gosec justification in SippyGetAbsolute to describe the broader e2e test
usage accurately, while keeping the same suppression on the http.Client request
line.
🤖 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 `@pkg/sippyserver/server.go`:
- Around line 690-710: The HATEOAS link builder in injectFeatureGateHATEOASLinks
is too narrow and can return incorrect test links. Update tests_by_annotation to
match both feature-gate tag forms, including OCPFeatureGate alongside
FeatureGate, and adjust tests_by_capability to use exact array membership
semantics (“has entry”) rather than substring-based contains so unrelated tests
are not matched by prefix collisions.

In `@sippy-ng/src/App.js`:
- Around line 262-275: The redirect logic in FeatureGateDetailWrapper is
updating the wrong path segment for the “latest” release case. When useParams()
returns release === 'latest', change the navigation in
RedirectLatestReleaseWrapper usage so it targets the full
/feature_gates/${defaultRelease}/${feature_gate} URL instead of a relative ../
redirect. Keep the existing release and feature_gate values from
FeatureGateDetailWrapper/FeatureGateDetail, but ensure the redirect writes the
release segment so the loop stops.

In `@sippy-ng/src/tests/FeatureGateDetail.js`:
- Around line 101-112: The sorting state in DataGrid is controlled but never
updated, so header clicks cannot change the order. Update the FeatureGateDetail
DataGrid setup to manage sort state with a component state value, and wire
`onSortModelChange` to persist user changes instead of always passing the fixed
`sortModel` literal. Keep the existing default sort for initial render, but make
sure `DataGrid` in `FeatureGateDetail` reflects the current sort model on
subsequent renders.
- Around line 204-213: SimpleBreadcrumbs is being passed a crumbs prop that it
ignores, so the Feature Gates back link never renders. Update the
FeatureGateDetail test/setup to use the supported previousPage prop on
SimpleBreadcrumbs instead of crumbs, keeping release and currentPage as-is so
the breadcrumb can show the Feature Gates link correctly.

---

Nitpick comments:
In `@pkg/sippyserver/server.go`:
- Around line 693-698: Add a brief explanatory comment near the FeatureGate
annotation filter in server.go to document why the trailing ] is intentionally
included in the value, and make the generated URLs consistent by escaping
release before interpolating it into tests_by_annotation, tests_by_capability,
and ui_detail in the same code path that already uses url.QueryEscape for
fg.FeatureGate.

In `@sippy-ng/src/tests/FeatureGateDetail.js`:
- Around line 136-154: The FeatureGateDetail test is manually constructing and
encoding a filter payload instead of using the shared filter helpers. Update the
fetch URL-building logic to create the filter with filterFor plus
single/multiple/multiple_or as appropriate, and append it with
pathForAPIWithFilter rather than JSON.stringify and safeEncodeURIComponent. Use
the existing FeatureGateDetail fetch call and the API path construction there as
the place to swap in the shared helpers so encoding stays consistent.
- Around line 148-154: The fetch URL construction in FeatureGateDetail’s request
builder concatenates release directly into the query string, unlike filterParam
which is encoded. Update the URL assembly in the fetch call to pass release
through encodeURIComponent or safeEncodeURIComponent before appending it, so the
query string is consistently encoded and safe.

In `@test/e2e/util/e2erequest.go`:
- Around line 42-48: The suppression comment on SippyGetAbsolute’s
client.Get(url) call is outdated because this exported helper can now receive
direct HATEOAS links, not only BuildE2EURL output. Update the nolint/gosec
justification in SippyGetAbsolute to describe the broader e2e test usage
accurately, while keeping the same suppression on the http.Client request line.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: d8d39b25-4310-40ad-8d3d-fa26362b5e58

📥 Commits

Reviewing files that changed from the base of the PR and between 8b5848b and 086d074.

📒 Files selected for processing (8)
  • cmd/sippy/seed_data.go
  • pkg/apis/api/types.go
  • pkg/sippyserver/server.go
  • sippy-ng/src/App.js
  • sippy-ng/src/tests/FeatureGateDetail.js
  • sippy-ng/src/tests/FeatureGates.js
  • test/e2e/feature_gates_test.go
  • test/e2e/util/e2erequest.go

Comment thread pkg/sippyserver/server.go
Comment on lines +690 to +710
func injectFeatureGateHATEOASLinks(fg *apitype.FeatureGate, release, baseAPIURL, baseFrontendURL string) {
fg.Links = make(map[string]string, 3)

annotationFilter := url.QueryEscape(fmt.Sprintf(
`{"items":[{"columnField":"name","operatorValue":"contains","value":"FeatureGate:%s]"}]}`,
fg.FeatureGate))
fg.Links["tests_by_annotation"] = fmt.Sprintf(
"%s/api/tests?release=%s&filter=%s",
baseAPIURL, release, annotationFilter)

capabilityFilter := url.QueryEscape(fmt.Sprintf(
`{"items":[{"columnField":"name","operatorValue":"contains","value":"openshift-tests should work"},{"columnField":"variants","operatorValue":"contains","value":"Capability:%s"}],"linkOperator":"and"}`,
fg.FeatureGate))
fg.Links["tests_by_capability"] = fmt.Sprintf(
"%s/api/tests?release=%s&filter=%s",
baseAPIURL, release, capabilityFilter)

fg.Links["ui_detail"] = fmt.Sprintf(
"%s/feature_gates/%s/%s",
baseFrontendURL, release, url.PathEscape(fg.FeatureGate))
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C5 '"variants"' --type=go pkg/filter pkg/db/query 2>/dev/null
rg -n -C5 'columnField.*variants|case "variants"' --type=go

Repository: openshift/sippy

Length of output: 153


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant file and search for feature-gate link construction and filter handling.
ast-grep outline pkg/sippyserver/server.go --view expanded || true
rg -n -C4 'injectFeatureGateHATEOASLinks|tests_by_capability|tests_by_annotation|FeatureGate:' pkg/sippyserver/server.go
rg -n -C4 'columnField.*variants|variants.*contains|case "variants"|operatorValue.*contains' pkg --type=go

Repository: openshift/sippy

Length of output: 18733


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect any filter/query code that may define "contains" semantics.
rg -n -C4 'contains' pkg --type=go
rg -n -C4 '"variants"' pkg --type=go
rg -n -C4 'FeatureGate|feature gate|feature_gate' pkg --type=go

Repository: openshift/sippy

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the filter implementation to determine how "contains" behaves for array fields.
ast-grep outline pkg/filter --view expanded || true
rg -n -C4 'func .*contains|Operator: "contains"|strings.Contains|Contains' pkg/filter --type=go
sed -n '1,260p' pkg/filter/filterable.go

Repository: openshift/sippy

Length of output: 20233


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect how feature-gate annotations are represented and whether the trailing bracket is intentional.
rg -n -C3 'FeatureGate:' pkg --type=go
rg -n -C3 'FeatureGate.*\]' pkg --type=go
rg -n -C3 'annotations|annotation' pkg/apis pkg/filter pkg/sippyserver --type=go | head -n 200

Repository: openshift/sippy

Length of output: 12971


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the feature-gate response type to see how links and gate names are represented.
sed -n '1040,1105p' pkg/apis/api/types.go

Repository: openshift/sippy

Length of output: 1594


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Look for existing feature-gate names that might already share prefixes.
rg -n 'FeatureGate:' pkg --type=go

Repository: openshift/sippy

Length of output: 562


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check the in-memory array filter semantics for the exact operator we should use here.
sed -n '640,660p' pkg/filter/filterable.go

Repository: openshift/sippy

Length of output: 587


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the FeatureGate API type to see how its name/value fields are used.
sed -n '1070,1100p' pkg/apis/api/types.go

Repository: openshift/sippy

Length of output: 713


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for OCPFeatureGate usage to understand whether it should be included in the link filter.
rg -n 'OCPFeatureGate' .

Repository: openshift/sippy

Length of output: 983


Include both feature-gate tag forms

  • tests_by_annotation only matches FeatureGate:%s], but the data also carries OCPFeatureGate:%s] tags, so this link can miss valid tests.
  • tests_by_capability should use exact array membership (has entry) instead of contains; array filtering here is substring-based, so prefix collisions can pull in unrelated tests.
🤖 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 `@pkg/sippyserver/server.go` around lines 690 - 710, The HATEOAS link builder
in injectFeatureGateHATEOASLinks is too narrow and can return incorrect test
links. Update tests_by_annotation to match both feature-gate tag forms,
including OCPFeatureGate alongside FeatureGate, and adjust tests_by_capability
to use exact array membership semantics (“has entry”) rather than
substring-based contains so unrelated tests are not matched by prefix
collisions.

Comment thread sippy-ng/src/App.js
Comment on lines +101 to +112
<DataGrid
loading={!isLoaded}
rows={rows}
columns={columns}
getRowId={(row) => row.name}
getRowHeight={() => 'auto'}
autoHeight={true}
rowsPerPageOptions={[10, 25, 50]}
pageSize={25}
sortModel={[{ field: 'current_pass_percentage', sort: 'asc' }]}
disableSelectionOnClick
/>

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Sorting is non-functional: sortModel is set but never updated.

DataGrid is given a fixed sortModel without onSortModelChange. Since sortModel makes the grid a controlled component for sorting, clicking column headers won't actually reorder rows — the prop will be reset back to the fixed value each render.

🔧 Proposed fix
+  const [sortModel, setSortModel] = React.useState([
+    { field: 'current_pass_percentage', sort: 'asc' },
+  ])
...
       <DataGrid
         loading={!isLoaded}
         rows={rows}
         columns={columns}
         getRowId={(row) => row.name}
         getRowHeight={() => 'auto'}
         autoHeight={true}
         rowsPerPageOptions={[10, 25, 50]}
         pageSize={25}
-        sortModel={[{ field: 'current_pass_percentage', sort: 'asc' }]}
+        sortModel={sortModel}
+        onSortModelChange={setSortModel}
         disableSelectionOnClick
       />
📝 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
<DataGrid
loading={!isLoaded}
rows={rows}
columns={columns}
getRowId={(row) => row.name}
getRowHeight={() => 'auto'}
autoHeight={true}
rowsPerPageOptions={[10, 25, 50]}
pageSize={25}
sortModel={[{ field: 'current_pass_percentage', sort: 'asc' }]}
disableSelectionOnClick
/>
const [sortModel, setSortModel] = React.useState([
{ field: 'current_pass_percentage', sort: 'asc' },
])
<DataGrid
loading={!isLoaded}
rows={rows}
columns={columns}
getRowId={(row) => row.name}
getRowHeight={() => 'auto'}
autoHeight={true}
rowsPerPageOptions={[10, 25, 50]}
pageSize={25}
sortModel={sortModel}
onSortModelChange={setSortModel}
disableSelectionOnClick
/>
🤖 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 `@sippy-ng/src/tests/FeatureGateDetail.js` around lines 101 - 112, The sorting
state in DataGrid is controlled but never updated, so header clicks cannot
change the order. Update the FeatureGateDetail DataGrid setup to manage sort
state with a component state value, and wire `onSortModelChange` to persist user
changes instead of always passing the fixed `sortModel` literal. Keep the
existing default sort for initial render, but make sure `DataGrid` in
`FeatureGateDetail` reflects the current sort model on subsequent renders.

Comment on lines +204 to +213
<SimpleBreadcrumbs
release={release}
currentPage={featureGate}
crumbs={[
{
text: 'Feature Gates',
link: `/feature_gates/${release}`,
},
]}
/>

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the referenced test file and breadcrumb component
git ls-files | rg 'sippy-ng/src/tests/FeatureGateDetail\.js|SimpleBreadcrumbs|Breadcrumbs' -n

# Show the relevant component definition and the usage site with line numbers
for f in $(git ls-files | rg 'SimpleBreadcrumbs|Breadcrumbs' | head -n 20); do
  echo "### $f"
  wc -l "$f"
done

echo
echo "### Usage site"
sed -n '180,240p' sippy-ng/src/tests/FeatureGateDetail.js

echo
echo "### Search for SimpleBreadcrumbs definitions/usages"
rg -n "function SimpleBreadcrumbs|const SimpleBreadcrumbs|class SimpleBreadcrumbs|<SimpleBreadcrumbs|previousPage=|crumbs=" sippy-ng/src -g '!**/node_modules/**'

Repository: openshift/sippy

Length of output: 4379


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' sippy-ng/src/components/SimpleBreadcrumbs.js

echo
echo "### Nearby examples that use the supported prop shape"
sed -n '380,420p' sippy-ng/src/jobs/JobAnalysis.js
echo
sed -n '160,190p' sippy-ng/src/tests/TestAnalysis.js

Repository: openshift/sippy

Length of output: 2619


Use previousPage for the Feature Gates breadcrumb link SimpleBreadcrumbs only renders release, previousPage, and currentPage, so crumbs is ignored and the back link never appears.

🤖 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 `@sippy-ng/src/tests/FeatureGateDetail.js` around lines 204 - 213,
SimpleBreadcrumbs is being passed a crumbs prop that it ignores, so the Feature
Gates back link never renders. Update the FeatureGateDetail test/setup to use
the supported previousPage prop on SimpleBreadcrumbs instead of crumbs, keeping
release and currentPage as-is so the breadcrumb can show the Feature Gates link
correctly.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

- Centralizes the logic for how to find test results for a featuregate
  for re-use in the openshift/api verification job.
- Feature Gate API now returns hateoas links clients can follow.
- Includes a link to the tests tagged for the feature gate name.
- Includes a link to the synthetic "openshift-tests should work" as an
  indicator the job fully passed, for any jobs tied to a Capability.
- Replaces the hack for featuregates containing Install to automatically
  route to all install results and exclude actual tests for the FG.
- Adds feature gate seed data and e2e tests.
@dgoodwin dgoodwin changed the title WIP: Rework feature gate test filtering to cover component owned jobs TRT-2769: WIP: Rework feature gate test filtering to cover component owned jobs Jul 13, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 13, 2026

Copy link
Copy Markdown

@dgoodwin: This pull request references TRT-2769 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 bug to target the "5.0.0" version, but no target version was set.

Details

In response to this:

  • Centralizes the logic for how to find test results for a featuregate
    for re-use in the openshift/api verification job.
  • Feature Gate API now returns hateoas links clients can follow.
  • Includes a link to the tests tagged for the feature gate name.
  • Includes a link to the synthetic "openshift-tests should work" as an
    indicator the job fully passed, for any jobs tied to a Capability.
  • Replaces the hack for featuregates containing Install to automatically
    route to all install results and exclude actual tests for the FG.
  • Adds feature gate seed data and e2e tests.

Summary by CodeRabbit

  • New Features

  • Added a dedicated Feature Gates detail view with tabs for tests by annotation and capability.

  • Feature Gate results now include helpful navigation links to related tests and the detail page.

  • Feature gate seeding now covers additional feature-gated scenarios and releases.

  • Bug Fixes

  • Improved navigation from the Feature Gates list so rows open the correct detail page.

  • Feature gate data is now populated consistently even when seed data already exists.

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/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 13, 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 Jul 13, 2026

@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

🤖 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 `@sippy-ng/src/tests/FeatureGateDetail.js`:
- Around line 20-45: Update the TestResultsSection useEffect to call
setLoaded(true) and clear or reset the rows when apiUrl is falsy before
returning, so tabs without a specific test link finish loading and display the
empty state instead of remaining on the spinner.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: abb599d9-a446-4314-a94a-70d9bc66ca73

📥 Commits

Reviewing files that changed from the base of the PR and between 086d074 and 246b4da.

📒 Files selected for processing (8)
  • cmd/sippy/seed_data.go
  • pkg/apis/api/types.go
  • pkg/sippyserver/server.go
  • sippy-ng/src/App.js
  • sippy-ng/src/tests/FeatureGateDetail.js
  • sippy-ng/src/tests/FeatureGates.js
  • test/e2e/feature_gates_test.go
  • test/e2e/util/e2erequest.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • pkg/apis/api/types.go
  • sippy-ng/src/tests/FeatureGates.js
  • pkg/sippyserver/server.go
  • test/e2e/util/e2erequest.go
  • test/e2e/feature_gates_test.go
  • cmd/sippy/seed_data.go
  • sippy-ng/src/App.js

Comment on lines +20 to +45
function TestResultsSection({ title, apiUrl, release }) {
const [rows, setRows] = React.useState([])
const [isLoaded, setLoaded] = React.useState(false)
const [fetchError, setFetchError] = React.useState('')

useEffect(() => {
if (!apiUrl) return
setLoaded(false)
setFetchError('')

fetch(apiUrl)
.then((response) => {
if (response.status !== 200) {
throw new Error('server returned ' + response.status)
}
return response.json()
})
.then((json) => {
setRows(json || [])
setLoaded(true)
})
.catch((error) => {
setFetchError('Could not retrieve ' + title + ': ' + error)
setLoaded(true)
})
}, [apiUrl, title])

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Loading state never resolves when apiUrl is empty.

If gate.links exists but the specific link (tests_by_annotation/tests_by_capability) is missing, apiUrl is falsy and the effect returns at line 26 without ever calling setLoaded(true). Since isLoaded starts false, the tab is stuck showing the loading spinner and "... tests" forever, with no indication that there's simply no data for that tab.

🐛 Proposed fix
   useEffect(() => {
-    if (!apiUrl) return
+    if (!apiUrl) {
+      setRows([])
+      setLoaded(true)
+      return
+    }
     setLoaded(false)
     setFetchError('')
📝 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
function TestResultsSection({ title, apiUrl, release }) {
const [rows, setRows] = React.useState([])
const [isLoaded, setLoaded] = React.useState(false)
const [fetchError, setFetchError] = React.useState('')
useEffect(() => {
if (!apiUrl) return
setLoaded(false)
setFetchError('')
fetch(apiUrl)
.then((response) => {
if (response.status !== 200) {
throw new Error('server returned ' + response.status)
}
return response.json()
})
.then((json) => {
setRows(json || [])
setLoaded(true)
})
.catch((error) => {
setFetchError('Could not retrieve ' + title + ': ' + error)
setLoaded(true)
})
}, [apiUrl, title])
function TestResultsSection({ title, apiUrl, release }) {
const [rows, setRows] = React.useState([])
const [isLoaded, setLoaded] = React.useState(false)
const [fetchError, setFetchError] = React.useState('')
useEffect(() => {
if (!apiUrl) {
setRows([])
setLoaded(true)
return
}
setLoaded(false)
setFetchError('')
fetch(apiUrl)
.then((response) => {
if (response.status !== 200) {
throw new Error('server returned ' + response.status)
}
return response.json()
})
.then((json) => {
setRows(json || [])
setLoaded(true)
})
.catch((error) => {
setFetchError('Could not retrieve ' + title + ': ' + error)
setLoaded(true)
})
}, [apiUrl, title])
🤖 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 `@sippy-ng/src/tests/FeatureGateDetail.js` around lines 20 - 45, Update the
TestResultsSection useEffect to call setLoaded(true) and clear or reset the rows
when apiUrl is falsy before returning, so tabs without a specific test link
finish loading and display the empty state instead of remaining on the spinner.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@dgoodwin: all tests passed!

Full PR test history. Your PR dashboard.

Details

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

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

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. 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.

2 participants