Skip to content

Commit 345e6ee

Browse files
committed
troubleshooting panel
1 parent b2d7d34 commit 345e6ee

6 files changed

Lines changed: 130 additions & 6 deletions

File tree

web/cypress/e2e/coo/01.coo_bvt.cy.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { commonPages } from '../../views/common';
22
import { nav } from '../../views/nav';
3+
import { troubleshootingPanelPage } from '../../views/troubleshooting-panel';
34

45

56
// Set constants for the operators that need to be installed for tests.
@@ -31,9 +32,12 @@ describe('BVT: COO', { tags: ['@smoke', '@coo'] }, () => {
3132
commonPages.titleShouldHaveText('Alerting');
3233
nav.tabs.switchTab('Silences');
3334
nav.tabs.switchTab('Alerting rules');
34-
// nav.tabs.switchTab('Incidents');
35+
nav.tabs.switchTab('Incidents');
3536
nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']);
3637
commonPages.titleShouldHaveText('Dashboards');
38+
nav.sidenav.clickNavLink(['Observe', 'Alerting']);
39+
troubleshootingPanelPage.openSignalCorrelation();
40+
troubleshootingPanelPage.troubleshootingPanelPageShouldBeLoadedEnabled();
3741

3842
});
3943

web/cypress/e2e/coo/01.coo_ivt.cy.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import { Classes } from '../../../src/components/data-test';
2-
import { commonPages } from '../../views/common';
3-
import { nav } from '../../views/nav';
41
import { guidedTour } from '../../views/tour';
2+
import { troubleshootingPanelPage } from '../../views/troubleshooting-panel';
53

64
// Set constants for the operators that need to be installed for tests.
75
const KBV = {
@@ -29,6 +27,7 @@ describe('IVT: Monitoring UIPlugin + Virtualization', { tags: ['@smoke', '@coo']
2927
cy.switchPerspective('Virtualization');
3028
cy.byAriaLabel('Welcome modal').should('be.visible');
3129
guidedTour.closeKubevirtTour();
30+
troubleshootingPanelPage.signalCorrelationShouldNotBeVisible();
3231
cy.switchPerspective('Administrator');
3332

3433
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: observability.openshift.io/v1alpha1
2+
kind: UIPlugin
3+
metadata:
4+
name: troubleshooting-panel
5+
spec:
6+
type: TroubleshootingPanel

web/cypress/support/commands/operator-commands.ts

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Shadow = Cypress.Shadow;
66
import 'cypress-wait-until';
77
import { operatorHubPage } from '../../views/operator-hub-page';
88
import { nav } from '../../views/nav';
9+
import { DataTestIDs, LegacyTestIDs } from '../../../src/components/data-test';
910

1011
export { };
1112

@@ -398,6 +399,38 @@ const operatorUtils = {
398399
cy.url().should('include', '/monitoring/v2/dashboards');
399400
},
400401

402+
setupTroubleshootingPanel(MCP: { namespace: string }): void {
403+
cy.log('Create troubleshooting panel instance.');
404+
cy.exec(`oc apply -f ./cypress/fixtures/coo/troubleshooting-panel-ui-plugin.yaml --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`);
405+
406+
cy.log('Troubleshooting panel instance created. Waiting for pods to be ready.');
407+
cy.exec(
408+
`sleep 15 && oc wait --for=condition=Ready pods --selector=app.kubernetes.io/instance=troubleshooting-panel -n ${MCP.namespace} --timeout=60s --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`,
409+
{
410+
timeout: readyTimeoutMilliseconds,
411+
failOnNonZeroExit: true
412+
}
413+
).then((result) => {
414+
expect(result.code).to.eq(0);
415+
cy.log(`Troubleshooting panel pod is now running in namespace: ${MCP.namespace}`);
416+
});
417+
418+
cy.exec(
419+
`sleep 15 && oc wait --for=condition=Ready pods --selector=app.kubernetes.io/instance=korrel8r -n ${MCP.namespace} --timeout=600s --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`,
420+
{
421+
timeout: installTimeoutMilliseconds,
422+
failOnNonZeroExit: true
423+
}
424+
).then((result) => {
425+
expect(result.code).to.eq(0);
426+
cy.log(`Korrel8r pod is now running in namespace: ${MCP.namespace}`);
427+
});
428+
429+
cy.reload(true);
430+
cy.byLegacyTestID(LegacyTestIDs.ApplicationLauncher).should('be.visible').click();
431+
cy.byTestID(DataTestIDs.MastHeadApplicationItem).contains('Signal Correlation').should('be.visible');
432+
},
433+
401434
revertMonitoringPluginImage(MP: { namespace: string }): void {
402435
if (Cypress.env('MP_IMAGE')) {
403436
cy.log('MP_IMAGE is set. Lets revert CMO operator CSV');
@@ -484,7 +517,6 @@ const operatorUtils = {
484517
if (checkResult.code === 0) {
485518
// Namespace exists, proceed with deletion
486519
cy.log('Namespace exists, proceeding with deletion');
487-
cy.log('Eve');
488520

489521
// Step 1: Delete CSV (ClusterServiceVersion)
490522
cy.exec(
@@ -579,16 +611,66 @@ const operatorUtils = {
579611
}
580612
});
581613
};
582-
614+
583615
checkStatus();
584616

617+
cy.then(() => {
618+
operatorUtils.waitForPodsDeleted(MCP.namespace);
619+
});
620+
585621
} else {
586622
cy.log('Namespace does not exist, skipping deletion');
587623
}
588624
});
589625
}
590626
},
591627

628+
waitForPodsDeleted(namespace: string, maxWaitMs: number = 120000): void {
629+
const kubeconfigPath = Cypress.env('KUBECONFIG_PATH');
630+
const checkIntervalMs = 5000;
631+
const startTime = Date.now();
632+
const podPatterns = 'monitoring|perses|perses-0|health-analyzer|troubleshooting-panel|korrel8r';
633+
634+
const checkPods = () => {
635+
const elapsed = Date.now() - startTime;
636+
637+
if (elapsed > maxWaitMs) {
638+
throw new Error(`Timeout: Pods still exist after ${maxWaitMs / 1000}s`);
639+
}
640+
641+
cy.exec(
642+
`oc get pods -n ${namespace} --kubeconfig ${kubeconfigPath} -o name 2>&1 | grep -E '${podPatterns}' | wc -l`,
643+
{ failOnNonZeroExit: false }
644+
).then((result) => {
645+
const count = parseInt(result.stdout.trim(), 10);
646+
647+
if (count === 0 || result.stderr.includes('not found')) {
648+
cy.log(`✓ All target pods deleted after ${elapsed}ms`);
649+
} else {
650+
cy.log(`${elapsed}ms - ${count} pod(s) still exist, retrying...`);
651+
cy.wait(checkIntervalMs).then(checkPods);
652+
}
653+
});
654+
};
655+
656+
checkPods();
657+
},
658+
659+
cleanupTroubleshootingPanel(MCP: { namespace: string, config1?: { kind: string, name: string } }): void {
660+
const config1 = MCP.config1 || { kind: 'UIPlugin', name: 'troubleshooting-panel' };
661+
662+
if (Cypress.env('SKIP_ALL_INSTALL')) {
663+
cy.log('SKIP_ALL_INSTALL is set. Skipping Troubleshooting Panel instance deletion.');
664+
return;
665+
}
666+
667+
cy.log('Delete Troubleshooting Panel instance.');
668+
cy.executeAndDelete(
669+
`oc delete ${config1.kind} ${config1.name} --ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`,
670+
);
671+
672+
},
673+
592674
RemoveClusterAdminRole(): void {
593675
cy.log('Remove cluster-admin role from user.');
594676
cy.executeAndDelete(
@@ -697,6 +779,7 @@ Cypress.Commands.add('beforeBlock', (MP: { namespace: string, operatorName: stri
697779
cy.log('SKIP_ALL_INSTALL is set. Skipping COO cleanup and operator verifications (preserves existing setup).');
698780
return;
699781
}
782+
operatorUtils.cleanupTroubleshootingPanel(MCP);
700783
operatorUtils.cleanup(MCP);
701784
operatorUtils.revertMonitoringPluginImage(MP);
702785
cy.log('Cleanup COO (no session) completed');
@@ -711,6 +794,7 @@ Cypress.Commands.add('beforeBlock', (MP: { namespace: string, operatorName: stri
711794
operatorUtils.waitForCOOReady(MCP);
712795
operatorUtils.setupMonitoringConsolePlugin(MCP);
713796
operatorUtils.setupDashboardsAndPlugins(MCP);
797+
operatorUtils.setupTroubleshootingPanel(MCP);
714798
operatorUtils.setupMonitoringPluginImage(MP);
715799
operatorUtils.RemoveClusterAdminRole();
716800
operatorUtils.collectDebugInfo(MP, MCP);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { DataTestIDs, Classes, LegacyTestIDs, IDs } from "../../src/components/data-test";
2+
3+
export const troubleshootingPanelPage = {
4+
5+
openSignalCorrelation: () => {
6+
cy.log('troubleshootingPanelPage.openSignalCorrelation');
7+
cy.byLegacyTestID(LegacyTestIDs.ApplicationLauncher).should('be.visible').click();
8+
cy.byTestID(DataTestIDs.MastHeadApplicationItem).contains('Signal Correlation').should('be.visible').click();
9+
},
10+
11+
signalCorrelationShouldNotBeVisible: () => {
12+
cy.log('troubleshootingPanelPage.signalCorrelationShouldNotBeVisible');
13+
cy.byLegacyTestID(LegacyTestIDs.ApplicationLauncher).should('be.visible').click();
14+
cy.byTestID(DataTestIDs.MastHeadApplicationItem).contains('Signal Correlation').should('not.exist');
15+
cy.byLegacyTestID(LegacyTestIDs.ApplicationLauncher).should('be.visible').click();
16+
},
17+
18+
troubleshootingPanelPageShouldBeLoadedEnabled: () => {
19+
cy.log('troubleshootingPanelPage.troubleshootingPanelPageShouldBeLoadedEnabled');
20+
cy.get('h1').contains('Troubleshooting').should('be.visible');
21+
cy.byAriaLabel('Close').should('be.visible');
22+
cy.byButtonText('Focus').should('be.visible');
23+
cy.get('#query-toggle').should('be.visible');
24+
//svg path for refresh button
25+
cy.get('.tp-plugin__panel-query-container').find('path').eq(1).should('have.attr', 'd', 'M440.65 12.57l4 82.77A247.16 247.16 0 0 0 255.83 8C134.73 8 33.91 94.92 12.29 209.82A12 12 0 0 0 24.09 224h49.05a12 12 0 0 0 11.67-9.26 175.91 175.91 0 0 1 317-56.94l-101.46-4.86a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12H500a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12h-47.37a12 12 0 0 0-11.98 12.57zM255.83 432a175.61 175.61 0 0 1-146-77.8l101.8 4.87a12 12 0 0 0 12.57-12v-47.4a12 12 0 0 0-12-12H12a12 12 0 0 0-12 12V500a12 12 0 0 0 12 12h47.35a12 12 0 0 0 12-12.6l-4.15-82.57A247.17 247.17 0 0 0 255.83 504c121.11 0 221.93-86.92 243.55-201.82a12 12 0 0 0-11.8-14.18h-49.05a12 12 0 0 0-11.67 9.26A175.86 175.86 0 0 1 255.83 432z');
26+
cy.byDataID('korrel8r_graph').should('be.visible');
27+
},
28+
29+
30+
};

web/src/components/data-test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ export const LegacyTestIDs = {
169169
SelectAllSilencesCheckbox: 'select-all-silences-checkbox',
170170
PersesDashboardSection: 'dashboard',
171171
NamespaceBarDropdown: 'namespace-bar-dropdown',
172+
ApplicationLauncher: 'application-launcher',
172173
};
173174

174175
export const IDs = {

0 commit comments

Comments
 (0)