Skip to content

Commit

Permalink
Acceptance tests for node driver and node events
Browse files Browse the repository at this point in the history
  • Loading branch information
DingoEatingFuzz committed May 21, 2018
1 parent fd9a890 commit e388bc1
Show file tree
Hide file tree
Showing 12 changed files with 278 additions and 33 deletions.
2 changes: 2 additions & 0 deletions ui/app/components/list-accordion/accordion-head.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export default Component.extend({
classNames: ['accordion-head'],
classNameBindings: ['isOpen::is-light', 'isExpandable::is-inactive'],

'data-test-accordion-head': true,

buttonLabel: 'toggle',
isOpen: false,
isExpandable: true,
Expand Down
2 changes: 1 addition & 1 deletion ui/app/templates/allocations/allocation/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<tr data-test-task-row={{row.model.task.name}}>
<td class="is-narrow">
{{#if (not row.model.driverStatus.healthy)}}
<span class="tooltip text-center" aria-label="{{row.model.driver}} is unhealthy">
<span data-test-icon="unhealthy-driver" class="tooltip text-center" aria-label="{{row.model.driver}} is unhealthy">
{{x-icon "warning" class="is-warning"}}
</span>
{{/if}}
Expand Down
24 changes: 12 additions & 12 deletions ui/app/templates/clients/client.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
</div>
</div>

<div class="boxed-section">
<div data-test-client-events class="boxed-section">
<div class="boxed-section-head">
Client Events
</div>
Expand All @@ -105,10 +105,10 @@
<th>Message</th>
{{/t.head}}
{{#t.body as |row|}}
<tr data-test-node-event>
<td data-test-task-event-time>{{moment-format row.model.time "MM/DD/YY HH:mm:ss"}}</td>
<td data-test-task-event-type>{{row.model.subsystem}}</td>
<td data-test-task-event-message>
<tr data-test-client-event>
<td data-test-client-event-time>{{moment-format row.model.time "MM/DD/YY HH:mm:ss"}}</td>
<td data-test-client-event-subsystem>{{row.model.subsystem}}</td>
<td data-test-client-event-message>
{{#if row.model.message}}
{{row.model.message}}
{{else}}
Expand All @@ -121,7 +121,7 @@
</div>
</div>

<div class="boxed-section">
<div data-test-driver-status class="boxed-section">
<div class="boxed-section-head">
Driver Status
</div>
Expand All @@ -130,11 +130,11 @@
{{#a.head buttonLabel="details" isExpandable=a.item.detected}}
<div class="columns inline-definitions {{unless a.item.detected "is-faded"}}">
<div class="column is-1">
<span>{{a.item.name}}</span>
<span data-test-name>{{a.item.name}}</span>
</div>
<div class="column is-2">
{{#if a.item.detected}}
<span>
<span data-test-health>
<span class="color-swatch {{a.item.healthClass}}"></span>
{{if a.item.healthy "Healthy" "Unhealthy"}}
</span>
Expand All @@ -143,20 +143,20 @@
<div class="column">
<span class="pair">
<span class="term">Detected</span>
{{if a.item.detected "Yes" "No"}}
<span data-test-detected>{{if a.item.detected "Yes" "No"}}</span>
</span>
<span class="is-pulled-right">
<span class="pair">
<span class="term">Last Updated</span>
{{moment-from-now a.item.updateTime interval=1000}}
<span data-test-last-updated>{{moment-from-now a.item.updateTime interval=1000}}</span>
</span>
</span>
</div>
</div>
{{/a.head}}
{{#a.body}}
<p class="message">{{a.item.healthDescription}}</p>
<div class="boxed-section">
<p data-test-health-description class="message">{{a.item.healthDescription}}</p>
<div data-test-driver-attributes class="boxed-section">
<div class="boxed-section-head">
{{capitalize a.item.name}} Attributes
</div>
Expand Down
4 changes: 2 additions & 2 deletions ui/app/templates/components/allocation-row.hbs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<td data-test-indicators class="is-narrow">
{{#if allocation.unhealthyDrivers.length}}
<span class="tooltip text-center" aria-label="Allocation depends on unhealthy drivers">
<span data-test-icon="unhealthy-driver" class="tooltip text-center" aria-label="Allocation depends on unhealthy drivers">
{{x-icon "warning" class="is-warning"}}
</span>
{{/if}}
{{#if allocation.nextAllocation}}
<span class="tooltip text-center" aria-label="Allocation was rescheduled">
<span data-test-icon="reschedule" class="tooltip text-center" aria-label="Allocation was rescheduled">
{{x-icon "history" class="is-faded"}}
</span>
{{/if}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{#if isOpen}}
<div class="accordion-body">
<div data-test-accordion-body class="accordion-body">
{{yield}}
</div>
{{/if}}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{{yield}}
</div>
<button
data-test-accordion-toggle
class="button is-light is-compact pull-right accordion-toggle {{unless isExpandable "is-invisible"}}"
onclick={{action (if isOpen onClose onOpen) item}}>
{{buttonLabel}}
Expand Down
22 changes: 21 additions & 1 deletion ui/tests/acceptance/allocation-detail-test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import $ from 'jquery';
import { assign } from '@ember/polyfills';
import { click, findAll, currentURL, find, visit, waitFor } from 'ember-native-dom-helpers';
import { test } from 'qunit';
import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance';
Expand All @@ -13,9 +14,24 @@ moduleForAcceptance('Acceptance | allocation detail', {
server.create('agent');

node = server.create('node');
job = server.create('job', { groupCount: 0 });
job = server.create('job', { groupCount: 0, createAllocations: false });
allocation = server.create('allocation', 'withTaskWithPorts');

// Make sure the node has an unhealthy driver
node.update({
driver: assign(node.drivers, {
docker: {
detected: true,
healthy: false,
},
}),
});

// Make sure a task for the allocation depends on the unhealthy driver
server.schema.tasks.first().update({
driver: 'docker',
});

visit(`/allocations/${allocation.id}`);
},
});
Expand Down Expand Up @@ -121,6 +137,10 @@ test('each task row should list high-level information for the task', function(a
});
});

test('tasks with an unhealthy driver have a warning icon', function(assert) {
assert.ok(find('[data-test-task-row] [data-test-icon="unhealthy-driver"]'), 'Warning is shown');
});

test('when the allocation has not been rescheduled, the reschedule events section is not rendered', function(assert) {
assert.notOk(find('[data-test-reschedule-events]'), 'Reschedule Events section exists');
});
Expand Down
193 changes: 181 additions & 12 deletions ui/tests/acceptance/client-detail-test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { assign } from '@ember/polyfills';
import $ from 'jquery';
import { click, find, findAll, currentURL, visit } from 'ember-native-dom-helpers';
import { test } from 'qunit';
Expand All @@ -24,12 +25,12 @@ test('/clients/:id should have a breadcrumb trail linking back to clients', func

andThen(() => {
assert.equal(
find('[data-test-breadcrumb="clients"]').textContent,
find('[data-test-breadcrumb="clients"]').textContent.trim(),
'Clients',
'First breadcrumb says clients'
);
assert.equal(
find('[data-test-breadcrumb="client"]').textContent,
find('[data-test-breadcrumb="client"]').textContent.trim(),
node.id.split('-')[0],
'Second breadcrumb says the node short id'
);
Expand Down Expand Up @@ -58,23 +59,26 @@ test('/clients/:id should list additional detail for the node below the title',
visit(`/clients/${node.id}`);

andThen(() => {
assert.equal(
findAll('.inline-definitions .pair')[0].textContent,
`Status ${node.status}`,
assert.ok(
find('.inline-definitions .pair')
.textContent.trim()
.includes(node.status),
'Status is in additional details'
);
assert.ok(
$('[data-test-status-definition] .status-text').hasClass(`node-${node.status}`),
'Status is decorated with a status class'
);
assert.equal(
find('[data-test-address-definition]').textContent,
`Address ${node.httpAddr}`,
assert.ok(
find('[data-test-address-definition]')
.textContent.trim()
.includes(node.httpAddr),
'Address is in additional details'
);
assert.equal(
find('[data-test-datacenter-definition]').textContent,
`Datacenter ${node.datacenter}`,
assert.ok(
find('[data-test-datacenter-definition]')
.textContent.trim()
.includes(node.datacenter),
'Datacenter is in additional details'
);
});
Expand Down Expand Up @@ -330,9 +334,174 @@ test('when the node is not found, an error message is shown, but the URL persist
assert.equal(currentURL(), '/clients/not-a-real-node', 'The URL persists');
assert.ok(find('[data-test-error]'), 'Error message is shown');
assert.equal(
find('[data-test-error-title]').textContent,
find('[data-test-error-title]').textContent.trim(),
'Not Found',
'Error message is for 404'
);
});
});

test('/clients/:id shows the recent events list', function(assert) {
visit(`/clients/${node.id}`);

andThen(() => {
assert.ok(find('[data-test-client-events]'), 'Client events section exists');
});
});

test('each node event shows basic node event information', function(assert) {
const event = server.db.nodeEvents
.where({ nodeId: node.id })
.sortBy('time')
.reverse()[0];

visit(`/clients/${node.id}`);

andThen(() => {
const eventRow = $(find('[data-test-client-event]'));
assert.equal(
eventRow
.find('[data-test-client-event-time]')
.text()
.trim(),
moment(event.time).format('MM/DD/YY HH:mm:ss'),
'Event timestamp'
);
assert.equal(
eventRow
.find('[data-test-client-event-subsystem]')
.text()
.trim(),
event.subsystem,
'Event subsystem'
);
assert.equal(
eventRow
.find('[data-test-client-event-message]')
.text()
.trim(),
event.message,
'Event message'
);
});
});

test('/clients/:id shows the driver status of every driver for the node', function(assert) {
// Set the drivers up so health and detection is well tested
const nodeDrivers = node.drivers;
const undetectedDriver = 'raw_exec';

Object.values(nodeDrivers).forEach(driver => {
driver.Detected = true;
});

nodeDrivers[undetectedDriver].Detected = false;
node.drivers = nodeDrivers;

const drivers = Object.keys(node.drivers)
.map(driverName => assign({ Name: driverName }, node.drivers[driverName]))
.sortBy('Name');

assert.ok(drivers.length > 0, 'Node has drivers');

visit(`/clients/${node.id}`);

andThen(() => {
const driverRows = findAll('[data-test-driver-status] [data-test-accordion-head]');

drivers.forEach((driver, index) => {
const driverRow = $(driverRows[index]);

assert.equal(
driverRow
.find('[data-test-name]')
.text()
.trim(),
driver.Name,
`${driver.Name}: Name is correct`
);
assert.equal(
driverRow
.find('[data-test-detected]')
.text()
.trim(),
driver.Detected ? 'Yes' : 'No',
`${driver.Name}: Detection is correct`
);
assert.equal(
driverRow
.find('[data-test-last-updated]')
.text()
.trim(),
moment(driver.UpdateTime).fromNow(),
`${driver.Name}: Last updated shows time since now`
);

if (driver.Name === undetectedDriver) {
assert.notOk(
driverRow.find('[data-test-health]').length,
`${driver.Name}: No health for the undetected driver`
);
} else {
assert.equal(
driverRow
.find('[data-test-health]')
.text()
.trim(),
driver.Healthy ? 'Healthy' : 'Unhealthy',
`${driver.Name}: Health is correct`
);
assert.ok(
driverRow
.find('[data-test-health] .color-swatch')
.hasClass(driver.Healthy ? 'running' : 'failed'),
`${driver.Name}: Swatch with correct class is shown`
);
}
});
});
});

test('each driver can be opened to see a message and attributes', function(assert) {
// Only detected drivers can be expanded
const nodeDrivers = node.drivers;
Object.values(nodeDrivers).forEach(driver => {
driver.Detected = true;
});
node.drivers = nodeDrivers;

const driver = Object.keys(node.drivers)
.map(driverName => assign({ Name: driverName }, node.drivers[driverName]))
.sortBy('Name')[0];

visit(`/clients/${node.id}`);

andThen(() => {
const driverBody = $(find('[data-test-driver-status] [data-test-accordion-body]'));
assert.notOk(
driverBody.find('[data-test-health-description]').length,
'Driver health description is not shown'
);
assert.notOk(
driverBody.find('[data-test-driver-attributes]').length,
'Driver attributes section is not shown'
);
click('[data-test-driver-status] [data-test-accordion-toggle]');
});

andThen(() => {
const driverBody = $(find('[data-test-driver-status] [data-test-accordion-body]'));
assert.equal(
driverBody
.find('[data-test-health-description]')
.text()
.trim(),
driver.HealthDescription,
'Driver health description is now shown'
);
assert.ok(
driverBody.find('[data-test-driver-attributes]').length,
'Driver attributes section is now shown'
);
});
});
Loading

0 comments on commit e388bc1

Please sign in to comment.