Skip to content

OCPBUGS-62851: feat(e2e): add check for Service and Pod Monitors - #6965

Closed
sjenning wants to merge 1 commit into
openshift:mainfrom
sjenning:fix-sm-targets
Closed

OCPBUGS-62851: feat(e2e): add check for Service and Pod Monitors#6965
sjenning wants to merge 1 commit into
openshift:mainfrom
sjenning:fix-sm-targets

Conversation

@sjenning

@sjenning sjenning commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

We need to catch when Service and Pod Monitor targets are down


Note

Introduces a health check to catch down metrics targets during cluster creation.

  • Adds EnsureNoMetricsTargetsAreDown in test/e2e/util/util.go to list ServiceMonitors/PodMonitors, derive jobs, and query Prometheus up{namespace="<hcp>"} with retries; skips autoscaler PodMonitor when no pods match
  • Registers Prometheus Operator monitoring.v1 types in test/e2e/util/scheme.go
  • Invokes the new check in TestCreateCluster after existing validations

Written by Cursor Bugbot for commit 3affe38. This will update automatically on new commits. Configure here.

@openshift-ci

openshift-ci Bot commented Oct 8, 2025

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

@openshift-ci openshift-ci Bot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. do-not-merge/needs-area labels Oct 8, 2025
@sjenning

sjenning commented Oct 8, 2025

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-minimal

@openshift-ci openshift-ci Bot added area/testing Indicates the PR includes changes for e2e testing and removed do-not-merge/needs-area labels Oct 8, 2025
@openshift-ci

openshift-ci Bot commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: sjenning

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

coderabbitai Bot commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🚫 Review skipped — only excluded labels are configured. (1)
  • do-not-merge/work-in-progress

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Registers Prometheus monitoring types in the test scheme, adds a test helper that verifies Prometheus scrape targets for ServiceMonitors and PodMonitors in the hosted control plane namespace, and invokes that helper from the cluster creation e2e test.

Changes

Cohort / File(s) Summary
Prometheus scheme registration
test/e2e/util/scheme.go
Imported Prometheus Operator monitoringv1 and registered it in the test runtime scheme (_ = monitoringv1.AddToScheme(scheme)).
Prometheus target health check helper
test/e2e/util/util.go
Added EnsureNoMetricsTargetsAreDown(t *testing.T, ctx context.Context, client crclient.Client, hostedCluster *hyperv1.HostedCluster). Discovers ServiceMonitor and PodMonitor resources in the hosted control plane namespace, maps jobs to expected targets (resolving Services via selectors, handling cluster-autoscaler PodMonitor special-case and Service name fallback), queries Prometheus up metric for those jobs/targets, and fails the test if any targets are down.
Test integration
test/e2e/create_cluster_test.go
Inserted a call to e2eutil.EnsureNoMetricsTargetsAreDown(t, ctx, mgtClient, hostedCluster) in TestCreateCluster after EnsureFeatureGateStatus.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review focus areas:
    • PromQL correctness and Prometheus query time window / vector matching.
    • Service discovery logic for ServiceMonitor selectors and PodMonitor handling.
    • Special-case handling for cluster-autoscaler and Service name fallback.
    • Test stability: timeouts, transient metric availability, and error reporting.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feat(e2e): add check for Service and Pod Monitors" directly corresponds to the main changes in the changeset. The PR adds a new e2e test utility function EnsureNoMetricsTargetsAreDown that validates Service and Pod Monitor targets are operational, registers the necessary Prometheus monitoring schemes, and integrates this check into the test flow. The title is concise, clear, and accurately summarizes the primary feature being introduced without unnecessary details or vague language.
Description Check ✅ Passed The pull request description is clearly related to the changeset. It articulates the purpose of the changes—detecting when ServiceMonitor and PodMonitor targets are down—and provides specific implementation details, including the addition of EnsureNoMetricsTargetsAreDown, the scheme registration for Prometheus Operator types, and integration into the test suite. The description is sufficiently detailed to convey the intent and scope of the changes without being vague or off-topic.

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

