From 0614ffe8d06db74bb0d029a92bd64d72ddf87882 Mon Sep 17 00:00:00 2001 From: Eli Golderg Date: Mon, 13 Aug 2018 15:25:30 +0300 Subject: [PATCH] Integration tests (#37) --- .eslintrc | 7 +++- .travis.yml | 6 +++ package.json | 5 ++- test/integration/request.test.js | 70 ++++++++++++++++++++++++++++++++ test/{ => unit}/aspect.test.js | 11 ++++- test/utils/http.js | 21 ++++++++++ test/utils/zipkinQuery.js | 17 ++++++++ 7 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 test/integration/request.test.js rename test/{ => unit}/aspect.test.js (85%) create mode 100644 test/utils/http.js create mode 100644 test/utils/zipkinQuery.js diff --git a/.eslintrc b/.eslintrc index eff93f7..03ee606 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,10 +1,13 @@ { "extends": "strongloop", "env": { - "node": true + "node": true, + "es6": true }, - "parserOptions": { "ecmaVersion": 6 }, + "parserOptions": { "ecmaVersion": 9 }, "globals": { + "before": true, + "after": true, "describe": true, "it": true, "xit": true diff --git a/.travis.yml b/.travis.yml index 2d98ccc..823ee3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,3 +3,9 @@ node_js: - "8" - "6" - "node" +sudo: required +services: + - docker +before_install: + - docker run -d -p 9411:9411 openzipkin/zipkin + - while netstat -lnt | awk '$4 ~ /:9411$/ {exit 1}'; do sleep 10; done diff --git a/package.json b/package.json index 5939ac6..0f5fcbe 100755 --- a/package.json +++ b/package.json @@ -15,11 +15,14 @@ "eslint": "^3.14.1", "eslint-config-strongloop": "^2.1.0", "mocha": "^5.2.0", + "request-promise-native": "1.0.5", "sinon": "^6.1.3", "tap": "^10.0.1" }, "scripts": { - "test": "mocha test/", + "test": "npm run test:unit && npm run test:integration", + "test:unit": "mocha test/unit/", + "test:integration": "mocha -t 3000 test/integration/", "pretest": "eslint .", "pretravis": "eslint .", "travis": "" diff --git a/test/integration/request.test.js b/test/integration/request.test.js new file mode 100644 index 0000000..ce53109 --- /dev/null +++ b/test/integration/request.test.js @@ -0,0 +1,70 @@ +'use strict'; + +const { expect } = require('chai'); + +const { request, createServer } = require('../utils/http'); +const { getTraces } = require('../utils/zipkinQuery'); + +const zipkinHost = '127.0.0.1'; +const zipkinPort = 9411; +const zipkinSampleRate = 1.0; +const serviceName = 'frontend'; + +function waitAndGetTraces() { + return new Promise(resolve => { + setTimeout(() => { // We want to let all background requests going to zipkin complete + resolve(getTraces({ zipkinHost, zipkinPort, serviceName })); + }, 1000); + }); +} + +describe('http requests', () => { + describe('outbound requests', () => { + let server; + let http; + + before(() => { + require('../../')({ + host: zipkinHost, + port: zipkinPort, + sampleRate: zipkinSampleRate, + serviceName + }); + + http = require('http'); + return createServer({ http, port: 3000 }) + .then(createdServer => { + server = createdServer; + }); + }); + after(() => { + if (server) server.close(); + }); + it('should reach zipkin with a simple http request (string options)', () => { + let outgoingTraceId; + return request({ http, options: 'http://localhost:3000' }) + .then(({ request }) => { + const outgoingHeaders = request._headers; + outgoingTraceId = outgoingHeaders['x-b3-traceid']; + }) + .then(waitAndGetTraces) + .then((traces) => { + expect(traces.length > 0).to.be.ok; + expect(traces.some(trace => trace[0].traceId === outgoingTraceId)).to.be.ok; + }); + }); + it('should reach zipkin with a simple http request (object options)', () => { + let outgoingTraceId; + return request({ http, options: { hostname: 'localhost', port: 3000 } }) + .then(({ request }) => { + const outgoingHeaders = request._headers; + outgoingTraceId = outgoingHeaders['x-b3-traceid']; + }) + .then(waitAndGetTraces) + .then((traces) => { + expect(traces.length > 0).to.be.ok; + expect(traces.some(trace => trace[0].traceId === outgoingTraceId)).to.be.ok; + }); + }); + }); +}); diff --git a/test/aspect.test.js b/test/unit/aspect.test.js similarity index 85% rename from test/aspect.test.js rename to test/unit/aspect.test.js index af875d5..e75ebc4 100644 --- a/test/aspect.test.js +++ b/test/unit/aspect.test.js @@ -2,7 +2,7 @@ const { expect } = require('chai'); const { stub } = require('sinon'); -const { before, after, around, findCallbackArg, aroundCallback } = require('../lib/aspect'); +const { before, after, around, findCallbackArg, aroundCallback } = require('../../lib/aspect'); describe('aspect', () => { describe('before', () => { it('should call hook before target method', () => { @@ -13,6 +13,15 @@ describe('aspect', () => { testObj.a(); expect(hookStub.calledBefore(origStub)).to.be.ok; }); + it('should pass original arguments', () => { + const origStub = stub(); + const hookStub = stub(); + const testObj = { a: origStub }; + before(testObj, ['a'], hookStub); + const testString = 'This is a test string'; + testObj.a(testString); + expect(origStub.calledWith(testString)).to.be.ok; + }); }); describe('after', () => { it('should call hook after target method', () => { diff --git a/test/utils/http.js b/test/utils/http.js new file mode 100644 index 0000000..9c4c27c --- /dev/null +++ b/test/utils/http.js @@ -0,0 +1,21 @@ +'use strict'; + +module.exports.request = ({ http, options }) => { + return new Promise(resolve => { + http.get(options, (res) => { + resolve({ request: res.req, response: res }); + }); + }); +}; + +module.exports.createServer = ({ http, port }) => { + return new Promise((resolve) => { + let server = http.createServer(function(req, res) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Hello World\n'); + }); + server.listen(port, function() { + resolve(server); + }); + }); +}; diff --git a/test/utils/zipkinQuery.js b/test/utils/zipkinQuery.js new file mode 100644 index 0000000..0af1f1d --- /dev/null +++ b/test/utils/zipkinQuery.js @@ -0,0 +1,17 @@ +'use strict'; + +const request = require('request-promise-native'); + +const url = ({ zipkinHost, zipkinPort }) => `http://${zipkinHost}:${zipkinPort}`; + +module.exports.getTraces = ({ zipkinHost, zipkinPort, serviceName }) => { + const zipkinUrl = url({ zipkinHost, zipkinPort }); + return request({ + url: `${zipkinUrl}/api/v2/traces`, + qs: { + serviceName + }, + json: true + }); +}; +