Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {CsvDirectoryReader} from '../../../../../lib/generic-cpu/helpers/csv-directory-reader';

describe('lib/generic-cpu/helpers:', () => {
describe('CsvDirectoryReader', () => {
describe('init: ', () => {
it('valid', () => {
const csvDirectoryReader: CsvDirectoryReader = new CsvDirectoryReader(
__dirname + '/test-data/'
);
const expected1 = {
simple1: [
['CPU_perc', 'Throughput_reqPerSec', 'POWER_W'],
['0', '0', '70'],
['10', '600000', '90'],
['20', '800000', '100'],
],
};
const expected2 = {
simple2: [
['CPU_perc', 'Throughput_reqPerSec', 'POWER_W'],
['0', '0', '90'],
['10', '700000', '100'],
['20', '900000', '110'],
],
};
expect(csvDirectoryReader.read(['simple1'])).toEqual(expected1);
expect(csvDirectoryReader.read(['simple2'])).toEqual(expected2);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {LinearInterpolator} from '../../../../../lib/generic-cpu/helpers/linear-interpolator';

describe('lib/generic-cpu/helpers:', () => {
describe('LinearInterpolator', () => {
describe('sanity: ', () => {
const linearnterpolator: LinearInterpolator = new LinearInterpolator();
const lookupSeries = [10, 20, 40, 100];
const valueSeries = [1000, 2000, 4000, 10000];
const invalidLookupSeries = [10, -20, 40, 100];
const invalidValueSeries = [1000, 2000, -4000, 10000];
it('out of range low', () => {
expect(
linearnterpolator.interpolate(5, lookupSeries, valueSeries)
).toEqual(500);
});
it('out of range high', () => {
expect(
linearnterpolator.interpolate(150, lookupSeries, valueSeries)
).toEqual(10000);
});
it('no interpolation needed', () => {
expect(
linearnterpolator.interpolate(40, lookupSeries, valueSeries)
).toEqual(4000);
});
it('interpolation', () => {
expect(
linearnterpolator.interpolate(50, lookupSeries, valueSeries)
).toEqual(5000);
});
it('interpolation with percision', () => {
expect(
linearnterpolator.interpolate(20.01, lookupSeries, valueSeries)
).toBeCloseTo(2001);
});
it('negative lookup key', () => {
const interpolateCall = () =>
linearnterpolator.interpolate(-20.01, lookupSeries, valueSeries);
expect(interpolateCall).toThrow(Error);
});
it('negative item in lookup series', () => {
const interpolateCall = () =>
linearnterpolator.interpolate(
20.01,
invalidLookupSeries,
valueSeries
);
expect(interpolateCall).toThrow(Error);
});
it('negative item in value series', () => {
const interpolateCall = () =>
linearnterpolator.interpolate(
20.01,
lookupSeries,
invalidValueSeries
);
expect(interpolateCall).toThrow(Error);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {CsvDirectoryReader} from '../../../../../lib/generic-cpu/helpers/csv-directory-reader';
import {LinearInterpolator} from '../../../../../lib/generic-cpu/helpers/linear-interpolator';
import {PowerCalculator} from '../../../../../lib/generic-cpu/helpers/power-calculator';

describe('lib/generic-cpu/helpers:', () => {
describe('CsvDirectoryReader', () => {
describe('sanity: ', () => {
const powerCalculator: PowerCalculator = new PowerCalculator(
['prod1', 'prod2'],
new CsvDirectoryReader(__dirname + '/test-data/'),
new LinearInterpolator()
);
it('calculate', () => {
expect(powerCalculator.calculate(15, 'prod1')).toEqual(95);
});
it('simulate', () => {
expect(powerCalculator.simulate(15, 'prod1', 'prod2')).toEqual(110);
});
it('calculate processor not found', () => {
const calculateCall = () => powerCalculator.calculate(15, 'prodX');
expect(calculateCall).toThrow(Error);
});
it('simulate physical processor not found', () => {
const simulateCall = () =>
powerCalculator.simulate(15, 'prodX', 'prod2');
expect(simulateCall).toThrow(Error);
});
it('simulate simualted processor not found', () => {
const simulateCall = () =>
powerCalculator.simulate(15, 'prod1', 'prodX');
expect(simulateCall).toThrow(Error);
});
});
});
});
13 changes: 13 additions & 0 deletions src/__tests__/unit/lib/generic-cpu/helpers/test-data/prod1.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CPU_perc,Throughput_reqPerSec,POWER_W
0,0,70
10,600000,90
20,800000,100
30,1100000,120
40,1400000,130
50,1800000,150
60,2200000,170
70,2500000,180
80,2600000,180
80,2700000,180
90,2750000,180
100,2800000,180
13 changes: 13 additions & 0 deletions src/__tests__/unit/lib/generic-cpu/helpers/test-data/prod2.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CPU_perc,Throughput_reqPerSec,POWER_W
0,0,70
10,600000,90
20,700000,110
30,1200000,130
40,1500000,140
50,1900000,170
60,2300000,180
70,2600000,190
80,2700000,200
80,2800000,210
90,2850000,220
100,2900000,220
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CPU_perc,Throughput_reqPerSec,POWER_W
0,0,70
10,600000,90
20,800000,100
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CPU_perc,Throughput_reqPerSec,POWER_W
0,0,90
10,700000,100
20,900000,110
149 changes: 149 additions & 0 deletions src/__tests__/unit/lib/generic-cpu/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import {GenericCPU} from '../../../../lib';
import {PluginParams} from '../../../../types/common';

describe('lib/generic-cpu/helpers:', () => {
describe('CsvDirectoryReader', () => {
describe('sanity: ', () => {
it('calculate-no-interpolation', async () => {
const globalConfig = {
'power-curves-root-dir': __dirname + '/helpers/test-data/',
'physical-processor': 'prod1',
};
const inputs: PluginParams[] = [
{
duration: 1,
'cpu/utilization': 20,
timestamp: '2021-01-01T00:00:00Z',
},
{
duration: 1,
'cpu/utilization': 30,
timestamp: '2021-01-01T00:00:01Z',
},
{
duration: 1,
'cpu/utilization': 90,
timestamp: '2021-01-01T00:00:02Z',
},
];
const expected: PluginParams[] = [
{
duration: 1,
'cpu/utilization': 20, // => 100 W
timestamp: '2021-01-01T00:00:00Z',
'cpu/energy': 0.000027777777777777776, // (100 * 1/3600) / 1000
},
{
duration: 1,
'cpu/utilization': 30, // => 120 W
timestamp: '2021-01-01T00:00:01Z',
'cpu/energy': 0.000033333333333333335, // (120 * 1/3600) / 1000
},
{
duration: 1,
'cpu/utilization': 90, // => 180 W
timestamp: '2021-01-01T00:00:02Z',
'cpu/energy': 0.00005, // (120 * 1/3600) / 1000
},
];
const genericCpu = GenericCPU(globalConfig);
const actual = await genericCpu.execute(inputs);
expect(actual).toEqual(expected);
});

it('calculate-with-interpolation', async () => {
const globalConfig = {
'power-curves-root-dir': __dirname + '/helpers/test-data/',
'physical-processor': 'prod1',
};
const inputs: PluginParams[] = [
{
duration: 1,
'cpu/utilization': 15,
timestamp: '2021-01-01T00:00:00Z',
},
{
duration: 1,
'cpu/utilization': 24,
timestamp: '2021-01-01T00:00:01Z',
},
{
duration: 1,
'cpu/utilization': 61,
timestamp: '2021-01-01T00:00:02Z',
},
];
const expected: PluginParams[] = [
{
duration: 1,
'cpu/utilization': 15, // => 95 W
timestamp: '2021-01-01T00:00:00Z',
'cpu/energy': 0.00002638888888888889, // (95 * 1/3600) / 1000
},
{
duration: 1,
'cpu/utilization': 24, // => 108 W
timestamp: '2021-01-01T00:00:01Z',
'cpu/energy': 0.000029999999999999997, // (108 * 1/3600) / 1000
},
{
duration: 1,
'cpu/utilization': 61, // => 171 W
timestamp: '2021-01-01T00:00:02Z',
'cpu/energy': 0.0000475, // (171 * 1/3600) / 1000
},
];
const genericCpu = GenericCPU(globalConfig);
const actual = await genericCpu.execute(inputs);
expect(actual).toEqual(expected);
});
it('simulate-with-interpolation', async () => {
const globalConfig = {
'power-curves-root-dir': __dirname + '/helpers/test-data/',
'physical-processor': 'prod1',
'simulated-processor': 'prod2',
};
const inputs: PluginParams[] = [
{
duration: 1,
'cpu/utilization': 20,
timestamp: '2021-01-01T00:00:00Z',
},
{
duration: 1,
'cpu/utilization': 55,
timestamp: '2021-01-01T00:00:01Z',
},
{
duration: 1,
'cpu/utilization': 61,
timestamp: '2021-01-01T00:00:02Z',
},
];
const expected: PluginParams[] = [
{
duration: 1,
'cpu/utilization': 20, // => 800000 req/sec => 22% => 114 W
timestamp: '2021-01-01T00:00:00Z',
'cpu/energy': 0.000031666666666666666, // (114 * 1/3600) / 1000
},
{
duration: 1,
'cpu/utilization': 55, // => 2000000 req/sec => 52.5% => 172.5 W
timestamp: '2021-01-01T00:00:01Z',
'cpu/energy': 0.00004791666666666667, // (172.5 * 1/3600) / 1000
},
{
duration: 1,
'cpu/utilization': 61, // => 2230000 req/sec => 58.25% => 178.25 W
timestamp: '2021-01-01T00:00:02Z',
'cpu/energy': 0.00004951388888888889, // (178.25 * 1/3600) / 1000
},
];
const genericCpu = GenericCPU(globalConfig);
const actual = await genericCpu.execute(inputs);
expect(actual).toEqual(expected);
});
});
});
});
53 changes: 53 additions & 0 deletions src/__tests__/unit/lib/generic-cpu/models/data-table.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {DataTable} from '../../../../../lib/generic-cpu/models/data-table';

describe('lib/generic-cpu/models:', () => {
describe('DataTable', () => {
describe('init: ', () => {
it('valid input data.', () => {
const inputData = [
['id', 'grade', 'age'],
['6565464', '89', '12'],
['1230985', '91', '11'],
['1237899', '100', '12'],
];
const dataTable = new DataTable(inputData);
expect(dataTable.getSize()).toEqual(3);
expect(dataTable.getColumnData('id')).toEqual([
6565464, 1230985, 1237899,
]);
expect(dataTable.getColumnData('grade')).toEqual([89, 91, 100]);
expect(dataTable.getColumnData('age')).toEqual([12, 11, 12]);
});
it('missing header.', () => {
const inputData = [
['id', '', 'age'],
['6565464', '89', '12'],
['1230985', '91', '11'],
['1237899', '100', '12'],
];
const constructorCall = () => new DataTable(inputData);
expect(constructorCall).toThrow(Error);
});
it('missing value.', () => {
const inputData = [
['id', 'grade', 'age'],
['6565464', '', '12'],
['1230985', '91', '11'],
['1237899', '100', '12'],
];
const constructorCall = () => new DataTable(inputData);
expect(constructorCall).toThrow(Error);
});
it('invalid value (NaN).', () => {
const inputData = [
['id', 'grade', 'age'],
['6565464', '89', '12'],
['1230985', 'qewrwrt', '11'],
['1237899', '100', '12'],
];
const constructorCall = () => new DataTable(inputData);
expect(constructorCall).toThrow(Error);
});
});
});
});
Loading