Skip to content

Add lifecycle filter to the Tests page - #3870

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
mstaeble:tests-lifecycle-filter
Aug 4, 2026
Merged

Add lifecycle filter to the Tests page#3870
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
mstaeble:tests-lifecycle-filter

Conversation

@mstaeble

@mstaeble mstaeble commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Expose lifecycle (blocking/informing) as a filter-only column on the Tests page, both collapsed and per-variant views.
  • lifecycleWhereClause applies equals/not-equals before aggregation, honoring LinkOperator so OR-linked filters return a union instead of an unsatisfiable AND.
  • BigQuery-backed /api/tests/v2 returns HTTP 400 for lifecycle filters (tables lack the column).
  • Frontend: GridToolbarFilterItem gains generic values-restricted dropdown support (fixed choices, equals/!= only).
  • Integration tests: new tests_report_test.go with end-to-end coverage for both query paths; shared fixtures extracted to util/fixtures.go.

Staging verification

Tested against sippy-staging (build sippy-staging-148, release 4.22).
Release 4.22 has both lifecycle values: 177M blocking rows, 1M informing rows.

Collapsed path (/api/tests?collapse=true)

Filter Result
No filter 18,289 tests
lifecycle = blocking 18,186
lifecycle = informing 106
lifecycle != blocking 106 (matches informing)
lifecycle != informing 18,186 (matches blocking)
lifecycle = blocking OR lifecycle = informing 18,289 (matches no-filter total)
Combined: lifecycle = informing AND name contains 'network' 52
Unsupported operator (contains) HTTP 400

Uncollapsed path (/api/tests?collapse=false)

Scoped to name contains 'NetworkSegmentation' to keep result sets manageable.

Filter Result
No filter 12,632 rows
lifecycle = blocking 6,640
lifecycle = informing 5,994
lifecycle != blocking 5,994 (matches informing)
lifecycle != informing 6,640 (matches blocking)

BigQuery path (/api/tests/v2)

Filter Result
lifecycle = blocking HTTP 400 (expected)

Observations

  • Equals/not-equals pairs are symmetric across both paths.
  • OR-linked filter (blocking OR informing) returns the same count as unfiltered, confirming the LinkOperator fix works correctly.
  • Combined lifecycle + name filters narrow results as expected.
  • Unsupported operators return HTTP 400 (not silently ignored).

Test plan

  • make lint clean
  • make test passes (unit + Vitest)
  • make integration passes (204/204)
  • Staging verification: collapsed path (8 scenarios)
  • Staging verification: uncollapsed path (5 scenarios)
  • Staging verification: BigQuery rejection
  • Manual UI verification of filter dropdown behavior

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added Lifecycle filtering to Tests reports, supporting “blocking” and “informing” values.
    • Added a Lifecycle filter dropdown with supported equality and inequality options.
    • Lifecycle filters now apply consistently to collapsed, uncollapsed, and statistical report results.
  • Bug Fixes

    • Invalid filter operators now return a clear HTTP 400 error.
    • The BigQuery-backed Tests endpoint now clearly rejects unsupported Lifecycle filters.

@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 added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 4, 2026
@openshift-ci

openshift-ci Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@mstaeble, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 6bb19d1f-f9bd-4c6f-9813-dde363ccf4da

📥 Commits

Reviewing files that changed from the base of the PR and between aa01fb0 and 70e4e06.

📒 Files selected for processing (14)
  • pkg/api/README.md
  • pkg/api/api.go
  • pkg/api/tests.go
  • pkg/api/tests_test.go
  • pkg/db/query/cumulative_query.go
  • pkg/db/query/cumulative_query_test.go
  • pkg/db/query/test_queries.go
  • pkg/filter/filterable.go
  • sippy-ng/src/datagrid/GridToolbarFilterItem.jsx
  • sippy-ng/src/datagrid/GridToolbarFilterItem.test.jsx
  • sippy-ng/src/tests/TestTable.jsx
  • test/integration/component_readiness_test.go
  • test/integration/tests_report_test.go
  • test/integration/util/fixtures.go

Walkthrough

Changes

Lifecycle filtering

Layer / File(s) Summary
Lifecycle filter contract and UI
pkg/filter/filterable.go, sippy-ng/src/datagrid/GridToolbarFilterItem.jsx, sippy-ng/src/datagrid/GridToolbarFilterItem.test.jsx, sippy-ng/src/tests/TestTable.jsx
Adds fixed lifecycle values and restricts operators to equals and !=.
API filter routing and validation
pkg/api/api.go, pkg/api/tests.go, pkg/api/tests_test.go, pkg/api/README.md
Routes lifecycle filters to Postgres reports and rejects them for BigQuery reports with typed validation errors.
Postgres lifecycle query conditions
pkg/db/query/cumulative_query.go, pkg/db/query/test_queries.go, pkg/db/query/cumulative_query_test.go
Builds lifecycle SQL predicates and applies them to collapsed reports, uncollapsed reports, and statistics.
Report fixtures and integration validation
test/integration/util/fixtures.go, test/integration/component_readiness_test.go, test/integration/tests_report_test.go
Adds shared report fixtures and integration coverage for lifecycle filtering, aggregation, statistics, metadata, and existing filter behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TestTable
  participant TestsAPI
  participant PostgresQueries
  participant BigQueryGenerator
  TestTable->>TestsAPI: Submit lifecycle filter
  TestsAPI->>PostgresQueries: Apply lifecycle predicate
  PostgresQueries-->>TestsAPI: Return filtered report
  TestsAPI->>BigQueryGenerator: Receive lifecycle filter
  BigQueryGenerator-->>TestsAPI: Return HTTP 400 validation error
