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

Bug 1896101: Added negative tests for migration from VMWare and RHV #6249

Merged
merged 1 commit into from
Nov 10, 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 @@ -4,12 +4,13 @@ import {
getSelectedOptionText,
getSelectOptions,
selectItemFromDropdown,
checkForError,
} from '../utils/utils';
import * as view from '../../views/dialogs/diskDialog.view';
import { modalSubmitButton, saveButton } from '../../views/kubevirtUIResource.view';
import { Disk, DiskSourceConfig } from '../types/types';
import { diskAccessMode, DISK_SOURCE } from '../utils/constants/vm';
import { waitForNoLoaders, modalCancelButton } from '../../views/wizard.view';
import { waitForNoLoaders, modalCancelButton, errorHelper } from '../../views/wizard.view';
import { browser, ExpectedConditions as until, $ } from 'protractor';

export class DiskDialog {
Expand Down Expand Up @@ -39,6 +40,7 @@ export class DiskDialog {

async fillName(name: string) {
await fillInput(view.diskName, name);
return checkForError(errorHelper);
}

async fillSize(size: string) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { click, fillInput } from '@console/shared/src/test-utils/utils';
import * as view from '../../views/dialogs/networkInterface.view';
import { selectOptionByText, getSelectOptions, selectItemFromDropdown } from '../utils/utils';
import {
selectOptionByText,
getSelectOptions,
selectItemFromDropdown,
checkForError,
} from '../utils/utils';
import { Network } from '../types/types';
import { modalSubmitButton, saveButton } from '../../views/kubevirtUIResource.view';
import { waitForNoLoaders } from '../../views/wizard.view';
import * as wizardView from '../../views/importWizard.view';

export class NetworkInterfaceDialog {
async fillName(name: string) {
await fillInput(view.nicName, name);
return checkForError(wizardView.errorHelper);
}

async selectModel(model: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,13 @@ export const datavolumeClonerClusterRole = {
],
};
deepFreeze(datavolumeClonerClusterRole);

export const v2vUIDeployment = {
apiVersion: 'apps/v1',
kind: 'Deployment',
metadata: {
name: `v2v-vmware`,
namespace: testName,
},
};
deepFreeze(v2vUIDeployment);
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ import { click, asyncForEach } from '@console/shared/src/test-utils/utils';
import { NetworkInterfaceDialog } from '../dialogs/networkInterfaceDialog';
import { DiskDialog } from '../dialogs/diskDialog';
import { tableRows, saveButton } from '../../views/kubevirtUIResource.view';
import { selectOptionByText } from '../utils/utils';
import { STORAGE_CLASS, VIRTUALIZATION_TITLE } from '../utils/constants/common';
import { checkForError, getSelectOptions, selectOptionByText } from '../utils/utils';
import {
IMPORT_WIZARD_CONN_NAME_PREFIX,
KEBAP_ACTION,
STORAGE_CLASS,
VIRTUALIZATION_TITLE,
VOLUME_MODE,
} from '../utils/constants/common';
import * as view from '../../views/importWizard.view';
import { waitForNoLoaders, clickKebabAction } from '../../views/wizard.view';
import { Wizard } from './wizard';
Expand All @@ -16,6 +22,7 @@ import { clickNavLink } from '@console/internal-integration-tests/views/sidenav.
import { resourceHorizontalTab } from '../../views/uiResource.view';
import { VirtualMachineTemplateModel, Network, Disk } from '../types/types';
import { networkTabCol } from '../utils/constants/vm';
import * as rhvView from '../../views/rhvImportWizard.view';

export class ImportWizard extends Wizard {
async openWizard(model: K8sKind) {
Expand All @@ -40,60 +47,97 @@ export class ImportWizard extends Wizard {
}

async confirmAndCreate() {
await click(view.importButon);
await click(view.importButton);
}

async selectInstanceByPrefixName(selector: any) {
const instanceFullName = (await getSelectOptions(selector)).find((option) =>
option.startsWith(IMPORT_WIZARD_CONN_NAME_PREFIX),
);
await selectOptionByText(selector, instanceFullName);
await this.waitForSpinner();
}

/**
* Edits attributes of a NICs that are being imported from source VM.
*/
async updateImportedNICs() {
async updateNic(nic: Network) {
const nicDialog = new NetworkInterfaceDialog();
await clickKebabAction(nic.name, KEBAP_ACTION.Edit);
await waitForNoLoaders();
const networks = await nicDialog.getNetworks();
if (networks.length > 0) {
await nicDialog.selectNetwork(networks[networks.length - 1]);
const err = await checkForError(view.errorHelper);
if (err) {
return err;
}
} else {
throw Error('No available networks to assign imported NICs');
}
await click(view.confirmActionButton);
await waitForNoLoaders();
return null;
}

async getImportedNics() {
const rows = await tableRows();
let importedNICs = rows.map((line) => {
const cols = line.split(/\t/);
return rows.map((line) => {
const cols = line.split(/\n/);
return {
name: cols[networkTabCol.name],
};
});
}

async updateImportedNICs() {
const importedNICs = await this.getImportedNics();
// TODO: This is horrible, but unfortunately no better way to dynamically extract only device names
// without using ElementArrayFinder, which on the other hand may cause NoStaleElement Exceptions
importedNICs = importedNICs.filter((_, i) => i % 3 === 0);

const NICDialog = new NetworkInterfaceDialog();
await asyncForEach(importedNICs, async (NIC) => {
await clickKebabAction(NIC.name, 'Edit');
await waitForNoLoaders();
const networks = await NICDialog.getNetworks();
if (networks.length > 0) {
await NICDialog.selectNetwork(networks[networks.length - 1]);
} else {
throw Error('No available networks to assign imported NICs');
}
await click(view.confirmActionButton);
await waitForNoLoaders();
// importedNICs = importedNICs.filter((_, i) => i % 11 === 0);
await asyncForEach(importedNICs, async (nic) => {
return this.updateNic(nic);
});
}

/**
* Edits attributes of Disks that are being imported from source VM.
*/
async updateImportedDisks() {

async updateDisk(disk: Disk) {
const diskDialog = new DiskDialog();
await clickKebabAction(disk.name, KEBAP_ACTION.Edit);
await waitForNoLoaders();
await diskDialog.selectStorageClass(STORAGE_CLASS);
// Configures volume mode if customized (block or filesystem)
if (VOLUME_MODE) {
await diskDialog.openAdvancedSettingsDrawer();
await diskDialog.selectVolumeMode(VOLUME_MODE);
}
const err = await checkForError(view.errorHelper);
if (err) {
return err;
}
await click(saveButton);
await waitForNoLoaders();
return null;
}

async getImportedDisks() {
const rows = await tableRows();
let importedDisks = rows.map((line) => {
const cols = line.split(/\t/);
return rows.map((line) => {
const cols = line.split(/\n/);
return {
name: cols[networkTabCol.name],
storageClass: STORAGE_CLASS,
};
});
importedDisks = importedDisks.filter((_, i) => i % 3 === 0);
}

const diskDialog = new DiskDialog();
async updateImportedDisks() {
const importedDisks = await this.getImportedDisks();
await asyncForEach(importedDisks, async (disk) => {
await clickKebabAction(disk.name, 'Edit');
await waitForNoLoaders();
await diskDialog.selectStorageClass(disk.storageClass);
await click(saveButton);
await waitForNoLoaders();
await this.updateDisk(disk);
});
}

Expand All @@ -102,6 +146,37 @@ export class ImportWizard extends Wizard {
await isLoaded();
}

async importNetworkStep(config) {
const { networkResources } = config;
// Binding networks
// First update imported network interfaces to comply with k8s
await this.updateImportedNICs();
// Adding networks if any
if (networkResources) {
await this.addVmNetworks(networkResources);
}
await this.next();
}

async importDiskStep(config) {
const { storageResources } = config;
// Binding storage disks
// First update disks that come from the source VM
await this.updateImportedDisks();
// Adding disks if any
if (storageResources) {
await this.addVmStorage(storageResources);
}
await this.next();
}

async edit(config) {
const { advancedEdit } = config;
if (advancedEdit) {
Copy link
Member

Choose a reason for hiding this comment

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

this fails for me here - because there is one another condition here - a presence and evaluation of vmware-to-kubevirt-os configMap

IMO we should check if there are errors on top of the page are present if we wish to use advancedEdit: otherwise I get this exception:

1) VMWare Wizard validation, negative tests : VMWare - Import Wizard shows warning when using incorrect VM name
   Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
       at listOnTimeout internal/timers.js:554:17
       at processTimers internal/timers.js:497:7
   
   UnexpectedAlertOpenError: unexpected alert open: {Alert text : Are you sure you want to navigate away from this form? Any data you've added will be lost.}
     (Session info: chrome=84.0.4147.125)
     (Driver info: chromedriver=84.0.4147.30 (48b3e868b4cc0aa7e8149519690b6f6949e110a8-refs/branch-heads/4147@{#310}),platform=Linux 5.8.14-arch1-1 x86_64)
       at Object.checkLegacyResponse /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/error.js:553:13
       at parseHttpResponse /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/http.js:509:13
       at /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/http.js:441:30
       at runMicrotasks <anonymous>:null:null
       at processTicksAndRejections internal/process/task_queues.js:93:5
   
   From: Task: WebDriver.findElements(Bycss selector, #vm-name)
       at Driver.schedule /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/webdriver.js:807:17
       at Driver.findElements /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/webdriver.js:1048:19
       at /home/ansy/projects/openshift/console/frontend/node_modules/protractor/built/element.js:159:44
       at ManagedPromise.invokeCallback_ /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:1376:14
       at TaskQueue.execute_ /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:3084:14
       at TaskQueue.executeNext_ /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:3067:27
       at /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:2927:27
       at /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:668:7
   
   From: Task: <anonymous>
       at Timeout.pollCondition [as _onTimeout] /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:2195:19
       at listOnTimeout internal/timers.js:554:17
       at processTimers internal/timers.js:497:7
   
   From: Task: <anonymous wait>
       at scheduleWait /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:2188:20
       at ControlFlow.wait /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:2517:12
       at Driver.wait /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/webdriver.js:934:29
       at run /home/ansy/projects/openshift/console/frontend/node_modules/protractor/built/browser.js:59:33
       at ProtractorBrowser.to.<computed> [as wait] /home/ansy/projects/openshift/console/frontend/node_modules/protractor/built/browser.js:67:16
       at Object.<anonymous> /home/ansy/projects/openshift/console/frontend/packages/console-shared/src/test-utils/utils.ts:106:40
       at Generator.next <anonymous>:null:null
       at /home/ansy/projects/openshift/console/frontend/packages/console-shared/src/test-utils/utils.ts:8:71
       at new Promise <anonymous>:null:null
       at __awaiter /home/ansy/projects/openshift/console/frontend/packages/console-shared/src/test-utils/utils.ts:4:12
       at Object.fillInput /home/ansy/projects/openshift/console/frontend/packages/console-shared/src/test-utils/utils.ts:98:12
       at VmwareImportWizard.<anonymous> /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/tests/models/wizard.ts:81:27
       at Generator.next <anonymous>:null:null
       at /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/tests/models/wizard.ts:8:71
       at new Promise <anonymous>:null:null
       at __awaiter /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/tests/models/wizard.ts:4:12
       at VmwareImportWizard.fillName /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/tests/models/wizard.ts:80:16
       at /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/v2v/vmware/v2v.vmware.import.incorrect.names.negative.scenario.ts:33:38
       at Generator.next <anonymous>:null:null
       at /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/v2v/vmware/v2v.vmware.import.incorrect.names.negative.scenario.ts:8:71
       at new Promise <anonymous>:null:null
       at __awaiter /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/v2v/vmware/v2v.vmware.import.incorrect.names.negative.scenario.ts:4:12
       at /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/v2v/vmware/v2v.vmware.import.incorrect.names.negative.scenario.ts:32:68
       at Object.<anonymous> /home/ansy/projects/openshift/console/frontend/packages/console-shared/src/test-utils/utils.ts:159:19
       at Generator.next <anonymous>:null:null
       at /home/ansy/projects/openshift/console/frontend/packages/console-shared/src/test-utils/utils.ts:8:71
       at new Promise <anonymous>:null:null
       at __awaiter /home/ansy/projects/openshift/console/frontend/packages/console-shared/src/test-utils/utils.ts:4:12
       at Object.asyncForEach /home/ansy/projects/openshift/console/frontend/packages/console-shared/src/test-utils/utils.ts:156:12
       at /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/v2v/vmware/v2v.vmware.import.incorrect.names.negative.scenario.ts:32:23
       at Generator.next <anonymous>:null:null
       at fulfilled /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/v2v/vmware/v2v.vmware.import.incorrect.names.negative.scenario.ts:5:58
       at processTicksAndRejections internal/process/task_queues.js:93:5
   
   From: Task: Run it"VMWare - Import Wizard shows warning when using incorrect VM name" in control flow
       at UserContext.<anonymous> /home/ansy/projects/openshift/console/frontend/node_modules/jasminewd2/index.js:94:19
       at /home/ansy/projects/openshift/console/frontend/node_modules/jasminewd2/index.js:64:48
       at ControlFlow.emit /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/events.js:62:21
       at ControlFlow.shutdown_ /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:2674:10
       at /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:2599:53
       at /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:2728:9
       at /home/ansy/projects/openshift/console/frontend/node_modules/selenium-webdriver/lib/promise.js:668:7
       at processTicksAndRejections internal/process/task_queues.js:93:5
   
   From asynchronous test: 
   Error
       at Suite.<anonymous> /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/v2v/vmware/v2v.vmware.import.incorrect.names.negative.scenario.ts:30:5
       at Env.<anonymous> /home/ansy/projects/openshift/console/frontend/node_modules/jasmine-fail-fast/dist/jasmine-fail-fast.js:57:26
       at Env.wrapper [as describe] /home/ansy/projects/openshift/console/frontend/node_modules/jasmine-fail-fast/node_modules/lodash/index.js:3592:19
       at Object.<anonymous> /home/ansy/projects/openshift/console/frontend/packages/kubevirt-plugin/integration-tests/v2v/vmware/v2v.vmware.import.incorrect.names.negative.scenario.ts:22:1
       at Module._compile internal/modules/cjs/loader.js:1063:30
       at Module.m._compile /home/ansy/projects/openshift/console/frontend/node_modules/ts-node/dist/index.js:234:29
       at Module._extensions..js internal/modules/cjs/loader.js:1092:10
       at Object.require.extensions.<computed> [as .ts] /home/ansy/projects/openshift/console/frontend/node_modules/ts-node/dist/index.js:236:16
       at Module.load /home/ansy/projects/openshift/console/frontend/node_modules/coffeescript/lib/coffee-script/register.js:45:36
       at Function.Module._load internal/modules/cjs/loader.js:769:14
       at Module.require internal/modules/cjs/loader.js:952:19
       at require internal/modules/cjs/helpers.js:88:18
       at /home/ansy/projects/openshift/console/frontend/node_modules/jasmine/lib/jasmine.js:93:5
       at Array.forEach <anonymous>:null:null
       at Jasmine.loadSpecs /home/ansy/projects/openshift/console/frontend/node_modules/jasmine/lib/jasmine.js:92:18
       at Jasmine.execute /home/ansy/projects/openshift/console/frontend/node_modules/jasmine/lib/jasmine.js:197:8
       at /home/ansy/projects/openshift/console/frontend/node_modules/protractor/built/frameworks/jasmine.js:132:15
       at Function.promise /home/ansy/projects/openshift/console/frontend/node_modules/q/q.js:682:9
       at /home/ansy/projects/openshift/console/frontend/node_modules/protractor/built/frameworks/jasmine.js:104:14
       at _fulfilled /home/ansy/projects/openshift/console/frontend/node_modules/q/q.js:834:54
       at /home/ansy/projects/openshift/console/frontend/node_modules/q/q.js:863:30
       at Promise.promise.promiseDispatch /home/ansy/projects/openshift/console/frontend/node_modules/q/q.js:796:13
       at /home/ansy/projects/openshift/console/frontend/node_modules/q/q.js:556:49
       at runSingle /home/ansy/projects/openshift/console/frontend/node_modules/q/q.js:137:13
       at flush /home/ansy/projects/openshift/console/frontend/node_modules/q/q.js:125:13
       at processTicksAndRejections internal/process/task_queues.js:75:11
   

click(rhvView.editButton);
}
}

/**
* Waits for loading icon on Import tab to disappear.
* As the icon disappears and re-appears several times when loading VM details
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
IMPORT_WIZARD_CONN_TO_NEW_INSTANCE,
RHV_WIZARD_CREATE_SUCCESS,
PAGE_LOAD_TIMEOUT_SECS,
IMPORT_WIZARD_CONN_NAME_PREFIX,
} from '../utils/constants/common';
import * as view from '../../views/importWizard.view';
import * as rhvView from '../../views/rhvImportWizard.view';
Expand Down Expand Up @@ -50,11 +51,14 @@ export class RhvImportWizard extends ImportWizard {
}

async configureInstance(instanceConfig: InstanceConfig) {
await selectOptionByText(rhvView.ovirtInstanceSelect, instanceConfig.instance);
if (instanceConfig.instance === IMPORT_WIZARD_CONN_TO_NEW_INSTANCE) {
await selectOptionByText(rhvView.ovirtInstanceSelect, instanceConfig.instance);
await this.configureProvider(instanceConfig);
await this.connectToInstance();
} else if (instanceConfig.instance.includes(IMPORT_WIZARD_CONN_NAME_PREFIX)) {
await this.selectInstanceByPrefixName(rhvView.ovirtInstanceSelect);
} else {
throw Error('Saved provider instances are not implemented');
throw Error('No RHV instance was found');
}
}

Expand All @@ -73,24 +77,12 @@ export class RhvImportWizard extends ImportWizard {
);
}

async import(config: VMImportConfig) {
const {
provider,
instanceConfig,
name,
description,
sourceVMName,
storageResources,
networkResources,
startOnCreation,
} = config;
await this.openWizard(VirtualMachineModel);

// General section
async importVmConnectProviderStep(config) {
const { provider, instanceConfig, sourceVMName } = config;
// Establishing connection:
await this.selectProvider(provider);
await this.waitForSpinner();
await this.configureInstance(instanceConfig);
await this.connectToInstance();
await this.waitForSpinner();

// Selecting RHV cluster
Expand All @@ -99,45 +91,36 @@ export class RhvImportWizard extends ImportWizard {
await this.selectSourceVirtualMachine(sourceVMName);
Copy link
Member

Choose a reason for hiding this comment

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

this await fails. Please make sure the elements are in focus and clickable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This await should look like this inside:

  async selectSourceVirtualMachine(sourceVirtualMachine: string) {
    await selectOptionByText(rhvView.ovirtVmSelect, sourceVirtualMachine);
  }

Does it look the same in your code? If not - it will fail

await this.waitForSpinner();
// Clicking `edit` button to reach network and storage settings
await click(rhvView.editButton);
await this.edit(config);
await browser.sleep(2000);
await click(view.nextButton);
await this.next();
}

async importVmConfigStep(config) {
const { name, description } = config;
// Impossible to do changes of flavor, workload profile and/or OS, only VM name and description can be updated
if (name) {
await this.fillName(name);
}
if (description) {
await this.fillDescription(description);
}
await this.next();
// Binding networks
// First update imported network interfaces to comply with k8s
await this.updateImportedNICs();
// Adding networks if any
if (networkResources) {
await this.addVmNetworks(networkResources);
}
await this.next();
await click(view.nextButton);
}

// Binding storage disks
// First update disks that come from the source VM
await this.updateImportedDisks();
// Adding disks if any
if (storageResources) {
await this.addVmStorage(storageResources);
}
await this.next();
async import(config: VMImportConfig) {
const { name } = config;
await this.openWizard(VirtualMachineModel);

await this.importVmConnectProviderStep(config);
await this.importVmConfigStep(config);
await this.importNetworkStep(config);
await this.importDiskStep(config);
// CloudInit page is in read-only mode
await this.next();
// Additional devices page is in read-only mode
await this.next();

// Review
await this.validateReviewTab(config);
if (startOnCreation) {
await this.startOnCreation();
}

await this.processReviewStep(config);
// Import
await this.confirmAndCreate();
await this.waitForCreation();
Expand Down