From f8cab3eebdcee288332e16bda5bd6b2fa17e02ac Mon Sep 17 00:00:00 2001 From: Alex Shatov Date: Fri, 6 Apr 2018 12:41:29 -0400 Subject: 4.4.1 deployment-handler -unit tests 84% coverage - more logging on metrics - log both req and res - unit tests of policy-update API - log timing and messaging in unit tests - code coverage 84.28% Statements 938/1113 65.51% Branches 321/490 81.58% Functions 155/190 84.34% Lines 926/1098 Change-Id: I3587135ceac76b291f83753441421a917a8b8bdf Signed-off-by: Alex Shatov Issue-ID: DCAEGEN2-258 --- lib/policy.js | 2 +- lib/promise_request.js | 6 +- package.json | 2 +- pom.xml | 2 +- tests/mock_utils.js | 11 + tests/test_dcae-deployments.js | 201 ++++++++++++----- tests/test_info.js | 8 +- tests/test_policy.js | 474 +++++++++++++++++++++++++++++++++++------ version.properties | 2 +- 9 files changed, 577 insertions(+), 131 deletions(-) diff --git a/lib/policy.js b/lib/policy.js index d471cff..7c47dd3 100644 --- a/lib/policy.js +++ b/lib/policy.js @@ -26,7 +26,7 @@ const config = process.mainModule.exports.config; const createError = require('./dispatcher-error').createDispatcherError; const logger = require('./logging').getLogger(); -var cloudify = require("./cloudify.js"); +const cloudify = require("./cloudify.js"); // Set config for cloudify interface library cloudify.setAPIAddress(config.cloudify.url); diff --git a/lib/promise_request.js b/lib/promise_request.js index 68e8c2f..c34227d 100644 --- a/lib/promise_request.js +++ b/lib/promise_request.js @@ -113,16 +113,18 @@ exports.doRequest = function(mainReq, options, body, targetEntity) { } opInfo.respCode = resp.statusCode || 500; + const metrics_text = "res: " + result.body + + ((reqBody && " req: " + ((typeof(reqBody) !== 'string' && typeof(reqBody)) || reqBody)) || ""); if (resp.statusCode > 199 && resp.statusCode < 300) { // HTTP status code indicates success - resolve the promise opInfo.complete = true; - logger.metrics(mainReq, opInfo, result.body); + logger.metrics(mainReq, opInfo, metrics_text); resolve(result); } else { // Reject the promise opInfo.complete = false; - logger.metrics(mainReq, opInfo, result.body); + logger.metrics(mainReq, opInfo, metrics_text); reject(result); } diff --git a/package.json b/package.json index 1752374..9a11f49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "onap-dcae-deployment-handler", - "version": "4.4.0", + "version": "4.4.1", "description": "ONAP DCAE Deployment Handler", "main": "deployment-handler.js", "dependencies": { diff --git a/pom.xml b/pom.xml index 5c13022..7c6c7ca 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property. org.onap.dcaegen2.platform deployment-handler dcaegen2-platform-deployment-handler - 2.1.0-SNAPSHOT + 2.1.1-SNAPSHOT http://maven.apache.org UTF-8 diff --git a/tests/mock_utils.js b/tests/mock_utils.js index 2d7d2e5..311e9dc 100644 --- a/tests/mock_utils.js +++ b/tests/mock_utils.js @@ -23,3 +23,14 @@ module.exports.sleep = function(time) { resolve(); }, time)); }; + +module.exports.ActionTimer = class ActionTimer { + constructor() { + this.started = Date.now(); + } + get step() { + let num = Date.now() - this.started; + return ("000000" + num).slice(-Math.max(5, (""+num).length)); + } +}; + diff --git a/tests/test_dcae-deployments.js b/tests/test_dcae-deployments.js index 2aca4c7..ae95e06 100644 --- a/tests/test_dcae-deployments.js +++ b/tests/test_dcae-deployments.js @@ -195,14 +195,20 @@ function test_get_dcae_deployments(dh_server) { const req_path = "/dcae-deployments"; const test_txt = "GET " + req_path; describe(test_txt, () => { - console.log(test_txt); it('GET all the dcae-deployments from inventory', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + const inv_resp = Inventory.resp_services(EXISTING_DEPLOYMENT_ID); - nock(dh.INVENTORY_URL).get(INV_PATH_DCAE_SERVICES).reply(200, inv_resp); + nock(dh.INVENTORY_URL).get(INV_PATH_DCAE_SERVICES) + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.INVENTORY_URL, uri); + return JSON.stringify(inv_resp); + }); return chai.request(dh_server.app).get(req_path) .then(function(res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(200); expect(res).to.be.json; @@ -215,7 +221,7 @@ function test_get_dcae_deployments(dh_server) { new RegExp("^http:[/][/]127.0.0.1:[0-9]+[/]dcae-deployments[/]" + EXISTING_DEPLOYMENT_ID)); }) .catch(function(err) { - console.error("err for", test_txt, err); + console.error(action_timer.step, "err for", test_txt, err); throw err; }); }); @@ -226,14 +232,19 @@ function test_get_dcae_deployments_service_type_unknown(dh_server) { const req_path = "/dcae-deployments?serviceTypeId=" + I_DONT_KNOW; const test_txt = "GET " + req_path; describe(test_txt, () => { - console.log(test_txt); it('GET nothing for unknown service-type from inventory', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); nock(dh.INVENTORY_URL).get(INV_PATH_DCAE_SERVICES + INV_PARAM_TYPE_ID + I_DONT_KNOW) - .reply(200, Inventory.resp_empty); + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.INVENTORY_URL, uri); + return JSON.stringify(Inventory.resp_empty); + } + ); return chai.request(dh_server.app).get(req_path) .then(function(res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(200); expect(res).to.be.json; @@ -243,7 +254,7 @@ function test_get_dcae_deployments_service_type_unknown(dh_server) { assert.lengthOf(res.body.deployments, 0); }) .catch(function(err) { - console.error("err for", test_txt, err); + console.error(action_timer.step, "err for", test_txt, err); throw err; }); }); @@ -267,18 +278,25 @@ function test_put_dcae_deployments_i_dont_know(dh_server) { const message = create_main_message(I_DONT_KNOW); const test_txt = "PUT " + req_path + ": " + JSON.stringify(message); describe(test_txt, () => { - console.log(test_txt); it('Fail to deploy i-dont-know service', function(done) { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); nock(dh.INVENTORY_URL).get(INV_PATH_DCAE_SERVICES + "/" + I_DONT_KNOW) - .reply(404, Inventory.resp_not_found_service(I_DONT_KNOW)); + .reply(404, function(uri) { + console.log(action_timer.step, "get", dh.INVENTORY_URL, uri); + return JSON.stringify(Inventory.resp_not_found_service(I_DONT_KNOW)); + }); nock(dh.INVENTORY_URL).get(INV_PATH_DCAE_SERVICE_TYPES + I_DONT_KNOW) - .reply(404, " Error 404 Not Found "); + .reply(404, function(uri) { + console.log(action_timer.step, "get", dh.INVENTORY_URL, uri); + return " Error 404 Not Found "; + }); chai.request(dh_server.app).put(req_path) .set('content-type', 'application/json') .send(message) .end(function(err, res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(404); expect(res.body).to.have.property('message'); expect(res.body.message).to.be.equal("No service type with ID " + I_DONT_KNOW); @@ -293,19 +311,36 @@ function test_put_dcae_deployments_missing_input_error(dh_server) { const message = create_main_message(INV_EXISTING_SERVICE_TYPE); const test_txt = "PUT " + req_path + ": " + JSON.stringify(message); describe(test_txt, () => { - console.log(test_txt); it('Fail to deploy service - missing_input', function(done) { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + nock(dh.INVENTORY_URL).get(INV_PATH_DCAE_SERVICES + "/" + DEPLOYMENT_ID_JFL) - .reply(404, Inventory.resp_not_found_service(DEPLOYMENT_ID_JFL)); + .reply(404, function(uri) { + console.log(action_timer.step, "get", dh.INVENTORY_URL, uri); + return JSON.stringify(Inventory.resp_not_found_service(DEPLOYMENT_ID_JFL)); + }); nock(dh.INVENTORY_URL).get(INV_PATH_DCAE_SERVICE_TYPES + INV_EXISTING_SERVICE_TYPE) - .reply(200, Inventory.resp_existing_blueprint(INV_EXISTING_SERVICE_TYPE)); + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.INVENTORY_URL, uri); + return JSON.stringify(Inventory.resp_existing_blueprint(INV_EXISTING_SERVICE_TYPE)); + }); nock(dh.INVENTORY_URL).put(INV_PATH_DCAE_SERVICES + "/" + DEPLOYMENT_ID_JFL) - .reply(200, Inventory.resp_put_service(DEPLOYMENT_ID_JFL, INV_EXISTING_SERVICE_TYPE)); + .reply(200, function(uri, requestBody) { + console.log(action_timer.step, "put", dh.INVENTORY_URL, uri, JSON.stringify(requestBody)); + return JSON.stringify(Inventory.resp_put_service(DEPLOYMENT_ID_JFL, INV_EXISTING_SERVICE_TYPE)); + }); nock(dh.INVENTORY_URL).delete(INV_PATH_DCAE_SERVICES + "/" + DEPLOYMENT_ID_JFL) - .reply(200); + .reply(200, function(uri) { + console.log(action_timer.step, "delete", dh.INVENTORY_URL, uri); + return ""; + }); nock(dh.CLOUDIFY_URL).put("/api/v2.1/blueprints/" + DEPLOYMENT_ID_JFL) - .reply(200, Cloudify.resp_blueprint(DEPLOYMENT_ID_JFL)); + .reply(200, function(uri, requestBody) { + console.log(action_timer.step, "put", dh.CLOUDIFY_URL, uri, JSON.stringify(requestBody)); + return JSON.stringify(Cloudify.resp_blueprint(DEPLOYMENT_ID_JFL)); + }); const depl_rejected = { "message": "Required inputs blah...", @@ -313,13 +348,16 @@ function test_put_dcae_deployments_missing_input_error(dh_server) { "server_traceback": "Traceback blah..." }; nock(dh.CLOUDIFY_URL).put("/api/v2.1/deployments/" + DEPLOYMENT_ID_JFL) - .reply(400, depl_rejected); + .reply(400, function(uri) { + console.log(action_timer.step, "put", dh.CLOUDIFY_URL, uri); + return JSON.stringify(depl_rejected); + }); chai.request(dh_server.app).put(req_path) .set('content-type', 'application/json') .send(message) .end(function(err, res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(400); expect(res.body).to.have.property('message'); expect(res.body.message).to.be.equal("Status 400 from CM API -- error code: " + depl_rejected.error_code + " -- message: " + depl_rejected.message); @@ -335,45 +373,71 @@ function test_put_dcae_deployments_success(dh_server) { const test_txt = "PUT " + req_path + ": " + JSON.stringify(message); const execution_id = "execution_" + DEPLOYMENT_ID_JFL_1; describe(test_txt, () => { - console.log(test_txt); it('Success deploy service', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + nock(dh.INVENTORY_URL).get(INV_PATH_DCAE_SERVICES + "/" + DEPLOYMENT_ID_JFL_1) - .reply(404, Inventory.resp_not_found_service(DEPLOYMENT_ID_JFL_1)); + .reply(404, function(uri) { + console.log(action_timer.step, "get", dh.INVENTORY_URL, uri); + return JSON.stringify(Inventory.resp_not_found_service(DEPLOYMENT_ID_JFL_1)); + }); nock(dh.INVENTORY_URL).get(INV_PATH_DCAE_SERVICE_TYPES + INV_EXISTING_SERVICE_TYPE) - .reply(200, Inventory.resp_existing_blueprint(INV_EXISTING_SERVICE_TYPE)); + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.INVENTORY_URL, uri); + return JSON.stringify(Inventory.resp_existing_blueprint(INV_EXISTING_SERVICE_TYPE)); + }); nock(dh.INVENTORY_URL).put(INV_PATH_DCAE_SERVICES + "/" + DEPLOYMENT_ID_JFL_1) - .reply(200, Inventory.resp_put_service(DEPLOYMENT_ID_JFL_1, INV_EXISTING_SERVICE_TYPE)); + .reply(200, function(uri, requestBody) { + console.log(action_timer.step, "put", dh.INVENTORY_URL, uri, JSON.stringify(requestBody)); + return JSON.stringify(Inventory.resp_put_service(DEPLOYMENT_ID_JFL_1, INV_EXISTING_SERVICE_TYPE)); + }); nock(dh.CLOUDIFY_URL).put("/api/v2.1/blueprints/" + DEPLOYMENT_ID_JFL_1) - .reply(200, Cloudify.resp_blueprint(DEPLOYMENT_ID_JFL_1)); + .reply(200, function(uri, requestBody) { + console.log(action_timer.step, "put", dh.CLOUDIFY_URL, uri, JSON.stringify(requestBody)); + return JSON.stringify(Cloudify.resp_blueprint(DEPLOYMENT_ID_JFL_1)); + }); nock(dh.CLOUDIFY_URL).put("/api/v2.1/deployments/" + DEPLOYMENT_ID_JFL_1) - .reply(201, Cloudify.resp_deploy(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, message.inputs)); + .reply(201, function(uri, requestBody) { + console.log(action_timer.step, "put", dh.CLOUDIFY_URL, uri, JSON.stringify(requestBody)); + return JSON.stringify(Cloudify.resp_deploy(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, message.inputs)); + }); - nock(dh.CLOUDIFY_URL).post("/api/v2.1/executions").reply(201, - Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, execution_id)); + nock(dh.CLOUDIFY_URL).post("/api/v2.1/executions") + .reply(201, function(uri, requestBody) { + console.log(action_timer.step, "post", dh.CLOUDIFY_URL, uri, JSON.stringify(requestBody)); + return JSON.stringify(Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, execution_id)); + }); - nock(dh.CLOUDIFY_URL).get("/api/v2.1/executions/" + execution_id).reply(200, - Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, execution_id, true)); + nock(dh.CLOUDIFY_URL).get("/api/v2.1/executions/" + execution_id) + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.CLOUDIFY_URL, uri); + return JSON.stringify(Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, execution_id, true)); + }); nock(dh.CLOUDIFY_URL).get("/api/v2.1/deployments/" + DEPLOYMENT_ID_JFL_1 + "/outputs") - .reply(200, Cloudify.resp_outputs(DEPLOYMENT_ID_JFL_1)); + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.CLOUDIFY_URL, uri); + return JSON.stringify(Cloudify.resp_outputs(DEPLOYMENT_ID_JFL_1)); + }); return chai.request(dh_server.app).put(req_path) .set('content-type', 'application/json') .send(message) .then(function(res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(202); expect(res).to.be.json; return utils.sleep(10000); }) .then(function() { - console.log("the end of test"); + console.log(action_timer.step, "the end of test"); }) .catch(function(err) { - console.error("err for", test_txt, err); + console.error(action_timer.step, "err for", test_txt, err); throw err; }); }).timeout(50000); @@ -385,19 +449,23 @@ function test_get_dcae_deployments_operation(dh_server) { const req_path = "/dcae-deployments/" + DEPLOYMENT_ID_JFL_1 + "/operation/" + execution_id; const test_txt = "GET " + req_path; describe(test_txt, () => { - console.log(test_txt); it('Get operation execution succeeded', function() { - nock(dh.CLOUDIFY_URL).get("/api/v2.1/executions/" + execution_id).reply(200, - Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, execution_id, true)); + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + nock(dh.CLOUDIFY_URL).get("/api/v2.1/executions/" + execution_id) + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.CLOUDIFY_URL, uri); + return JSON.stringify(Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, execution_id, true)); + }); return chai.request(dh_server.app).get(req_path) .then(function(res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(200); expect(res).to.be.json; }) .catch(function(err) { - console.error("err for", test_txt, err); + console.error(action_timer.step, "err for", test_txt, err); throw err; }); }); @@ -408,16 +476,20 @@ function test_get_dcae_deployments_service_type_deployed(dh_server) { const req_path = "/dcae-deployments?serviceTypeId=" + INV_EXISTING_SERVICE_TYPE; const test_txt = "GET " + req_path; describe(test_txt, () => { - console.log(test_txt); it('GET services=deployments of the service-type from inventory', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); const deployed_count = 10; nock(dh.INVENTORY_URL) .get(INV_PATH_DCAE_SERVICES + INV_PARAM_TYPE_ID + INV_EXISTING_SERVICE_TYPE) - .reply(200, Inventory.resp_services(DEPLOYMENT_ID_JFL_1, INV_EXISTING_SERVICE_TYPE, deployed_count)); + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.INVENTORY_URL, uri); + return JSON.stringify(Inventory.resp_services(DEPLOYMENT_ID_JFL_1, INV_EXISTING_SERVICE_TYPE, deployed_count)); + }); return chai.request(dh_server.app).get(req_path) .then(function(res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(200); expect(res).to.be.json; @@ -427,7 +499,7 @@ function test_get_dcae_deployments_service_type_deployed(dh_server) { assert.lengthOf(res.body.deployments, deployed_count); }) .catch(function(err) { - console.error("err for", test_txt, err); + console.error(action_timer.step, "err for", test_txt, err); throw err; }); }); @@ -440,38 +512,55 @@ function test_delete_dcae_deployments_success(dh_server) { const workflow_id = "uninstall"; const execution_id = workflow_id + "_" + DEPLOYMENT_ID_JFL_1; describe(test_txt, () => { - console.log(test_txt); it('Success DELETE service', function() { - nock(dh.CLOUDIFY_URL).post("/api/v2.1/executions").reply(201, - Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, - execution_id, false, workflow_id)); + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + + nock(dh.CLOUDIFY_URL).post("/api/v2.1/executions") + .reply(201, function(uri, requestBody) { + console.log(action_timer.step, "post", dh.CLOUDIFY_URL, uri, JSON.stringify(requestBody)); + return JSON.stringify(Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, + execution_id, false, workflow_id)); + }); nock(dh.INVENTORY_URL).delete(INV_PATH_DCAE_SERVICES + "/" + DEPLOYMENT_ID_JFL_1) - .reply(200); + .reply(200, function(uri) { + console.log(action_timer.step, "delete", dh.INVENTORY_URL, uri); + return ""; + }); - nock(dh.CLOUDIFY_URL).get("/api/v2.1/executions/" + execution_id).reply(200, - Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, - execution_id, true, workflow_id)); + nock(dh.CLOUDIFY_URL).get("/api/v2.1/executions/" + execution_id) + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.CLOUDIFY_URL, uri); + return JSON.stringify(Cloudify.resp_execution(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1, + execution_id, true, workflow_id)); + }); nock(dh.CLOUDIFY_URL).delete("/api/v2.1/deployments/" + DEPLOYMENT_ID_JFL_1) - .reply(201, Cloudify.resp_deploy(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1)); + .reply(201, function(uri) { + console.log(action_timer.step, "delete", dh.CLOUDIFY_URL, uri); + return JSON.stringify(Cloudify.resp_deploy(DEPLOYMENT_ID_JFL_1, DEPLOYMENT_ID_JFL_1)); + }); nock(dh.CLOUDIFY_URL).delete("/api/v2.1/blueprints/" + DEPLOYMENT_ID_JFL_1) - .reply(200, Cloudify.resp_blueprint(DEPLOYMENT_ID_JFL_1)); + .reply(200, function(uri) { + console.log(action_timer.step, "delete", dh.CLOUDIFY_URL, uri); + return JSON.stringify(Cloudify.resp_blueprint(DEPLOYMENT_ID_JFL_1)); + }); return chai.request(dh_server.app).delete(req_path) .then(function(res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(202); expect(res).to.be.json; return utils.sleep(45000); }) .then(function() { - console.log("the end of test"); + console.log(action_timer.step, "the end of test"); }) .catch(function(err) { - console.error("err for", test_txt, err); + console.error(action_timer.step, "err for", test_txt, err); throw err; }); }).timeout(60000); diff --git a/tests/test_info.js b/tests/test_info.js index b2f8a91..1156d59 100644 --- a/tests/test_info.js +++ b/tests/test_info.js @@ -28,16 +28,18 @@ const chai = require('chai') chai.use(chaiHttp); const dh = require('./mock_deployment_handler'); +const utils = require('./mock_utils'); function test_get_info(dh_server) { const req_path = "/"; const test_txt = "GET " + req_path; describe(test_txt, () => { - console.log(test_txt); it('GET info', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); return chai.request(dh_server.app).get(req_path) .then(function(res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(200); expect(res).to.be.json; @@ -47,7 +49,7 @@ function test_get_info(dh_server) { assert.deepEqual(config.apiLinks, info.links); }) .catch(function(err) { - console.error("err for", test_txt, err); + console.error(action_timer.step, "err for", test_txt, err); throw err; }); }); diff --git a/tests/test_policy.js b/tests/test_policy.js index e32b2f6..86d6ab4 100644 --- a/tests/test_policy.js +++ b/tests/test_policy.js @@ -29,6 +29,7 @@ const nock = require('nock') chai.use(chaiHttp); const dh = require('./mock_deployment_handler'); +const utils = require('./mock_utils'); const RUN_TS = new Date(); const RUN_TS_HOURS = RUN_TS.getHours(); @@ -39,109 +40,450 @@ const POLICY_NAME = "policyName"; const POLICY_BODY = 'policy_body'; const POLICY_CONFIG = 'config'; -const MONKEYED_POLICY_ID = "DCAE_alex.Config_peach" -const MONKEYED_POLICY_ID_2 = "DCAE_alex.Config_peach_2" +const BLUEPRINT_ID = "demo_dcaepolicy"; +const DEPLOYMENT_ID = "demo_dcae_policy_depl"; +const OPERATION_POLICY_UPDATE = "dcae.interfaces.policy.policy_update"; +const EXECUTE_OPERATION = "execute_operation"; -function create_policy_body(policy_id, policy_version=1) { - const prev_ver = policy_version - 1; - const timestamp = new Date(RUN_TS.getTime()); - timestamp.setHours(RUN_TS_HOURS + prev_ver); +const MONKEYED_POLICY_ID = "DCAE_alex.Config_peach"; +const MONKEYED_POLICY_ID_2 = "DCAE_alex.Config_peach_2"; +const MONKEYED_POLICY_ID_3 = "DCAE_alex.Config_peach_3"; +const MONKEYED_POLICY_ID_4 = "DCAE_alex.Config_peach_4"; +const MONKEYED_POLICY_ID_5 = "DCAE_alex.Config_peach_5"; +const MONKEYED_POLICY_ID_6 = "DCAE_alex.Config_peach_6"; +const CLAMP_POLICY_ID = "CLAMP.Config_clamp_policy"; +const CFY_API = "/api/v2.1"; +const CFY_API_NODE_INSTANCES = CFY_API + "/node-instances"; +const CFY_API_EXECUTIONS = CFY_API + "/executions"; +const CFY_API_EXECUTION = CFY_API_EXECUTIONS + "/"; + +function create_policy_body(policy_id, policy_version=1, matching_conditions=null) { const this_ver = policy_version.toString(); - const config = { - "policy_updated_from_ver": prev_ver.toString(), - "policy_updated_to_ver": this_ver.toString(), - "policy_hello": "world!", - "policy_updated_ts": timestamp, - "updated_policy_id": policy_id + + const matchingConditions = { + "ONAPName": "DCAE", + "ConfigName": "alex_config_name" }; + if (matching_conditions) { + Object.assign(matchingConditions, matching_conditions); + } return { "policyConfigMessage": "Config Retrieved! ", "policyConfigStatus": "CONFIG_RETRIEVED", "type": "JSON", - POLICY_NAME: policy_id + "." + this_ver + ".xml", - POLICY_VERSION: this_ver, - POLICY_CONFIG: config, - "matchingConditions": { - "ONAPName": "DCAE", - "ConfigName": "alex_config_name" - }, + [POLICY_NAME]: (policy_id && (policy_id + "." + this_ver + ".xml") || null), + [POLICY_VERSION]: this_ver, + [POLICY_CONFIG]: {"policy_hello": "world!"}, + "matchingConditions": matchingConditions, "responseAttributes": {}, "property": null }; } -function create_policy(policy_id, policy_version=1) { +function create_policy(policy_id, policy_version=1, matching_conditions=null) { return { - POLICY_ID : policy_id, - POLICY_BODY : MonkeyedPolicyBody.create_policy_body(policy_id, policy_version) + [POLICY_ID] : policy_id, + [POLICY_BODY] : create_policy_body(policy_id, policy_version, matching_conditions) }; } -nock(dh.CLOUDIFY_URL).persist().get(/[/]api[/]v2[.]1[/]node-instances/) - .reply(200, { - "items": [ - { - "deployment_id": "demo_dcae_policy_depl", - "id": "host_vm_163f7", - "runtime_properties": { - "application_config": { - "capacity_ts": "2017-09-07T16:54:31.696Z", - "capacity": "123", - "policy_hello": "world!", - "policy_updated_ts": "2017-09-05T18:09:54.109548Z", - "policy_updated_from_ver": "20", - "location": "neverland", - "updated_policy_id": MONKEYED_POLICY_ID_2, - "policy_updated_to_ver": "21", - "location_ts": "2017-09-07T16:54:31.696Z" - }, - "execute_operation": "policy_update", - "service_component_name": "2caa5ccf-bfc6-4a75-aca7-4af03745f478.unknown.unknown.unknown.dcae.onap.org", - "exe_task": "node_configure", - "policies": { - "DCAE_alex.Config_host_location_policy_id_value": { - "policy_required": true, - "policy_body": create_policy_body(MONKEYED_POLICY_ID, 55), - "policy_id": MONKEYED_POLICY_ID - }, - "DCAE_alex.Config_host_capacity_policy_id_value": { - "policy_required": true, - "policy_body": create_policy_body(MONKEYED_POLICY_ID_2, 21), - "policy_id": MONKEYED_POLICY_ID_2 - } +const cloudify_node_instances = [ + { + "deployment_id": DEPLOYMENT_ID, + "id": "host_vm_163f7", + "runtime_properties": { + "application_config": { + "policy_hello": "world!", + "location": "neverland", + "location_ts": "2017-09-07T16:54:31.696Z" + }, + [EXECUTE_OPERATION]: "policy_update", + "service_component_name": "2caa5ccf-bfc6-4a75-aca7-4af03745f478.unknown.unknown.unknown.dcae.onap.org", + "exe_task": "node_configure", + "policies": { + [MONKEYED_POLICY_ID]: { + "policy_required": true, + "policy_persistent": true, + "policy_body": create_policy_body(MONKEYED_POLICY_ID, 55), + "policy_id": MONKEYED_POLICY_ID + }, + [MONKEYED_POLICY_ID_2]: { + "policy_persistent": false, + "policy_body": create_policy_body(MONKEYED_POLICY_ID_2, 21, {"key1": "value1"}), + "policy_id": MONKEYED_POLICY_ID_2 + }, + [MONKEYED_POLICY_ID_3]: { + "policy_persistent": false, + "policy_body": create_policy_body(MONKEYED_POLICY_ID_3, 33, {"service": "alex_service"}), + "policy_id": MONKEYED_POLICY_ID_3 + }, + [MONKEYED_POLICY_ID_5]: { + "policy_persistent": false, + "policy_body": create_policy_body(MONKEYED_POLICY_ID_5, 1), + "policy_id": MONKEYED_POLICY_ID_5 + }, + [CLAMP_POLICY_ID]: { + "policy_persistent": false, + "policy_body": create_policy_body(CLAMP_POLICY_ID, 9), + "policy_id": CLAMP_POLICY_ID + } + }, + "policy_filters": { + "db_client_policies_c83de": { + "policy_filter_id": "db_client_policies_c83de", + "policy_filter": { + "policyName": MONKEYED_POLICY_ID_2 + ".*", + "unique": false, + "onapName": "DCAE", + "configName": "alex_config_name", + "configAttributes": {"key1": "value1"} + } + }, + "db_client_policies_microservice_09f09": { + "policy_filter_id": "db_client_policies_microservice_09f09", + "policy_filter": { + "policyName": MONKEYED_POLICY_ID + ".*", + "unique": false, + "onapName": "DCAE", + "configName": "alex_config_name", + "configAttributes": {"service": "alex_service"} + } + }, + "policy_filter_by_id_02d02": { + "policy_filter_id": "policy_filter_by_id_02d02", + "policy_filter": { + "policyName": MONKEYED_POLICY_ID_6 + } + }, + "new_policies_09f09": { + "policy_filter_id": "new_policies_09f09", + "policy_filter": { + "policyName": MONKEYED_POLICY_ID_4 + ".*", + "unique": false, + "onapName": "DCAE", + "configName": "alex_config_name", + "configAttributes": {"service": "alex_service"} + } + }, + "db_client_policies_not_found_cfed6": { + "policy_filter_id": "db_client_policies_not_found_cfed6", + "policy_filter": { + "configAttributes": {"not-to-be-found": "ever"}, + "unique": false, + "onapName": "DCAE", + "policyName": "DCAE_alex.Config_not_found_ever_.*" + } + }, + "filter_without_policy_name_22abcd": { + "policy_filter_id": "filter_without_policy_name", + "policy_filter": {"onapName": "DCAE"} + }, + "db_client_policies_no_match_afed8": { + "policy_filter_id": "db_client_policies_no_match_afed8", + "policy_filter": { + "policyName": "DCAE_alex.Config_not_found_ever_.*" } } } - ], - "metadata": { - "pagination": { - "total": 1, - "offset": 0, - "size": 10000 - } + } + }, + { + "deployment_id": DEPLOYMENT_ID, + "id": "no_policies_on_node_1212beef", + "runtime_properties": {"application_config": {}} + }, + { + "deployment_id": DEPLOYMENT_ID, + "id": "no_policy_filters_on_node_55ham", + "runtime_properties": { + "application_config": {}, + "policies": {} } } -); +]; + +function nock_cfy_node_instances(action_timer) { + nock(dh.CLOUDIFY_URL).get(CFY_API_NODE_INSTANCES).query(true) + .reply(200, function(uri) { + console.log(action_timer.step, "get", dh.CLOUDIFY_URL, uri); + return JSON.stringify({ + "items": cloudify_node_instances, + "metadata": {"pagination": {"total": cloudify_node_instances.length, "offset": 0, "size": 10000}} + }); + }); +} function test_get_policy_components(dh_server) { const req_path = "/policy/components"; const test_txt = "GET " + req_path; describe(test_txt, () => { - console.log(test_txt); it('GET all the components with policy from cloudify', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + nock_cfy_node_instances(action_timer); + return chai.request(dh_server.app).get(req_path) .then(function(res) { - console.log("res for", test_txt, res.text); + console.log(action_timer.step, "res for", test_txt, res.text); expect(res).to.have.status(200); expect(res).to.be.json; }) .catch(function(err) { - console.error("err for", test_txt, err); + console.error(action_timer.step, "err for", test_txt, err); throw err; }); }); }); } -dh.add_tests([test_get_policy_components]); +function test_post_policy_catch_up(dh_server) { + const req_path = "/policy"; + const message = { + "errored_scopes": ["CLAMP.Config_"], + "catch_up": true, + "scope_prefixes": ["DCAE_alex.Config_", "DCAE.Config_"], + "errored_policies": {}, + "latest_policies": { + [MONKEYED_POLICY_ID]: create_policy(MONKEYED_POLICY_ID, 55), + [MONKEYED_POLICY_ID_2]: create_policy(MONKEYED_POLICY_ID_2, 22, {"key1": "value1"}), + [MONKEYED_POLICY_ID_4]: create_policy(MONKEYED_POLICY_ID_4, 77, {"service": "alex_service"}), + [MONKEYED_POLICY_ID_5]: create_policy(MONKEYED_POLICY_ID_5, "nan_version"), + [MONKEYED_POLICY_ID_6]: create_policy(MONKEYED_POLICY_ID_6, 66), + "junk_policy": create_policy("junk_policy", "nan_version"), + "fail_filtered": create_policy("fail_filtered", 12, {"ONAPName": "not-match"}), + "fail_filtered_2": create_policy("fail_filtered_2", 32, {"ConfigName": "not-match2"}), + "": create_policy("", 1) + } + }; + const test_txt = "POST " + req_path + " - catchup " + JSON.stringify(message); + describe(test_txt, () => { + it('POST policy-update - catchup', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + const execution_id = "policy_catch_up"; + const resp_to_exe = {"status": "none"}; + nock_cfy_node_instances(action_timer); + + nock(dh.CLOUDIFY_URL).post(CFY_API_EXECUTIONS) + .reply(201, function(uri, requestBody) { + requestBody = JSON.stringify(requestBody); + console.log(action_timer.step, "on_post", dh.CLOUDIFY_URL, uri, requestBody); + Object.assign(resp_to_exe, JSON.parse(requestBody)); + resp_to_exe.status = "pending"; + resp_to_exe.created_at = RUN_TS; + resp_to_exe.workflow_id = EXECUTE_OPERATION; + resp_to_exe.is_system_workflow = false; + resp_to_exe.blueprint_id = BLUEPRINT_ID; + resp_to_exe.error = ""; + resp_to_exe.id = execution_id; + resp_to_exe.parameters.run_by_dependency_order = false; + resp_to_exe.parameters.operation = OPERATION_POLICY_UPDATE; + resp_to_exe.parameters.type_names = []; + + console.log(action_timer.step, "reply to post", dh.CLOUDIFY_URL, uri, JSON.stringify(resp_to_exe)); + + return JSON.stringify(resp_to_exe); + }); + + nock(dh.CLOUDIFY_URL).get(CFY_API_EXECUTION + execution_id) + .reply(200, function(uri) { + resp_to_exe.status = "pending"; + console.log(action_timer.step, "get", dh.CLOUDIFY_URL, uri, JSON.stringify(resp_to_exe)); + return JSON.stringify(resp_to_exe); + }); + nock(dh.CLOUDIFY_URL).get(CFY_API_EXECUTION + execution_id) + .times(2) + .reply(200, function(uri) { + resp_to_exe.status = "started"; + console.log(action_timer.step, "get", dh.CLOUDIFY_URL, uri, JSON.stringify(resp_to_exe)); + return JSON.stringify(resp_to_exe); + }); + nock(dh.CLOUDIFY_URL).get(CFY_API_EXECUTION + execution_id) + .reply(200, function(uri) { + resp_to_exe.status = "terminated"; + console.log(action_timer.step, "get", dh.CLOUDIFY_URL, uri, JSON.stringify(resp_to_exe)); + return JSON.stringify(resp_to_exe); + }); + + return chai.request(dh_server.app).post(req_path) + .set('content-type', 'application/json') + .set('X-ECOMP-RequestID', 'test_post_policy_catch_up') + .send(message) + .then(function(res) { + console.log(action_timer.step, "res for", test_txt, res.text); + expect(res).to.have.status(200); + expect(res).to.be.json; + + return utils.sleep(25000); + }) + .then(function() { + console.log(action_timer.step, "the end of test"); + }) + .catch(function(err) { + console.error(action_timer.step, "err for", test_txt, err); + throw err; + }); + }).timeout(30000); + }); +} + +function test_fail_cfy_policy_catch_up(dh_server) { + const req_path = "/policy"; + const message = { + "errored_scopes": [], + "catch_up": true, + "scope_prefixes": ["DCAE_alex.Config_", "DCAE.Config_"], + "errored_policies": {}, + "latest_policies": { + [MONKEYED_POLICY_ID_6]: create_policy(MONKEYED_POLICY_ID_6, 66) + } + }; + const test_txt = "fail POST " + req_path + " - catchup without execution_id " + JSON.stringify(message); + describe(test_txt, () => { + it('fail POST policy-update - catchup without execution_id', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + const execution_id = "policy_catch_up"; + const resp_to_exe = {"status": "none"}; + nock_cfy_node_instances(action_timer); + + nock(dh.CLOUDIFY_URL).post(CFY_API_EXECUTIONS) + .reply(201, function(uri, requestBody) { + requestBody = JSON.stringify(requestBody); + console.log(action_timer.step, "on_post", dh.CLOUDIFY_URL, uri, requestBody); + Object.assign(resp_to_exe, JSON.parse(requestBody)); + resp_to_exe.status = "pending"; + + console.log(action_timer.step, "reply to post", dh.CLOUDIFY_URL, uri, JSON.stringify(resp_to_exe)); + + return JSON.stringify(resp_to_exe); + }); + + return chai.request(dh_server.app).post(req_path) + .set('content-type', 'application/json') + .set('X-ECOMP-RequestID', 'test_post_policy_catch_up') + .send(message) + .then(function(res) { + console.log(action_timer.step, "res for", test_txt, res.text); + expect(res).to.have.status(200); + expect(res).to.be.json; + + return utils.sleep(1000); + }) + .then(function() { + console.log(action_timer.step, "the end of test"); + }) + .catch(function(err) { + console.error(action_timer.step, "err for", test_txt, err); + throw err; + }); + }).timeout(30000); + }); +} + +function test_fail_400_cfy_policy_catch_up(dh_server) { + const req_path = "/policy"; + const message = { + "errored_scopes": [], + "catch_up": true, + "scope_prefixes": ["DCAE_alex.Config_", "DCAE.Config_"], + "errored_policies": {}, + "latest_policies": { + [MONKEYED_POLICY_ID_6]: create_policy(MONKEYED_POLICY_ID_6, 66) + } + }; + const test_txt = "fail 400 POST " + req_path + " - existing_running_execution_error " + JSON.stringify(message); + describe(test_txt, () => { + it('fail 400 POST policy-update - existing_running_execution_error', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + const execution_id = "policy_catch_up"; + const resp_to_exe = {"error_code": "existing_running_execution_error"}; + nock_cfy_node_instances(action_timer); + + nock(dh.CLOUDIFY_URL).post(CFY_API_EXECUTIONS).times(5) + .reply(400, function(uri, requestBody) { + console.log(action_timer.step, "on_post", dh.CLOUDIFY_URL, uri, JSON.stringify(requestBody)); + console.log(action_timer.step, "reply to post", dh.CLOUDIFY_URL, uri, JSON.stringify(resp_to_exe)); + return JSON.stringify(resp_to_exe); + }); + + return chai.request(dh_server.app).post(req_path) + .set('content-type', 'application/json') + .set('X-ECOMP-RequestID', 'test_post_policy_catch_up') + .send(message) + .then(function(res) { + console.log(action_timer.step, "res for", test_txt, res.text); + expect(res).to.have.status(200); + expect(res).to.be.json; + + return utils.sleep(25000); + }) + .then(function() { + console.log(action_timer.step, "the end of test"); + }) + .catch(function(err) { + console.error(action_timer.step, "err for", test_txt, err); + throw err; + }); + }).timeout(30000); + }); +} + +function test_fail_404_cfy_policy_catch_up(dh_server) { + const req_path = "/policy"; + const message = { + "errored_scopes": [], + "catch_up": true, + "scope_prefixes": ["DCAE_alex.Config_", "DCAE.Config_"], + "errored_policies": {}, + "latest_policies": { + [MONKEYED_POLICY_ID_6]: create_policy(MONKEYED_POLICY_ID_6, 66) + } + }; + const test_txt = "fail 404 POST " + req_path + " - not_found_error " + JSON.stringify(message); + describe(test_txt, () => { + it('fail 404 POST policy-update - not_found_error', function() { + const action_timer = new utils.ActionTimer(); + console.log(action_timer.step, test_txt); + const execution_id = "policy_catch_up"; + const resp_to_exe = {"error_code": "not_found_error"}; + nock_cfy_node_instances(action_timer); + + nock(dh.CLOUDIFY_URL).post(CFY_API_EXECUTIONS).times(5) + .reply(404, function(uri, requestBody) { + console.log(action_timer.step, "on_post", dh.CLOUDIFY_URL, uri, JSON.stringify(requestBody)); + console.log(action_timer.step, "reply to post", dh.CLOUDIFY_URL, uri, JSON.stringify(resp_to_exe)); + return JSON.stringify(resp_to_exe); + }); + + return chai.request(dh_server.app).post(req_path) + .set('content-type', 'application/json') + .set('X-ECOMP-RequestID', 'test_post_policy_catch_up') + .send(message) + .then(function(res) { + console.log(action_timer.step, "res for", test_txt, res.text); + expect(res).to.have.status(200); + expect(res).to.be.json; + + return utils.sleep(1000); + }) + .then(function() { + console.log(action_timer.step, "the end of test"); + }) + .catch(function(err) { + console.error(action_timer.step, "err for", test_txt, err); + throw err; + }); + }).timeout(30000); + }); +} + +dh.add_tests([ + test_get_policy_components, + test_post_policy_catch_up, + test_fail_cfy_policy_catch_up, + test_fail_400_cfy_policy_catch_up, + test_fail_404_cfy_policy_catch_up +]); diff --git a/version.properties b/version.properties index 91dd40e..607bf2c 100644 --- a/version.properties +++ b/version.properties @@ -1,6 +1,6 @@ major=2 minor=1 -patch=0 +patch=1 base_version=${major}.${minor}.${patch} release_version=${base_version} snapshot_version=${base_version}-SNAPSHOT -- cgit 1.2.3-korg