UNPKG

hawkly

Version:
376 lines 32.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const opentracing = require("opentracing"); const sinon = require("sinon"); const Tracer_1 = require("./Tracer"); const ava_1 = require("ava"); // This file contains tests for the public interface ava_1.test('Check Tracer options are set correctly', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const accessToken = 'testAccessToken'; const componentName = 'testComponentname'; const recordCallback = sinon.spy(); const tracer = new Tracer_1.Tracer({ accessToken, componentName, recordCallback, }); t.is(tracer.accessToken, accessToken, 'accessToken does not match'); t.is(tracer.componentName, componentName, 'componentName does not match'); t.is(tracer.recordCallback, recordCallback, 'recordCallback does not match'); // Call the recordCallback tracer.recordCallback(); t.true(recordCallback.called); })); ava_1.test('Check Tracer throws when constructor options are not set correctly', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { // Check accessToken errors const accessTokenUndefinedError = t.throws(() => { const tracer = new Tracer_1.Tracer({ componentName: 'help', }); tracer.clear(); }); t.is(accessTokenUndefinedError.message, 'You need to set your accessToken for the hawkly tracer'); const accessTokenNonStringError = t.throws(() => { const tracer = new Tracer_1.Tracer({ accessToken: 234, componentName: 'im', }); tracer.clear(); }); t.is(accessTokenNonStringError.message, 'The accessToken must be a string'); // Check componentName errors const componentNameUndefinedError = t.throws(() => { const tracer = new Tracer_1.Tracer({ accessToken: 'trapped', }); tracer.clear(); }); t.is(componentNameUndefinedError.message, 'You need to set a componentName to identify where these traces are coming from'); const componentNameNonStringError = t.throws(() => { const tracer = new Tracer_1.Tracer({ accessToken: 'in', componentName: 23423, }); tracer.clear(); }); t.is(componentNameNonStringError.message, 'The componentName must be a string'); // Check recordCallback errors const recordCallbackNonFunctionButDefinedError = t.throws(() => { const tracer = new Tracer_1.Tracer({ accessToken: 'a', componentName: 'testing', recordCallback: 'factory', }); tracer.clear(); }); t.is(recordCallbackNonFunctionButDefinedError.message, 'recordCallback must be a function'); })); // Havent been able to get this to work // test('should log error if the context is not a Span or Context', async (t: any) => { // const tracer: Tracer = new Tracer({ // accessToken: 'test', // componentName: 'test', // recordCallback: () => { // // // }, // }); // const span: any = tracer.startSpan('test2', { childOf: undefined }); // span.finish(); // // t.is(tracer.internalEvents // console.log(tracer.internalEvents); // // t.true(tracer.internalEvents.find((event: any) => { // // return event.msg === 'Span reference has an invalid context' // // && event.payload === 'parent'; // // })); // }); ava_1.test('supports childOf with a Span object', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const parent = tracer.startSpan('test1'); const span = tracer.startSpan('test2', { childOf: parent }); span.finish(); parent.finish(); t.true(span.context().traceId === parent.context().traceId, 'traceId does not match'); t.true(span.context().parentId === parent.context().spanId, 'parentId does not match'); t.true(parent.context().referenceType === 'root'); t.true(span.context().referenceType === 'childOf'); })); ava_1.test('supports childOf with a SpanContext object', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const parent = tracer.startSpan('test1'); const span = tracer.startSpan('test2', { childOf: parent.context() }); span.finish(); parent.finish(); t.true(span.context().traceId === parent.context().traceId, 'traceId does not match'); t.true(span.context().parentId === parent.context().spanId, 'parentId does not match'); t.true(parent.context().referenceType === 'root'); t.true(span.context().referenceType === 'childOf'); })); ava_1.test('supports followsFrom with a Span object', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const parent = tracer.startSpan('test1'); const span = tracer.startSpan('test2', { followsFrom: parent }); span.finish(); parent.finish(); t.true(span.context().traceId === parent.context().traceId, 'traceId does not match'); t.true(span.context().parentId === parent.context().spanId, 'parentId does not match'); t.true(parent.context().referenceType === 'root'); t.true(span.context().referenceType === 'followsFrom'); })); ava_1.test('supports followsFrom with a SpanContext object', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const parent = tracer.startSpan('test1'); const parentContext = parent.context(); parent.finish(); const span = tracer.startSpan('test2', { followsFrom: parentContext }); span.finish(); t.true(span.context().traceId === parent.context().traceId, 'traceId does not match'); t.true(span.context().parentId === parent.context().spanId, 'parentId does not match'); t.true(parent.context().referenceType === 'root'); t.true(span.context().referenceType === 'followsFrom'); })); ava_1.test('supports startTime', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const now = Date.now() - 5000; const span = tracer.startSpan('test2', { startTime: now }); span.finish(); t.is(span._startMs, now, 'start time does not match what was supplied'); })); ava_1.test('should throw when startTime is not a number', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const error = yield t.throws(() => { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const span = tracer.startSpan('test2', { startTime: 'now' }); span.finish(); }); t.is(error.message, 'startTime must be a timestamp of type number'); })); ava_1.test('supports tags', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { yield t.notThrows(() => { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); // Verify that we can add tags at startSpan time. const span = tracer.startSpan('test', { tags: { tag_a: 1, tag_b: 'b', tag_c: true, }, }); span.finish(); }); })); ava_1.test('should throw when tags is not an object', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const error = yield t.throws(() => { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const span = tracer.startSpan('test', { tags: 'tags', }); span.finish(); }); t.is(error.message, 'tags must be an object'); })); ava_1.test('should throw when tags is an Array', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const error = yield t.throws(() => { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const span = tracer.startSpan('test', { tags: [], }); span.finish(); }); t.is(error.message, 'tags must be an object'); })); ava_1.test('should handle a large number of spans gracefully', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { yield t.notThrows(() => { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); // Loop through a large number of span creations. // This syntax may loop weird, but we're avoiding i++ and a for loop [...Array(10000)].forEach(() => { const span = tracer.startSpan('microspan'); span.finish(); }); }); })); ava_1.test('should handle clearing spans', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); [...Array(100)].forEach(() => { const span = tracer.startSpan('microspan'); span.finish(); }); t.true(tracer._spans.length === 100); tracer.clear(); t.true(tracer._spans.length === 0); })); ava_1.test('should handle passing in the opentracing module', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', opentracingModule: opentracing, recordCallback: () => { // }, }); // Verify that we can add tags at startSpan time. const span = tracer.startSpan('test'); span.finish(); t.is(tracer.opentracing, opentracing); })); ava_1.test('should throw when the first arg of Span.log() is not an object', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const error = yield t.throws(() => { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const span = tracer.startSpan('test', { tags: [], }); span.finish(); }); t.is(error.message, 'tags must be an object'); })); ava_1.test('should be able to inject Context into a TextMap', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const carrier = {}; const span = tracer.startSpan('test'); span.finish(); tracer.inject(span, 'text_map', carrier); t.is(carrier['ot-tracer-spanId'], span.context().spanId); t.is(carrier['ot-tracer-parentId'], span.context().parentId); t.is(carrier['ot-tracer-traceId'], span.context().traceId); t.is(carrier['ot-tracer-referenceType'], span.context().referenceType); t.is(carrier['ot-tracer-sampled'], span.context().sampled); })); ava_1.test('should be able to extract a Context from a TextMap', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const carrier = {}; const span = tracer.startSpan('test'); span.finish(); tracer.inject(span, 'text_map', carrier); t.is(carrier['ot-tracer-spanId'], span.context().spanId); t.is(carrier['ot-tracer-parentId'], span.context().parentId); t.is(carrier['ot-tracer-traceId'], span.context().traceId); t.is(carrier['ot-tracer-referenceType'], span.context().referenceType); t.is(carrier['ot-tracer-sampled'], span.context().sampled); const extractedContext = tracer.extract('text_map', carrier); t.is(extractedContext.spanId, span.context().spanId); t.is(extractedContext.parentId, span.context().parentId); t.is(extractedContext.traceId, span.context().traceId); t.is(extractedContext.referenceType, span.context().referenceType); t.is(extractedContext.sampled, span.context().sampled); })); ava_1.test('should be able to inject Context into a TextMap', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const carrier = {}; const span = tracer.startSpan('test'); span.finish(); tracer.inject(span, 'text_map', carrier); t.is(carrier['ot-tracer-spanId'], span.context().spanId); t.is(carrier['ot-tracer-parentId'], span.context().parentId); t.is(carrier['ot-tracer-traceId'], span.context().traceId); t.is(carrier['ot-tracer-referenceType'], span.context().referenceType); t.is(carrier['ot-tracer-sampled'], span.context().sampled); })); ava_1.test('should be able to join to a carrier', (t) => tslib_1.__awaiter(this, void 0, void 0, function* () { const tracer = new Tracer_1.Tracer({ accessToken: 'test', componentName: 'test', recordCallback: () => { // }, }); const carrier = {}; const span = tracer.startSpan('test'); span.finish(); tracer.inject(span, 'text_map', carrier); const childSpan = tracer.join('childSpan', carrier, 'text_map'); childSpan.finish(); t.is(childSpan.context().parentId, span.context().spanId); t.is(childSpan.context().traceId, span.context().traceId); t.is(childSpan.context().referenceType, 'childOf'); })); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhY2VyLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdHJhY2VyL1RyYWNlci5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUEyQztBQUMzQywrQkFBK0I7QUFFL0IscUNBQWtDO0FBQ2xDLDZCQUEyQjtBQUUzQixvREFBb0Q7QUFFcEQsVUFBSSxDQUFDLHdDQUF3QyxFQUFFLENBQU8sQ0FBTTtJQUMxRCxNQUFNLFdBQVcsR0FBVyxpQkFBaUIsQ0FBQztJQUM5QyxNQUFNLGFBQWEsR0FBVyxtQkFBbUIsQ0FBQztJQUNsRCxNQUFNLGNBQWMsR0FBUSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7SUFFeEMsTUFBTSxNQUFNLEdBQVEsSUFBSSxlQUFNLENBQUM7UUFDN0IsV0FBVztRQUNYLGFBQWE7UUFDYixjQUFjO0tBQ2YsQ0FBQyxDQUFDO0lBRUgsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSw0QkFBNEIsQ0FBQyxDQUFDO0lBQ3BFLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxhQUFhLEVBQUUsOEJBQThCLENBQUMsQ0FBQztJQUMxRSxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsY0FBYyxFQUFFLCtCQUErQixDQUFDLENBQUM7SUFFN0UsMEJBQTBCO0lBQzFCLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNoQyxDQUFDLENBQUEsQ0FBQyxDQUFDO0FBRUgsVUFBSSxDQUFDLG9FQUFvRSxFQUFFLENBQU8sQ0FBTTtJQUN0RiwyQkFBMkI7SUFDM0IsTUFBTSx5QkFBeUIsR0FBUSxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQzlDLE1BQU0sTUFBTSxHQUFXLElBQUksZUFBTSxDQUFDO1lBQ2hDLGFB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QztJQUNILE1BQU0sT0FBTyxHQUFRLEVBQUUsQ0FBQztJQUN4QixNQUFNLElBQUksR0FBUSxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzNDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNkLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUV6QyxNQUFNLFNBQVMsR0FBUSxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDckUsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBRW5CLENBQUMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUQsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMxRCxDQUFDLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDckQsQ0FBQyxDQUFBLENBQUMsQ0FBQyJ9