import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; import generateResources from '../../../mirage/data/generate-resources'; import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage'; import { find, render } from '@ember/test-helpers'; 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) { setupRenderingTest(hooks); hooks.beforeEach(function () { fragmentSerializerInitializer(this.owner); this.store = this.owner.lookup('service:store'); this.server = startMirage(); this.server.create('namespace'); this.server.create('node'); this.server.create('job', { createAllocations: false }); }); hooks.afterEach(function () { this.server.shutdown(); }); test('Allocation row polls for stats, even when it errors or has an invalid response', async function (assert) { const component = this; let currentFrame = 0; let frames = [ JSON.stringify({ ResourceUsage: generateResources() }), JSON.stringify({ ResourceUsage: generateResources() }), null, 'Valid JSON', JSON.stringify({ ResourceUsage: generateResources() }), ]; this.server.get('/client/allocation/:id/stats', function () { const response = frames[++currentFrame]; // Disable polling to stop the EC task in the component if (currentFrame >= frames.length) { component.set('enablePolling', false); } if (response) { return response; } return new Response(500, {}, ''); }); this.server.create('allocation', { clientStatus: 'running' }); await this.store.findAll('allocation'); const allocation = this.store.peekAll('allocation').get('firstObject'); this.setProperties({ allocation, context: 'job', enablePolling: true, }); await render(hbs` `); assert.equal( this.server.pretender.handledRequests.filterBy( 'url', `/v1/client/allocation/${allocation.get('id')}/stats` ).length, frames.length, 'Requests continue to be made after malformed responses and server errors' ); }); 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); const node = this.server.schema.nodes.first(); const drivers = node.drivers; Object.values(drivers).forEach((driver) => { driver.Healthy = false; driver.Detected = true; }); node.update({ drivers }); this.server.create('allocation', { clientStatus: 'running' }); await this.store.findAll('job'); await this.store.findAll('node'); await this.store.findAll('allocation'); const allocation = this.store.peekAll('allocation').get('firstObject'); this.setProperties({ allocation, context: 'job', }); await render(hbs` `); assert.ok( find('[data-test-icon="unhealthy-driver"]'), 'Unhealthy driver icon is shown' ); await componentA11yAudit(this.element, 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); this.setProperties({ allocation, context: 'job' }); await render(hbs` `); assert.ok(find('[data-test-icon="preemption"]'), 'Preempted icon is shown'); await componentA11yAudit(this.element, 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, }); // All non-running statuses need to be tested ['pending', 'complete', 'failed', 'lost'].forEach((clientStatus) => this.server.create('allocation', { clientStatus }) ); await this.store.findAll('allocation'); const allocations = this.store.peekAll('allocation'); for (const allocation of allocations.toArray()) { this.set('allocation', allocation); await render(hbs` `); const status = allocation.get('clientStatus'); assert.notOk( find('[data-test-cpu] .inline-chart'), `No CPU chart for ${status}` ); assert.notOk( find('[data-test-mem] .inline-chart'), `No Mem chart for ${status}` ); } }); });