From fd4cec31e7473d53ffa6a8650b341e7dec49a2cf Mon Sep 17 00:00:00 2001 From: Pagan Gazzard Date: Tue, 31 Mar 2020 16:25:57 +0100 Subject: [PATCH] Convert test/12-logger.spec.coffee to javascript Change-type: patch --- test/12-logger.spec.coffee | 116 ----------------------------- test/12-logger.spec.js | 148 +++++++++++++++++++++++++++++++++++++ tsconfig.js.json | 2 +- tsconfig.json | 2 +- tsconfig.release.json | 2 +- 5 files changed, 151 insertions(+), 119 deletions(-) delete mode 100644 test/12-logger.spec.coffee create mode 100644 test/12-logger.spec.js diff --git a/test/12-logger.spec.coffee b/test/12-logger.spec.coffee deleted file mode 100644 index e598e594..00000000 --- a/test/12-logger.spec.coffee +++ /dev/null @@ -1,116 +0,0 @@ -https = require 'https' -stream = require 'stream' -zlib = require 'zlib' - -Promise = require 'bluebird' -{ expect } = require './lib/chai-config' -sinon = require 'sinon' -{ stub } = sinon - -{ Logger } = require '../src/logger' -{ ContainerLogs } = require '../src/logging/container' -describe 'Logger', -> - beforeEach -> - @_req = new stream.PassThrough() - @_req.flushHeaders = sinon.spy() - @_req.end = sinon.spy() - - @_req.body = '' - @_req - .pipe(zlib.createGunzip()) - .on 'data', (chunk) => - @_req.body += chunk - - stub(https, 'request').returns(@_req) - - @fakeEventTracker = { - track: sinon.spy() - } - - @logger = new Logger({ eventTracker: @fakeEventTracker }) - @logger.init({ - apiEndpoint: 'https://example.com' - uuid: 'deadbeef' - deviceApiKey: 'secretkey' - unmanaged: false - enableLogs: true - localMode: false - }) - - afterEach -> - https.request.restore() - - it 'waits the grace period before sending any logs', -> - clock = sinon.useFakeTimers() - @logger.log({ message: 'foobar', serviceId: 15 }) - clock.tick(4999) - clock.restore() - - Promise.delay(100) - .then => - expect(@_req.body).to.equal('') - - it 'tears down the connection after inactivity', -> - clock = sinon.useFakeTimers() - @logger.log({ message: 'foobar', serviceId: 15 }) - clock.tick(61000) - clock.restore() - - Promise.delay(100) - .then => - expect(@_req.end.calledOnce).to.be.true - - - it 'sends logs as gzipped ndjson', -> - timestamp = Date.now() - @logger.log({ message: 'foobar', serviceId: 15 }) - @logger.log({ timestamp: 1337, message: 'foobar', serviceId: 15 }) - @logger.log({ message: 'foobar' }) # shold be ignored - - Promise.delay(5500).then => - expect(https.request.calledOnce).to.be.true - opts = https.request.firstCall.args[0] - - expect(opts.href).to.equal('https://example.com/device/v2/deadbeef/log-stream') - expect(opts.method).to.equal('POST') - expect(opts.headers).to.deep.equal({ - 'Authorization': 'Bearer secretkey' - 'Content-Type': 'application/x-ndjson' - 'Content-Encoding': 'gzip' - }) - - lines = @_req.body.split('\n') - expect(lines.length).to.equal(3) - expect(lines[2]).to.equal('') - - msg = JSON.parse(lines[0]) - expect(msg).to.have.property('message').that.equals('foobar') - expect(msg).to.have.property('serviceId').that.equals(15) - expect(msg).to.have.property('timestamp').that.is.at.least(timestamp) - msg = JSON.parse(lines[1]) - expect(msg).to.deep.equal({ timestamp: 1337, message: 'foobar', serviceId: 15 }) - - it 'allows logging system messages which are also reported to the eventTracker', -> - timestamp = Date.now() - @logger.logSystemMessage('Hello there!', { someProp: 'someVal' }, 'Some event name') - - Promise.delay(5500) - .then => - expect(@fakeEventTracker.track).to.be.calledWith('Some event name', { someProp: 'someVal' }) - lines = @_req.body.split('\n') - expect(lines.length).to.equal(2) - expect(lines[1]).to.equal('') - - msg = JSON.parse(lines[0]) - expect(msg).to.have.property('message').that.equals('Hello there!') - expect(msg).to.have.property('isSystem').that.equals(true) - expect(msg).to.have.property('timestamp').that.is.at.least(timestamp) - - it 'should support non-tty log lines', -> - message = '\u0001\u0000\u0000\u0000\u0000\u0000\u0000?2018-09-21T12:37:09.819134000Z this is the message' - buffer = Buffer.from(message) - - expect(ContainerLogs.extractMessage(buffer)).to.deep.equal({ - message: 'this is the message', - timestamp: 1537533429819 - }) diff --git a/test/12-logger.spec.js b/test/12-logger.spec.js new file mode 100644 index 00000000..8ec7a162 --- /dev/null +++ b/test/12-logger.spec.js @@ -0,0 +1,148 @@ +import * as https from 'https'; +import * as stream from 'stream'; +import * as zlib from 'zlib'; +import * as Promise from 'bluebird'; +import { expect } from './lib/chai-config'; +import * as sinon from 'sinon'; + +import { Logger } from '../src/logger'; +import { ContainerLogs } from '../src/logging/container'; +describe('Logger', function() { + beforeEach(function() { + this._req = new stream.PassThrough(); + this._req.flushHeaders = sinon.spy(); + this._req.end = sinon.spy(); + + this._req.body = ''; + this._req.pipe(zlib.createGunzip()).on('data', chunk => { + this._req.body += chunk; + }); + + this.requestStub = sinon.stub(https, 'request').returns(this._req); + + this.fakeEventTracker = { + track: sinon.spy(), + }; + + // @ts-ignore missing db property + this.logger = new Logger({ eventTracker: this.fakeEventTracker }); + return this.logger.init({ + apiEndpoint: 'https://example.com', + uuid: 'deadbeef', + deviceApiKey: 'secretkey', + unmanaged: false, + enableLogs: true, + localMode: false, + }); + }); + + afterEach(function() { + this.requestStub.restore(); + }); + + it('waits the grace period before sending any logs', function() { + const clock = sinon.useFakeTimers(); + this.logger.log({ message: 'foobar', serviceId: 15 }); + clock.tick(4999); + clock.restore(); + + return Promise.delay(100).then(() => { + expect(this._req.body).to.equal(''); + }); + }); + + it('tears down the connection after inactivity', function() { + const clock = sinon.useFakeTimers(); + this.logger.log({ message: 'foobar', serviceId: 15 }); + clock.tick(61000); + clock.restore(); + + return Promise.delay(100).then(() => { + expect(this._req.end.calledOnce).to.be.true; + }); + }); + + it('sends logs as gzipped ndjson', function() { + const timestamp = Date.now(); + this.logger.log({ message: 'foobar', serviceId: 15 }); + this.logger.log({ timestamp: 1337, message: 'foobar', serviceId: 15 }); + this.logger.log({ message: 'foobar' }); // shold be ignored + + return Promise.delay(5500).then(() => { + expect(this.requestStub.calledOnce).to.be.true; + const opts = this.requestStub.firstCall.args[0]; + + expect(opts.href).to.equal( + 'https://example.com/device/v2/deadbeef/log-stream', + ); + expect(opts.method).to.equal('POST'); + expect(opts.headers).to.deep.equal({ + Authorization: 'Bearer secretkey', + 'Content-Type': 'application/x-ndjson', + 'Content-Encoding': 'gzip', + }); + + const lines = this._req.body.split('\n'); + expect(lines.length).to.equal(3); + expect(lines[2]).to.equal(''); + + let msg = JSON.parse(lines[0]); + expect(msg) + .to.have.property('message') + .that.equals('foobar'); + expect(msg) + .to.have.property('serviceId') + .that.equals(15); + expect(msg) + .to.have.property('timestamp') + .that.is.at.least(timestamp); + msg = JSON.parse(lines[1]); + expect(msg).to.deep.equal({ + timestamp: 1337, + message: 'foobar', + serviceId: 15, + }); + }); + }); + + it('allows logging system messages which are also reported to the eventTracker', function() { + const timestamp = Date.now(); + this.logger.logSystemMessage( + 'Hello there!', + { someProp: 'someVal' }, + 'Some event name', + ); + + return Promise.delay(5500).then(() => { + expect(this.fakeEventTracker.track).to.be.calledWith('Some event name', { + someProp: 'someVal', + }); + const lines = this._req.body.split('\n'); + expect(lines.length).to.equal(2); + expect(lines[1]).to.equal(''); + + const msg = JSON.parse(lines[0]); + expect(msg) + .to.have.property('message') + .that.equals('Hello there!'); + expect(msg) + .to.have.property('isSystem') + .that.equals(true); + expect(msg) + .to.have.property('timestamp') + .that.is.at.least(timestamp); + }); + }); + + it('should support non-tty log lines', function() { + const message = + '\u0001\u0000\u0000\u0000\u0000\u0000\u0000?2018-09-21T12:37:09.819134000Z this is the message'; + const buffer = Buffer.from(message); + + // @ts-ignore accessing a private function + expect(ContainerLogs.extractMessage(buffer)).to.deep.equal({ + message: 'this is the message', + timestamp: 1537533429819, + }); + }); +}); diff --git a/tsconfig.js.json b/tsconfig.js.json index caaaf0e9..158c1cd5 100644 --- a/tsconfig.js.json +++ b/tsconfig.js.json @@ -4,5 +4,5 @@ "noImplicitAny": false, "checkJs": true }, - "include": ["src/**/*.ts", "src/**/*.js", "typings/**/*.d.ts"] + "include": ["src/**/*", "test/**/*", "typings/**/*.d.ts"] } diff --git a/tsconfig.json b/tsconfig.json index 6af31d1b..91f9edfd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,5 +11,5 @@ "resolveJsonModule": true, "allowJs": true }, - "include": ["src/**/*.ts", "src/**/*.js", "test/**/*.ts", "typings/**/*.d.ts"] + "include": ["src/**/*", "test/**/*", "typings/**/*.d.ts"] } diff --git a/tsconfig.release.json b/tsconfig.release.json index d9ddae0c..82f1594b 100644 --- a/tsconfig.release.json +++ b/tsconfig.release.json @@ -6,5 +6,5 @@ "preserveConstEnums": true, "removeComments": true }, - "include": ["src/**/*.ts", "src/**/*.js", "typings/**/*.d.ts"] + "include": ["src/**/*", "typings/**/*.d.ts"] }