From b99f3d6702ecc3a16385c15a2a4c772d404a4774 Mon Sep 17 00:00:00 2001 From: David Luna Date: Mon, 16 Jun 2025 16:37:43 +0200 Subject: [PATCH 01/14] chore: add docker file to test with services locally --- package.json | 3 + .../test/index.metrics.test.ts | 24 +--- .../test/index.test.ts | 47 ++++--- .../test/mysql.test.ts | 54 ++++---- test/docker-compose.yaml | 117 ++++++++++++++++++ test/test-services.env | 35 ++++++ 6 files changed, 222 insertions(+), 58 deletions(-) create mode 100644 test/docker-compose.yaml create mode 100644 test/test-services.env diff --git a/package.json b/package.json index 42f95b8113..a0665501fc 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,9 @@ "test:browser": "nx run-many -t test:browser", "test:ci:changed": "nx affected -t test --base=origin/main --head=HEAD", "test-all-versions": "nx run-many -t test-all-versions", + "test-services:start": "docker compose -f ./test/docker-compose.yaml up -d --wait", + "test-services:stop": "docker compose -f ./test/docker-compose.yaml down", + "test:with-test-services": "NODE_OPTIONS='-r dotenv/config' DOTENV_CONFIG_PATH=./test/test-services.env npm test", "changelog": "lerna-changelog", "lint": "nx run-many -t lint && npm run lint:deps && npm run lint:readme && npm run lint:markdown && npm run lint:semconv-deps", "lint:fix": "nx run-many -t lint:fix && npm run lint:markdown:fix", diff --git a/plugins/node/opentelemetry-instrumentation-mysql/test/index.metrics.test.ts b/plugins/node/opentelemetry-instrumentation-mysql/test/index.metrics.test.ts index 3661904b5b..89c40c891b 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql/test/index.metrics.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql/test/index.metrics.test.ts @@ -24,7 +24,6 @@ import { } from '@opentelemetry/sdk-metrics'; import * as assert from 'assert'; import { MySQLInstrumentation } from '../src'; -import * as testUtils from '@opentelemetry/contrib-test-utils'; import { registerInstrumentationTesting } from '@opentelemetry/contrib-test-utils'; const instrumentation = registerInstrumentationTesting( @@ -62,9 +61,9 @@ import * as mysqlTypes from 'mysql'; describe('mysql@2.x-Metrics', () => { let otelTestingMeterProvider; let inMemoryMetricsExporter: InMemoryMetricExporter; - const testMysql = process.env.RUN_MYSQL_TESTS; // For CI: assumes local mysql db is already available - const testMysqlLocally = process.env.RUN_MYSQL_TESTS_LOCAL; // For local: spins up local mysql db via docker - const shouldTest = testMysql || testMysqlLocally; // Skips these tests if false (default) + // assumes local mysql db is already available in CI or + // using `npm run test-services:start` script at the root folder + const shouldTest = process.env.RUN_MYSQL_TESTS; function initMeterProvider() { inMemoryMetricsExporter = new InMemoryMetricExporter( @@ -90,22 +89,7 @@ describe('mysql@2.x-Metrics', () => { console.log('Skipping test-mysql for metrics.'); this.skip(); } - - if (testMysqlLocally) { - testUtils.startDocker('mysql'); - // wait 15 seconds for docker container to start - this.timeout(20000); - setTimeout(done, 15000); - } else { - done(); - } - }); - - after(function () { - if (testMysqlLocally) { - this.timeout(5000); - testUtils.cleanUpDocker('mysql'); - } + done(); }); describe('#Pool - metrics', () => { diff --git a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts index 122c1cb2ac..5f347e06bf 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts @@ -25,7 +25,6 @@ import { SEMATTRS_NET_PEER_NAME, SEMATTRS_NET_PEER_PORT, } from '@opentelemetry/semantic-conventions'; -import * as testUtils from '@opentelemetry/contrib-test-utils'; import { BasicTracerProvider, InMemorySpanExporter, @@ -41,6 +40,7 @@ const database = process.env.MYSQL_DATABASE || 'test_db'; const host = process.env.MYSQL_HOST || '127.0.0.1'; const user = process.env.MYSQL_USER || 'otel'; const password = process.env.MYSQL_PASSWORD || 'secret'; +const rootPassword = process.env.MYSQL_ROOT_PASSWORD || 'rootpw'; const instrumentation = new MySQLInstrumentation(); instrumentation.enable(); @@ -49,14 +49,24 @@ instrumentation.disable(); import * as mysqlTypes from 'mysql'; import { AttributeNames } from '../src/AttributeNames'; +// Helper function to setup the database +const execPromise = (conn: mysqlTypes.Connection, command: string) => { + return new Promise((res, rej) => { + conn.query(command, (err) => { + if (err) rej(err); + else res(); + }) + }) +}; + describe('mysql@2.x-Tracing', () => { let contextManager: AsyncLocalStorageContextManager; let connection: mysqlTypes.Connection; let pool: mysqlTypes.Pool; let poolCluster: mysqlTypes.PoolCluster; - const testMysql = process.env.RUN_MYSQL_TESTS; // For CI: assumes local mysql db is already available - const testMysqlLocally = process.env.RUN_MYSQL_TESTS_LOCAL; // For local: spins up local mysql db via docker - const shouldTest = testMysql || testMysqlLocally; // Skips these tests if false (default) + // assumes local mysql db is already available in CI or + // using `npm run test-services:start` script at the root folder + const shouldTest = process.env.RUN_MYSQL_TESTS; // For CI: assumes local mysql db is already available const memoryExporter = new InMemorySpanExporter(); const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], @@ -68,23 +78,26 @@ describe('mysql@2.x-Tracing', () => { // https://github.com/mochajs/mocha/issues/2683#issuecomment-375629901 this.test!.parent!.pending = true; this.skip(); - } - - if (testMysqlLocally) { - testUtils.startDocker('mysql'); - // wait 15 seconds for docker container to start - this.timeout(20000); - setTimeout(done, 15000); } else { done(); } - }); - after(function () { - if (testMysqlLocally) { - this.timeout(5000); - testUtils.cleanUpDocker('mysql'); - } + // const connection = mysqlTypes.createConnection({ + // port, + // user: 'root', + // host, + // password: rootPassword, + // database, + // }); + // try { + // await execPromise(connection, `SET GLOBAL log_output='TABLE'`); + // await execPromise(connection, `SET GLOBAL general_log = 1`); + // } catch (execErr) { + // console.error('MySQL seup error: ', execErr); + // this.skip(); + // } finally { + // connection.end(); + // } }); beforeEach(() => { diff --git a/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts b/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts index 5874b69adc..e8405c0352 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts @@ -64,28 +64,38 @@ interface Result extends RowDataPacket { solution: number; } -describe('mysql2', () => { - const testMysql = process.env.RUN_MYSQL_TESTS; // For CI: assumes local mysql db is already available - const testMysqlLocally = process.env.RUN_MYSQL_TESTS_LOCAL; // For local: spins up local mysql db via docker - const shouldTest = testMysql || testMysqlLocally; // Skips these tests if false (default) - - before(function (done) { - if (testMysqlLocally) { - testUtils.startDocker('mysql'); - // wait 15 seconds for docker container to start - this.timeout(20000); - setTimeout(done, 15000); - } else { - done(); - } - }); +// Helper function to setup the database +const execPromise = (conn: Connection, command: string) => { + return new Promise((res, rej) => { + conn.execute(command, (err) => { + if (err) rej(err); + else res(); + }) + }) +}; - after(function (done) { - if (testMysqlLocally) { - this.timeout(5000); - testUtils.cleanUpDocker('mysql'); +describe('mysql2', () => { + // assumes local mysql db is already available in CI or + // using `npm run test-services:start` script at the root folder + const shouldTest = process.env.RUN_MYSQL_TESTS; + + before(async function () { + const connection = createConnection({ + port, + user: 'root', + host, + password: rootPassword, + database, + }); + try { + await execPromise(connection, `SET GLOBAL log_output='TABLE'`); + await execPromise(connection, `SET GLOBAL general_log = 1`); + } catch (execErr) { + console.error('MySQL seup error: ', execErr); + this.skip(); + } finally { + connection.end(); } - done(); }); describe('callback API', () => { @@ -358,7 +368,9 @@ describe('mysql2', () => { it('should not add comment by default', done => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { - connection.query('SELECT 1+1 as solution', () => { + connection.query('SELECT 1+1 as solution', (e, r) => { + console.log(e) + console.log(r) const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); getLastQueries(1).then(([query]) => { diff --git a/test/docker-compose.yaml b/test/docker-compose.yaml new file mode 100644 index 0000000000..f65a575f10 --- /dev/null +++ b/test/docker-compose.yaml @@ -0,0 +1,117 @@ +# A `docker compose` config file to run tests services for testing +# `@opentelemetry/instrumentation-*` locally. +# +# Note: This isn't used in CI. CI uses GitHub Actions' `services: ...` for +# defining test services. +# +# Usage: +# npm run test-services:start [services...] +# npm run test-services:stop [services...] + +name: opentelemetry-nodejs-test-services + +services: + cassandra: + image: bitnami/cassandra:3 + environment: + MAX_HEAP_SIZE: "1G" + HEAP_NEWSIZE: 400m + ports: + - "9042:9042" + healthcheck: + test: ["CMD-SHELL", "[ $$(nodetool statusgossip) = running ]"] + interval: 1s + timeout: 10s + retries: 30 + + memcached: + image: memcached:1.6.37-alpine + ports: + - 11211:11211 + mongodb: + image: mongo:7 + ports: + - "27017:27017" + healthcheck: + test: ["CMD", "mongosh", "--eval", "db.runCommand('ping').ok", "--quiet"] + interval: 1s + timeout: 10s + retries: 30 + + mssql: + # Tags listed at https://hub.docker.com/r/microsoft/mssql-server + # Docs: https://learn.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker + image: mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 + platform: linux/amd64 + environment: + - ACCEPT_EULA=Y + - MSSQL_SA_PASSWORD=mssql_passw0rd + ports: + - "1433:1433" + healthcheck: + test: ["CMD", "/opt/mssql-tools18/bin/sqlcmd", "-C", "-S", "mssql", "-U", "sa", "-P", "mssql_passw0rd", "-Q", "select 1"] + interval: 1s + timeout: 10s + retries: 30 + + mysql: + image: mysql:5.7 + environment: + MYSQL_USER: "otel" + MYSQL_PASSWORD: "secret" + MYSQL_DATABASE: "test_db" + MYSQL_ROOT_PASSWORD: "rootpw" + ports: + - "33306:3306" + healthcheck: + test: ["CMD", "mysqladmin" ,"ping"] + interval: 1s + timeout: 10s + retries: 30 + + oracledb: + image: gvenzl/oracle-free:slim + environment: + APP_USER: "otel" + APP_USER_PASSWORD: "secret" + ORACLE_PASSWORD: "oracle" + ports: + - 1521:1521 + healthcheck: + test: ["CMD", "sqlplus" ,"system/oracle@//localhost/FREEPDB1"] + interval: 10s + timeout: 5s + retries: 30 + postgres: + # https://github.com/docker-library/docs/blob/master/postgres/README.md#how-to-extend-this-image + image: postgres:16-alpine + ports: + - "5432:5432" + environment: + POSTGRES_HOST_AUTH_METHOD: "trust" + POSTGRES_USER: "postgres" + POSTGRES_DB: "otel_pg_database" + POSTGRES_PASSWORD: "postgres" + healthcheck: + test: ["CMD", "pg_isready"] + interval: 1s + timeout: 10s + retries: 30 + + rabbitmq: + image: rabbitmq:3 + environment: + RABBITMQ_DEFAULT_USER: "username" + RABBITMQ_DEFAULT_PASS: "password" + ports: + - "22221:5672" + + redis: + image: redis:7 + ports: + - "6379:6379" + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 1s + timeout: 10s + retries: 30 diff --git a/test/test-services.env b/test/test-services.env new file mode 100644 index 0000000000..4a077bf3e5 --- /dev/null +++ b/test/test-services.env @@ -0,0 +1,35 @@ +RUN_CASSANDRA_TESTS=1 +RUN_MEMCACHED_TESTS=1 +RUN_MONGODB_TESTS=1 +RUN_MYSQL_TESTS=1 +RUN_MSSQL_TESTS=1 +RUN_ORACLEDB_TESTS=1 +RUN_POSTGRES_TESTS=1 +RUN_REDIS_TESTS=1 +RUN_RABBIT_TESTS=1 +CASSANDRA_HOST=localhost +MONGODB_DB=opentelemetry-tests +MONGODB_HOST=127.0.0.1 +MONGODB_PORT=27017 +MSSQL_PASSWORD=mssql_passw0rd +MYSQL_DATABASE=otel_mysql_database +MYSQL_HOST=127.0.0.1 +MYSQL_PASSWORD=secret +MYSQL_ROOT_PASSWORD=rootpw +MYSQL_PORT=3306 +MYSQL_USER=otel +OPENTELEMETRY_MEMCACHED_HOST=localhost +OPENTELEMETRY_MEMCACHED_PORT=11211 +OPENTELEMETRY_REDIS_HOST=localhost +OPENTELEMETRY_REDIS_PORT=6379 +ORACLE_HOSTNAME=localhost +ORACLE_PORT=1521 +ORACLE_CONNECTSTRING=localhost:1521/freepdb1 +ORACLE_USER=otel +ORACLE_PASSWORD=secret +ORACLE_SERVICENAME=FREEPDB1 +POSTGRES_DB=otel_pg_database +POSTGRES_HOST=localhost +POSTGRES_PORT=5432 +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres \ No newline at end of file From 86669071bacffa7dac502a72d30f3bb3f5406157 Mon Sep 17 00:00:00 2001 From: David Luna Date: Mon, 16 Jun 2025 16:38:50 +0200 Subject: [PATCH 02/14] chore: remove mysql config step in workflows --- .github/workflows/test-all-versions.yml | 2 -- .github/workflows/unit-test.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/test-all-versions.yml b/.github/workflows/test-all-versions.yml index 3029878065..83a261dbfb 100644 --- a/.github/workflows/test-all-versions.yml +++ b/.github/workflows/test-all-versions.yml @@ -163,8 +163,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - - name: Set MySQL variables - run: mysql --user=root --password=${MYSQL_ROOT_PASSWORD} --host=${MYSQL_HOST} --port=${MYSQL_PORT} -e "SET GLOBAL log_output='TABLE'; SET GLOBAL general_log = 1;" mysql - name: Install run: npm ci - name: Download Build Artifacts diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 68826df198..d2fe1de428 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -176,8 +176,6 @@ jobs: - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - - name: Set MySQL variables - run: mysql --user=root --password=${MYSQL_ROOT_PASSWORD} --host=${MYSQL_HOST} --port=${MYSQL_PORT} -e "SET GLOBAL log_output='TABLE'; SET GLOBAL general_log = 1;" mysql - name: Install run: npm ci - name: Download Build Artifacts From b2cea6218565914b11551190efc8450f44d5e25d Mon Sep 17 00:00:00 2001 From: David Luna Date: Mon, 16 Jun 2025 16:42:17 +0200 Subject: [PATCH 03/14] chore: fix lint issues --- .../test/index.test.ts | 6 +++--- .../test/mysql.test.ts | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts index 5f347e06bf..0fefb06bc7 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts @@ -52,11 +52,11 @@ import { AttributeNames } from '../src/AttributeNames'; // Helper function to setup the database const execPromise = (conn: mysqlTypes.Connection, command: string) => { return new Promise((res, rej) => { - conn.query(command, (err) => { + conn.query(command, err => { if (err) rej(err); else res(); - }) - }) + }); + }); }; describe('mysql@2.x-Tracing', () => { diff --git a/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts b/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts index e8405c0352..85dcec5b39 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts @@ -67,11 +67,11 @@ interface Result extends RowDataPacket { // Helper function to setup the database const execPromise = (conn: Connection, command: string) => { return new Promise((res, rej) => { - conn.execute(command, (err) => { + conn.execute(command, err => { if (err) rej(err); else res(); - }) - }) + }); + }); }; describe('mysql2', () => { @@ -88,8 +88,8 @@ describe('mysql2', () => { database, }); try { - await execPromise(connection, `SET GLOBAL log_output='TABLE'`); - await execPromise(connection, `SET GLOBAL general_log = 1`); + await execPromise(connection, "SET GLOBAL log_output='TABLE'"); + await execPromise(connection, 'SET GLOBAL general_log = 1'); } catch (execErr) { console.error('MySQL seup error: ', execErr); this.skip(); @@ -369,8 +369,8 @@ describe('mysql2', () => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { connection.query('SELECT 1+1 as solution', (e, r) => { - console.log(e) - console.log(r) + console.log(e); + console.log(r); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); getLastQueries(1).then(([query]) => { From b75a0c17f872305864b2345fe6f804f1157c6cf3 Mon Sep 17 00:00:00 2001 From: David Luna Date: Mon, 16 Jun 2025 16:50:00 +0200 Subject: [PATCH 04/14] fix: fix compilation issue --- .../test/index.test.ts | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts index 0fefb06bc7..6437c21167 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts @@ -40,7 +40,6 @@ const database = process.env.MYSQL_DATABASE || 'test_db'; const host = process.env.MYSQL_HOST || '127.0.0.1'; const user = process.env.MYSQL_USER || 'otel'; const password = process.env.MYSQL_PASSWORD || 'secret'; -const rootPassword = process.env.MYSQL_ROOT_PASSWORD || 'rootpw'; const instrumentation = new MySQLInstrumentation(); instrumentation.enable(); @@ -49,16 +48,6 @@ instrumentation.disable(); import * as mysqlTypes from 'mysql'; import { AttributeNames } from '../src/AttributeNames'; -// Helper function to setup the database -const execPromise = (conn: mysqlTypes.Connection, command: string) => { - return new Promise((res, rej) => { - conn.query(command, err => { - if (err) rej(err); - else res(); - }); - }); -}; - describe('mysql@2.x-Tracing', () => { let contextManager: AsyncLocalStorageContextManager; let connection: mysqlTypes.Connection; @@ -81,23 +70,6 @@ describe('mysql@2.x-Tracing', () => { } else { done(); } - - // const connection = mysqlTypes.createConnection({ - // port, - // user: 'root', - // host, - // password: rootPassword, - // database, - // }); - // try { - // await execPromise(connection, `SET GLOBAL log_output='TABLE'`); - // await execPromise(connection, `SET GLOBAL general_log = 1`); - // } catch (execErr) { - // console.error('MySQL seup error: ', execErr); - // this.skip(); - // } finally { - // connection.end(); - // } }); beforeEach(() => { From 38ef4fed5236fee74baef190764ed9e497d6efa8 Mon Sep 17 00:00:00 2001 From: David Luna Date: Tue, 17 Jun 2025 10:49:18 +0200 Subject: [PATCH 05/14] chore: fix databae and port for mysql service --- test/docker-compose.yaml | 2 +- test/test-services.env | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/docker-compose.yaml b/test/docker-compose.yaml index f65a575f10..fc93d18cb6 100644 --- a/test/docker-compose.yaml +++ b/test/docker-compose.yaml @@ -59,7 +59,7 @@ services: environment: MYSQL_USER: "otel" MYSQL_PASSWORD: "secret" - MYSQL_DATABASE: "test_db" + MYSQL_DATABASE: "otel_mysql_database" MYSQL_ROOT_PASSWORD: "rootpw" ports: - "33306:3306" diff --git a/test/test-services.env b/test/test-services.env index 4a077bf3e5..ce9118cf66 100644 --- a/test/test-services.env +++ b/test/test-services.env @@ -16,7 +16,7 @@ MYSQL_DATABASE=otel_mysql_database MYSQL_HOST=127.0.0.1 MYSQL_PASSWORD=secret MYSQL_ROOT_PASSWORD=rootpw -MYSQL_PORT=3306 +MYSQL_PORT=33306 MYSQL_USER=otel OPENTELEMETRY_MEMCACHED_HOST=localhost OPENTELEMETRY_MEMCACHED_PORT=11211 From 864fe05ff7ce528ff739c12887fcc321f77f9185 Mon Sep 17 00:00:00 2001 From: David Luna Date: Tue, 17 Jun 2025 15:38:48 +0200 Subject: [PATCH 06/14] chore: fix env for pg instrumentation tests --- .../node/opentelemetry-instrumentation-pg/test/pg.test.ts | 2 +- test/docker-compose.yaml | 6 ++++-- test/test-services.env | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-pg/test/pg.test.ts b/plugins/node/opentelemetry-instrumentation-pg/test/pg.test.ts index 5b9b6f4f19..267e0b968a 100644 --- a/plugins/node/opentelemetry-instrumentation-pg/test/pg.test.ts +++ b/plugins/node/opentelemetry-instrumentation-pg/test/pg.test.ts @@ -64,7 +64,7 @@ const memoryExporter = new InMemorySpanExporter(); const CONFIG = { user: process.env.POSTGRES_USER || 'postgres', password: process.env.POSTGRES_PASSWORD || 'postgres', - database: process.env.POSTGRES_DB || 'postgres', + database: process.env.POSTGRES_DB || 'otel_pg_database', host: process.env.POSTGRES_HOST || 'localhost', port: process.env.POSTGRES_PORT ? parseInt(process.env.POSTGRES_PORT, 10) diff --git a/test/docker-compose.yaml b/test/docker-compose.yaml index fc93d18cb6..c4dbd2ec0c 100644 --- a/test/docker-compose.yaml +++ b/test/docker-compose.yaml @@ -12,7 +12,7 @@ name: opentelemetry-nodejs-test-services services: cassandra: - image: bitnami/cassandra:3 + image: cassandra:3 environment: MAX_HEAP_SIZE: "1G" HEAP_NEWSIZE: 400m @@ -56,6 +56,8 @@ services: mysql: image: mysql:5.7 + # No ARM64 image layer. See https://stackoverflow.com/a/65592942 + platform: linux/x86_64 environment: MYSQL_USER: "otel" MYSQL_PASSWORD: "secret" @@ -86,7 +88,7 @@ services: # https://github.com/docker-library/docs/blob/master/postgres/README.md#how-to-extend-this-image image: postgres:16-alpine ports: - - "5432:5432" + - "54320:5432" environment: POSTGRES_HOST_AUTH_METHOD: "trust" POSTGRES_USER: "postgres" diff --git a/test/test-services.env b/test/test-services.env index ce9118cf66..ed79732a1c 100644 --- a/test/test-services.env +++ b/test/test-services.env @@ -30,6 +30,6 @@ ORACLE_PASSWORD=secret ORACLE_SERVICENAME=FREEPDB1 POSTGRES_DB=otel_pg_database POSTGRES_HOST=localhost -POSTGRES_PORT=5432 +POSTGRES_PORT=54320 POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres \ No newline at end of file From 42a11237448382e836768b3476d25a4629305ec1 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 18 Jun 2025 11:48:16 +0200 Subject: [PATCH 07/14] chore: update docs --- CONTRIBUTING.md | 28 ++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1ee8e3479..7ac6bfcd50 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -135,6 +135,34 @@ The conventional commit type (in PR title) is very important to automatically bu There is no need to update the CHANGELOG in a PR because it will be updated as part of the release process (see [RELEASING.md](RELEASING.md) for more details). +### Testing + +Most unit tests case be run via: + +```sh +npm test +``` + +However, some instrumentations require test-services to be running (e.g. the `instrumentation-mongodb` package requires a MongoDB server). Use the `test-services`-related npm scripts to start all required services in Docker and then run the tests with the appropriate configuration to use those services: + +```sh +npm run test-services:start # starts services in Docker +npm run test:with-services-config # runs 'npm test' with envvars from test/test-services.env +npm run test-services:stop # stops services in Docker +``` + +If you only want to test a sigle package (e.g. the `instrumentation-mongodb`) you can `cd` into it and run the tests after you started the services. + +```sh +npm run test-services:start # starts services in Docker +cd plugins/node/opentelemetry-instrumentation-mongodb # get into the instrumenation folder +RUN_MONGODB_TESTS=1 npm test # run the test with the proper config (check each package) +cd ../../.. # go back to root folder +npm run test-services:stop # stops services in Docker +``` + +NOTE: scripts for each package will be added to avoid extra consumption of resources and improve the development experience. + ### Benchmarks When two or more approaches must be compared, please write a benchmark in the benchmark/index.js module so that we can keep track of the most efficient algorithm. diff --git a/package.json b/package.json index a0665501fc..5a629d0ba0 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "test-all-versions": "nx run-many -t test-all-versions", "test-services:start": "docker compose -f ./test/docker-compose.yaml up -d --wait", "test-services:stop": "docker compose -f ./test/docker-compose.yaml down", - "test:with-test-services": "NODE_OPTIONS='-r dotenv/config' DOTENV_CONFIG_PATH=./test/test-services.env npm test", + "test:with-services-config": "NODE_OPTIONS='-r dotenv/config' DOTENV_CONFIG_PATH=./test/test-services.env npm test", "changelog": "lerna-changelog", "lint": "nx run-many -t lint && npm run lint:deps && npm run lint:readme && npm run lint:markdown && npm run lint:semconv-deps", "lint:fix": "nx run-many -t lint:fix && npm run lint:markdown:fix", From 3815bcabebbc4b1c79c3402c5537ed3438527062 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 18 Jun 2025 12:42:40 +0200 Subject: [PATCH 08/14] chore: remove logs --- .../opentelemetry-instrumentation-mysql2/test/mysql.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts b/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts index 85dcec5b39..1169e1e3d3 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts @@ -369,8 +369,6 @@ describe('mysql2', () => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { connection.query('SELECT 1+1 as solution', (e, r) => { - console.log(e); - console.log(r); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); getLastQueries(1).then(([query]) => { From 7bf72e93ecd3928505458daa254020224f353175 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 25 Jun 2025 14:35:22 +0200 Subject: [PATCH 09/14] Update plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts Co-authored-by: Trent Mick --- .../node/opentelemetry-instrumentation-mysql/test/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts index 6437c21167..cd0ccc6e7f 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts @@ -55,7 +55,7 @@ describe('mysql@2.x-Tracing', () => { let poolCluster: mysqlTypes.PoolCluster; // assumes local mysql db is already available in CI or // using `npm run test-services:start` script at the root folder - const shouldTest = process.env.RUN_MYSQL_TESTS; // For CI: assumes local mysql db is already available + const shouldTest = process.env.RUN_MYSQL_TESTS; const memoryExporter = new InMemorySpanExporter(); const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], From 642e9a9d61889bd462d716104791db733e743f3c Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 25 Jun 2025 14:35:57 +0200 Subject: [PATCH 10/14] Update test/docker-compose.yaml Co-authored-by: Trent Mick --- test/docker-compose.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/docker-compose.yaml b/test/docker-compose.yaml index c4dbd2ec0c..7055807360 100644 --- a/test/docker-compose.yaml +++ b/test/docker-compose.yaml @@ -84,6 +84,7 @@ services: interval: 10s timeout: 5s retries: 30 + postgres: # https://github.com/docker-library/docs/blob/master/postgres/README.md#how-to-extend-this-image image: postgres:16-alpine From 9b6a94d13267437c5a32125d938a83a674613582 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 25 Jun 2025 14:36:06 +0200 Subject: [PATCH 11/14] Update test/docker-compose.yaml Co-authored-by: Trent Mick --- test/docker-compose.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/docker-compose.yaml b/test/docker-compose.yaml index 7055807360..8d01c47d7c 100644 --- a/test/docker-compose.yaml +++ b/test/docker-compose.yaml @@ -28,6 +28,7 @@ services: image: memcached:1.6.37-alpine ports: - 11211:11211 + mongodb: image: mongo:7 ports: From 2ba1b1197540164ebafbff3da155ecd1dd386449 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 25 Jun 2025 14:36:25 +0200 Subject: [PATCH 12/14] Update test/docker-compose.yaml Co-authored-by: Trent Mick --- test/docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/docker-compose.yaml b/test/docker-compose.yaml index 8d01c47d7c..973d500839 100644 --- a/test/docker-compose.yaml +++ b/test/docker-compose.yaml @@ -8,7 +8,7 @@ # npm run test-services:start [services...] # npm run test-services:stop [services...] -name: opentelemetry-nodejs-test-services +name: opentelemetry-js-contrib-test-services services: cassandra: From f832c977421fb8f826f87013126af2d128ac203c Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 25 Jun 2025 16:58:19 +0200 Subject: [PATCH 13/14] chore: add cross-env in test script --- package-lock.json | 1 + package.json | 3 ++- test/test-services.env | 32 ++++++++++++++++++++------------ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8120c33d03..d53696f4d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "devDependencies": { "@typescript-eslint/eslint-plugin": "5.8.1", "@typescript-eslint/parser": "5.8.1", + "cross-env": "^7.0.3", "eslint": "8.7.0", "eslint-config-airbnb-base": "15.0.0", "eslint-config-prettier": "8.8.0", diff --git a/package.json b/package.json index 5a629d0ba0..595c4a1ac5 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "test-all-versions": "nx run-many -t test-all-versions", "test-services:start": "docker compose -f ./test/docker-compose.yaml up -d --wait", "test-services:stop": "docker compose -f ./test/docker-compose.yaml down", - "test:with-services-config": "NODE_OPTIONS='-r dotenv/config' DOTENV_CONFIG_PATH=./test/test-services.env npm test", + "test:with-services-env": "cross-env NODE_OPTIONS='-r dotenv/config' DOTENV_CONFIG_PATH=./test/test-services.env npm test", "changelog": "lerna-changelog", "lint": "nx run-many -t lint && npm run lint:deps && npm run lint:readme && npm run lint:markdown && npm run lint:semconv-deps", "lint:fix": "nx run-many -t lint:fix && npm run lint:markdown:fix", @@ -46,6 +46,7 @@ "devDependencies": { "@typescript-eslint/eslint-plugin": "5.8.1", "@typescript-eslint/parser": "5.8.1", + "cross-env": "^7.0.3", "eslint": "8.7.0", "eslint-config-airbnb-base": "15.0.0", "eslint-config-prettier": "8.8.0", diff --git a/test/test-services.env b/test/test-services.env index ed79732a1c..4f8a62f10b 100644 --- a/test/test-services.env +++ b/test/test-services.env @@ -1,35 +1,43 @@ RUN_CASSANDRA_TESTS=1 +CASSANDRA_HOST=localhostç + RUN_MEMCACHED_TESTS=1 +OPENTELEMETRY_MEMCACHED_HOST=localhost +OPENTELEMETRY_MEMCACHED_PORT=11211 + RUN_MONGODB_TESTS=1 -RUN_MYSQL_TESTS=1 -RUN_MSSQL_TESTS=1 -RUN_ORACLEDB_TESTS=1 -RUN_POSTGRES_TESTS=1 -RUN_REDIS_TESTS=1 -RUN_RABBIT_TESTS=1 -CASSANDRA_HOST=localhost MONGODB_DB=opentelemetry-tests MONGODB_HOST=127.0.0.1 MONGODB_PORT=27017 + +RUN_MSSQL_TESTS=1 MSSQL_PASSWORD=mssql_passw0rd + +RUN_MYSQL_TESTS=1 MYSQL_DATABASE=otel_mysql_database MYSQL_HOST=127.0.0.1 MYSQL_PASSWORD=secret MYSQL_ROOT_PASSWORD=rootpw MYSQL_PORT=33306 MYSQL_USER=otel -OPENTELEMETRY_MEMCACHED_HOST=localhost -OPENTELEMETRY_MEMCACHED_PORT=11211 -OPENTELEMETRY_REDIS_HOST=localhost -OPENTELEMETRY_REDIS_PORT=6379 + +RUN_ORACLEDB_TESTS=1 ORACLE_HOSTNAME=localhost ORACLE_PORT=1521 ORACLE_CONNECTSTRING=localhost:1521/freepdb1 ORACLE_USER=otel ORACLE_PASSWORD=secret ORACLE_SERVICENAME=FREEPDB1 + +RUN_POSTGRES_TESTS=1 POSTGRES_DB=otel_pg_database POSTGRES_HOST=localhost POSTGRES_PORT=54320 POSTGRES_USER=postgres -POSTGRES_PASSWORD=postgres \ No newline at end of file +POSTGRES_PASSWORD=postgres + +RUN_REDIS_TESTS=1 +OPENTELEMETRY_REDIS_HOST=localhost +OPENTELEMETRY_REDIS_PORT=6379 + +RUN_RABBIT_TESTS=1 \ No newline at end of file From daee8876c4faa157e74d1ea88637bc723947eeef Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 25 Jun 2025 20:41:19 +0200 Subject: [PATCH 14/14] Update CONTRIBUTING.md Co-authored-by: Marc Pichler --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ac6bfcd50..95e527646e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -151,7 +151,7 @@ npm run test:with-services-config # runs 'npm test' with envvars from test/test- npm run test-services:stop # stops services in Docker ``` -If you only want to test a sigle package (e.g. the `instrumentation-mongodb`) you can `cd` into it and run the tests after you started the services. +If you only want to test a single package (e.g. the `instrumentation-mongodb`) you can `cd` into it and run the tests after you started the services. ```sh npm run test-services:start # starts services in Docker