Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/integration-tests/protractor.conf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ export const config: Config = {
'../packages/kubevirt-plugin/integration-tests/tests/vm.resources.scenario.ts',
'../packages/kubevirt-plugin/integration-tests/tests/vm.clone.scenario.ts',
'../packages/kubevirt-plugin/integration-tests/tests/vm.detail.flavor.ts',
'../packages/kubevirt-plugin/integration-tests/tests/vm.template.wizard.scenario.ts',
]),
all: suite([
'tests/crud.scenario.ts',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,7 @@ export class VirtualMachine extends KubevirtDetailView {

// Networking
for (const resource of networkResources) {
await wizard.addNIC(
resource.name,
resource.mac,
resource.networkDefinition,
resource.binding,
);
await wizard.addNIC(resource);
}
await wizard.next();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* eslint-disable no-unused-vars, no-undef, no-await-in-loop, no-console */
import { browser } from 'protractor';
import { testName } from '../../../../../integration-tests/protractor.conf';
import {
errorMessage,
filterForName,
resourceRowsPresent,
} from '../../../../../integration-tests/views/crud.view';
import { VMTemplateConfig } from '../utils/types';
import { WIZARD_CREATE_TEMPLATE_ERROR, WIZARD_TABLE_FIRST_ROW } from '../utils/consts';
import { Wizard } from './wizard';
import { KubevirtDetailView } from './kubevirtDetailView';

export class VirtualMachineTemplate extends KubevirtDetailView {
constructor(templateConfig) {
super({ ...templateConfig, kind: 'vmtemplates' });
}

async create({
name,
namespace,
description,
provisionSource,
operatingSystem,
flavor,
workloadProfile,
cloudInit,
storageResources,
networkResources,
}: VMTemplateConfig) {
await this.navigateToListView();

// Basic Settings for VM template
const wizard = new Wizard();
await wizard.openWizard();
await wizard.fillName(name);
await wizard.fillDescription(description);
if (!(await browser.getCurrentUrl()).includes(`${testName}/${this.kind}`)) {
await wizard.selectNamespace(namespace);
}
await wizard.selectProvisionSource(provisionSource);
await wizard.selectOperatingSystem(operatingSystem);
await wizard.selectFlavor(flavor);
await wizard.selectWorkloadProfile(workloadProfile);
if (cloudInit.useCloudInit) {
await wizard.useCloudInit(cloudInit);
}
await wizard.next();

// Networking
for (const resource of networkResources) {
await wizard.addNIC(resource);
}
await wizard.next();

// Storage
for (const resource of storageResources) {
if (resource.name === 'rootdisk' && provisionSource.method === 'URL') {
// Rootdisk is present by default, only edit specific properties
await wizard.editDiskAttribute(WIZARD_TABLE_FIRST_ROW, 'size', resource.size);
await wizard.editDiskAttribute(WIZARD_TABLE_FIRST_ROW, 'storage', resource.storageClass);
} else {
await wizard.addDisk(resource);
}
}

// Create VM template
await wizard.next();
await wizard.waitForCreation();

// Check for errors and close wizard
if (await errorMessage.isPresent()) {
console.error(await errorMessage.getText());
throw new Error(WIZARD_CREATE_TEMPLATE_ERROR);
}
await wizard.next();

// Verify VM template is created
await filterForName(name);
Copy link
Member

Choose a reason for hiding this comment

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

could we add this verification even to the models/virtualMachine.ts

Copy link
Member Author

Choose a reason for hiding this comment

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

added to the vm test

Copy link
Member Author

Choose a reason for hiding this comment

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

removed from virtualMachine.ts because (in the meentime) another PR added a similar check (L178) that checks that the VM is acctually created in cases when we do not check that it is running.

await resourceRowsPresent();
}

asResource() {
return {
kind: 'template',
metadata: {
namespace: this.namespace,
name: this.name,
},
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { $, browser, ExpectedConditions as until } from 'protractor';
import { createItemButton, isLoaded } from '../../../../../integration-tests/views/crud.view';
import { selectDropdownOption, click } from '../../../../console-shared/src/test-utils/utils';
import { fillInput } from '../utils/utils';
import { CloudInitConfig, StorageResource } from '../utils/types';
import { CloudInitConfig, StorageResource, NetworkResource } from '../utils/types';
import { PAGE_LOAD_TIMEOUT_SECS } from '../utils/consts';
import * as wizardView from '../../views/wizard.view';

Expand Down Expand Up @@ -80,8 +80,9 @@ export class Wizard {
await isLoaded();
}

async addNIC(name: string, mac: string, networkDefinition: string, binding: string) {
async addNIC(NICConfig: NetworkResource) {
await click(wizardView.createNIC);
const { name, mac, networkDefinition, binding } = NICConfig;
const rowsCount = await this.getTableRowsCount();
// Dropdown selection needs to be first due to https://github.com/kubevirt/web-ui-components/issues/9
await wizardView.selectTableDropdownAttribute(rowsCount, 'network', networkDefinition);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,16 @@ export type ProvisionConfig = {
networkResources: NetworkResource[];
storageResources: StorageResource[];
};

export type VMTemplateConfig = {
name: string;
namespace: string;
description: string;
provisionSource?: ProvisionOption;
operatingSystem?: string;
flavor?: string;
workloadProfile?: string;
cloudInit?: CloudInitConfig;
storageResources?: StorageResource[];
networkResources?: NetworkResource[];
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* eslint-disable no-undef, max-nested-callbacks */
import { OrderedMap } from 'immutable';
import { testName } from '../../../../integration-tests/protractor.conf';
import {
removeLeakedResources,
createResources,
deleteResources,
addLeakableResource,
} from '../../../console-shared/src/test-utils/utils';
import { NetworkResource, StorageResource, ProvisionOption } from './utils/types';
import { VM_BOOTUP_TIMEOUT_SECS } from './utils/consts';
import { basicVMConfig, rootDisk, networkInterface, multusNAD, hddDisk } from './utils/mocks';
import { getTestDataVolume } from './vm.wizard.configs';
import { VirtualMachine } from './models/virtualMachine';
import { VirtualMachineTemplate } from './models/virtualMachineTemplate';

describe('Kubevirt create VM Template using wizard', () => {
const leakedResources = new Set<string>();
const testDataVolume = getTestDataVolume(testName);
const commonSettings = {
cloudInit: {
useCloudInit: false,
},
namespace: testName,
description: `Default description ${testName}`,
flavor: basicVMConfig.flavor,
operatingSystem: basicVMConfig.operatingSystem,
workloadProfile: basicVMConfig.workloadProfile,
};
const vmTemplateConfig = (name, provisionConfig) => {
return {
...commonSettings,
name: `${name}-${testName}`,
provisionSource: provisionConfig.provision,
storageResources: provisionConfig.storageResources,
networkResources: provisionConfig.networkResources,
};
};
const vmConfig = (name, templateConfig) => {
return {
...commonSettings,
startOnCreation: true,
name: `${name}-${testName}`,
template: templateConfig.name,
storageResources: [],
networkResources: [],
};
};

const provisionConfigs = OrderedMap<
string,
{
provision: ProvisionOption;
networkResources: NetworkResource[];
storageResources: StorageResource[];
}
>()
.set('URL', {
provision: {
method: 'URL',
source: basicVMConfig.sourceURL,
},
networkResources: [networkInterface],
storageResources: [rootDisk],
})
.set('Container', {
provision: {
method: 'Container',
source: basicVMConfig.sourceContainer,
},
networkResources: [networkInterface],
storageResources: [hddDisk],
})
.set('PXE', {
provision: {
method: 'PXE',
},
networkResources: [networkInterface],
storageResources: [rootDisk],
});

beforeAll(async () => {
createResources([multusNAD, testDataVolume]);
});

afterAll(async () => {
deleteResources([multusNAD, testDataVolume]);
});

afterEach(() => {
removeLeakedResources(leakedResources);
});

provisionConfigs.forEach((provisionConfig, configName) => {
it(
`Create VM Template using ${configName}.`,
async () => {
const vmTemplate = new VirtualMachineTemplate(
vmTemplateConfig(configName.toLowerCase(), provisionConfig),
);
const vm = new VirtualMachine(vmConfig(configName.toLowerCase(), vmTemplate));

addLeakableResource(leakedResources, vmTemplate.asResource());
addLeakableResource(leakedResources, vm.asResource());

await vmTemplate.create(vmTemplateConfig(configName.toLowerCase(), provisionConfig));
await vm.create(vmConfig(configName.toLowerCase(), vmTemplate));
},
VM_BOOTUP_TIMEOUT_SECS * 2,
);
});
});