github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/tests/integration/components/allocation-row-test.js (about) 1 import { module, test } from 'qunit'; 2 import { setupRenderingTest } from 'ember-qunit'; 3 import hbs from 'htmlbars-inline-precompile'; 4 import generateResources from '../../../mirage/data/generate-resources'; 5 import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage'; 6 import { find, render } from '@ember/test-helpers'; 7 import Response from 'ember-cli-mirage/response'; 8 import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer'; 9 import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit'; 10 11 module('Integration | Component | allocation row', function (hooks) { 12 setupRenderingTest(hooks); 13 14 hooks.beforeEach(function () { 15 fragmentSerializerInitializer(this.owner); 16 this.store = this.owner.lookup('service:store'); 17 this.server = startMirage(); 18 this.server.create('namespace'); 19 this.server.create('node'); 20 this.server.create('job', { createAllocations: false }); 21 }); 22 23 hooks.afterEach(function () { 24 this.server.shutdown(); 25 }); 26 27 test('Allocation row polls for stats, even when it errors or has an invalid response', async function (assert) { 28 const component = this; 29 30 let currentFrame = 0; 31 let frames = [ 32 JSON.stringify({ ResourceUsage: generateResources() }), 33 JSON.stringify({ ResourceUsage: generateResources() }), 34 null, 35 '<Not>Valid JSON</Not>', 36 JSON.stringify({ ResourceUsage: generateResources() }), 37 ]; 38 39 this.server.get('/client/allocation/:id/stats', function () { 40 const response = frames[++currentFrame]; 41 42 // Disable polling to stop the EC task in the component 43 if (currentFrame >= frames.length) { 44 component.set('enablePolling', false); 45 } 46 47 if (response) { 48 return response; 49 } 50 return new Response(500, {}, ''); 51 }); 52 53 this.server.create('allocation', { clientStatus: 'running' }); 54 await this.store.findAll('allocation'); 55 56 const allocation = this.store.peekAll('allocation').get('firstObject'); 57 58 this.setProperties({ 59 allocation, 60 context: 'job', 61 enablePolling: true, 62 }); 63 64 await render(hbs` 65 <AllocationRow 66 @allocation={{allocation}} 67 @context={{context}} 68 @enablePolling={{enablePolling}} /> 69 `); 70 71 assert.equal( 72 this.server.pretender.handledRequests.filterBy( 73 'url', 74 `/v1/client/allocation/${allocation.get('id')}/stats` 75 ).length, 76 frames.length, 77 'Requests continue to be made after malformed responses and server errors' 78 ); 79 }); 80 81 test('Allocation row shows warning when it requires drivers that are unhealthy on the node it is running on', async function (assert) { 82 assert.expect(2); 83 84 const node = this.server.schema.nodes.first(); 85 const drivers = node.drivers; 86 Object.values(drivers).forEach((driver) => { 87 driver.Healthy = false; 88 driver.Detected = true; 89 }); 90 node.update({ drivers }); 91 92 this.server.create('allocation', { clientStatus: 'running' }); 93 await this.store.findAll('job'); 94 await this.store.findAll('node'); 95 await this.store.findAll('allocation'); 96 97 const allocation = this.store.peekAll('allocation').get('firstObject'); 98 99 this.setProperties({ 100 allocation, 101 context: 'job', 102 }); 103 104 await render(hbs` 105 <AllocationRow 106 @allocation={{allocation}} 107 @context={{context}} /> 108 `); 109 110 assert.ok( 111 find('[data-test-icon="unhealthy-driver"]'), 112 'Unhealthy driver icon is shown' 113 ); 114 await componentA11yAudit(this.element, assert); 115 }); 116 117 test('Allocation row shows an icon indicator when it was preempted', async function (assert) { 118 assert.expect(2); 119 120 const allocId = this.server.create('allocation', 'preempted').id; 121 const allocation = await this.store.findRecord('allocation', allocId); 122 123 this.setProperties({ allocation, context: 'job' }); 124 await render(hbs` 125 <AllocationRow 126 @allocation={{allocation}} 127 @context={{context}} /> 128 `); 129 130 assert.ok(find('[data-test-icon="preemption"]'), 'Preempted icon is shown'); 131 await componentA11yAudit(this.element, assert); 132 }); 133 134 test('when an allocation is not running, the utilization graphs are omitted', async function (assert) { 135 assert.expect(8); 136 137 this.setProperties({ 138 context: 'job', 139 enablePolling: false, 140 }); 141 142 // All non-running statuses need to be tested 143 ['pending', 'complete', 'failed', 'lost'].forEach((clientStatus) => 144 this.server.create('allocation', { clientStatus }) 145 ); 146 147 await this.store.findAll('allocation'); 148 149 const allocations = this.store.peekAll('allocation'); 150 151 for (const allocation of allocations.toArray()) { 152 this.set('allocation', allocation); 153 await render(hbs` 154 <AllocationRow 155 @allocation={{allocation}} 156 @context={{context}} 157 @enablePolling={{enablePolling}} /> 158 `); 159 160 const status = allocation.get('clientStatus'); 161 assert.notOk( 162 find('[data-test-cpu] .inline-chart'), 163 `No CPU chart for ${status}` 164 ); 165 assert.notOk( 166 find('[data-test-mem] .inline-chart'), 167 `No Mem chart for ${status}` 168 ); 169 } 170 }); 171 });