Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .ci-operator.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
build_root_image:
name: release
namespace: openshift
tag: rhel-9-release-golang-1.24-openshift-4.21
tag: rhel-9-release-golang-1.24-openshift-4.22
6 changes: 3 additions & 3 deletions Dockerfile.art
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM registry.ci.openshift.org/ocp/builder:rhel-9-base-nodejs-openshift-4.21 AS web-builder
FROM registry.ci.openshift.org/ocp/builder:rhel-9-base-nodejs-openshift-4.22 AS web-builder

# Copy app sources
COPY $REMOTE_SOURCES $REMOTE_SOURCES_DIR
Expand All @@ -17,7 +17,7 @@ RUN test -d ${REMOTE_SOURCES_DIR}/cachito-gomod-with-deps || exit 1; \
&& make build-frontend


FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.24-openshift-4.21 AS go-builder
FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.24-openshift-4.22 AS go-builder

COPY $REMOTE_SOURCES $REMOTE_SOURCES_DIR
WORKDIR $REMOTE_SOURCES_DIR/cachito-gomod-with-deps/app
Expand All @@ -28,7 +28,7 @@ ENV CGO_ENABLED=1
RUN source $REMOTE_SOURCES_DIR/cachito-gomod-with-deps/cachito.env \
&& make build-backend BUILD_OPTS="-tags strictfipsruntime"

FROM registry.ci.openshift.org/ocp/4.21:base-rhel9
FROM registry.ci.openshift.org/ocp/4.22:base-rhel9

USER 1001

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ install-frontend:

.PHONY: install-frontend-ci
install-frontend-ci:
cd web && npm ci --omit=optional --ignore-scripts
cd web && npm ci --ignore-scripts

.PHONY: install-frontend-ci-clean
install-frontend-ci-clean: install-frontend-ci
Expand Down
File renamed without changes.
68 changes: 68 additions & 0 deletions docs/incident_detection/tests/2.ui_display_flows.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,74 @@ start,end,alertname,namespace,severity,silenced,labels
- Check the "last updated date" field
- Verify that the format changes without the need to reload the page

### 2.3.2 Incident Bar Trimming on Time Filter Change
**BUG**: When "Last N Days" is shorter than an incident's duration, the bar should be visually trimmed to show only the portion within the selected time window.
**Automation Status**: NOT AUTOMATED

**Background**:
- Incorrect behavior: Changing time filter "squashes" the X-axis to the right while still showing the full incident bar
- Correct behavior: Incident bar is trimmed/clipped to only display the portion that falls within the selected time range

- [ ] **Bar Trimming - Long Incident with Short Filter**: Create an incident spanning 15 days
- With "Last 15 days": Full incident bar visible with correct proportional width
- Set time filter to "Last 7 days"
- Verify the incident bar is trimmed to show only the 7-day portion (not the full 15-day bar)
- Verify the X-axis scale matches the 7-day window (not squashed to the right)
- Verify the bar starts at the left edge of the chart (since incident started before the 7-day window)

- [ ] **Tooltip Accuracy After Trimming**: Hover over a trimmed incident bar
- Verify tooltip shows the actual absolute Start date (which may be before the visible window)
- Verify tooltip shows correct End date
- Verify the displayed duration reflects the full incident, not just the visible portion

### 2.3.3 Mixed Severity Interval Boundary Times
**Automation Status**: NOT AUTOMATED

This section covers two related time display bugs in multi-severity incident tooltips.

#### Issue 1: Boundary End Times Not Rounded (OU-1205)
**BUG**: Consecutive interval end times within the same incident bar are not 5-minute rounded in tooltips.

**Background**:
- The interval calculation logic in `utils.ts` uses 1-second offsets to prevent overlapping intervals
- Example: If timestamps are at 100, 200, 300 seconds, intervals are calculated as:
- Interval 1: [100, 199, 'critical']
- Interval 2: [200, 299, 'warning']
- This results in end times like "23:29:59" instead of the expected rounded "23:30"
- The fix should round the displayed tooltip text, not change the interval calculation logic

