Skip to content
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

drop configuration usage for sanity.test.ts #52

Open
wants to merge 19 commits into
base: v1.7
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cypress.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
12 changes: 9 additions & 3 deletions cypress/integration/models/plan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,19 @@ 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})
.then($a => {
expect($a.text()).to.equal('Migration succeeded')
})
});
}

Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/models/repo.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/tests/cluster_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
82 changes: 49 additions & 33 deletions cypress/integration/tests/sanity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand Down Expand Up @@ -56,39 +58,52 @@ 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]);

(`${planData.source}` == 'source-cluster') ? selectedCluster = sourceCluster : selectedCluster = targetCluster;

// 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;

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', () => {
Expand Down Expand Up @@ -128,16 +143,17 @@ 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
// todo: if the migration fails the following step should be skipped
targetCluster.assertAppMigrated(planData.namespaceList)

// delete all the projects in both clusters
targetCluster.cleanProjects(planData.namespaceList);
sourceCluster.cleanProjects(planData.namespaceList);
}
});
});
Expand Down
116 changes: 116 additions & 0 deletions cypress/utils/openshift.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// 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
// test oush
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: 60000})
.then((result) => {
expect(result.stdout).to.contain(`\"${namespace}\" deleted`);
})
.wait(10000);
}
});
}

private createProjects(namespaceList: [string]) {
namespaceList.forEach((namespace) => {
this.createProject(namespace);
this.deployApp("django-psql-persistent");
});
}

private createProject(namespace: string) {
cy
.exec(`oc new-project ${namespace}`, {failOnNonZeroExit: false})
.wait(10000);
}

private deployApp(app: string) {
cy
.exec(`oc new-app ${app}`, {timeout: 60000})
.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.code).to.equal(0);
// 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)
}
}
11 changes: 11 additions & 0 deletions cypress/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,15 @@ 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','')
.replace(/\s+/g, ' ')
.trim()
.split(' ')
}