diff --git a/.taprc b/.taprc deleted file mode 100644 index a449493..0000000 --- a/.taprc +++ /dev/null @@ -1,4 +0,0 @@ -timeout: 120 - -files: - - test/**/*.test.js diff --git a/package.json b/package.json index ce229b6..9c6d874 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "zipkin": "docker run -p 9411:9411 openzipkin/zipkin", "lint": "standard", "test": "npm run test:unit && npm run test:typescript", - "test:unit": "tap", + "test:unit": "c8 --100 node --test", "test:typescript": "tsd" }, "repository": { @@ -28,11 +28,11 @@ "license": "MIT", "devDependencies": { "@fastify/pre-commit": "2.1.0", + "c8": "^10.1.2", "fastify": "^5.0.0", "node-fetch": "^2.6.7", "sinon": "^18.0.0", "standard": "^17.0.0", - "tap": "^16.0.0", "tsd": "^0.31.0" }, "dependencies": { diff --git a/test/index.test.js b/test/index.test.js index 198d4bf..42eeb7f 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,6 +1,6 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const sinon = require('sinon') const Fastify = require('fastify') const zipkinPlugin = require('..') @@ -8,7 +8,7 @@ const zipkin = require('zipkin') const Tracer = zipkin.Tracer const ExplicitContext = zipkin.ExplicitContext -test('Should error when initializing the plugin without serviceName argument', async t => { +test('Should error when initializing the plugin without serviceName argument', t => { const fastify = Fastify() const record = sinon.spy() @@ -20,11 +20,11 @@ test('Should error when initializing the plugin without serviceName argument', a try { fastify.register(zipkinPlugin, { tracer, httpReporterUrl }) } catch (e) { - t.equal(e.message, 'serviceName option should not be empty') + t.assert.strictEqual(e.message, 'serviceName option should not be empty') } }) -test('Should error when initializing the plugin without httpReporterUrl argument', async t => { +test('Should error when initializing the plugin without httpReporterUrl argument', t => { const fastify = Fastify() const record = sinon.spy() @@ -36,7 +36,23 @@ test('Should error when initializing the plugin without httpReporterUrl argument try { fastify.register(zipkinPlugin, { tracer, serviceName }) } catch (e) { - t.equal(e.message, 'httpReporterUrl option should not be empty') + t.assert.strictEqual(e.message, 'httpReporterUrl option should not be empty') + } +}) + +test('Should error when initializing the plugin without httpReporterUrl argument', t => { + const fastify = Fastify() + + const record = sinon.spy() + const recorder = { record } + const ctxImpl = new ExplicitContext() + const tracer = new Tracer({ recorder, ctxImpl }) + const serviceName = 'test' + + try { + fastify.register(zipkinPlugin, { tracer, serviceName }) + } catch (e) { + t.assert.equal(e.message, 'httpReporterUrl option should not be empty') } }) @@ -69,31 +85,30 @@ test('Should register the hooks and trace the request', t => { } }, (err, res) => { - t.error(err) + t.assert.ifError(err) const annotations = record.args.map(args => args[0]) - annotations.forEach(ann => t.equal(ann.traceId.traceId, 'aaa')) - annotations.forEach(ann => t.equal(ann.traceId.spanId, 'bbb')) - t.equal(annotations[0].annotation.annotationType, 'ServiceName') - t.equal(annotations[0].annotation.serviceName, serviceName) - t.equal(annotations[1].annotation.annotationType, 'Rpc') - t.equal(annotations[1].annotation.name, 'GET') - t.equal( + annotations.forEach(ann => t.assert.strictEqual(ann.traceId.traceId, 'aaa')) + annotations.forEach(ann => t.assert.strictEqual(ann.traceId.spanId, 'bbb')) + t.assert.strictEqual(annotations[0].annotation.annotationType, 'ServiceName') + t.assert.strictEqual(annotations[0].annotation.serviceName, serviceName) + t.assert.strictEqual(annotations[1].annotation.annotationType, 'Rpc') + t.assert.strictEqual(annotations[1].annotation.name, 'GET') + t.assert.strictEqual( annotations[2].annotation.annotationType, 'BinaryAnnotation' ) - t.equal(annotations[2].annotation.key, 'http.path') - t.equal(annotations[2].annotation.value, '/') - t.equal(annotations[3].annotation.annotationType, 'ServerRecv') - t.equal(annotations[4].annotation.annotationType, 'LocalAddr') - t.equal( + t.assert.strictEqual(annotations[2].annotation.key, 'http.path') + t.assert.strictEqual(annotations[2].annotation.value, '/') + t.assert.strictEqual(annotations[3].annotation.annotationType, 'ServerRecv') + t.assert.strictEqual(annotations[4].annotation.annotationType, 'LocalAddr') + t.assert.strictEqual( annotations[5].annotation.annotationType, 'BinaryAnnotation' ) - t.equal(annotations[5].annotation.key, 'http.status_code') - t.equal(annotations[5].annotation.value, '201') - t.equal(annotations[6].annotation.annotationType, 'ServerSend') - t.end() + t.assert.strictEqual(annotations[5].annotation.key, 'http.status_code') + t.assert.strictEqual(annotations[5].annotation.value, '201') + t.assert.strictEqual(annotations[6].annotation.annotationType, 'ServerSend') } ) }) @@ -118,17 +133,15 @@ test('Should register the hooks and trace the request (404)', t => { method: 'GET' }, (err, res) => { - t.error(err) + t.assert.ifError(err) const annotations = record.args.map(args => args[0]) - t.equal( + t.assert.strictEqual( annotations[5].annotation.annotationType, 'BinaryAnnotation' ) - t.equal(annotations[5].annotation.key, 'http.status_code') - t.equal(annotations[5].annotation.value, '' + res.statusCode) - - t.end() + t.assert.strictEqual(annotations[5].annotation.key, 'http.status_code') + t.assert.strictEqual(annotations[5].annotation.value, '' + res.statusCode) } ) }) @@ -160,15 +173,84 @@ test('Should record a reasonably accurate span duration', t => { method: 'GET' }, (err, res) => { - t.error(err) + t.assert.ifError(err) const annotations = record.args.map(args => args[0]) const serverRecvTs = annotations[3].timestamp / 1000.0 const serverSendTs = annotations[6].timestamp / 1000.0 const durationMillis = serverSendTs - serverRecvTs - t.ok(durationMillis >= PAUSE_TIME_MILLIS) + t.assert.ok(durationMillis >= PAUSE_TIME_MILLIS) + } + ) + }) +}) + +test('Should register the hooks and trace the request (404)', t => { + const fastify = Fastify() + + const record = sinon.spy() + const recorder = { record } + const ctxImpl = new ExplicitContext() + const serviceName = 'test' + const tracer = new Tracer({ recorder, ctxImpl }) + const httpReporterUrl = 'http://0.0.0.0:9441/api/v2/spans' + + ctxImpl.scoped(() => { + fastify.register(zipkinPlugin, { tracer, serviceName, httpReporterUrl }) + + fastify.inject( + { + url: '/404', + method: 'GET' + }, + (err, res) => { + t.assert.ifError(err) + + const annotations = record.args.map(args => args[0]) + t.assert.strictEqual( + annotations[5].annotation.annotationType, + 'BinaryAnnotation' + ) + t.assert.strictEqual(annotations[5].annotation.key, 'http.status_code') + t.assert.strictEqual(annotations[5].annotation.value, '' + res.statusCode) + } + ) + }) +}) + +test('Should record a reasonably accurate span duration', t => { + const fastify = Fastify() + + const record = sinon.spy() + const recorder = { record } + const ctxImpl = new ExplicitContext() + const serviceName = 'test' + const httpReporterUrl = 'http://0.0.0.0:9441/api/v2/spans' + const tracer = new Tracer({ recorder, ctxImpl }) + const PAUSE_TIME_MILLIS = 100 + + ctxImpl.scoped(() => { + fastify.register(zipkinPlugin, { tracer, serviceName, httpReporterUrl }) + + fastify.get('/', (req, reply) => { + setTimeout(() => { + reply.send({ hello: 'world' }) + }, PAUSE_TIME_MILLIS) + }) + + fastify.inject( + { + url: '/', + method: 'GET' + }, + (err, res) => { + t.assert.ifError(err) - t.end() + const annotations = record.args.map(args => args[0]) + const serverRecvTs = annotations[3].timestamp / 1000.0 + const serverSendTs = annotations[6].timestamp / 1000.0 + const durationMillis = serverSendTs - serverRecvTs + t.assert.ok(durationMillis >= PAUSE_TIME_MILLIS) } ) }) @@ -176,6 +258,7 @@ test('Should record a reasonably accurate span duration', t => { test('Should record a reasonably accurate span duration with custom recorder', t => { const fastify = Fastify() + fastify.setNotFoundHandler(() => {}) const record = sinon.spy() const recorder = { record } @@ -199,15 +282,13 @@ test('Should record a reasonably accurate span duration with custom recorder', t method: 'GET' }, (err, res) => { - t.error(err) + t.assert.ifError(err) const annotations = record.args.map(args => args[0]) const serverRecvTs = annotations[3].timestamp / 1000.0 const serverSendTs = annotations[6].timestamp / 1000.0 const durationMillis = serverSendTs - serverRecvTs - t.ok(durationMillis >= PAUSE_TIME_MILLIS) - - t.end() + t.assert.ok(durationMillis >= PAUSE_TIME_MILLIS) } ) })