- [ ] **End Times Should Be 5-Minute Rounded**: Use AlertC from test data (multi-severity incident)
- Hover over each severity segment within the incident bar
- Verify End time in tooltip shows rounded value (e.g., "23:30") not unrounded (e.g., "23:29:59")
- Verify all interval boundaries display at 5-minute precision in tooltips

#### Issue 2: Start Times 5 Minutes Off (OU-1221)
**BUG**: Multi-severity incident bar tooltip start times are 5 minutes off from the values shown in alert tooltips and alerts table.

**Background**:
- When hovering over a severity segment in an incident bar, the Start time shown differs from:
- The Start time shown in the corresponding alert tooltip
- The Start time shown in the alerts details table
- This creates user confusion as the same data point shows different times in different UI elements

- [ ] **Start Times Match Alert Tooltip**: Use AlertC from test data
- Click incident to open alerts chart
- Hover over an alert bar: Note the Start time in alert tooltip
- Hover over the corresponding severity segment in the incident bar
- Verify incident tooltip Start time matches alert tooltip Start time exactly

- [ ] **Start Times Match Alerts Table**:
- With incident selected, check alerts table Start column
- Hover over the corresponding severity segment in incident bar
- Verify incident tooltip Start time matches alerts table Start time exactly

- [ ] **Consecutive Interval Boundaries Match**: Check multi-severity incident
- Hover over first severity segment: Note the End time
- Hover over next severity segment: Note the Start time
- Verify End time of previous segment matches Start time of next segment (no 5-minute gap)
- Example failure: Info ends at "10:15" but Warning starts at "10:20"
- Expected: Info ends at "10:15" and Warning starts at "10:15"

### 2.4 Silences labels (Not Automated)
- Verify that information about silences is contained in the alert name
as `NetworkLatencyHigh (silenced)` instead of the additional `silenced=true`
Expand Down
38 changes: 35 additions & 3 deletions docs/incident_detection/tests/3.api_calls_data_loading_flows.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,43 @@ start,end,alertname,namespace,severity,silenced,labels
- Verify the latest query end time param is within the last 5 minutes


### 3.4 Data Integrity
**NEW, NOT AUTOMATED, TODO COO 1.4**
### 3.4 15-Day Data Loading with "Last N Days" Filtering
**FEATURE**: UI always loads 15 days of data (one query_range call per day), then filters client-side based on "Last N Days" selection.
**Automation Status**: NOT AUTOMATED

**Background**:
- Before: Data was downloaded only for "Last N Days", causing Start dates to be relative to N days
- After: Start displays an absolute date, even when "Last N Days" is shorter than the incident's actual start
- Limit: Start is capped at max 15 days (the maximum supported range)

**Fix Implementation**:
The absolute start date of an incident/alert is always displayed, regardless of the selected "Last N Days" filter.

Solution uses a new API call:
- Absolute timestamps are retrieved by performing an **instant query** call to Prometheus
- For incidents: `min_over_time(timestamp(cluster_health_components_map{}))`
- For alerts: `min_over_time(timestamp(ALERTS{}))`
- This returns the timestamp of the first datapoint for that metric
- The result is saved into Redux store and matched to related incident/alert to update the Start date displayed in the tooltip

**Manual Testing Data**:
Use `docs/incident_detection/simulate_scenarios/long-incident-15-days.csv` which creates a 15-day spanning incident for testing absolute start date display.

- [ ] **Absolute Start Date Display**: Use `long-incident-15-days.csv` (creates 15-day incident)
- Set time filter to "Last 7 days"
- Verify incident Start date shows the absolute date (15 days ago), NOT a date relative to 7 days
- Verify the incident bar in the chart is trimmed to show only the portion within the 7-day window
- Verify tooltip shows the actual absolute start time

- [ ] **API Call Pattern Verification**: Monitor network requests on initial page load
- Verify 15 query_range calls are made on initial page load (one per day)
- Verify instant query calls for `min_over_time(timestamp(cluster_health_components_map{}))` and `min_over_time(timestamp(ALERTS{}))`
- Verify the time ranges cover the full 15-day window regardless of "Last N Days" selection

### 3.5 Data Integrity
**NEW, NOT AUTOMATED, TODO COO 1.4**
- [ ] Incident grouping by `group_id` works correctly
- [ ] Values deduplicated across multiple time range queries
- [ ] Component lists combined for same group_id
- [ ] Watchdog alerts filtered out