Loading

Possibly related PRs

Suggested reviewers: smg247

🚥 Pre-merge checks | ✅ 19 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Coverage For New Features ⚠️ Warning Most lifecycle query and UI paths have tests, but the new IsBadRequestError ErrUnsupportedOperator branch has no test; existing classifier cases omit this sentinel. Add a TestIsBadRequestError case for direct and wrapped ErrUnsupportedOperator, or an API test that verifies unsupported lifecycle operators produce HTTP 400.
✅ Passed checks (19 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main feature added across the changeset: lifecycle filtering capability on the Tests page.
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.
Go Error Handling ✅ Passed All Go error handling patterns comply with best practices: errors are wrapped with fmt.Errorf and %w, nil pointers checked before dereferencing, no panic calls, and no new ignored errors introduced.
Sql Injection Prevention ✅ Passed lifecycleWhereClause uses parameterized SQL with ? placeholders and appends filter values to a separate args array rather than concatenating them into SQL strings. User input columnRef is hardcoded...
Excessive Css In React Should Use Styles ✅ Passed The PR adds no inline CSS. GridToolbarFilterItem uses existing useStyles; existing inline styles have one property and were not changed.
Single Responsibility And Clear Naming ✅ Passed New functions follow focused single-responsibility patterns. Function names (lifecycleWhereClause, TestReportQueryCollapsed, CreateCumulativeSummary) clearly communicate their purpose. No generic n...
Feature Documentation ✅ Passed API documentation in pkg/api/README.md was updated with lifecycle filter details (operators, values, aggregation behavior, endpoint restrictions). Feature documentation not required per check instr...
Stable And Deterministic Test Names ✅ Passed Repository uses standard Go tests, not Ginkgo. All test function names (25 new tests) are static descriptive strings with no dynamic content. Table-driven test cases use static string literals.
Test Structure And Quality ✅ Passed This pull request uses standard Go testing with testing.T, not Ginkgo BDD tests. The custom check is designed for Ginkgo tests only and does not apply here.
Microshift Test Compatibility ✅ Passed The PR adds standard Go tests using testing.T and database fixtures, not Ginkgo e2e tests; no MicroShift-sensitive OpenShift APIs or assumptions are introduced.
Single Node Openshift (Sno) Test Compatibility ✅ Passed This PR adds integration tests to Sippy, a backend service for analyzing test results. Tests use standard Go testing package (testing.T), not Ginkgo. No Ginkgo e2e tests are added, so the SNO compa...
Topology-Aware Scheduling Compatibility ✅ Passed This PR modifies Sippy, a test result analysis tool. It adds a lifecycle filter feature to the Go backend and React frontend, with integration tests. No deployment manifests, operator code, control...
Ote Binary Stdout Contract ✅ Passed PR contains no process-level stdout writes. All changed Go files are application logic with no fmt.Print/log.Print/klog writes at main/init/suite level; JavaScript changes do not execute in OTE bin...
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The patch adds Go Test functions and React Vitest tests, not Ginkgo e2e tests; changed test code has no IPv4 assumptions or external/public network access.
No-Weak-Crypto ✅ Passed The PR adds filtering, UI, and test fixtures only; the diff contains no weak crypto APIs, custom cryptography, or secret/token comparisons.
Container-Privileges ✅ Passed The PR changes no container or Kubernetes manifests, and its diff contains no privileged, host namespace, SYS_ADMIN, root-user, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed No logging statements that expose passwords, tokens, API keys, PII, session IDs, internal hostnames, or customer data were added in this PR. Error messages and filter handling properly separate met...
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 4, 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

🧹 Nitpick comments (1)
test/integration/tests_report_test.go (1)

56-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid appending twice to testMetadataColumns.

Lines 57 and 59 both append to testMetadataColumns. This is safe only because the slice literal has cap == len, so each append allocates a new backing array. If testMetadataColumns is later built with spare capacity, the second append overwrites the element that collapsedColumns holds, and the collapsed query silently selects the wrong column.

Build each slice independently.

♻️ Proposed change
 	testMetadataColumns := []string{"suite_name", "name", "jira_component", "jira_component_id"}
-	collapsedColumns := append(testMetadataColumns, query.QueryTestFields)
+	collapsedColumns := slices.Concat(testMetadataColumns, []string{query.QueryTestFields})
 	rawQuery := dbc.DB.Table("(?) AS r", collapsedQuery).Select(strings.Join(collapsedColumns, ","))
-	selectColumns := append(testMetadataColumns, query.QueryTestSummarizer)
+	selectColumns := slices.Concat(testMetadataColumns, []string{query.QueryTestSummarizer})

Add the slices import.

🤖 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/integration/tests_report_test.go` around lines 56 - 61, Build
collapsedColumns and selectColumns independently from testMetadataColumns in the
test query setup, using the slices package as suggested to avoid shared
backing-array mutations when appending query.QueryTestFields and
query.QueryTestSummarizer.
🤖 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/api/README.md`:
- Around line 469-475: The `/api/tests` response documentation still describes a
bare array; update the endpoint response contract to return an object containing
the test results and a `links` object with at least the filtered `self` URL.
Adjust the frontend client and API tests consuming `/api/tests` to use the new
representation, and update the README example/schema accordingly while
preserving lifecycle filtering behavior.

---

Nitpick comments:
In `@test/integration/tests_report_test.go`:
- Around line 56-61: Build collapsedColumns and selectColumns independently from
testMetadataColumns in the test query setup, using the slices package as
suggested to avoid shared backing-array mutations when appending
query.QueryTestFields and query.QueryTestSummarizer.
🪄 Autofix

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: aa46c563-6f5e-49e9-87b3-b5f18de052bf

📥 Commits

Reviewing files that changed from the base of the PR and between d965487 and aa01fb0.

📒 Files selected for processing (14)
  • pkg/api/README.md
  • pkg/api/api.go
  • pkg/api/tests.go
  • pkg/api/tests_test.go
  • pkg/db/query/cumulative_query.go
  • pkg/db/query/cumulative_query_test.go
  • pkg/db/query/test_queries.go
  • pkg/filter/filterable.go
  • sippy-ng/src/datagrid/GridToolbarFilterItem.jsx
  • sippy-ng/src/datagrid/GridToolbarFilterItem.test.jsx
  • sippy-ng/src/tests/TestTable.jsx
  • test/integration/component_readiness_test.go
  • test/integration/tests_report_test.go
  • test/integration/util/fixtures.go

Comment thread pkg/api/README.md
Builds on the lifecycle-as-a-dimension work in test_cumulative_summaries
to expose lifecycle (blocking/informing) as a filter on the Tests page,
both collapsed and per-variant views.

Changes:
- pkg/db/query: lifecycleWhereClause applies equals/not-equals before
  aggregation in TestReportQueryCollapsed and UncollapsedTestReportWithStats
  (re-applied inside the stats CTE too, so cross-variant averages don't
  blend in excluded-lifecycle data). Honors the filter's LinkOperator so
  an OR-linked filter selecting both lifecycles returns their union
  instead of an unsatisfiable AND.
- pkg/filter: new ErrUnsupportedOperator sentinel so unsupported
  operators surface as a 400 instead of being silently ignored; lives
  in pkg/filter (not pkg/api) to avoid an import cycle with pkg/db/query
- pkg/api: split lifecycle out of the Postgres filter pipeline;
  BigQuery-backed /api/tests/v2 returns 400 for a lifecycle filter,
  since the underlying junit_7day_comparison/junit_2day_comparison
  tables have no lifecycle column
- sippy-ng: GridToolbarFilterItem gains generic "values"-restricted
  dropdown support (fixed choices, equals/!= only) used by the new
  Lifecycle column in TestTable.jsx
- test/integration: new tests_report_test.go covering both query paths
  end-to-end (period math, name/variant/lifecycle filters including the
  OR-linked case, cross-variant stats, never-stable handling, open bugs,
  jira component resolution); reusable fixtures added to util/fixtures.go,
  and component_readiness_test.go's near-duplicate private helpers now
  delegate to those shared fixtures instead of re-implementing them

make integration: 204/204 pass. make lint: clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mstaeble
mstaeble force-pushed the tests-lifecycle-filter branch from aa01fb0 to 70e4e06 Compare August 4, 2026 14:19
@mstaeble
mstaeble marked this pull request as ready for review August 4, 2026 14:20
@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 Aug 4, 2026
@openshift-ci openshift-ci Bot added the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label Aug 4, 2026
@openshift-ci
openshift-ci Bot requested review from dgoodwin and stbenjam August 4, 2026 14:22
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

@openshift-ci

openshift-ci Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

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

@dgoodwin

dgoodwin commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Can we get a display marker that indicates the test is informing (or contains some informing results collapsed into the one row). This will be helpful in a number of views. A column with an icon if informing would be nice but may be too much of a waste of space. Collapsing into the test name perhaps with an icon at the start?

@neisw

neisw commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

/lgtm
@mstaeble plans a followup pr for pending ui work

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 4, 2026
@openshift-ci

openshift-ci Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mstaeble, neisw

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

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot
openshift-merge-bot Bot merged commit 5f29773 into openshift:main Aug 4, 2026
10 checks passed
@mstaeble
mstaeble deleted the tests-lifecycle-filter branch August 4, 2026 18:44
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. lgtm Indicates that a PR is ready to be merged. ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants