-
Notifications
You must be signed in to change notification settings - Fork 25
[NETOBSERV-2376] FlowCollector Status Page UI Test #1439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d985cda
fa0d9b9
7ec6e12
ad34470
6ee6578
f071eb9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| kind: FlowCollector | ||
| apiVersion: flows.netobserv.io/v1beta2 | ||
| metadata: | ||
| name: cluster | ||
| spec: | ||
| agent: | ||
| ebpf: | ||
| sampling: 1 | ||
| type: eBPF | ||
| loki: | ||
| enable: true | ||
| mode: LokiStack | ||
| lokiStack: | ||
| name: loki |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import { Operator } from "@views/netobserv" | ||
| import { flowcollectorStatusPage, flowcollectorStatusSelectors } from "@views/flowcollector-status" | ||
|
|
||
| describe('Network_Observability FlowCollector status error scenario', { tags: ['Network_Observability'] }, function () { | ||
|
|
||
| before('setup', function () { | ||
| cy.adminCLI(`oc adm policy add-cluster-role-to-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) | ||
| cy.uiLogin(Cypress.env('LOGIN_IDP'), Cypress.env('LOGIN_USERNAME'), Cypress.env('LOGIN_PASSWORD')) | ||
|
|
||
| Operator.install() | ||
| cy.checkStorageClass(this) | ||
| Operator.createFlowcollector("LokiWithoutLokiStack") | ||
| }) | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| it("(OCP-88744, kapjain, Network_Observability) Verify error status when Loki enabled without LokiStack", function () { | ||
| // Visit status page and wait for Ready condition to show False (error state) | ||
| flowcollectorStatusPage.visit() | ||
| cy.get(flowcollectorStatusSelectors.readyRow, { timeout: 120000 }).should('exist') | ||
| .should('have.attr', 'data-test-status', 'False') | ||
| cy.get(flowcollectorStatusSelectors.readyRow) | ||
| .should('have.attr', 'data-test-reason') | ||
| .and('not.equal', 'Pending') | ||
| .and('not.equal', 'Valid') | ||
|
|
||
| // Verify WaitingFLPMonolith condition shows error about loki-gateway-ca-bundle | ||
| cy.get(flowcollectorStatusSelectors.flpMonolithRow).should('exist') | ||
| .should('have.attr', 'data-test-status', 'True') | ||
| cy.get(flowcollectorStatusSelectors.flpMonolithRow).parent() | ||
| .should('contain.text', 'loki-gateway-ca-bundle') | ||
|
|
||
| // Verify Flowlogs Pipeline component shows error about loki-gateway-ca-bundle | ||
| cy.contains('td', 'Flowlogs Pipeline').parent('tr') | ||
| .should('contain.text', 'loki-gateway-ca-bundle') | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| // Verify WaitingLokiStack condition shows LokiStack not found error | ||
| cy.get(flowcollectorStatusSelectors.lokiStackRow).should('exist') | ||
| .should('have.attr', 'data-test-status', 'True') | ||
| cy.get(flowcollectorStatusSelectors.lokiStackRow) | ||
| .should('contain.text', 'Loki is configured in LokiStack mode, but LokiStack API is missing') | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| // Verify WaitingFLPParent condition shows FLP error | ||
| cy.get(flowcollectorStatusSelectors.flpParentRow).should('exist') | ||
| .should('have.attr', 'data-test-status', 'True') | ||
| .and('have.attr', 'data-test-reason', 'FLPError') | ||
|
|
||
| // Verify status icon tooltip shows error | ||
| cy.get(flowcollectorStatusSelectors.statusButton) | ||
| .find('span span').trigger('mouseenter', { force: true }) | ||
| cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) | ||
| .should('contain.text', 'FlowCollector has errors') | ||
|
|
||
| // Verify "Open Network Traffic page" button is disabled | ||
| cy.byLegacyTestID('open-network-traffic').should('exist') | ||
| .should('have.attr', 'aria-disabled', 'true') | ||
| }) | ||
|
|
||
| after("all tests", function () { | ||
| Operator.deleteFlowCollector() | ||
| cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) | ||
| }) | ||
| }) | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,7 +1,9 @@ | ||||||||
| import { netflowPage, overviewSelectors, pluginSelectors } from "@views/netflow-page" | ||||||||
| import { Operator } from "@views/netobserv" | ||||||||
| import {flowcollectorStatusPage, flowcollectorStatusSelectors} from "@views/flowcollector-status"; | ||||||||
| import {searchPage} from "@views/search"; | ||||||||
|
|
||||||||
| describe('(OCP-84156 Network_Observability) StaticPlugin test', { tags: ['Network_Observability'] }, function () { | ||||||||
| describe('(OCP-84156 OCP-88744 Network_Observability) StaticPlugin test with Status Check', { tags: ['Network_Observability'] }, function () { | ||||||||
|
|
||||||||
| before('any test', function () { | ||||||||
| cy.adminCLI(`oc adm policy add-cluster-role-to-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) | ||||||||
|
|
@@ -12,35 +14,113 @@ describe('(OCP-84156 Network_Observability) StaticPlugin test', { tags: ['Networ | |||||||
| Operator.createFlowcollector("StaticPlugin") | ||||||||
| }) | ||||||||
|
|
||||||||
| it("(OCP-84156, aramesha, Network_Observability) Edit flowcollector form view", function () { | ||||||||
| it("(OCP-84156, OCP-88744 aramesha, Network_Observability) Edit flowcollector form view with Status Check", function () { | ||||||||
| // Edit flowcollector form view to update sampling to 1 | ||||||||
| cy.visit('k8s/cluster/flows.netobserv.io~v1beta2~FlowCollector/status') | ||||||||
| flowcollectorStatusPage.visit() | ||||||||
|
|
||||||||
| // Verify status page title with status icon and tooltip on hover | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| cy.contains('Network Observability FlowCollector status').should('exist') | ||||||||
| cy.get(flowcollectorStatusSelectors.statusButton).should('exist') | ||||||||
| .find('span span').trigger('mouseenter', { force: true }) | ||||||||
| cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) | ||||||||
| .should('contain.text', 'FlowCollector is ready') | ||||||||
|
|
||||||||
| // Verify component statuses table headers | ||||||||
| cy.contains('Component statuses').should('exist') | ||||||||
| cy.contains('th', 'Component').should('exist') | ||||||||
| cy.contains('th', 'State').should('exist') | ||||||||
| cy.contains('th', 'Replicas').should('exist') | ||||||||
| cy.contains('th', 'Details').should('exist') | ||||||||
|
|
||||||||
| // Verify component rows | ||||||||
| cy.contains('eBPF Agent').should('exist') | ||||||||
| cy.contains('Flowlogs Pipeline').should('exist') | ||||||||
| cy.contains('Console Plugin').should('exist') | ||||||||
| cy.contains('Loki').should('exist') | ||||||||
| cy.contains('Monitoring').should('exist') | ||||||||
|
|
||||||||
| // Verify "Open Network Traffic page" button is enabled when FC is ready | ||||||||
| cy.byLegacyTestID('open-network-traffic').should('exist') | ||||||||
| .should('not.have.attr', 'aria-disabled', 'true') | ||||||||
|
|
||||||||
| // Verify demoloki install warning alert at top of status page | ||||||||
| cy.get(flowcollectorStatusSelectors.configIssueRow).should('exist') | ||||||||
| .should('have.attr', 'data-test-status', 'True') | ||||||||
| .should('have.attr', 'data-test-reason', 'Warnings') | ||||||||
| cy.contains('Configuration warnings').should('exist') | ||||||||
|
|
||||||||
| // Verify Conditions | ||||||||
| cy.contains('Conditions').should('exist') | ||||||||
| cy.get(flowcollectorStatusSelectors.readyRow) | ||||||||
| .should('have.attr', 'data-test-status', 'True') | ||||||||
| cy.get(flowcollectorStatusSelectors.agentReadyRow).should('exist') | ||||||||
| cy.get(flowcollectorStatusSelectors.pluginReadyRow).should('exist') | ||||||||
| cy.get(flowcollectorStatusSelectors.monitoringReadyRow).should('exist') | ||||||||
|
|
||||||||
| // Updating ebpf Sampling to 1 | ||||||||
| cy.get(pluginSelectors.editFlowcollector).click() | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add comment about editing flowcollector to update sampling here |
||||||||
| cy.get('#root_spec_agent_accordion-toggle').click() | ||||||||
| cy.get('#root_spec_agent_ebpf_sampling').clear().type('1') | ||||||||
| cy.get(pluginSelectors.update).click() | ||||||||
|
|
||||||||
| // Wait for flowcollector to get ready | ||||||||
| cy.wait(20000) | ||||||||
| cy.get('[id=Ready-row]', { timeout: 60000 }).each($td => { | ||||||||
| cy.wrap($td).should('have.attr', 'data-test-status', 'True') | ||||||||
| cy.wrap($td).should('have.attr', "data-test-reason", 'Ready') | ||||||||
| }) | ||||||||
|
|
||||||||
| cy.get(flowcollectorStatusSelectors.readyRow,{ timeout: 60000 }).should('exist') | ||||||||
| .should('have.attr', 'data-test-status', 'True') | ||||||||
| .should('have.attr', 'data-test-reason', 'Ready') | ||||||||
| cy.get(pluginSelectors.openNetworkTraffic).click() | ||||||||
|
|
||||||||
| // Verify PacketDrop data is seen | ||||||||
| cy.get('li.overviewTabButton').trigger('click') | ||||||||
| netflowPage.clearAllFilters() | ||||||||
| netflowPage.setAutoRefresh() | ||||||||
| cy.checkPanel(overviewSelectors.defaultPacketDropPanels) | ||||||||
| cy.checkPanelsNum(6); | ||||||||
|
|
||||||||
| cy.checkNetflowTraffic() | ||||||||
| }) | ||||||||
|
|
||||||||
| afterEach("test", function () { | ||||||||
| netflowPage.resetClearFilters() | ||||||||
| }) | ||||||||
|
|
||||||||
| it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Health page", function () { | ||||||||
| cy.visit('/network-health') | ||||||||
|
|
||||||||
| // cy.get('#content-scrollable', { timeout: 30000 }).should('exist') | ||||||||
| cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') | ||||||||
| .find('span span').trigger('mouseenter', { force: true }) | ||||||||
| cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) | ||||||||
| .should('contain.text', 'FlowCollector is ready') | ||||||||
| cy.get(flowcollectorStatusSelectors.statusIndicator).click() | ||||||||
| cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') | ||||||||
| }) | ||||||||
|
|
||||||||
| it("(OCP-88744, kapjain, Network_Observability) Verify status indicator on Network Traffic page", function () { | ||||||||
| cy.visit('/netflow-traffic') | ||||||||
|
|
||||||||
| // cy.get('#overview-container', { timeout: 60000 }).should('exist') | ||||||||
| cy.get(flowcollectorStatusSelectors.statusIndicator).should('exist') | ||||||||
| .find('span span').trigger('mouseenter', { force: true }) | ||||||||
| cy.get(flowcollectorStatusSelectors.statusTooltip, { timeout: 10000 }) | ||||||||
| .should('contain.text', 'FlowCollector is ready') | ||||||||
| cy.get(flowcollectorStatusSelectors.statusIndicator).click() | ||||||||
| cy.contains('Network Observability FlowCollector status', { timeout: 30000 }).should('exist') | ||||||||
| }) | ||||||||
|
|
||||||||
| it("(OCP-88744, kapjain, Network_Observability) Verify FlowCollector status via search and cluster columns", function () { | ||||||||
| // Search for FlowCollector via search page | ||||||||
| searchPage.navToSearchPage() | ||||||||
| searchPage.chooseResourceType('FlowCollector') | ||||||||
| cy.byTestID('data-view-table', { timeout: 30000 }).should('exist') | ||||||||
| cy.byTestID('data-view-cell-cluster-name').should('exist') | ||||||||
|
|
||||||||
| // Verify additionalPrinterColumn headers | ||||||||
| cy.byTestID('additional-printer-column-header-Agent').should('exist') | ||||||||
| cy.byTestID('additional-printer-column-header-Processor').should('exist') | ||||||||
| cy.byTestID('additional-printer-column-header-Plugin').should('exist') | ||||||||
| cy.byTestID('additional-printer-column-header-Status').should('exist') | ||||||||
|
|
||||||||
| // Verify status column shows Ready | ||||||||
| cy.byTestID('additional-printer-column-data-Status').should('contain.text', 'Ready') | ||||||||
| }) | ||||||||
|
|
||||||||
| after("after all tests", function () { | ||||||||
| Operator.deleteFlowCollector() | ||||||||
| cy.adminCLI(`oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`) | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| export namespace flowcollectorStatusSelectors { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these can be moved to netfow-page.ts instead of a new file
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if Page is diff it should have a diff view |
||
| export const statusIndicator = '#flowcollector-status-indicator' | ||
| export const statusButton = 'button[aria-label="FlowCollector status"]' | ||
| export const statusTooltip = '#flowcollector-status-tooltip' | ||
| export const readyRow = '[id=Ready-row]' | ||
| export const agentReadyRow = '[id=WaitingEBPFAgents-row]' | ||
| export const pluginReadyRow = '[id=WaitingWebConsole-row]' | ||
| export const monitoringReadyRow = '[id=WaitingMonitoring-row]' | ||
| export const configIssueRow = '[id=ConfigurationIssue-row]' | ||
| export const flpMonolithRow = '[id=WaitingFLPMonolith-row]' | ||
| export const lokiStackRow = '[id=WaitingLokiStack-row]' | ||
| export const flpParentRow = '[id=WaitingFLPParent-row]' | ||
| } | ||
|
|
||
| export const flowcollectorStatusPage = { | ||
| visit: () => { | ||
| cy.visit('k8s/cluster/flows.netobserv.io~v1beta2~FlowCollector/status') | ||
| cy.get(flowcollectorStatusSelectors.readyRow, { timeout: 30000 }).should('exist') | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -19,6 +19,7 @@ type FlowCollectorParameter = | |||||
| | 'DNSTracking' | ||||||
| | 'UDNMapping' | ||||||
| | 'LokiDisabled' | ||||||
| | 'LokiWithoutLokiStack' | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont think we need Loki at the start as well |
||||||
| | 'Conversations' | ||||||
| | 'ZonesAndMultiCluster' | ||||||
| | 'BytesMetrics' | ||||||
|
|
@@ -48,6 +49,7 @@ const FIXTURE_PATHS = { | |||||
| flowRTT: './cypress/fixtures/flowcollector/fc_flowRTT.yaml', | ||||||
| udnMapping: './cypress/fixtures/flowcollector/fc_UDN.yaml', | ||||||
| lokiDisabled: './cypress/fixtures/flowcollector/fc_lokiDisabled.yaml', | ||||||
| lokiWithoutLokiStack: './cypress/fixtures/flowcollector/fc_lokiWithoutLokiStack.yaml', | ||||||
| conversations: './cypress/fixtures/flowcollector/fc_conversations.yaml', | ||||||
| subnetLabels: './cypress/fixtures/flowcollector/fc_subnetLabel.yaml', | ||||||
| zonesMultiCluster: './cypress/fixtures/flowcollector/fc_zoneMulticluster.yaml', | ||||||
|
|
@@ -165,6 +167,9 @@ export const Operator = { | |||||
| case "LokiDisabled": | ||||||
| cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.lokiDisabled) | ||||||
| break; | ||||||
| case "LokiWithoutLokiStack": | ||||||
| cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.lokiWithoutLokiStack) | ||||||
| break; | ||||||
| case "Conversations": | ||||||
| cy.deployFlowcollectorFromFixture(FIXTURE_PATHS.conversations) | ||||||
| break; | ||||||
|
|
@@ -199,11 +204,13 @@ export const Operator = { | |||||
| // wait for all window refresh | ||||||
| cy.wait('@reload', { timeout: 100000 }) | ||||||
| cy.log("Console refreshed successfully") | ||||||
| if (parameters !== "LokiDisabled") { | ||||||
| if (parameters !== "LokiDisabled" && parameters !== "LokiWithoutLokiStack") { | ||||||
| cy.adminCLI(`oc wait --for=condition=Ready pod -l app=loki -n ${project} --timeout=180s`) | ||||||
| } | ||||||
| Operator.visitFlowcollector() | ||||||
| cy.byTestID('status-text', { timeout: 120000 }).should('exist').should('contain.text', 'Ready') | ||||||
| if (parameters !== "LokiWithoutLokiStack") { | ||||||
| Operator.visitFlowcollector() | ||||||
| cy.byTestID('status-text', { timeout: 120000 }).should('exist').should('contain.text', 'Ready') | ||||||
| } | ||||||
| } | ||||||
| }) | ||||||
| }, | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| export const searchPage = { | ||
| navToSearchPage: () => cy.visit('/search/all-namespaces'), | ||
| chooseResourceType: (resource_type) => { | ||
| cy.get('input[placeholder="Resources"]').clear().type(`${resource_type}`); | ||
| cy.get(`label[id$="~${resource_type}"]`).click(); | ||
| }, | ||
| clearAllFilters: () => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This func already exists know?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just copied the search view from openshfit-test-private repo and this function is for search view. |
||
| cy.byButtonText('Clear all filters').click({force: true}); | ||
| }, | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is WithoutLokiStack, we are using Loki configuration but Lokistack is not created
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or maybe
IncorrectLokiStackwould sound better?🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LokiWithoutLokiStack looks good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, lets go with your approach then👍