Result
This commit is contained in:
53
src/index.ts
53
src/index.ts
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
144
test/index.ts
144
test/index.ts
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user