From: Nizamudeen A Date: Mon, 4 Jul 2022 07:39:43 +0000 (+0530) Subject: mgr/dashboard: rbd-mirroring e2e tests X-Git-Tag: v18.0.0~423^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=59ed661458b1b88fc7dc0a83726e4ef9346b30b6;p=ceph-ci.git mgr/dashboard: rbd-mirroring e2e tests Signed-off-by: Nizamudeen A --- diff --git a/src/pybind/mgr/dashboard/frontend/cypress.json b/src/pybind/mgr/dashboard/frontend/cypress.json index 0de1008cb54..996b285301f 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress.json +++ b/src/pybind/mgr/dashboard/frontend/cypress.json @@ -21,6 +21,9 @@ "retries": 1, "env": { "LOGIN_USER": "admin", - "LOGIN_PWD": "admin" - } + "LOGIN_PWD": "admin", + "CEPH2_URL": "http://localhost:4202/" + }, + "experimentalSessionAndOrigin": true, + "chromeWebSecurity": false } diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.e2e-spec.ts index dfba73b2740..77deca7012e 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.e2e-spec.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.e2e-spec.ts @@ -25,6 +25,67 @@ describe('Mirroring page', () => { mirroring.getTabText(2).should('eq', 'Ready (0)'); }); + describe('rbd mirroring bootstrap', () => { + const poolName = 'rbd-mirror'; + + beforeEach(() => { + cy.login(); + Cypress.Cookies.preserveOnce('token'); + pools.navigateTo('create'); + pools.create(poolName, 8, 'rbd'); + pools.navigateTo(); + pools.existTableCell(poolName, true); + mirroring.navigateTo(); + }); + + it('should generate and import the bootstrap token between clusters', () => { + const url: string = Cypress.env('CEPH2_URL'); + mirroring.navigateTo(); + mirroring.generateToken(poolName); + cy.get('@token').then((bootstrapToken) => { + // pass the token to the origin as an arg + const args = { name: poolName, token: String(bootstrapToken) }; + + // login to the second ceph cluster + cy.ceph2Login(); + + // can't use any imports or functions inside the origin + // so writing the code to copy the token inside the origin manually + // rather than using a function call + // @ts-ignore + cy.origin(url, { args }, ({ name, token }: any) => { + // Create an rbd pool in the second cluster + cy.visit('#/pool/create').wait(100); + cy.get('input[name=name]').clear().type(name); + cy.get(`select[name=poolType]`).select('replicated'); + cy.get(`select[name=poolType] option:checked`).contains('replicated'); + cy.get('.float-left.mr-2.select-menu-edit').click(); + cy.get('.popover-body').should('be.visible'); + // Choose rbd as the application label + cy.get('.select-menu-item-content').contains('rbd').click(); + cy.get('cd-submit-button').click(); + cy.get('cd-pool-list').should('exist'); + + cy.visit('#/block/mirroring').wait(1000); + cy.get('.table-actions button.dropdown-toggle').first().click(); + cy.get('[aria-label="Import Bootstrap Token"]').click(); + cy.get('cd-bootstrap-import-modal').within(() => { + cy.get(`label[for=${name}]`).click(); + cy.get('textarea[id=token]').wait(100).type(token); + cy.get('button[type=submit]').click(); + }); + }); + }); + + // login again since origin removes all the cookies + // sessions, localStorage items etc.. + cy.login(); + Cypress.Cookies.preserveOnce('token'); + mirroring.navigateTo(); + mirroring.checkPoolHealthStatus(poolName, 'OK'); + }); + }); + describe('checks that edit mode functionality shows in the pools table', () => { const poolName = 'mirroring_test'; diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.po.ts index e24a3ebc037..456223a873e 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/block/mirroring.po.ts @@ -7,6 +7,11 @@ const pages = { export class MirroringPageHelper extends PageHelper { pages = pages; + poolsColumnIndex = { + name: 1, + health: 6 + }; + /** * Goes to the mirroring page and edits a pool in the Pool table. Clicks on the * pool and chooses an option (either pool, image, or disabled) @@ -32,4 +37,28 @@ export class MirroringPageHelper extends PageHelper { // unselect the pool in the table this.getFirstTableCell(name).click(); } + + @PageHelper.restrictTo(pages.index.url) + generateToken(poolName: string) { + cy.get('[aria-label="Create Bootstrap Token"]').first().click(); + cy.get('cd-bootstrap-create-modal').within(() => { + cy.get(`label[for=${poolName}]`).click(); + cy.get('button[type=submit]').click(); + cy.get('textarea[id=token]').wait(200).invoke('val').as('token'); + cy.get('[aria-label="Back"]').click(); + }); + } + + @PageHelper.restrictTo(pages.index.url) + checkPoolHealthStatus(poolName: string, status: string) { + cy.get('cd-mirroring-pools').within(() => { + this.getTableCell(this.poolsColumnIndex.name, poolName) + .parent() + .find(`datatable-body-cell:nth-child(${this.poolsColumnIndex.health}) .badge`) + .should(($ele) => { + const newLabels = $ele.toArray().map((v) => v.innerText); + expect(newLabels).to.include(status); + }); + }); + } } diff --git a/src/pybind/mgr/dashboard/frontend/cypress/support/commands.ts b/src/pybind/mgr/dashboard/frontend/cypress/support/commands.ts index 768d8527686..cdd39c680b7 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/support/commands.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/support/commands.ts @@ -1,9 +1,10 @@ declare global { namespace Cypress { interface Chainable { - login(): void; + login(username?: string, password?: string): void; logToConsole(message: string, optional?: any): void; text(): Chainable; + ceph2Login(username?: string, password?: string): Chainable; } } } @@ -26,29 +27,58 @@ const fillAuth = () => { window.localStorage.setItem('sso', auth.sso); }; -Cypress.Commands.add('login', () => { - const username = Cypress.env('LOGIN_USER'); - const password = Cypress.env('LOGIN_PWD'); - - if (auth === undefined) { - cy.request({ - method: 'POST', - url: 'api/auth', - headers: { Accept: CdHelperClass.cdVersionHeader('1', '0') }, - body: { username: username, password: password } - }).then((resp) => { - auth = resp.body; - auth.permissions = JSON.stringify(new Permissions(auth.permissions)); - auth.pwdExpirationDate = String(auth.pwdExpirationDate); - auth.pwdUpdateRequired = String(auth.pwdUpdateRequired); - auth.sso = String(auth.sso); - fillAuth(); - }); - } else { +Cypress.Commands.add('login', (username, password) => { + requestAuth(username, password).then((resp) => { + auth = resp.body; + auth.permissions = JSON.stringify(new Permissions(auth.permissions)); + auth.pwdExpirationDate = String(auth.pwdExpirationDate); + auth.pwdUpdateRequired = String(auth.pwdUpdateRequired); + auth.sso = String(auth.sso); fillAuth(); - } + }); +}); + +Cypress.Commands.add('ceph2Login', (username, password) => { + const url: string = Cypress.env('CEPH2_URL'); + requestAuth(username, password, url).then((resp) => { + auth = resp.body; + auth.permissions = JSON.stringify(new Permissions(auth.permissions)); + auth.pwdExpirationDate = String(auth.pwdExpirationDate); + auth.pwdUpdateRequired = String(auth.pwdUpdateRequired); + auth.sso = String(auth.sso); + const args = { + username: auth.username, + permissions: auth.permissions, + pwdExpirationDate: auth.pwdExpirationDate, + pwdUpdateRequired: auth.pwdUpdateRequired, + sso: auth.sso + }; + // @ts-ignore + cy.origin( + url, + { args }, + ({ uname, permissions, pwdExpirationDate, pwdUpdateRequired, sso }: any) => { + window.localStorage.setItem('dashboard_username', uname); + window.localStorage.setItem('dashboard_permissions', permissions); + window.localStorage.setItem('user_pwd_expiration_date', pwdExpirationDate); + window.localStorage.setItem('user_pwd_update_required', pwdUpdateRequired); + window.localStorage.setItem('sso', sso); + } + ); + }); }); +function requestAuth(username: string, password: string, url = '') { + username = username ? username : Cypress.env('LOGIN_USER'); + password = password ? password : Cypress.env('LOGIN_PWD'); + return cy.request({ + method: 'POST', + url: !url ? 'api/auth' : `${url}api/auth`, + headers: { Accept: CdHelperClass.cdVersionHeader('1', '0') }, + body: { username: username, password: password } + }); +} + // @ts-ignore Cypress.Commands.add('text', { prevSubject: true }, (subject: any) => { return subject.text(); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.html index a9090aaf202..2d8a787c0d1 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.html @@ -1,4 +1,5 @@