github.com/blixtra/nomad@v0.7.2-0.20171221000451-da9a1d7bb050/ui/tests/acceptance/task-group-detail-test.js (about) 1 import Ember from 'ember'; 2 import { click, find, findAll, fillIn, currentURL, visit } from 'ember-native-dom-helpers'; 3 import { test } from 'qunit'; 4 import moduleForAcceptance from 'nomad-ui/tests/helpers/module-for-acceptance'; 5 import { formatBytes } from 'nomad-ui/helpers/format-bytes'; 6 import moment from 'moment'; 7 8 const { $ } = Ember; 9 10 let job; 11 let taskGroup; 12 let tasks; 13 let allocations; 14 15 const sum = (total, n) => total + n; 16 17 moduleForAcceptance('Acceptance | task group detail', { 18 beforeEach() { 19 server.create('agent'); 20 server.create('node', 'forceIPv4'); 21 22 job = server.create('job', { 23 groupsCount: 2, 24 createAllocations: false, 25 }); 26 27 const taskGroups = server.db.taskGroups.where({ jobId: job.id }); 28 taskGroup = taskGroups[0]; 29 30 tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id)); 31 32 server.create('node', 'forceIPv4'); 33 34 allocations = server.createList('allocation', 2, { 35 jobId: job.id, 36 taskGroup: taskGroup.name, 37 }); 38 39 // Allocations associated to a different task group on the job to 40 // assert that they aren't showing up in on this page in error. 41 server.createList('allocation', 3, { 42 jobId: job.id, 43 taskGroup: taskGroups[1].name, 44 }); 45 46 // Set a static name to make the search test deterministic 47 server.db.allocations.forEach(alloc => { 48 alloc.name = 'aaaaa'; 49 }); 50 51 visit(`/jobs/${job.id}/${taskGroup.name}`); 52 }, 53 }); 54 55 test('/jobs/:id/:task-group should list high-level metrics for the allocation', function(assert) { 56 const totalCPU = tasks.mapBy('Resources.CPU').reduce(sum, 0); 57 const totalMemory = tasks.mapBy('Resources.MemoryMB').reduce(sum, 0); 58 const totalDisk = taskGroup.ephemeralDisk.SizeMB; 59 60 assert.equal( 61 findAll('.inline-definitions .pair')[0].textContent, 62 `# Tasks ${tasks.length}`, 63 '# Tasks' 64 ); 65 assert.equal( 66 findAll('.inline-definitions .pair')[1].textContent, 67 `Reserved CPU ${totalCPU} MHz`, 68 'Aggregated CPU reservation for all tasks' 69 ); 70 assert.equal( 71 findAll('.inline-definitions .pair')[2].textContent, 72 `Reserved Memory ${totalMemory} MiB`, 73 'Aggregated Memory reservation for all tasks' 74 ); 75 assert.equal( 76 findAll('.inline-definitions .pair')[3].textContent, 77 `Reserved Disk ${totalDisk} MiB`, 78 'Aggregated Disk reservation for all tasks' 79 ); 80 }); 81 82 test('/jobs/:id/:task-group should have breadcrumbs for job and jobs', function(assert) { 83 assert.equal(findAll('.breadcrumb')[0].textContent.trim(), 'Jobs', 'First breadcrumb says jobs'); 84 assert.equal( 85 findAll('.breadcrumb')[1].textContent.trim(), 86 job.name, 87 'Second breadcrumb says the job name' 88 ); 89 assert.equal( 90 findAll('.breadcrumb')[2].textContent.trim(), 91 taskGroup.name, 92 'Third breadcrumb says the job name' 93 ); 94 }); 95 96 test('/jobs/:id/:task-group first breadcrumb should link to jobs', function(assert) { 97 click(findAll('.breadcrumb')[0]); 98 andThen(() => { 99 assert.equal(currentURL(), '/jobs', 'First breadcrumb links back to jobs'); 100 }); 101 }); 102 103 test('/jobs/:id/:task-group second breadcrumb should link to the job for the task group', function( 104 assert 105 ) { 106 click(findAll('.breadcrumb')[1]); 107 andThen(() => { 108 assert.equal( 109 currentURL(), 110 `/jobs/${job.id}`, 111 'Second breadcrumb links back to the job for the task group' 112 ); 113 }); 114 }); 115 116 test('/jobs/:id/:task-group should list one page of allocations for the task group', function( 117 assert 118 ) { 119 const pageSize = 10; 120 121 server.createList('allocation', 10, { 122 jobId: job.id, 123 taskGroup: taskGroup.name, 124 }); 125 126 visit('/jobs'); 127 visit(`/jobs/${job.id}/${taskGroup.name}`); 128 129 andThen(() => { 130 assert.ok( 131 server.db.allocations.where({ jobId: job.id }).length > pageSize, 132 'There are enough allocations to invoke pagination' 133 ); 134 135 assert.equal( 136 findAll('.allocations tbody tr').length, 137 pageSize, 138 'All allocations for the task group' 139 ); 140 }); 141 }); 142 143 test('each allocation should show basic information about the allocation', function(assert) { 144 const allocation = allocations.sortBy('modifyIndex').reverse()[0]; 145 const allocationRow = $(findAll('.allocations tbody tr')[0]); 146 147 andThen(() => { 148 assert.equal( 149 allocationRow 150 .find('td:eq(0)') 151 .text() 152 .trim(), 153 allocation.id.split('-')[0], 154 'Allocation short id' 155 ); 156 assert.equal( 157 allocationRow 158 .find('td:eq(1)') 159 .text() 160 .trim(), 161 moment(allocation.modifyTime / 1000000).format('MM/DD HH:mm:ss'), 162 'Allocation modify time' 163 ); 164 assert.equal( 165 allocationRow 166 .find('td:eq(2)') 167 .text() 168 .trim(), 169 allocation.name, 170 'Allocation name' 171 ); 172 assert.equal( 173 allocationRow 174 .find('td:eq(3)') 175 .text() 176 .trim(), 177 allocation.clientStatus, 178 'Client status' 179 ); 180 assert.equal( 181 allocationRow 182 .find('td:eq(4)') 183 .text() 184 .trim(), 185 allocation.jobVersion, 186 'Job Version' 187 ); 188 assert.equal( 189 allocationRow 190 .find('td:eq(5)') 191 .text() 192 .trim(), 193 server.db.nodes.find(allocation.nodeId).id.split('-')[0], 194 'Node ID' 195 ); 196 }); 197 198 click(allocationRow.find('td:eq(5) a').get(0)); 199 200 andThen(() => { 201 assert.equal(currentURL(), `/clients/${allocation.nodeId}`, 'Node links to node page'); 202 }); 203 }); 204 205 test('each allocation should show stats about the allocation, retrieved directly from the node', function( 206 assert 207 ) { 208 const allocation = allocations.sortBy('name')[0]; 209 const allocationRow = $(findAll('.allocations tbody tr')[0]); 210 const allocStats = server.db.clientAllocationStats.find(allocation.id); 211 const tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id)); 212 213 const cpuUsed = tasks.reduce((sum, task) => sum + task.Resources.CPU, 0); 214 const memoryUsed = tasks.reduce((sum, task) => sum + task.Resources.MemoryMB, 0); 215 216 assert.equal( 217 allocationRow 218 .find('td:eq(6)') 219 .text() 220 .trim(), 221 Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks) / cpuUsed, 222 'CPU %' 223 ); 224 225 assert.equal( 226 allocationRow.find('td:eq(6) .tooltip').attr('aria-label'), 227 `${Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks)} / ${cpuUsed} MHz`, 228 'Detailed CPU information is in a tooltip' 229 ); 230 231 assert.equal( 232 allocationRow 233 .find('td:eq(7)') 234 .text() 235 .trim(), 236 allocStats.resourceUsage.MemoryStats.RSS / 1024 / 1024 / memoryUsed, 237 'Memory used' 238 ); 239 240 assert.equal( 241 allocationRow.find('td:eq(7) .tooltip').attr('aria-label'), 242 `${formatBytes([allocStats.resourceUsage.MemoryStats.RSS])} / ${memoryUsed} MiB`, 243 'Detailed memory information is in a tooltip' 244 ); 245 246 const node = server.db.nodes.find(allocation.nodeId); 247 const nodeStatsUrl = `//${node.httpAddr}/v1/client/allocation/${allocation.id}/stats`; 248 249 assert.ok( 250 server.pretender.handledRequests.some(req => req.url === nodeStatsUrl), 251 `Requests ${nodeStatsUrl}` 252 ); 253 }); 254 255 test('when the allocation search has no matches, there is an empty message', function(assert) { 256 fillIn('.search-box input', 'zzzzzz'); 257 258 andThen(() => { 259 assert.ok(find('.allocations .empty-message')); 260 assert.equal(find('.allocations .empty-message-headline').textContent, 'No Matches'); 261 }); 262 });