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

Add E2E tests for Installation flow #4803

Merged
merged 1 commit into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
STORAGE_CLASS_PATTERNS,
STORAGE_CLUSTER_NAME,
SECOND,
SUCCESS,
} from '../../utils/consts';
import {
InstallCluster,
Expand Down Expand Up @@ -40,7 +41,7 @@ describe('Testing OCS Subscription', () => {
async () => {
await Installer.subscribeToOperator();
const text = await ocsOperatorStatus.getText();
expect(text.includes('Succeeded')).toBe(true);
expect(text.includes(SUCCESS)).toBe(true);
},
3 * MINUTE,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { execSync } from 'child_process';
import { browser, ExpectedConditions as until } from 'protractor';
import * as crudView from '@console/internal-integration-tests/views/crud.view';
import { click } from '@console/shared/src/test-utils/utils';
import {
MINUTE,
SECOND,
NS,
OCS_NODE_LABEL,
STORAGE_CLUSTER_NAME,
CATALOG_SRC,
} from '../../utils/consts';
import {
selectWorkerRows,
InstallCluster,
ocsOperator,
createLink,
sizeDropdown,
optionSmallSize,
primaryButton,
} from '../../views/installFlow.view';
import { getStorageClusterLink } from '../../views/add-capacity.view';
import { hasTaints, hasOCSTaint, refreshIfNotVisible } from '../../utils/helpers';

const Installer = new InstallCluster(NS);

const testNodeLabel = (node) => {
const nodeJSON = JSON.parse(execSync(`kubectl get nodes ${node} -o json`).toString());
const labelKeys = Object.keys(nodeJSON.metadata.labels);
expect(labelKeys).toContain(OCS_NODE_LABEL);
expect(hasOCSTaint(nodeJSON) || !hasTaints(nodeJSON)).toBe(true);
};

describe('Testing OCS Cluster Creation', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
describe('Testing OCS Cluster Creation', () => {
describe('Testing OpenShift Container Storage Installation, () => {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are testing cluster creation there are e2e-tests for operators-hub that test installation of an operator.

beforeAll(async () => {
await Installer.createNamespace();
expect(browser.getCurrentUrl()).toContain(NS);
await Installer.subscribeToOperator(CATALOG_SRC);
await click(ocsOperator);
await browser.wait(until.and(crudView.untilNoLoadersPresent));
// This can fail in a fresh cluster
try {
await browser.wait(until.visibilityOf(createLink), 10 * SECOND);
} catch {
await refreshIfNotVisible(createLink, 5);
}
const storageClusterLink = await getStorageClusterLink();
await click(storageClusterLink);
}, 3 * MINUTE);

it(
'Test Storage Cluster Creation',
async () => {
await browser.wait(until.and(crudView.untilNoLoadersPresent));
// Node list fluctuates
await browser.sleep(5 * SECOND);
const nodes = await selectWorkerRows();
bipuladh marked this conversation as resolved.
Show resolved Hide resolved
await click(sizeDropdown);
await click(optionSmallSize);
await browser.wait(until.elementToBeClickable(primaryButton));
await click(primaryButton);
await browser.wait(until.and(crudView.untilNoLoadersPresent));
// eslint-disable-next-line no-useless-escape
const defaultSC = execSync(`kubectl get storageclasses | grep -Po '\\w+(?=.*default)'`)
.toString()
.trim();
const storageCR = JSON.parse(
execSync(`kubectl get storageclusters ${STORAGE_CLUSTER_NAME} -n ${NS} -o json`).toString(),
);
const scFromYAML =
storageCR?.spec?.storageDeviceSets?.[0]?.dataPVCTemplate?.spec?.storageClassName;
const size =
storageCR?.spec?.storageDeviceSets?.[0]?.dataPVCTemplate?.spec?.resources?.requests
?.storage;
expect(defaultSC).toEqual(scFromYAML);
// Tests for storage class
expect(size).toEqual('512Gi');
nodes.forEach((node, i) => testNodeLabel(nodes[i]));
},
5 * MINUTE,
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ export const NS = 'openshift-storage';
export const SECOND = 1000;
export const MINUTE = 60 * SECOND;

export const STORAGE_CLUSTER_NAME = 'ocs-storagecluster';

export enum POD_NAME_PATTERNS {
OCS = 'ocs-operator-',
ROOK = 'rook-ceph-operator-',
Expand Down Expand Up @@ -33,16 +31,26 @@ export enum CLUSTER_STATUS {
}

export const OCS_NODE_LABEL = 'cluster.ocs.openshift.io/openshift-storage';
export const CATALOG_SRC = 'redhat-operators';

export const KIND = 'storagecluster';
export const EXPAND_WAIT = 15 * MINUTE;
export const CAPACITY_UNIT = 'TiB';
export const CAPACITY_VALUE = '2';
export const OCS_OPERATOR_NAME = 'ocs-operator';
export const OCS_OPERATOR_NAME = 'ocs-operatorv4';
bipuladh marked this conversation as resolved.
Show resolved Hide resolved
export const STORAGE_CLUSTER_NAME = 'ocs-storagecluster';
export const HOST = 'host';
export const ZONE = 'zone';
export const OSD = 'osd';

export const SUCCESS = 'Succeeded';

export const ocsTaint = Object.freeze({
key: 'node.ocs.openshift.io/storage',
value: 'true',
effect: 'NoSchedule',
});

export enum VOLUME_ACCESS_MODES {
RWO = 'ReadWriteOnce',
RWX = 'ReadWriteMany',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { execSync } from 'child_process';
import * as crudView from '@console/internal-integration-tests/views/crud.view';
import { ExpectedConditions as until, browser, $ } from 'protractor';
import * as _ from 'lodash';
import { OSD, POD_NAME_PATTERNS, SECOND } from './consts';
import { ExpectedConditions as until, browser, $ } from 'protractor';
import * as crudView from '@console/internal-integration-tests/views/crud.view';
import { OSD, POD_NAME_PATTERNS, SECOND, ocsTaint } from './consts';

export const checkIfClusterIsReady = async () => {
let stillLoading = true;
Expand Down Expand Up @@ -159,6 +159,15 @@ export const verifyNodeOSDMapping = (
return filteredOsds.length === 0;
};

export const hasTaints = (node) => {
return !_.isEmpty(node.spec?.taints);
};

export const hasOCSTaint = (node) => {
const taints = node?.spec?.taints || [];
return taints.some((taint) => _.isEqual(taint, ocsTaint));
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you have defined the functions again here? You can reuse the function from node-list.tsx

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't pull that code into e2e tests and vice versa,


export type NodeType = {
id: number;
name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { namespaceDropdown, openshiftStorageItem } from './installFlow.view';
export const ocsOp = $(`a[data-test-operator-row='${OCS_OP}']`);
export const getStorageClusterLink = async () => {
const index = await getOperatorHubCardIndex('Storage Cluster');
const link = $(`article:nth-child(${index}) a`);
const link = $(`article:nth-child(${index + 1}) a`);
return link;
};
export const actionForLabel = (label: string) => $(`button[data-test-action='${label}']`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@ import { appHost } from '@console/internal-integration-tests/protractor.conf';
import { MINUTE, NS, OCS_OP, SECOND, OCS_OPERATOR_NAME } from '../utils/consts';
import { waitFor, refreshIfNotVisible } from '../utils/helpers';

// Primary Create Button
export const primaryButton = $('.pf-m-primary');

// Operator Hub & Installed Operators
const ocsOperator = $('.co-clusterserviceversion-logo__name__clusterserviceversion');
export const ocsOperator = $('a[data-test-operator-row="OpenShift Container Storage"]');
export const ocsOperatorStatus = $('.co-clusterserviceversion-row__status');
const installOperator = $('.pf-m-primary');
export const createLink = $('.pf-c-card__footer a');
export const searchInputOperators = $('input[placeholder="Filter by name..."]');
const searchInputOperatorHub = $('input[placeholder="Filter by keyword..."]');
const searchInputOperators = $('input[placeholder="Filter by name..."]');

// Subscription Page
const subscribeButton = $('.pf-m-primary');
const dropdownForNamespace = $('#dropdown-selectbox');
const customNamespaceRadio = $('input[value="OwnNamespace"]');
const selectNamespace = (namespace: string) => $(`#${namespace}-Project-link`);
const statuses = $$('.co-icon-and-text');
const status = statuses.get(0);

// Create storage cluster page
const btnCreate = $('.pf-m-primary');
const selectAllBtn = $('[aria-label="Select all rows"]');
const live = process.env.OCS_LIVE;
let CATALOG_SRC = 'ocs-catalogsource';
Expand All @@ -35,6 +36,10 @@ const ocsLink = (elem, catalogSource) =>
export const namespaceDropdown = $('.co-namespace-selector button');
export const openshiftStorageItem = $('#openshift-storage-link');

// Size Dropdown
export const sizeDropdown = $('button[id="ocs-service-capacity-dropdown"]');
export const optionSmallSize = $('button[id="512Gi-link"]');

// Namespace
const labelValue = 'true';
const label = `openshift.io/cluster-monitoring=${labelValue}`;
Expand All @@ -50,10 +55,10 @@ export const goToOperatorHub = async () => {
await browser.wait(until.and(crudView.untilNoLoadersPresent));
};

export const searchInOperatorHub = async (searchParam) => {
export const searchInOperatorHub = async (searchParam, catalogSource) => {
await browser.wait(until.visibilityOf(searchInputOperatorHub));
await searchInputOperatorHub.sendKeys(searchParam);
const ocs = await ocsLink(OCS_NAME, CATALOG_SRC);
const ocs = await ocsLink(OCS_NAME, catalogSource);
await browser.wait(until.visibilityOf(ocs));
return ocs;
};
Expand All @@ -74,6 +79,7 @@ export const selectWorkerRows = async () => {
// Wait for 3 inputs to show up
const selectedNodes = [];
await browser.wait(until.presenceOf($('[data-label="Role"]')), 10000);
await browser.sleep(5 * SECOND);
expect(await browser.wait($$('tbody tr').count())).toBeGreaterThanOrEqual(3);
const isAllSeleted = await selectAllBtn.isSelected();
if (isAllSeleted === true) await selectAllBtn.click();
Expand Down Expand Up @@ -106,6 +112,7 @@ export const selectWorkerRows = async () => {
);
}
}
await browser.sleep(SECOND);
});
return selectedNodes;
};
Expand All @@ -123,12 +130,12 @@ export class InstallCluster {
this.namespace = namespace;
}

async subscribeToOperator() {
async subscribeToOperator(catalogSource = CATALOG_SRC) {
await goToOperatorHub();
const ocsOp = await searchInOperatorHub(OCS_OP);
const ocsOp = await searchInOperatorHub(OCS_OP, catalogSource);
await click(ocsOp);
await browser.sleep(2 * SECOND);
await click(installOperator);
await click(primaryButton);
await browser.refresh();
await this.installOperator();
await browser.wait(until.visibilityOf(ocsOperator));
Expand All @@ -146,7 +153,7 @@ export class InstallCluster {
await dropdownForNamespace.click();
const nsTag = selectNamespace(this.namespace);
await nsTag.click();
await subscribeButton.click();
await primaryButton.click();
await browser.wait(until.and(crudView.untilNoLoadersPresent));
await browser.wait(until.visibilityOf(searchInputOperators));
await searchInputOperators.sendKeys(OCS_OPERATOR_NAME);
Expand All @@ -168,8 +175,7 @@ export class InstallCluster {
const nodes = await selectWorkerRows();
// Fluctating
await browser.sleep(5 * SECOND);
await browser.wait(until.elementToBeClickable(btnCreate));
await click(btnCreate);
await click(primaryButton);
// Let it move to the other page
await browser.sleep(1000);
await browser.wait(until.visibilityOf(status));
Expand Down
3 changes: 3 additions & 0 deletions frontend/packages/ceph-storage-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
],
"ceph-storage": [
"integration-tests/**/*.scenario.ts"
],
"e2e": [
bipuladh marked this conversation as resolved.
Show resolved Hide resolved
"integration-tests/tests/ocp-tests/*.scenario.ts"
]
}
}
Expand Down