Skip to content

Commit

Permalink
Acceptance test for PluginDetail
Browse files Browse the repository at this point in the history
  • Loading branch information
DingoEatingFuzz committed May 7, 2020
1 parent 6b46b28 commit 877cadf
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 17 deletions.
10 changes: 5 additions & 5 deletions ui/app/templates/csi/plugins/plugin.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{title "CSI Plugin " model.id}}
{{title "CSI Plugin " model.plainId}}
<section class="section with-headspace">
<h1 class="title" data-test-title>{{model.plainId}}</h1>

Expand Down Expand Up @@ -26,7 +26,7 @@
<div class="boxed-section-head">
Controller Allocations
</div>
<div class="boxed-section-body is-full-bleed">
<div class="boxed-section-body {{if model.controllers "is-full-bleed"}}">
{{#if model.controllers}}
{{#list-table
source=sortedControllers
Expand All @@ -46,7 +46,7 @@
{{/t.head}}
{{#t.body as |row|}}
{{plugin-allocation-row
data-test-controller-allocation=row.model.id
data-test-controller-allocation=row.model.allocID
pluginAllocation=row.model}}
{{/t.body}}
{{/list-table}}
Expand All @@ -63,7 +63,7 @@
<div class="boxed-section-head">
Node Allocations
</div>
<div class="boxed-section-body is-full-bleed">
<div class="boxed-section-body {{if model.nodes "is-full-bleed"}}">
{{#if model.nodes}}
{{#list-table
source=sortedNodes
Expand All @@ -83,7 +83,7 @@
{{/t.head}}
{{#t.body as |row|}}
{{plugin-allocation-row
data-test-node-allocation=row.model.id
data-test-node-allocation=row.model.allocID
pluginAllocation=row.model}}
{{/t.body}}
{{/list-table}}
Expand Down
20 changes: 9 additions & 11 deletions ui/mirage/factories/csi-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ export default Factory.extend({
provider: faker.helpers.randomize(STORAGE_PROVIDERS),
version: '1.0.1',
controllerRequired: faker.random.boolean,
controllersHealthy: () => faker.random.number(10),
controllersHealthy: () => faker.random.number(3),
controllersExpected() {
return this.controllersHealthy + faker.random.number(10);
return this.controllersHealthy + faker.random.number({ min: 1, max: 2 });
},

nodesHealthy: () => faker.random.number(10),
nodesHealthy: () => faker.random.number(3),
nodesExpected() {
return this.nodesHealthy + faker.random.number(10);
return this.nodesHealthy + faker.random.number({ min: 1, max: 2 });
},

// Internal property to determine whether or not this plugin
Expand All @@ -36,20 +36,18 @@ export default Factory.extend({

if (plugin.isMonolith) {
const pluginJob = server.create('job', { type: 'service', createAllocations: false });
const count = faker.random.number({ min: 1, max: 5 });
const count = plugin.nodesExpected;
storageNodes = server.createList('storage-node', count, { job: pluginJob });
storageControllers = server.createList('storage-controller', count, { job: pluginJob });
} else {
const controllerJob = server.create('job', { type: 'service', createAllocations: false });
const nodeJob = server.create('job', { type: 'service', createAllocations: false });
storageNodes = server.createList('storage-node', faker.random.number({ min: 1, max: 5 }), {
storageNodes = server.createList('storage-node', plugin.nodesExpected, {
job: nodeJob,
});
storageControllers = server.createList(
'storage-controller',
faker.random.number({ min: 1, max: 5 }),
{ job: controllerJob }
);
storageControllers = server.createList('storage-controller', plugin.controllersExpected, {
job: controllerJob,
});
}

plugin.update({
Expand Down
164 changes: 164 additions & 0 deletions ui/tests/acceptance/plugin-detail-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { module, test } from 'qunit';
import { currentURL } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import moment from 'moment';
import { formatBytes } from 'nomad-ui/helpers/format-bytes';
import PluginDetail from 'nomad-ui/tests/pages/storage/plugins/detail';

module('Acceptance | plugin detail', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);

let plugin;

hooks.beforeEach(function() {
server.create('node');
plugin = server.create('csi-plugin');
});

test('/csi/plugins/:id should have a breadcrumb trail linking back to Plugins and Storage', async function(assert) {
await PluginDetail.visit({ id: plugin.id });

assert.equal(PluginDetail.breadcrumbFor('csi.index').text, 'Storage');
assert.equal(PluginDetail.breadcrumbFor('csi.plugins').text, 'Plugins');
assert.equal(PluginDetail.breadcrumbFor('csi.plugins.plugin').text, plugin.id);
});

test('/csi/plugins/:id should show the plugin name in the title', async function(assert) {
await PluginDetail.visit({ id: plugin.id });

assert.equal(document.title, `CSI Plugin ${plugin.id} - Nomad`);
assert.equal(PluginDetail.title, plugin.id);
});

test('/csi/plugins/:id should list additional details for the plugin below the title', async function(assert) {
await PluginDetail.visit({ id: plugin.id });

assert.ok(
PluginDetail.controllerHealth.includes(
`${Math.round((plugin.controllersHealthy / plugin.controllersExpected) * 100)}%`
)
);
assert.ok(
PluginDetail.controllerHealth.includes(
`${plugin.controllersHealthy}/${plugin.controllersExpected}`
)
);
assert.ok(
PluginDetail.nodeHealth.includes(
`${Math.round((plugin.nodesHealthy / plugin.nodesExpected) * 100)}%`
)
);
assert.ok(PluginDetail.nodeHealth.includes(`${plugin.nodesHealthy}/${plugin.nodesExpected}`));
assert.ok(PluginDetail.provider.includes(plugin.provider));
});

test('/csi/plugins/:id should list all the controller plugin allocations for the plugin', async function(assert) {
await PluginDetail.visit({ id: plugin.id });

assert.equal(PluginDetail.controllerAllocations.length, plugin.controllers.length);
plugin.controllers.models
.sortBy('updateTime')
.reverse()
.forEach((allocation, idx) => {
assert.equal(PluginDetail.controllerAllocations.objectAt(idx).id, allocation.allocID);
});
});

test('/csi/plugins/:id should list all the node plugin allocations for the plugin', async function(assert) {
await PluginDetail.visit({ id: plugin.id });

assert.equal(PluginDetail.nodeAllocations.length, plugin.nodes.length);
plugin.nodes.models
.sortBy('updateTime')
.reverse()
.forEach((allocation, idx) => {
assert.equal(PluginDetail.nodeAllocations.objectAt(idx).id, allocation.allocID);
});
});

test('each allocation should have high-level details for the allocation', async function(assert) {
const controller = plugin.controllers.models.sortBy('updateTime').reverse()[0];
const allocation = server.db.allocations.find(controller.allocID);
const allocStats = server.db.clientAllocationStats.find(allocation.id);
const taskGroup = server.db.taskGroups.findBy({
name: allocation.taskGroup,
jobId: allocation.jobId,
});

const tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id));
const cpuUsed = tasks.reduce((sum, task) => sum + task.Resources.CPU, 0);
const memoryUsed = tasks.reduce((sum, task) => sum + task.Resources.MemoryMB, 0);

await PluginDetail.visit({ id: plugin.id });

PluginDetail.controllerAllocations.objectAt(0).as(allocationRow => {
assert.equal(allocationRow.shortId, allocation.id.split('-')[0], 'Allocation short ID');
assert.equal(
allocationRow.createTime,
moment(allocation.createTime / 1000000).format('MMM D')
);
assert.equal(
allocationRow.createTooltip,
moment(allocation.createTime / 1000000).format('MMM DD HH:mm:ss ZZ')
);
assert.equal(allocationRow.modifyTime, moment(allocation.modifyTime / 1000000).fromNow());
assert.equal(allocationRow.health, controller.healthy ? 'Healthy' : 'Unhealthy');
assert.equal(
allocationRow.client,
server.db.nodes.find(allocation.nodeId).id.split('-')[0],
'Node ID'
);
assert.equal(allocationRow.job, server.db.jobs.find(allocation.jobId).name, 'Job name');
assert.ok(allocationRow.taskGroup, 'Task group name');
assert.ok(allocationRow.jobVersion, 'Job Version');
assert.equal(
allocationRow.cpu,
Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks) / cpuUsed,
'CPU %'
);
assert.equal(
allocationRow.cpuTooltip,
`${Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks)} / ${cpuUsed} MHz`,
'Detailed CPU information is in a tooltip'
);
assert.equal(
allocationRow.mem,
allocStats.resourceUsage.MemoryStats.RSS / 1024 / 1024 / memoryUsed,
'Memory used'
);
assert.equal(
allocationRow.memTooltip,
`${formatBytes([allocStats.resourceUsage.MemoryStats.RSS])} / ${memoryUsed} MiB`,
'Detailed memory information is in a tooltip'
);
});
});

test('each allocation should link to the allocation detail page', async function(assert) {
const controller = plugin.controllers.models.sortBy('updateTime').reverse()[0];

await PluginDetail.visit({ id: plugin.id });
await PluginDetail.controllerAllocations.objectAt(0).visit();

assert.equal(currentURL(), `/allocations/${controller.allocID}`);
});

test('when there are no plugin allocations, the tables present empty states', async function(assert) {
const emptyPlugin = server.create('csi-plugin', {
controllersHealthy: 0,
controllersExpected: 0,
nodesHealthy: 0,
nodesExpected: 0,
});

await PluginDetail.visit({ id: emptyPlugin.id });

assert.ok(PluginDetail.controllerTableIsEmpty);
assert.equal(PluginDetail.controllerEmptyState.headline, 'No Controller Plugin Allocations');

assert.ok(PluginDetail.nodeTableIsEmpty);
assert.equal(PluginDetail.nodeEmptyState.headline, 'No Node Plugin Allocations');
});
});
2 changes: 1 addition & 1 deletion ui/tests/acceptance/volume-detail-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module('Acceptance | volume detail', function(hooks) {
volume = server.create('csi-volume');
});

test('/csi/volumes/:id should have a breadcrumb trail linking back to Volumes and CSI', async function(assert) {
test('/csi/volumes/:id should have a breadcrumb trail linking back to Volumes and Storage', async function(assert) {
await VolumeDetail.visit({ id: volume.id });

assert.equal(VolumeDetail.breadcrumbFor('csi.index').text, 'Storage');
Expand Down
2 changes: 2 additions & 0 deletions ui/tests/pages/components/allocations.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export default function(selector = '[data-test-allocation]', propKey = 'allocati
id: attribute(attr),
shortId: text('[data-test-short-id]'),
createTime: text('[data-test-create-time]'),
createTooltip: attribute('aria-label', '[data-test-create-time] .tooltip'),
modifyTime: text('[data-test-modify-time]'),
health: text('[data-test-health]'),
status: text('[data-test-client-status]'),
job: text('[data-test-job]'),
taskGroup: text('[data-test-task-group]'),
Expand Down

0 comments on commit 877cadf

Please sign in to comment.