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

Compute tests #565

Merged
merged 5 commits into from
Apr 2, 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
234 changes: 234 additions & 0 deletions src/__tests__/unit/lib/compute.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
import {compute} from '../../../lib/compute';

import {ComputeParams} from '../../../types/compute';
import {pluginStorage} from '../../../util/plugin-storage';

describe('lib/compute: ', () => {
/**
* Mock plugins.
*/
const mockExecutePlugin = () => ({
execute: (inputs: any) =>
inputs.map((input: any) => {
input.newField = 'mock-newField';

return input;
}),
metadata: {
kind: 'execute',
},
});
const mockGroupByPlugin = () => ({
execute: (inputs: any) => ({children: inputs}),
metadata: {
kind: 'groupby',
},
});
/**
* Compute params.
*/
const paramsExecute: ComputeParams = {
context: {
name: 'mock-name',
initialize: {
plugins: {
mock: {
path: 'mockavizta',
method: 'Mockavizta',
},
},
},
},
pluginStorage: pluginStorage().set('mock', mockExecutePlugin()),
};
const params: ComputeParams = {
context: {
name: 'mock-name',
initialize: {
plugins: {
mock: {
path: 'mockavizta',
method: 'Mockavizta',
},
},
},
},
pluginStorage: pluginStorage().set('mock', mockGroupByPlugin()),
};

describe('compute(): ', () => {
it('computes simple tree with execute plugin.', async () => {
const tree = {
children: {
mockChild: {
pipeline: ['mock'],
inputs: [
{timestamp: 'mock-timestamp-1', duration: 10},
{timestamp: 'mock-timestamp-2', duration: 10},
],
},
},
};

const response = await compute(tree, paramsExecute);
const expectedResult = mockExecutePlugin().execute(
tree.children.mockChild.inputs
);

expect(response.children.mockChild.outputs).toEqual(expectedResult);
});

it('computes simple tree with groupby plugin.', async () => {
const tree = {
children: {
mockChild: {
pipeline: ['mock'],
inputs: [
{timestamp: 'mock-timestamp-1', duration: 10},
{timestamp: 'mock-timestamp-2', duration: 10},
],
},
},
};
const response = await compute(tree, params);
const expectedResult = mockGroupByPlugin().execute(
tree.children.mockChild.inputs
);

expect(response.children.mockChild.children).toEqual(expectedResult);
});

it('computes simple tree with defaults and execute plugin.', async () => {
const tree = {
children: {
mockChild: {
pipeline: ['mock'],
defaults: {
'cpu/name': 'Intel CPU',
},
inputs: [
{timestamp: 'mock-timestamp-1', duration: 10},
{timestamp: 'mock-timestamp-2', duration: 10},
],
},
},
};
const response = await compute(tree, paramsExecute);
const expectedResult = mockExecutePlugin().execute(
tree.children.mockChild.inputs.map((input: any) => {
input['cpu/name'] = 'Intel CPU';

return input;
})
);

expect(response.children.mockChild.outputs).toEqual(expectedResult);
});

it('computes nested tree with defaults and execute plugin.', async () => {
const tree = {
children: {
mockChild1: {
pipeline: ['mock'],
defaults: {
'cpu/name': 'Intel CPU',
},
inputs: [
{timestamp: 'mock-timestamp-1', duration: 10},
{timestamp: 'mock-timestamp-2', duration: 10},
],
},
mockChild2: {
children: {
mockChild21: {
pipeline: ['mock'],
defaults: {
'cpu/name': 'Intel CPU',
},
inputs: [
{timestamp: 'mock-timestamp-1', duration: 10},
{timestamp: 'mock-timestamp-2', duration: 10},
],
},
},
},
},
};
const response = await compute(tree, paramsExecute);

const mapper = (input: any) => {
input['cpu/name'] = 'Intel CPU';

return input;
};
const expectedResult1 = mockExecutePlugin().execute(
tree.children.mockChild1.inputs.map(mapper)
);
const expectedResult21 = mockExecutePlugin().execute(
tree.children.mockChild2.children.mockChild21.inputs.map(mapper)
);

expect(response.children.mockChild1.outputs).toEqual(expectedResult1);
expect(response.children.mockChild2.children.mockChild21.outputs).toEqual(
expectedResult21
);
});

it('computes simple tree with no defaults and no inputs with execue plugin.', async () => {
const tree = {
children: {
mockChild: {
pipeline: ['mock'],
defaults: {},
inputs: [],
},
},
};
const response = await compute(tree, paramsExecute);
const expectedResult: any[] = [];

expect(response.children.mockChild.outputs).toEqual(expectedResult);
});

it('computes simple tree with defaults and no inputs with execue plugin.', async () => {
const tree = {
children: {
mockChild: {
pipeline: ['mock'],
defaults: {
carbon: 10,
},
input: [],
},
},
};
const response = await compute(tree, paramsExecute);
const expectedResult: any[] = [{carbon: 10, newField: 'mock-newField'}];

expect(response.children.mockChild.outputs).toEqual(expectedResult);
});

it('computes simple tree with node config and execute plugin.', async () => {
const tree = {
children: {
mockChild: {
pipeline: ['mock'],
config: {
'cpu/name': 'Intel CPU',
},
inputs: [
{timestamp: 'mock-timestamp-1', duration: 10},
{timestamp: 'mock-timestamp-2', duration: 10},
],
},
},
};
const response = await compute(tree, paramsExecute);
const expectedResult = mockExecutePlugin().execute(
tree.children.mockChild.inputs
);

expect(response.children.mockChild.outputs).toEqual(expectedResult);
});
});
});
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const impactEngine = async () => {

const {tree, context, parameters} = await load(inputPath, paramPath);
parameterize.combine(context.params, parameters);
const plugins = await initalize(context.initialize.plugins);
const computedTree = await compute(tree, {context, plugins});
const pluginStorage = await initalize(context.initialize.plugins);
const computedTree = await compute(tree, {context, pluginStorage});
const aggregatedTree = aggregate(computedTree, context.aggregation);
context['if-version'] = packageJson.version;
exhaust(aggregatedTree, context, outputPath);
Expand Down
12 changes: 6 additions & 6 deletions src/lib/compute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,23 @@ const computeNode = async (node: Node, params: Params): Promise<any> => {
});
}

let storage = node.inputs as PluginParams[];
storage = mergeDefaults(storage, defaults);
let inputStorage = structuredClone(node.inputs) as PluginParams[];
inputStorage = mergeDefaults(inputStorage, defaults);
const pipelineCopy = structuredClone(pipeline);

while (pipelineCopy.length !== 0) {
const pluginName = pipelineCopy.shift() as string;
const plugin = params.plugins.get(pluginName);
const plugin = params.pluginStorage.get(pluginName);
const nodeConfig = config && config[pluginName];

if (isExecute(plugin)) {
storage = await plugin.execute(storage, nodeConfig);
node.outputs = storage;
inputStorage = await plugin.execute(inputStorage, nodeConfig);
node.outputs = inputStorage;
}

if (isGroupBy(plugin)) {
node.children = await plugin.execute(
storage,
inputStorage,
nodeConfig as GroupByConfig
);
delete node.inputs;
Expand Down
4 changes: 2 additions & 2 deletions src/types/compute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type NodeConfig = {
};

export type Params = {
plugins: PluginStorageInterface;
pluginStorage: PluginStorageInterface;
context: Context;
pipeline?: string[];
config?: NodeConfig;
Expand All @@ -25,5 +25,5 @@ export type Node = {

export type ComputeParams = {
context: Context;
plugins: PluginStorageInterface;
pluginStorage: PluginStorageInterface;
};
Loading