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

Fix VM related test cases #1319

Merged
merged 3 commits into from
Jun 19, 2024
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
2 changes: 2 additions & 0 deletions cypress/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ export default defineConfig({
baseUrl: 'https://online-server',
host: [{
name: 'harvester-node-1',
customName: '',
disks: [
{
name: '',
devPath: '',
},
],
witnessNode: false
}],
image: {
name: 'openSUSE-Leap-15.3-3-NET-x86_64.qcow2',
Expand Down
24 changes: 13 additions & 11 deletions cypress/cypress.env.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@
"rancherUser": "admin",
"rancherPassword": "admin",
"rancherBootstrapPassword": "admin",
"host":
{
"name": "",
"disks":
[
{
"name": "",
"devPath": ""
}
]
},
"host": [
{
"name": "",
"customName": "",
"disks": [
{
"name": "",
"devPath": ""
}
],
"witnessNode": false
}
],
"largeImage": {
"name": "openSUSE-Leap-15.3-3-DVD-x86_64-Build38.1-Media.iso",
"url": "https://mirrors.bfsu.edu.cn/opensuse/distribution/leap/15.3/iso/openSUSE-Leap-15.3-3-DVD-x86_64-Build38.1-Media.iso"
Expand Down
4 changes: 4 additions & 0 deletions cypress/models/host.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface Node {
name: string;
customName: string;
}
9 changes: 5 additions & 4 deletions cypress/pageobjects/hosts.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const constants = new Constants();
import CruResourcePo from '@/utils/components/cru-resource.po';
import { HCI } from '@/constants/types'
import LabeledInputPo from '@/utils/components/labeled-input.po';
import { Node } from '@/models/host'

interface ValueInterface {
namespace?: string,
Expand Down Expand Up @@ -69,13 +70,13 @@ export class HostsPage extends CruResourcePo {
}
}

enableMaintenance(name:string) {
cy.intercept('POST', `/v1/harvester/${this.realType}s/${name}?action=enableMaintenanceMode`).as('enable');
this.clickAction(name, 'Enable Maintenance Mode');
enableMaintenance(node: Node) {
cy.intercept('POST', `/v1/harvester/${this.realType}s/${node.name}?action=enableMaintenanceMode`).as('enable');
this.clickAction(node.customName || node.name, 'Enable Maintenance Mode');
// Maintenance
cy.get('.card-container').contains('Apply').click();
cy.wait('@enable').then(res => {
expect(res.response?.statusCode, `Enable maintenance ${name}`).to.equal(204);
expect(res.response?.statusCode, `Enable maintenance ${node.name}`).to.equal(204);
})
}

Expand Down
35 changes: 18 additions & 17 deletions cypress/pageobjects/virtualmachine.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,27 +468,28 @@ export class VmsPage extends CruResourcePo {
setNodeScheduling({
radio, nodeName, selector
}: {
radio?: string,
radio?: 'any' | 'specific' | 'rules',
nodeName?: string,
selector?: any,
}) {
this.clickTab('nodeScheduling');

const anyRadio = new RadioButtonPo('.radio-group', ':contains("Run VM on any available node")')
const specificRadio = new RadioButtonPo('.radio-group', ':contains("Run VM on specific node")')
const rulesRadio = new RadioButtonPo('.radio-group', ':contains("Run VM on node(s) matching scheduling rules")')

if (radio === 'any') {
// anyRadio.input(null)
} else if (radio = 'Run VM on any available node') {
specificRadio.input('Run VM on specific node')

const nodeNameSelector = new LabeledSelectPo('.labeled-select', `:contains("Node Name")`)
nodeNameSelector.select({
option: nodeName,
})
} else if (radio === 'rules') {
rulesRadio.input('Run VM on node(s) matching scheduling rules')

const rulesRadio = new RadioButtonPo('.radio-group', ':contains("Run VM on node(s) matching scheduling rules")')
const specificRadio = new RadioButtonPo('.radio-group', ':contains("Run VM on specific node")')
const nodeNameSelector = new LabeledSelectPo('.labeled-select', `:contains("Node Name")`)

switch (radio) {
case 'rules':
rulesRadio.input('Run VM on node(s) matching scheduling rules')
break;
case 'specific':
specificRadio.input('Run VM on specific node')

nodeNameSelector.select({
selector: '.vs__dropdown-menu',
option: nodeName,
})
break;
}
}
}
7 changes: 4 additions & 3 deletions cypress/testcases/virtualmachines/node-scheduling.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { VmsPage } from "@/pageobjects/virtualmachine.po";

import { generateName } from '@/utils/utils';
import { generateName, host as hostUtil } from '@/utils/utils';
import { Constants } from "@/constants/constants";

const vmPO = new VmsPage();
Expand All @@ -27,11 +27,12 @@ describe('Stop VM Negative', () => {
vmPO.setBasics('1', '1');
vmPO.setVolumes(volume);

const host = Cypress.env('host');
const hostList = hostUtil.list();
const host = hostList[0];

vmPO.setNodeScheduling({
radio: 'specific',
nodeName: host.name,
nodeName: host.customName || host.name,
});

vmPO.save();
Expand Down
18 changes: 11 additions & 7 deletions cypress/testcases/virtualmachines/scheduling.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { VmsPage } from "@/pageobjects/virtualmachine.po";
import { HostsPage } from "@/pageobjects/hosts.po";
import { host as hostsUtil } from '@/utils/utils';
import { Node } from '@/models/host'

const vms = new VmsPage();
const hosts = new HostsPage();
Expand All @@ -13,26 +15,28 @@ describe('VM scheduling on Specific node', () => {
});

it('Schedule VM on the Node which is Enable Maintenance Mode', () => {
const hostList = Cypress.env('host');
const hostNames: string[] = hostList.map((host: any) => host.name);
const maintenanceNode = hostNames[0]
const filterMaintenanceNames = hostNames.filter(name => name !== maintenanceNode);
const hostList = hostsUtil.list();

const hostNames: string[] = hostList.map((node: Node) => node.customName || node.name);

const maintenanceNodeName = hostNames[0]
Copy link
Contributor

@a110605 a110605 Jun 13, 2024

Choose a reason for hiding this comment

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

Even host is prefilled with a item in cypress.env.json.
How about add an early return error message if hostList is empty or undefined ?
Same in node-scheduling.spec.ts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, I just added a hosts util to do that.

const filterMaintenanceNodeNames = hostNames.filter(name => name !== maintenanceNodeName);

// Check whether all nodes can be selected
vms.goToCreate();
vms.selectSchedulingType({type: 'specific'});
vms.checkSpecificNodes({includeNodes: hostNames});

hosts.goToList();
hosts.enableMaintenance(hostNames[0]);
hosts.enableMaintenance(hostList[0]);

// Maintenance nodes should not be selected
vms.goToCreate();
vms.selectSchedulingType({type: 'specific'});
vms.checkSpecificNodes({includeNodes: filterMaintenanceNames, excludeNodes: [maintenanceNode]});
vms.checkSpecificNodes({includeNodes: filterMaintenanceNodeNames, excludeNodes: [maintenanceNodeName]});

hosts.goToList();
hosts.clickAction(hostList[0].name, 'Disable Maintenance Mode');
hosts.clickAction(hostNames[0], 'Disable Maintenance Mode');

// Check whether all nodes can be selected
vms.goToCreate();
Expand Down
22 changes: 22 additions & 0 deletions cypress/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

import AdmZip from 'adm-zip';
import { Node } from '@/models/host'
/**
* This will validate the zip file by checking the contents. Assumes that this is in
* the downloads folder
Expand Down Expand Up @@ -46,3 +47,24 @@ export function base64DecodeToBuffer(string: string) {
export function base64Decode(string: string) {
return !string ? string : base64DecodeToBuffer(string.replace(/[-_]/g, char => char === '-' ? '+' : '/')).toString();
}

export const host = {
list(): Node[] {
const hosts = Cypress.env('host');

if (!hosts || hosts.length < 1) {
throw new Error("No hosts defined in cypress env");
}

return hosts;
},
filterWitnessNode: (hosts: {name: string, witnessNode: boolean}[]) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

filterWitnessNode() and witnessNode config feild are not used in the code.
Are they prepare for future test cases use?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I would keep this code for future test cases.

const ret = hosts.filter((host) => !host.witnessNode);

if (!ret.length) {
throw new Error("No eligible hosts found for testing");
}

return ret;
}
}