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

kubevirt: add test for creating windows 10 VM #3611

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
Expand Up @@ -19,12 +19,10 @@ import {
VM_ACTIONS_TIMEOUT_SECS,
VM_STOP_TIMEOUT_SECS,
VM_STATUS,
CONFIG_NAME_URL,
CONFIG_NAME_PXE,
CONFIG_NAME_DISK,
} from '../utils/consts';
import { detailViewAction, listViewAction } from '../../views/vm.actions.view';
import { nameInput as cloneDialogNameInput } from '../../views/dialogs/cloneVirtualMachineDialog.view';
import { ProvisionConfigName } from '../utils/constants/wizard';
import { Wizard } from './wizard';
import { KubevirtDetailView } from './kubevirtDetailView';

Expand Down Expand Up @@ -199,21 +197,21 @@ export class VirtualMachine extends KubevirtDetailView {
for (const resource of networkResources) {
await wizard.addNIC(resource);
}
if (provisionSource.method === CONFIG_NAME_PXE && template === undefined) {
if (provisionSource.method === ProvisionConfigName.PXE && template === undefined) {
// Select the last NIC as the source for booting
await wizard.selectBootableNIC(networkResources[networkResources.length - 1].network);
}
await wizard.next();

// Storage
for (const resource of storageResources) {
if (resource.name === 'rootdisk' && provisionSource.method === CONFIG_NAME_URL) {
if (resource.name === 'rootdisk' && provisionSource.method === ProvisionConfigName.URL) {
await wizard.editDisk(resource.name, resource);
} else {
await wizard.addDisk(resource);
}
}
if (provisionSource.method === CONFIG_NAME_DISK) {
if (provisionSource.method === ProvisionConfigName.DISK) {
// Select the last Disk as the source for booting
await wizard.selectBootableDisk(storageResources[storageResources.length - 1].name);
}
Expand Down
Expand Up @@ -4,7 +4,7 @@ import {
resourceRowsPresent,
} from '@console/internal-integration-tests/views/crud.view';
import { VMTemplateConfig } from '../utils/types';
import { CONFIG_NAME_PXE, CONFIG_NAME_URL } from '../utils/consts';
import { ProvisionConfigName } from '../utils/constants/wizard';
import { Wizard } from './wizard';
import { KubevirtDetailView } from './kubevirtDetailView';

Expand Down Expand Up @@ -43,15 +43,15 @@ export class VirtualMachineTemplate extends KubevirtDetailView {
for (const resource of networkResources) {
await wizard.addNIC(resource);
}
if (provisionSource.method === CONFIG_NAME_PXE) {
if (provisionSource.method === ProvisionConfigName.PXE) {
// Select the last NIC as the source for booting
await wizard.selectBootableNIC(networkResources[networkResources.length - 1].network);
}
await wizard.next();

// Storage
for (const resource of storageResources) {
if (resource.name === 'rootdisk' && provisionSource.method === CONFIG_NAME_URL) {
if (resource.name === 'rootdisk' && provisionSource.method === ProvisionConfigName.URL) {
await wizard.editDisk(resource.name, resource);
} else {
await wizard.addDisk(resource);
Expand Down
@@ -0,0 +1,30 @@
export enum ProvisionConfigName {
URL = 'URL',
CONTAINER = 'Container',
PXE = 'PXE',
DISK = 'Disk',
CLONED_DISK = 'ClonedDisk',
}

export enum OperatingSystem {
RHEL7_6 = 'Red Hat Enterprise Linux 7.6',
WINDOWS_10 = 'Microsoft Windows 10',
}

export const OSIDLookup = {
[OperatingSystem.WINDOWS_10]: 'win10',
};

export enum Flavor {
TINY = 'tiny',
SMALL = 'small',
MEDIUM = 'medium',
LARGE = 'large',
CUSTOM = 'Custom',
}

export enum WorkloadProfile {
DESKTOP = 'desktop',
HIGH_PERFORMANCE = 'highperformance',
SERVER = 'server',
}
Expand Up @@ -37,17 +37,12 @@ export const NODE_MAINTENANCE_STATUS = 'Under maintenance';
export const NODE_STOPPING_MAINTENANCE_STATUS = 'Stopping maintenance';
export const NODE_READY_STATUS = 'Ready';

// Wizard
export const CONFIG_NAME_URL = 'URL';
export const CONFIG_NAME_CONTAINER = 'Container';
export const CONFIG_NAME_PXE = 'PXE';
export const CONFIG_NAME_DISK = 'Disk';
export const CONFIG_NAME_CLONED_DISK = 'ClonedDisk';

// Kubevirt related
export const KUBEVIRT_STORAGE_CLASS_DEFAULTS = 'kubevirt-storage-class-defaults';
export const KUBEVIRT_PROJECT_NAME = 'openshift-cnv';
export const COMMON_TEMPLATES_VERSION = 'v0.6.2';
export const COMMON_TEMPLATES_NAMESPACE = 'openshift';
export const COMMON_TEMPLATES_REVISION = '1';

export enum TAB {
Consoles = 'Consoles',
Expand Down
Expand Up @@ -7,8 +7,11 @@ import {
DISK_INTERFACE,
KUBEVIRT_STORAGE_CLASS_DEFAULTS,
KUBEVIRT_PROJECT_NAME,
COMMON_TEMPLATES_NAMESPACE,
COMMON_TEMPLATES_REVISION,
} from './consts';
import { getRandomMacAddress, getResourceObject, resolveStorageDataAttribute } from './utils';
import { Flavor, OperatingSystem, WorkloadProfile } from './constants/wizard';

export const multusNAD = {
apiVersion: 'k8s.cni.cncf.io/v1',
Expand Down Expand Up @@ -53,9 +56,9 @@ export const dataVolumeManifest = ({ name, namespace, sourceURL, accessMode, vol
};

export const basicVMConfig = {
operatingSystem: 'Red Hat Enterprise Linux 7.6',
flavor: 'tiny',
workloadProfile: 'desktop',
operatingSystem: OperatingSystem.RHEL7_6,
flavor: Flavor.TINY,
workloadProfile: WorkloadProfile.DESKTOP,
sourceURL: 'https://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img',
sourceContainer: 'kubevirt/cirros-registry-disk-demo',
cloudInitScript: `#cloud-config\nuser: cloud-user\npassword: atomic\nchpasswd: {expire: False}\nhostname: vm-${testName}`,
Expand Down Expand Up @@ -115,8 +118,8 @@ export function getVMManifest(
'flavor.template.kubevirt.io/tiny': 'true',
'os.template.kubevirt.io/rhel7.6': 'true',
'vm.kubevirt.io/template': `rhel7-desktop-tiny-${COMMON_TEMPLATES_VERSION}`,
'vm.kubevirt.io/template-namespace': 'openshift',
'vm.kubevirt.io/template.revision': '1',
'vm.kubevirt.io/template-namespace': COMMON_TEMPLATES_NAMESPACE,
'vm.kubevirt.io/template.revision': COMMON_TEMPLATES_REVISION,
'vm.kubevirt.io/template.version': COMMON_TEMPLATES_VERSION,
'workload.template.kubevirt.io/desktop': 'true',
},
Expand Down
Expand Up @@ -8,14 +8,11 @@ import {
} from '@console/shared/src/test-utils/utils';
import * as editCdView from '../views/editCDView';
import * as virtualMachineView from '../views/virtualMachine.view';
import {
VM_CREATE_AND_EDIT_TIMEOUT_SECS,
CONFIG_NAME_CONTAINER,
STORAGE_CLASS,
} from './utils/consts';
import { VM_CREATE_AND_EDIT_TIMEOUT_SECS, STORAGE_CLASS } from './utils/consts';
import { selectOptionByOptionValue } from './utils/utils';
import { VirtualMachine } from './models/virtualMachine';
import { vmConfig, getProvisionConfigs, getTestDataVolume } from './vm.wizard.configs';
import { ProvisionConfigName } from './utils/constants/wizard';

describe('KubeVirt VM detail - edit cdroms', () => {
const testDataVolume = getTestDataVolume(testName);
Expand All @@ -30,7 +27,7 @@ describe('KubeVirt VM detail - edit cdroms', () => {
const leakedResources = new Set<string>();
const provisionConfigs = getProvisionConfigs(testName);

const configName = CONFIG_NAME_CONTAINER;
const configName = ProvisionConfigName.CONTAINER;
const provisionConfig = provisionConfigs.get(configName);

provisionConfig.networkResources = [];
Expand Down
Expand Up @@ -6,17 +6,18 @@ import {
click,
} from '@console/shared/src/test-utils/utils';
import * as virtualMachineView from '../views/virtualMachine.view';
import { VM_CREATE_AND_EDIT_TIMEOUT_SECS, CONFIG_NAME_CONTAINER } from './utils/consts';
import { VM_CREATE_AND_EDIT_TIMEOUT_SECS } from './utils/consts';
import { VirtualMachine } from './models/virtualMachine';
import { vmConfig, getProvisionConfigs } from './vm.wizard.configs';
import * as editFlavorView from './models/editFlavorView';
import { fillInput } from './utils/utils';
import { ProvisionConfigName } from './utils/constants/wizard';

describe('KubeVirt VM detail - edit flavor', () => {
const leakedResources = new Set<string>();
const provisionConfigs = getProvisionConfigs(testName);

const configName = CONFIG_NAME_CONTAINER;
const configName = ProvisionConfigName.CONTAINER;
const provisionConfig = provisionConfigs.get(configName);

// not needed for testing flavor
Expand Down
Expand Up @@ -11,13 +11,10 @@ import {
KUBEVIRT_STORAGE_CLASS_DEFAULTS,
KUBEVIRT_PROJECT_NAME,
DISK_INTERFACE,
CONFIG_NAME_URL,
CONFIG_NAME_PXE,
CONFIG_NAME_CONTAINER,
CONFIG_NAME_DISK,
DISK_SOURCE,
} from './utils/consts';
import { resolveStorageDataAttribute, getResourceObject } from './utils/utils';
import { ProvisionConfigName } from './utils/constants/wizard';

export const vmConfig = (name: string, provisionConfig, testName: string) => {
const commonSettings = {
Expand Down Expand Up @@ -72,33 +69,33 @@ const getDiskToCloneFrom = (testName: string): StorageResource => {
};

export const getProvisionConfigs = (testName: string) =>
OrderedMap<string, ProvisionConfig>()
.set(CONFIG_NAME_URL, {
OrderedMap<ProvisionConfigName, ProvisionConfig>()
.set(ProvisionConfigName.URL, {
provision: {
method: CONFIG_NAME_URL,
method: ProvisionConfigName.URL,
source: basicVMConfig.sourceURL,
},
networkResources: [networkInterface],
storageResources: [rootDisk],
})
.set(CONFIG_NAME_CONTAINER, {
.set(ProvisionConfigName.CONTAINER, {
provision: {
method: CONFIG_NAME_CONTAINER,
method: ProvisionConfigName.CONTAINER,
source: basicVMConfig.sourceContainer,
},
networkResources: [networkInterface],
storageResources: [hddDisk],
})
.set(CONFIG_NAME_PXE, {
.set(ProvisionConfigName.PXE, {
provision: {
method: CONFIG_NAME_PXE,
method: ProvisionConfigName.PXE,
},
networkResources: [networkInterface],
storageResources: [rootDisk],
})
.set(CONFIG_NAME_DISK, {
.set(ProvisionConfigName.DISK, {
provision: {
method: CONFIG_NAME_DISK,
method: ProvisionConfigName.DISK,
},
networkResources: [networkInterface],
storageResources: [getDiskToCloneFrom(testName)],
Expand Down
Expand Up @@ -6,6 +6,7 @@ import {
createResources,
deleteResources,
} from '@console/shared/src/test-utils/utils';
import { getAnnotations, getLabels } from '../../src/selectors/selectors';
import { VirtualMachine } from './models/virtualMachine';
import { getResourceObject, resolveStorageDataAttribute } from './utils/utils';
import {
Expand All @@ -14,8 +15,9 @@ import {
VM_ACTION,
CLONED_VM_BOOTUP_TIMEOUT_SECS,
VM_STATUS,
CONFIG_NAME_DISK,
CONFIG_NAME_URL,
COMMON_TEMPLATES_VERSION,
COMMON_TEMPLATES_NAMESPACE,
COMMON_TEMPLATES_REVISION,
} from './utils/consts';
import { multusNAD } from './utils/mocks';
import {
Expand All @@ -24,6 +26,13 @@ import {
getTestDataVolume,
kubevirtStorage,
} from './vm.wizard.configs';
import {
Flavor,
OperatingSystem,
OSIDLookup,
ProvisionConfigName,
WorkloadProfile,
} from './utils/constants/wizard';

describe('Kubevirt create VM using wizard', () => {
const leakedResources = new Set<string>();
Expand All @@ -44,7 +53,7 @@ describe('Kubevirt create VM using wizard', () => {

provisionConfigs.forEach((provisionConfig, configName) => {
const specTimeout =
configName === CONFIG_NAME_DISK ? CLONE_VM_TIMEOUT_SECS : VM_BOOTUP_TIMEOUT_SECS;
configName === ProvisionConfigName.DISK ? CLONE_VM_TIMEOUT_SECS : VM_BOOTUP_TIMEOUT_SECS;
it(
`Create VM using ${configName}.`,
async () => {
Expand All @@ -59,10 +68,63 @@ describe('Kubevirt create VM using wizard', () => {
);
});

it(
'Creates windows 10 VM with correct metadata',
async () => {
const testVMConfig = vmConfig(
'windows10',
provisionConfigs.get(ProvisionConfigName.CONTAINER),
testName,
);
testVMConfig.networkResources = [];
testVMConfig.operatingSystem = OperatingSystem.WINDOWS_10;
testVMConfig.flavor = Flavor.MEDIUM;
testVMConfig.workloadProfile = WorkloadProfile.SERVER;
testVMConfig.startOnCreation = false; // do not check as there is only medium/large profile present and we would get insufficient memory.
const osID = OSIDLookup[testVMConfig.operatingSystem];

const vm = new VirtualMachine(testVMConfig);

await withResource(leakedResources, vm.asResource(), async () => {
await vm.create(testVMConfig);
const vmResult = getResourceObject(vm.name, vm.namespace, vm.kind);
const annotations = getAnnotations(vmResult);
const labels = getLabels(vmResult);

expect(annotations).toBeDefined();
expect(labels).toBeDefined();

const requiredAnnotations = {
[`name.os.template.kubevirt.io/${osID}`]: OperatingSystem.WINDOWS_10,
};

const requiredLabels = {
[`workload.template.kubevirt.io/${testVMConfig.workloadProfile}`]: 'true',
[`flavor.template.kubevirt.io/${testVMConfig.flavor}`]: 'true',
[`os.template.kubevirt.io/${osID}`]: 'true',
'vm.kubevirt.io/template': `win2k12r2-${testVMConfig.workloadProfile}-${
testVMConfig.flavor
}-${COMMON_TEMPLATES_VERSION}`,
'vm.kubevirt.io/template-namespace': COMMON_TEMPLATES_NAMESPACE,
'vm.kubevirt.io/template.revision': COMMON_TEMPLATES_REVISION,
'vm.kubevirt.io/template.version': COMMON_TEMPLATES_VERSION,
};

expect(_.pick(annotations, Object.keys(requiredAnnotations))).toEqual(requiredAnnotations);
expect(_.pick(labels, Object.keys(requiredLabels))).toEqual(requiredLabels);
});
},
VM_BOOTUP_TIMEOUT_SECS,
);

it(
'Creates DV with correct accessMode/volumeMode',
async () => {
const testVMConfig = vmConfig('test-dv', provisionConfigs.get(CONFIG_NAME_URL), testName);
const testVMConfig = vmConfig(
'test-dv',
provisionConfigs.get(ProvisionConfigName.URL),
testName,
);
testVMConfig.networkResources = [];
const vm = new VirtualMachine(testVMConfig);

Expand All @@ -84,7 +146,7 @@ describe('Kubevirt create VM using wizard', () => {
it(
'Multiple VMs created using "Cloned Disk" method from single source',
async () => {
const clonedDiskProvisionConfig = provisionConfigs.get(CONFIG_NAME_DISK);
const clonedDiskProvisionConfig = provisionConfigs.get(ProvisionConfigName.DISK);
const vm1Config = vmConfig('vm1', clonedDiskProvisionConfig, testName);
const vm2Config = vmConfig('vm2', clonedDiskProvisionConfig, testName);
vm1Config.startOnCreation = false;
Expand Down