diff --git a/ui/app/routes/allocations/allocation/index.js b/ui/app/routes/allocations/allocation/index.js index 7072c5d8a..ebe985da2 100644 --- a/ui/app/routes/allocations/allocation/index.js +++ b/ui/app/routes/allocations/allocation/index.js @@ -3,8 +3,10 @@ import Route from '@ember/routing/route'; export default Route.extend({ setupController(controller, model) { // Suppress the preemptedByAllocation fetch error in the event it's a 404 - const setPreempter = () => controller.set('preempter', model.preemptedByAllocation); - model.preemptedByAllocation.then(setPreempter, setPreempter); + if (model) { + const setPreempter = () => controller.set('preempter', model.preemptedByAllocation); + model.preemptedByAllocation.then(setPreempter, setPreempter); + } return this._super(...arguments); }, diff --git a/ui/app/templates/allocations/allocation/index.hbs b/ui/app/templates/allocations/allocation/index.hbs index c6fdb4884..09df050e2 100644 --- a/ui/app/templates/allocations/allocation/index.hbs +++ b/ui/app/templates/allocations/allocation/index.hbs @@ -106,23 +106,23 @@ - {{preempter.name}} - {{#link-to "allocations.allocation" preempter data-test-allocation-link}}{{preempter.shortId}}{{/link-to}} + {{preempter.name}} + {{#link-to "allocations.allocation" preempter data-test-allocation-id}}{{preempter.shortId}}{{/link-to}} Job {{#link-to "jobs.job" preempter.job (query-params jobNamespace=preempter.job.namespace.id) data-test-job-link}}{{preempter.job.name}}{{/link-to}} Priority - {{preempter.job.priority}} + {{preempter.job.priority}} Client {{#link-to "clients.client" preempter.node data-test-client-link}}{{preempter.node.shortId}}{{/link-to}} Reserved CPU - {{preempter.resources.cpu}} MHz + {{preempter.resources.cpu}} MHz Reserved Memory - {{preempter.resources.memory}} MiB + {{preempter.resources.memory}} MiB @@ -131,7 +131,7 @@ {{/if}} - {{#if model.preemptedAllocations.length}} + {{#if (and model.preemptedAllocations.isFulfilled model.preemptedAllocations.length)}}
Preempted Allocations
@@ -151,7 +151,7 @@ Memory {{/t.head}} {{#t.body as |row|}} - {{allocation-row allocation=row.model context="job"}} + {{allocation-row allocation=row.model context="job" data-test-allocation=row.model.id}} {{/t.body}} {{/list-table}}
diff --git a/ui/tests/acceptance/allocation-detail-test.js b/ui/tests/acceptance/allocation-detail-test.js index 21b613e28..3e5ca5980 100644 --- a/ui/tests/acceptance/allocation-detail-test.js +++ b/ui/tests/acceptance/allocation-detail-test.js @@ -199,3 +199,106 @@ module('Acceptance | allocation detail (not running)', function(hooks) { ); }); }); + +module('Acceptance | allocation detail (preemptions)', function(hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + hooks.beforeEach(async function() { + server.create('agent'); + node = server.create('node'); + job = server.create('job', { createAllocations: false }); + }); + + test('shows a dedicated section to the allocation that preempted this allocation', async function(assert) { + allocation = server.create('allocation', 'preempted'); + const preempter = server.schema.find('allocation', allocation.preemptedByAllocation); + const preempterJob = server.schema.find('job', preempter.jobId); + const preempterClient = server.schema.find('node', preempter.nodeId); + + await Allocation.visit({ id: allocation.id }); + assert.ok(Allocation.wasPreempted, 'Preempted allocation section is shown'); + assert.equal(Allocation.preempter.status, preempter.clientStatus, 'Preempter status matches'); + assert.equal(Allocation.preempter.name, preempter.name, 'Preempter name matches'); + assert.equal( + Allocation.preempter.priority, + preempterJob.priority, + 'Preempter priority matches' + ); + + await Allocation.preempter.visit(); + assert.equal( + currentURL(), + `/allocations/${preempter.id}`, + 'Clicking the preempter id navigates to the preempter allocation detail page' + ); + + await Allocation.visit({ id: allocation.id }); + await Allocation.preempter.visitJob(); + assert.equal( + currentURL(), + `/jobs/${preempterJob.id}`, + 'Clicking the preempter job link navigates to the preempter job page' + ); + + await Allocation.visit({ id: allocation.id }); + await Allocation.preempter.visitClient(); + assert.equal( + currentURL(), + `/clients/${preempterClient.id}`, + 'Clicking the preempter client link navigates to the preempter client page' + ); + }); + + test('shows a dedicated section to the allocations this allocation preempted', async function(assert) { + allocation = server.create('allocation', 'preempter'); + await Allocation.visit({ id: allocation.id }); + assert.ok(Allocation.preempted, 'The allocations this allocation preempted are shown'); + }); + + test('each preempted allocation in the table lists basic allocation information', async function(assert) { + allocation = server.create('allocation', 'preempter'); + await Allocation.visit({ id: allocation.id }); + + const preemption = allocation.preemptedAllocations + .map(id => server.schema.find('allocation', id)) + .sortBy('modifyIndex') + .reverse()[0]; + const preemptionRow = Allocation.preemptions.objectAt(0); + + assert.equal( + Allocation.preemptions.length, + allocation.preemptedAllocations.length, + 'The preemptions table has a row for each preempted allocation' + ); + + assert.equal(preemptionRow.shortId, preemption.id.split('-')[0], 'Preemption short id'); + assert.equal( + preemptionRow.createTime, + moment(preemption.createTime / 1000000).format('MMM DD HH:mm:ss ZZ'), + 'Preemption create time' + ); + assert.equal( + preemptionRow.modifyTime, + moment(preemption.modifyTime / 1000000).fromNow(), + 'Preemption modify time' + ); + assert.equal(preemptionRow.status, preemption.clientStatus, 'Client status'); + assert.equal(preemptionRow.jobVersion, preemption.jobVersion, 'Job Version'); + assert.equal( + preemptionRow.client, + server.db.nodes.find(preemption.nodeId).id.split('-')[0], + 'Node ID' + ); + + await preemptionRow.visitClient(); + assert.equal(currentURL(), `/clients/${preemption.nodeId}`, 'Node links to node page'); + }); + + test('when an allocation both preempted allocations and was preempted itself, both preemptions sections are shown', async function(assert) { + allocation = server.create('allocation', 'preempter', 'preempted'); + await Allocation.visit({ id: allocation.id }); + assert.ok(Allocation.preempted, 'The allocations this allocation preempted are shown'); + assert.ok(Allocation.wasPreempted, 'Preempted allocation section is shown'); + }); +});