From 6dbbe8d1e1e21d1443b6e476835cdcb572aa5385 Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Mon, 7 Aug 2023 19:40:11 +0200 Subject: [PATCH] test(NODE-3049): drivers atlas testing --- package.json | 1 + test/atlas/drivers_atlas_testing.test.ts | 22 ++++++++++ test/tools/runner/config.ts | 10 +++++ test/tools/unified-spec-runner/entities.ts | 9 +++- test/tools/unified-spec-runner/operations.ts | 44 ++++++++++++++++++++ 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 test/atlas/drivers_atlas_testing.test.ts diff --git a/package.json b/package.json index 741b47b9d9..a2367098ab 100644 --- a/package.json +++ b/package.json @@ -143,6 +143,7 @@ "check:unit": "mocha test/unit", "check:ts": "node ./node_modules/typescript/bin/tsc -v && node ./node_modules/typescript/bin/tsc --noEmit", "check:atlas": "mocha --config test/manual/mocharc.json test/manual/atlas_connectivity.test.js", + "check:drivers-atlas-testing": "mocha --config test/mocha_mongodb.json test/atlas/drivers_atlas_testing.test.ts", "check:adl": "mocha --config test/mocha_mongodb.json test/manual/atlas-data-lake-testing", "check:aws": "nyc mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_aws.test.ts", "check:oidc": "mocha --config test/mocha_mongodb.json test/manual/mongodb_oidc.prose.test.ts", diff --git a/test/atlas/drivers_atlas_testing.test.ts b/test/atlas/drivers_atlas_testing.test.ts new file mode 100644 index 0000000000..89ac82d5b8 --- /dev/null +++ b/test/atlas/drivers_atlas_testing.test.ts @@ -0,0 +1,22 @@ +import { writeFile } from 'node:fs/promises'; + +import * as path from 'path'; + +import { runUnifiedSuite } from '../tools/unified-spec-runner/runner'; + +describe('Node Driver Atlas Testing', async function () { + console.log('process.env', process.env); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const spec = JSON.parse(process.env.WORKLOAD_SPECIFICATION!); + runUnifiedSuite([spec]); + // Write the events.json to the execution directory. + await writeFile( + path.join(process.env.OUTPUT_DIRECTORY ?? '', 'events.json'), + JSON.stringify({ events: [], errors: [], failures: [] }) + ); + // Write the results.json to the execution directory. + await writeFile( + path.join(process.env.OUTPUT_DIRECTORY ?? '', 'results.json'), + JSON.stringify({ numErrors: 0, numFailures: 0, numSuccesses: 0, numIterations: 0 }) + ); +}); diff --git a/test/tools/runner/config.ts b/test/tools/runner/config.ts index a07f6373cc..e0a41cfcda 100644 --- a/test/tools/runner/config.ts +++ b/test/tools/runner/config.ts @@ -159,6 +159,11 @@ export class TestConfiguration { } newClient(dbOptions?: string | Record, serverOptions?: Record) { + if (process.env.DRIVERS_ATLAS_TESTING_URI) { + console.log('Using drivers Atlas testing URI', process.env.DRIVERS_ATLAS_TESTING_URI); + return new MongoClient(process.env.DRIVERS_ATLAS_TESTING_URI); + } + serverOptions = Object.assign({}, getEnvironmentalOptions(), serverOptions); // support MongoClient constructor form (url, options) for `newClient` @@ -258,6 +263,11 @@ export class TestConfiguration { ...options }; + if (process.env.DRIVERS_ATLAS_TESTING_URI) { + console.log('Using drivers Atlas testing URI', process.env.DRIVERS_ATLAS_TESTING_URI); + return process.env.DRIVERS_ATLAS_TESTING_URI; + } + const FILLER_HOST = 'fillerHost'; const protocol = this.isServerless ? 'mongodb+srv' : 'mongodb'; diff --git a/test/tools/unified-spec-runner/entities.ts b/test/tools/unified-spec-runner/entities.ts index c437a940e7..a1c56020f7 100644 --- a/test/tools/unified-spec-runner/entities.ts +++ b/test/tools/unified-spec-runner/entities.ts @@ -22,7 +22,7 @@ import { type ConnectionPoolReadyEvent, type ConnectionReadyEvent, Db, - type Document, + Document, GridFSBucket, type HostAddress, type Log, @@ -357,6 +357,7 @@ export type Entity = | AbstractCursor | UnifiedChangeStream | GridFSBucket + | Document | ClientEncryption | TopologyDescription // From recordTopologyDescription operation | Document; // Results from operations @@ -370,6 +371,7 @@ export type EntityCtor = | typeof AbstractCursor | typeof GridFSBucket | typeof UnifiedThread + | typeof Document | ClientEncryption; export type EntityTypeId = @@ -381,7 +383,8 @@ export type EntityTypeId = | 'thread' | 'cursor' | 'stream' - | 'clientEncryption'; + | 'clientEncryption' + | 'error'; const ENTITY_CTORS = new Map(); ENTITY_CTORS.set('client', UnifiedMongoClient); @@ -392,6 +395,7 @@ ENTITY_CTORS.set('bucket', GridFSBucket); ENTITY_CTORS.set('thread', UnifiedThread); ENTITY_CTORS.set('cursor', AbstractCursor); ENTITY_CTORS.set('stream', ChangeStream); +ENTITY_CTORS.set('error', Document); export class EntitiesMap extends Map { failPoints: FailPointMap; @@ -435,6 +439,7 @@ export class EntitiesMap extends Map { getEntity(type: 'thread', key: string, assertExists?: boolean): UnifiedThread; getEntity(type: 'cursor', key: string, assertExists?: boolean): AbstractCursor; getEntity(type: 'stream', key: string, assertExists?: boolean): UnifiedChangeStream; + getEntity(type: 'error', key: string, assertExists?: boolean): Document[]; getEntity(type: 'clientEncryption', key: string, assertExists?: boolean): ClientEncryption; getEntity(type: EntityTypeId, key: string, assertExists = true): Entity | undefined { const entity = this.get(key); diff --git a/test/tools/unified-spec-runner/operations.ts b/test/tools/unified-spec-runner/operations.ts index b5e5752aea..e7b4caf934 100644 --- a/test/tools/unified-spec-runner/operations.ts +++ b/test/tools/unified-spec-runner/operations.ts @@ -377,6 +377,50 @@ operations.set('listIndexes', async ({ entities, operation }) => { return collection.listIndexes(operation.arguments!).toArray(); }); +operations.set('loop', async ({ entities, operation, client, testConfig }) => { + const controller = new AbortController(); + process.on('SIGINT', () => { + controller.abort('Process received SIGINT, aborting operation loop.'); + }); + const args = operation.arguments!; + const storeIterationsAsEntity = args.storeIterationsAsEntity; + const storeSuccessesAsEntity = args.storeSuccessesAsEntity; + const storeErrorsAsEntity = args.storeErrorsAsEntity; + const storeFailuresAsEntity = args.storeFailuresAsEntity; + + if (storeErrorsAsEntity) { + entities.set(storeErrorsAsEntity, []); + } + if (storeFailuresAsEntity) { + entities.set(storeFailuresAsEntity, []); + } + let iterations = 0; + let successes = 0; + while (!controller.signal.aborted) { + if (storeIterationsAsEntity) { + entities.set(storeIterationsAsEntity, iterations++); + } + for (const op of args.operations) { + console.log('op', op); + try { + await executeOperationAndCheck(op, entities, client, testConfig); + if (storeSuccessesAsEntity) { + entities.set(storeSuccessesAsEntity, successes++); + } + } catch (error) { + console.log('error', error); + if (storeErrorsAsEntity) { + entities + .getEntity('error', storeErrorsAsEntity) + .push({ error: error.message, time: Date.now() }); + } else { + throw error; + } + } + } + } +}); + operations.set('replaceOne', async ({ entities, operation }) => { const collection = entities.getEntity('collection', operation.object); const { filter, replacement, ...opts } = operation.arguments!;