From c0c53894b8aba89b89a17dbd9200eaa93165ad4f Mon Sep 17 00:00:00 2001 From: Railag Date: Wed, 12 Dec 2018 16:06:08 +0300 Subject: [PATCH 1/7] fix(bug) fixed system microservices (HAL, bluetooth) launch (EWC-413) (#424) --- src/sequelize/managers/microservice-manager.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sequelize/managers/microservice-manager.js b/src/sequelize/managers/microservice-manager.js index 8f60db033..2e6729cae 100644 --- a/src/sequelize/managers/microservice-manager.js +++ b/src/sequelize/managers/microservice-manager.js @@ -25,6 +25,7 @@ const User = models.User; const Routing = models.Routing; const Registry = models.Registry; const MicroserviceStatus = models.MicroserviceStatus; +const Op = require('sequelize').Op; const microserviceExcludedFields = [ 'configLastUpdated', @@ -135,18 +136,27 @@ class MicroserviceManager extends BaseManager { attributes: ['url'] } ], - attributes: ['picture'] + attributes: ['picture', 'category'] }, { model: Flow, as: 'flow', - required: true, + required: false, attributes: ['isActivated'] } ], where: { iofogUuid: iofogUuid, - '$flow.is_activated$': true + [Op.or]: + [ + { + '$flow.is_activated$': true + }, + { + '$catalogItem.category$': {[Op.eq]: 'SYSTEM'} + } + ] + } }, {transaction: transaction}) } From 45f07d62d49de8dbe62c9122bfb545ff676a77c1 Mon Sep 17 00:00:00 2001 From: epankou <35571073+epankou@users.noreply.github.com> Date: Thu, 13 Dec 2018 13:01:23 +0300 Subject: [PATCH 2/7] fix(bug) added registry email validation (EWC-418) --- src/schemas/registry.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/schemas/registry.js b/src/schemas/registry.js index de986a302..6acd7e6f8 100644 --- a/src/schemas/registry.js +++ b/src/schemas/registry.js @@ -19,7 +19,10 @@ const registryCreate = { "isPublic": {"type": "boolean"}, "username": {"type": "string", "minLength": 1}, "password": {"type": "string"}, - "email": {"type": "string"}, + "email": { + "type": "string", + "pattern": "^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$" + }, "requiresCert": {"type": "boolean"}, "certificate": {"type": "string"} }, @@ -45,7 +48,10 @@ const registryUpdate = { "isPublic": {"type": "boolean"}, "username": {"type": "string", "minLength": 1}, "password": {"type": "string"}, - "email": {"type": "string"}, + "email": { + "type": "string", + "pattern": "^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$" + }, "requiresCert": {"type": "boolean"}, "certificate": {"type": "string"} }, From c0c2b1986b92d2b93cb676e86ffc8a65431cc926 Mon Sep 17 00:00:00 2001 From: Railag Date: Thu, 13 Dec 2018 16:29:56 +0300 Subject: [PATCH 3/7] test(core) unit tests for iofog-controller (EWC-382) (#426) --- src/controllers/iofog-controller.js | 37 +- test/src/controllers/iofog-controller.test.js | 549 ++++++++++++++++++ .../microservices-controller.test.js | 10 +- 3 files changed, 574 insertions(+), 22 deletions(-) create mode 100644 test/src/controllers/iofog-controller.test.js diff --git a/src/controllers/iofog-controller.js b/src/controllers/iofog-controller.js index 72d27e9c0..52727dc01 100644 --- a/src/controllers/iofog-controller.js +++ b/src/controllers/iofog-controller.js @@ -30,16 +30,17 @@ async function updateFogEndPoint(req, user) { } async function deleteFogEndPoint(req, user) { - logger.info("Parameters:" + JSON.stringify(req.body)); - const deleteFog = {}; - deleteFog.uuid = req.params.uuid; + const deleteFog = { + uuid: req.params.uuid + }; return await FogService.deleteFog(deleteFog, user, false) } async function getFogEndPoint(req, user) { - logger.info("Parameters:" + JSON.stringify(req.body)); - const getFog = {}; - getFog.uuid = req.params.uuid; + const getFog = { + uuid: req.params.uuid + }; + return await FogService.getFogWithTransaction(getFog, user, false) } @@ -50,24 +51,27 @@ async function getFogListEndPoint(req, user) { } async function generateProvisionKeyEndPoint(req, user) { - logger.info("Parameters:" + JSON.stringify(req.body)); - const fog = {}; - fog.uuid = req.params.uuid; + const fog = { + uuid: req.params.uuid + }; + return await FogService.generateProvisioningKey(fog, user, false) } async function setFogVersionCommandEndPoint(req, user) { - logger.info("Parameters:" + JSON.stringify(req.body)); - const fogVersionCommand = {}; - fogVersionCommand.uuid = req.params.uuid; - fogVersionCommand.versionCommand = req.params.versionCommand; + const fogVersionCommand = { + uuid: req.params.uuid, + versionCommand: req.params.versionCommand + }; + return await FogService.setFogVersionCommand(fogVersionCommand, user, false) } async function setFogRebootCommandEndPoint(req, user) { - logger.info("Parameters:" + JSON.stringify(req.body)); - const fog = {}; - fog.uuid = req.params.uuid; + const fog = { + uuid: req.params.uuid + }; + return await FogService.setFogRebootCommand(fog, user, false) } @@ -81,7 +85,6 @@ async function getHalHardwareInfoEndPoint(req, user) { return await FogService.getHalHardwareInfo(uuidObj, user, false); } - async function getHalUsbInfoEndPoint(req, user) { const uuidObj = { uuid: req.params.uuid diff --git a/test/src/controllers/iofog-controller.test.js b/test/src/controllers/iofog-controller.test.js new file mode 100644 index 000000000..9405c625d --- /dev/null +++ b/test/src/controllers/iofog-controller.test.js @@ -0,0 +1,549 @@ +const {expect} = require('chai'); +const sinon = require('sinon'); + +const ioFogController = require('../../../src/controllers/iofog-controller'); +const ioFogService = require('../../../src/services/iofog-service'); +const qs = require('qs'); + + +describe('ioFog Controller', () => { + def('subject', () => ioFogController); + def('sandbox', () => sinon.createSandbox()); + + afterEach(() => $sandbox.restore()); + + describe('.createFogEndPoint()', () => { + def('user', () => 'user!'); + + def('name', () => 'testName'); + def('location', () => 'testLocation'); + def('latitude', () => 15); + def('longitude', () => 16); + def('description', () => 'testDescription'); + def('dockerUrl', () => 'testDockerUrl'); + def('diskLimit', () => 25); + def('diskDirectory', () => 'testDiskDirectory'); + def('memoryLimit', () => 35); + def('cpuLimit', () => 45); + def('logLimit', () => 15); + def('logDirectory', () => 'testLogDirectory'); + def('logFileCount', () => 8); + def('statusFrequency', 6); + def('changeFrequency', 18); + def('deviceScanFrequency', 28); + def('bluetoothEnabled', () => false); + def('watchdogEnabled', () => true); + def('abstractedHardwareEnabled', () => false); + def('fogType', () => 0); + + def('req', () => ({ + body: { + name: $name, + location: $location, + latitude: $latitude, + longitude: $longitude, + description: $description, + dockerUrl: $dockerUrl, + diskLimit: $diskLimit, + diskDirectory: $diskDirectory, + memoryLimit: $memoryLimit, + cpuLimit: $cpuLimit, + logLimit: $logLimit, + logDirectory: $logDirectory, + logFileCount: $logFileCount, + statusFrequency: $statusFrequency, + changeFrequency: $changeFrequency, + deviceScanFrequency: $deviceScanFrequency, + bluetoothEnabled: $bluetoothEnabled, + watchdogEnabled: $watchdogEnabled, + abstractedHardwareEnabled: $abstractedHardwareEnabled, + fogType: $fogType + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.createFogEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ioFogService, 'createFog').returns($response); + }); + + it('calls ioFogService.createFog with correct args', async () => { + await $subject; + expect(ioFogService.createFog).to.have.been.calledWith({ + name: $name, + location: $location, + latitude: $latitude, + longitude: $longitude, + description: $description, + dockerUrl: $dockerUrl, + diskLimit: $diskLimit, + diskDirectory: $diskDirectory, + memoryLimit: $memoryLimit, + cpuLimit: $cpuLimit, + logLimit: $logLimit, + logDirectory: $logDirectory, + logFileCount: $logFileCount, + statusFrequency: $statusFrequency, + changeFrequency: $changeFrequency, + deviceScanFrequency: $deviceScanFrequency, + bluetoothEnabled: $bluetoothEnabled, + watchdogEnabled: $watchdogEnabled, + abstractedHardwareEnabled: $abstractedHardwareEnabled, + fogType: $fogType + }, $user, false); + }); + + context('when ioFogService#createFog fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService#createFog succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.updateFogEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('name', () => 'testName'); + def('location', () => 'testLocation'); + def('latitude', () => 15); + def('longitude', () => 16); + def('description', () => 'testDescription'); + def('dockerUrl', () => 'testDockerUrl'); + def('diskLimit', () => 25); + def('diskDirectory', () => 'testDiskDirectory'); + def('memoryLimit', () => 35); + def('cpuLimit', () => 45); + def('logLimit', () => 15); + def('logDirectory', () => 'testLogDirectory'); + def('logFileCount', () => 8); + def('statusFrequency', 6); + def('changeFrequency', 18); + def('deviceScanFrequency', 28); + def('bluetoothEnabled', () => false); + def('watchdogEnabled', () => true); + def('abstractedHardwareEnabled', () => false); + def('fogType', () => 0); + + def('req', () => ({ + params: { + uuid: $uuid + }, + body: { + name: $name, + location: $location, + latitude: $latitude, + longitude: $longitude, + description: $description, + dockerUrl: $dockerUrl, + diskLimit: $diskLimit, + diskDirectory: $diskDirectory, + memoryLimit: $memoryLimit, + cpuLimit: $cpuLimit, + logLimit: $logLimit, + logDirectory: $logDirectory, + logFileCount: $logFileCount, + statusFrequency: $statusFrequency, + changeFrequency: $changeFrequency, + deviceScanFrequency: $deviceScanFrequency, + bluetoothEnabled: $bluetoothEnabled, + watchdogEnabled: $watchdogEnabled, + abstractedHardwareEnabled: $abstractedHardwareEnabled, + fogType: $fogType + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.updateFogEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ioFogService, 'updateFog').returns($response); + }); + + it('calls ioFogService.updateFog with correct args', async () => { + await $subject; + expect(ioFogService.updateFog).to.have.been.calledWith({ + uuid: $uuid, + name: $name, + location: $location, + latitude: $latitude, + longitude: $longitude, + description: $description, + dockerUrl: $dockerUrl, + diskLimit: $diskLimit, + diskDirectory: $diskDirectory, + memoryLimit: $memoryLimit, + cpuLimit: $cpuLimit, + logLimit: $logLimit, + logDirectory: $logDirectory, + logFileCount: $logFileCount, + statusFrequency: $statusFrequency, + changeFrequency: $changeFrequency, + deviceScanFrequency: $deviceScanFrequency, + bluetoothEnabled: $bluetoothEnabled, + watchdogEnabled: $watchdogEnabled, + abstractedHardwareEnabled: $abstractedHardwareEnabled, + fogType: $fogType + }, $user, false) + }); + + context('when ioFogService#updateFog fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService#updateFog succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + + }); + + describe('.deleteFogEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'newTestUuid'); + + def('req', () => ({ + params: { + uuid: $uuid + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.deleteFogEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ioFogService, 'deleteFog').returns($response); + }); + + it('calls ioFogService.deleteFog with correct args', async () => { + await $subject; + expect(ioFogService.deleteFog).to.have.been.calledWith({uuid: $uuid}, $user, false); + }); + + context('when ioFogService#deleteFog fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService#deleteFog succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.getFogEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('req', () => ({ + params: { + uuid: $uuid + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getFogEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ioFogService, 'getFogWithTransaction').returns($response); + }); + + it('calls ioFogService.getFogWithTransaction with correct args', async () => { + await $subject; + expect(ioFogService.getFogWithTransaction).to.have.been.calledWith({uuid: $uuid}, $user, false); + }); + + context('when ioFogService#getFogWithTransaction fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService#getFogWithTransaction succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.getFogListEndPoint()', () => { + def('user', () => 'user!'); + def('filters', () => 'filtersQuery'); + + def('req', () => ({ + query: { + filters: $filters + } + })); + def('response', () => Promise.resolve()); + def('queryParseResponse', () => ({ + filters: $filters + })); + def('subject', () => $subject.getFogListEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(qs, 'parse').returns($queryParseResponse); + $sandbox.stub(ioFogService, 'getFogList').returns($response); + }); + + it('calls qs.parse with correct args', async () => { + await $subject; + expect(qs.parse).to.have.been.calledWith($queryParseResponse); + }); + + context('when qs.parse fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when qs.parse succeeds', () => { + it('calls ioFogService.getFogList with correct args', async () => { + await $subject; + expect(ioFogService.getFogList).to.have.been.calledWith($filters, $user, false); + }); + + context('when ioFogService.getFogList fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService.getFogList succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }) + }); + + describe('.generateProvisionKeyEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('req', () => ({ + params: { + uuid: $uuid + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.generateProvisioningKeyEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ioFogService, 'generateProvisioningKey').returns($response); + }); + + it('calls ioFogService.generateProvisioningKey with correct args', async () => { + await $subject; + expect(ioFogService.generateProvisioningKey).to.have.been.calledWith({uuid: $uuid}, $user, false); + }); + + context('when ioFogService#generateProvisioningKey fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService#generateProvisioningKey succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('setFogVersionCommandEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + def('versionCommand', () => 'version'); + + def('req', () => ({ + params: { + uuid: $uuid, + versionCommand: $versionCommand + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.setFogVersionCommandEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ioFogService, 'setFogVersionCommand').returns($response); + }); + + it('calls ioFogService.setFogVersionCommand with correct args', async () => { + await $subject; + expect(ioFogService.setFogVersionCommand).to.have.been.calledWith({ + uuid: $uuid, + versionCommand: $versionCommand + }, $user, false); + }); + + context('when ioFogService#setFogVersionCommand fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService#setFogVersionCommand succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('setFogRebootCommandEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('req', () => ({ + params: { + uuid: $uuid + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.setFogRebootCommandEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ioFogService, 'setFogRebootCommand').returns($response); + }); + + it('calls ioFogService.setFogRebootCommand with correct args', async () => { + await $subject; + expect(ioFogService.setFogRebootCommand).to.have.been.calledWith({uuid: $uuid}, $user, false); + }); + + context('when ioFogService#setFogRebootCommand fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService#setFogRebootCommand succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('getHalHardwareInfoEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('req', () => ({ + params: { + uuid: $uuid + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getHalHardwareInfoEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ioFogService, 'getHalHardwareInfo').returns($response); + }); + + it('calls ioFogService.getHalHardwareInfo with correct args', async () => { + await $subject; + expect(ioFogService.getHalHardwareInfo).to.have.been.calledWith({uuid: $uuid}, $user, false); + }); + + context('when ioFogService#getHalHardwareInfo fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService#getHalHardwareInfo succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('getHalUsbInfoEndPoint.()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('req', () => ({ + params: { + uuid: $uuid + } + })); + def('response', () => Promise.resolve({info: undefined})); + def('subject', () => $subject.getHalUsbInfoEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ioFogService, 'getHalUsbInfo').returns($response); + }); + + it('calls ioFogService.getHalUsbInfo with correct args', async () => { + await $subject; + expect(ioFogService.getHalUsbInfo).to.have.been.calledWith({uuid: $uuid}, $user, false); + }); + + context('when ioFogService#getHalUsbInfo fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ioFogService#getHalUsbInfo succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.have.property('info'); + }) + }) + }); + +}); \ No newline at end of file diff --git a/test/src/controllers/microservices-controller.test.js b/test/src/controllers/microservices-controller.test.js index 405a3625c..3baa7d889 100644 --- a/test/src/controllers/microservices-controller.test.js +++ b/test/src/controllers/microservices-controller.test.js @@ -322,7 +322,7 @@ describe('Microservices Controller', () => { }) }); - describe('deleteMicroserviceRouteEndPoint.()', () => { + describe('deleteMicroserviceRouteEndPoint()', () => { def('user', () => 'user!'); def('uuid', () => 'testUuid'); def('receiverUuid', () => 'testReceiverUuid'); @@ -452,7 +452,7 @@ describe('Microservices Controller', () => { }) }); - describe('getMicroservicePortMappingListEndPoint.()', () => { + describe('getMicroservicePortMappingListEndPoint()', () => { def('user', () => 'user!'); def('uuid', () => 'testUuid'); @@ -490,7 +490,7 @@ describe('Microservices Controller', () => { }) }); - describe('createMicroserviceVolumeMappingEndPoint.()', () => { + describe('createMicroserviceVolumeMappingEndPoint()', () => { def('user', () => 'user!'); def('uuid', () => 'testUuid'); @@ -541,7 +541,7 @@ describe('Microservices Controller', () => { }) }); - describe('listMicroserviceVolumeMappingsEndPoint.()', () => { + describe('listMicroserviceVolumeMappingsEndPoint()', () => { def('user', () => 'user!'); def('uuid', () => 'testUuid'); @@ -579,7 +579,7 @@ describe('Microservices Controller', () => { }) }); - describe('deleteMicroserviceVolumeMappingEndPoint.()', () => { + describe('deleteMicroserviceVolumeMappingEndPoint()', () => { def('user', () => 'user!'); def('uuid', () => 'testUuid'); def('id', () => 35); From 6f488b50717f83cfe2624c7a266007819965fe47 Mon Sep 17 00:00:00 2001 From: Railag Date: Thu, 13 Dec 2018 17:29:02 +0300 Subject: [PATCH 4/7] test(core) unit tests for flow & diagnostics controllers, updated postman collection & refactored diagnostics (EWC-382) (#427) --- src/cli/diagnostics.js | 16 +- src/controllers/diagnostic-controller.js | 24 +- src/controllers/flow-controller.js | 28 +-- src/routes/diagnostics.js | 11 +- ...Controller Testing.postman_collection.json | 29 ++- .../diagnostics-controller.test.js | 238 ++++++++++++++++++ test/src/controllers/flow-controller.test.js | 228 +++++++++++++++++ 7 files changed, 520 insertions(+), 54 deletions(-) create mode 100644 test/src/controllers/diagnostics-controller.test.js create mode 100644 test/src/controllers/flow-controller.test.js diff --git a/src/cli/diagnostics.js b/src/cli/diagnostics.js index fd1fd6025..9506b8e1a 100644 --- a/src/cli/diagnostics.js +++ b/src/cli/diagnostics.js @@ -38,7 +38,7 @@ class Diagnostics extends BaseCLIHandler { group: [constants.CMD_STRACE_UPDATE] }, { - name: 'microservice-id', alias: 'i', type: String, description: 'Microservice ID', + name: 'microservice-uuid', alias: 'i', type: String, description: 'Microservice UUID', group: [constants.CMD_STRACE_UPDATE, constants.CMD_STRACE_INFO, constants.CMD_STRACE_FTP_POST, constants.CMD_IMAGE_SNAPSHOT_CREATE, constants.CMD_IMAGE_SNAPSHOT_GET] }, @@ -128,16 +128,16 @@ const _executeCase = async function (diagnosticCommand, commandName, f, isUserRe const _changeMicroserviceStraceState = async function (obj) { logger.info(JSON.stringify(obj)); - const enable = AppHelper.validateBooleanCliOptions(obj.enable, obj.disable); - await DiagnosticService.changeMicroserviceStraceState(obj.microserviceId, {enable: enable}, {}, true); - const msg = enable ? 'Microservice strace has been enabled' : 'Microservice strace has been disabled'; + const isEnable = AppHelper.validateBooleanCliOptions(obj.enable, obj.disable); + await DiagnosticService.changeMicroserviceStraceState(obj.microserviceUuid, {enable: isEnable}, {}, true); + const msg = isEnable ? 'Microservice strace has been enabled' : 'Microservice strace has been disabled'; logger.info(msg); }; const _getMicroserviceStraceData = async function (obj) { logger.info(JSON.stringify(obj)); - const result = await DiagnosticService.getMicroserviceStraceData(obj.microserviceId, {format: obj.format}, {}, true); + const result = await DiagnosticService.getMicroserviceStraceData(obj.microserviceUuid, {format: obj.format}, {}, true); logger.info(JSON.stringify(result, null, 2)); logger.info('Microservice strace data has been retrieved successfully.'); }; @@ -145,21 +145,21 @@ const _getMicroserviceStraceData = async function (obj) { const _postMicroserviceStraceDataToFtp = async function (obj) { logger.info(JSON.stringify(obj)); - await DiagnosticService.postMicroserviceStraceDatatoFtp(obj.microserviceId, obj, {}, true); + await DiagnosticService.postMicroserviceStraceDatatoFtp(obj.microserviceUuid, obj, {}, true); logger.info('Strace data has been posted to ftp successfully.'); }; const _postMicroserviceImageSnapshotCreate = async function (obj) { logger.info(JSON.stringify(obj)); - await DiagnosticService.postMicroserviceImageSnapshotCreate(obj.microserviceId, {}, true); + await DiagnosticService.postMicroserviceImageSnapshotCreate(obj.microserviceUuid, {}, true); logger.info('Microservice image snapshot has been created successfully.'); }; const _getMicroserviceImageSnapshot = async function (obj) { logger.info(JSON.stringify(obj)); - const filePath = await DiagnosticService.getMicroserviceImageSnapshot(obj.microserviceId, {}, true); + const filePath = await DiagnosticService.getMicroserviceImageSnapshot(obj.microserviceUuid, {}, true); logger.info('Microservice images path = ' + filePath); }; diff --git a/src/controllers/diagnostic-controller.js b/src/controllers/diagnostic-controller.js index 699a6c382..7512f175e 100644 --- a/src/controllers/diagnostic-controller.js +++ b/src/controllers/diagnostic-controller.js @@ -17,32 +17,30 @@ const AuthDecorator = require('./../decorators/authorization-decorator'); const changeMicroserviceStraceStateEndPoint = async function (req, user) { logger.info("Parameters: " + JSON.stringify(req.body)); - logger.info("Microservice id: " + req.params.id); - return await DiagnosticService.changeMicroserviceStraceState(req.params.id, req.body, user, false); + logger.info("Microservice UUID: " + req.params.uuid); + return await DiagnosticService.changeMicroserviceStraceState(req.params.uuid, req.body, user, false); }; const getMicroserviceStraceDataEndPoint = async function (req, user) { logger.info("Parameters:" + JSON.stringify(req.query)); - logger.info("Microservice id: " + req.params.id); - return await DiagnosticService.getMicroserviceStraceData(req.params.id, req.query, user, false); + logger.info("Microservice UUID: " + req.params.uuid); + return await DiagnosticService.getMicroserviceStraceData(req.params.uuid, req.query, user, false); }; const postMicroserviceStraceDataToFtpEndPoint = async function (req, user) { logger.info("Parameters:" + JSON.stringify(req.body)); - logger.info("Microservice id: " + req.params.id); - return await DiagnosticService.postMicroserviceStraceDatatoFtp(req.params.id, req.body, user, false); + logger.info("Microservice UUID: " + req.params.uuid); + return await DiagnosticService.postMicroserviceStraceDatatoFtp(req.params.uuid, req.body, user, false); }; const createMicroserviceImageSnapshotEndPoint = async function (req, user) { - logger.info("Parameters:" + JSON.stringify(req.body)); - logger.info("Microservice id: " + req.params.id); - return await DiagnosticService.postMicroserviceImageSnapshotCreate(req.params.id, user, false); + logger.info("Microservice UUID: " + req.params.uuid); + return await DiagnosticService.postMicroserviceImageSnapshotCreate(req.params.uuid, user, false); }; const getMicroserviceImageSnapshotEndPoint = async function (req, user) { - logger.info("Parameters:" + JSON.stringify(req.body)); - logger.info("Microservice id: " + req.params.id); - return await DiagnosticService.getMicroserviceImageSnapshot(req.params.id, user, false); + logger.info("Microservice UUID: " + req.params.uuid); + return await DiagnosticService.getMicroserviceImageSnapshot(req.params.uuid, user, false); }; module.exports = { @@ -50,5 +48,5 @@ module.exports = { getMicroserviceStraceDataEndPoint: AuthDecorator.checkAuthToken(getMicroserviceStraceDataEndPoint), postMicroserviceStraceDataToFtpEndPoint: AuthDecorator.checkAuthToken(postMicroserviceStraceDataToFtpEndPoint), createMicroserviceImageSnapshotEndPoint: AuthDecorator.checkAuthToken(createMicroserviceImageSnapshotEndPoint), - getMicroserviceImageSnapshotEndPoint: AuthDecorator.checkAuthToken(getMicroserviceImageSnapshotEndPoint), + getMicroserviceImageSnapshotEndPoint: AuthDecorator.checkAuthToken(getMicroserviceImageSnapshotEndPoint) }; diff --git a/src/controllers/flow-controller.js b/src/controllers/flow-controller.js index ecd9a432b..f66a0cd5e 100644 --- a/src/controllers/flow-controller.js +++ b/src/controllers/flow-controller.js @@ -15,7 +15,7 @@ const logger = require('../logger'); const AuthDecorator = require('./../decorators/authorization-decorator'); const FlowService = require('../services/flow-service'); -const _createFlowEndPoint = async function (req, user) { +const createFlowEndPoint = async function (req, user) { const flow = req.body; logger.info("Parameters:" + JSON.stringify(flow)); @@ -23,40 +23,40 @@ const _createFlowEndPoint = async function (req, user) { return await FlowService.createFlow(flow, user, false) }; -const _getFlowsByUserEndPoint = async function (req, user) { +const getFlowsByUserEndPoint = async function (req, user) { return await FlowService.getUserFlows(user, false) }; -const _getFlowEndPoint = async function (req, user) { +const getFlowEndPoint = async function (req, user) { const flowId = req.params.id; - logger.info("Flow id:" + JSON.stringify(flowId)) + logger.info("Flow id:" + JSON.stringify(flowId)); return await FlowService.getFlowWithTransaction(flowId, user, false) }; -const _updateFlowEndPoint = async function (req, user) { +const updateFlowEndPoint = async function (req, user) { const flow = req.body; const flowId = req.params.id; - logger.info("Parameters:" + JSON.stringify(flow)) - logger.info("Flow id:" + JSON.stringify(flowId)) + logger.info("Parameters:" + JSON.stringify(flow)); + logger.info("Flow id:" + JSON.stringify(flowId)); return await FlowService.updateFlow(flow, flowId, user, false) }; -const _deleteFlowEndPoint = async function (req, user) { +const deleteFlowEndPoint = async function (req, user) { const flowId = req.params.id; - logger.info("Flow id:" + JSON.stringify(flowId)) + logger.info("Flow id:" + JSON.stringify(flowId)); return await FlowService.deleteFlow(flowId, user, false) }; module.exports = { - createFlowEndPoint: AuthDecorator.checkAuthToken(_createFlowEndPoint), - getFlowsByUserEndPoint: AuthDecorator.checkAuthToken(_getFlowsByUserEndPoint), - getFlowEndPoint: AuthDecorator.checkAuthToken(_getFlowEndPoint), - updateFlowEndPoint: AuthDecorator.checkAuthToken(_updateFlowEndPoint), - deleteFlowEndPoint: AuthDecorator.checkAuthToken(_deleteFlowEndPoint) + createFlowEndPoint: AuthDecorator.checkAuthToken(createFlowEndPoint), + getFlowsByUserEndPoint: AuthDecorator.checkAuthToken(getFlowsByUserEndPoint), + getFlowEndPoint: AuthDecorator.checkAuthToken(getFlowEndPoint), + updateFlowEndPoint: AuthDecorator.checkAuthToken(updateFlowEndPoint), + deleteFlowEndPoint: AuthDecorator.checkAuthToken(deleteFlowEndPoint) }; \ No newline at end of file diff --git a/src/routes/diagnostics.js b/src/routes/diagnostics.js index 372828670..d9f512771 100644 --- a/src/routes/diagnostics.js +++ b/src/routes/diagnostics.js @@ -14,13 +14,12 @@ const constants = require('../helpers/constants'); const DiagnosticController = require('../controllers/diagnostic-controller'); const ResponseDecorator = require('../decorators/response-decorator'); const Errors = require('../helpers/errors'); -const ErrorMessages = require('../helpers/error-messages'); const fs = require('fs'); module.exports = [ { method: 'post', - path: '/api/v3/microservices/:id/image-snapshot', + path: '/api/v3/microservices/:uuid/image-snapshot', middleware: async (req, res) => { const successCode = constants.HTTP_CODE_CREATED; @@ -49,7 +48,7 @@ module.exports = [ }, { method: 'get', - path: '/api/v3/microservices/:id/image-snapshot', + path: '/api/v3/microservices/:uuid/image-snapshot', middleware: async (req, res) => { const successCode = constants.HTTP_CODE_SUCCESS; const errorCodes = [ @@ -85,7 +84,7 @@ module.exports = [ }, { method: 'patch', - path: '/api/v3/microservices/:id/strace', + path: '/api/v3/microservices/:uuid/strace', middleware: async (req, res) => { const successCode = constants.HTTP_CODE_NO_CONTENT; @@ -118,7 +117,7 @@ module.exports = [ }, { method: 'get', - path: '/api/v3/microservices/:id/strace', + path: '/api/v3/microservices/:uuid/strace', middleware: async (req, res) => { const successCode = constants.HTTP_CODE_SUCCESS; @@ -147,7 +146,7 @@ module.exports = [ }, { method: 'put', - path: '/api/v3/microservices/:id/strace', + path: '/api/v3/microservices/:uuid/strace', middleware: async (req, res) => { const successCode = constants.HTTP_CODE_NO_CONTENT; const errorCodes = [ diff --git a/test/Controller Testing.postman_collection.json b/test/Controller Testing.postman_collection.json index f18490ce9..0c1d186b1 100644 --- a/test/Controller Testing.postman_collection.json +++ b/test/Controller Testing.postman_collection.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "507ec948-6bd6-48ad-9272-ab609e6ce965", + "_postman_id": "f26c12d6-fdb5-4606-841b-de7979fe33f5", "name": "Controller Testing", "description": "iofog-controller collection", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" @@ -8,7 +8,6 @@ "item": [ { "name": "User", - "description": "User collection", "item": [ { "name": "Create user", @@ -508,6 +507,7 @@ "response": [] } ], + "description": "User collection", "event": [ { "listen": "prerequest", @@ -533,7 +533,6 @@ }, { "name": "General", - "description": "General collection", "item": [ { "name": "Status", @@ -653,6 +652,7 @@ "response": [] } ], + "description": "General collection", "event": [ { "listen": "prerequest", @@ -678,7 +678,6 @@ }, { "name": "Agent", - "description": "Agent collection", "item": [ { "name": "Create user", @@ -1635,7 +1634,7 @@ "", "var data = JSON.parse(responseBody);", "", - "tests[\"Response error message is valid\"] = data.name === \"ValidationError\" && data.message === \"Uploaded image snapshot file not found\"" + "tests[\"Response error message is valid\"] = data.name === \"ValidationError\" && data.message === \"Invalid content type\"" ], "type": "text/javascript" } @@ -1766,6 +1765,7 @@ "response": [] } ], + "description": "Agent collection", "event": [ { "listen": "prerequest", @@ -1791,7 +1791,6 @@ }, { "name": "Flow", - "description": "Flow collection", "item": [ { "name": "Create user", @@ -2175,6 +2174,7 @@ "response": [] } ], + "description": "Flow collection", "event": [ { "listen": "prerequest", @@ -2200,7 +2200,6 @@ }, { "name": "Catalog", - "description": "Catalog collection", "item": [ { "name": "Create user", @@ -2593,6 +2592,7 @@ "response": [] } ], + "description": "Catalog collection", "event": [ { "listen": "prerequest", @@ -2618,7 +2618,6 @@ }, { "name": "Tunnel", - "description": "Tunnel collection", "item": [ { "name": "Create user", @@ -2959,6 +2958,7 @@ "response": [] } ], + "description": "Tunnel collection", "event": [ { "listen": "prerequest", @@ -2984,7 +2984,6 @@ }, { "name": "Microservices", - "description": "Microservices collection", "item": [ { "name": "Create user", @@ -3759,7 +3758,10 @@ "value": "{{user-token}}" } ], - "body": {}, + "body": { + "mode": "raw", + "raw": "" + }, "url": { "raw": "{{host}}/api/v3/microservices/{{ms-id}}/volume-mapping", "host": [ @@ -4056,6 +4058,7 @@ "response": [] } ], + "description": "Microservices collection", "event": [ { "listen": "prerequest", @@ -4081,7 +4084,6 @@ }, { "name": "Diagnostics", - "description": "Diagnostics collection", "item": [ { "name": "Create user", @@ -4877,6 +4879,7 @@ "response": [] } ], + "description": "Diagnostics collection", "event": [ { "listen": "prerequest", @@ -4902,7 +4905,6 @@ }, { "name": "ioFog", - "description": "ioFog collection", "item": [ { "name": "Create user", @@ -5606,6 +5608,7 @@ "response": [] } ], + "description": "ioFog collection", "event": [ { "listen": "prerequest", @@ -5631,7 +5634,6 @@ }, { "name": "Registries", - "description": "Registries collection", "item": [ { "name": "Create user", @@ -5966,6 +5968,7 @@ "response": [] } ], + "description": "Registries collection", "event": [ { "listen": "prerequest", diff --git a/test/src/controllers/diagnostics-controller.test.js b/test/src/controllers/diagnostics-controller.test.js new file mode 100644 index 000000000..1403afd63 --- /dev/null +++ b/test/src/controllers/diagnostics-controller.test.js @@ -0,0 +1,238 @@ +const {expect} = require('chai'); +const sinon = require('sinon'); + +const DiagnosticController = require('../../../src/controllers/diagnostic-controller'); +const DiagnosticService = require('../../../src/services/diagnostic-service'); + +describe('Diagnostic Controller', () => { + def('subject', () => DiagnosticController); + def('sandbox', () => sinon.createSandbox()); + + afterEach(() => $sandbox.restore()); + + describe('.changeMicroserviceStraceStateEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('enable', () => true); + + def('req', () => ({ + params: { + uuid: $uuid + }, + body: { + enable: $enable + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.changeMicroserviceStraceStateEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(DiagnosticService, 'changeMicroserviceStraceState').returns($response); + }); + + it('calls DiagnosticService.changeMicroserviceStraceState with correct args', async () => { + await $subject; + expect(DiagnosticService.changeMicroserviceStraceState).to.have.been.calledWith($uuid, { + enable: $enable + }, $user, false); + }); + + context('when DiagnosticService#changeMicroserviceStraceState fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when DiagnosticService#changeMicroserviceStraceState succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.getMicroserviceStraceDataEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + def('format', () => 'string'); + + def('req', () => ({ + params: { + uuid: $uuid + }, + query: { + format: $format + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getMicroserviceStraceDataEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(DiagnosticService, 'getMicroserviceStraceData').returns($response); + }); + + it('calls DiagnosticService.getMicroserviceStraceData with correct args', async () => { + await $subject; + expect(DiagnosticService.getMicroserviceStraceData).to.have.been.calledWith($uuid, { + format: $format + }, $user, false) + }); + + context('when DiagnosticService#getMicroserviceStraceData fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when DiagnosticService#getMicroserviceStraceData succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + + }); + + describe('.postMicroserviceStraceDataToFtpEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('ftpHost', () => 'testHost'); + def('ftpPort', () => 15); + def('ftpPass', () => 'ftpPass'); + def('ftpDestDir', () => 'ftpDestDirectory'); + + def('req', () => ({ + params: { + uuid: $uuid + }, + body: { + ftpHost: $ftpHost, + ftpPort: $ftpPort, + ftpPass: $ftpPass, + ftpDestDir: $ftpDestDir + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.postMicroserviceStraceDataToFtpEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(DiagnosticService, 'postMicroserviceStraceDatatoFtp').returns($response); + }); + + it('calls DiagnosticService.postMicroserviceStraceDatatoFtp with correct args', async () => { + await $subject; + expect(DiagnosticService.postMicroserviceStraceDatatoFtp).to.have.been.calledWith($uuid, { + ftpHost: $ftpHost, + ftpPort: $ftpPort, + ftpPass: $ftpPass, + ftpDestDir: $ftpDestDir + }, $user, false); + }); + + context('when DiagnosticService#postMicroserviceStraceDatatoFtp fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when DiagnosticService#postMicroserviceStraceDatatoFtp succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.createMicroserviceImageSnapshotEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('req', () => ({ + params: { + uuid: $uuid + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.createMicroserviceImageSnapshotEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(DiagnosticService, 'postMicroserviceImageSnapshotCreate').returns($response); + }); + + it('calls DiagnosticService.postMicroserviceImageSnapshotCreate with correct args', async () => { + await $subject; + expect(DiagnosticService.postMicroserviceImageSnapshotCreate).to.have.been.calledWith($uuid, $user, false); + }); + + context('when DiagnosticService#postMicroserviceImageSnapshotCreate fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when DiagnosticService#postMicroserviceImageSnapshotCreate succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.getMicroserviceImageSnapshotEndPoint()', () => { + def('user', () => 'user!'); + def('uuid', () => 'testUuid'); + + def('req', () => ({ + params: { + uuid: $uuid + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.getMicroserviceImageSnapshotEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(DiagnosticService, 'getMicroserviceImageSnapshot').returns($response); + }); + + it('calls DiagnosticService.getMicroserviceImageSnapshot with correct args', async () => { + await $subject; + expect(DiagnosticService.getMicroserviceImageSnapshot).to.have.been.calledWith($uuid, $user, false); + }); + + context('when DiagnosticService.getMicroserviceImageSnapshot fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when DiagnosticService.getMicroserviceImageSnapshot succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + + }); + +}); \ No newline at end of file diff --git a/test/src/controllers/flow-controller.test.js b/test/src/controllers/flow-controller.test.js new file mode 100644 index 000000000..ecb45b2a4 --- /dev/null +++ b/test/src/controllers/flow-controller.test.js @@ -0,0 +1,228 @@ +const {expect} = require('chai'); +const sinon = require('sinon'); + +const FlowController = require('../../../src/controllers/flow-controller'); +const FlowService = require('../../../src/services/flow-service'); + +describe('Flow Controller', () => { + def('subject', () => FlowController); + def('sandbox', () => sinon.createSandbox()); + + afterEach(() => $sandbox.restore()); + + describe('.createFlowEndPoint()', () => { + def('user', () => 'user!'); + + def('name', () => 'testName'); + def('description', () => 'testDescription'); + def('isActivated', () => true); + + def('req', () => ({ + body: { + name: $name, + description: $description, + isActivated: $isActivated + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.createFlowEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(FlowService, 'createFlow').returns($response); + }); + + it('calls FlowService.createFlow with correct args', async () => { + await $subject; + expect(FlowService.createFlow).to.have.been.calledWith({ + name: $name, + description: $description, + isActivated: $isActivated + }, $user, false); + }); + + context('when FlowService#createFlow fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when FlowService#createFlow succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.getFlowsByUserEndPoint()', () => { + def('user', () => 'user!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getFlowsByUserEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(FlowService, 'getUserFlows').returns($response); + }); + + it('calls FlowService.getUserFlows with correct args', async () => { + await $subject; + expect(FlowService.getUserFlows).to.have.been.calledWith($user, false) + }); + + context('when FlowService#getUserFlows fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when FlowService#getUserFlows succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + + }); + + describe('.getFlowEndPoint()', () => { + def('user', () => 'user!'); + def('id', () => 15); + + def('req', () => ({ + params: { + id: $id + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.getFlowEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(FlowService, 'getFlowWithTransaction').returns($response); + }); + + it('calls FlowService.getFlowWithTransaction with correct args', async () => { + await $subject; + expect(FlowService.getFlowWithTransaction).to.have.been.calledWith($id, $user, false); + }); + + context('when FlowService#getFlowWithTransaction fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when FlowService#getFlowWithTransaction succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.updateFlowEndPoint()', () => { + def('user', () => 'user!'); + def('id', () => 15); + + def('name', () => 'updatedTestName'); + def('description', () => 'updatedTestDescription'); + def('isActivated', () => false); + + def('req', () => ({ + params: { + id: $id + }, + body: { + name: $name, + description: $description, + isActivated: $isActivated + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.updateFlowEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(FlowService, 'updateFlow').returns($response); + }); + + it('calls FlowService.updateFlow with correct args', async () => { + await $subject; + expect(FlowService.updateFlow).to.have.been.calledWith({ + name: $name, + description: $description, + isActivated: $isActivated + }, $id, $user, false); + }); + + context('when FlowService#updateFlow fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when FlowService#updateFlow succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.deleteFlowEndPoint()', () => { + def('user', () => 'user!'); + def('id', () => 15); + + def('req', () => ({ + params: { + id: $id + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.deleteFlowEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(FlowService, 'deleteFlow').returns($response); + }); + + it('calls FlowService.deleteFlow with correct args', async () => { + await $subject; + expect(FlowService.deleteFlow).to.have.been.calledWith($id, $user, false); + }); + + context('when FlowService.deleteFlow fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when FlowService.deleteFlow succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + + }); + +}); \ No newline at end of file From a11cf4bbee5683559d54c8c49763cd614fe9b5a0 Mon Sep 17 00:00:00 2001 From: alexandershpak <35569337+alexandershpak@users.noreply.github.com> Date: Thu, 13 Dec 2018 18:19:12 +0300 Subject: [PATCH 5/7] bug(fix) CLI diagnostics: Incorrect error message is displayed when user try to get strace-info (#428) --- src/helpers/error-messages.js | 1 + src/services/diagnostic-service.js | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/helpers/error-messages.js b/src/helpers/error-messages.js index c107044c0..6ab703477 100644 --- a/src/helpers/error-messages.js +++ b/src/helpers/error-messages.js @@ -23,6 +23,7 @@ module.exports = { INVALID_FOG_NODE_UUID: 'Invalid ioFog UUID {}', INVALID_USER_EMAIL: 'Invalid user email', INVALID_MICROSERVICE_UUID: "Invalid microservice UUID '{}'", + INVALID_MICROSERVICE_STRACE: "Strace data for this microservice not found", INVALID_VOLUME_MAPPING_UUID: "Invalid volume mapping id '{}'", ACTIVATION_CODE_NOT_FOUND: 'Activation code not found', INVALID_OLD_PASSWORD: 'Old password is incorrect', diff --git a/src/services/diagnostic-service.js b/src/services/diagnostic-service.js index d2aeeb6c0..741f122f4 100644 --- a/src/services/diagnostic-service.js +++ b/src/services/diagnostic-service.js @@ -56,6 +56,10 @@ const getMicroserviceStraceData = async function (id, data, user, isCLI, transac } const straceData = await StraceDiagnosticManager.findOne({microserviceUuid: id}, transaction); + if (!straceData) { + throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_STRACE, id)) + } + const dir = config.get('Diagnostics:DiagnosticDir') || 'diagnostics'; const filePath = dir + '/' + id; From 8075b4dbf46daa13db76371b741f0018cf87ac3f Mon Sep 17 00:00:00 2001 From: Railag Date: Fri, 14 Dec 2018 16:42:00 +0300 Subject: [PATCH 6/7] test(core) unit tests for catalog, controller and agent controllers (EWC-382) (#430) --- src/decorators/authorization-decorator.js | 2 +- src/schemas/agent.js | 4 +- src/sequelize/managers/strace-manager.js | 2 +- src/services/agent-service.js | 4 +- test/src/controllers/agent-controller.test.js | 767 ++++++++++++++++++ .../controllers/catalog-controller.test.js | 320 ++++++++ .../controllers/controller-controller.test.js | 115 +++ 7 files changed, 1208 insertions(+), 6 deletions(-) create mode 100644 test/src/controllers/agent-controller.test.js create mode 100644 test/src/controllers/catalog-controller.test.js create mode 100644 test/src/controllers/controller-controller.test.js diff --git a/src/decorators/authorization-decorator.js b/src/decorators/authorization-decorator.js index a3f78aee4..9702d2235 100644 --- a/src/decorators/authorization-decorator.js +++ b/src/decorators/authorization-decorator.js @@ -86,4 +86,4 @@ function checkFogToken(f) { module.exports = { checkAuthToken: checkAuthToken, checkFogToken: checkFogToken -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/schemas/agent.js b/src/schemas/agent.js index 3d3c19cc5..5dd990aa4 100644 --- a/src/schemas/agent.js +++ b/src/schemas/agent.js @@ -104,10 +104,10 @@ const straceData = { "id": "/straceData", "type": "object", "properties": { - "microserviceId": {"type": "string"}, + "microserviceUuid": {"type": "string"}, "buffer": {"type": "string"} }, - "required": ["microserviceId", "buffer"], + "required": ["microserviceUuid", "buffer"], "additionalProperties": false }; diff --git a/src/sequelize/managers/strace-manager.js b/src/sequelize/managers/strace-manager.js index f910e196b..8d0f50422 100644 --- a/src/sequelize/managers/strace-manager.js +++ b/src/sequelize/managers/strace-manager.js @@ -26,7 +26,7 @@ class StraceManager extends BaseManager { return Strace } - async pushBufferByMicroserviceId(uuid, pushingData, transaction) { + async pushBufferByMicroserviceUuid(uuid, pushingData, transaction) { const strace = await this.findOne({ microserviceUuid: uuid }, transaction); diff --git a/src/services/agent-service.js b/src/services/agent-service.js index 8160eb82e..ab71dd9b9 100644 --- a/src/services/agent-service.js +++ b/src/services/agent-service.js @@ -315,9 +315,9 @@ const updateAgentStrace = async function (straceData, fog, transaction) { await Validator.validate(straceData, Validator.schemas.updateAgentStrace); for (const strace of straceData.straceData) { - const microserviceId = strace.microserviceId; + const microserviceUuid = strace.microserviceUuid; const buffer = strace.buffer; - await StraceManager.pushBufferByMicroserviceId(microserviceId, buffer, transaction) + await StraceManager.pushBufferByMicroserviceUuid(microserviceUuid, buffer, transaction) } }; diff --git a/test/src/controllers/agent-controller.test.js b/test/src/controllers/agent-controller.test.js new file mode 100644 index 000000000..4524ba76b --- /dev/null +++ b/test/src/controllers/agent-controller.test.js @@ -0,0 +1,767 @@ +const {expect} = require('chai'); +const sinon = require('sinon'); + +const AgentController = require('../../../src/controllers/agent-controller'); +const AgentService = require('../../../src/services/agent-service'); + +describe('Agent Controller', () => { + def('subject', () => AgentController); + def('sandbox', () => sinon.createSandbox()); + + afterEach(() => $sandbox.restore()); + + describe('.agentProvisionEndPoint()', () => { + def('type', () => 1); + def('key', () => 'testKey'); + + def('req', () => ({ + body: { + type: $type, + key: $key + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.agentProvisionEndPoint($req)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'agentProvision').returns($response); + }); + + it('calls AgentService.agentProvision with correct args', async () => { + await $subject; + expect(AgentService.agentProvision).to.have.been.calledWith({ + type: $type, + key: $key + }); + }); + + context('when AgentService#agentProvision fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#agentProvision succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.getAgentConfigEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getAgentConfigEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'getAgentConfig').returns($response); + }); + + it('calls AgentService.getAgentConfig with correct args', async () => { + await $subject; + expect(AgentService.getAgentConfig).to.have.been.calledWith($fog) + }); + + context('when AgentService#getAgentConfig fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#getAgentConfig succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + + }); + + describe('.updateAgentConfigEndPoint()', () => { + def('fog', () => 'fog!'); + + def('networkInterface', () => 'testNetworkInterface'); + def('dockerUrl', () => 'testDockerUrl'); + def('diskLimit', 15); + def('diskDirectory', () => 'testDiskDirectory'); + def('memoryLimit', () => 25); + def('cpuLimit', () => 35); + def('logLimit', () => 45); + def('logDirectory', () => 'testLogDirectory'); + def('logFileCount', () => 5); + def('statusFrequency', () => 60); + def('changeFrequency', () => 30); + def('deviceScanFrequency', () => 40); + def('watchdogEnabled', () => true); + def('latitude', () => 30); + def('longitude', () => 40); + def('gpsMode', () => 'testGpsMode'); + + def('req', () => ({ + body: { + networkInterface: $networkInterface, + dockerUrl: $dockerUrl, + diskLimit: $diskLimit, + diskDirectory: $diskDirectory, + memoryLimit: $memoryLimit, + cpuLimit: $cpuLimit, + logLimit: $logLimit, + logDirectory: $logDirectory, + logFileCount: $logFileCount, + statusFrequency: $statusFrequency, + changeFrequency: $changeFrequency, + devicesScanFrequency: $deviceScanFrequency, + watchdogEnabled: $watchdogEnabled, + latitude: $latitude, + longitude: $longitude, + gpsMode: $gpsMode + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.updateAgentConfigEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'updateAgentConfig').returns($response); + }); + + it('calls AgentService.updateAgentConfig with correct args', async () => { + await $subject; + expect(AgentService.updateAgentConfig).to.have.been.calledWith({ + networkInterface: $networkInterface, + dockerUrl: $dockerUrl, + diskLimit: $diskLimit, + diskDirectory: $diskDirectory, + memoryLimit: $memoryLimit, + cpuLimit: $cpuLimit, + logLimit: $logLimit, + logDirectory: $logDirectory, + logFileCount: $logFileCount, + statusFrequency: $statusFrequency, + changeFrequency: $changeFrequency, + devicesScanFrequency: $deviceScanFrequency, + watchdogEnabled: $watchdogEnabled, + latitude: $latitude, + longitude: $longitude, + gpsMode: $gpsMode + }, $fog); + }); + + context('when AgentService#updateAgentConfig fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#updateAgentConfig succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.getAgentConfigChangesEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getAgentConfigChangesEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'getAgentConfigChanges').returns($response); + }); + + it('calls AgentService.getAgentConfigChanges with correct args', async () => { + await $subject; + expect(AgentService.getAgentConfigChanges).to.have.been.calledWith($fog); + }); + + context('when AgentService#getAgentConfigChanges fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#getAgentConfigChanges succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.updateAgentStatusEndPoint()', () => { + def('fog', () => 'fog!'); + + def('daemonStatus', () => 'testDaemonStatus'); + def('daemonOperatingDuration', () => 'testDaemonOperatingDuration'); + def('daemonLastStart', () => 5); + def('memoryUsage', () => 25); + def('diskUsage', () => 35); + def('cpuUsage', () => 45); + def('memoryViolation', () => true); + def('diskViolation', () => true); + def('cpuViolation', () => true); + def('microserviceStatus', () => 'RUNNING'); + def('repositoryCount', () => 5); + def('repositoryStatus', () => 'testRepositoryStatus'); + def('systemTime', () => 1555555); + def('lastStatusTime', () => 15555555); + def('ipAddress', () => 'testIpAddress'); + def('processedMessages', () => 155); + def('microserviceMessageCounts', () => 1555); + def('messageSpeed', () => 5); + def('lastCommandTime', () => 155555555); + def('tunnelStatus', () => 'testTunnelStatus'); + def('version', () => '1.5.6'); + def('isReadyToUpgrade', () => true); + def('isReadyToRollback', () => true); + + def('req', () => ({ + body: { + daemonStatus: $daemonStatus, + daemonOperatingDuration: $daemonOperatingDuration, + daemonLastStart: $daemonLastStart, + memoryUsage: $memoryUsage, + diskUsage: $diskUsage, + cpuUsage: $cpuUsage, + memoryViolation: $memoryViolation, + diskViolation: $diskViolation, + cpuViolation: $cpuViolation, + microserviceStatus: $microserviceStatus, + repositoryCount: $repositoryCount, + repositoryStatus: $repositoryStatus, + systemTime: $systemTime, + lastStatusTime: $lastStatusTime, + ipAddress: $ipAddress, + processedMessages: $processedMessages, + microserviceMessageCounts: $microserviceMessageCounts, + messageSpeed: $messageSpeed, + lastCommandTime: $lastCommandTime, + tunnelStatus: $tunnelStatus, + version: $version, + IsReadyToUpgrade: $isReadyToUpgrade, + isReadyToRollback: $isReadyToRollback + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.updateAgentStatusEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'updateAgentStatus').returns($response); + }); + + it('calls AgentService.updateAgentStatus with correct args', async () => { + await $subject; + expect(AgentService.updateAgentStatus).to.have.been.calledWith({ + daemonStatus: $daemonStatus, + daemonOperatingDuration: $daemonOperatingDuration, + daemonLastStart: $daemonLastStart, + memoryUsage: $memoryUsage, + diskUsage: $diskUsage, + cpuUsage: $cpuUsage, + memoryViolation: $memoryViolation, + diskViolation: $diskViolation, + cpuViolation: $cpuViolation, + microserviceStatus: $microserviceStatus, + repositoryCount: $repositoryCount, + repositoryStatus: $repositoryStatus, + systemTime: $systemTime, + lastStatusTime: $lastStatusTime, + ipAddress: $ipAddress, + processedMessages: $processedMessages, + microserviceMessageCounts: $microserviceMessageCounts, + messageSpeed: $messageSpeed, + lastCommandTime: $lastCommandTime, + tunnelStatus: $tunnelStatus, + version: $version, + IsReadyToUpgrade: $isReadyToUpgrade, + isReadyToRollback: $isReadyToRollback + }, $fog); + }); + + context('when AgentService#updateAgentStatus fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#updateAgentStatus succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.getAgentMicroservicesEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getAgentMicroservicesEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'getAgentMicroservices').returns($response); + }); + + it('calls AgentService.getAgentMicroservices with correct args', async () => { + await $subject; + expect(AgentService.getAgentMicroservices).to.have.been.calledWith($fog); + }); + + context('when AgentService#getAgentMicroservices fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#getAgentMicroservices succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('getAgentMicroserviceEndPoint()', () => { + def('fog', () => 'fog!'); + def('microserviceUuid', () => 'testUuid'); + + def('req', () => ({ + params: { + microserviceUuid: $microserviceUuid, + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getAgentMicroserviceEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'getAgentMicroservice').returns($response); + }); + + it('calls AgentService.getAgentMicroservice with correct args', async () => { + await $subject; + expect(AgentService.getAgentMicroservice).to.have.been.calledWith($microserviceUuid, $fog); + }); + + context('when AgentService#getAgentMicroservice fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#getAgentMicroservice succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('getAgentRegistriesEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getAgentRegistriesEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'getAgentRegistries').returns($response); + }); + + it('calls AgentService.getAgentRegistries with correct args', async () => { + await $subject; + expect(AgentService.getAgentRegistries).to.have.been.calledWith($fog); + }); + + context('when AgentService#getAgentRegistries fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#getAgentRegistries succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('getAgentTunnelEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getAgentTunnelEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'getAgentTunnel').returns($response); + }); + + it('calls AgentService.getAgentTunnel with correct args', async () => { + await $subject; + expect(AgentService.getAgentTunnel).to.have.been.calledWith($fog); + }); + + context('when AgentService#getAgentTunnel fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#getAgentTunnel succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('getAgentStraceEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getAgentStraceEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'getAgentStrace').returns($response); + }); + + it('calls AgentService.getAgentStrace with correct args', async () => { + await $subject; + expect(AgentService.getAgentStrace).to.have.been.calledWith($fog); + }); + + context('when AgentService#getAgentStrace fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#getAgentStrace succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('updateAgentStraceEndPoint()', () => { + def('fog', () => 'fog!'); + def('microserviceUuid', () => 'microserviceUuid'); + def('buffer', () => 'testBuffer'); + + def('straceData', [{ + microserviceUuid: $microserviceUuid, + buffer: $buffer + }]); + + def('req', () => ({ + body: { + straceData: $straceData + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.updateAgentStraceEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'updateAgentStrace').returns($response); + }); + + it('calls AgentService.updateAgentStrace with correct args', async () => { + await $subject; + expect(AgentService.updateAgentStrace).to.have.been.calledWith({ + straceData: $straceData + }, $fog); + }); + + context('when AgentService#updateAgentStrace fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#updateAgentStrace succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('getAgentChangeVersionCommandEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getAgentChangeVersionCommandEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'getAgentChangeVersionCommand').returns($response); + }); + + it('calls AgentService.getAgentChangeVersionCommand with correct args', async () => { + await $subject; + expect(AgentService.getAgentChangeVersionCommand).to.have.been.calledWith($fog); + }); + + context('when AgentService#getAgentChangeVersionCommand fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#getAgentChangeVersionCommand succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('updateHalHardwareInfoEndPoint()', () => { + def('fog', () => 'fog!'); + + def('info', () => 'testInfo'); + + def('req', () => ({ + body: { + info: $info + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.updateHalHardwareInfoEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'updateHalHardwareInfo').returns($response); + }); + + it('calls AgentService.updateHalHardwareInfo with correct args', async () => { + await $subject; + expect(AgentService.updateHalHardwareInfo).to.have.been.calledWith({ + info: $info + }, $fog); + }); + + context('when AgentService#updateHalHardwareInfo fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#updateHalHardwareInfo succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('updateHalUsbInfoEndPoint()', () => { + def('fog', () => 'fog!'); + + def('info', () => 'testInfo'); + + def('req', () => ({ + body: { + info: $info + } + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.updateHalUsbInfoEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'updateHalUsbInfo').returns($response); + }); + + it('calls AgentService.updateHalUsbInfo with correct args', async () => { + await $subject; + expect(AgentService.updateHalUsbInfo).to.have.been.calledWith({ + info: $info + }, $fog); + }); + + context('when AgentService#updateHalUsbInfo fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#updateHalUsbInfo succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('deleteNodeEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.deleteNodeEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'deleteNode').returns($response); + }); + + it('calls AgentService.deleteNode with correct args', async () => { + await $subject; + expect(AgentService.deleteNode).to.have.been.calledWith($fog); + }); + + context('when AgentService#deleteNode fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#deleteNode succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('getImageSnapshotEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.getImageSnapshotEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'getImageSnapshot').returns($response); + }); + + it('calls AgentService.getImageSnapshot with correct args', async () => { + await $subject; + expect(AgentService.getImageSnapshot).to.have.been.calledWith($fog); + }); + + context('when AgentService#getImageSnapshot fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#getImageSnapshot succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('putImageSnapshotEndPoint()', () => { + def('fog', () => 'fog!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.putImageSnapshotEndPoint($req, $fog)); + + beforeEach(() => { + $sandbox.stub(AgentService, 'putImageSnapshot').returns($response); + }); + + it('calls AgentService.putImageSnapshot with correct args', async () => { + await $subject; + expect(AgentService.putImageSnapshot).to.have.been.calledWith($req, $fog); + }); + + context('when AgentService#putImageSnapshot fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when AgentService#putImageSnapshot succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + +}); \ No newline at end of file diff --git a/test/src/controllers/catalog-controller.test.js b/test/src/controllers/catalog-controller.test.js new file mode 100644 index 000000000..18c611d04 --- /dev/null +++ b/test/src/controllers/catalog-controller.test.js @@ -0,0 +1,320 @@ +const {expect} = require('chai'); +const sinon = require('sinon'); + +const CatalogController = require('../../../src/controllers/catalog-controller'); +const CatalogService = require('../../../src/services/catalog-service'); + +describe('Catalog Controller', () => { + def('subject', () => CatalogController); + def('sandbox', () => sinon.createSandbox()); + + afterEach(() => $sandbox.restore()); + + describe('.createCatalogItemEndPoint()', () => { + def('user', () => 'user!'); + + def('name', () => 'testName'); + def('description', () => 'testDescription'); + def('category', () => 'testCategory'); + def('containerImage', () => 'testContainerImage'); + def('fogTypeId', () => 'testFogTypeId'); + def('images', () => [{ + containerImage: $containerImage, + fogTypeId: $fogTypeId + }]); + def('publisher', () => 'testPublisher'); + def('diskRequired', () => 15); + def('ramRequired', () => 25); + def('picture', () => 'testPicture'); + def('isPublic', () => false); + def('registryId', () => 5); + def('inputInfoType', () => 'testInfoType'); + def('inputInfoFormat', () => 'testInfoFormat'); + def('inputType', () => ({ + infoType: $inputInfoType, + infoFormat: $inputInfoFormat + })); + def('outputInfoType', () => 'testInfoType'); + def('outputInfoFormat', () => 'testInfoFormat'); + def('outputType', () => ({ + infoType: $outputInfoType, + infoFormat: $outputInfoFormat + })); + def('configExample', () => '{}'); + + def('req', () => ({ + body: { + name: $name, + description: $description, + category: $category, + images: $images, + publisher: $publisher, + diskRequired: $diskRequired, + ramRequired: $ramRequired, + picture: $picture, + isPublic: $isPublic, + registryId: $registryId, + inputType: $inputType, + outputType: $outputType, + configExample: $configExample + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.createCatalogItemEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(CatalogService, 'createCatalogItem').returns($response); + }); + + it('calls CatalogService.createCatalogItem with correct args', async () => { + await $subject; + expect(CatalogService.createCatalogItem).to.have.been.calledWith({ + name: $name, + description: $description, + category: $category, + images: $images, + publisher: $publisher, + diskRequired: $diskRequired, + ramRequired: $ramRequired, + picture: $picture, + isPublic: $isPublic, + registryId: $registryId, + inputType: $inputType, + outputType: $outputType, + configExample: $configExample + }, $user); + }); + + context('when CatalogService#createCatalogItem fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogService#createCatalogItem succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.listCatalogItemsEndPoint()', () => { + def('user', () => 'user!'); + + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.listCatalogItemsEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(CatalogService, 'listCatalogItems').returns($response); + }); + + it('calls CatalogService.listCatalogItems with correct args', async () => { + await $subject; + expect(CatalogService.listCatalogItems).to.have.been.calledWith($user, false) + }); + + context('when CatalogService#listCatalogItems fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogService#listCatalogItems succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + + }); + + + + describe('.listCatalogItemEndPoint()', () => { + def('user', () => 'user!'); + def('id', () => 15); + + def('req', () => ({ + params: { + id: $id + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.listCatalogItemEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(CatalogService, 'getCatalogItem').returns($response); + }); + + it('calls CatalogService.getCatalogItem with correct args', async () => { + await $subject; + expect(CatalogService.getCatalogItem).to.have.been.calledWith($id, $user, false); + }); + + context('when CatalogService#getCatalogItem fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogService#getCatalogItem succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.deleteCatalogItemEndPoint()', () => { + def('user', () => 'user!'); + def('id', () => 15); + + def('req', () => ({ + params: { + id: $id + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.deleteCatalogItemEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(CatalogService, 'deleteCatalogItem').returns($response); + }); + + it('calls CatalogService.deleteCatalogItem with correct args', async () => { + await $subject; + expect(CatalogService.deleteCatalogItem).to.have.been.calledWith($id, $user, false); + }); + + context('when CatalogService#deleteCatalogItem fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogService#deleteCatalogItem succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.updateCatalogItemEndPoint()', () => { + def('user', () => 'user!'); + def('id', () => 15); + + def('name', () => 'testName'); + def('description', () => 'testDescription'); + def('category', () => 'testCategory'); + def('containerImage', () => 'testContainerImage'); + def('fogTypeId', () => 'testFogTypeId'); + def('images', () => [{ + containerImage: $containerImage, + fogTypeId: $fogTypeId + }]); + def('publisher', () => 'testPublisher'); + def('diskRequired', () => 15); + def('ramRequired', () => 25); + def('picture', () => 'testPicture'); + def('isPublic', () => false); + def('registryId', () => 5); + def('inputInfoType', () => 'testInfoType'); + def('inputInfoFormat', () => 'testInfoFormat'); + def('inputType', () => ({ + infoType: $inputInfoType, + infoFormat: $inputInfoFormat + })); + def('outputInfoType', () => 'testInfoType'); + def('outputInfoFormat', () => 'testInfoFormat'); + def('outputType', () => ({ + infoType: $outputInfoType, + infoFormat: $outputInfoFormat + })); + def('configExample', () => '{}'); + + def('req', () => ({ + params: { + id: $id + }, + body: { + name: $name, + description: $description, + category: $category, + images: $images, + publisher: $publisher, + diskRequired: $diskRequired, + ramRequired: $ramRequired, + picture: $picture, + isPublic: $isPublic, + registryId: $registryId, + inputType: $inputType, + outputType: $outputType, + configExample: $configExample + } + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.updateCatalogItemEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(CatalogService, 'updateCatalogItem').returns($response); + }); + + it('calls CatalogService.updateCatalogItem with correct args', async () => { + await $subject; + expect(CatalogService.updateCatalogItem).to.have.been.calledWith($id, { + name: $name, + description: $description, + category: $category, + images: $images, + publisher: $publisher, + diskRequired: $diskRequired, + ramRequired: $ramRequired, + picture: $picture, + isPublic: $isPublic, + registryId: $registryId, + inputType: $inputType, + outputType: $outputType, + configExample: $configExample + }, $user, false); + }); + + context('when CatalogService.updateCatalogItem fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when CatalogService.updateCatalogItem succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + + }); + +}); \ No newline at end of file diff --git a/test/src/controllers/controller-controller.test.js b/test/src/controllers/controller-controller.test.js new file mode 100644 index 000000000..fe5b70471 --- /dev/null +++ b/test/src/controllers/controller-controller.test.js @@ -0,0 +1,115 @@ +const {expect} = require('chai'); +const sinon = require('sinon'); + +const Controller = require('../../../src/controllers/controller'); +const ControllerService = require('../../../src/services/controller-service'); + +describe('Controller', () => { + def('subject', () => Controller); + def('sandbox', () => sinon.createSandbox()); + + afterEach(() => $sandbox.restore()); + + describe('.statusControllerEndPoint()', () => { + def('req', () => ({ + body: {} + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.statusControllerEndPoint($req)); + + beforeEach(() => { + $sandbox.stub(ControllerService, 'statusController').returns($response); + }); + + it('calls ControllerService.statusController with correct args', async () => { + await $subject; + expect(ControllerService.statusController).to.have.been.calledWith(false); + }); + + context('when ControllerService#statusController fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ControllerService#statusController succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + + describe('.emailActivationEndPoint()', () => { + def('req', () => ({ + body: {} + })); + def('response', () => Promise.resolve()); + def('subject', () => $subject.emailActivationEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ControllerService, 'emailActivation').returns($response); + }); + + it('calls ControllerService.emailActivation with correct args', async () => { + await $subject; + expect(ControllerService.emailActivation).to.have.been.calledWith(false) + }); + + context('when ControllerService#emailActivation fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ControllerService#emailActivation succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + + }); + + describe('.fogTypesEndPoint()', () => { + def('req', () => ({ + body: {} + })); + + def('response', () => Promise.resolve()); + def('subject', () => $subject.fogTypesEndPoint($req, $user)); + + beforeEach(() => { + $sandbox.stub(ControllerService, 'getFogTypes').returns($response); + }); + + it('calls ControllerService.getFogTypes with correct args', async () => { + await $subject; + expect(ControllerService.getFogTypes).to.have.been.calledWith(false); + }); + + context('when ControllerService#getFogTypes fails', () => { + const error = 'Error!'; + + def('response', () => Promise.reject(error)); + + it(`fails with "${error}"`, () => { + return expect($subject).to.be.rejectedWith(error) + }) + }); + + context('when ControllerService#getFogTypes succeeds', () => { + it(`succeeds`, () => { + return expect($subject).to.eventually.equal(undefined) + }) + }) + }); + +}); \ No newline at end of file From 076f96b4a39e57c916206273bfc936e5d1d741e5 Mon Sep 17 00:00:00 2001 From: alexandershpak <35569337+alexandershpak@users.noreply.github.com> Date: Fri, 14 Dec 2018 17:36:26 +0300 Subject: [PATCH 7/7] bug(fix) CLI diagnostics ftp: Incorrect error message is displayed when user try to get strace-info (EWC-431) --- src/services/diagnostic-service.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/services/diagnostic-service.js b/src/services/diagnostic-service.js index 741f122f4..474db7797 100644 --- a/src/services/diagnostic-service.js +++ b/src/services/diagnostic-service.js @@ -80,6 +80,11 @@ const getMicroserviceStraceData = async function (id, data, user, isCLI, transac const postMicroserviceStraceDatatoFtp = async function (id, data, user, isCLI, transaction) { await Validator.validate(data, Validator.schemas.stracePostToFtp); const straceData = await StraceDiagnosticManager.findOne({microserviceUuid: id}, transaction); + + if (!straceData) { + throw new Errors.NotFoundError(AppHelper.formatMessage(ErrorMessages.INVALID_MICROSERVICE_STRACE, id)) + } + const dir = config.get('Diagnostics:DiagnosticDir'); const filePath = dir + '/' + id;