diff --git a/ui/app/adapters/node.js b/ui/app/adapters/node.js index b3c14fdd8..140f27907 100644 --- a/ui/app/adapters/node.js +++ b/ui/app/adapters/node.js @@ -19,4 +19,29 @@ export default Watchable.extend({ }, }); }, + + // Force: -1s deadline + // No Deadline: 0 deadline + drain(node, drainSpec) { + const url = addToPath(this.urlForFindRecord(node.id, 'node'), '/drain'); + return this.ajax(url, 'POST', { + data: Object.assign( + { + NodeID: node.id, + Deadline: 0, + IgnoreSystemJobs: true, + }, + drainSpec + ), + }); + }, + + forceDrain(node, drainSpec) { + return this.drain( + node, + Object.assign({}, drainSpec, { + Deadline: -1000 * 1000000, + }) + ); + }, }); diff --git a/ui/app/models/node.js b/ui/app/models/node.js index ed4149550..919121f30 100644 --- a/ui/app/models/node.js +++ b/ui/app/models/node.js @@ -81,4 +81,12 @@ export default Model.extend({ if (!this.isEligible) return RSVP.resolve(); return this.store.adapterFor('node').setIneligible(this); }, + + drain(drainSpec) { + return this.store.adapterFor('node').drain(this, drainSpec); + }, + + forceDrain(drainSpec) { + return this.store.adapterFor('node').forceDrain(this, drainSpec); + }, }); diff --git a/ui/tests/unit/adapters/node-test.js b/ui/tests/unit/adapters/node-test.js index 6ab277bbb..a0f3e97e3 100644 --- a/ui/tests/unit/adapters/node-test.js +++ b/ui/tests/unit/adapters/node-test.js @@ -131,6 +131,86 @@ module('Unit | Adapter | Node', function(hooks) { 'POST request is made with the correct body arguments' ); }); + + test('drain makes the correct POST request to /:node_id/drain with appropriate defaults', async function(assert) { + const { pretender } = this.server; + const node = await run(() => this.store.findRecord('node', 'node-1')); + + await this.subject().drain(node); + + const request = pretender.handledRequests.lastObject; + assert.equal(request.url, `/v1/node/${node.id}/drain`, 'Request was made to /:node_id/drain'); + assert.equal(request.method, 'POST', 'Request was made with the POST method'); + assert.deepEqual( + JSON.parse(request.requestBody), + { + NodeID: node.id, + Deadline: 0, + IgnoreSystemJobs: true, + }, + 'POST request is made with the default body arguments' + ); + }); + + test('drain makes the correct POST request to /:node_id/drain with the provided drain spec', async function(assert) { + const { pretender } = this.server; + const node = await run(() => this.store.findRecord('node', 'node-1')); + + const spec = { Deadline: 123456789, IgnoreSystemJobs: false }; + await this.subject().drain(node, spec); + + const request = pretender.handledRequests.lastObject; + assert.deepEqual( + JSON.parse(request.requestBody), + { + NodeID: node.id, + Deadline: spec.Deadline, + IgnoreSystemJobs: spec.IgnoreSystemJobs, + }, + 'POST request is made with the drain spec as body arguments' + ); + }); + + test('forceDrain makes the correct POST request to /:node_id/drain with appropriate defaults', async function(assert) { + const { pretender } = this.server; + const node = await run(() => this.store.findRecord('node', 'node-1')); + + await this.subject().forceDrain(node); + + const request = pretender.handledRequests.lastObject; + assert.equal(request.url, `/v1/node/${node.id}/drain`, 'Request was made to /:node_id/drain'); + assert.equal(request.method, 'POST', 'Request was made with the POST method'); + assert.deepEqual( + JSON.parse(request.requestBody), + { + NodeID: node.id, + Deadline: -1000000000, + IgnoreSystemJobs: true, + }, + 'POST request is made with the default body arguments' + ); + }); + + test('forceDrain makes the correct POST request to /:node_id/drain with the provided drain spec', async function(assert) { + const { pretender } = this.server; + const node = await run(() => this.store.findRecord('node', 'node-1')); + + const spec = { Deadline: 123456789, IgnoreSystemJobs: false }; + await this.subject().forceDrain(node, spec); + + const request = pretender.handledRequests.lastObject; + assert.equal(request.url, `/v1/node/${node.id}/drain`, 'Request was made to /:node_id/drain'); + assert.equal(request.method, 'POST', 'Request was made with the POST method'); + assert.deepEqual( + JSON.parse(request.requestBody), + { + NodeID: node.id, + Deadline: -1000000000, + IgnoreSystemJobs: spec.IgnoreSystemJobs, + }, + 'POST request is made with the drain spec, except deadline is not overridden' + ); + }); }); // Using fetchLink on a model's hasMany relationship exercises the adapter's