From cae4bec3c9b3c5173f2f195a26f7bbd8bfda11c0 Mon Sep 17 00:00:00 2001 From: Jai Bhagat Date: Thu, 20 Jan 2022 10:39:02 -0500 Subject: [PATCH] ui: fix remaining linting errors --- ui/app/abilities/client.js | 8 +- ui/app/components/trigger.js | 2 +- ui/app/controllers/allocations/allocation.js | 7 +- .../allocations/allocation/task.js | 6 +- ui/app/controllers/csi/volumes/volume.js | 8 +- ui/app/models/allocation.js | 4 +- ui/app/routes/allocations/allocation.js | 2 +- ui/app/routes/csi/volumes/volume.js | 6 +- ui/app/routes/jobs/job/index.js | 8 +- ui/app/routes/jobs/job/task-group.js | 6 +- ui/app/services/breadcrumbs.js | 2 +- ui/app/utils/properties/job-client-status.js | 14 +- ui/tests/acceptance/allocation-detail-test.js | 128 ++++++------- ui/tests/acceptance/client-monitor-test.js | 18 +- ui/tests/acceptance/server-monitor-test.js | 5 +- ui/tests/acceptance/task-detail-test.js | 95 +++++----- ui/tests/acceptance/task-group-detail-test.js | 172 +++++++++--------- ui/tests/helpers/module-for-job.js | 56 +++--- .../components/allocation-row-test.js | 40 ++-- .../components/app-breadcrumbs-test.js | 16 +- .../components/breadcrumbs-test.js | 38 +++- .../integration/components/trigger-test.js | 78 +++++--- ui/tests/pages/jobs/detail.js | 28 +-- ui/tests/unit/abilities/client-test.js | 14 +- ui/tests/unit/utils/job-client-status-test.js | 18 +- 25 files changed, 426 insertions(+), 353 deletions(-) diff --git a/ui/app/abilities/client.js b/ui/app/abilities/client.js index e54dd159a..cd1fc8ed1 100644 --- a/ui/app/abilities/client.js +++ b/ui/app/abilities/client.js @@ -21,14 +21,14 @@ export default class Client extends AbstractAbility { get policiesIncludeNodeRead() { return policiesIncludePermissions(this.get('token.selfTokenPolicies'), [ 'read', - 'write' + 'write', ]); } @computed('token.selfTokenPolicies.[]') get policiesIncludeNodeWrite() { return policiesIncludePermissions(this.get('token.selfTokenPolicies'), [ - 'write' + 'write', ]); } } @@ -37,9 +37,9 @@ function policiesIncludePermissions(policies = [], permissions = []) { // For each policy record, extract the Node policy const nodePolicies = policies .toArray() - .map(policy => get(policy, 'rulesJSON.Node.Policy')) + .map((policy) => get(policy, 'rulesJSON.Node.Policy')) .compact(); // Check for requested permissions - return nodePolicies.some(policy => permissions.includes(policy)); + return nodePolicies.some((policy) => permissions.includes(policy)); } diff --git a/ui/app/components/trigger.js b/ui/app/components/trigger.js index 17f981b87..d141e6c33 100644 --- a/ui/app/components/trigger.js +++ b/ui/app/components/trigger.js @@ -49,7 +49,7 @@ export default class Trigger extends Component { this.error = null; } - @task(function*() { + @task(function* () { this._reset(); try { this.result = yield this.args.do(); diff --git a/ui/app/controllers/allocations/allocation.js b/ui/app/controllers/allocations/allocation.js index b29d7b6cb..142c9f3ff 100644 --- a/ui/app/controllers/allocations/allocation.js +++ b/ui/app/controllers/allocations/allocation.js @@ -35,7 +35,12 @@ export default class AllocationsAllocationController extends Controller { { title: 'Task Group', label: allocation.taskGroupName, - args: ['jobs.job.task-group', job.plainId, allocation.taskGroupName, jobQueryParams], + args: [ + 'jobs.job.task-group', + job.plainId, + allocation.taskGroupName, + jobQueryParams, + ], }, { title: 'Allocation', diff --git a/ui/app/controllers/allocations/allocation/task.js b/ui/app/controllers/allocations/allocation/task.js index 3e3c9a034..7ebc8b67a 100644 --- a/ui/app/controllers/allocations/allocation/task.js +++ b/ui/app/controllers/allocations/allocation/task.js @@ -9,7 +9,11 @@ export default class AllocationsAllocationTaskController extends Controller { return { title: 'Task', label: this.task.get('name'), - args: ['allocations.allocation.task', this.task.get('allocation'), this.task], + args: [ + 'allocations.allocation.task', + this.task.get('allocation'), + this.task, + ], }; } } diff --git a/ui/app/controllers/csi/volumes/volume.js b/ui/app/controllers/csi/volumes/volume.js index c151e5dec..46bf9a235 100644 --- a/ui/app/controllers/csi/volumes/volume.js +++ b/ui/app/controllers/csi/volumes/volume.js @@ -25,7 +25,9 @@ export default class VolumeController extends Controller { label: 'Volumes', args: [ 'csi.volumes', - qpBuilder({ volumeNamespace: volume.get('namespace.name') || 'default' }), + qpBuilder({ + volumeNamespace: volume.get('namespace.name') || 'default', + }), ], }, { @@ -33,7 +35,9 @@ export default class VolumeController extends Controller { args: [ 'csi.volumes.volume', volume.plainId, - qpBuilder({ volumeNamespace: volume.get('namespace.name') || 'default' }), + qpBuilder({ + volumeNamespace: volume.get('namespace.name') || 'default', + }), ], }, ]; diff --git a/ui/app/models/allocation.js b/ui/app/models/allocation.js index dd2aad6a0..45d42727e 100644 --- a/ui/app/models/allocation.js +++ b/ui/app/models/allocation.js @@ -35,9 +35,7 @@ export default class Allocation extends Model { @attr('string') nodeName; @computed get shortNodeId() { - return this.belongsTo('node') - .id() - .split('-')[0]; + return this.belongsTo('node').id().split('-')[0]; } @attr('number') modifyIndex; diff --git a/ui/app/routes/allocations/allocation.js b/ui/app/routes/allocations/allocation.js index bb5ce7bfc..f95ebc31e 100644 --- a/ui/app/routes/allocations/allocation.js +++ b/ui/app/routes/allocations/allocation.js @@ -17,7 +17,7 @@ export default class AllocationRoute extends Route.extend(WithWatchers) { // Preload the job for the allocation since it's required for the breadcrumb trail return super .model(...arguments) - .then(allocation => + .then((allocation) => allocation .get('job') .then(() => this.store.findAll('namespace')) // namespaces belong to a job and are an asynchronous relationship so we can peak them later on diff --git a/ui/app/routes/csi/volumes/volume.js b/ui/app/routes/csi/volumes/volume.js index 8c5041fc4..e5722374a 100644 --- a/ui/app/routes/csi/volumes/volume.js +++ b/ui/app/routes/csi/volumes/volume.js @@ -16,7 +16,7 @@ export default class VolumeRoute extends Route.extend(WithWatchers) { if (!model) return; controller.set('watchers', { - model: this.watch.perform(model) + model: this.watch.perform(model), }); } @@ -30,9 +30,9 @@ export default class VolumeRoute extends Route.extend(WithWatchers) { const fullId = JSON.stringify([`csi/${name}`, namespace || 'default']); return RSVP.hash({ volume: this.store.findRecord('volume', fullId, { reload: true }), - namespaces: this.store.findAll('namespace') + namespaces: this.store.findAll('namespace'), }) - .then(hash => hash.volume) + .then((hash) => hash.volume) .catch(notifyError(this)); } diff --git a/ui/app/routes/jobs/job/index.js b/ui/app/routes/jobs/job/index.js index 0f36a70c0..8accf8734 100644 --- a/ui/app/routes/jobs/job/index.js +++ b/ui/app/routes/jobs/job/index.js @@ -5,7 +5,7 @@ import { watchRecord, watchRelationship, watchAll, - watchQuery + watchQuery, } from 'nomad-ui/utils/properties/watch'; import WithWatchers from 'nomad-ui/mixins/with-watchers'; @@ -43,12 +43,12 @@ export default class IndexRoute extends Route.extend(WithWatchers) { list: model.job.get('hasChildren') && this.watchAllJobs.perform({ - namespace: model.job.namespace.get('name') + namespace: model.job.namespace.get('name'), }), nodes: this.can.can('read client') && model.job.get('hasClientStatus') && - this.watchNodes.perform() + this.watchNodes.perform(), }); } @@ -61,7 +61,7 @@ export default class IndexRoute extends Route.extend(WithWatchers) { ) { controller.setProperties({ sortProperty: 'submitTime', - sortDescending: true + sortDescending: true, }); } return super.setupController(...arguments); diff --git a/ui/app/routes/jobs/job/task-group.js b/ui/app/routes/jobs/job/task-group.js index 7f5a8f49c..88b654301 100644 --- a/ui/app/routes/jobs/job/task-group.js +++ b/ui/app/routes/jobs/job/task-group.js @@ -4,7 +4,7 @@ import EmberError from '@ember/error'; import { resolve, all } from 'rsvp'; import { watchRecord, - watchRelationship + watchRelationship, } from 'nomad-ui/utils/properties/watch'; import WithWatchers from 'nomad-ui/mixins/with-watchers'; import notifyError from 'nomad-ui/utils/notify-error'; @@ -34,7 +34,7 @@ export default class TaskGroupRoute extends Route.extend(WithWatchers) { // Refresh job allocations before-hand (so page sort works on load) return all([ job.hasMany('allocations').reload(), - job.get('scaleState') + job.get('scaleState'), ]).then(() => taskGroup); }) .catch(notifyError(this)); @@ -50,7 +50,7 @@ export default class TaskGroupRoute extends Route.extend(WithWatchers) { allocations: this.watchAllocations.perform(job), latestDeployment: job.get('supportsDeployments') && - this.watchLatestDeployment.perform(job) + this.watchLatestDeployment.perform(job), }); } } diff --git a/ui/app/services/breadcrumbs.js b/ui/app/services/breadcrumbs.js index eacf9f955..5d92984be 100644 --- a/ui/app/services/breadcrumbs.js +++ b/ui/app/services/breadcrumbs.js @@ -13,7 +13,7 @@ export default class BucketService extends Service { } @action deregisterBreadcrumb(crumb) { - const newCrumbs = this.crumbs.filter(c => c !== crumb); + const newCrumbs = this.crumbs.filter((c) => c !== crumb); this.crumbs = newCrumbs; } diff --git a/ui/app/utils/properties/job-client-status.js b/ui/app/utils/properties/job-client-status.js index d0e5e78fc..a71578681 100644 --- a/ui/app/utils/properties/job-client-status.js +++ b/ui/app/utils/properties/job-client-status.js @@ -19,12 +19,12 @@ export default function jobClientStatus(nodesKey, jobKey) { return computed( `${nodesKey}.[]`, `${jobKey}.{datacenters,status,allocations.@each.clientStatus,taskGroups}`, - function() { + function () { const job = this.get(jobKey); const nodes = this.get(nodesKey); // Filter nodes by the datacenters defined in the job. - const filteredNodes = nodes.filter(n => { + const filteredNodes = nodes.filter((n) => { return job.datacenters.indexOf(n.datacenter) >= 0; }); @@ -34,7 +34,7 @@ export default function jobClientStatus(nodesKey, jobKey) { // Group the job allocations by the ID of the client that is running them. const allocsByNodeID = {}; - job.allocations.forEach(a => { + job.allocations.forEach((a) => { const nodeId = a.belongsTo('node').id(); if (!allocsByNodeID[nodeId]) { allocsByNodeID[nodeId] = []; @@ -47,7 +47,7 @@ export default function jobClientStatus(nodesKey, jobKey) { byStatus: {}, totalNodes: filteredNodes.length, }; - filteredNodes.forEach(n => { + filteredNodes.forEach((n) => { const status = jobStatus(allocsByNodeID[n.id], job.taskGroups.length); result.byNode[n.id] = status; @@ -63,9 +63,9 @@ export default function jobClientStatus(nodesKey, jobKey) { } function allQueued(nodes) { - const nodeIDs = nodes.map(n => n.id); + const nodeIDs = nodes.map((n) => n.id); return { - byNode: Object.fromEntries(nodeIDs.map(id => [id, 'queued'])), + byNode: Object.fromEntries(nodeIDs.map((id) => [id, 'queued'])), byStatus: canonicalizeStatus({ queued: nodeIDs }), totalNodes: nodes.length, }; @@ -105,7 +105,7 @@ function jobStatus(allocs, expected) { // Count how many allocations are in each `clientStatus` value. const summary = allocs - .filter(a => !a.isOld) + .filter((a) => !a.isOld) .reduce((acc, a) => { const status = a.clientStatus; if (!acc[status]) { diff --git a/ui/tests/acceptance/allocation-detail-test.js b/ui/tests/acceptance/allocation-detail-test.js index 0d6dbe204..00861d08a 100644 --- a/ui/tests/acceptance/allocation-detail-test.js +++ b/ui/tests/acceptance/allocation-detail-test.js @@ -16,21 +16,21 @@ let job; let node; let allocation; -module('Acceptance | allocation detail', function(hooks) { +module('Acceptance | allocation detail', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); node = server.create('node'); job = server.create('job', { groupsCount: 1, withGroupServices: true, - createAllocations: false + createAllocations: false, }); allocation = server.create('allocation', 'withTaskWithPorts', { - clientStatus: 'running' + clientStatus: 'running', }); // Make sure the node has an unhealthy driver @@ -38,14 +38,14 @@ module('Acceptance | allocation detail', function(hooks) { driver: assign(node.drivers, { docker: { detected: true, - healthy: false - } - }) + healthy: false, + }, + }), }); // Make sure a task for the allocation depends on the unhealthy driver server.schema.tasks.first().update({ - driver: 'docker' + driver: 'docker', }); window.localStorage.clear(); @@ -53,11 +53,11 @@ module('Acceptance | allocation detail', function(hooks) { await Allocation.visit({ id: allocation.id }); }); - test('it passes an accessibility audit', async function(assert) { + test('it passes an accessibility audit', async function (assert) { await a11yAudit(assert); }); - test('/allocation/:id should name the allocation and link to the corresponding job and node', async function(assert) { + test('/allocation/:id should name the allocation and link to the corresponding job and node', async function (assert) { assert.ok( Allocation.title.includes(allocation.name), 'Allocation name is in the heading' @@ -93,7 +93,7 @@ module('Acceptance | allocation detail', function(hooks) { ); }); - test('/allocation/:id should include resource utilization graphs', async function(assert) { + test('/allocation/:id should include resource utilization graphs', async function (assert) { assert.equal( Allocation.resourceCharts.length, 2, @@ -111,17 +111,17 @@ module('Acceptance | allocation detail', function(hooks) { ); }); - test('/allocation/:id should present task lifecycles', async function(assert) { + test('/allocation/:id should present task lifecycles', async function (assert) { const job = server.create('job', { groupsCount: 1, groupTaskCount: 6, withGroupServices: true, - createAllocations: false + createAllocations: false, }); const allocation = server.create('allocation', 'withTaskWithPorts', { clientStatus: 'running', - jobId: job.id + jobId: job.id, }); await Allocation.visit({ id: allocation.id }); @@ -136,7 +136,7 @@ module('Acceptance | allocation detail', function(hooks) { const prestartEphemeralTask = server.db.taskStates .where({ allocationId: allocation.id }) .sortBy('name') - .find(taskState => { + .find((taskState) => { const task = server.db.tasks.findBy({ name: taskState.name }); return ( task.Lifecycle && @@ -151,7 +151,7 @@ module('Acceptance | allocation detail', function(hooks) { ); }); - test('/allocation/:id should list all tasks for the allocation', async function(assert) { + test('/allocation/:id should list all tasks for the allocation', async function (assert) { assert.equal( Allocation.tasks.length, server.db.taskStates.where({ allocationId: allocation.id }).length, @@ -160,7 +160,7 @@ module('Acceptance | allocation detail', function(hooks) { assert.notOk(Allocation.isEmpty, 'Task table empty state is not shown'); }); - test('each task row should list high-level information for the task', async function(assert) { + test('each task row should list high-level information for the task', async function (assert) { const task = server.db.taskStates .where({ allocationId: allocation.id }) .sortBy('name')[0]; @@ -169,16 +169,16 @@ module('Acceptance | allocation detail', function(hooks) { const taskGroup = server.schema.taskGroups.where({ jobId: allocation.jobId, - name: allocation.taskGroup + name: allocation.taskGroup, }).models[0]; - const jobTask = taskGroup.tasks.models.find(m => m.name === task.name); - const volumes = jobTask.volumeMounts.map(volume => ({ + const jobTask = taskGroup.tasks.models.find((m) => m.name === task.name); + const volumes = jobTask.volumeMounts.map((volume) => ({ name: volume.Volume, - source: taskGroup.volumes[volume.Volume].Source + source: taskGroup.volumes[volume.Volume].Source, })); - Allocation.tasks[0].as(taskRow => { + Allocation.tasks[0].as((taskRow) => { assert.equal(taskRow.name, task.name, 'Name'); assert.equal(taskRow.state, task.state, 'State'); assert.equal(taskRow.message, event.displayMessage, 'Event Message'); @@ -189,7 +189,7 @@ module('Acceptance | allocation detail', function(hooks) { ); const volumesText = taskRow.volumes; - volumes.forEach(volume => { + volumes.forEach((volume) => { assert.ok( volumesText.includes(volume.name), `Found label ${volume.name}` @@ -202,7 +202,7 @@ module('Acceptance | allocation detail', function(hooks) { }); }); - test('each task row should link to the task detail page', async function(assert) { + test('each task row should link to the task detail page', async function (assert) { const task = server.db.taskStates .where({ allocationId: allocation.id }) .sortBy('name')[0]; @@ -226,16 +226,16 @@ module('Acceptance | allocation detail', function(hooks) { ); }); - test('tasks with an unhealthy driver have a warning icon', async function(assert) { + test('tasks with an unhealthy driver have a warning icon', async function (assert) { // Driver health status require node:read permission. const policy = server.create('policy', { id: 'node-read', name: 'node-read', rulesJSON: { Node: { - Policy: 'read' - } - } + Policy: 'read', + }, + }, }); const clientToken = server.create('token', { type: 'client' }); clientToken.policyIds = [policy.id]; @@ -253,17 +253,17 @@ module('Acceptance | allocation detail', function(hooks) { ); }); - test('proxy task has a proxy tag', async function(assert) { + test('proxy task has a proxy tag', async function (assert) { // Must create a new job as existing one has loaded and it contains the tasks job = server.create('job', { groupsCount: 1, withGroupServices: true, - createAllocations: false + createAllocations: false, }); allocation = server.create('allocation', 'withTaskWithPorts', { clientStatus: 'running', - jobId: job.id + jobId: job.id, }); const taskState = allocation.taskStates.models.sortBy('name')[0]; @@ -276,24 +276,24 @@ module('Acceptance | allocation detail', function(hooks) { assert.ok(Allocation.tasks[0].hasProxyTag); }); - test('when there are no tasks, an empty state is shown', async function(assert) { + test('when there are no tasks, an empty state is shown', async function (assert) { // Make sure the allocation is pending in order to ensure there are no tasks allocation = server.create('allocation', 'withTaskWithPorts', { - clientStatus: 'pending' + clientStatus: 'pending', }); await Allocation.visit({ id: allocation.id }); assert.ok(Allocation.isEmpty, 'Task table empty state is shown'); }); - test('when the allocation has not been rescheduled, the reschedule events section is not rendered', async function(assert) { + test('when the allocation has not been rescheduled, the reschedule events section is not rendered', async function (assert) { assert.notOk( Allocation.hasRescheduleEvents, 'Reschedule Events section exists' ); }); - test('ports are listed', async function(assert) { + test('ports are listed', async function (assert) { const allServerPorts = allocation.taskResources.models[0].resources.Ports; allServerPorts.sortBy('Label').forEach((serverPort, index) => { @@ -308,9 +308,9 @@ module('Acceptance | allocation detail', function(hooks) { }); }); - test('services are listed', async function(assert) { + test('services are listed', async function (assert) { const taskGroup = server.schema.taskGroups.findBy({ - name: allocation.taskGroup + name: allocation.taskGroup, }); assert.equal(Allocation.services.length, taskGroup.services.length); @@ -331,7 +331,7 @@ module('Acceptance | allocation detail', function(hooks) { const upstreams = serverService.Connect.SidecarService.Proxy.Upstreams; const serverUpstreamsString = upstreams .map( - upstream => `${upstream.DestinationName}:${upstream.LocalBindPort}` + (upstream) => `${upstream.DestinationName}:${upstream.LocalBindPort}` ) .join(' '); @@ -339,12 +339,12 @@ module('Acceptance | allocation detail', function(hooks) { }); }); - test('when the allocation is not found, an error message is shown, but the URL persists', async function(assert) { + test('when the allocation is not found, an error message is shown, but the URL persists', async function (assert) { await Allocation.visit({ id: 'not-a-real-allocation' }); assert.equal( server.pretender.handledRequests - .filter(request => !request.url.includes('policy')) + .filter((request) => !request.url.includes('policy')) .findBy('status', 404).url, '/v1/allocation/not-a-real-allocation', 'A request to the nonexistent allocation is made' @@ -362,20 +362,20 @@ module('Acceptance | allocation detail', function(hooks) { ); }); - test('allocation can be stopped', async function(assert) { + test('allocation can be stopped', async function (assert) { await Allocation.stop.idle(); await Allocation.stop.confirm(); assert.equal( server.pretender.handledRequests - .reject(request => request.url.includes('fuzzy')) + .reject((request) => request.url.includes('fuzzy')) .findBy('method', 'POST').url, `/v1/allocation/${allocation.id}/stop`, 'Stop request is made for the allocation' ); }); - test('allocation can be restarted', async function(assert) { + test('allocation can be restarted', async function (assert) { await Allocation.restart.idle(); await Allocation.restart.confirm(); @@ -386,7 +386,7 @@ module('Acceptance | allocation detail', function(hooks) { ); }); - test('while an allocation is being restarted, the stop button is disabled', async function(assert) { + test('while an allocation is being restarted, the stop button is disabled', async function (assert) { server.pretender.post('/v1/allocation/:id/stop', () => [204, {}, ''], true); await Allocation.stop.idle(); @@ -400,7 +400,7 @@ module('Acceptance | allocation detail', function(hooks) { await Allocation.stop.confirm(); }); - test('if stopping or restarting fails, an error message is shown', async function(assert) { + test('if stopping or restarting fails, an error message is shown', async function (assert) { server.pretender.post('/v1/allocation/:id/stop', () => [403, {}, '']); await Allocation.stop.idle(); @@ -425,11 +425,11 @@ module('Acceptance | allocation detail', function(hooks) { }); }); -module('Acceptance | allocation detail (rescheduled)', function(hooks) { +module('Acceptance | allocation detail (rescheduled)', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); node = server.create('node'); @@ -439,7 +439,7 @@ module('Acceptance | allocation detail (rescheduled)', function(hooks) { await Allocation.visit({ id: allocation.id }); }); - test('when the allocation has been rescheduled, the reschedule events section is rendered', async function(assert) { + test('when the allocation has been rescheduled, the reschedule events section is rendered', async function (assert) { assert.ok( Allocation.hasRescheduleEvents, 'Reschedule Events section exists' @@ -447,11 +447,11 @@ module('Acceptance | allocation detail (rescheduled)', function(hooks) { }); }); -module('Acceptance | allocation detail (not running)', function(hooks) { +module('Acceptance | allocation detail (not running)', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); node = server.create('node'); @@ -461,7 +461,7 @@ module('Acceptance | allocation detail (not running)', function(hooks) { await Allocation.visit({ id: allocation.id }); }); - test('when the allocation is not running, the utilization graphs are replaced by an empty message', async function(assert) { + test('when the allocation is not running, the utilization graphs are replaced by an empty message', async function (assert) { assert.equal(Allocation.resourceCharts.length, 0, 'No resource charts'); assert.equal( Allocation.resourceEmptyMessage, @@ -470,25 +470,25 @@ module('Acceptance | allocation detail (not running)', function(hooks) { ); }); - test('the exec and stop/restart buttons are absent', async function(assert) { + test('the exec and stop/restart buttons are absent', async function (assert) { assert.notOk(Allocation.execButton.isPresent); assert.notOk(Allocation.stop.isPresent); assert.notOk(Allocation.restart.isPresent); }); }); -module('Acceptance | allocation detail (preemptions)', function(hooks) { +module('Acceptance | allocation detail (preemptions)', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); node = server.create('node'); job = server.create('job', { createAllocations: false }); window.localStorage.clear(); }); - test('shows a dedicated section to the allocation that preempted this allocation', async function(assert) { + 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', @@ -539,7 +539,7 @@ module('Acceptance | allocation detail (preemptions)', function(hooks) { ); }); - test('shows a dedicated section to the allocations this allocation preempted', async function(assert) { + 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( @@ -548,12 +548,12 @@ module('Acceptance | allocation detail (preemptions)', function(hooks) { ); }); - test('each preempted allocation in the table lists basic allocation information', async function(assert) { + 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)) + .map((id) => server.schema.find('allocation', id)) .sortBy('modifyIndex') .reverse()[0]; const preemptionRow = Allocation.preemptions.objectAt(0); @@ -596,16 +596,16 @@ module('Acceptance | allocation detail (preemptions)', function(hooks) { ); }); - test('clicking the client ID in the preempted allocation row naviates to the client page', async function(assert) { + test('clicking the client ID in the preempted allocation row naviates to the client page', async function (assert) { // Navigating to the client page requires node:read permission. const policy = server.create('policy', { id: 'node-read', name: 'node-read', rulesJSON: { Node: { - Policy: 'read' - } - } + Policy: 'read', + }, + }, }); const clientToken = server.create('token', { type: 'client' }); clientToken.policyIds = [policy.id]; @@ -616,7 +616,7 @@ module('Acceptance | allocation detail (preemptions)', function(hooks) { await Allocation.visit({ id: allocation.id }); const preemption = allocation.preemptedAllocations - .map(id => server.schema.find('allocation', id)) + .map((id) => server.schema.find('allocation', id)) .sortBy('modifyIndex') .reverse()[0]; const preemptionRow = Allocation.preemptions.objectAt(0); @@ -629,7 +629,7 @@ module('Acceptance | allocation detail (preemptions)', function(hooks) { ); }); - test('when an allocation both preempted allocations and was preempted itself, both preemptions sections are shown', async function(assert) { + 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( diff --git a/ui/tests/acceptance/client-monitor-test.js b/ui/tests/acceptance/client-monitor-test.js index 900885b97..9b7db370a 100644 --- a/ui/tests/acceptance/client-monitor-test.js +++ b/ui/tests/acceptance/client-monitor-test.js @@ -11,11 +11,11 @@ let node; let managementToken; let clientToken; -module('Acceptance | client monitor', function(hooks) { +module('Acceptance | client monitor', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(function() { + hooks.beforeEach(function () { node = server.create('node'); managementToken = server.create('token'); @@ -27,12 +27,14 @@ module('Acceptance | client monitor', function(hooks) { run.later(run, run.cancelTimers, 500); }); - test('it passes an accessibility audit', async function(assert) { + test('it passes an accessibility audit', async function (assert) { + assert.expect(1); + await ClientMonitor.visit({ id: node.id }); await a11yAudit(assert); }); - test('/clients/:id/monitor should have a breadcrumb trail linking back to clients', async function(assert) { + test('/clients/:id/monitor should have a breadcrumb trail linking back to clients', async function (assert) { await ClientMonitor.visit({ id: node.id }); assert.equal(Layout.breadcrumbFor('clients.index').text, 'Clients'); @@ -45,10 +47,10 @@ module('Acceptance | client monitor', function(hooks) { assert.equal(currentURL(), '/clients'); }); - test('the monitor page immediately streams agent monitor output at the info level', async function(assert) { + test('the monitor page immediately streams agent monitor output at the info level', async function (assert) { await ClientMonitor.visit({ id: node.id }); - const logRequest = server.pretender.handledRequests.find(req => + const logRequest = server.pretender.handledRequests.find((req) => req.url.startsWith('/v1/agent/monitor') ); assert.ok(ClientMonitor.logsArePresent); @@ -56,13 +58,13 @@ module('Acceptance | client monitor', function(hooks) { assert.ok(logRequest.url.includes('log_level=info')); }); - test('switching the log level persists the new log level as a query param', async function(assert) { + test('switching the log level persists the new log level as a query param', async function (assert) { await ClientMonitor.visit({ id: node.id }); await ClientMonitor.selectLogLevel('Debug'); assert.equal(currentURL(), `/clients/${node.id}/monitor?level=debug`); }); - test('when the current access token does not include the agent:read rule, a descriptive error message is shown', async function(assert) { + test('when the current access token does not include the agent:read rule, a descriptive error message is shown', async function (assert) { window.localStorage.nomadTokenSecret = clientToken.secretId; await ClientMonitor.visit({ id: node.id }); diff --git a/ui/tests/acceptance/server-monitor-test.js b/ui/tests/acceptance/server-monitor-test.js index b6b174a3f..dc3b755e7 100644 --- a/ui/tests/acceptance/server-monitor-test.js +++ b/ui/tests/acceptance/server-monitor-test.js @@ -40,7 +40,10 @@ module('Acceptance | server monitor', function (hooks) { 'Servers', 'The page should read the breadcrumb Servers' ); - assert.equal(Layout.breadcrumbFor('servers.server').text, `Server ${agent.name}`); + assert.equal( + Layout.breadcrumbFor('servers.server').text, + `Server ${agent.name}` + ); await Layout.breadcrumbFor('servers.index').visit(); assert.equal(currentURL(), '/servers'); diff --git a/ui/tests/acceptance/task-detail-test.js b/ui/tests/acceptance/task-detail-test.js index 625b09821..b9adbb3d0 100644 --- a/ui/tests/acceptance/task-detail-test.js +++ b/ui/tests/acceptance/task-detail-test.js @@ -1,3 +1,4 @@ +/* eslint-disable qunit/require-expect */ import { currentURL, waitFor } from '@ember/test-helpers'; import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; @@ -10,27 +11,29 @@ import moment from 'moment'; let allocation; let task; -module('Acceptance | task detail', function(hooks) { +module('Acceptance | task detail', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); server.create('node'); server.create('job', { createAllocations: false }); allocation = server.create('allocation', 'withTaskWithPorts', { - clientStatus: 'running' + clientStatus: 'running', }); task = server.db.taskStates.where({ allocationId: allocation.id })[0]; await Task.visit({ id: allocation.id, name: task.name }); }); - test('it passes an accessibility audit', async function(assert) { + test('it passes an accessibility audit', async function (assert) { + assert.expect(1); + await a11yAudit(assert); }); - test('/allocation/:id/:task_name should name the task and list high-level task information', async function(assert) { + test('/allocation/:id/:task_name should name the task and list high-level task information', async function (assert) { assert.ok(Task.title.text.includes(task.name), 'Task name'); assert.ok(Task.state.includes(task.state), 'Task state'); @@ -61,7 +64,7 @@ module('Acceptance | task detail', function(hooks) { assert.equal(document.title, `Task ${task.name} - Nomad`); }); - test('breadcrumbs match jobs / job / task group / allocation / task', async function(assert) { + test('breadcrumbs match jobs / job / task group / allocation / task', async function (assert) { const { jobId, taskGroup } = allocation; const job = server.db.jobs.find(jobId); @@ -122,7 +125,7 @@ module('Acceptance | task detail', function(hooks) { ); }); - test('/allocation/:id/:task_name should include resource utilization graphs', async function(assert) { + test('/allocation/:id/:task_name should include resource utilization graphs', async function (assert) { assert.equal( Task.resourceCharts.length, 2, @@ -140,7 +143,7 @@ module('Acceptance | task detail', function(hooks) { ); }); - test('the events table lists all recent events', async function(assert) { + test('the events table lists all recent events', async function (assert) { const events = server.db.taskEvents.where({ taskStateId: task.id }); assert.equal( @@ -150,26 +153,26 @@ module('Acceptance | task detail', function(hooks) { ); }); - test('when a task has volumes, the volumes table is shown', async function(assert) { + test('when a task has volumes, the volumes table is shown', async function (assert) { const taskGroup = server.schema.taskGroups.where({ jobId: allocation.jobId, - name: allocation.taskGroup + name: allocation.taskGroup, }).models[0]; - const jobTask = taskGroup.tasks.models.find(m => m.name === task.name); + const jobTask = taskGroup.tasks.models.find((m) => m.name === task.name); assert.ok(Task.hasVolumes); assert.equal(Task.volumes.length, jobTask.volumeMounts.length); }); - test('when a task does not have volumes, the volumes table is not shown', async function(assert) { + test('when a task does not have volumes, the volumes table is not shown', async function (assert) { const job = server.create('job', { createAllocations: false, - noHostVolumes: true + noHostVolumes: true, }); allocation = server.create('allocation', { jobId: job.id, - clientStatus: 'running' + clientStatus: 'running', }); task = server.db.taskStates.where({ allocationId: allocation.id })[0]; @@ -177,16 +180,16 @@ module('Acceptance | task detail', function(hooks) { assert.notOk(Task.hasVolumes); }); - test('each volume in the volumes table shows information about the volume', async function(assert) { + test('each volume in the volumes table shows information about the volume', async function (assert) { const taskGroup = server.schema.taskGroups.where({ jobId: allocation.jobId, - name: allocation.taskGroup + name: allocation.taskGroup, }).models[0]; - const jobTask = taskGroup.tasks.models.find(m => m.name === task.name); + const jobTask = taskGroup.tasks.models.find((m) => m.name === task.name); const volume = jobTask.volumeMounts[0]; - Task.volumes[0].as(volumeRow => { + Task.volumes[0].as((volumeRow) => { assert.equal(volumeRow.name, volume.Volume); assert.equal(volumeRow.destination, volume.Destination); assert.equal( @@ -200,7 +203,7 @@ module('Acceptance | task detail', function(hooks) { }); }); - test('each recent event should list the time, type, and description of the event', async function(assert) { + test('each recent event should list the time, type, and description of the event', async function (assert) { const event = server.db.taskEvents.where({ taskStateId: task.id })[0]; const recentEvent = Task.events.objectAt(Task.events.length - 1); @@ -213,12 +216,12 @@ module('Acceptance | task detail', function(hooks) { assert.equal(recentEvent.message, event.displayMessage, 'Event message'); }); - test('when the allocation is not found, the application errors', async function(assert) { + test('when the allocation is not found, the application errors', async function (assert) { await Task.visit({ id: 'not-a-real-allocation', name: task.name }); assert.equal( server.pretender.handledRequests - .filter(request => !request.url.includes('policy')) + .filter((request) => !request.url.includes('policy')) .findBy('status', 404).url, '/v1/allocation/not-a-real-allocation', 'A request to the nonexistent allocation is made' @@ -232,7 +235,7 @@ module('Acceptance | task detail', function(hooks) { assert.equal(Task.error.title, 'Not Found', 'Error message is for 404'); }); - test('when the allocation is found but the task is not, the application errors', async function(assert) { + test('when the allocation is found but the task is not, the application errors', async function (assert) { await Task.visit({ id: allocation.id, name: 'not-a-real-task-name' }); assert.ok( @@ -251,7 +254,7 @@ module('Acceptance | task detail', function(hooks) { assert.equal(Task.error.title, 'Not Found', 'Error message is for 404'); }); - test('task can be restarted', async function(assert) { + test('task can be restarted', async function (assert) { await Task.restart.idle(); await Task.restart.confirm(); @@ -269,11 +272,11 @@ module('Acceptance | task detail', function(hooks) { ); }); - test('when task restart fails (403), an ACL permissions error message is shown', async function(assert) { + test('when task restart fails (403), an ACL permissions error message is shown', async function (assert) { server.pretender.put('/v1/client/allocation/:id/restart', () => [ 403, {}, - '' + '', ]); await Task.restart.idle(); @@ -294,12 +297,12 @@ module('Acceptance | task detail', function(hooks) { assert.notOk(Task.inlineError.isShown, 'Inline error is no longer shown'); }); - test('when task restart fails (500), the error message from the API is piped through to the alert', async function(assert) { + test('when task restart fails (500), the error message from the API is piped through to the alert', async function (assert) { const message = 'A plaintext error message'; server.pretender.put('/v1/client/allocation/:id/restart', () => [ 500, {}, - message + message, ]); await Task.restart.idle(); @@ -314,21 +317,21 @@ module('Acceptance | task detail', function(hooks) { assert.notOk(Task.inlineError.isShown); }); - test('exec button is present', async function(assert) { + test('exec button is present', async function (assert) { assert.ok(Task.execButton.isPresent); }); }); -module('Acceptance | task detail (no addresses)', function(hooks) { +module('Acceptance | task detail (no addresses)', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); server.create('node'); server.create('job'); allocation = server.create('allocation', 'withoutTaskWithPorts', { - clientStatus: 'running' + clientStatus: 'running', }); task = server.db.taskStates.where({ allocationId: allocation.id })[0]; @@ -336,28 +339,28 @@ module('Acceptance | task detail (no addresses)', function(hooks) { }); }); -module('Acceptance | task detail (different namespace)', function(hooks) { +module('Acceptance | task detail (different namespace)', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); server.create('node'); server.create('namespace'); server.create('namespace', { id: 'other-namespace' }); server.create('job', { createAllocations: false, - namespaceId: 'other-namespace' + namespaceId: 'other-namespace', }); allocation = server.create('allocation', 'withTaskWithPorts', { - clientStatus: 'running' + clientStatus: 'running', }); task = server.db.taskStates.where({ allocationId: allocation.id })[0]; await Task.visit({ id: allocation.id, name: task.name }); }); - test('breadcrumbs match jobs / job / task group / allocation / task', async function(assert) { + test('breadcrumbs match jobs / job / task group / allocation / task', async function (assert) { const { jobId, taskGroup } = allocation; const job = server.db.jobs.find(jobId); @@ -394,28 +397,28 @@ module('Acceptance | task detail (different namespace)', function(hooks) { }); }); -module('Acceptance | task detail (not running)', function(hooks) { +module('Acceptance | task detail (not running)', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); server.create('node'); server.create('namespace'); server.create('namespace', { id: 'other-namespace' }); server.create('job', { createAllocations: false, - namespaceId: 'other-namespace' + namespaceId: 'other-namespace', }); allocation = server.create('allocation', 'withTaskWithPorts', { - clientStatus: 'complete' + clientStatus: 'complete', }); task = server.db.taskStates.where({ allocationId: allocation.id })[0]; await Task.visit({ id: allocation.id, name: task.name }); }); - test('when the allocation for a task is not running, the resource utilization graphs are replaced by an empty message', async function(assert) { + test('when the allocation for a task is not running, the resource utilization graphs are replaced by an empty message', async function (assert) { assert.equal(Task.resourceCharts.length, 0, 'No resource charts'); assert.equal( Task.resourceEmptyMessage, @@ -424,21 +427,21 @@ module('Acceptance | task detail (not running)', function(hooks) { ); }); - test('exec button is absent', async function(assert) { + test('exec button is absent', async function (assert) { assert.notOk(Task.execButton.isPresent); }); }); -module('Acceptance | proxy task detail', function(hooks) { +module('Acceptance | proxy task detail', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); server.create('node'); server.create('job', { createAllocations: false }); allocation = server.create('allocation', 'withTaskWithPorts', { - clientStatus: 'running' + clientStatus: 'running', }); const taskState = allocation.taskStates.models[0]; @@ -449,7 +452,7 @@ module('Acceptance | proxy task detail', function(hooks) { await Task.visit({ id: allocation.id, name: taskState.name }); }); - test('a proxy tag is shown', async function(assert) { + test('a proxy tag is shown', async function (assert) { assert.ok(Task.title.proxyTag.isPresent); }); }); diff --git a/ui/tests/acceptance/task-group-detail-test.js b/ui/tests/acceptance/task-group-detail-test.js index e5378f0af..c07e0c477 100644 --- a/ui/tests/acceptance/task-group-detail-test.js +++ b/ui/tests/acceptance/task-group-detail-test.js @@ -9,7 +9,7 @@ import { formatBytes, formatHertz, formatScheduledBytes, - formatScheduledHertz + formatScheduledHertz, } from 'nomad-ui/utils/units'; import TaskGroup from 'nomad-ui/tests/pages/jobs/job/task-group'; import Layout from 'nomad-ui/tests/pages/layout'; @@ -24,30 +24,30 @@ let managementToken; const sum = (total, n) => total + n; -module('Acceptance | task group detail', function(hooks) { +module('Acceptance | task group detail', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('agent'); server.create('node', 'forceIPv4'); job = server.create('job', { groupsCount: 2, - createAllocations: false + createAllocations: false, }); const taskGroups = server.db.taskGroups.where({ jobId: job.id }); taskGroup = taskGroups[0]; - tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id)); + tasks = taskGroup.taskIds.map((id) => server.db.tasks.find(id)); server.create('node', 'forceIPv4'); allocations = server.createList('allocation', 2, { jobId: job.id, taskGroup: taskGroup.name, - clientStatus: 'running' + clientStatus: 'running', }); // Allocations associated to a different task group on the job to @@ -55,20 +55,20 @@ module('Acceptance | task group detail', function(hooks) { server.createList('allocation', 3, { jobId: job.id, taskGroup: taskGroups[1].name, - clientStatus: 'running' + clientStatus: 'running', }); // Set a static name to make the search test deterministic - server.db.allocations.forEach(alloc => { + server.db.allocations.forEach((alloc) => { alloc.name = 'aaaaa'; }); // Mark the first alloc as rescheduled allocations[0].update({ - nextAllocation: allocations[1].id + nextAllocation: allocations[1].id, }); allocations[1].update({ - previousAllocation: allocations[0].id + previousAllocation: allocations[0].id, }); managementToken = server.create('token'); @@ -76,16 +76,16 @@ module('Acceptance | task group detail', function(hooks) { window.localStorage.clear(); }); - test('it passes an accessibility audit', async function(assert) { + test('it passes an accessibility audit', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); await a11yAudit(assert); }); - test('/jobs/:id/:task-group should list high-level metrics for the allocation', async function(assert) { + test('/jobs/:id/:task-group should list high-level metrics for the allocation', async function (assert) { const totalCPU = tasks.mapBy('resources.CPU').reduce(sum, 0); const totalMemory = tasks.mapBy('resources.MemoryMB').reduce(sum, 0); const totalMemoryMax = tasks - .map(t => t.resources.MemoryMaxMB || t.resources.MemoryMB) + .map((t) => t.resources.MemoryMaxMB || t.resources.MemoryMB) .reduce(sum, 0); const totalDisk = taskGroup.ephemeralDisk.SizeMB; @@ -127,7 +127,7 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('/jobs/:id/:task-group should have breadcrumbs for job and jobs', async function(assert) { + test('/jobs/:id/:task-group should have breadcrumbs for job and jobs', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); assert.equal( @@ -147,14 +147,14 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('/jobs/:id/:task-group first breadcrumb should link to jobs', async function(assert) { + test('/jobs/:id/:task-group first breadcrumb should link to jobs', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); await Layout.breadcrumbFor('jobs.index').visit(); assert.equal(currentURL(), '/jobs', 'First breadcrumb links back to jobs'); }); - test('/jobs/:id/:task-group second breadcrumb should link to the job for the task group', async function(assert) { + test('/jobs/:id/:task-group second breadcrumb should link to the job for the task group', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); await Layout.breadcrumbFor('jobs.job.index').visit(); @@ -165,7 +165,7 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('when the user has a client token that has a namespace with a policy to run and scale a job the autoscaler options should be available', async function(assert) { + test('when the user has a client token that has a namespace with a policy to run and scale a job the autoscaler options should be available', async function (assert) { window.localStorage.clear(); const SCALE_AND_WRITE_NAMESPACE = 'scale-and-write-namespace'; @@ -174,7 +174,7 @@ module('Acceptance | task group detail', function(hooks) { server.create('namespace', { id: SCALE_AND_WRITE_NAMESPACE }); const secondNamespace = server.create('namespace', { - id: READ_ONLY_NAMESPACE + id: READ_ONLY_NAMESPACE, }); job = server.create('job', { @@ -182,14 +182,14 @@ module('Acceptance | task group detail', function(hooks) { createAllocations: false, shallow: true, noActiveDeployment: true, - namespaceId: SCALE_AND_WRITE_NAMESPACE + namespaceId: SCALE_AND_WRITE_NAMESPACE, }); const scalingGroup = server.create('task-group', { job, name: 'scaling', count: 1, shallow: true, - withScaling: true + withScaling: true, }); job.update({ taskGroupIds: [scalingGroup.id] }); @@ -198,14 +198,14 @@ module('Acceptance | task group detail', function(hooks) { createAllocations: false, shallow: true, noActiveDeployment: true, - namespaceId: READ_ONLY_NAMESPACE + namespaceId: READ_ONLY_NAMESPACE, }); const scalingGroup2 = server.create('task-group', { job: job2, name: 'scaling', count: 1, shallow: true, - withScaling: true + withScaling: true, }); job2.update({ taskGroupIds: [scalingGroup2.id] }); @@ -216,14 +216,14 @@ module('Acceptance | task group detail', function(hooks) { Namespaces: [ { Name: SCALE_AND_WRITE_NAMESPACE, - Capabilities: ['scale-job', 'submit-job', 'read-job', 'list-jobs'] + Capabilities: ['scale-job', 'submit-job', 'read-job', 'list-jobs'], }, { Name: READ_ONLY_NAMESPACE, - Capabilities: ['list-jobs', 'read-job'] - } - ] - } + Capabilities: ['list-jobs', 'read-job'], + }, + ], + }, }); clientToken.policyIds = [policy.id]; @@ -234,7 +234,7 @@ module('Acceptance | task group detail', function(hooks) { await TaskGroup.visit({ id: job.id, name: scalingGroup.name, - namespace: SCALE_AND_WRITE_NAMESPACE + namespace: SCALE_AND_WRITE_NAMESPACE, }); assert.equal( @@ -246,7 +246,7 @@ module('Acceptance | task group detail', function(hooks) { await TaskGroup.visit({ id: job2.id, name: scalingGroup2.name, - namespace: secondNamespace.name + namespace: secondNamespace.name, }); assert.equal( currentURL(), @@ -255,11 +255,11 @@ module('Acceptance | task group detail', function(hooks) { assert.ok(TaskGroup.countStepper.increment.isDisabled); }); - test('/jobs/:id/:task-group should list one page of allocations for the task group', async function(assert) { + test('/jobs/:id/:task-group should list one page of allocations for the task group', async function (assert) { server.createList('allocation', TaskGroup.pageSize, { jobId: job.id, taskGroup: taskGroup.name, - clientStatus: 'running' + clientStatus: 'running', }); await TaskGroup.visit({ id: job.id, name: taskGroup.name }); @@ -277,7 +277,7 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('each allocation should show basic information about the allocation', async function(assert) { + test('each allocation should show basic information about the allocation', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); const allocation = allocations.sortBy('modifyIndex').reverse()[0]; @@ -320,16 +320,16 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('clicking the client ID in the allocation row naviates to the client page', async function(assert) { + test('clicking the client ID in the allocation row naviates to the client page', async function (assert) { // Navigating to the client page requires node:read permission. const policy = server.create('policy', { id: 'node-read', name: 'node-read', rulesJSON: { Node: { - Policy: 'read' - } - } + Policy: 'read', + }, + }, }); const clientToken = server.create('token', { type: 'client' }); clientToken.policyIds = [policy.id]; @@ -349,14 +349,14 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('each allocation should show stats about the allocation', async function(assert) { + test('each allocation should show stats about the allocation', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); const allocation = allocations.sortBy('name')[0]; const allocationRow = TaskGroup.allocations.objectAt(0); const allocStats = server.db.clientAllocationStats.find(allocation.id); - const tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id)); + const tasks = taskGroup.taskIds.map((id) => server.db.tasks.find(id)); const cpuUsed = tasks.reduce((sum, task) => sum + task.resources.CPU, 0); const memoryUsed = tasks.reduce( @@ -395,7 +395,7 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('when the allocation search has no matches, there is an empty message', async function(assert) { + test('when the allocation search has no matches, there is an empty message', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); await TaskGroup.search('zzzzzz'); @@ -408,7 +408,7 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('when the allocation has reschedule events, the allocation row is denoted with an icon', async function(assert) { + test('when the allocation has reschedule events, the allocation row is denoted with an icon', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); const rescheduleRow = TaskGroup.allocationFor(allocations[0].id); @@ -421,10 +421,10 @@ module('Acceptance | task group detail', function(hooks) { assert.notOk(normalRow.rescheduled, 'Normal row has no reschedule icon'); }); - test('/jobs/:id/:task-group should present task lifecycles', async function(assert) { + test('/jobs/:id/:task-group should present task lifecycles', async function (assert) { job = server.create('job', { groupsCount: 2, - groupTaskCount: 3 + groupTaskCount: 3, }); const taskGroups = server.db.taskGroups.where({ jobId: job.id }); @@ -438,21 +438,21 @@ module('Acceptance | task group detail', function(hooks) { 'Task Lifecycle Configuration' ); - tasks = taskGroup.taskIds.map(id => server.db.tasks.find(id)); + tasks = taskGroup.taskIds.map((id) => server.db.tasks.find(id)); const taskNames = tasks.mapBy('name'); // This is thoroughly tested in allocation detail tests, so this mostly checks what’s different assert.equal(TaskGroup.lifecycleChart.tasks.length, 3); - TaskGroup.lifecycleChart.tasks.forEach(Task => { + TaskGroup.lifecycleChart.tasks.forEach((Task) => { assert.ok(taskNames.includes(Task.name)); assert.notOk(Task.isActive); assert.notOk(Task.isFinished); }); }); - test('when the task group depends on volumes, the volumes table is shown', async function(assert) { + test('when the task group depends on volumes, the volumes table is shown', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); assert.ok(TaskGroup.hasVolumes); @@ -462,7 +462,7 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('when the task group does not depend on volumes, the volumes table is not shown', async function(assert) { + test('when the task group does not depend on volumes, the volumes table is not shown', async function (assert) { job = server.create('job', { noHostVolumes: true, shallow: true }); taskGroup = server.db.taskGroups.where({ jobId: job.id })[0]; @@ -471,10 +471,10 @@ module('Acceptance | task group detail', function(hooks) { assert.notOk(TaskGroup.hasVolumes); }); - test('each row in the volumes table lists information about the volume', async function(assert) { + test('each row in the volumes table lists information about the volume', async function (assert) { await TaskGroup.visit({ id: job.id, name: taskGroup.name }); - TaskGroup.volumes[0].as(volumeRow => { + TaskGroup.volumes[0].as((volumeRow) => { const volume = taskGroup.volumes[volumeRow.name]; assert.equal(volumeRow.name, volume.Name); assert.equal(volumeRow.type, volume.Type); @@ -486,21 +486,21 @@ module('Acceptance | task group detail', function(hooks) { }); }); - test('the count stepper sends the appropriate POST request', async function(assert) { + test('the count stepper sends the appropriate POST request', async function (assert) { window.localStorage.nomadTokenSecret = managementToken.secretId; job = server.create('job', { groupCount: 0, createAllocations: false, shallow: true, - noActiveDeployment: true + noActiveDeployment: true, }); const scalingGroup = server.create('task-group', { job, name: 'scaling', count: 1, shallow: true, - withScaling: true + withScaling: true, }); job.update({ taskGroupIds: [scalingGroup.id] }); @@ -509,28 +509,28 @@ module('Acceptance | task group detail', function(hooks) { await settled(); const scaleRequest = server.pretender.handledRequests.find( - req => req.method === 'POST' && req.url.endsWith('/scale') + (req) => req.method === 'POST' && req.url.endsWith('/scale') ); const requestBody = JSON.parse(scaleRequest.requestBody); assert.equal(requestBody.Target.Group, scalingGroup.name); assert.equal(requestBody.Count, scalingGroup.count + 1); }); - test('the count stepper is disabled when a deployment is running', async function(assert) { + test('the count stepper is disabled when a deployment is running', async function (assert) { window.localStorage.nomadTokenSecret = managementToken.secretId; job = server.create('job', { groupCount: 0, createAllocations: false, shallow: true, - activeDeployment: true + activeDeployment: true, }); const scalingGroup = server.create('task-group', { job, name: 'scaling', count: 1, shallow: true, - withScaling: true + withScaling: true, }); job.update({ taskGroupIds: [scalingGroup.id] }); @@ -541,15 +541,15 @@ module('Acceptance | task group detail', function(hooks) { assert.ok(TaskGroup.countStepper.decrement.isDisabled); }); - test('when the job for the task group is not found, an error message is shown, but the URL persists', async function(assert) { + test('when the job for the task group is not found, an error message is shown, but the URL persists', async function (assert) { await TaskGroup.visit({ id: 'not-a-real-job', - name: 'not-a-real-task-group' + name: 'not-a-real-task-group', }); assert.equal( server.pretender.handledRequests - .filter(request => !request.url.includes('policy')) + .filter((request) => !request.url.includes('policy')) .findBy('status', 404).url, '/v1/job/not-a-real-job', 'A request to the nonexistent job is made' @@ -567,7 +567,7 @@ module('Acceptance | task group detail', function(hooks) { ); }); - test('when the task group is not found on the job, an error message is shown, but the URL persists', async function(assert) { + test('when the task group is not found on the job, an error message is shown, but the URL persists', async function (assert) { await TaskGroup.visit({ id: job.id, name: 'not-a-real-task-group' }); assert.ok( @@ -598,16 +598,16 @@ module('Acceptance | task group detail', function(hooks) { server.createList('allocation', TaskGroup.pageSize, { jobId: job.id, taskGroup: taskGroup.name, - clientStatus: 'running' + clientStatus: 'running', }); await TaskGroup.visit({ id: job.id, name: taskGroup.name }); - } + }, }); - test('when a task group has no scaling events, there is no recent scaling events section', async function(assert) { + test('when a task group has no scaling events, there is no recent scaling events section', async function (assert) { const taskGroupScale = job.jobScale.taskGroupScales.models.find( - m => m.name === taskGroup.name + (m) => m.name === taskGroup.name ); taskGroupScale.update({ events: [] }); @@ -616,9 +616,9 @@ module('Acceptance | task group detail', function(hooks) { assert.notOk(TaskGroup.hasScaleEvents); }); - test('the recent scaling events section shows all recent scaling events in reverse chronological order', async function(assert) { + test('the recent scaling events section shows all recent scaling events in reverse chronological order', async function (assert) { const taskGroupScale = job.jobScale.taskGroupScales.models.find( - m => m.name === taskGroup.name + (m) => m.name === taskGroup.name ); taskGroupScale.update({ events: [ @@ -627,8 +627,8 @@ module('Acceptance | task group detail', function(hooks) { server.create('scale-event', { error: true }), server.create('scale-event', { error: true }), server.create('scale-event', { count: 3, error: false }), - server.create('scale-event', { count: 1, error: false }) - ] + server.create('scale-event', { count: 1, error: false }), + ], }); const scaleEvents = taskGroupScale.events.models.sortBy('time').reverse(); await TaskGroup.visit({ id: job.id, name: taskGroup.name }); @@ -660,9 +660,9 @@ module('Acceptance | task group detail', function(hooks) { }); }); - test('when a task group has at least two count scaling events and the count scaling events outnumber the non-count scaling events, a timeline is shown in addition to the accordion', async function(assert) { + test('when a task group has at least two count scaling events and the count scaling events outnumber the non-count scaling events, a timeline is shown in addition to the accordion', async function (assert) { const taskGroupScale = job.jobScale.taskGroupScales.models.find( - m => m.name === taskGroup.name + (m) => m.name === taskGroup.name ); taskGroupScale.update({ events: [ @@ -674,8 +674,8 @@ module('Acceptance | task group detail', function(hooks) { server.create('scale-event', { count: 3, error: false }), server.create('scale-event', { count: 2, error: false }), server.create('scale-event', { count: 9, error: false }), - server.create('scale-event', { count: 1, error: false }) - ] + server.create('scale-event', { count: 1, error: false }), + ], }); const scaleEvents = taskGroupScale.events.models.sortBy('time').reverse(); await TaskGroup.visit({ id: job.id, name: taskGroup.name }); @@ -685,7 +685,7 @@ module('Acceptance | task group detail', function(hooks) { assert.equal( TaskGroup.scalingAnnotations.length, - scaleEvents.filter(ev => ev.count == null).length + scaleEvents.filter((ev) => ev.count == null).length ); }); @@ -694,7 +694,7 @@ module('Acceptance | task group detail', function(hooks) { paramName: 'status', expectedOptions: ['Pending', 'Running', 'Complete', 'Failed', 'Lost'], async beforeEach() { - ['pending', 'running', 'complete', 'failed', 'lost'].forEach(s => { + ['pending', 'running', 'complete', 'failed', 'lost'].forEach((s) => { server.createList('allocation', 5, { clientStatus: s }); }); await TaskGroup.visit({ id: job.id, name: taskGroup.name }); @@ -702,7 +702,7 @@ module('Acceptance | task group detail', function(hooks) { filter: (alloc, selection) => alloc.jobId == job.id && alloc.taskGroup == taskGroup.name && - selection.includes(alloc.clientStatus) + selection.includes(alloc.clientStatus), }); testFacet('Client', { @@ -713,21 +713,21 @@ module('Acceptance | task group detail', function(hooks) { new Set( allocs .filter( - alloc => + (alloc) => alloc.jobId == job.id && alloc.taskGroup == taskGroup.name ) .mapBy('nodeId') - .map(id => id.split('-')[0]) + .map((id) => id.split('-')[0]) ) ).sort(); }, async beforeEach() { const nodes = server.createList('node', 3, 'forceIPv4'); - nodes.forEach(node => + nodes.forEach((node) => server.createList('allocation', 5, { nodeId: node.id, jobId: job.id, - taskGroup: taskGroup.name + taskGroup: taskGroup.name, }) ); await TaskGroup.visit({ id: job.id, name: taskGroup.name }); @@ -735,7 +735,7 @@ module('Acceptance | task group detail', function(hooks) { filter: (alloc, selection) => alloc.jobId == job.id && alloc.taskGroup == taskGroup.name && - selection.includes(alloc.nodeId.split('-')[0]) + selection.includes(alloc.nodeId.split('-')[0]), }); }); @@ -743,7 +743,7 @@ function testFacet( label, { facet, paramName, beforeEach, filter, expectedOptions } ) { - test(`facet ${label} | the ${label} facet has the correct options`, async function(assert) { + test(`facet ${label} | the ${label} facet has the correct options`, async function (assert) { await beforeEach(); await facet.toggle(); @@ -755,13 +755,13 @@ function testFacet( } assert.deepEqual( - facet.options.map(option => option.label.trim()), + facet.options.map((option) => option.label.trim()), expectation, 'Options for facet are as expected' ); }); - test(`facet ${label} | the ${label} facet filters the allocations list by ${label}`, async function(assert) { + test(`facet ${label} | the ${label} facet filters the allocations list by ${label}`, async function (assert) { let option; await beforeEach(); @@ -772,7 +772,7 @@ function testFacet( const selection = [option.key]; const expectedAllocs = server.db.allocations - .filter(alloc => filter(alloc, selection)) + .filter((alloc) => filter(alloc, selection)) .sortBy('modifyIndex') .reverse(); @@ -785,7 +785,7 @@ function testFacet( }); }); - test(`facet ${label} | selecting multiple options in the ${label} facet results in a broader search`, async function(assert) { + test(`facet ${label} | selecting multiple options in the ${label} facet results in a broader search`, async function (assert) { const selection = []; await beforeEach(); @@ -799,7 +799,7 @@ function testFacet( selection.push(option2.key); const expectedAllocs = server.db.allocations - .filter(alloc => filter(alloc, selection)) + .filter((alloc) => filter(alloc, selection)) .sortBy('modifyIndex') .reverse(); @@ -812,7 +812,7 @@ function testFacet( }); }); - test(`facet ${label} | selecting options in the ${label} facet updates the ${paramName} query param`, async function(assert) { + test(`facet ${label} | selecting options in the ${label} facet updates the ${paramName} query param`, async function (assert) { const selection = []; await beforeEach(); diff --git a/ui/tests/helpers/module-for-job.js b/ui/tests/helpers/module-for-job.js index f873a0452..5fb740a01 100644 --- a/ui/tests/helpers/module-for-job.js +++ b/ui/tests/helpers/module-for-job.js @@ -16,10 +16,10 @@ export default function moduleForJob( ) { let job; - module(title, function(hooks) { + module(title, function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.before(function() { + hooks.before(function () { if (context !== 'allocations' && context !== 'children') { throw new Error( `Invalid context provided to moduleForJob, expected either "allocations" or "children", got ${context}` @@ -27,7 +27,7 @@ export default function moduleForJob( } }); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { server.create('node'); job = jobFactory(); if (!job.namespace || job.namespace === 'default') { @@ -37,7 +37,7 @@ export default function moduleForJob( } }); - test('visiting /jobs/:job_id', async function(assert) { + test('visiting /jobs/:job_id', async function (assert) { const expectedURL = new URL( urlWithNamespace(`/jobs/${encodeURIComponent(job.id)}`, job.namespace), window.location @@ -49,7 +49,7 @@ export default function moduleForJob( assert.equal(document.title, `Job ${job.name} - Nomad`); }); - test('the subnav links to overview', async function(assert) { + test('the subnav links to overview', async function (assert) { await JobDetail.tabFor('overview').visit(); const expectedURL = new URL( @@ -62,7 +62,7 @@ export default function moduleForJob( assert.deepEqual(gotURL.searchParams, expectedURL.searchParams); }); - test('the subnav links to definition', async function(assert) { + test('the subnav links to definition', async function (assert) { await JobDetail.tabFor('definition').visit(); assert.equal( currentURL(), @@ -73,7 +73,7 @@ export default function moduleForJob( ); }); - test('the subnav links to versions', async function(assert) { + test('the subnav links to versions', async function (assert) { await JobDetail.tabFor('versions').visit(); assert.equal( currentURL(), @@ -84,7 +84,7 @@ export default function moduleForJob( ); }); - test('the subnav links to evaluations', async function(assert) { + test('the subnav links to evaluations', async function (assert) { await JobDetail.tabFor('evaluations').visit(); assert.equal( currentURL(), @@ -95,7 +95,7 @@ export default function moduleForJob( ); }); - test('the title buttons are dependent on job status', async function(assert) { + test('the title buttons are dependent on job status', async function (assert) { if (job.status === 'dead') { assert.ok(JobDetail.start.isPresent); assert.notOk(JobDetail.stop.isPresent); @@ -108,7 +108,7 @@ export default function moduleForJob( }); if (context === 'allocations') { - test('allocations for the job are shown in the overview', async function(assert) { + test('allocations for the job are shown in the overview', async function (assert) { assert.ok( JobDetail.allocationsSummary.isPresent, 'Allocations are shown in the summary section' @@ -119,7 +119,7 @@ export default function moduleForJob( ); }); - test('clicking in an allocation row navigates to that allocation', async function(assert) { + test('clicking in an allocation row navigates to that allocation', async function (assert) { const allocationRow = JobDetail.allocations[0]; const allocationId = allocationRow.id; @@ -132,7 +132,7 @@ export default function moduleForJob( ); }); - test('clicking legend item navigates to a pre-filtered allocations table', async function(assert) { + test('clicking legend item navigates to a pre-filtered allocations table', async function (assert) { const legendItem = JobDetail.allocationsSummary.legend.clickableItems[1]; const status = legendItem.label; @@ -151,7 +151,7 @@ export default function moduleForJob( assert.deepEqual(gotURL.searchParams, expectedURL.searchParams); }); - test('clicking in a slice takes you to a pre-filtered allocations table', async function(assert) { + test('clicking in a slice takes you to a pre-filtered allocations table', async function (assert) { const slice = JobDetail.allocationsSummary.slices[1]; const status = slice.label; await slice.click(); @@ -180,7 +180,7 @@ export default function moduleForJob( } if (context === 'children') { - test('children for the job are shown in the overview', async function(assert) { + test('children for the job are shown in the overview', async function (assert) { assert.ok( JobDetail.childrenSummary.isPresent, 'Children are shown in the summary section' @@ -193,7 +193,7 @@ export default function moduleForJob( } for (var testName in additionalTests) { - test(testName, async function(assert) { + test(testName, async function (assert) { await additionalTests[testName].call(this, job, assert); }); } @@ -208,20 +208,20 @@ export function moduleForJobWithClientStatus( ) { let job; - module(title, function(hooks) { + module(title, function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); - hooks.beforeEach(async function() { + hooks.beforeEach(async function () { // Displaying the job status in client requires node:read permission. const policy = server.create('policy', { id: 'node-read', name: 'node-read', rulesJSON: { Node: { - Policy: 'read' - } - } + Policy: 'read', + }, + }, }); const clientToken = server.create('token', { type: 'client' }); clientToken.policyIds = [policy.id]; @@ -232,10 +232,10 @@ export function moduleForJobWithClientStatus( const clients = server.createList('node', 3, { datacenter: 'dc1', - status: 'ready' + status: 'ready', }); job = jobFactory(); - clients.forEach(c => { + clients.forEach((c) => { server.create('allocation', { jobId: job.id, nodeId: c.id }); }); if (!job.namespace || job.namespace === 'default') { @@ -245,7 +245,7 @@ export function moduleForJobWithClientStatus( } }); - test('job status summary is collapsed when not authorized', async function(assert) { + test('job status summary is collapsed when not authorized', async function (assert) { const clientToken = server.create('token', { type: 'client' }); await Tokens.visit(); await Tokens.secret(clientToken.secretId).submit(); @@ -262,7 +262,7 @@ export function moduleForJobWithClientStatus( ); }); - test('the subnav links to clients', async function(assert) { + test('the subnav links to clients', async function (assert) { await JobDetail.tabFor('clients').visit(); assert.equal( currentURL(), @@ -273,14 +273,14 @@ export function moduleForJobWithClientStatus( ); }); - test('job status summary is shown in the overview', async function(assert) { + test('job status summary is shown in the overview', async function (assert) { assert.ok( JobDetail.jobClientStatusSummary.statusBar.isPresent, 'Summary bar is displayed in the Job Status in Client summary section' ); }); - test('clicking legend item navigates to a pre-filtered clients table', async function(assert) { + test('clicking legend item navigates to a pre-filtered clients table', async function (assert) { const legendItem = JobDetail.jobClientStatusSummary.statusBar.legend.clickableItems[0]; const status = legendItem.label; @@ -299,7 +299,7 @@ export function moduleForJobWithClientStatus( assert.deepEqual(gotURL.searchParams, expectedURL.searchParams); }); - test('clicking in a slice takes you to a pre-filtered clients table', async function(assert) { + test('clicking in a slice takes you to a pre-filtered clients table', async function (assert) { const slice = JobDetail.jobClientStatusSummary.statusBar.slices[0]; const status = slice.label; await slice.click(); @@ -325,7 +325,7 @@ export function moduleForJobWithClientStatus( }); for (var testName in additionalTests) { - test(testName, async function(assert) { + test(testName, async function (assert) { await additionalTests[testName].call(this, job, assert); }); } diff --git a/ui/tests/integration/components/allocation-row-test.js b/ui/tests/integration/components/allocation-row-test.js index 97caad096..864629e79 100644 --- a/ui/tests/integration/components/allocation-row-test.js +++ b/ui/tests/integration/components/allocation-row-test.js @@ -8,10 +8,10 @@ import Response from 'ember-cli-mirage/response'; import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer'; import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit'; -module('Integration | Component | allocation row', function(hooks) { +module('Integration | Component | allocation row', function (hooks) { setupRenderingTest(hooks); - hooks.beforeEach(function() { + hooks.beforeEach(function () { fragmentSerializerInitializer(this.owner); this.store = this.owner.lookup('service:store'); this.token = this.owner.lookup('service:token'); @@ -22,11 +22,11 @@ module('Integration | Component | allocation row', function(hooks) { window.localStorage.clear(); }); - hooks.afterEach(function() { + hooks.afterEach(function () { this.server.shutdown(); }); - test('Allocation row polls for stats, even when it errors or has an invalid response', async function(assert) { + test('Allocation row polls for stats, even when it errors or has an invalid response', async function (assert) { const component = this; let currentFrame = 0; @@ -35,10 +35,10 @@ module('Integration | Component | allocation row', function(hooks) { JSON.stringify({ ResourceUsage: generateResources() }), null, 'Valid JSON', - JSON.stringify({ ResourceUsage: generateResources() }) + JSON.stringify({ ResourceUsage: generateResources() }), ]; - this.server.get('/client/allocation/:id/stats', function() { + this.server.get('/client/allocation/:id/stats', function () { const response = frames[++currentFrame]; // Disable polling to stop the EC task in the component @@ -60,7 +60,7 @@ module('Integration | Component | allocation row', function(hooks) { this.setProperties({ allocation, context: 'job', - enablePolling: true + enablePolling: true, }); await render(hbs` @@ -80,16 +80,18 @@ module('Integration | Component | allocation row', function(hooks) { ); }); - test('Allocation row shows warning when it requires drivers that are unhealthy on the node it is running on', async function(assert) { + test('Allocation row shows warning when it requires drivers that are unhealthy on the node it is running on', async function (assert) { + assert.expect(2); + // Driver health status require node:read permission. const policy = server.create('policy', { id: 'node-read', name: 'node-read', rulesJSON: { Node: { - Policy: 'read' - } - } + Policy: 'read', + }, + }, }); const clientToken = server.create('token', { type: 'client' }); clientToken.policyIds = [policy.id]; @@ -101,7 +103,7 @@ module('Integration | Component | allocation row', function(hooks) { const node = this.server.schema.nodes.first(); const drivers = node.drivers; - Object.values(drivers).forEach(driver => { + Object.values(drivers).forEach((driver) => { driver.Healthy = false; driver.Detected = true; }); @@ -116,7 +118,7 @@ module('Integration | Component | allocation row', function(hooks) { this.setProperties({ allocation, - context: 'job' + context: 'job', }); await render(hbs` @@ -132,7 +134,9 @@ module('Integration | Component | allocation row', function(hooks) { await componentA11yAudit(this.element, assert); }); - test('Allocation row shows an icon indicator when it was preempted', async function(assert) { + test('Allocation row shows an icon indicator when it was preempted', async function (assert) { + assert.expect(2); + const allocId = this.server.create('allocation', 'preempted').id; const allocation = await this.store.findRecord('allocation', allocId); @@ -147,14 +151,16 @@ module('Integration | Component | allocation row', function(hooks) { await componentA11yAudit(this.element, assert); }); - test('when an allocation is not running, the utilization graphs are omitted', async function(assert) { + test('when an allocation is not running, the utilization graphs are omitted', async function (assert) { + assert.expect(8); + this.setProperties({ context: 'job', - enablePolling: false + enablePolling: false, }); // All non-running statuses need to be tested - ['pending', 'complete', 'failed', 'lost'].forEach(clientStatus => + ['pending', 'complete', 'failed', 'lost'].forEach((clientStatus) => this.server.create('allocation', { clientStatus }) ); diff --git a/ui/tests/integration/components/app-breadcrumbs-test.js b/ui/tests/integration/components/app-breadcrumbs-test.js index 9c95f79b8..e1bad7de6 100644 --- a/ui/tests/integration/components/app-breadcrumbs-test.js +++ b/ui/tests/integration/components/app-breadcrumbs-test.js @@ -1,20 +1,21 @@ /* eslint-disable ember-a11y-testing/a11y-audit-called */ import { setComponentTemplate } from '@ember/component'; -import Component from '@glimmer/component'; +import templateOnlyComponent from '@ember/component/template-only'; import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { findAll, render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -module('Integration | Component | app breadcrumbs', function(hooks) { +module('Integration | Component | app breadcrumbs', function (hooks) { setupRenderingTest(hooks); const commonCrumbs = [ { label: 'Jobs', args: ['jobs.index'] }, - { label: 'Job', args: ['jobs.job.index'] } + { label: 'Job', args: ['jobs.job.index'] }, ]; - test('every breadcrumb is rendered correctly', async function(assert) { + test('every breadcrumb is rendered correctly', async function (assert) { + assert.expect(3); this.set('commonCrumbs', commonCrumbs); await render(hbs` @@ -40,21 +41,20 @@ module('Integration | Component | app breadcrumbs', function(hooks) { }); }); - test('when we register a crumb with a type property, a dedicated breadcrumb/ component renders', async function(assert) { + test('when we register a crumb with a type property, a dedicated breadcrumb/ component renders', async function (assert) { const crumbs = [ { label: 'Jobs', args: ['jobs.index'] }, - { type: 'special', label: 'Job', args: ['jobs.job.index'] } + { type: 'special', label: 'Job', args: ['jobs.job.index'] }, ]; this.set('crumbs', crumbs); - class MockComponent extends Component {} this.owner.register( 'component:breadcrumbs/special', setComponentTemplate( hbs`
Test
`, - MockComponent + templateOnlyComponent() ) ); diff --git a/ui/tests/integration/components/breadcrumbs-test.js b/ui/tests/integration/components/breadcrumbs-test.js index 5d24329ff..b8fe92503 100644 --- a/ui/tests/integration/components/breadcrumbs-test.js +++ b/ui/tests/integration/components/breadcrumbs-test.js @@ -4,10 +4,10 @@ import { setupRenderingTest } from 'ember-qunit'; import { click, findAll, render } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; -module('Integration | Component | breadcrumbs', function(hooks) { +module('Integration | Component | breadcrumbs', function (hooks) { setupRenderingTest(hooks); - test('it declaratively renders a list of registered crumbs', async function(assert) { + test('it declaratively renders a list of registered crumbs', async function (assert) { this.set('isRegistered', false); this.set('toggleCrumb', () => this.set('isRegistered', !this.isRegistered)); await render(hbs` @@ -25,8 +25,12 @@ module('Integration | Component | breadcrumbs', function(hooks) { {{/if}} `); - assert.dom('[data-test-crumb]').exists({ count: 1 }, 'We register one crumb'); - assert.dom('[data-test-crumb]').hasText('Zoey', 'The first registered crumb is Zoey'); + assert + .dom('[data-test-crumb]') + .exists({ count: 1 }, 'We register one crumb'); + assert + .dom('[data-test-crumb]') + .hasText('Zoey', 'The first registered crumb is Zoey'); await click('[data-test-button]'); const crumbs = await findAll('[data-test-crumb]'); @@ -36,19 +40,30 @@ module('Integration | Component | breadcrumbs', function(hooks) { .exists({ count: 2 }, 'The second crumb registered successfully'); assert .dom(crumbs[0]) - .hasText('Zoey', 'Breadcrumbs maintain the order in which they are declared'); + .hasText( + 'Zoey', + 'Breadcrumbs maintain the order in which they are declared' + ); assert .dom(crumbs[1]) - .hasText('Tomster', 'Breadcrumbs maintain the order in which they are declared'); + .hasText( + 'Tomster', + 'Breadcrumbs maintain the order in which they are declared' + ); await click('[data-test-button]'); - assert.dom('[data-test-crumb]').exists({ count: 1 }, 'We deregister one crumb'); assert .dom('[data-test-crumb]') - .hasText('Zoey', 'Zoey remains in the template after Tomster deregisters'); + .exists({ count: 1 }, 'We deregister one crumb'); + assert + .dom('[data-test-crumb]') + .hasText( + 'Zoey', + 'Zoey remains in the template after Tomster deregisters' + ); }); - test('it can register complex crumb objects', async function(assert) { + test('it can register complex crumb objects', async function (assert) { await render(hbs`
    @@ -62,6 +77,9 @@ module('Integration | Component | breadcrumbs', function(hooks) { assert .dom('[data-test-crumb]') - .hasText('Tomster', 'We can access the registered breadcrumbs in the template'); + .hasText( + 'Tomster', + 'We can access the registered breadcrumbs in the template' + ); }); }); diff --git a/ui/tests/integration/components/trigger-test.js b/ui/tests/integration/components/trigger-test.js index 20999b01a..2d17b35f0 100644 --- a/ui/tests/integration/components/trigger-test.js +++ b/ui/tests/integration/components/trigger-test.js @@ -4,11 +4,11 @@ import { setupRenderingTest } from 'ember-qunit'; import { render, click, waitFor } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; -module('Integration | Component | trigger', function(hooks) { +module('Integration | Component | trigger', function (hooks) { setupRenderingTest(hooks); - module('Synchronous Interactions', function() { - test('it can trigger a synchronous action', async function(assert) { + module('Synchronous Interactions', function () { + test('it can trigger a synchronous action', async function (assert) { this.set('name', 'Tomster'); this.set('changeName', () => this.set('name', 'Zoey')); await render(hbs` @@ -17,16 +17,21 @@ module('Integration | Component | trigger', function(hooks) { `); - assert.dom('[data-test-name]').hasText('Tomster', 'Initial state renders correctly.'); + assert + .dom('[data-test-name]') + .hasText('Tomster', 'Initial state renders correctly.'); await click('[data-test-button]'); assert .dom('[data-test-name]') - .hasText('Zoey', 'The name property changes when the button is clicked'); + .hasText( + 'Zoey', + 'The name property changes when the button is clicked' + ); }); - test('it sets the result of the action', async function(assert) { + test('it sets the result of the action', async function (assert) { this.set('tomster', () => 'Tomster'); await render(hbs` @@ -38,22 +43,27 @@ module('Integration | Component | trigger', function(hooks) { `); assert .dom('[data-test-name]') - .doesNotExist('Initial state does not render because there is no result yet.'); + .doesNotExist( + 'Initial state does not render because there is no result yet.' + ); await click('[data-test-button]'); assert .dom('[data-test-name]') - .hasText('Tomster', 'The result state updates after the triggered action'); + .hasText( + 'Tomster', + 'The result state updates after the triggered action' + ); }); }); - module('Asynchronous Interactions', function() { - test('it can trigger an asynchronous action', async function(assert) { + module('Asynchronous Interactions', function () { + test('it can trigger an asynchronous action', async function (assert) { this.set( 'onTrigger', () => - new Promise(resolve => { + new Promise((resolve) => { this.set('resolve', resolve); }) ); @@ -72,15 +82,21 @@ module('Integration | Component | trigger', function(hooks) { assert .dom('[data-test-div]') - .doesNotExist('The div does not render until after the action dispatches successfully'); + .doesNotExist( + 'The div does not render until after the action dispatches successfully' + ); await click('[data-test-button]'); assert .dom('[data-test-div-loading]') - .exists('Loading state is displayed when the action hasnt resolved yet'); + .exists( + 'Loading state is displayed when the action hasnt resolved yet' + ); assert .dom('[data-test-div]') - .doesNotExist('Success message does not display until after promise resolves'); + .doesNotExist( + 'Success message does not display until after promise resolves' + ); this.resolve(); await waitFor('[data-test-div]'); @@ -91,15 +107,21 @@ module('Integration | Component | trigger', function(hooks) { ); assert .dom('[data-test-div]') - .exists('Action has dispatched successfully after the promise resolves'); + .exists( + 'Action has dispatched successfully after the promise resolves' + ); await click('[data-test-button]'); assert .dom('[data-test-div]') - .doesNotExist('Aftering clicking the button, again, the state is reset'); + .doesNotExist( + 'Aftering clicking the button, again, the state is reset' + ); assert .dom('[data-test-div-loading]') - .exists('After clicking the button, again, we are back in the loading state'); + .exists( + 'After clicking the button, again, we are back in the loading state' + ); this.resolve(); await waitFor('[data-test-div]'); @@ -111,11 +133,11 @@ module('Integration | Component | trigger', function(hooks) { ); }); - test('it handles the success state', async function(assert) { + test('it handles the success state', async function (assert) { this.set( 'onTrigger', () => - new Promise(resolve => { + new Promise((resolve) => { this.set('resolve', resolve); }) ); @@ -132,14 +154,16 @@ module('Integration | Component | trigger', function(hooks) { assert .dom('[data-test-div]') - .doesNotExist('No text should appear until after the onSuccess callback is fired'); + .doesNotExist( + 'No text should appear until after the onSuccess callback is fired' + ); await click('[data-test-button]'); this.resolve(); await waitFor('[data-test-div]'); assert.verifySteps(['On success happened']); }); - test('it handles the error state', async function(assert) { + test('it handles the error state', async function (assert) { this.set( 'onTrigger', () => @@ -166,11 +190,15 @@ module('Integration | Component | trigger', function(hooks) { await click('[data-test-button]'); assert .dom('[data-test-div-loading]') - .exists('Loading state is displayed when the action hasnt resolved yet'); + .exists( + 'Loading state is displayed when the action hasnt resolved yet' + ); assert .dom('[data-test-div]') - .doesNotExist('No text should appear until after the onError callback is fired'); + .doesNotExist( + 'No text should appear until after the onError callback is fired' + ); this.reject(); await waitFor('[data-test-span]'); @@ -180,7 +208,9 @@ module('Integration | Component | trigger', function(hooks) { assert .dom('[data-test-div-loading]') - .exists('The previous error state was cleared and we show loading, again.'); + .exists( + 'The previous error state was cleared and we show loading, again.' + ); assert.dom('[data-test-div]').doesNotExist('The error state is cleared'); diff --git a/ui/tests/pages/jobs/detail.js b/ui/tests/pages/jobs/detail.js index aaefaf6e0..9c07feaa7 100644 --- a/ui/tests/pages/jobs/detail.js +++ b/ui/tests/pages/jobs/detail.js @@ -7,7 +7,7 @@ import { isPresent, property, text, - visitable + visitable, } from 'ember-cli-page-object'; import allocations from 'nomad-ui/tests/pages/components/allocations'; @@ -22,7 +22,7 @@ export default create({ tabs: collection('[data-test-tab]', { id: attribute('data-test-tab'), - visit: clickable('a') + visit: clickable('a'), }), tabFor(id) { @@ -44,22 +44,22 @@ export default create({ scope: '[data-test-exec-button]', isDisabled: property('disabled'), hasTooltip: hasClass('tooltip'), - tooltipText: attribute('aria-label') + tooltipText: attribute('aria-label'), }, incrementButton: { scope: '[data-test-scale-controls-increment]', - isDisabled: property('disabled') + isDisabled: property('disabled'), }, dispatchButton: { scope: '[data-test-dispatch-button]', - isDisabled: property('disabled') + isDisabled: property('disabled'), }, stats: collection('[data-test-job-stat]', { id: attribute('data-test-job-stat'), - text: text() + text: text(), }), statFor(id) { @@ -68,7 +68,7 @@ export default create({ packStats: collection('[data-test-pack-stat]', { id: attribute('data-test-pack-stat'), - text: text() + text: text(), }), packStatFor(id) { @@ -82,8 +82,8 @@ export default create({ scope: '[data-test-accordion-head] [data-test-accordion-toggle]', click: clickable(), isDisabled: attribute('disabled'), - tooltip: attribute('aria-label') - } + tooltip: attribute('aria-label'), + }, }, childrenSummary: jobClientStatusBar( '[data-test-job-summary] [data-test-children-status-bar]' @@ -98,7 +98,7 @@ export default create({ jobsHeader: { scope: '[data-test-jobs-header]', hasSubmitTime: isPresent('[data-test-jobs-submit-time-header]'), - hasNamespace: isPresent('[data-test-jobs-namespace-header]') + hasNamespace: isPresent('[data-test-jobs-namespace-header]'), }, jobs: collection('[data-test-job-row]', { @@ -113,17 +113,17 @@ export default create({ taskGroups: text('[data-test-job-task-groups]'), clickRow: clickable(), - clickName: clickable('[data-test-job-name] a') + clickName: clickable('[data-test-job-name] a'), }), error: { isPresent: isPresent('[data-test-error]'), title: text('[data-test-error-title]'), message: text('[data-test-error-message]'), - seekHelp: clickable('[data-test-error-message] a') + seekHelp: clickable('[data-test-error-message] a'), }, recentAllocationsEmptyState: { - headline: text('[data-test-empty-recent-allocations-headline]') - } + headline: text('[data-test-empty-recent-allocations-headline]'), + }, }); diff --git a/ui/tests/unit/abilities/client-test.js b/ui/tests/unit/abilities/client-test.js index 2a9fe9986..8d2c2a731 100644 --- a/ui/tests/unit/abilities/client-test.js +++ b/ui/tests/unit/abilities/client-test.js @@ -4,11 +4,11 @@ import { setupTest } from 'ember-qunit'; import Service from '@ember/service'; import setupAbility from 'nomad-ui/tests/helpers/setup-ability'; -module('Unit | Ability | client', function(hooks) { +module('Unit | Ability | client', function (hooks) { setupTest(hooks); setupAbility('client')(hooks); - test('it permits client read and write when ACLs are disabled', function(assert) { + test('it permits client read and write when ACLs are disabled', function (assert) { const mockToken = Service.extend({ aclEnabled: false, }); @@ -18,7 +18,7 @@ module('Unit | Ability | client', function(hooks) { assert.ok(this.ability.canWrite); }); - test('it permits client read and write for management tokens', function(assert) { + test('it permits client read and write for management tokens', function (assert) { const mockToken = Service.extend({ aclEnabled: true, selfToken: { type: 'management' }, @@ -29,7 +29,7 @@ module('Unit | Ability | client', function(hooks) { assert.ok(this.ability.canWrite); }); - test('it permits client read and write for tokens with a policy that has node-write', function(assert) { + test('it permits client read and write for tokens with a policy that has node-write', function (assert) { const mockToken = Service.extend({ aclEnabled: true, selfToken: { type: 'client' }, @@ -49,7 +49,7 @@ module('Unit | Ability | client', function(hooks) { assert.ok(this.ability.canWrite); }); - test('it permits client read and write for tokens with a policy that allows write and another policy that disallows it', function(assert) { + test('it permits client read and write for tokens with a policy that allows write and another policy that disallows it', function (assert) { const mockToken = Service.extend({ aclEnabled: true, selfToken: { type: 'client' }, @@ -76,7 +76,7 @@ module('Unit | Ability | client', function(hooks) { assert.ok(this.ability.canWrite); }); - test('it permits client read and blocks client write for tokens with a policy that does not allow node-write', function(assert) { + test('it permits client read and blocks client write for tokens with a policy that does not allow node-write', function (assert) { const mockToken = Service.extend({ aclEnabled: true, selfToken: { type: 'client' }, @@ -96,7 +96,7 @@ module('Unit | Ability | client', function(hooks) { assert.notOk(this.ability.canWrite); }); - test('it blocks client read and write for tokens without a node policy', function(assert) { + test('it blocks client read and write for tokens without a node policy', function (assert) { const mockToken = Service.extend({ aclEnabled: true, selfToken: { type: 'client' }, diff --git a/ui/tests/unit/utils/job-client-status-test.js b/ui/tests/unit/utils/job-client-status-test.js index 70a6532a4..e625a4f57 100644 --- a/ui/tests/unit/utils/job-client-status-test.js +++ b/ui/tests/unit/utils/job-client-status-test.js @@ -51,8 +51,8 @@ class AllocationMock { } } -module('Unit | Util | JobClientStatus', function() { - test('it handles the case where all nodes are running', async function(assert) { +module('Unit | Util | JobClientStatus', function () { + test('it handles the case where all nodes are running', async function (assert) { const node = new NodeMock('node-1', 'dc1'); const nodes = [node]; const job = { @@ -84,7 +84,7 @@ module('Unit | Util | JobClientStatus', function() { assert.deepEqual(result, expected); }); - test('it handles the degraded case where a node has a failing allocation', async function(assert) { + test('it handles the degraded case where a node has a failing allocation', async function (assert) { const node = new NodeMock('node-2', 'dc1'); const nodes = [node]; const job = { @@ -120,7 +120,7 @@ module('Unit | Util | JobClientStatus', function() { assert.deepEqual(result, expected); }); - test('it handles the case where a node has all lost allocations', async function(assert) { + test('it handles the case where a node has all lost allocations', async function (assert) { const node = new NodeMock('node-1', 'dc1'); const nodes = [node]; const job = { @@ -156,7 +156,7 @@ module('Unit | Util | JobClientStatus', function() { assert.deepEqual(result, expected); }); - test('it handles the case where a node has all failed allocations', async function(assert) { + test('it handles the case where a node has all failed allocations', async function (assert) { const node = new NodeMock('node-1', 'dc1'); const nodes = [node]; const job = { @@ -192,7 +192,7 @@ module('Unit | Util | JobClientStatus', function() { assert.deepEqual(result, expected); }); - test('it handles the degraded case where the expected number of allocations doesnt match the actual number of allocations', async function(assert) { + test('it handles the degraded case where the expected number of allocations doesnt match the actual number of allocations', async function (assert) { const node = new NodeMock('node-1', 'dc1'); const nodes = [node]; const job = { @@ -228,7 +228,7 @@ module('Unit | Util | JobClientStatus', function() { assert.deepEqual(result, expected); }); - test('it handles the not scheduled case where a node has no allocations', async function(assert) { + test('it handles the not scheduled case where a node has no allocations', async function (assert) { const node = new NodeMock('node-1', 'dc1'); const nodes = [node]; const job = { @@ -260,7 +260,7 @@ module('Unit | Util | JobClientStatus', function() { assert.deepEqual(result, expected); }); - test('it handles the queued case where the job is pending', async function(assert) { + test('it handles the queued case where the job is pending', async function (assert) { const node = new NodeMock('node-1', 'dc1'); const nodes = [node]; const job = { @@ -296,7 +296,7 @@ module('Unit | Util | JobClientStatus', function() { assert.deepEqual(result, expected); }); - test('it filters nodes by the datacenter of the job', async function(assert) { + test('it filters nodes by the datacenter of the job', async function (assert) { const node1 = new NodeMock('node-1', 'dc1'); const node2 = new NodeMock('node-2', 'dc2'); const nodes = [node1, node2];