From e76dc80e472062a77a636b147408b5d93e3097d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Sat, 22 Jul 2017 01:57:00 +0300 Subject: [PATCH] MXS-1300: Reorganize and refactor tests The tests are now sorted by command type. This allows for more consistent test creation as tests can be done per source code file instead of per object type. Added helper functions for common testing operations. The two main ones are doCommand, which executes a MaxCtrl command and returns a result, and verifyCommand, that executes a command and verifies the result via the REST API. --- maxctrl/test/alter.js | 89 ++++++++++++++++++++++++++++ maxctrl/test/createdestroy.js | 104 ++++++++++++++++++++++++++++++++ maxctrl/test/diagnostics.js | 7 ++- maxctrl/test/enabledisable.js | 20 +++++++ maxctrl/test/link.js | 72 +++++++++++++++++++++++ maxctrl/test/monitor.js | 108 ---------------------------------- maxctrl/test/server.js | 73 ----------------------- maxctrl/test/service.js | 85 -------------------------- maxctrl/test/startstop.js | 38 ++++++++++++ maxctrl/test/states.js | 14 ++--- maxctrl/test/unknown.js | 30 ++++++++++ maxctrl/test_utils.js | 20 +++++++ 12 files changed, 381 insertions(+), 279 deletions(-) create mode 100644 maxctrl/test/alter.js create mode 100644 maxctrl/test/createdestroy.js create mode 100644 maxctrl/test/enabledisable.js create mode 100644 maxctrl/test/link.js delete mode 100644 maxctrl/test/monitor.js delete mode 100644 maxctrl/test/server.js delete mode 100644 maxctrl/test/service.js create mode 100644 maxctrl/test/startstop.js create mode 100644 maxctrl/test/unknown.js diff --git a/maxctrl/test/alter.js b/maxctrl/test/alter.js new file mode 100644 index 000000000..82ec29b9a --- /dev/null +++ b/maxctrl/test/alter.js @@ -0,0 +1,89 @@ +require('../test_utils.js')() + +var ctrl = require('../lib/core.js') +var opts = { extra_args: [ '--quiet'] } + +describe("Alter Commands", function() { + before(startMaxScale) + + it('alter server', function() { + return verifyCommand('alter server server1 port 3004', 'servers/server1') + .then(function(res) { + res.data.attributes.parameters.port.should.equal(3004) + }) + }) + + it('alter server with bad parameters', function() { + return doCommand('alter server server1 port not-a-port') + .should.be.rejected + }) + + it('alter nonexistent server', function() { + return doCommand('alter server server123 port 3000') + .should.be.rejected + }) + + it('alter monitor', function() { + return verifyCommand('alter monitor MySQL-Monitor monitor_interval 1000', 'monitors/MySQL-Monitor') + .then(function(res) { + res.data.attributes.parameters.monitor_interval.should.equal(1000) + }) + }) + + it('alter monitor with bad parameters', function() { + return doCommand('alter monitor MySQL-Monitor monitor_interval not-a-number') + .should.be.rejected + }) + + it('alter nonexistent monitor', function() { + return doCommand('alter monitor monitor123 monitor_interval 3000') + .should.be.rejected + }) + + it('alter service parameter', function() { + return verifyCommand('alter service Read-Connection-Router user testuser', 'services/Read-Connection-Router') + .then(function(res) { + res.data.attributes.parameters.user.should.equal("testuser") + }) + }) + + it('alter non-existent service parameter', function() { + return doCommand('alter service Read-Connection-Router turbocharge yes-please') + .should.be.rejected + }) + + it('alter non-existent service', function() { + return doCommand('alter service not-a-service user maxuser') + .should.be.rejected + }) + + it('alter logging', function() { + return verifyCommand('alter logging maxlog false', 'maxscale/logs') + .then(function() { + return verifyCommand('alter logging syslog false', 'maxscale/logs') + }) + .then(function(res) { + res.data.attributes.parameters.maxlog.should.equal(false) + res.data.attributes.parameters.syslog.should.equal(false) + }) + }) + + it('alter logging with bad parameter', function() { + doCommand('alter logging some-parameter maybe') + .should.be.rejectted + }) + + it('alter maxscale', function() { + return verifyCommand('alter maxscale auth_connect_timeout 5', 'maxscale') + .then(function(res) { + res.data.attributes.parameters.auth_connect_timeout.should.equal(5) + }) + }) + + it('alter maxscale with bad parameter', function() { + return doCommand('alter maxscale some_timeout 123') + .should.be.rejected + }) + + after(stopMaxScale) +}); diff --git a/maxctrl/test/createdestroy.js b/maxctrl/test/createdestroy.js new file mode 100644 index 000000000..33c38603b --- /dev/null +++ b/maxctrl/test/createdestroy.js @@ -0,0 +1,104 @@ +require('../test_utils.js')() + +var ctrl = require('../lib/core.js') +var opts = { extra_args: [ '--quiet'] } + +describe("Create/Destroy Commands", function() { + before(startMaxScale) + + it('create monitor', function() { + return doCommand('create monitor my-monitor mysqlmon') + .then(function() { + return request.get(host + 'monitors/my-monitor', {json: true}) + .should.be.fulfilled + }) + }) + + it('destroy monitor', function() { + return doCommand('destroy monitor my-monitor') + .should.be.fulfilled + }) + + it('destroy the same monitor again', function() { + return doCommand('destroy monitor my-monitor') + .should.be.rejected + }) + + it('destroy nonexistent monitor', function() { + return doCommand('destroy monitor monitor123') + .should.be.rejected + }) + + it('create monitor with bad parameters', function() { + return doCommand('create monitor my-monitor some-module') + .should.be.rejected + }) + + it('create monitor with bad options', function() { + return doCommand('create monitor my-monitor mysqlmon --this-is-not-an-option') + .should.be.rejected + }) + + it('create monitor with options', function() { + return stopMaxScale() + .then(startMaxScale) + .then(function() { + return doCommand('unlink monitor MySQL-Monitor server4') + }) + .then(function() { + return verifyCommand('create monitor my-monitor mysqlmon --servers server4 --monitor-user maxuser --monitor-password maxpwd', + 'monitors/my-monitor') + }) + .then(function(res) { + res.data.relationships.servers.data.length.should.equal(1) + res.data.relationships.servers.data[0].id.should.equal("server4") + res.data.attributes.parameters.user.should.equal("maxuser") + res.data.attributes.parameters.password.should.equal("maxpwd") + }) + }) + + it('create already existing monitor', function() { + return doCommand('create monitor my-monitor mysqlmon') + .should.be.rejected + }) + + it('create server', function() { + return verifyCommand('create server server5 127.0.0.1 3003', 'servers/server5') + .should.be.fulfilled + }) + + it('destroy server', function() { + return doCommand('destroy server server5') + .should.be.fulfilled + }) + + it('create server with bad parameters', function() { + return doCommand('create server server5 bad parameter') + .should.be.rejected + }) + + it('create server with bad options', function() { + return doCommand('create server server5 bad parameter --this-is-not-an-option') + .should.be.rejected + }) + + it('create server with options', function() { + return verifyCommand('create server server5 127.0.0.1 3003 --authenticator GSSAPIBackendAuth', + 'servers/server5') + .then(function(res) { + res.data.attributes.parameters.authenticator.should.equal("GSSAPIBackendAuth") + }) + }) + + it('create already existing server', function() { + return doCommand('create server server1 127.0.0.1 3000') + .should.be.rejected + }) + + it('destroy nonexistent server', function() { + return doCommand('destroy server server123') + .should.be.rejected + }) + + after(stopMaxScale) +}); diff --git a/maxctrl/test/diagnostics.js b/maxctrl/test/diagnostics.js index 9d642f799..5b67c5625 100644 --- a/maxctrl/test/diagnostics.js +++ b/maxctrl/test/diagnostics.js @@ -1,9 +1,12 @@ require('../test_utils.js')() var ctrl = require('../lib/core.js') +var opts = { extra_args: [ '--quiet'] } + var tests = [ 'list servers', 'list services', + 'list listeners RW-Split-Router', 'list monitors', 'list sessions', 'list filters', @@ -24,9 +27,7 @@ describe("Diagnostic commands", function() { tests.forEach(function(i) { it(i, function() { - return ctrl.execute(i.split(' '), { - extra_args: [ '--quiet'] - }) + return doCommand(i) .should.be.fulfilled }); }) diff --git a/maxctrl/test/enabledisable.js b/maxctrl/test/enabledisable.js new file mode 100644 index 000000000..6c4af038c --- /dev/null +++ b/maxctrl/test/enabledisable.js @@ -0,0 +1,20 @@ +require('../test_utils.js')() + +var ctrl = require('../lib/core.js') +var opts = { extra_args: [ '--quiet'] } + +describe("Enable/Disable Commands", function() { + before(startMaxScale) + + it('disable with bad parameter', function() { + return doCommand('disable log-priority bad-stuff') + .should.be.rejected + }) + + it('enable with bad parameter', function() { + return doCommand('enable log-priority bad-stuff') + .should.be.rejected + }) + + after(stopMaxScale) +}); diff --git a/maxctrl/test/link.js b/maxctrl/test/link.js new file mode 100644 index 000000000..9c1599bf1 --- /dev/null +++ b/maxctrl/test/link.js @@ -0,0 +1,72 @@ +require('../test_utils.js')() + +var ctrl = require('../lib/core.js') +var opts = { extra_args: [ '--quiet'] } + +describe("Service Commands", function() { + before(startMaxScale) + + it('link servers to a service', function() { + return verifyCommand('link service Read-Connection-Router server1 server2 server3 server4', + 'services/Read-Connection-Router') + .then(function(res) { + res.data.relationships.servers.data.length.should.equal(4) + res.data.relationships.servers.data[0].id.should.equal("server1") + res.data.relationships.servers.data[1].id.should.equal("server2") + res.data.relationships.servers.data[2].id.should.equal("server3") + res.data.relationships.servers.data[3].id.should.equal("server4") + }) + }) + + it('unlink servers from a service', function() { + return verifyCommand('unlink service Read-Connection-Router server2 server3 server4', + 'services/Read-Connection-Router') + .then(function(res) { + res.data.relationships.servers.data.length.should.equal(1) + res.data.relationships.servers.data[0].id.should.equal("server1") + }) + }) + + it('unlink servers from a monitor', function() { + return verifyCommand('unlink monitor MySQL-Monitor server2 server3 server4', + 'monitors/MySQL-Monitor') + .then(function(res) { + res.data.relationships.servers.data.length.should.equal(1) + res.data.relationships.servers.data[0].id.should.equal("server1") + }) + }) + + it('link servers to a monitor', function() { + return verifyCommand('link monitor MySQL-Monitor server1 server2 server3 server4', + 'monitors/MySQL-Monitor') + .then(function(res) { + res.data.relationships.servers.data.length.should.equal(4) + res.data.relationships.servers.data[0].id.should.equal("server1") + res.data.relationships.servers.data[1].id.should.equal("server2") + res.data.relationships.servers.data[2].id.should.equal("server3") + res.data.relationships.servers.data[3].id.should.equal("server4") + }) + }) + + it('link non-existent service to servers', function() { + return doCommand('link service not-a-service server1 server2 server3 server4') + .should.be.rejected + }) + + it('link non-existent monitor to servers', function() { + return doCommand('link monitor not-a-monitor server1 server2 server3 server4') + .should.be.rejected + }) + + it('unlink non-existent service to servers', function() { + return doCommand('unlink service not-a-service server1 server2 server3 server4') + .should.be.rejected + }) + + it('unlink non-existent monitor to servers', function() { + return doCommand('unlink monitor not-a-monitor server1 server2 server3 server4') + .should.be.rejected + }) + + after(stopMaxScale) +}); diff --git a/maxctrl/test/monitor.js b/maxctrl/test/monitor.js deleted file mode 100644 index 8c305f2ee..000000000 --- a/maxctrl/test/monitor.js +++ /dev/null @@ -1,108 +0,0 @@ -require('../test_utils.js')() - -var ctrl = require('../lib/core.js') -var opts = { extra_args: [ '--quiet'] } - -describe("Monitor Commands", function() { - before(startMaxScale) - - it('create monitor', function() { - return ctrl.execute('create monitor my-monitor mysqlmon'.split(' '), opts) - .then(function() { - return request.get(host + 'monitors/my-monitor', {json: true}) - .should.be.fulfilled - }) - }) - - it('destroy monitor', function() { - return ctrl.execute('destroy monitor my-monitor'.split(' '), opts) - .should.be.fulfilled - }) - - it('destroy the same monitor again', function() { - return ctrl.execute('destroy monitor my-monitor'.split(' '), opts) - .should.be.rejected - }) - - it('destroy nonexistent monitor', function() { - return ctrl.execute('destroy monitor monitor123'.split(' '), opts) - .should.be.rejected - }) - - it('create monitor with bad parameters', function() { - return ctrl.execute('create monitor my-monitor some-module'.split(' '), opts) - .should.be.rejected - }) - - it('create monitor with bad options', function() { - return ctrl.execute('create monitor my-monitor mysqlmon --this-is-not-an-option'.split(' '), opts) - .should.be.rejected - }) - - it('create monitor with options', function() { - return stopMaxScale() - .then(startMaxScale) - .then(function() { - return ctrl.execute('unlink monitor MySQL-Monitor server4'.split(' '), opts) - }) - .then(function() { - return ctrl.execute('create monitor my-monitor mysqlmon --servers server4 --monitor-user maxuser --monitor-password maxpwd'.split(' '), opts) - }) - .then(function() { - return request.get(host + 'monitors/my-monitor', {json: true}) - }) - .then(function(res) { - res.data.relationships.servers.data.length.should.equal(1) - res.data.relationships.servers.data[0].id.should.equal("server4") - res.data.attributes.parameters.user.should.equal("maxuser") - res.data.attributes.parameters.password.should.equal("maxpwd") - }) - }) - - it('alter monitor', function() { - return ctrl.execute('alter monitor my-monitor monitor_interval 1000'.split(' '), opts) - .then(function() { - return request.get(host + 'monitors/my-monitor', {json: true}) - }) - .then(function(res) { - res.data.attributes.parameters.monitor_interval.should.equal(1000) - }) - }) - - it('alter monitor with bad parameters', function() { - return ctrl.execute('alter monitor my-monitor monitor_interval not-a-number'.split(' '), opts) - .should.be.rejected - }) - - it('create already existing monitor', function() { - return ctrl.execute('create monitor my-monitor mysqlmon'.split(' '), opts) - .should.be.rejected - }) - - it('alter nonexistent monitor', function() { - return ctrl.execute('alter monitor monitor123 monitor_interval 3000'.split(' '), opts) - .should.be.rejected - }) - - it('stop monitor', function() { - return ctrl.execute('stop monitor my-monitor'.split(' '), opts) - .then(function() { - return request.get(host + 'monitors/my-monitor', {json: true}) - }) - .then(function(res) { - res.data.attributes.state.should.equal("Stopped") - }) - }) - - it('start monitor', function() { - return ctrl.execute('start monitor my-monitor'.split(' '), opts) - .then(function() { - return request.get(host + 'monitors/my-monitor', {json: true}) - }) - .then(function(res) { - res.data.attributes.state.should.equal("Running") - }) - }) - - after(stopMaxScale) -}); diff --git a/maxctrl/test/server.js b/maxctrl/test/server.js deleted file mode 100644 index 8ecc9e6b5..000000000 --- a/maxctrl/test/server.js +++ /dev/null @@ -1,73 +0,0 @@ -require('../test_utils.js')() - -var ctrl = require('../lib/core.js') -var opts = { extra_args: [ '--quiet'] } - -describe("Server Commands", function() { - before(startMaxScale) - - it('create server', function() { - return ctrl.execute('create server server5 127.0.0.1 3003'.split(' '), opts) - .then(function() { - return request.get(host + 'servers/server5', {json: true}) - .should.be.fulfilled - }) - }) - - it('alter server', function() { - return ctrl.execute('alter server server5 port 3004'.split(' '), opts) - .then(function() { - return request.get(host + 'servers/server5', {json: true}) - }) - .then(function(res) { - res.data.attributes.parameters.port.should.equal(3004) - }) - }) - - it('destroy server', function() { - return ctrl.execute('destroy server server5'.split(' '), opts) - .should.be.fulfilled - }) - - it('create server with bad parameters', function() { - return ctrl.execute('create server server5 bad parameter'.split(' '), opts) - .should.be.rejected - }) - - it('create server with bad options', function() { - return ctrl.execute('create server server5 bad parameter --this-is-not-an-option'.split(' '), opts) - .should.be.rejected - }) - - it('create server with options', function() { - return ctrl.execute('create server server5 127.0.0.1 3003 --authenticator GSSAPIBackendAuth'.split(' '), opts) - .then(function() { - return request.get(host + 'servers/server5', {json: true}) - }) - .then(function(res) { - res.data.attributes.parameters.authenticator.should.equal("GSSAPIBackendAuth") - }) - }) - - it('alter server with bad parameters', function() { - return ctrl.execute('alter server server1 port not-a-port'.split(' '), opts) - .should.be.rejected - }) - - it('create already existing server', function() { - return ctrl.execute('create server server1 127.0.0.1 3000'.split(' '), opts) - .should.be.rejected - }) - - it('alter nonexistent server', function() { - return ctrl.execute('alter server server123 port 3000'.split(' '), opts) - .should.be.rejected - }) - - it('destroy nonexistent server', function() { - return ctrl.execute('destroy server server123'.split(' '), opts) - .should.be.rejected - }) - - after(stopMaxScale) -}); diff --git a/maxctrl/test/service.js b/maxctrl/test/service.js deleted file mode 100644 index e9d65de2d..000000000 --- a/maxctrl/test/service.js +++ /dev/null @@ -1,85 +0,0 @@ -require('../test_utils.js')() - -var ctrl = require('../lib/core.js') -var opts = { extra_args: [ '--quiet'] } - -describe("Service Commands", function() { - before(startMaxScale) - - it('link servers to a service', function() { - return ctrl.execute('link service Read-Connection-Router server1 server2 server3 server4'.split(' '), opts) - .then(function() { - return request.get(host + 'services/Read-Connection-Router', {json: true}) - }) - .then(function(res) { - res.data.relationships.servers.data.length.should.equal(4) - res.data.relationships.servers.data[0].id.should.equal("server1") - res.data.relationships.servers.data[1].id.should.equal("server2") - res.data.relationships.servers.data[2].id.should.equal("server3") - res.data.relationships.servers.data[3].id.should.equal("server4") - }) - }) - - it('link non-existent service to servers', function() { - return ctrl.execute('link service not-a-service server1 server2 server3 server4'.split(' '), opts) - .should.be.rejected - }) - - it('unlink servers from a service', function() { - return ctrl.execute('unlink service Read-Connection-Router server2 server3 server4'.split(' '), opts) - .then(function() { - return request.get(host + 'services/Read-Connection-Router', {json: true}) - }) - .then(function(res) { - res.data.relationships.servers.data.length.should.equal(1) - res.data.relationships.servers.data[0].id.should.equal("server1") - }) - }) - - it('unlink non-existent service to servers', function() { - return ctrl.execute('unlink service not-a-service server1 server2 server3 server4'.split(' '), opts) - .should.be.rejected - }) - - it('alter service parameter', function() { - return ctrl.execute('alter service Read-Connection-Router user testuser'.split(' '), opts) - .then(function() { - return request.get(host + 'services/Read-Connection-Router', {json: true}) - }) - .then(function(res) { - res.data.attributes.parameters.user.should.equal("testuser") - }) - }) - - it('alter non-existent service parameter', function() { - return ctrl.execute('alter service Read-Connection-Router turbocharge yes-please'.split(' '), opts) - .should.be.rejected - }) - - it('alter non-existent service', function() { - return ctrl.execute('alter service not-a-service user maxuser'.split(' '), opts) - .should.be.rejected - }) - - it('stop service', function() { - return ctrl.execute('stop service Read-Connection-Router'.split(' '), opts) - .then(function() { - return request.get(host + 'services/Read-Connection-Router', {json: true}) - }) - .then(function(res) { - res.data.attributes.state.should.equal("Stopped") - }) - }) - - it('start service', function() { - return ctrl.execute('start service Read-Connection-Router'.split(' '), opts) - .then(function() { - return request.get(host + 'services/Read-Connection-Router', {json: true}) - }) - .then(function(res) { - res.data.attributes.state.should.equal("Started") - }) - }) - - after(stopMaxScale) -}); diff --git a/maxctrl/test/startstop.js b/maxctrl/test/startstop.js new file mode 100644 index 000000000..7f2e4825e --- /dev/null +++ b/maxctrl/test/startstop.js @@ -0,0 +1,38 @@ +require('../test_utils.js')() + +var ctrl = require('../lib/core.js') +var opts = { extra_args: [ '--quiet'] } + +describe("Start/Stop Commands", function() { + before(startMaxScale) + + it('stop service', function() { + return verifyCommand('stop service Read-Connection-Router', 'services/Read-Connection-Router') + .then(function(res) { + res.data.attributes.state.should.equal("Stopped") + }) + }) + + it('start service', function() { + return verifyCommand('start service Read-Connection-Router', 'services/Read-Connection-Router') + .then(function(res) { + res.data.attributes.state.should.equal("Started") + }) + }) + + it('stop monitor', function() { + return verifyCommand('stop monitor MySQL-Monitor', 'monitors/MySQL-Monitor') + .then(function(res) { + res.data.attributes.state.should.equal("Stopped") + }) + }) + + it('start monitor', function() { + return verifyCommand('start monitor MySQL-Monitor', 'monitors/MySQL-Monitor') + .then(function(res) { + res.data.attributes.state.should.equal("Running") + }) + }) + + after(stopMaxScale) +}); diff --git a/maxctrl/test/states.js b/maxctrl/test/states.js index 97eb11dac..29ae81e30 100644 --- a/maxctrl/test/states.js +++ b/maxctrl/test/states.js @@ -12,32 +12,26 @@ describe("Server states", function() { }) it('set correct state', function() { - return ctrl.execute('set server server2 master'.split(' '), opts) - .then(function() { - return request.get(host + 'servers/server2', {json: true}) - }) + return verifyCommand('set server server2 master', 'servers/server2') .then(function(res) { res.data.attributes.state.should.match(/Master/) }) }) it('clear correct state', function() { - return ctrl.execute('clear server server2 master'.split(' '), opts) - .then(function() { - return request.get(host + 'servers/server2', {json: true}) - }) + return verifyCommand('clear server server2 master', 'servers/server2') .then(function(res) { res.data.attributes.state.should.not.match(/Master/) }) }) it('set incorrect state', function() { - return ctrl.execute('set server server2 something'.split(' '), opts) + return doCommand('set server server2 something') .should.be.rejected }) it('clear incorrect state', function() { - return ctrl.execute('clear server server2 something'.split(' '), opts) + return doCommand('clear server server2 something') .should.be.rejected }) diff --git a/maxctrl/test/unknown.js b/maxctrl/test/unknown.js new file mode 100644 index 000000000..18d513290 --- /dev/null +++ b/maxctrl/test/unknown.js @@ -0,0 +1,30 @@ +require('../test_utils.js')() + +describe("Unknown Commands", function() { + before(startMaxScale) + + var endpoints = [ + 'list', + 'show', + 'enable', + 'disable', + 'create', + 'destroy', + 'link', + 'unlink', + 'start', + 'stop', + 'alter', + 'rotate', + 'call', + ] + + endpoints.forEach(function (i) { + it('unknown ' + i + ' command', function() { + return doCommand(i + ' something') + .should.be.rejected + }) + }) + + after(stopMaxScale) +}); diff --git a/maxctrl/test_utils.js b/maxctrl/test_utils.js index 3fa90727b..7dae81e87 100644 --- a/maxctrl/test_utils.js +++ b/maxctrl/test_utils.js @@ -15,6 +15,7 @@ module.exports = function() { this.expect = chai.expect this.host = 'http://localhost:8989/v1/' + // Start MaxScale, this should be called in the `before` handler of each test unit this.startMaxScale = function() { return new Promise(function(resolve, reject) { child_process.execFile("./start_maxscale.sh", function(err, stdout, stderr) { @@ -26,6 +27,8 @@ module.exports = function() { }) }) }; + + // Stop MaxScale, this should be called in the `after` handler of each test unit this.stopMaxScale = function() { return new Promise(function(resolve, reject) { child_process.execFile("./stop_maxscale.sh", function(err, stdout, stderr) { @@ -37,4 +40,21 @@ module.exports = function() { }) }) }; + + // Execute a single MaxCtrl command, returns a Promise + this.doCommand = function(command) { + var ctrl = require('./lib/core.js') + var opts = { extra_args: [ '--quiet'] } + + return ctrl.execute(command.split(' '), opts) + } + + // Execute a single MaxCtrl command and request a resource via the REST API, + // returns a Promise with the JSON format resource as an argument + this.verifyCommand = function(command, resource) { + return doCommand(command) + .then(function() { + return request.get(host + resource, {json: true}) + }) + }; }