Comment thread test/e2e/util/util.go
Comment thread test/e2e/util/util.go Outdated
Comment thread test/e2e/util/util.go
// up == 1 means the target is healthy, up == 0 means it's down
query := fmt.Sprintf(`up{job="%s",namespace="%s"}`, sm.Name, hcpNamespace)

result, warnings, err := prometheusClient.Query(ctx, query, time.Now())

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.

An alternative would be to use the Prometheus API to query the targets endpoint, but for the sake of an e2e I don't think it would be any better or worse than using an actual query like you have. https://prometheus.io/docs/prometheus/latest/querying/api/#targets

Comment thread test/e2e/util/util.go
@sjenning

sjenning commented Oct 9, 2025

Copy link
Copy Markdown
Contributor Author
: TestCreateCluster/Main/EnsureNoMetricsTargetsAreDown expand_less	0s
{Failed  === RUN   TestCreateCluster/Main/EnsureNoMetricsTargetsAreDown
    util.go:3908: No targets found for ServiceMonitor catalog-operator (this may be expected if scraping hasn't started yet)
    util.go:3908: No targets found for ServiceMonitor etcd (this may be expected if scraping hasn't started yet)
    util.go:3908: No targets found for ServiceMonitor monitor-multus-admission-controller (this may be expected if scraping hasn't started yet)
    util.go:3908: No targets found for ServiceMonitor monitor-ovn-control-plane-metrics (this may be expected if scraping hasn't started yet)
    util.go:3908: No targets found for ServiceMonitor olm-operator (this may be expected if scraping hasn't started yet)
    util.go:3924: Found 2 down metrics target(s):
        ServiceMonitor: cluster-version-operator, Target: up{_id="468b5c20-f993-4d57-9436-b148665d38b8", container="cluster-version-operator", endpoint="https", instance="10.124.0.43:8443", job="cluster-version-operator", namespace="e2e-clusters-2rgsh-create-cluster-rzknb", pod="cluster-version-operator-86d4649f6c-nrctv", prometheus="openshift-monitoring/k8s", service="cluster-version-operator"}
        ServiceMonitor: node-tuning-operator, Target: up{_id="468b5c20-f993-4d57-9436-b148665d38b8", container="cluster-node-tuning-operator", endpoint="60000", instance="10.124.0.51:60000", job="node-tuning-operator", namespace="e2e-clusters-2rgsh-create-cluster-rzknb", pod="cluster-node-tuning-operator-6c775b96d4-sxrbs", prometheus="openshift-monitoring/k8s", service="node-tuning-operator"}
        --- FAIL: TestCreateCluster/Main/EnsureNoMetricsTargetsAreDown (0.09s)
}

@sjenning

sjenning commented Oct 9, 2025

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-minimal

@csrwng

csrwng commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Oct 9, 2025
@sjenning sjenning changed the title feat(e2e): add check for ServiceMonitors feat(e2e): add check for Service and Pod Monitors Oct 9, 2025
@simonpasquier

Copy link
Copy Markdown
Contributor

Because of target relabel configs, you have no guarantees that the job label == service name. As such the test feels brittle to me.

Comment thread test/e2e/util/util.go Outdated
@sjenning

sjenning commented Oct 9, 2025

Copy link
Copy Markdown
Contributor Author

/hold
until openshift/cluster-version-operator#1243 chain merges and NTO metrics issue is debugged

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 9, 2025
@sjenning sjenning changed the title feat(e2e): add check for Service and Pod Monitors OCPBUGS-62851: feat(e2e): add check for Service and Pod Monitors Oct 9, 2025
@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels Oct 9, 2025
@openshift-ci-robot

Copy link
Copy Markdown

@sjenning: This pull request references Jira Issue OCPBUGS-62851, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.21.0) matches configured target version for branch (4.21.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

No GitHub users were found matching the public email listed for the QA contact in Jira (yli2@redhat.com), skipping review request.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

We need to catch when ServiceMonitor targets are down

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.

Comment thread test/e2e/util/util.go Outdated
jobLabel := string(sample.Metric["job"])

// Only check targets for our monitors
if monitorSet[jobLabel] {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of looping over samples and seeing if they're in our expected monitor set, can we loop over the expected monitor set and see if they're in the collected samples? Failing if we didn't find a sample that we were expected would allow us to fail-closed and catch things like the job label not matching the ServiceMonitor name (as long as you didn't have any other monitors with that same name or someone else injecting an external monitor that generated the job label you were expecting, but those both seem like safe enough assumptions).

Comment thread test/e2e/util/util.go Outdated
Comment thread test/e2e/util/util.go
}

// Use the first matching Service
service := serviceList.Items[0]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Non-deterministic Service matching causes flaky tests.

When multiple Services match a ServiceMonitor's selector, using the first Service from serviceList.Items[0] creates non-deterministic behavior since Kubernetes list ordering isn't guaranteed. If the matching Services have different values for the job label, the test could track the wrong job name and produce flaky results across test runs.

Fix in Cursor Fix in Web

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 15e4dce and 90a0b5b.

📒 Files selected for processing (3)
  • test/e2e/create_cluster_test.go (1 hunks)
  • test/e2e/util/scheme.go (2 hunks)
  • test/e2e/util/util.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e/create_cluster_test.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • test/e2e/util/scheme.go
  • test/e2e/util/util.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Red Hat Konflux / hypershift-cli-mce-211-on-pull-request
  • GitHub Check: Red Hat Konflux / hypershift-operator-main-on-pull-request
  • GitHub Check: Red Hat Konflux / hypershift-release-mce-211-on-pull-request
  • GitHub Check: Cursor Bugbot

Comment thread test/e2e/util/util.go
Comment thread test/e2e/util/util.go

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

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

4003-4008: Consider deterministic service selection when multiple services match.

When multiple Services match a ServiceMonitor's selector, using serviceList.Items[0] creates non-deterministic behavior since Kubernetes list ordering isn't guaranteed. If matching Services have different values for the job label, the test could derive the wrong job name and produce inconsistent results across test runs.

For most Hypershift ServiceMonitors this may not be an issue in practice, but consider either:

  1. Asserting that exactly one Service matches (fail if multiple), or
  2. Sorting by name and documenting the selection strategy.

Based on past review comments.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 90a0b5b and 4179f5b.

📒 Files selected for processing (3)
  • test/e2e/create_cluster_test.go (1 hunks)
  • test/e2e/util/scheme.go (2 hunks)
  • test/e2e/util/util.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e/create_cluster_test.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • test/e2e/util/util.go
  • test/e2e/util/scheme.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Red Hat Konflux / hypershift-operator-main-on-pull-request
  • GitHub Check: Red Hat Konflux / hypershift-release-mce-211-on-pull-request
  • GitHub Check: Red Hat Konflux / hypershift-cli-mce-211-on-pull-request
🔇 Additional comments (7)
test/e2e/util/scheme.go (2)

19-19: LGTM: Prometheus Operator types imported.

The import enables the test scheme to recognize ServiceMonitor and PodMonitor custom resources.


34-34: LGTM: Monitoring types registered with test scheme.

This registration allows the e2e test client to list and work with ServiceMonitor and PodMonitor resources.

test/e2e/util/util.go (5)

73-73: LGTM: Import added for Prometheus monitoring types.

This import enables the function to work with ServiceMonitor and PodMonitor lists.


4012-4020: LGTM: Job name derivation correctly implemented.

The code properly handles both cases:

  • When jobLabel is specified, it reads the value from the matched Service's labels (not the ServiceMonitor's selector)
  • When jobLabel is empty, it uses the Service name as the job name

This addresses previous review feedback about jobLabel handling.


4026-4053: LGTM: PodMonitor processing correctly handles label selectors.

The code properly:

  • Builds selectors supporting both matchLabels and matchExpressions via metav1.LabelSelectorAsSelector
  • Uses the correct client list option MatchingLabelsSelector
  • Handles the cluster-autoscaler PodMonitor case where pods may not exist
  • Uses namespace/name format for PodMonitor job names (Prometheus convention)

This addresses previous feedback about selector handling.


4061-4084: LGTM: Prometheus query correctly retrieves target health metrics.

The query uses the standard up metric to check target health in the HCP namespace. The validation ensures results are in the expected vector format and fails if no targets are found, implementing appropriate fail-closed behavior.


4086-4125: LGTM: Target aggregation implements correct fail-closed logic.

The code properly implements fail-closed behavior where any down target marks the entire job as down:

  • Detects down targets using sample.Value != 1
  • Records all down instances per job
  • Prevents a healthy instance from overriding a job that has failures
  • Provides detailed failure reporting with instance information

This addresses previous feedback about failing closed when any target is down.

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Dec 15, 2025
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 6, 2026
@openshift-ci-robot openshift-ci-robot added jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. and removed jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels Jan 6, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@sjenning: This pull request references Jira Issue OCPBUGS-62851, which is invalid:

  • expected the bug to target either version "4.22." or "openshift-4.22.", but it targets "4.21.0" instead

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

Details

In response to this:

We need to catch when Service and Pod Monitor targets are down


[!NOTE]
Ensures metrics scraping health for hosted control planes during e2e.

  • Adds EnsureNoMetricsTargetsAreDown in test/e2e/util/util.go to list ServiceMonitors/PodMonitors, derive jobs (respecting jobLabel and skipping cluster-autoscaler PodMonitor when no pods), and query Prometheus up{namespace=...} to fail on any down targets
  • Invokes the check from TestCreateCluster in test/e2e/create_cluster_test.go
  • Registers Prometheus Operator monitoring API (monitoring/v1) in test/e2e/util/scheme.go

Written by Cursor Bugbot for commit b722df5. This will update automatically on new commits. Configure here.

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.

Comment thread test/e2e/util/util.go

// Add the PodMonitor name as a job, initially marked as down (false)
jobName := fmt.Sprintf("%s/%s", pm.Namespace, pm.Name)
jobs[jobName] = false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PodMonitor jobLabel field is not handled

Medium Severity

The code always derives the PodMonitor job name using the namespace/name format. However, per the PodMonitorSpec, if spec.JobLabel is set, Prometheus uses the corresponding Pod label value as the job name instead. Unlike the ServiceMonitor handling which checks sm.Spec.JobLabel, PodMonitors with jobLabel set will have a mismatched job name, causing the test to report them as down even when healthy.

Fix in Cursor Fix in Web

Adds and e2e check to make sure that all pod and service monitors
are scraping successfully.
Comment thread test/e2e/util/util.go
if len(serviceMonitors.Items) == 0 && len(podMonitors.Items) == 0 {
t.Logf("No ServiceMonitors or PodMonitors found in namespace %s", hcpNamespace)
return
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty jobs map causes test failure when all PodMonitors skipped

Medium Severity

The early return check verifies if serviceMonitors.Items and podMonitors.Items are empty, but the actual relevant condition is whether the jobs map is empty. When there are no ServiceMonitors and all PodMonitors are cluster-autoscaler ones without matching pods, the loop skips all PodMonitors, leaving jobs empty. However, the check at line 4266 sees non-empty podMonitors.Items and proceeds. Later, g.Expect(vector).NotTo(BeEmpty()) fails if there are no Prometheus targets, causing the test to timeout even though there are no expected jobs to monitor.

Additional Locations (1)

Fix in Cursor Fix in Web

Comment thread test/e2e/util/util.go
// The jobLabel specifies which label on the matched Service contains the job name
labelValue, ok := service.GetLabels()[sm.Spec.JobLabel]
g.Expect(ok).To(BeTrue(), "ServiceMonitor %s/%s expects label %s on Service %s", sm.Namespace, sm.Name, sm.Spec.JobLabel, service.Name)
jobName = labelValue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServiceMonitor JobLabel fallback to Service name not implemented

Medium Severity

According to the Prometheus Operator ServiceMonitor spec, when JobLabel is set but the specified label doesn't exist on the Service, the job name should fall back to the Service name. The test code instead fails with g.Expect(ok).To(BeTrue()) when the label is missing. This causes the test to fail in cases where Prometheus would correctly use the Service name as a fallback, creating false negative test failures for valid configurations.

Fix in Cursor Fix in Web

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 10, 2026
@openshift-merge-robot

Copy link
Copy Markdown
Contributor

PR needs rebase.

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.

@openshift-ci

openshift-ci Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

@sjenning: The following tests 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/okd-scos-e2e-aws-ovn 4179f5b link false /test okd-scos-e2e-aws-ovn
ci/prow/e2e-aws 3affe38 link true /test e2e-aws
ci/prow/e2e-aws-upgrade-hypershift-operator 3affe38 link true /test e2e-aws-upgrade-hypershift-operator
ci/prow/e2e-aks-4-21 3affe38 link true /test e2e-aks-4-21
ci/prow/e2e-aks 3affe38 link true /test e2e-aks
ci/prow/e2e-aws-4-21 3affe38 link true /test e2e-aws-4-21
ci/prow/unit 3affe38 link true /test unit
ci/prow/e2e-azure-self-managed 3affe38 link true /test e2e-azure-self-managed
ci/prow/verify-workflows 3affe38 link true /test verify-workflows
ci/prow/security 3affe38 link true /test security

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.

@bryan-cox

Copy link
Copy Markdown
Member

Are we still looking to get this PR in?

@openshift-ci

openshift-ci Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Stale PRs are closed after 21d of inactivity.

If this PR is still relevant, comment to refresh it or remove the stale label.
Mark the PR as fresh by commenting /remove-lifecycle stale.

If this PR is safe to close now please do so with /close.

/lifecycle stale

@openshift-ci openshift-ci Bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jun 20, 2026
@openshift-ci

openshift-ci Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Stale PRs rot after 14d of inactivity.

Mark the PR as fresh by commenting /remove-lifecycle rotten.
Rotten PRs close after an additional 7d of inactivity.

If this PR is safe to close now please do so with /close.

/lifecycle rotten
/remove-lifecycle stale

@openshift-ci openshift-ci Bot added lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Jul 5, 2026
@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

The background agent confirmed my analysis. The report above is already complete with all the root cause details. Here's the final report:

Test Failure Analysis Complete

Job Information

  • Prow Jobs: pull-ci-openshift-hypershift-main-e2e-aws, pull-ci-openshift-hypershift-main-e2e-aks, pull-ci-openshift-hypershift-main-e2e-aws-upgrade-hypershift-operator, pull-ci-openshift-hypershift-main-security
  • Build IDs: 2008936329575927808 (e2e-aws), 2008936329475264512 (e2e-aks), 2008936329668202496 (e2e-aws-upgrade), 2053899604419678208 (security)
  • PR: OCPBUGS-62851: feat(e2e): add check for Service and Pod Monitors #6965OCPBUGS-62851: feat(e2e): add check for Service and Pod Monitors
  • Branch: fix-sm-targets

Test Failure Analysis

Error

e2e-aws: TestCreateCluster/Main/EnsureNoMetricsTargetsAreDown timed out after 600.13s
  waiting for Prometheus targets [catalog-operator-metrics, olm-operator-metrics] to become healthy

e2e-aks: TestCreateCluster/Main/EnsureNoMetricsTargetsAreDown panicked after 0.59s
  panic: failed to get prometheus-k8s service: services "prometheus-k8s" not found

e2e-aws-upgrade: TestUpgradeHyperShiftOperator/ValidateHostedCluster/EnsureNoCrashingPods
  (pre-existing flake — openshift-controller-manager restartCount=1, not PR-related)

security: Merge conflict in test/e2e/util/util.go — PR branch is outdated against main

Summary

The new EnsureNoMetricsTargetsAreDown test introduced in PR #6965 has two distinct bugs causing failures across all platforms. On AWS, the test discovers catalog-operator-metrics and olm-operator-metrics ServiceMonitor targets whose Prometheus scrape endpoints are persistently down (port 8443 unreachable), causing a 10-minute timeout. These OLM operator metrics targets are commonly unhealthy in CI environments, and the test has no mechanism to exclude known-flaky or non-critical targets. On AKS (Azure), the NewPrometheusClient function panics because the prometheus-k8s Service does not exist in the openshift-monitoring namespace on AKS-based hosted clusters — the function calls panic() instead of returning an error, which crashes the entire test binary and cascades failures to 142 other tests. The upgrade job failure (EnsureNoCrashingPods) is a pre-existing flake unrelated to this PR. The security job fails due to a merge conflict because the PR branch is stale against main.

Root Cause

Two bugs in the new test code:

  1. AKS panic — NewPrometheusClient uses panic() instead of error return (util.go:1511): The NewPrometheusClient function attempts to look up the prometheus-k8s Service in the openshift-monitoring namespace. On AKS-based hosted clusters, this Service does not exist because Prometheus is not deployed in the same way. Instead of returning an error, the function calls panic(), which crashes the entire test process. This killed the e2e-aks test binary, causing 142 tests to fail with (unknown) status — a catastrophic cascade from a single test.

  2. AWS timeout — OLM metrics targets are persistently down (util.go:4337): The test discovers ALL ServiceMonitor targets in the hosted control plane namespace and requires every single one to have up == 1 in Prometheus. The catalog-operator-metrics and olm-operator-metrics targets have scrape endpoints on port 8443 that are consistently unreachable in CI. The test waits 10 minutes (600s) polling every 15 seconds before timing out. During the wait, transient scrape failures from other targets (cluster-version-operator, kube-controller-manager, hosted-cluster-config-operator, ovnkube-control-plane) appear and resolve, but the OLM targets remain permanently down. The test has no allowlist/denylist for known-unhealthy targets and no way to distinguish between critical and non-critical monitoring targets.

  3. Security job — merge conflict (not a code bug): The PR branch fix-sm-targets is stale against main. The file test/e2e/util/util.go has conflicting changes between the PR and recent merges to main (e.g., PR OCPBUGS-62177: verify cert revocation against all KAS pods #8263). This is a rebasing issue.

  4. Upgrade job — pre-existing flake (not PR-related): The EnsureNoCrashingPods failure is caused by openshift-controller-manager having restartCount > 0 (1), which is a known transient condition during HyperShift operator upgrades and is unrelated to this PR's changes.

Recommendations
  1. Fix the panic in NewPrometheusClient: Replace panic() at util.go:1511 with a proper error return. The calling code in EnsureNoMetricsTargetsAreDown already has g.Expect(err).NotTo(HaveOccurred()) — make it return (prometheusv1.API, error) instead of panicking. Alternatively, skip the test on platforms where Prometheus is not available.

  2. Add an exclusion list for known-unhealthy targets: The OLM operator metrics (catalog-operator-metrics, olm-operator-metrics) are known to have flaky scrape endpoints in CI. Either:

    • Add an exclusion list for targets known to be unreliable in ephemeral CI clusters
    • Only check targets that are explicitly managed by the HyperShift operator (exclude OLM/marketplace targets)
    • Make the test check for critical control plane targets only, not every ServiceMonitor
  3. Guard against platform differences: Add platform detection (e.g., if platform == Azure { t.Skip("...") }) or probe for the existence of the Prometheus service before attempting to create the client.

  4. Rebase the PR branch: Rebase fix-sm-targets onto current main to resolve the merge conflict in test/e2e/util/util.go and re-trigger the security job.

  5. The upgrade job failure is unrelated: EnsureNoCrashingPods failing on openshift-controller-manager restartCount=1 is a known flake — no action needed from this PR.

Evidence
Evidence Detail
e2e-aws failure TestCreateCluster/Main/EnsureNoMetricsTargetsAreDown timed out at 600.13s; persistently down targets: catalog-operator-metrics [10.126.2.26:8443] and olm-operator-metrics [10.126.2.27:8443] never recovered
e2e-aks panic panic: failed to get prometheus-k8s service: services "prometheus-k8s" not found at util.go:1511 in NewPrometheusClient — crashed entire test binary, cascading 142 test failures
e2e-aks stack trace util.NewPrometheusClientutil.EnsureNoMetricsTargetsAreDown.func1 (util.go:4272) → panic propagation through testing.tRunner
e2e-aks cascade 252 tests run, 18 skipped, 142 failures — all non-TestCreateCluster tests show (unknown) status due to process crash
Security job CONFLICT (content): Merge conflict in test/e2e/util/util.go — PR branch stale against main (commit 1cec72f52)
Upgrade job (unrelated) EnsureNoCrashingPods: openshift-controller-manager pod openshift-controller-manager-78445b8f86-zrzls has restartCount > 0 (1) — pre-existing flake
PR diff Only TestCreateCluster has the new e2eutil.EnsureNoMetricsTargetsAreDown(t, ctx, mgtClient, hostedCluster) call — not added to upgrade or other test suites
AWS transient issues During the 10-min wait, additional targets temporarily went down: cluster-version-operator, kube-controller-manager, hosted-cluster-config-operator, multus-admission-controller, ovnkube-control-plane — all recovered except OLM targets
Test timeout config g.Eventually(...).WithTimeout(10*time.Minute).WithPolling(15*time.Second) — 10-minute hard timeout for all targets to be healthy simultaneously
Tide error Tide reports error state because required CI checks are failing — will auto-resolve when CI passes

@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Rotten PRs close after 7d of inactivity.

Reopen the PR by commenting /reopen.
Mark the PR as fresh by commenting /remove-lifecycle rotten.

/close

@openshift-ci openshift-ci Bot closed this Jul 13, 2026
@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@openshift-ci[bot]: Closed this PR.

Details

In response to this:

Rotten PRs close after 7d of inactivity.

Reopen the PR by commenting /reopen.
Mark the PR as fresh by commenting /remove-lifecycle rotten.

/close

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.

@openshift-ci-robot

Copy link
Copy Markdown

@sjenning: This pull request references Jira Issue OCPBUGS-62851. The bug has been updated to no longer refer to the pull request using the external bug tracker. All external bug links have been closed. The bug has been moved to the NEW state.

Details

In response to this:

We need to catch when Service and Pod Monitor targets are down


[!NOTE]
Introduces a health check to catch down metrics targets during cluster creation.

  • Adds EnsureNoMetricsTargetsAreDown in test/e2e/util/util.go to list ServiceMonitors/PodMonitors, derive jobs, and query Prometheus up{namespace="<hcp>"} with retries; skips autoscaler PodMonitor when no pods match
  • Registers Prometheus Operator monitoring.v1 types in test/e2e/util/scheme.go
  • Invokes the new check in TestCreateCluster after existing validations

Written by Cursor Bugbot for commit 3affe38. This will update automatically on new commits. Configure here.

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.

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. area/testing Indicates the PR includes changes for e2e testing jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants