mirror of
https://github.com/kemko/nomad.git
synced 2026-01-07 10:55:42 +03:00
Merge pull request #3777 from johncowen/f-ui-api-task-events-messages
UI: Make task-events use the `message` from the API rather than hardcoded
This commit is contained in:
@@ -1,27 +1,6 @@
|
||||
import { computed } from '@ember/object';
|
||||
import Fragment from 'ember-data-model-fragments/fragment';
|
||||
import attr from 'ember-data/attr';
|
||||
import { fragmentOwner } from 'ember-data-model-fragments/attributes';
|
||||
import moment from 'moment';
|
||||
|
||||
const displayProps = [
|
||||
'message',
|
||||
'validationError',
|
||||
'setupError',
|
||||
'driverError',
|
||||
'downloadError',
|
||||
'killReason',
|
||||
'killTimeout',
|
||||
'killError',
|
||||
'exitCode',
|
||||
'signal',
|
||||
'startDelay',
|
||||
'restartReason',
|
||||
'failedSibling',
|
||||
'taskSignal',
|
||||
'taskSignalReason',
|
||||
'driverMessage',
|
||||
];
|
||||
|
||||
export default Fragment.extend({
|
||||
state: fragmentOwner(),
|
||||
@@ -45,103 +24,5 @@ export default Fragment.extend({
|
||||
taskSignal: attr('string'),
|
||||
taskSignalReason: attr('string'),
|
||||
validationError: attr('string'),
|
||||
vaultError: attr('string'),
|
||||
message: attr('string'),
|
||||
failedSibling: attr('string'),
|
||||
|
||||
displayMessage: computed(...displayProps, function() {
|
||||
let desc = '';
|
||||
switch (this.get('type')) {
|
||||
case 'Task Setup':
|
||||
desc = this.get('message');
|
||||
break;
|
||||
case 'Started':
|
||||
desc = 'Task started by client';
|
||||
break;
|
||||
case 'Received':
|
||||
desc = 'Task received by client';
|
||||
break;
|
||||
case 'Failed Validation':
|
||||
desc = this.get('validationError') || 'Validation of task failed';
|
||||
break;
|
||||
case 'Setup Failure':
|
||||
desc = this.get('setupError') || 'Task setup failed';
|
||||
break;
|
||||
case 'Driver Failure':
|
||||
desc = this.get('driverError') || 'Failed to start task';
|
||||
break;
|
||||
case 'Downloading Artifacts':
|
||||
desc = 'Client is downloading artifacts';
|
||||
break;
|
||||
case 'Failed Artifact Download':
|
||||
desc = this.get('downloadError') || 'Failed to download artifacts';
|
||||
break;
|
||||
case 'Killing':
|
||||
desc =
|
||||
this.get('killReason') ||
|
||||
(this.get('killTimeout') &&
|
||||
`Sent interrupt. Waiting ${this.get('killTimeout')} before force killing`);
|
||||
break;
|
||||
case 'Killed':
|
||||
desc = this.get('killError') || 'Task successfully killed';
|
||||
break;
|
||||
case 'Terminated':
|
||||
var parts = [`Exit Code: ${this.get('exitCode')}`];
|
||||
if (this.get('signal')) {
|
||||
parts.push(`Signal: ${this.get('signal')}`);
|
||||
}
|
||||
if (this.get('message')) {
|
||||
parts.push(`Exit Message: ${this.get('message')}`);
|
||||
}
|
||||
desc = parts.join(', ');
|
||||
break;
|
||||
case 'Restarting':
|
||||
var timerMessage = `Task restarting in ${moment
|
||||
.duration(this.get('startDelay') / 1000000, 'ms')
|
||||
.humanize()}`;
|
||||
if (this.get('restartReason') && this.get('restartReason') !== 'Restart within policy') {
|
||||
desc = `${this.get('restartReason')} - ${timerMessage}`;
|
||||
} else {
|
||||
desc = timerMessage;
|
||||
}
|
||||
break;
|
||||
case 'Not Restarting':
|
||||
desc = this.get('restartReason') || 'Task exceeded restart policy';
|
||||
break;
|
||||
case 'Sibling Task Failed':
|
||||
desc = this.get('failedSibling')
|
||||
? `Task's sibling ${this.get('failedSibling')} failed`
|
||||
: "Task's sibling failed";
|
||||
break;
|
||||
case 'Signaling':
|
||||
var signal = this.get('taskSignal');
|
||||
var reason = this.get('taskSignalReason');
|
||||
|
||||
if (!signal && !reason) {
|
||||
desc = 'Task being sent a signal';
|
||||
} else if (!signal) {
|
||||
desc = reason;
|
||||
} else if (!reason) {
|
||||
desc = `Task being sent signal ${signal}`;
|
||||
} else {
|
||||
desc = `Task being sent signal ${signal}: ${reason}`;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'Restart Signaled':
|
||||
desc = this.get('restartReason') || 'Task signaled to restart';
|
||||
break;
|
||||
case 'Driver':
|
||||
desc = this.get('driverMessage');
|
||||
break;
|
||||
case 'Leader Task Dead':
|
||||
desc = 'Leader Task in Group dead';
|
||||
break;
|
||||
case 'Generic':
|
||||
desc = this.get('message');
|
||||
break;
|
||||
}
|
||||
|
||||
return desc;
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
</td>
|
||||
<td data-test-state>{{row.model.state}}</td>
|
||||
<td data-test-message>
|
||||
{{#if row.model.events.lastObject.displayMessage}}
|
||||
{{row.model.events.lastObject.displayMessage}}
|
||||
{{#if row.model.events.lastObject.message}}
|
||||
{{row.model.events.lastObject.message}}
|
||||
{{else}}
|
||||
<em>No message</em>
|
||||
{{/if}}
|
||||
|
||||
@@ -83,8 +83,8 @@
|
||||
<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.type}}</td>
|
||||
<td data-test-task-event-message>
|
||||
{{#if row.model.displayMessage}}
|
||||
{{row.model.displayMessage}}
|
||||
{{#if row.model.message}}
|
||||
{{row.model.message}}
|
||||
{{else}}
|
||||
<em>No message</em>
|
||||
{{/if}}
|
||||
|
||||
@@ -18,9 +18,6 @@ export default Factory.extend({
|
||||
clientStatus: faker.list.random(...CLIENT_STATUSES),
|
||||
desiredStatus: faker.list.random(...DESIRED_STATUSES),
|
||||
|
||||
// Meta property for hinting at task events
|
||||
useMessagePassthru: false,
|
||||
|
||||
withTaskWithPorts: trait({
|
||||
afterCreate(allocation, server) {
|
||||
const taskGroup = server.db.taskGroups.findBy({ name: allocation.taskGroup });
|
||||
@@ -79,7 +76,6 @@ export default Factory.extend({
|
||||
server.create('task-state', {
|
||||
allocation,
|
||||
name: server.db.tasks.find(id).name,
|
||||
useMessagePassthru: allocation.useMessagePassthru,
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -7,12 +7,6 @@ const STATES = provide(10, faker.system.fileExt.bind(faker.system));
|
||||
export default Factory.extend({
|
||||
type: faker.list.random(...STATES),
|
||||
|
||||
// Message is a function of type, and this type uses the vanilla
|
||||
// message property.
|
||||
messagePassthru: trait({
|
||||
type: 'Task Setup',
|
||||
}),
|
||||
|
||||
signal: () => '',
|
||||
exitCode: () => null,
|
||||
time: () => faker.date.past(2 / 365, REF_TIME) * 1000000,
|
||||
@@ -26,6 +20,5 @@ export default Factory.extend({
|
||||
setupError: () => '',
|
||||
taskSignalReason: () => '',
|
||||
validationError: () => '',
|
||||
vaultError: () => '',
|
||||
message: () => faker.lorem.sentence(),
|
||||
});
|
||||
|
||||
@@ -14,13 +14,11 @@ export default Factory.extend({
|
||||
return new Date(this.startedAt + Math.random(1000 * 60 * 3) + 50);
|
||||
},
|
||||
|
||||
useMessagePassthru: false,
|
||||
|
||||
afterCreate(state, server) {
|
||||
const props = [
|
||||
'task-event',
|
||||
faker.random.number({ min: 1, max: 10 }),
|
||||
state.useMessagePassthru && 'messagePassthru',
|
||||
false,
|
||||
{
|
||||
taskStateId: state.id,
|
||||
},
|
||||
|
||||
@@ -14,17 +14,13 @@ moduleForAcceptance('Acceptance | allocation detail', {
|
||||
|
||||
node = server.create('node');
|
||||
job = server.create('job', { groupCount: 0 });
|
||||
allocation = server.create('allocation', 'withTaskWithPorts', {
|
||||
useMessagePassthru: true,
|
||||
});
|
||||
allocation = server.create('allocation', 'withTaskWithPorts');
|
||||
|
||||
visit(`/allocations/${allocation.id}`);
|
||||
},
|
||||
});
|
||||
|
||||
test('/allocation/:id should name the allocation and link to the corresponding job and node', function(
|
||||
assert
|
||||
) {
|
||||
test('/allocation/:id should name the allocation and link to the corresponding job and node', function(assert) {
|
||||
assert.ok(
|
||||
find('[data-test-title]').textContent.includes(allocation.name),
|
||||
'Allocation name is in the heading'
|
||||
@@ -125,9 +121,7 @@ test('each task row should list high-level information for the task', function(a
|
||||
});
|
||||
});
|
||||
|
||||
test('when the allocation is not found, an error message is shown, but the URL persists', function(
|
||||
assert
|
||||
) {
|
||||
test('when the allocation is not found, an error message is shown, but the URL persists', function(assert) {
|
||||
visit('/allocations/not-a-real-allocation');
|
||||
|
||||
andThen(() => {
|
||||
|
||||
@@ -12,18 +12,14 @@ moduleForAcceptance('Acceptance | task detail', {
|
||||
server.create('agent');
|
||||
server.create('node');
|
||||
server.create('job', { createAllocations: false });
|
||||
allocation = server.create('allocation', 'withTaskWithPorts', {
|
||||
useMessagePassthru: true,
|
||||
});
|
||||
allocation = server.create('allocation', 'withTaskWithPorts');
|
||||
task = server.db.taskStates.where({ allocationId: allocation.id })[0];
|
||||
|
||||
visit(`/allocations/${allocation.id}/${task.name}`);
|
||||
},
|
||||
});
|
||||
|
||||
test('/allocation/:id/:task_name should name the task and list high-level task information', function(
|
||||
assert
|
||||
) {
|
||||
test('/allocation/:id/:task_name should name the task and list high-level task information', function(assert) {
|
||||
assert.ok(find('[data-test-title]').textContent.includes(task.name), 'Task name');
|
||||
assert.ok(find('[data-test-state]').textContent.includes(task.state), 'Task state');
|
||||
|
||||
@@ -119,9 +115,7 @@ test('the events table lists all recent events', function(assert) {
|
||||
);
|
||||
});
|
||||
|
||||
test('each recent event should list the time, type, and description of the event', function(
|
||||
assert
|
||||
) {
|
||||
test('each recent event should list the time, type, and description of the event', function(assert) {
|
||||
const event = server.db.taskEvents.where({ taskStateId: task.id })[0];
|
||||
const recentEvent = findAll('[data-test-task-event]').get('lastObject');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user