github.com/zoomfoo/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/ui/tests/acceptance/allocation-detail-test.js (about) 1 import { assign } from '@ember/polyfills'; 2 import { currentURL } from 'ember-native-dom-helpers'; 3 import { test } from 'qunit'; 4 import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance'; 5 import Allocation from 'nomad-ui/tests/pages/allocations/detail'; 6 import moment from 'moment'; 7 8 let job; 9 let node; 10 let allocation; 11 12 moduleForAcceptance('Acceptance | allocation detail', { 13 beforeEach() { 14 server.create('agent'); 15 16 node = server.create('node'); 17 job = server.create('job', { groupsCount: 1, createAllocations: false }); 18 allocation = server.create('allocation', 'withTaskWithPorts'); 19 20 // Make sure the node has an unhealthy driver 21 node.update({ 22 driver: assign(node.drivers, { 23 docker: { 24 detected: true, 25 healthy: false, 26 }, 27 }), 28 }); 29 30 // Make sure a task for the allocation depends on the unhealthy driver 31 server.schema.tasks.first().update({ 32 driver: 'docker', 33 }); 34 35 Allocation.visit({ id: allocation.id }); 36 }, 37 }); 38 39 test('/allocation/:id should name the allocation and link to the corresponding job and node', function(assert) { 40 assert.ok(Allocation.title.includes(allocation.name), 'Allocation name is in the heading'); 41 assert.equal(Allocation.details.job, job.name, 'Job name is in the subheading'); 42 assert.equal( 43 Allocation.details.client, 44 node.id.split('-')[0], 45 'Node short id is in the subheading' 46 ); 47 48 andThen(() => { 49 Allocation.details.visitJob(); 50 }); 51 52 andThen(() => { 53 assert.equal(currentURL(), `/jobs/${job.id}`, 'Job link navigates to the job'); 54 }); 55 56 Allocation.visit({ id: allocation.id }); 57 58 andThen(() => { 59 Allocation.details.visitClient(); 60 }); 61 62 andThen(() => { 63 assert.equal(currentURL(), `/clients/${node.id}`, 'Client link navigates to the client'); 64 }); 65 }); 66 67 test('/allocation/:id should list all tasks for the allocation', function(assert) { 68 assert.equal( 69 Allocation.tasks.length, 70 server.db.taskStates.where({ allocationId: allocation.id }).length, 71 'Table lists all tasks' 72 ); 73 }); 74 75 test('each task row should list high-level information for the task', function(assert) { 76 const task = server.db.taskStates.where({ allocationId: allocation.id }).sortBy('name')[0]; 77 const taskResources = allocation.taskResourcesIds 78 .map(id => server.db.taskResources.find(id)) 79 .sortBy('name')[0]; 80 const reservedPorts = taskResources.resources.Networks[0].ReservedPorts; 81 const dynamicPorts = taskResources.resources.Networks[0].DynamicPorts; 82 const taskRow = Allocation.tasks.objectAt(0); 83 const events = server.db.taskEvents.where({ taskStateId: task.id }); 84 const event = events[events.length - 1]; 85 86 assert.equal(taskRow.name, task.name, 'Name'); 87 assert.equal(taskRow.state, task.state, 'State'); 88 assert.equal(taskRow.message, event.displayMessage, 'Event Message'); 89 assert.equal( 90 taskRow.time, 91 moment(event.time / 1000000).format('MM/DD/YY HH:mm:ss'), 92 'Event Time' 93 ); 94 95 assert.ok(reservedPorts.length, 'The task has reserved ports'); 96 assert.ok(dynamicPorts.length, 'The task has dynamic ports'); 97 98 const addressesText = taskRow.ports; 99 reservedPorts.forEach(port => { 100 assert.ok(addressesText.includes(port.Label), `Found label ${port.Label}`); 101 assert.ok(addressesText.includes(port.Value), `Found value ${port.Value}`); 102 }); 103 dynamicPorts.forEach(port => { 104 assert.ok(addressesText.includes(port.Label), `Found label ${port.Label}`); 105 assert.ok(addressesText.includes(port.Value), `Found value ${port.Value}`); 106 }); 107 }); 108 109 test('each task row should link to the task detail page', function(assert) { 110 const task = server.db.taskStates.where({ allocationId: allocation.id }).sortBy('name')[0]; 111 112 Allocation.tasks.objectAt(0).clickLink(); 113 114 andThen(() => { 115 assert.equal( 116 currentURL(), 117 `/allocations/${allocation.id}/${task.name}`, 118 'Task name in task row links to task detail' 119 ); 120 }); 121 122 andThen(() => { 123 Allocation.visit({ id: allocation.id }); 124 }); 125 126 andThen(() => { 127 Allocation.tasks.objectAt(0).clickRow(); 128 }); 129 130 andThen(() => { 131 assert.equal( 132 currentURL(), 133 `/allocations/${allocation.id}/${task.name}`, 134 'Task row links to task detail' 135 ); 136 }); 137 }); 138 139 test('tasks with an unhealthy driver have a warning icon', function(assert) { 140 assert.ok(Allocation.firstUnhealthyTask().hasUnhealthyDriver, 'Warning is shown'); 141 }); 142 143 test('when the allocation has not been rescheduled, the reschedule events section is not rendered', function(assert) { 144 assert.notOk(Allocation.hasRescheduleEvents, 'Reschedule Events section exists'); 145 }); 146 147 test('when the allocation is not found, an error message is shown, but the URL persists', function(assert) { 148 Allocation.visit({ id: 'not-a-real-allocation' }); 149 150 andThen(() => { 151 assert.equal( 152 server.pretender.handledRequests.findBy('status', 404).url, 153 '/v1/allocation/not-a-real-allocation', 154 'A request to the nonexistent allocation is made' 155 ); 156 assert.equal(currentURL(), '/allocations/not-a-real-allocation', 'The URL persists'); 157 assert.ok(Allocation.error.isShown, 'Error message is shown'); 158 assert.equal(Allocation.error.title, 'Not Found', 'Error message is for 404'); 159 }); 160 }); 161 162 moduleForAcceptance('Acceptance | allocation detail (rescheduled)', { 163 beforeEach() { 164 server.create('agent'); 165 166 node = server.create('node'); 167 job = server.create('job', { createAllocations: false }); 168 allocation = server.create('allocation', 'rescheduled'); 169 170 Allocation.visit({ id: allocation.id }); 171 }, 172 }); 173 174 test('when the allocation has been rescheduled, the reschedule events section is rendered', function(assert) { 175 assert.ok(Allocation.hasRescheduleEvents, 'Reschedule Events section exists'); 176 });