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
mgr/dashboard: introduce grafana frontend e2e testing #45811
Changes from all commits
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,86 @@ | ||
import { e2e } from '@grafana/e2e'; | ||
import { Then, When } from 'cypress-cucumber-preprocessor/steps'; | ||
import 'cypress-iframe'; | ||
|
||
function getIframe() { | ||
cy.frameLoaded('#iframe'); | ||
return cy.iframe(); | ||
} | ||
|
||
Then('I should see the grafana panel {string}', (panels: string) => { | ||
getIframe().within(() => { | ||
for (const panel of panels.split(', ')) { | ||
cy.get('.grafana-app') | ||
.wait(100) | ||
.within(() => { | ||
e2e.components.Panels.Panel.title(panel).should('be.visible'); | ||
}); | ||
} | ||
}); | ||
}); | ||
|
||
When('I view the grafana panel {string}', (panels: string) => { | ||
getIframe().within(() => { | ||
for (const panel of panels.split(', ')) { | ||
cy.get('.grafana-app') | ||
.wait(100) | ||
.within(() => { | ||
e2e.components.Panels.Panel.title(panel).should('be.visible').click(); | ||
e2e.components.Panels.Panel.headerItems('View').should('be.visible').click(); | ||
}); | ||
} | ||
}); | ||
}); | ||
|
||
Then('I should not see {string} in the panel {string}', (value: string, panels: string) => { | ||
getIframe().within(() => { | ||
for (const panel of panels.split(', ')) { | ||
cy.get('.grafana-app') | ||
.wait(100) | ||
.within(() => { | ||
cy.get(`[aria-label="${panel} panel"]`) | ||
.should('be.visible') | ||
.within(() => { | ||
cy.get('span').first().should('not.have.text', value); | ||
}); | ||
}); | ||
} | ||
}); | ||
}); | ||
|
||
Then( | ||
'I should see the legends {string} in the graph {string}', | ||
(legends: string, panels: string) => { | ||
getIframe().within(() => { | ||
for (const panel of panels.split(', ')) { | ||
cy.get('.grafana-app') | ||
.wait(100) | ||
.within(() => { | ||
cy.get(`[aria-label="${panel} panel"]`) | ||
.should('be.visible') | ||
.within(() => { | ||
for (const legend of legends.split(', ')) { | ||
cy.get('a').contains(legend); | ||
} | ||
}); | ||
}); | ||
} | ||
}); | ||
} | ||
); | ||
|
||
Then('I should not see No Data in the graph {string}', (panels: string) => { | ||
getIframe().within(() => { | ||
for (const panel of panels.split(', ')) { | ||
cy.get('.grafana-app') | ||
.wait(100) | ||
.within(() => { | ||
cy.get(`[aria-label="${panel} panel"]`) | ||
.should('be.visible') | ||
.within(() => { | ||
cy.get('div.datapoints-warning').should('not.exist'); | ||
}); | ||
}); | ||
} | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
Feature: Grafana panels | ||
|
||
Go to some of the grafana performance section and check if | ||
panels are populated without any issues | ||
|
||
Background: Log in | ||
Given I am logged in | ||
|
||
Scenario Outline: Hosts Overall Performance | ||
Given I am on the "hosts" page | ||
When I go to the "Overall Performance" tab | ||
Then I should see the grafana panel "<panel>" | ||
When I view the grafana panel "<panel>" | ||
Then I should not see "No Data" in the panel "<panel>" | ||
|
||
Examples: | ||
| panel | | ||
| OSD Hosts | | ||
| AVG CPU Busy | | ||
| AVG RAM Utilization | | ||
| Physical IOPS | | ||
| AVG Disk Utilization | | ||
| Network Load | | ||
| CPU Busy - Top 10 Hosts | | ||
| Network Load - Top 10 Hosts | | ||
|
||
Scenario Outline: RGW Daemon Overall Performance | ||
Given I am on the "rgw daemons" page | ||
When I go to the "Overall Performance" tab | ||
Then I should see the grafana panel "<panel>" | ||
When I view the grafana panel "<panel>" | ||
Then I should not see No Data in the graph "<panel>" | ||
And I should see the legends "<legends>" in the graph "<panel>" | ||
|
||
Examples: | ||
| panel | legends | | ||
| Total Requests/sec by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 | | ||
| GET Latencies by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 | | ||
| Bandwidth by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 | | ||
| PUT Latencies by RGW Instance | foo.ceph-node-00, foo.ceph-node-01, foo.ceph-node-02 | | ||
| Average GET/PUT Latencies | GET AVG, PUT AVG | | ||
| Bandwidth Consumed by Type | GETs, PUTs | | ||
|
||
Scenario Outline: RGW per Daemon Performance | ||
Given I am on the "rgw daemons" page | ||
When I expand the row "<name>" | ||
And I go to the "Performance Details" tab | ||
Then I should see the grafana panel "<panel>" | ||
When I view the grafana panel "<panel>" | ||
Then I should not see No Data in the graph "<panel>" | ||
And I should see the legends "<name>" in the graph "<panel>" | ||
|
||
Examples: | ||
| name | panel | | ||
| foo.ceph-node-00 | Bandwidth by HTTP Operation | | ||
| foo.ceph-node-00 | HTTP Request Breakdown | | ||
| foo.ceph-node-00 | Workload Breakdown | | ||
| foo.ceph-node-01 | Bandwidth by HTTP Operation | | ||
| foo.ceph-node-01 | HTTP Request Breakdown | | ||
| foo.ceph-node-01 | Workload Breakdown | | ||
| foo.ceph-node-02 | Bandwidth by HTTP Operation | | ||
| foo.ceph-node-02 | HTTP Request Breakdown | | ||
| foo.ceph-node-02 | Workload Breakdown | |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* tslint:disable*/ | ||
import { Input, ManagerModulesPageHelper } from '../../cluster/mgr-modules.po'; | ||
import { CreateClusterWizardHelper } from '../../cluster/create-cluster.po'; | ||
import { HostsPageHelper } from '../../cluster/hosts.po'; | ||
import { ServicesPageHelper } from '../../cluster/services.po'; | ||
|
@@ -8,6 +9,7 @@ describe('when cluster creation is completed', () => { | |
const createCluster = new CreateClusterWizardHelper(); | ||
const services = new ServicesPageHelper(); | ||
const hosts = new HostsPageHelper(); | ||
const mgrmodules = new ManagerModulesPageHelper(); | ||
|
||
const hostnames = ['ceph-node-00', 'ceph-node-01', 'ceph-node-02', 'ceph-node-03']; | ||
|
||
|
@@ -30,6 +32,35 @@ describe('when cluster creation is completed', () => { | |
hosts.navigateTo(); | ||
}); | ||
|
||
it('should check if monitoring stacks are running on the root host', () => { | ||
const monitoringStack = ['alertmanager', 'grafana', 'node-exporter', 'prometheus']; | ||
hosts.clickTab('cd-host-details', 'ceph-node-00', 'Daemons'); | ||
for (const daemon of monitoringStack) { | ||
cy.get('cd-host-details').within(() => { | ||
services.checkServiceStatus(daemon); | ||
}); | ||
} | ||
}); | ||
|
||
// avoid creating node-exporter on the newly added host | ||
// to favour the host draining process | ||
it('should reduce the count for node-exporter', () => { | ||
services.editService('node-exporter', '3'); | ||
}); | ||
|
||
// grafana ip address is set to the fqdn by default. | ||
// kcli is not working with that, so setting the IP manually. | ||
it('should change ip address of grafana', { retries: 2 }, () => { | ||
const dashboardArr: Input[] = [ | ||
{ | ||
id: 'GRAFANA_API_URL', | ||
newValue: 'https://192.168.100.100:3000', | ||
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. @epuertat @aaSharma14 recently some changes went into cephadm which basically means fetching the fqdn for some config urls. And our kcli configuration causes the fqdn to be something like |
||
oldValue: '' | ||
} | ||
]; | ||
mgrmodules.editMgrModule('dashboard', dashboardArr); | ||
}); | ||
|
||
it('should add one more host', () => { | ||
hosts.navigateTo('add'); | ||
hosts.add(hostnames[3]); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,13 @@ module.exports = (on, _config) => { | |
return launchOptions; | ||
} | ||
}); | ||
|
||
on('task', { | ||
log({ message, optional }) { | ||
optional ? console.log(message, optional) : console.log(message); | ||
return null; | ||
Comment on lines
+19
to
+21
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. What's this for? 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. the grafana-e2e commands like |
||
}, | ||
}); | ||
}; | ||
|
||
require('@applitools/eyes-cypress')(module); |
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.
extra_options
are just commented for now since we are not passing any extra options. It might be useful for later uses if we decides to pass some extra options so I thought I'll leave it here. Also, Avan pointed out to comment it out too. Maybe its useful in local too if we want to start a cluster and we don't want monitoring stacks, we can just add that skip option here.