github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/ui/tests/unit/adapters/node-test.js (about) 1 import { run } from '@ember/runloop'; 2 import { module, test } from 'qunit'; 3 import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage'; 4 import { setupTest } from 'ember-qunit'; 5 import { settled } from '@ember/test-helpers'; 6 7 module('Unit | Adapter | Node', function(hooks) { 8 setupTest(hooks); 9 10 hooks.beforeEach(function() { 11 this.store = this.owner.lookup('service:store'); 12 this.subject = () => this.store.adapterFor('node'); 13 14 window.localStorage.clear(); 15 16 this.server = startMirage(); 17 18 this.server.create('region', { id: 'region-1' }); 19 this.server.create('region', { id: 'region-2' }); 20 21 this.server.create('node', { id: 'node-1' }); 22 this.server.create('node', { id: 'node-2' }); 23 this.server.create('job', { id: 'job-1', createAllocations: false }); 24 25 this.server.create('allocation', { id: 'node-1-1', nodeId: 'node-1' }); 26 this.server.create('allocation', { id: 'node-1-2', nodeId: 'node-1' }); 27 this.server.create('allocation', { id: 'node-2-1', nodeId: 'node-2' }); 28 this.server.create('allocation', { id: 'node-2-2', nodeId: 'node-2' }); 29 }); 30 31 hooks.afterEach(function() { 32 this.server.shutdown(); 33 }); 34 35 test('findHasMany removes old related models from the store', async function(assert) { 36 // Fetch the model and related allocations 37 let node = await run(() => this.store.findRecord('node', 'node-1')); 38 let allocations = await run(() => findHasMany(node, 'allocations')); 39 assert.equal( 40 allocations.get('length'), 41 this.server.db.allocations.where({ nodeId: node.get('id') }).length, 42 'Allocations returned from the findHasMany matches the db state' 43 ); 44 45 await settled(); 46 server.db.allocations.remove('node-1-1'); 47 48 allocations = await run(() => findHasMany(node, 'allocations')); 49 const dbAllocations = this.server.db.allocations.where({ nodeId: node.get('id') }); 50 assert.equal( 51 allocations.get('length'), 52 dbAllocations.length, 53 'Allocations returned from the findHasMany matches the db state' 54 ); 55 assert.equal( 56 this.store.peekAll('allocation').get('length'), 57 dbAllocations.length, 58 'Server-side deleted allocation was removed from the store' 59 ); 60 }); 61 62 test('findHasMany does not remove old unrelated models from the store', async function(assert) { 63 // Fetch the first node and related allocations 64 const node = await run(() => this.store.findRecord('node', 'node-1')); 65 await run(() => findHasMany(node, 'allocations')); 66 67 // Also fetch the second node and related allocations; 68 const node2 = await run(() => this.store.findRecord('node', 'node-2')); 69 await run(() => findHasMany(node2, 'allocations')); 70 71 await settled(); 72 assert.deepEqual( 73 this.store 74 .peekAll('allocation') 75 .mapBy('id') 76 .sort(), 77 ['node-1-1', 'node-1-2', 'node-2-1', 'node-2-2'], 78 'All allocations for the first and second node are in the store' 79 ); 80 81 server.db.allocations.remove('node-1-1'); 82 83 // Reload the related allocations now that one was removed server-side 84 await run(() => findHasMany(node, 'allocations')); 85 assert.deepEqual( 86 this.store 87 .peekAll('allocation') 88 .mapBy('id') 89 .sort(), 90 ['node-1-2', 'node-2-1', 'node-2-2'], 91 'The deleted allocation is removed from the store and the allocations associated with the other node are untouched' 92 ); 93 }); 94 95 const testCases = [ 96 { 97 variation: '', 98 id: 'node-1', 99 region: null, 100 eligibility: 'POST /v1/node/node-1/eligibility', 101 drain: 'POST /v1/node/node-1/drain', 102 }, 103 { 104 variation: 'with non-default region', 105 id: 'node-1', 106 region: 'region-2', 107 eligibility: 'POST /v1/node/node-1/eligibility?region=region-2', 108 drain: 'POST /v1/node/node-1/drain?region=region-2', 109 }, 110 ]; 111 112 testCases.forEach(testCase => { 113 test(`setEligible makes the correct POST request to /:node_id/eligibility ${testCase.variation}`, async function(assert) { 114 const { pretender } = this.server; 115 if (testCase.region) window.localStorage.nomadActiveRegion = testCase.region; 116 117 const node = await run(() => this.store.findRecord('node', testCase.id)); 118 await this.subject().setEligible(node); 119 120 const request = pretender.handledRequests.lastObject; 121 assert.equal(`${request.method} ${request.url}`, testCase.eligibility); 122 assert.deepEqual(JSON.parse(request.requestBody), { 123 NodeID: node.id, 124 Eligibility: 'eligible', 125 }); 126 }); 127 128 test(`setIneligible makes the correct POST request to /:node_id/eligibility ${testCase.variation}`, async function(assert) { 129 const { pretender } = this.server; 130 if (testCase.region) window.localStorage.nomadActiveRegion = testCase.region; 131 132 const node = await run(() => this.store.findRecord('node', testCase.id)); 133 await this.subject().setIneligible(node); 134 135 const request = pretender.handledRequests.lastObject; 136 assert.equal(`${request.method} ${request.url}`, testCase.eligibility); 137 assert.deepEqual(JSON.parse(request.requestBody), { 138 NodeID: node.id, 139 Eligibility: 'ineligible', 140 }); 141 }); 142 143 test(`drain makes the correct POST request to /:node_id/drain with appropriate defaults ${testCase.variation}`, async function(assert) { 144 const { pretender } = this.server; 145 if (testCase.region) window.localStorage.nomadActiveRegion = testCase.region; 146 147 const node = await run(() => this.store.findRecord('node', testCase.id)); 148 await this.subject().drain(node); 149 150 const request = pretender.handledRequests.lastObject; 151 assert.equal(`${request.method} ${request.url}`, testCase.drain); 152 assert.deepEqual(JSON.parse(request.requestBody), { 153 NodeID: node.id, 154 DrainSpec: { 155 Deadline: 0, 156 IgnoreSystemJobs: true, 157 }, 158 }); 159 }); 160 161 test(`drain makes the correct POST request to /:node_id/drain with the provided drain spec ${testCase.variation}`, async function(assert) { 162 const { pretender } = this.server; 163 if (testCase.region) window.localStorage.nomadActiveRegion = testCase.region; 164 165 const node = await run(() => this.store.findRecord('node', testCase.id)); 166 167 const spec = { Deadline: 123456789, IgnoreSystemJobs: false }; 168 await this.subject().drain(node, spec); 169 170 const request = pretender.handledRequests.lastObject; 171 assert.equal(`${request.method} ${request.url}`, testCase.drain); 172 assert.deepEqual(JSON.parse(request.requestBody), { 173 NodeID: node.id, 174 DrainSpec: { 175 Deadline: spec.Deadline, 176 IgnoreSystemJobs: spec.IgnoreSystemJobs, 177 }, 178 }); 179 }); 180 181 test(`forceDrain makes the correct POST request to /:node_id/drain with appropriate defaults ${testCase.variation}`, async function(assert) { 182 const { pretender } = this.server; 183 if (testCase.region) window.localStorage.nomadActiveRegion = testCase.region; 184 185 const node = await run(() => this.store.findRecord('node', testCase.id)); 186 187 await this.subject().forceDrain(node); 188 189 const request = pretender.handledRequests.lastObject; 190 assert.equal(`${request.method} ${request.url}`, testCase.drain); 191 assert.deepEqual(JSON.parse(request.requestBody), { 192 NodeID: node.id, 193 DrainSpec: { 194 Deadline: -1, 195 IgnoreSystemJobs: true, 196 }, 197 }); 198 }); 199 200 test(`forceDrain makes the correct POST request to /:node_id/drain with the provided drain spec ${testCase.variation}`, async function(assert) { 201 const { pretender } = this.server; 202 if (testCase.region) window.localStorage.nomadActiveRegion = testCase.region; 203 204 const node = await run(() => this.store.findRecord('node', testCase.id)); 205 206 const spec = { Deadline: 123456789, IgnoreSystemJobs: false }; 207 await this.subject().forceDrain(node, spec); 208 209 const request = pretender.handledRequests.lastObject; 210 assert.equal(`${request.method} ${request.url}`, testCase.drain); 211 assert.deepEqual(JSON.parse(request.requestBody), { 212 NodeID: node.id, 213 DrainSpec: { 214 Deadline: -1, 215 IgnoreSystemJobs: spec.IgnoreSystemJobs, 216 }, 217 }); 218 }); 219 220 test(`cancelDrain makes the correct POST request to /:node_id/drain ${testCase.variation}`, async function(assert) { 221 const { pretender } = this.server; 222 if (testCase.region) window.localStorage.nomadActiveRegion = testCase.region; 223 224 const node = await run(() => this.store.findRecord('node', testCase.id)); 225 226 await this.subject().cancelDrain(node); 227 228 const request = pretender.handledRequests.lastObject; 229 assert.equal(`${request.method} ${request.url}`, testCase.drain); 230 assert.deepEqual(JSON.parse(request.requestBody), { 231 NodeID: node.id, 232 DrainSpec: null, 233 }); 234 }); 235 }); 236 }); 237 238 // Using fetchLink on a model's hasMany relationship exercises the adapter's 239 // findHasMany method as well normalizing the response and pushing it to the store 240 function findHasMany(model, relationshipName) { 241 const relationship = model.relationshipFor(relationshipName); 242 return model.hasMany(relationship.key).reload(); 243 }