186 lines
5.4 KiB
JavaScript
186 lines
5.4 KiB
JavaScript
import { find, render } from '@ember/test-helpers';
|
|
import { module, test } from 'qunit';
|
|
import { setupRenderingTest } from 'ember-qunit';
|
|
import hbs from 'htmlbars-inline-precompile';
|
|
import { setupMirage } from 'ember-cli-mirage/test-support';
|
|
import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit';
|
|
import { create } from 'ember-cli-page-object';
|
|
import sinon from 'sinon';
|
|
import faker from 'nomad-ui/mirage/faker';
|
|
import topoVizDatacenterPageObject from 'nomad-ui/tests/pages/components/topo-viz/datacenter';
|
|
import { formatBytes, formatHertz } from 'nomad-ui/utils/units';
|
|
|
|
const TopoVizDatacenter = create(topoVizDatacenterPageObject());
|
|
|
|
const nodeGen = (name, datacenter, memory, cpu, allocations = []) => ({
|
|
datacenter,
|
|
memory,
|
|
cpu,
|
|
node: { name },
|
|
allocations: allocations.map((alloc) => ({
|
|
memory: alloc.memory,
|
|
cpu: alloc.cpu,
|
|
memoryPercent: alloc.memory / memory,
|
|
cpuPercent: alloc.cpu / cpu,
|
|
allocation: {
|
|
id: faker.random.uuid(),
|
|
isScheduled: true,
|
|
},
|
|
})),
|
|
});
|
|
|
|
// Used in Array#reduce to sum by a property common to an array of objects
|
|
const sumBy = (prop) => (sum, obj) => (sum += obj[prop]);
|
|
|
|
module('Integration | Component | TopoViz::Datacenter', function (hooks) {
|
|
setupRenderingTest(hooks);
|
|
setupMirage(hooks);
|
|
|
|
const commonProps = (props) => ({
|
|
isSingleColumn: true,
|
|
isDense: false,
|
|
heightScale: () => 50,
|
|
onAllocationSelect: sinon.spy(),
|
|
onNodeSelect: sinon.spy(),
|
|
...props,
|
|
});
|
|
|
|
const commonTemplate = hbs`
|
|
<TopoViz::Datacenter
|
|
@datacenter={{this.datacenter}}
|
|
@isSingleColumn={{this.isSingleColumn}}
|
|
@isDense={{this.isDense}}
|
|
@heightScale={{this.heightScale}}
|
|
@onAllocationSelect={{this.onAllocationSelect}}
|
|
@onNodeSelect={{this.onNodeSelect}} />
|
|
`;
|
|
|
|
test('presents as a div with a label and a FlexMasonry with a collection of nodes', async function (assert) {
|
|
this.setProperties(
|
|
commonProps({
|
|
datacenter: {
|
|
name: 'dc1',
|
|
nodes: [nodeGen('node-1', 'dc1', 1000, 500)],
|
|
},
|
|
})
|
|
);
|
|
|
|
await render(commonTemplate);
|
|
|
|
assert.ok(TopoVizDatacenter.isPresent);
|
|
assert.equal(TopoVizDatacenter.nodes.length, this.datacenter.nodes.length);
|
|
|
|
await componentA11yAudit(this.element, assert);
|
|
});
|
|
|
|
test('datacenter stats are an aggregate of node stats', async function (assert) {
|
|
this.setProperties(
|
|
commonProps({
|
|
datacenter: {
|
|
name: 'dc1',
|
|
nodes: [
|
|
nodeGen('node-1', 'dc1', 1000, 500, [
|
|
{ memory: 100, cpu: 300 },
|
|
{ memory: 200, cpu: 50 },
|
|
]),
|
|
nodeGen('node-2', 'dc1', 1500, 100, [
|
|
{ memory: 50, cpu: 80 },
|
|
{ memory: 100, cpu: 20 },
|
|
]),
|
|
nodeGen('node-3', 'dc1', 2000, 300),
|
|
nodeGen('node-4', 'dc1', 3000, 200),
|
|
],
|
|
},
|
|
})
|
|
);
|
|
|
|
await render(commonTemplate);
|
|
|
|
const allocs = this.datacenter.nodes.reduce(
|
|
(allocs, node) => allocs.concat(node.allocations),
|
|
[]
|
|
);
|
|
const memoryReserved = allocs.reduce(sumBy('memory'), 0);
|
|
const cpuReserved = allocs.reduce(sumBy('cpu'), 0);
|
|
const memoryTotal = this.datacenter.nodes.reduce(sumBy('memory'), 0);
|
|
const cpuTotal = this.datacenter.nodes.reduce(sumBy('cpu'), 0);
|
|
|
|
assert.ok(TopoVizDatacenter.label.includes(this.datacenter.name));
|
|
assert.ok(
|
|
TopoVizDatacenter.label.includes(`${this.datacenter.nodes.length} Nodes`)
|
|
);
|
|
assert.ok(TopoVizDatacenter.label.includes(`${allocs.length} Allocs`));
|
|
assert.ok(
|
|
TopoVizDatacenter.label.includes(
|
|
`${formatBytes(memoryReserved, 'MiB')}/${formatBytes(
|
|
memoryTotal,
|
|
'MiB'
|
|
)}`
|
|
)
|
|
);
|
|
assert.ok(
|
|
TopoVizDatacenter.label.includes(
|
|
`${formatHertz(cpuReserved, 'MHz')}/${formatHertz(cpuTotal, 'MHz')}`
|
|
)
|
|
);
|
|
});
|
|
|
|
test('when @isSingleColumn is true, the FlexMasonry layout gets one column, otherwise it gets two', async function (assert) {
|
|
this.setProperties(
|
|
commonProps({
|
|
isSingleColumn: true,
|
|
datacenter: {
|
|
name: 'dc1',
|
|
nodes: [
|
|
nodeGen('node-1', 'dc1', 1000, 500),
|
|
nodeGen('node-2', 'dc1', 1000, 500),
|
|
],
|
|
},
|
|
})
|
|
);
|
|
|
|
await render(commonTemplate);
|
|
|
|
assert.ok(find('[data-test-flex-masonry].flex-masonry-columns-1'));
|
|
|
|
this.set('isSingleColumn', false);
|
|
assert.ok(find('[data-test-flex-masonry].flex-masonry-columns-2'));
|
|
});
|
|
|
|
test('args get passed down to the TopViz::Node children', async function (assert) {
|
|
const heightSpy = sinon.spy();
|
|
this.setProperties(
|
|
commonProps({
|
|
isDense: true,
|
|
heightScale: (...args) => {
|
|
heightSpy(...args);
|
|
return 50;
|
|
},
|
|
datacenter: {
|
|
name: 'dc1',
|
|
nodes: [
|
|
nodeGen('node-1', 'dc1', 1000, 500, [{ memory: 100, cpu: 300 }]),
|
|
],
|
|
},
|
|
})
|
|
);
|
|
|
|
await render(commonTemplate);
|
|
|
|
TopoVizDatacenter.nodes[0].as(async (TopoVizNode) => {
|
|
assert.notOk(TopoVizNode.labelIsPresent);
|
|
assert.ok(heightSpy.calledWith(this.datacenter.nodes[0].memory));
|
|
|
|
await TopoVizNode.selectNode();
|
|
assert.ok(this.onNodeSelect.calledWith(this.datacenter.nodes[0]));
|
|
|
|
await TopoVizNode.memoryRects[0].select();
|
|
assert.ok(
|
|
this.onAllocationSelect.calledWith(
|
|
this.datacenter.nodes[0].allocations[0]
|
|
)
|
|
);
|
|
});
|
|
});
|
|
});
|