diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml
index 5504e8528a..ba63f2c357 100644
--- a/.github/workflows/unit-test.yml
+++ b/.github/workflows/unit-test.yml
@@ -113,7 +113,7 @@ jobs:
chown -R 1001:121 "/github/home/.npm"
[ -e /__w/opentelemetry-js-contrib/opentelemetry-js-contrib/package-lock.json ] && chown 1001:121 /__w/opentelemetry-js-contrib/opentelemetry-js-contrib/package-lock.json
- name: Bootstrap Dependencies
- run: npx lerna bootstrap --no-ci --hoist --nohoist='zone.js'
+ run: npx lerna bootstrap --no-ci --hoist --nohoist='zone.js' --nohoist='mocha' --nohoist='ts-mocha'
- name: Unit tests
run: npm run test:ci:changed
- name: Report Coverage
diff --git a/packages/opentelemetry-test-utils/README.md b/packages/opentelemetry-test-utils/README.md
index 90970142e6..db3b3e2e0b 100644
--- a/packages/opentelemetry-test-utils/README.md
+++ b/packages/opentelemetry-test-utils/README.md
@@ -2,6 +2,60 @@
This is a internal utils package used across the contrib packages. No guarantees are given to uses outside of [open-telemetry/opentelemetry-js-contrib](https://github.com/open-telemetry/opentelemetry-js-contrib/) repository.
+## Instrumentation Testing
+This package exports a mocha [root hook plugin](https://mochajs.org/#root-hook-plugins), which implements common boilerplate code a developer probably needs for writing instrumentation unit tests in node.
+
+This package:
+- Initializes and registers a global trace provider for tests.
+- Registers a global memory exporter which can be referenced in test to access span.
+- Make sure there is only a single instance of an instrumentation class that is used across different `.spec.ts` files so patching is consistent, deterministic and idiomatic.
+- Reset the memory exporter before each test, so spans do not leak from one test to another.
+- Optionally - export the test traces to Jaeger for convenience while debugging and developing.
+
+By using this package, testing instrumentation code can be shorter, and good practices for writing tests are more easily applied.
+
+### Supporter Version
+Since [root hook plugin](https://mochajs.org/#root-hook-plugins) are used, this package is compatible to mocha v8.0.0 and above.
+
+### Usage
+1. Add dev dependency on this package:
+
+```
+npm install @opentelemetry/test-utils --save-dev
+```
+2. [`require`](https://mochajs.org/#-require-module-r-module) this package in mocha invocation:
+
+As command line argument option to mocha:
+```js
+ "scripts": {
+ "test": "mocha --require @opentelemetry/test-utils",
+ "test:jaeger": "OTEL_EXPORTER_JAEGER_AGENT_HOST=localhost mocha --require @opentelemetry/test-utils",
+ },
+``
+
+Or by using config file / package.json config:
+```js
+ "mocha": {
+ "require": [ "@opentelemetry/test-utils" ]
+ }
+```
+
+3. In your `.spec` file, import `registerInstrumentationTesting` and `getTestSpans` functions and use them to create instrumentation class instance and make assertions in the test:
+
+```js
+import { getTestSpans, registerInstrumentationTesting } from '@opentelemetry/test-utils';
+
+const instrumentation = registerInstrumentationTesting(new MyAwesomeInstrumentation());
+
+it('some test', () => {
+ // your code that generate spans for this test
+ const spans: ReadableSpan[] = getTestSpans();
+ // your code doing assertions with the spans array
+});
+```
+
+That's it - supper short and easy.
+
## Useful links
- For more information on OpenTelemetry, visit:
diff --git a/packages/opentelemetry-test-utils/package.json b/packages/opentelemetry-test-utils/package.json
index f8bc7c9638..3df4dc40d5 100644
--- a/packages/opentelemetry-test-utils/package.json
+++ b/packages/opentelemetry-test-utils/package.json
@@ -2,7 +2,8 @@
"name": "@opentelemetry/contrib-test-utils",
"version": "0.25.0",
"description": "Test utilities for opentelemetry components",
- "main": "build/index.js",
+ "main": "build/src/index.js",
+ "types": "build/src/index.d.ts",
"publishConfig": {
"access": "public"
},
@@ -43,6 +44,9 @@
},
"dependencies": {
"@opentelemetry/core": "0.25.0",
+ "@opentelemetry/exporter-jaeger": "0.25.0",
+ "@opentelemetry/instrumentation": "0.25.0",
+ "@opentelemetry/sdk-trace-node": "0.25.0",
"@opentelemetry/resources": "0.25.0",
"@opentelemetry/sdk-trace-base": "0.25.0",
"@opentelemetry/semantic-conventions": "0.25.0"
diff --git a/packages/opentelemetry-test-utils/index.ts b/packages/opentelemetry-test-utils/src/index.ts
similarity index 94%
rename from packages/opentelemetry-test-utils/index.ts
rename to packages/opentelemetry-test-utils/src/index.ts
index 13355c6afa..9ed12bb749 100644
--- a/packages/opentelemetry-test-utils/index.ts
+++ b/packages/opentelemetry-test-utils/src/index.ts
@@ -16,3 +16,4 @@
export * from './resource-assertions';
export * from './test-utils';
+export * from './instrumentations';
diff --git a/packages/opentelemetry-test-utils/src/instrumentations/index.ts b/packages/opentelemetry-test-utils/src/instrumentations/index.ts
new file mode 100644
index 0000000000..bd709db0cb
--- /dev/null
+++ b/packages/opentelemetry-test-utils/src/instrumentations/index.ts
@@ -0,0 +1,56 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Resource } from '@opentelemetry/resources';
+import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
+import { getInstrumentation } from './instrumentation-singelton';
+import { registerInstrumentationTestingProvider } from './otel-default-provider';
+import { resetMemoryExporter } from './otel-provider-api';
+
+export * from './instrumentation-singelton';
+export * from './otel-provider-api';
+export * from './otel-default-provider';
+
+export const mochaHooks = {
+ beforeAll(done: Function) {
+ // since we run mocha executable, process.argv[1] will look like this:
+ // ${root instrumentation package path}/node_modules/.bin/mocha
+ // this is not very robust, might need to refactor in the future
+ let serviceName = 'unknown_instrumentation';
+ if (process.env.OTEL_SERVICE_NAME) {
+ serviceName = process.env.OTEL_SERVICE_NAME;
+ } else {
+ try {
+ serviceName = require(process.argv[1] + '/../../../package.json').name;
+ } catch {
+ // could not determine serviceName, continue regardless of this
+ }
+ }
+ const provider = registerInstrumentationTestingProvider({
+ resource: new Resource({
+ [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
+ }),
+ });
+ getInstrumentation()?.setTracerProvider(provider);
+ done();
+ },
+
+ beforeEach(done: Function) {
+ resetMemoryExporter();
+ // reset the config before each test, so that we don't leak state from one test to another
+ getInstrumentation()?.setConfig({});
+ done();
+ },
+};
diff --git a/packages/opentelemetry-test-utils/src/instrumentations/instrumentation-singelton.ts b/packages/opentelemetry-test-utils/src/instrumentations/instrumentation-singelton.ts
new file mode 100644
index 0000000000..732fed16d2
--- /dev/null
+++ b/packages/opentelemetry-test-utils/src/instrumentations/instrumentation-singelton.ts
@@ -0,0 +1,42 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { InstrumentationBase } from '@opentelemetry/instrumentation';
+
+const OTEL_TESTING_INSTRUMENTATION_SINGLETON = Symbol.for(
+ 'opentelemetry.testing.instrumentation_singleton'
+);
+
+type OTelInstrumentationSingeltonGlobal = {
+ [OTEL_TESTING_INSTRUMENTATION_SINGLETON]?: InstrumentationBase;
+};
+const _global = global as OTelInstrumentationSingeltonGlobal;
+
+export const getInstrumentation = ():
+ | T
+ | undefined => {
+ return _global[OTEL_TESTING_INSTRUMENTATION_SINGLETON] as T;
+};
+
+export const registerInstrumentationTesting = (
+ instrumentation: T
+): T => {
+ const existing = getInstrumentation();
+ if (existing) {
+ return existing;
+ }
+ _global[OTEL_TESTING_INSTRUMENTATION_SINGLETON] = instrumentation;
+ return instrumentation;
+};
diff --git a/packages/opentelemetry-test-utils/src/instrumentations/otel-default-provider.ts b/packages/opentelemetry-test-utils/src/instrumentations/otel-default-provider.ts
new file mode 100644
index 0000000000..7882b72c9a
--- /dev/null
+++ b/packages/opentelemetry-test-utils/src/instrumentations/otel-default-provider.ts
@@ -0,0 +1,48 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
+import {
+ NodeTracerProvider,
+ NodeTracerConfig,
+} from '@opentelemetry/sdk-trace-node';
+import {
+ InMemorySpanExporter,
+ SimpleSpanProcessor,
+} from '@opentelemetry/sdk-trace-base';
+import {
+ getTestMemoryExporter,
+ setTestMemoryExporter,
+} from './otel-provider-api';
+
+export const registerInstrumentationTestingProvider = (
+ config?: NodeTracerConfig
+): NodeTracerProvider => {
+ const otelTestingProvider = new NodeTracerProvider(config);
+
+ setTestMemoryExporter(new InMemorySpanExporter());
+ otelTestingProvider.addSpanProcessor(
+ new SimpleSpanProcessor(getTestMemoryExporter()!)
+ );
+
+ if (process.env.OTEL_EXPORTER_JAEGER_AGENT_HOST) {
+ otelTestingProvider.addSpanProcessor(
+ new SimpleSpanProcessor(new JaegerExporter())
+ );
+ }
+
+ otelTestingProvider.register();
+ return otelTestingProvider;
+};
diff --git a/packages/opentelemetry-test-utils/src/instrumentations/otel-provider-api.ts b/packages/opentelemetry-test-utils/src/instrumentations/otel-provider-api.ts
new file mode 100644
index 0000000000..05ad3d1a37
--- /dev/null
+++ b/packages/opentelemetry-test-utils/src/instrumentations/otel-provider-api.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {
+ InMemorySpanExporter,
+ ReadableSpan,
+} from '@opentelemetry/sdk-trace-base';
+
+const OTEL_TESTING_MEMORY_EXPORTER = Symbol.for(
+ 'opentelemetry.testing.memory_exporter'
+);
+
+type OTelProviderApiGlobal = {
+ [OTEL_TESTING_MEMORY_EXPORTER]?: InMemorySpanExporter;
+};
+const _global = global as OTelProviderApiGlobal;
+
+export const getTestMemoryExporter = (): InMemorySpanExporter | undefined => {
+ return _global[OTEL_TESTING_MEMORY_EXPORTER];
+};
+
+export const setTestMemoryExporter = (memoryExporter: InMemorySpanExporter) => {
+ _global[OTEL_TESTING_MEMORY_EXPORTER] = memoryExporter;
+};
+
+export const getTestSpans = (): ReadableSpan[] => {
+ return getTestMemoryExporter()!.getFinishedSpans();
+};
+
+export const resetMemoryExporter = () => {
+ getTestMemoryExporter()?.reset();
+};
diff --git a/packages/opentelemetry-test-utils/resource-assertions.ts b/packages/opentelemetry-test-utils/src/resource-assertions.ts
similarity index 100%
rename from packages/opentelemetry-test-utils/resource-assertions.ts
rename to packages/opentelemetry-test-utils/src/resource-assertions.ts
diff --git a/packages/opentelemetry-test-utils/test-utils.ts b/packages/opentelemetry-test-utils/src/test-utils.ts
similarity index 100%
rename from packages/opentelemetry-test-utils/test-utils.ts
rename to packages/opentelemetry-test-utils/src/test-utils.ts
diff --git a/packages/opentelemetry-test-utils/tsconfig.json b/packages/opentelemetry-test-utils/tsconfig.json
index 15ea27f288..31551191d7 100644
--- a/packages/opentelemetry-test-utils/tsconfig.json
+++ b/packages/opentelemetry-test-utils/tsconfig.json
@@ -5,6 +5,6 @@
"outDir": "build"
},
"include": [
- "*.ts"
+ "src/**/*.ts"
]
}
diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/package.json b/plugins/node/opentelemetry-instrumentation-mongodb/package.json
index a55bcc7eed..f8182dbbb0 100644
--- a/plugins/node/opentelemetry-instrumentation-mongodb/package.json
+++ b/plugins/node/opentelemetry-instrumentation-mongodb/package.json
@@ -7,7 +7,7 @@
"repository": "open-telemetry/opentelemetry-js-contrib",
"scripts": {
"docker:start": "docker run -e MONGODB_DB=opentelemetry-tests -e MONGODB_PORT=27017 -e MONGODB_HOST=localhost -p 27017:27017 --rm mongo",
- "test": "nyc ts-mocha --parallel -p tsconfig.json 'test/**/*.test.ts'",
+ "test": "nyc ts-mocha --parallel -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/**/*.test.ts'",
"test-all-versions": "tav",
"codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../",
"tdd": "npm run test -- --watch-extensions ts --watch",
@@ -49,6 +49,7 @@
},
"devDependencies": {
"@opentelemetry/api": "1.0.2",
+ "@opentelemetry/contrib-test-utils": "^0.25.0",
"@opentelemetry/context-async-hooks": "0.25.0",
"@opentelemetry/sdk-trace-base": "0.25.0",
"@opentelemetry/sdk-trace-node": "0.25.0",
@@ -69,4 +70,4 @@
"@opentelemetry/semantic-conventions": "^0.25.0",
"@types/mongodb": "3.6.20"
}
-}
+}
\ No newline at end of file
diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb.test.ts b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb.test.ts
index f88f3bea78..d86c8490be 100644
--- a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb.test.ts
+++ b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb.test.ts
@@ -17,19 +17,18 @@
// for testing locally "npm run docker:start"
import { context, trace, SpanKind, Span } from '@opentelemetry/api';
-import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
-import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';
-import {
- InMemorySpanExporter,
- SimpleSpanProcessor,
-} from '@opentelemetry/sdk-trace-base';
import * as assert from 'assert';
import { MongoDBInstrumentation, MongoDBInstrumentationConfig } from '../src';
import { MongoResponseHookInformation } from '../src/types';
+import {
+ registerInstrumentationTesting,
+ getTestSpans,
+ resetMemoryExporter,
+} from '@opentelemetry/contrib-test-utils';
-const instrumentation = new MongoDBInstrumentation();
-instrumentation.enable();
-instrumentation.disable();
+const instrumentation = registerInstrumentationTesting(
+ new MongoDBInstrumentation()
+);
import * as mongodb from 'mongodb';
import { assertSpans, accessCollection } from './utils';
@@ -38,7 +37,6 @@ import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
describe('MongoDBInstrumentation', () => {
function create(config: MongoDBInstrumentationConfig = {}) {
instrumentation.setConfig(config);
- instrumentation.enable();
}
// For these tests, mongo must be running. Add RUN_MONGODB_TESTS to run
// these tests.
@@ -58,16 +56,8 @@ describe('MongoDBInstrumentation', () => {
let client: mongodb.MongoClient;
let collection: mongodb.Collection;
- const provider = new BasicTracerProvider();
- const contextManager = new AsyncHooksContextManager().enable();
- const memoryExporter = new InMemorySpanExporter();
- const spanProcessor = new SimpleSpanProcessor(memoryExporter);
before(done => {
- instrumentation.enable();
- instrumentation.setTracerProvider(provider);
- provider.addSpanProcessor(spanProcessor);
- context.setGlobalContextManager(contextManager);
shouldTest = true;
accessCollection(URL, DB_NAME, COLLECTION_NAME)
.then(result => {
@@ -83,10 +73,6 @@ describe('MongoDBInstrumentation', () => {
done();
});
});
- after(() => {
- contextManager.disable();
- instrumentation.disable();
- });
beforeEach(function mongoBeforeEach(done) {
// Skipping all tests in beforeEach() is a workaround. Mocha does not work
@@ -95,16 +81,15 @@ describe('MongoDBInstrumentation', () => {
if (!shouldTest) {
this.skip();
}
- memoryExporter.reset();
// Non traced insertion of basic data to perform tests
const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }];
collection.insertMany(insertData, (err, result) => {
+ resetMemoryExporter();
done();
});
});
afterEach(done => {
- memoryExporter.reset();
if (shouldTest) {
return collection.deleteMany({}, done);
}
@@ -119,53 +104,39 @@ describe('MongoDBInstrumentation', () => {
/** Should intercept query */
describe('Instrumenting query operations', () => {
- beforeEach(() => {
- memoryExporter.reset();
- });
it('should create a child span for insert', done => {
const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }];
- const span = provider.getTracer('default').startSpan('insertRootSpan');
+ const span = trace.getTracer('default').startSpan('insertRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.insertMany(insertData, (err, result) => {
span.end();
assert.ifError(err);
- assertSpans(
- memoryExporter.getFinishedSpans(),
- 'mongodb.insert',
- SpanKind.CLIENT
- );
+ assertSpans(getTestSpans(), 'mongodb.insert', SpanKind.CLIENT);
done();
});
});
});
it('should create a child span for update', done => {
- const span = provider.getTracer('default').startSpan('updateRootSpan');
+ const span = trace.getTracer('default').startSpan('updateRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.updateOne({ a: 2 }, { $set: { b: 1 } }, (err, result) => {
span.end();
+ console.log(getTestSpans());
assert.ifError(err);
- assertSpans(
- memoryExporter.getFinishedSpans(),
- 'mongodb.update',
- SpanKind.CLIENT
- );
+ assertSpans(getTestSpans(), 'mongodb.update', SpanKind.CLIENT);
done();
});
});
});
it('should create a child span for remove', done => {
- const span = provider.getTracer('default').startSpan('removeRootSpan');
+ const span = trace.getTracer('default').startSpan('removeRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.deleteOne({ a: 3 }, (err, result) => {
span.end();
assert.ifError(err);
- assertSpans(
- memoryExporter.getFinishedSpans(),
- 'mongodb.remove',
- SpanKind.CLIENT
- );
+ assertSpans(getTestSpans(), 'mongodb.remove', SpanKind.CLIENT);
done();
});
});
@@ -174,27 +145,19 @@ describe('MongoDBInstrumentation', () => {
/** Should intercept cursor */
describe('Instrumenting cursor operations', () => {
- beforeEach(() => {
- memoryExporter.reset();
- });
-
it('should create a child span for find', done => {
- const span = provider.getTracer('default').startSpan('findRootSpan');
+ const span = trace.getTracer('default').startSpan('findRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.find({ a: 1 }).toArray((err, result) => {
span.end();
assert.ifError(err);
- assertSpans(
- memoryExporter.getFinishedSpans(),
- 'mongodb.find',
- SpanKind.CLIENT
- );
+ assertSpans(getTestSpans(), 'mongodb.find', SpanKind.CLIENT);
done();
});
});
});
it('should create a child span for cursor operations', done => {
- const span = provider.getTracer('default').startSpan('findRootSpan');
+ const span = trace.getTracer('default').startSpan('findRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
const cursor = collection.find().batchSize(1);
cursor.next().then(firstElement => {
@@ -204,19 +167,17 @@ describe('MongoDBInstrumentation', () => {
assert(secondElement !== null);
// assert that we correctly got the first as a find
assertSpans(
- memoryExporter
- .getFinishedSpans()
- .filter(
- span => span.name.includes('mongodb.getMore') === false
- ),
+ getTestSpans().filter(
+ span => span.name.includes('mongodb.getMore') === false
+ ),
'mongodb.find',
SpanKind.CLIENT
);
// assert that we correctly got the first as a find
assertSpans(
- memoryExporter
- .getFinishedSpans()
- .filter(span => span.name.includes('mongodb.find') === false),
+ getTestSpans().filter(
+ span => span.name.includes('mongodb.find') === false
+ ),
'mongodb.getMore',
SpanKind.CLIENT
);
@@ -229,21 +190,13 @@ describe('MongoDBInstrumentation', () => {
/** Should intercept command */
describe('Instrumenting command operations', () => {
- beforeEach(() => {
- memoryExporter.reset();
- });
-
it('should create a child span for create index', done => {
- const span = provider.getTracer('default').startSpan('indexRootSpan');
+ const span = trace.getTracer('default').startSpan('indexRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.createIndex({ a: 1 }, (err, result) => {
span.end();
assert.ifError(err);
- assertSpans(
- memoryExporter.getFinishedSpans(),
- 'mongodb.createIndexes',
- SpanKind.CLIENT
- );
+ assertSpans(getTestSpans(), 'mongodb.createIndexes', SpanKind.CLIENT);
done();
});
});
@@ -256,18 +209,17 @@ describe('MongoDBInstrumentation', () => {
const object = { [key]: value };
beforeEach(() => {
- memoryExporter.reset();
create({
enhancedDatabaseReporting: false,
});
});
it('should properly collect db statement (hide attribute values)', done => {
- const span = provider.getTracer('default').startSpan('insertRootSpan');
+ const span = trace.getTracer('default').startSpan('insertRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.insertOne(object).then(() => {
span.end();
- const spans = memoryExporter.getFinishedSpans();
+ const spans = getTestSpans();
const operationName = 'mongodb.insert';
assertSpans(spans, operationName, SpanKind.CLIENT, false, false);
const mongoSpan = spans.find(s => s.name === operationName);
@@ -288,7 +240,6 @@ describe('MongoDBInstrumentation', () => {
describe('with a valid function', () => {
beforeEach(() => {
- memoryExporter.reset();
create({
dbStatementSerializer: (commandObj: Record) => {
return JSON.stringify(commandObj);
@@ -297,11 +248,11 @@ describe('MongoDBInstrumentation', () => {
});
it('should properly collect db statement', done => {
- const span = provider.getTracer('default').startSpan('insertRootSpan');
+ const span = trace.getTracer('default').startSpan('insertRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.insertOne(object).then(() => {
span.end();
- const spans = memoryExporter.getFinishedSpans();
+ const spans = getTestSpans();
const operationName = 'mongodb.insert';
assertSpans(spans, operationName, SpanKind.CLIENT, false, true);
const mongoSpan = spans.find(s => s.name === operationName);
@@ -317,7 +268,6 @@ describe('MongoDBInstrumentation', () => {
describe('with an invalid function', () => {
beforeEach(() => {
- memoryExporter.reset();
create({
enhancedDatabaseReporting: true,
dbStatementSerializer: (_commandObj: Record) => {
@@ -327,11 +277,11 @@ describe('MongoDBInstrumentation', () => {
});
it('should not do any harm when throwing an exception', done => {
- const span = provider.getTracer('default').startSpan('insertRootSpan');
+ const span = trace.getTracer('default').startSpan('insertRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.insertOne(object).then(() => {
span.end();
- const spans = memoryExporter.getFinishedSpans();
+ const spans = getTestSpans();
assertSpans(spans, 'mongodb.insert', SpanKind.CLIENT);
done();
});
@@ -342,9 +292,6 @@ describe('MongoDBInstrumentation', () => {
describe('when specifying a responseHook configuration', () => {
const dataAttributeName = 'mongodb_data';
- beforeEach(() => {
- memoryExporter.reset();
- });
describe('with a valid function', () => {
beforeEach(() => {
@@ -360,12 +307,12 @@ describe('MongoDBInstrumentation', () => {
it('should attach response hook data to the resulting span for insert function', done => {
const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }];
- const span = provider.getTracer('default').startSpan('insertRootSpan');
+ const span = trace.getTracer('default').startSpan('insertRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.insertMany(insertData, (err, result) => {
span.end();
assert.ifError(err);
- const spans = memoryExporter.getFinishedSpans();
+ const spans = getTestSpans();
const insertSpan = spans[0];
assert.deepStrictEqual(
@@ -379,12 +326,12 @@ describe('MongoDBInstrumentation', () => {
});
it('should attach response hook data to the resulting span for find function', done => {
- const span = provider.getTracer('default').startSpan('findRootSpan');
+ const span = trace.getTracer('default').startSpan('findRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.find({ a: 1 }).toArray((err, results) => {
span.end();
assert.ifError(err);
- const spans = memoryExporter.getFinishedSpans();
+ const spans = getTestSpans();
const findSpan = spans[0];
const hookAttributeValue = JSON.parse(
findSpan.attributes[dataAttributeName] as string
@@ -411,11 +358,11 @@ describe('MongoDBInstrumentation', () => {
});
it('should not do any harm when throwing an exception', done => {
- const span = provider.getTracer('default').startSpan('findRootSpan');
+ const span = trace.getTracer('default').startSpan('findRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.find({ a: 1 }).toArray((err, results) => {
span.end();
- const spans = memoryExporter.getFinishedSpans();
+ const spans = getTestSpans();
assert.ifError(err);
assertSpans(spans, 'mongodb.find', SpanKind.CLIENT);
@@ -428,24 +375,20 @@ describe('MongoDBInstrumentation', () => {
});
describe('Mixed operations with callback', () => {
- beforeEach(() => {
- memoryExporter.reset();
- });
-
it('should create a span for find after callback insert', done => {
const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }];
- const span = provider.getTracer('default').startSpan('insertRootSpan');
+ const span = trace.getTracer('default').startSpan('insertRootSpan');
context.with(trace.setSpan(context.active(), span), () => {
collection.insertMany(insertData, (err, result) => {
span.end();
assert.ifError(err);
- const spans = memoryExporter.getFinishedSpans();
+ const spans = getTestSpans();
const mainSpan = spans[spans.length - 1];
assertSpans(spans, 'mongodb.insert', SpanKind.CLIENT);
- memoryExporter.reset();
+ resetMemoryExporter();
collection.find({ a: 1 }).toArray((err, result) => {
- const spans2 = memoryExporter.getFinishedSpans();
+ const spans2 = getTestSpans();
spans2.push(mainSpan);
assert.ifError(err);
@@ -454,7 +397,6 @@ describe('MongoDBInstrumentation', () => {
mainSpan.spanContext().spanId,
spans2[0].parentSpanId
);
- memoryExporter.reset();
done();
});
});
@@ -464,10 +406,6 @@ describe('MongoDBInstrumentation', () => {
/** Should intercept command */
describe('Removing Instrumentation', () => {
- beforeEach(() => {
- memoryExporter.reset();
- });
-
it('should unpatch plugin', () => {
assert.doesNotThrow(() => {
instrumentation.disable();
@@ -476,31 +414,31 @@ describe('MongoDBInstrumentation', () => {
it('should not create a child span for query', done => {
const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }];
- const span = provider.getTracer('default').startSpan('insertRootSpan');
+ const span = trace.getTracer('default').startSpan('insertRootSpan');
collection.insertMany(insertData, (err, result) => {
span.end();
assert.ifError(err);
- assert.strictEqual(memoryExporter.getFinishedSpans().length, 1);
+ assert.strictEqual(getTestSpans().length, 1);
done();
});
});
it('should not create a child span for cursor', done => {
- const span = provider.getTracer('default').startSpan('findRootSpan');
+ const span = trace.getTracer('default').startSpan('findRootSpan');
collection.find({}).toArray((err, result) => {
span.end();
assert.ifError(err);
- assert.strictEqual(memoryExporter.getFinishedSpans().length, 1);
+ assert.strictEqual(getTestSpans().length, 1);
done();
});
});
it('should not create a child span for command', done => {
- const span = provider.getTracer('default').startSpan('indexRootSpan');
+ const span = trace.getTracer('default').startSpan('indexRootSpan');
collection.createIndex({ a: 1 }, (err, result) => {
span.end();
assert.ifError(err);
- assert.strictEqual(memoryExporter.getFinishedSpans().length, 1);
+ assert.strictEqual(getTestSpans().length, 1);
done();
});
});