From 8ea65fcfa0f00b1d95f7bfffa8d4c549e1ba3817 Mon Sep 17 00:00:00 2001 From: midays Date: Tue, 29 Nov 2022 20:12:03 +0200 Subject: [PATCH 01/18] - added openshift.ts object - removed the usage of configuration_script.ts in sanity test cases - added a function to split the login string in utils.ts --- cypress/integration/tests/sanity.test.ts | 80 +++++++++------- cypress/utils/openshift.ts | 114 +++++++++++++++++++++++ cypress/utils/utils.ts | 9 ++ 3 files changed, 170 insertions(+), 33 deletions(-) create mode 100644 cypress/utils/openshift.ts diff --git a/cypress/integration/tests/sanity.test.ts b/cypress/integration/tests/sanity.test.ts index e618d09..c6729ee 100644 --- a/cypress/integration/tests/sanity.test.ts +++ b/cypress/integration/tests/sanity.test.ts @@ -15,17 +15,19 @@ import { IntraClusterStateSource, IntraClusterStateTarget } from './cluster_config'; -import {login, log} from '../../utils/utils'; +import {login, splitLoginString} from '../../utils/utils'; import {Plan} from '../models/plan' import {PlanData} from '../types/types'; import {run_command_oc} from "../../utils/oc_wrapper"; import {skipOn} from '@cypress/skip-test' +import {Openshift} from "../../utils/openshift"; -const sourceCluster = Cypress.env('sourceCluster'); -const targetCluster = Cypress.env('targetCluster'); -const configurationScript = "./cypress/utils/configuration_script.sh" +const sourceClusterString = Cypress.env('sourceCluster'); +const targetClusterString = Cypress.env('targetCluster'); const plan = new Plan(); +let targetCluster; +let sourceCluster; const selectorTuple: [PlanData, string][] = [ [directImagePlanData, 'Direct image migration without copy verification'], @@ -56,39 +58,51 @@ selectorTuple.forEach(($type) => { describe(`'${migrationType}'`, () => { + before("Create cluster objects", () => { + + // split the login string for the source and target clusters + const sourceValues = splitLoginString(sourceClusterString); + const targetValues = splitLoginString(targetClusterString); + + // initiate source and target clusters objects from Openshift object + sourceCluster = new Openshift(sourceValues[0], sourceValues[1], sourceValues[2]) + targetCluster = new Openshift(targetValues[0], targetValues[1], targetValues[2]) + + // clean all the migration plans before starting + targetCluster.deleteAllMigrationPlans() + + }); + // if this is a state migraiton or scc, then check there are more than 1 sc available, if not, then skip the test if (['Storage class conversion', 'State migration'].indexOf(`${planData.migration_type}`) > -1) { - before('Check SC', () => { - (`${planData.source}` == 'source-cluster') ? selectedCluster = sourceCluster : selectedCluster = targetCluster; + (`${planData.source}` == 'source-cluster') ? selectedCluster = sourceCluster : selectedCluster = targetCluster; + before('Check SC', () => { + // todo: create a method in the Openshit object to get the storage class count if (planData.migration_type == 'Storage class conversion') { run_command_oc((planData.source == 'source-cluster') ? 'source' : 'target', 'get sc | wc -l').then((result) => { - let count: number = result.stdout + let count: number = parseInt(result.stdout) skipOn(count <= 2) }); } }); - } - // run before the all coming tests - it('Setting up Clusters', () => { - // cy.wait(10000) - if (['Storage class conversion', 'State migration'].indexOf(`${planData.migration_type}`) > -1) { + it(`Setting up ${( planData.source == 'host' ) ? 'target' : 'source'} cluster`, () => { + selectedCluster.setupCluster(planData.namespaceList); + }); - cy.exec(`"${configurationScript}" setup_source_cluster ${planData.namespaceList} ${selectedCluster}`, {timeout: 200000}).then((result) => { - log(`'${migrationType}_setup_source_cluster'`, result) - }); + } else { - } else { - cy.exec(`"${configurationScript}" setup_source_cluster ${planData.namespaceList} ${sourceCluster}`, {timeout: 200000}).then((result) => { - log(`'${migrationType}_setup_source_cluster'`, result) - }); - cy.exec(`"${configurationScript}" setup_target_cluster ${planData.namespaceList} ${targetCluster}`, {timeout: 200000}).then((result) => { - log(`'${migrationType}_setup_target_cluster'`, result) - }); - } - }); + it('Setting up source cluster', () => { + sourceCluster.setupCluster(planData.namespaceList) + }); + + it('Setting up target cluster', () => { + targetCluster.cleanProjects(planData.namespaceList) + }); + + } // login it('Login', () => { @@ -128,16 +142,16 @@ selectorTuple.forEach(($type) => { after('Validate Migration & clean resources', () => { if (['Storage class conversion', 'State migration'].indexOf(`${planData.migration_type}`) > -1) { - cy.exec(`"${configurationScript}" post_migration_verification_on_target ${planData.namespaceList} ${selectedCluster}`, {timeout: 100000}).then((result) => { - log(`'${migrationType}_post_migration_verification_on_target'`, result) - }); + // delete all the projects in the selected cluster + selectedCluster.cleanProjects(planData.namespaceList); + } else { - cy.exec(`"${configurationScript}" post_migration_verification_on_target ${planData.namespaceList} ${targetCluster}`, {timeout: 100000}).then((result) => { - log(`'${migrationType}_post_migration_verification_on_target'`, result) - }); - cy.exec(`"${configurationScript}" cleanup_source_cluster ${planData.namespaceList} ${sourceCluster}`, {timeout: 100000}).then((result) => { - log(`'${migrationType}_cleanup_source_cluster'`, result) - }); + // assert the application has successfully migrated + targetCluster.assertAppMigrated(planData.namespaceList) + + // delete all the projects in both clusters + targetCluster.cleanProjects(planData.namespaceList); + sourceCluster.cleanProjects(planData.namespaceList); } }); }); diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts new file mode 100644 index 0000000..3b61c54 --- /dev/null +++ b/cypress/utils/openshift.ts @@ -0,0 +1,114 @@ +// function login( +// urlEndpoint: string, +// username: string, +// password: string, +// failOnNonZeroExit: boolean = false +// ) { +// return function ( +// target: any, +// propertyKey: string, +// descriptor: PropertyDescriptor +// ) { +// cy.log("login") +// cy.exec( +// `oc login ${urlEndpoint} -u ${username} -p ${password} --insecure-skip-tls-verify`, +// { +// failOnNonZeroExit: failOnNonZeroExit, +// } +// ); +// }; +// } + +// todo: implement decorator to login automatically instead of calling the login in every method +export class Openshift { + urlEndpoint; + username; + password; + + + constructor(urlEndpoint, username, password) { + this.urlEndpoint = urlEndpoint; + this.username = username; + this.password = password; + } + + private login( + urlEndpoint: string, + username: string, + password: string, + failOnNonZeroExit: boolean = false + ) { + // todo: fix extra double quotation issue :/ + cy.log(`Logging in to ${urlEndpoint.indexOf('tgt') >= 0 ? 'target' : 'source'} cluster`) + cy.exec( + `oc login ${urlEndpoint} -u ${username} -p ${password} --insecure-skip-tls-verify`.replace("\"", "").replace("\"", ""), + { + failOnNonZeroExit: failOnNonZeroExit, + } + ); + } + + cleanProjects(namespaceList: [string]) { + this.login(this.urlEndpoint, this.username, this.password); + namespaceList.forEach((namespace) => { + this.deleteProject(namespace); + }); + } + + private deleteProject(namespace: string) { + cy.exec('oc get ns').then(result => { + if (result.stdout.indexOf(namespace) >= 0) { + cy.exec(`oc delete project ${namespace}`, {timeout: 10000}) + .then((result) => { + expect(result.stdout).to.contain(`\"${namespace}\" deleted`); + }) + .wait(10000); + } + }); + } + + private createProjects(namespaceList: [string], deployApp: boolean = true) { + namespaceList.forEach((namespace) => { + this.createProject(namespace); + if (deployApp) { + this.deployApp("django-psql-persistent", namespace); + } + }); + } + + private deployApp(app: string, namespace: string) { + cy.exec(`oc new-app -n ${namespace} ${app}`, {timeout: 10000}); + cy.wait(10000) + } + + assertAppMigrated(namespaceList: [string]) { + + this.login(this.urlEndpoint, this.username, this.password) + + namespaceList.forEach(namespace => { + cy + .wait(10000) + .exec(`curl "$(oc get routes -n ${namespace} | grep django | awk '{print $2}')"`) + .then(result => { + expect(result.stdout).to.contain('Welcome to your Django application on OpenShift'); + }); + }); + } + + setupCluster(namespaceList: [string]) { + this.login(this.urlEndpoint, this.username, this.password); + this.cleanProjects(namespaceList); + this.createProjects(namespaceList); + } + + deleteAllMigrationPlans() { + this.login(this.urlEndpoint, this.username, this.password); + cy.exec("oc delete migplan --all -n openshift-migration"); + cy.wait(10000) + } + + private createProject(namespace: string) { + cy.exec(`oc new-project ${namespace}`); + cy.wait(5000) + } +} diff --git a/cypress/utils/utils.ts b/cypress/utils/utils.ts index 70af149..e3f6e1e 100644 --- a/cypress/utils/utils.ts +++ b/cypress/utils/utils.ts @@ -123,4 +123,13 @@ export function generateRandomStringLowerCaseOnly(length: number) { export function generateRandomStringUpperCaseOnly(length: number) { return generateRandomString(length, "ABCDEFGHIJKLMOPQRSTUVWXYZ"); +} + +export function splitLoginString(clusterLoginString: string) { + return clusterLoginString + .replace('oc login ', '') + .replace('-u ', '') + .replace('-p ','') + .replace(' --insecure-skip-tls-verify','') + .split(' ') } \ No newline at end of file From 3d2d8da09945b5d5c8aebdc9dfc3df5466024743 Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 14:16:54 +0200 Subject: [PATCH 02/18] - increased waiting time after creating a new project --- cypress/utils/openshift.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index 3b61c54..fef244a 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -109,6 +109,6 @@ export class Openshift { private createProject(namespace: string) { cy.exec(`oc new-project ${namespace}`); - cy.wait(5000) + cy.wait(10000) } } From babeb2ce08c99dba7f4b2939e8f69ccdf3ee32bc Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 14:56:53 +0200 Subject: [PATCH 03/18] - log error --- cypress/utils/openshift.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index fef244a..18c5c0a 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -77,7 +77,11 @@ export class Openshift { } private deployApp(app: string, namespace: string) { - cy.exec(`oc new-app -n ${namespace} ${app}`, {timeout: 10000}); + cy.exec(`oc new-app -n ${namespace} ${app}`, {timeout: 10000}).then(result => { + if ( result.code != 0 ){ + cy.log(result.stderr) + } + }); cy.wait(10000) } From 76e81461a1eceacd4eaa8e3ebe9ef53909a43960 Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 15:40:42 +0200 Subject: [PATCH 04/18] - log deploy app errors --- cypress/utils/openshift.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index 18c5c0a..79f3c6d 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -78,9 +78,7 @@ export class Openshift { private deployApp(app: string, namespace: string) { cy.exec(`oc new-app -n ${namespace} ${app}`, {timeout: 10000}).then(result => { - if ( result.code != 0 ){ - cy.log(result.stderr) - } + cy.writeFile("deploy-app-error.txt", result.stderr) }); cy.wait(10000) } From cb2c27ecc190fee21d95373da62d10d48ae4846d Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 17:16:28 +0200 Subject: [PATCH 05/18] - 1 test --- cypress/integration/tests/sanity.test.ts | 36 ++++++++++++------------ cypress/utils/openshift.ts | 7 ++--- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/cypress/integration/tests/sanity.test.ts b/cypress/integration/tests/sanity.test.ts index c6729ee..e4022ef 100644 --- a/cypress/integration/tests/sanity.test.ts +++ b/cypress/integration/tests/sanity.test.ts @@ -31,24 +31,24 @@ let sourceCluster; const selectorTuple: [PlanData, string][] = [ [directImagePlanData, 'Direct image migration without copy verification'], - [directPvPlanData, 'Direct PV migration without copy verification'], - [verifyCopydirectPvPlan, 'Direct PV migration with copy verification'], - [noVerifyCopyPlanData, 'Indirect migration without copy verification'], - [verifyCopyPlanData, 'Direct migration with copy verification'], - [noVerifyCopyPlanData, 'Rollover indirect migration and then migrate'], - [directImagePvPlan, 'Rollover direct migration and then migrate'], - [indirectMultipleProjects, 'Indirect migration of multiple projects'], - [directMultipleProjects, 'direct migration of multiple projects'], - [changeTargetNamespace, 'Direct migration of a single project to non-default target namespace'], - [IndirectChangeTargetNamespace, 'Indirect migration of a single project to non-default target namespace'], - [directImagePvPlan, 'Direct image and PV migration'], - [InterclusterState, 'Inter cluster state migration plan'], - [storageClassConversionSource, 'Storage class conversion - Source cluster'], - [storageClassConversionTarget, 'Storage class conversion - Target cluster'], - [storageClassConversionSource, 'Storage class conversion - Source-Rollover'], - [storageClassConversionTarget, 'Storage class conversion - Target-Rollover'], - [IntraClusterStateSource, 'Intra cluster state migration - Source cluster'], - [IntraClusterStateTarget, 'Intra cluster state migration - Target cluster'] + // [directPvPlanData, 'Direct PV migration without copy verification'], + // [verifyCopydirectPvPlan, 'Direct PV migration with copy verification'], + // [noVerifyCopyPlanData, 'Indirect migration without copy verification'], + // [verifyCopyPlanData, 'Direct migration with copy verification'], + // [noVerifyCopyPlanData, 'Rollover indirect migration and then migrate'], + // [directImagePvPlan, 'Rollover direct migration and then migrate'], + // [indirectMultipleProjects, 'Indirect migration of multiple projects'], + // [directMultipleProjects, 'direct migration of multiple projects'], + // [changeTargetNamespace, 'Direct migration of a single project to non-default target namespace'], + // [IndirectChangeTargetNamespace, 'Indirect migration of a single project to non-default target namespace'], + // [directImagePvPlan, 'Direct image and PV migration'], + // [InterclusterState, 'Inter cluster state migration plan'], + // [storageClassConversionSource, 'Storage class conversion - Source cluster'], + // [storageClassConversionTarget, 'Storage class conversion - Target cluster'], + // [storageClassConversionSource, 'Storage class conversion - Source-Rollover'], + // [storageClassConversionTarget, 'Storage class conversion - Target-Rollover'], + // [IntraClusterStateSource, 'Intra cluster state migration - Source cluster'], + // [IntraClusterStateTarget, 'Intra cluster state migration - Target cluster'] ]; selectorTuple.forEach(($type) => { diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index 79f3c6d..204ea27 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -77,10 +77,9 @@ export class Openshift { } private deployApp(app: string, namespace: string) { - cy.exec(`oc new-app -n ${namespace} ${app}`, {timeout: 10000}).then(result => { - cy.writeFile("deploy-app-error.txt", result.stderr) - }); - cy.wait(10000) + cy + .exec(`oc new-app -n ${namespace} ${app}`, {timeout: 10000}) + .wait(10000); } assertAppMigrated(namespaceList: [string]) { From f819680479d7175903d108bf21515ebe8951d9a6 Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 17:48:38 +0200 Subject: [PATCH 06/18] - removed namespace from new-app command --- cypress/utils/openshift.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index 204ea27..b1bc729 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -70,15 +70,19 @@ export class Openshift { private createProjects(namespaceList: [string], deployApp: boolean = true) { namespaceList.forEach((namespace) => { this.createProject(namespace); - if (deployApp) { - this.deployApp("django-psql-persistent", namespace); - } + this.deployApp("django-psql-persistent"); }); } - private deployApp(app: string, namespace: string) { + private createProject(namespace: string) { + cy + .exec(`oc new-project ${namespace}`) + .wait(10000); + } + + private deployApp(app: string) { cy - .exec(`oc new-app -n ${namespace} ${app}`, {timeout: 10000}) + .exec(`oc new-app ${app}`, {timeout: 10000}) .wait(10000); } @@ -107,9 +111,4 @@ export class Openshift { cy.exec("oc delete migplan --all -n openshift-migration"); cy.wait(10000) } - - private createProject(namespace: string) { - cy.exec(`oc new-project ${namespace}`); - cy.wait(10000) - } } From d1f1c46f7cd4e962fc1810d056d499fadf1030f7 Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 18:00:12 +0200 Subject: [PATCH 07/18] - wait 1 minute before deploying app --- cypress/utils/openshift.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index b1bc729..534dccc 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -77,7 +77,7 @@ export class Openshift { private createProject(namespace: string) { cy .exec(`oc new-project ${namespace}`) - .wait(10000); + .wait(60000); } private deployApp(app: string) { From d2f0d7cea32fd1d94742396b0fc3078a4b64a134 Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 18:15:54 +0200 Subject: [PATCH 08/18] - ignore error when creating new namespace --- cypress.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cypress.json b/cypress.json index d40156d..1b11a78 100644 --- a/cypress.json +++ b/cypress.json @@ -5,10 +5,10 @@ "video": false, "env": { "user": "kubeadmin", - "pass": "best-password-ever", - "craneUrl": "https://migration-openshift-migration.apps.devcluster.openshift.com", - "sourceCluster": "https://api.cam-src.devcluster.openshift.com:6443 -u kubeadmin -p password", - "targetCluster": "https://api.cam.tgt.devcluster.openshift.com:6443 -u kubeadmin -p password" + "password": "IJxhS-VwHyA-YnMGy-MEM4B", + "craneUrl": "https://migration-openshift-migration.apps.cam-tgt-48070.qe.devcluster.openshift.com", + "sourceCluster": "\"oc login https://api.cam-src-48070.qe.devcluster.openshift.com:6443 -u kubeadmin -p eP2Ub-AVF62-V4rXh-uxVDM --insecure-skip-tls-verify\"", + "targetCluster": "\"oc login https://api.cam-tgt-48070.qe.devcluster.openshift.com:6443 -u kubeadmin -p IJxhS-VwHyA-YnMGy-MEM4B --insecure-skip-tls-verify\"" }, "reporter": "cypress-multi-reporters", "reporterOptions": { From 9feb4ddb4a375443f5e07c13e04ae8b191a05916 Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 18:42:28 +0200 Subject: [PATCH 09/18] - fail on login issue --- cypress/utils/openshift.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index 534dccc..bba53ee 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -20,6 +20,7 @@ // } // todo: implement decorator to login automatically instead of calling the login in every method + export class Openshift { urlEndpoint; username; @@ -43,7 +44,7 @@ export class Openshift { cy.exec( `oc login ${urlEndpoint} -u ${username} -p ${password} --insecure-skip-tls-verify`.replace("\"", "").replace("\"", ""), { - failOnNonZeroExit: failOnNonZeroExit, + failOnNonZeroExit: true, } ); } @@ -62,7 +63,7 @@ export class Openshift { .then((result) => { expect(result.stdout).to.contain(`\"${namespace}\" deleted`); }) - .wait(10000); + .wait(15000); } }); } @@ -76,7 +77,7 @@ export class Openshift { private createProject(namespace: string) { cy - .exec(`oc new-project ${namespace}`) + .exec(`oc new-project ${namespace}`, {failOnNonZeroExit: false}) .wait(60000); } From aee9072706c78142602f4f593240740df715114a Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 18:52:12 +0200 Subject: [PATCH 10/18] - remove extra white spaces --- cypress/utils/openshift.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index bba53ee..900bc70 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -42,7 +42,7 @@ export class Openshift { // todo: fix extra double quotation issue :/ cy.log(`Logging in to ${urlEndpoint.indexOf('tgt') >= 0 ? 'target' : 'source'} cluster`) cy.exec( - `oc login ${urlEndpoint} -u ${username} -p ${password} --insecure-skip-tls-verify`.replace("\"", "").replace("\"", ""), + `oc login ${urlEndpoint} -u ${username} -p ${password} --insecure-skip-tls-verify`.replace(/\s+/g, ' ').trim().replace("\"", "").replace("\"", ""), { failOnNonZeroExit: true, } From 15272bd5f2094b7fb103c9e3a25330ef43cd3aed Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 19:04:58 +0200 Subject: [PATCH 11/18] - fixed string split - reduced waiting time --- cypress/utils/openshift.ts | 6 +++--- cypress/utils/utils.ts | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index 900bc70..53a9a41 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -42,7 +42,7 @@ export class Openshift { // todo: fix extra double quotation issue :/ cy.log(`Logging in to ${urlEndpoint.indexOf('tgt') >= 0 ? 'target' : 'source'} cluster`) cy.exec( - `oc login ${urlEndpoint} -u ${username} -p ${password} --insecure-skip-tls-verify`.replace(/\s+/g, ' ').trim().replace("\"", "").replace("\"", ""), + `oc login ${urlEndpoint} -u ${username} -p ${password} --insecure-skip-tls-verify`.replace("\"", "").replace("\"", ""), { failOnNonZeroExit: true, } @@ -63,7 +63,7 @@ export class Openshift { .then((result) => { expect(result.stdout).to.contain(`\"${namespace}\" deleted`); }) - .wait(15000); + .wait(10000); } }); } @@ -78,7 +78,7 @@ export class Openshift { private createProject(namespace: string) { cy .exec(`oc new-project ${namespace}`, {failOnNonZeroExit: false}) - .wait(60000); + .wait(10000); } private deployApp(app: string) { diff --git a/cypress/utils/utils.ts b/cypress/utils/utils.ts index e3f6e1e..36c0f54 100644 --- a/cypress/utils/utils.ts +++ b/cypress/utils/utils.ts @@ -131,5 +131,7 @@ export function splitLoginString(clusterLoginString: string) { .replace('-u ', '') .replace('-p ','') .replace(' --insecure-skip-tls-verify','') + .replace(/\s+/g, ' ') + .trim() .split(' ') } \ No newline at end of file From fde9ba911b024c7f0d719e693a78d9322b98668e Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 19:21:08 +0200 Subject: [PATCH 12/18] - re-added all test cases - assert app migrated by checking code --- cypress/integration/tests/sanity.test.ts | 36 ++++++++++++------------ cypress/utils/openshift.ts | 7 +++-- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/cypress/integration/tests/sanity.test.ts b/cypress/integration/tests/sanity.test.ts index e4022ef..c6729ee 100644 --- a/cypress/integration/tests/sanity.test.ts +++ b/cypress/integration/tests/sanity.test.ts @@ -31,24 +31,24 @@ let sourceCluster; const selectorTuple: [PlanData, string][] = [ [directImagePlanData, 'Direct image migration without copy verification'], - // [directPvPlanData, 'Direct PV migration without copy verification'], - // [verifyCopydirectPvPlan, 'Direct PV migration with copy verification'], - // [noVerifyCopyPlanData, 'Indirect migration without copy verification'], - // [verifyCopyPlanData, 'Direct migration with copy verification'], - // [noVerifyCopyPlanData, 'Rollover indirect migration and then migrate'], - // [directImagePvPlan, 'Rollover direct migration and then migrate'], - // [indirectMultipleProjects, 'Indirect migration of multiple projects'], - // [directMultipleProjects, 'direct migration of multiple projects'], - // [changeTargetNamespace, 'Direct migration of a single project to non-default target namespace'], - // [IndirectChangeTargetNamespace, 'Indirect migration of a single project to non-default target namespace'], - // [directImagePvPlan, 'Direct image and PV migration'], - // [InterclusterState, 'Inter cluster state migration plan'], - // [storageClassConversionSource, 'Storage class conversion - Source cluster'], - // [storageClassConversionTarget, 'Storage class conversion - Target cluster'], - // [storageClassConversionSource, 'Storage class conversion - Source-Rollover'], - // [storageClassConversionTarget, 'Storage class conversion - Target-Rollover'], - // [IntraClusterStateSource, 'Intra cluster state migration - Source cluster'], - // [IntraClusterStateTarget, 'Intra cluster state migration - Target cluster'] + [directPvPlanData, 'Direct PV migration without copy verification'], + [verifyCopydirectPvPlan, 'Direct PV migration with copy verification'], + [noVerifyCopyPlanData, 'Indirect migration without copy verification'], + [verifyCopyPlanData, 'Direct migration with copy verification'], + [noVerifyCopyPlanData, 'Rollover indirect migration and then migrate'], + [directImagePvPlan, 'Rollover direct migration and then migrate'], + [indirectMultipleProjects, 'Indirect migration of multiple projects'], + [directMultipleProjects, 'direct migration of multiple projects'], + [changeTargetNamespace, 'Direct migration of a single project to non-default target namespace'], + [IndirectChangeTargetNamespace, 'Indirect migration of a single project to non-default target namespace'], + [directImagePvPlan, 'Direct image and PV migration'], + [InterclusterState, 'Inter cluster state migration plan'], + [storageClassConversionSource, 'Storage class conversion - Source cluster'], + [storageClassConversionTarget, 'Storage class conversion - Target cluster'], + [storageClassConversionSource, 'Storage class conversion - Source-Rollover'], + [storageClassConversionTarget, 'Storage class conversion - Target-Rollover'], + [IntraClusterStateSource, 'Intra cluster state migration - Source cluster'], + [IntraClusterStateTarget, 'Intra cluster state migration - Target cluster'] ]; selectorTuple.forEach(($type) => { diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index 53a9a41..0f62209 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -44,7 +44,7 @@ export class Openshift { cy.exec( `oc login ${urlEndpoint} -u ${username} -p ${password} --insecure-skip-tls-verify`.replace("\"", "").replace("\"", ""), { - failOnNonZeroExit: true, + failOnNonZeroExit: failOnNonZeroExit, } ); } @@ -68,7 +68,7 @@ export class Openshift { }); } - private createProjects(namespaceList: [string], deployApp: boolean = true) { + private createProjects(namespaceList: [string]) { namespaceList.forEach((namespace) => { this.createProject(namespace); this.deployApp("django-psql-persistent"); @@ -96,7 +96,8 @@ export class Openshift { .wait(10000) .exec(`curl "$(oc get routes -n ${namespace} | grep django | awk '{print $2}')"`) .then(result => { - expect(result.stdout).to.contain('Welcome to your Django application on OpenShift'); + expect(result.code).to.equal(0); + // expect(result.stdout).to.contain('Welcome to your Django application on OpenShift'); }); }); } From 441b952b95677361b4e86417845c83b58ed5cca4 Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 19:30:02 +0200 Subject: [PATCH 13/18] - re-added all test cases - assert app migrated by checking code --- cypress/integration/tests/sanity.test.ts | 36 ++++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/cypress/integration/tests/sanity.test.ts b/cypress/integration/tests/sanity.test.ts index c6729ee..e4022ef 100644 --- a/cypress/integration/tests/sanity.test.ts +++ b/cypress/integration/tests/sanity.test.ts @@ -31,24 +31,24 @@ let sourceCluster; const selectorTuple: [PlanData, string][] = [ [directImagePlanData, 'Direct image migration without copy verification'], - [directPvPlanData, 'Direct PV migration without copy verification'], - [verifyCopydirectPvPlan, 'Direct PV migration with copy verification'], - [noVerifyCopyPlanData, 'Indirect migration without copy verification'], - [verifyCopyPlanData, 'Direct migration with copy verification'], - [noVerifyCopyPlanData, 'Rollover indirect migration and then migrate'], - [directImagePvPlan, 'Rollover direct migration and then migrate'], - [indirectMultipleProjects, 'Indirect migration of multiple projects'], - [directMultipleProjects, 'direct migration of multiple projects'], - [changeTargetNamespace, 'Direct migration of a single project to non-default target namespace'], - [IndirectChangeTargetNamespace, 'Indirect migration of a single project to non-default target namespace'], - [directImagePvPlan, 'Direct image and PV migration'], - [InterclusterState, 'Inter cluster state migration plan'], - [storageClassConversionSource, 'Storage class conversion - Source cluster'], - [storageClassConversionTarget, 'Storage class conversion - Target cluster'], - [storageClassConversionSource, 'Storage class conversion - Source-Rollover'], - [storageClassConversionTarget, 'Storage class conversion - Target-Rollover'], - [IntraClusterStateSource, 'Intra cluster state migration - Source cluster'], - [IntraClusterStateTarget, 'Intra cluster state migration - Target cluster'] + // [directPvPlanData, 'Direct PV migration without copy verification'], + // [verifyCopydirectPvPlan, 'Direct PV migration with copy verification'], + // [noVerifyCopyPlanData, 'Indirect migration without copy verification'], + // [verifyCopyPlanData, 'Direct migration with copy verification'], + // [noVerifyCopyPlanData, 'Rollover indirect migration and then migrate'], + // [directImagePvPlan, 'Rollover direct migration and then migrate'], + // [indirectMultipleProjects, 'Indirect migration of multiple projects'], + // [directMultipleProjects, 'direct migration of multiple projects'], + // [changeTargetNamespace, 'Direct migration of a single project to non-default target namespace'], + // [IndirectChangeTargetNamespace, 'Indirect migration of a single project to non-default target namespace'], + // [directImagePvPlan, 'Direct image and PV migration'], + // [InterclusterState, 'Inter cluster state migration plan'], + // [storageClassConversionSource, 'Storage class conversion - Source cluster'], + // [storageClassConversionTarget, 'Storage class conversion - Target cluster'], + // [storageClassConversionSource, 'Storage class conversion - Source-Rollover'], + // [storageClassConversionTarget, 'Storage class conversion - Target-Rollover'], + // [IntraClusterStateSource, 'Intra cluster state migration - Source cluster'], + // [IntraClusterStateTarget, 'Intra cluster state migration - Target cluster'] ]; selectorTuple.forEach(($type) => { From 07404dc63af26fe814c8e361547edcd96317f259 Mon Sep 17 00:00:00 2001 From: midays Date: Wed, 30 Nov 2022 19:40:57 +0200 Subject: [PATCH 14/18] - re-added all test cases - assert app migrated by checking code --- cypress/integration/tests/sanity.test.ts | 36 ++++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/cypress/integration/tests/sanity.test.ts b/cypress/integration/tests/sanity.test.ts index e4022ef..c6729ee 100644 --- a/cypress/integration/tests/sanity.test.ts +++ b/cypress/integration/tests/sanity.test.ts @@ -31,24 +31,24 @@ let sourceCluster; const selectorTuple: [PlanData, string][] = [ [directImagePlanData, 'Direct image migration without copy verification'], - // [directPvPlanData, 'Direct PV migration without copy verification'], - // [verifyCopydirectPvPlan, 'Direct PV migration with copy verification'], - // [noVerifyCopyPlanData, 'Indirect migration without copy verification'], - // [verifyCopyPlanData, 'Direct migration with copy verification'], - // [noVerifyCopyPlanData, 'Rollover indirect migration and then migrate'], - // [directImagePvPlan, 'Rollover direct migration and then migrate'], - // [indirectMultipleProjects, 'Indirect migration of multiple projects'], - // [directMultipleProjects, 'direct migration of multiple projects'], - // [changeTargetNamespace, 'Direct migration of a single project to non-default target namespace'], - // [IndirectChangeTargetNamespace, 'Indirect migration of a single project to non-default target namespace'], - // [directImagePvPlan, 'Direct image and PV migration'], - // [InterclusterState, 'Inter cluster state migration plan'], - // [storageClassConversionSource, 'Storage class conversion - Source cluster'], - // [storageClassConversionTarget, 'Storage class conversion - Target cluster'], - // [storageClassConversionSource, 'Storage class conversion - Source-Rollover'], - // [storageClassConversionTarget, 'Storage class conversion - Target-Rollover'], - // [IntraClusterStateSource, 'Intra cluster state migration - Source cluster'], - // [IntraClusterStateTarget, 'Intra cluster state migration - Target cluster'] + [directPvPlanData, 'Direct PV migration without copy verification'], + [verifyCopydirectPvPlan, 'Direct PV migration with copy verification'], + [noVerifyCopyPlanData, 'Indirect migration without copy verification'], + [verifyCopyPlanData, 'Direct migration with copy verification'], + [noVerifyCopyPlanData, 'Rollover indirect migration and then migrate'], + [directImagePvPlan, 'Rollover direct migration and then migrate'], + [indirectMultipleProjects, 'Indirect migration of multiple projects'], + [directMultipleProjects, 'direct migration of multiple projects'], + [changeTargetNamespace, 'Direct migration of a single project to non-default target namespace'], + [IndirectChangeTargetNamespace, 'Indirect migration of a single project to non-default target namespace'], + [directImagePvPlan, 'Direct image and PV migration'], + [InterclusterState, 'Inter cluster state migration plan'], + [storageClassConversionSource, 'Storage class conversion - Source cluster'], + [storageClassConversionTarget, 'Storage class conversion - Target cluster'], + [storageClassConversionSource, 'Storage class conversion - Source-Rollover'], + [storageClassConversionTarget, 'Storage class conversion - Target-Rollover'], + [IntraClusterStateSource, 'Intra cluster state migration - Source cluster'], + [IntraClusterStateTarget, 'Intra cluster state migration - Target cluster'] ]; selectorTuple.forEach(($type) => { From 185b501c0ff13a847e7ac0779616dbab6ca2d923 Mon Sep 17 00:00:00 2001 From: midays Date: Thu, 1 Dec 2022 14:39:38 +0200 Subject: [PATCH 15/18] - instead of waiting 30 minutes when a test fails, it directly reports the failure --- cypress/integration/models/plan.ts | 13 ++++++++++--- cypress/integration/tests/sanity.test.ts | 10 ++++++---- cypress/utils/openshift.ts | 4 ++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/cypress/integration/models/plan.ts b/cypress/integration/models/plan.ts index dbfbcfd..9ae40c9 100644 --- a/cypress/integration/models/plan.ts +++ b/cypress/integration/models/plan.ts @@ -132,13 +132,20 @@ export class Plan { } protected waitForSuccess(name: string): void { + const statuses = ['Migration succeeded','Cutover failed','Completed with warnings'] + const regex = new RegExp(`${statuses.join('|')}`, 'g') + cy.get('th') .contains(name, {timeout: 10000}) .closest('tr') .within(() => { - // todo: find a way to skip timeout from 30 minutes when a migration fails - // !cy.get(dataLabel.status).contains('Cutover failed', {timeout: 1900000}) - cy.get(dataLabel.status).contains('Migration succeeded', {timeout: 1900000}); + cy + .get(dataLabel.status) + .contains(regex, {timeout: 1900000}) + .invoke('attr', 'value') + .then(text => { + expect(text).to.equal('Migration succeeded') + }) }); } diff --git a/cypress/integration/tests/sanity.test.ts b/cypress/integration/tests/sanity.test.ts index c6729ee..c852463 100644 --- a/cypress/integration/tests/sanity.test.ts +++ b/cypress/integration/tests/sanity.test.ts @@ -65,8 +65,10 @@ selectorTuple.forEach(($type) => { const targetValues = splitLoginString(targetClusterString); // initiate source and target clusters objects from Openshift object - sourceCluster = new Openshift(sourceValues[0], sourceValues[1], sourceValues[2]) - targetCluster = new Openshift(targetValues[0], targetValues[1], targetValues[2]) + sourceCluster = new Openshift(sourceValues[0], sourceValues[1], sourceValues[2]); + targetCluster = new Openshift(targetValues[0], targetValues[1], targetValues[2]); + + (`${planData.source}` == 'source-cluster') ? selectedCluster = sourceCluster : selectedCluster = targetCluster; // clean all the migration plans before starting targetCluster.deleteAllMigrationPlans() @@ -76,7 +78,6 @@ selectorTuple.forEach(($type) => { // if this is a state migraiton or scc, then check there are more than 1 sc available, if not, then skip the test if (['Storage class conversion', 'State migration'].indexOf(`${planData.migration_type}`) > -1) { - (`${planData.source}` == 'source-cluster') ? selectedCluster = sourceCluster : selectedCluster = targetCluster; before('Check SC', () => { // todo: create a method in the Openshit object to get the storage class count @@ -88,7 +89,7 @@ selectorTuple.forEach(($type) => { } }); - it(`Setting up ${( planData.source == 'host' ) ? 'target' : 'source'} cluster`, () => { + it(`Setting up ${(planData.source == 'host') ? 'target' : 'source'} cluster`, () => { selectedCluster.setupCluster(planData.namespaceList); }); @@ -147,6 +148,7 @@ selectorTuple.forEach(($type) => { } else { // assert the application has successfully migrated + // todo: if the migration fails the following step should be skipped targetCluster.assertAppMigrated(planData.namespaceList) // delete all the projects in both clusters diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index 0f62209..7765e64 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -59,7 +59,7 @@ export class Openshift { private deleteProject(namespace: string) { cy.exec('oc get ns').then(result => { if (result.stdout.indexOf(namespace) >= 0) { - cy.exec(`oc delete project ${namespace}`, {timeout: 10000}) + cy.exec(`oc delete project ${namespace}`, {timeout: 60000}) .then((result) => { expect(result.stdout).to.contain(`\"${namespace}\" deleted`); }) @@ -83,7 +83,7 @@ export class Openshift { private deployApp(app: string) { cy - .exec(`oc new-app ${app}`, {timeout: 10000}) + .exec(`oc new-app ${app}`, {timeout: 60000}) .wait(10000); } From 36929c9eb27e06e48681f922e861d52fae34c237 Mon Sep 17 00:00:00 2001 From: midays Date: Mon, 5 Dec 2022 15:22:32 +0200 Subject: [PATCH 16/18] - tweaks --- cypress/integration/models/repo.ts | 2 +- cypress/integration/tests/cluster_config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress/integration/models/repo.ts b/cypress/integration/models/repo.ts index b190521..82f4743 100644 --- a/cypress/integration/models/repo.ts +++ b/cypress/integration/models/repo.ts @@ -1,4 +1,4 @@ -import { clickByText, inputText, openSidebarMenu } from '../../utils/utils'; +import { clickByText, inputText } from '../../utils/utils'; import { navMenuPoint } from '../views/menu.view'; import { RepoData } from '../types/types'; import { storageProvider, repoName, bucketName, bucketRegion, providerKey, providerSecret, dataLabel} from '../views/repo.view'; diff --git a/cypress/integration/tests/cluster_config.ts b/cypress/integration/tests/cluster_config.ts index 272bb39..3edc730 100644 --- a/cypress/integration/tests/cluster_config.ts +++ b/cypress/integration/tests/cluster_config.ts @@ -120,7 +120,7 @@ export const IndirectChangeTargetNamespace: PlanData = { source: 'source-cluster', target: 'host', repo: 'automatic', - namespaceList: ['indirect-migration-with-nondefault-target'], + namespaceList: ['indirect-nondefault-target'], directImageMigration : false, directPvmigration : false, nondefaultTargetNamespace : true, From 5731d7d25e532f83abd4ba93e17e0bd0acfe9c14 Mon Sep 17 00:00:00 2001 From: midays Date: Tue, 6 Dec 2022 14:13:01 +0200 Subject: [PATCH 17/18] - added check for jquery element --- cypress/integration/models/plan.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cypress/integration/models/plan.ts b/cypress/integration/models/plan.ts index 9ae40c9..e69adc8 100644 --- a/cypress/integration/models/plan.ts +++ b/cypress/integration/models/plan.ts @@ -142,9 +142,8 @@ export class Plan { cy .get(dataLabel.status) .contains(regex, {timeout: 1900000}) - .invoke('attr', 'value') - .then(text => { - expect(text).to.equal('Migration succeeded') + .then($a => { + expect($a.text()).to.equal('Migration succeeded') }) }); } From dbe48d429531a8ab1570c7de927b375ff1024a39 Mon Sep 17 00:00:00 2001 From: midays Date: Sun, 18 Dec 2022 15:04:03 +0200 Subject: [PATCH 18/18] - test push --- cypress/utils/openshift.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/utils/openshift.ts b/cypress/utils/openshift.ts index 7765e64..b480627 100644 --- a/cypress/utils/openshift.ts +++ b/cypress/utils/openshift.ts @@ -20,7 +20,7 @@ // } // todo: implement decorator to login automatically instead of calling the login in every method - +// test oush export class Openshift { urlEndpoint; username;