This commit is contained in:
Sebastian Seedorf
2020-12-07 20:54:25 +01:00
parent 72b9985e3e
commit afbdcec28a
2 changed files with 184 additions and 13 deletions

View File

@@ -1,5 +1,52 @@
export class SampleClass {
add(a: number, b: number): number {
return a+b;
export interface VM {
cpu: number,
memory: number,
network: number,
}
export interface ServerCapacity {
limitCpu: number,
limitMemory: number,
limitNetwork: number,
}
export type Server = Set<VM>;
export class ServerConsolidation {
doesVmFitOnServer(vm: VM, capacity: ServerCapacity): boolean {
return vm.cpu <= capacity.limitCpu &&
vm.memory <= capacity.limitMemory &&
vm.network <= capacity.limitNetwork;
}
reduceCapacity(vm: VM, capacity: ServerCapacity): void {
capacity.limitCpu -= vm.cpu;
capacity.limitMemory -= vm.memory;
capacity.limitNetwork -= vm.network;
}
fit(vms: VM[], capacity: ServerCapacity): Server[] {
const servers: Server[] = [];
const capacitiesLeft: ServerCapacity[] = [];
for (const vm of vms) {
let found = false;
for (const [idx, server] of servers.entries()) {
const capacity = capacitiesLeft[idx];
if (this.doesVmFitOnServer(vm, capacity)) {
found = true;
server.add(vm);
this.reduceCapacity(vm, capacity);
break;
}
}
if (!found) {
servers.push(new Set([vm]));
const newCapacity = {...capacity};
this.reduceCapacity(vm, newCapacity);
capacitiesLeft.push(newCapacity);
}
}
return servers;
}
}

View File

@@ -1,16 +1,140 @@
import {expect} from 'chai';
import {SampleClass} from '../src';
import {ServerCapacity, ServerConsolidation, VM, Server} from '../src';
describe('index', () => {
it('main', () => {
const cls = new SampleClass();
const cases: [number, number, unknown][] = [
[2, 3, 5],
[2, 0, 2],
[500, -10, 490],
interface TestCase {
vms: VM[],
capacity: ServerCapacity,
results: Server[],
}
describe('ServerConsolidation - fit', () => {
const cls = new ServerConsolidation();
const vms: {[name: string]: VM} = {
'a': {
cpu: 1,
memory: 1,
network: 1,
},
'b': {
cpu: 2,
memory: 2,
network: 2,
},
'b-copy': {
cpu: 2,
memory: 2,
network: 2,
},
'large': {
cpu: 10,
memory: 10,
network: 10,
},
'd': {
cpu: 3,
memory: 3,
network: 3,
},
};
it('should match server allocation', () => {
const cases: TestCase[] = [
// every vm fits on a single server
{
vms: [vms.a, vms.b],
capacity: {
limitCpu: 10,
limitMemory: 10,
limitNetwork: 10,
},
results: [
new Set([vms.a, vms.b]),
],
},
// multiple servers needed
{
vms: [vms.a, vms.b, vms.large],
capacity: {
limitCpu: 10,
limitMemory: 10,
limitNetwork: 10,
},
results: [
new Set([vms.a, vms.b]),
new Set([vms.large]),
],
},
// reuse of existing servers
{
vms: [
vms.a, vms.b, vms.large, vms.d],
capacity: {
limitCpu: 10,
limitMemory: 10,
limitNetwork: 10,
},
results: [
new Set([vms.a, vms.b, vms.d]),
new Set([vms.large]),
],
},
];
for (const [a, b, res] of cases) {
expect(cls.add(a, b)).to.be.deep.equal(res);
for (const {vms, capacity, results} of cases) {
const servers = cls.fit(vms, capacity);
for (const [idx, server] of servers.entries()) {
const result = results[idx];
expect(server).to.eqls(result);
}
}
});
it('should match reference', () => {
const cases: TestCase[] = [
// same reference of objects
{
vms: [
vms.a,
],
capacity: {
limitCpu: 10,
limitMemory: 10,
limitNetwork: 10,
},
results: [
new Set([
vms.a,
]),
],
},
];
for (const {vms, capacity, results} of cases) {
const servers = cls.fit(vms, capacity);
for (const server of servers[0]) {
results[0].has(server);
}
}
});
});
describe('ServerConsolidation - reduceCapacity', () => {
const cls = new ServerConsolidation();
it('should equal', () => {
const capacity: ServerCapacity = {
limitCpu: 10,
limitMemory: 3,
limitNetwork: 9,
};
const vm: VM = {
cpu: 3,
memory: 1,
network: 0,
};
const result: ServerCapacity = {
limitCpu: 7,
limitMemory: 2,
limitNetwork: 9,
};
cls.reduceCapacity(vm, capacity);
expect(capacity).to.deep.equal(result);
});
});