6 changes: 0 additions & 6 deletions package-lock.json

This file was deleted.

7 changes: 7 additions & 0 deletions pkg/plugin_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,14 @@ func patchManifest(baseManifestData []byte, cfg *Config) []byte {
patchedManifest = performPatch(baseManifestData, filepath.Join(cfg.ConfigPath, "clear-extensions.patch.json"))
}

if cfg.Features[Incidents] || cfg.Features[ClusterHealthAnalyzer] {
patchedManifest = performPatch(patchedManifest, filepath.Join(cfg.ConfigPath, "cluster-health-analyzer.patch.json"))
}

for feature := range cfg.Features {
if feature == ClusterHealthAnalyzer || feature == Incidents {
continue
}
patchedManifest = performPatch(patchedManifest, filepath.Join(cfg.ConfigPath, fmt.Sprintf("%s.patch.json", feature)))
}

Expand Down
9 changes: 5 additions & 4 deletions pkg/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ type PluginConfig struct {
type Feature string

const (
AcmAlerting Feature = "acm-alerting"
Incidents Feature = "incidents"
DevConfig Feature = "dev-config"
PersesDashboards Feature = "perses-dashboards"
AcmAlerting Feature = "acm-alerting"
Incidents Feature = "incidents"
DevConfig Feature = "dev-config"
PersesDashboards Feature = "perses-dashboards"
ClusterHealthAnalyzer Feature = "cluster-health-analyzer"
)

func (pluginConfig *PluginConfig) MarshalJSON() ([]byte, error) {
Expand Down
25 changes: 22 additions & 3 deletions web/cypress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Creates `export-env.sh` that you can source later: `source export-env.sh`
|----------|-------------|----------|
| `CYPRESS_MP_IMAGE` | Custom Monitoring Plugin image | Testing custom MP builds |
| `CYPRESS_MCP_CONSOLE_IMAGE` | Custom Monitoring Console Plugin image | Testing custom MCP builds |
| `CYPRESS_CHA_IMAGE` | Custom cluster-health-analyzer image | Testing custom CHA builds |

### Operator Installation Control

Expand Down Expand Up @@ -160,7 +161,25 @@ export CYPRESS_MP_IMAGE=quay.io/myorg/monitoring-plugin:my-branch
export CYPRESS_MCP_CONSOLE_IMAGE=quay.io/myorg/monitoring-console-plugin:my-branch
```

### Example 4: Pre-Provisioned Cluster (Skip Installations)
### Example 4: Testing Custom cluster-health-analyzer Build

For CI jobs testing PRs to cluster-health-analyzer:

```bash
# Required variables
export CYPRESS_BASE_URL=https://...
export CYPRESS_LOGIN_IDP=flexy-htpasswd-provider
export CYPRESS_LOGIN_USERS=username:password
export CYPRESS_KUBECONFIG_PATH=~/Downloads/kubeconfig

# Custom cluster-health-analyzer image built from PR
export CYPRESS_CHA_IMAGE=quay.io/myorg/cluster-health-analyzer:pr-123

# Use COO bundle (required for incidents feature testing)
export CYPRESS_KONFLUX_COO_BUNDLE_IMAGE=quay.io/rhobs/observability-operator-bundle:latest
```

### Example 5: Pre-Provisioned Cluster (Skip Installations)

```bash
# Required variables
Expand All @@ -173,14 +192,14 @@ export CYPRESS_KUBECONFIG_PATH=~/Downloads/kubeconfig
export CYPRESS_SKIP_ALL_INSTALL=true
```

### Example 5: Configurable COO Namespace
### Example 6: Configurable COO Namespace

Set the following var to specify the Cluster Observability Operator namespace. Defaults to `openshift-cluster-observability-operator` if not set. This is useful when testing with different namespace configurations (e.g., using `coo` instead of the default).
```bash
export CYPRESS_COO_NAMESPACE=openshift-cluster-observability-operator
```

### Example 6: Debug Mode
### Example 7: Debug Mode

```bash
# Required variables + debug
Expand Down
9 changes: 9 additions & 0 deletions web/cypress/configure-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ print_current_config() {
print_var "CYPRESS_KONFLUX_COO_BUNDLE_IMAGE" "${CYPRESS_KONFLUX_COO_BUNDLE_IMAGE-}"
print_var "CYPRESS_CUSTOM_COO_BUNDLE_IMAGE" "${CYPRESS_CUSTOM_COO_BUNDLE_IMAGE-}"
print_var "CYPRESS_MCP_CONSOLE_IMAGE" "${CYPRESS_MCP_CONSOLE_IMAGE-}"
print_var "CYPRESS_CHA_IMAGE" "${CYPRESS_CHA_IMAGE-}"
print_var "CYPRESS_TIMEZONE" "${CYPRESS_TIMEZONE-}"
print_var "CYPRESS_MOCK_NEW_METRICS" "${CYPRESS_MOCK_NEW_METRICS-}"
print_var "CYPRESS_SESSION" "${CYPRESS_SESSION-}"
Expand Down Expand Up @@ -226,6 +227,7 @@ main() {
local def_konflux_bundle=${CYPRESS_KONFLUX_COO_BUNDLE_IMAGE-}
local def_custom_coo_bundle=${CYPRESS_CUSTOM_COO_BUNDLE_IMAGE-}
local def_mcp_console_image=${CYPRESS_MCP_CONSOLE_IMAGE-}
local def_cha_image=${CYPRESS_CHA_IMAGE-}
local def_timezone=${CYPRESS_TIMEZONE-}
local def_mock_new_metrics=${CYPRESS_MOCK_NEW_METRICS-}
local def_session=${CYPRESS_SESSION-}
Expand Down Expand Up @@ -434,6 +436,9 @@ main() {
local mcp_console_image
mcp_console_image=$(ask "Monitoring Console Plugin UI image (CYPRESS_MCP_CONSOLE_IMAGE)" "$def_mcp_console_image")

local cha_image
cha_image=$(ask "Cluster Health Analyzer image (CYPRESS_CHA_IMAGE)" "$def_cha_image")

local timezone
timezone=$(ask "Cluster timezone (CYPRESS_TIMEZONE)" "${def_timezone:-UTC}")

Expand Down Expand Up @@ -500,6 +505,9 @@ main() {
if [[ -n "$mcp_console_image" ]]; then
export_lines+=("export CYPRESS_MCP_CONSOLE_IMAGE='$(printf %s "$mcp_console_image" | escape_for_single_quotes)'" )
fi
if [[ -n "$cha_image" ]]; then
export_lines+=("export CYPRESS_CHA_IMAGE='$(printf %s "$cha_image" | escape_for_single_quotes)'" )
fi
if [[ -n "$timezone" ]]; then
export_lines+=("export CYPRESS_TIMEZONE='$(printf %s "$timezone" | escape_for_single_quotes)'" )
fi
Expand Down Expand Up @@ -553,6 +561,7 @@ main() {
[[ -n "$konflux_bundle" ]] && echo " CYPRESS_KONFLUX_COO_BUNDLE_IMAGE=$konflux_bundle"
[[ -n "$custom_coo_bundle" ]] && echo " CYPRESS_CUSTOM_COO_BUNDLE_IMAGE=$custom_coo_bundle"
[[ -n "$mcp_console_image" ]] && echo " CYPRESS_MCP_CONSOLE_IMAGE=$mcp_console_image"
[[ -n "$cha_image" ]] && echo " CYPRESS_CHA_IMAGE=$cha_image"
[[ -n "$timezone" ]] && echo " CYPRESS_TIMEZONE=$timezone"
echo " CYPRESS_MOCK_NEW_METRICS=$mock_new_metrics"
echo " CYPRESS_SESSION=$session"
Expand Down
2 changes: 2 additions & 0 deletions web/cypress/e2e/coo/01.coo_bvt.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ describe('BVT: COO', { tags: ['@smoke', '@coo'] }, () => {

it('1. Admin perspective - Observe Menu', () => {
cy.log('Admin perspective - Observe Menu and verify all submenus');
cy.reload(true);
cy.wait(10000);
nav.sidenav.clickNavLink(['Observe', 'Alerting']);
commonPages.titleShouldHaveText('Alerting');
nav.tabs.switchTab('Silences');
Expand Down
Loading