Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
038428f
Initial port of api promotion requirements to sippy api
dgoodwin Jul 20, 2026
8a0fcae
Fix column widths
dgoodwin Jul 20, 2026
f136dae
Fix text colors
dgoodwin Jul 20, 2026
426bb8b
Explain errors better
dgoodwin Jul 20, 2026
4f2a382
Only show errors if relevant
dgoodwin Jul 20, 2026
89109e6
Replace broken ported assumptions about install gates
dgoodwin Jul 20, 2026
98361f2
Improve cell rendering when pass rate is good but low runs
dgoodwin Jul 21, 2026
facca43
Remove yellow cells, confusing as warnings which they are not
dgoodwin Jul 21, 2026
2a66e68
Sort warning/error lines
dgoodwin Jul 21, 2026
0e4e73b
Better representation of variants in response
dgoodwin Jul 21, 2026
92f0090
Begin working towards all tests passing 92% in jobs
dgoodwin Jul 24, 2026
879e93b
Add a new tab for the owned job tests below 92%
dgoodwin Jul 24, 2026
1875907
Fix the three fg tests pages to load properly
dgoodwin Jul 28, 2026
500d0f6
Add a feature_gate details api instead of overloading the list api
dgoodwin Jul 28, 2026
09138b6
Add matching_jobs to feature gate detail API and UI
dgoodwin Jul 28, 2026
0a97099
Merge the fg promotion api into fg details
dgoodwin Jul 29, 2026
5d3bd6a
Improve design to base analysis on hateoas links as authoritative
dgoodwin Jul 30, 2026
698fb5c
Fix non-existant rhel10 OS variant (rhcos10)
dgoodwin Jul 30, 2026
8c61591
Drop separate rhcos10 requirement, it's the default now
dgoodwin Jul 30, 2026
17fe23e
Improve tab names
dgoodwin Jul 30, 2026
61733ab
Document tabs better
dgoodwin Jul 30, 2026
fa26865
Link to job analysis for all owned jobs
dgoodwin Jul 30, 2026
ed25d83
Analyze all button
dgoodwin Jul 30, 2026
4a93390
Fix cell links to direct to test details for that specific test/varia…
dgoodwin Jul 30, 2026
46f1806
Do not report renamed tests as 0% 0 runs in this context
dgoodwin Jul 30, 2026
95919d9
Merge remote-tracking branch 'up/main' into merge-fg-api-review-logic
dgoodwin Aug 4, 2026
3bc741a
FeatureGatePromotionTab should be .jsx now
dgoodwin Aug 4, 2026
b49e5a7
Consider pass rate of all tests in owned jobs below 92% for promotion
dgoodwin Aug 4, 2026
a80de4a
Address perf issue with promotion api using a custom query
dgoodwin Aug 4, 2026
4615536
Display the owned job test regressions on promotion readiness page
dgoodwin Aug 4, 2026
c2f1bdf
Separate tables for each class of promotion analysis
dgoodwin Aug 4, 2026
daa9601
Expand e2e cov for feature gate promotion testing
dgoodwin Aug 4, 2026
36b72ee
Fix confusing seed data
dgoodwin Aug 4, 2026
245c542
Add unit test for platform specific assumptions during promotion
dgoodwin Aug 4, 2026
6f653b8
Fix lint issues and ensure API returns empty arrays for variant test …
dgoodwin Aug 4, 2026
cd59e42
Set Optional: true on OptionalSelfManagedPlatformVariants entries
dgoodwin Aug 4, 2026
8ab3d46
Exclude aggregated jobs from capability regression query
dgoodwin Aug 4, 2026
be8e455
Use OperatorHasEntry for capability variant in InstallTestFilter
dgoodwin Aug 4, 2026
dc09d39
Guard minPassRate computation against zero-run test results
dgoodwin Aug 4, 2026
e5d63b9
Add require.NotEmpty before variant result loop in e2e test
dgoodwin Aug 4, 2026
beeefc5
Merge remote-tracking branch 'up/main' into merge-fg-api-review-logic
dgoodwin Aug 6, 2026
0ff0c81
Filter out informing tests
dgoodwin Aug 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion cmd/sippy/seed_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ const awsAmd64Parallel = "periodic-ci-openshift-release-master-ci-%s-e2e-aws-ovn
const awsArm64Parallel = "periodic-ci-openshift-release-master-ci-%s-e2e-aws-ovn-arm64"
const gcpAmd64Parallel = "periodic-ci-openshift-release-master-ci-%s-e2e-gcp-ovn-amd64"
const awsAmd64CapabilityAWSDualStackInstall = "periodic-ci-openshift-release-master-ci-%s-e2e-aws-ovn-amd64-capability-awsdualstackinstall"
const awsAmd64CapabilityNetworkSegmentation = "periodic-ci-openshift-release-master-ci-%s-e2e-aws-ovn-amd64-capability-networksegmentation"
const azureAmd64Parallel = "periodic-ci-openshift-release-master-ci-%s-e2e-azure-ovn-amd64"

// allJobTemplates returns name templates from syntheticJobs for use in test specs
Expand Down Expand Up @@ -383,7 +384,7 @@ var syntheticTests = []syntheticTestSpec{
},
},
{
testID: "test-fg-aws-dual-stack-install", testName: "[sig-installer] [FeatureGate:AWSDualStackInstall] dual stack install should succeed",
testID: "test-fg-aws-dual-stack-install", testName: "[sig-installer] [FeatureGate:AWSDualStackInstall] specific test for the dual stack install feature",
component: "Installer / openshift-installer", capabilities: []string{"AWSDualStackInstall"},
jobCounts: map[string]map[string]testCount{
awsAmd64Parallel: {"4.22": {50, 48, 0}},
Expand All @@ -406,6 +407,29 @@ var syntheticTests = []syntheticTestSpec{
},
},

// --- Capability regression tests: tests on capability jobs with low pass rates ---
{
testID: "test-cap-regression-netseg", testName: "[sig-network] network connectivity should be reliable across nodes",
component: "Networking / ovn-kubernetes", capabilities: []string{"networking"},
jobCounts: map[string]map[string]testCount{
awsAmd64CapabilityNetworkSegmentation: {"4.22": {100, 85, 0}},
},
},
{
testID: "test-cap-regression-unpromoted-gate", testName: "[sig-network] [OCPFeatureGate:UnpromotedTestGate] should handle traffic correctly",
component: "Networking / ovn-kubernetes", capabilities: []string{"networking"},
jobCounts: map[string]map[string]testCount{
awsAmd64CapabilityNetworkSegmentation: {"4.22": {100, 80, 0}},
},
},
{
testID: "test-cap-regression-awsdualstack", testName: "[sig-network] dual stack services should route correctly",
component: "Networking / ovn-kubernetes", capabilities: []string{"networking"},
jobCounts: map[string]map[string]testCount{
awsAmd64CapabilityAWSDualStackInstall: {"4.22": {100, 88, 0}},
},
},

// --- Install / health indicator tests: run on every job, every release ---
{
testID: "test-install-overall", testName: "install should succeed: overall",
Expand Down Expand Up @@ -1319,6 +1343,8 @@ func seedFeatureGates(dbc *db.DB) error {
featureGates := []models.FeatureGate{
{Release: "4.22", Topology: "SelfManagedHA", FeatureSet: "TechPreviewNoUpgrade", FeatureGate: "NetworkSegmentation", Status: "enabled"},
{Release: "4.22", Topology: "SelfManagedHA", FeatureSet: "TechPreviewNoUpgrade", FeatureGate: "AWSDualStackInstall", Status: "enabled"},
{Release: "4.22", Topology: "SelfManagedHA", FeatureSet: "TechPreviewNoUpgrade", FeatureGate: "UnpromotedTestGate", Status: "enabled"},
{Release: "4.22", Topology: "SelfManagedHA", FeatureSet: "Default", FeatureGate: "PromotedTestGate", Status: "enabled"},
}

for _, fg := range featureGates {
Expand Down
34 changes: 34 additions & 0 deletions pkg/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -580,3 +580,37 @@ tables don't carry a lifecycle column.
```

</details>

## Feature Gates

### List Feature Gates

Endpoint: `/api/feature_gates`

Returns all feature gates and their test counts for a release. Each gate includes
lightweight HATEOAS links (`ui_detail` and `api_detail`) for navigation.

| Option | Type | Description |
|----------|--------|----------------------------------------------------------|
| release* | String | The OpenShift release to return results from (e.g., 5.0) |
| filter | Filter | Filters the results. See filtering above. |

### Feature Gate Detail

Endpoint: `/api/feature_gates/{feature_gate}`

Returns a single feature gate with full HATEOAS links for test queries
(`gate_tests`, `install_tests`, `gate_job_tests`, `ui_detail`).
The `install_tests` link is only present for gates whose name contains "Install".

The response includes a `promotion` object with promotion readiness data:
per-variant test pass rates, overall sufficiency, warnings, and errors.
The promotion evaluation is computed from the same data that the `gate_tests`
and `install_tests` HATEOAS links point to. Both the links and the promotion
logic use canonical filter definitions from
`pkg/api/featuregatepromotion/filters.go`, ensuring they always stay in sync.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

| Option | Type | Description |
|---------------|--------|----------------------------------------------------------|
| release* | String | The OpenShift release to return results from (e.g., 5.0) |
| feature_gate | Path | The feature gate name (in the URL path) |
56 changes: 56 additions & 0 deletions pkg/api/featuregatepromotion/filters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package featuregatepromotion

import (
"fmt"

"github.com/openshift/sippy/pkg/filter"
)

// GateTestFilter returns the canonical filter for annotation-based tests
// belonging to a feature gate. This is the authoritative definition used both
// to generate HATEOAS links and to query data for promotion evaluation.
func GateTestFilter(featureGate string) filter.Filter {
return filter.Filter{
Items: []filter.FilterItem{
{Field: "name", Operator: filter.OperatorContains, Value: fmt.Sprintf("FeatureGate:%s]", featureGate)},
{Field: "variants", Not: true, Operator: filter.OperatorHasEntry, Value: "never-stable"},
{Field: "variants", Not: true, Operator: filter.OperatorHasEntry, Value: "aggregated"},
},
LinkOperator: filter.LinkOperatorAnd,
}
}

// InstallTestFilter returns the canonical filter for install capability tests
// belonging to an Install feature gate. Only applicable when the feature gate
// name contains "Install". This is the authoritative definition used both
// to generate HATEOAS links and to query data for promotion evaluation.
func InstallTestFilter(featureGate string) filter.Filter {
return filter.Filter{
Items: []filter.FilterItem{
{Field: "name", Operator: filter.OperatorContains, Value: "install should succeed"},
{Field: "variants", Operator: filter.OperatorHasEntry, Value: fmt.Sprintf("Capability:%s", featureGate)},
{Field: "variants", Not: true, Operator: filter.OperatorHasEntry, Value: "never-stable"},
{Field: "variants", Not: true, Operator: filter.OperatorHasEntry, Value: "aggregated"},
},
LinkOperator: filter.LinkOperatorAnd,
}
}

// CapabilityRegressionsFilter returns the filter for identifying tests with
// low pass rates on jobs owned by this feature gate's capability.
func CapabilityRegressionsFilter(featureGate string) filter.Filter {
return filter.Filter{
Items: []filter.FilterItem{
{Field: "variants", Not: true, Operator: filter.OperatorHasEntry, Value: "never-stable"},
{Field: "variants", Not: true, Operator: filter.OperatorHasEntry, Value: "aggregated"},
{Field: "variants", Operator: filter.OperatorHasEntry, Value: fmt.Sprintf("Capability:%s", featureGate)},
{Field: "lifecycle", Operator: filter.OperatorEquals, Value: "blocking"},
{Field: "current_working_percentage", Operator: filter.OperatorArithmeticLessThan, Value: "92"},
{Field: "current_runs", Operator: filter.OperatorArithmeticGreaterThanOrEquals, Value: "1"},
{Field: "name", Not: true, Operator: filter.OperatorContains, Value: "install should succeed"},
{Field: "name", Not: true, Operator: filter.OperatorContains, Value: "openshift-tests should work"},
{Field: "name", Not: true, Operator: filter.OperatorContains, Value: "infrastructure should work"},
},
LinkOperator: filter.LinkOperatorAnd,
}
}
Loading