Skip to content

Commit 87d48fc

Browse files
committed
test: more Unified runner operations
Adds a number of operations, makes use of chai expect instead of boolean for assertions to track stack traces, adds session and bucket entity types. Passes utilClient through to operation functions which are" inlined into the operations map to get type checking to work. Modifies url helper function to make multipleMongoses detection work.
1 parent 19ba74a commit 87d48fc

File tree

8 files changed

+694
-611
lines changed

8 files changed

+694
-611
lines changed

test/functional/connection.test.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ describe('Connection - functional', function () {
144144
metadata: { requires: { topology: 'single' } },
145145

146146
test: function (done) {
147-
var configuration = this.configuration;
148-
var user = 'testConnectGoodAuth',
149-
password = 'password';
147+
const configuration = this.configuration;
148+
const username = 'testConnectGoodAuth';
149+
const password = 'password';
150150

151151
const setupClient = configuration.newClient();
152152

@@ -155,14 +155,14 @@ describe('Connection - functional', function () {
155155
expect(err).to.not.exist;
156156
var db = client.db(configuration.db);
157157

158-
db.addUser(user, password, function (err) {
158+
db.addUser(username, password, function (err) {
159159
expect(err).to.not.exist;
160160
client.close(restOfTest);
161161
});
162162
});
163163

164164
function restOfTest() {
165-
const testClient = configuration.newClient(configuration.url(user, password));
165+
const testClient = configuration.newClient(configuration.url({ username, password }));
166166
testClient.connect(
167167
connectionTester(configuration, 'testConnectGoodAuth', function (client) {
168168
client.close(done);
@@ -176,7 +176,7 @@ describe('Connection - functional', function () {
176176
metadata: { requires: { topology: 'single' } },
177177

178178
test: function (done) {
179-
var configuration = this.configuration;
179+
const configuration = this.configuration;
180180
const username = 'testConnectGoodAuthAsOption';
181181
const password = 'password';
182182

@@ -211,7 +211,9 @@ describe('Connection - functional', function () {
211211

212212
test: function (done) {
213213
var configuration = this.configuration;
214-
const client = configuration.newClient(configuration.url('slithy', 'toves'));
214+
const client = configuration.newClient(
215+
configuration.url({ username: 'slithy', password: 'toves' })
216+
);
215217
client.connect(function (err, client) {
216218
expect(err).to.exist;
217219
expect(client).to.not.exist;

test/functional/spec-runner/utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
function resolveConnectionString(configuration, spec, context) {
44
const isShardedEnvironment = configuration.topologyType === 'Sharded';
55
const useMultipleMongoses = spec && !!spec.useMultipleMongoses;
6-
const user = context && context.user;
6+
const username = context && context.user;
77
const password = context && context.password;
88
const authSource = context && context.authSource;
99
const connectionString =
1010
isShardedEnvironment && !useMultipleMongoses
1111
? `mongodb://${configuration.host}:${configuration.port}/${
1212
configuration.db
1313
}?directConnection=false${authSource ? '&authSource=${authSource}' : ''}`
14-
: configuration.url(user, password, { authSource });
14+
: configuration.url({ username, password, authSource });
1515
return connectionString;
1616
}
1717

test/functional/unified-spec-runner/entities.ts

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import { MongoClient, Db, Collection, GridFSBucket, Document } from '../../../src/index';
2+
import { ReadConcern } from '../../../src/read_concern';
3+
import { WriteConcern } from '../../../src/write_concern';
4+
import { ReadPreference } from '../../../src/read_preference';
25
import { ClientSession } from '../../../src/sessions';
36
import { ChangeStream } from '../../../src/change_stream';
47
import type { ClientEntity, EntityDescription } from './schema';
@@ -10,11 +13,16 @@ import type {
1013
import { patchCollectionOptions, patchDbOptions } from './unified-utils';
1114
import { TestConfiguration } from './unified.test';
1215
import { expect } from 'chai';
16+
import { parseURI } from '../../../src/connection_string';
1317

1418
interface UnifiedChangeStream extends ChangeStream {
1519
eventCollector: InstanceType<typeof import('../../tools/utils')['EventCollector']>;
1620
}
1721

22+
interface UnifiedClientSession extends ClientSession {
23+
client: UnifiedMongoClient;
24+
}
25+
1826
export type CommandEvent = CommandStartedEvent | CommandSucceededEvent | CommandFailedEvent;
1927

2028
export class UnifiedMongoClient extends MongoClient {
@@ -85,7 +93,7 @@ export type Entity =
8593
| UnifiedMongoClient
8694
| Db
8795
| Collection
88-
| ClientSession
96+
| UnifiedClientSession
8997
| UnifiedChangeStream
9098
| GridFSBucket
9199
| Document; // Results from operations
@@ -112,7 +120,7 @@ export class EntitiesMap<E = Entity> extends Map<string, E> {
112120
mapOf(type: 'client'): EntitiesMap<UnifiedMongoClient>;
113121
mapOf(type: 'db'): EntitiesMap<Db>;
114122
mapOf(type: 'collection'): EntitiesMap<Collection>;
115-
mapOf(type: 'session'): EntitiesMap<ClientSession>;
123+
mapOf(type: 'session'): EntitiesMap<UnifiedClientSession>;
116124
mapOf(type: 'bucket'): EntitiesMap<GridFSBucket>;
117125
mapOf(type: 'stream'): EntitiesMap<UnifiedChangeStream>;
118126
mapOf(type: EntityTypeId): EntitiesMap<Entity> {
@@ -126,13 +134,13 @@ export class EntitiesMap<E = Entity> extends Map<string, E> {
126134
getEntity(type: 'client', key: string, assertExists?: boolean): UnifiedMongoClient;
127135
getEntity(type: 'db', key: string, assertExists?: boolean): Db;
128136
getEntity(type: 'collection', key: string, assertExists?: boolean): Collection;
129-
getEntity(type: 'session', key: string, assertExists?: boolean): ClientSession;
137+
getEntity(type: 'session', key: string, assertExists?: boolean): UnifiedClientSession;
130138
getEntity(type: 'bucket', key: string, assertExists?: boolean): GridFSBucket;
131139
getEntity(type: 'stream', key: string, assertExists?: boolean): UnifiedChangeStream;
132140
getEntity(type: EntityTypeId, key: string, assertExists = true): Entity {
133141
const entity = this.get(key);
134142
if (!entity) {
135-
if (assertExists) throw new Error(`Entity ${key} does not exist`);
143+
if (assertExists) throw new Error(`Entity '${key}' does not exist`);
136144
return;
137145
}
138146
const ctor = ENTITY_CTORS.get(type);
@@ -163,7 +171,17 @@ export class EntitiesMap<E = Entity> extends Map<string, E> {
163171
const map = new EntitiesMap();
164172
for (const entity of entities ?? []) {
165173
if ('client' in entity) {
166-
const client = new UnifiedMongoClient(config.url(), entity.client);
174+
let uri = config.url();
175+
const { hosts, url } = parseURI(uri);
176+
177+
if (entity.client.useMultipleMongoses) {
178+
expect(hosts).to.have.length.greaterThan(1);
179+
} else if (entity.client.useMultipleMongoses === false) {
180+
url.host = hosts[0];
181+
uri = url.toString();
182+
}
183+
184+
const client = new UnifiedMongoClient(uri, entity.client);
167185
await client.connect();
168186
map.set(entity.client.id, client);
169187
} else if ('database' in entity) {
@@ -181,11 +199,60 @@ export class EntitiesMap<E = Entity> extends Map<string, E> {
181199
);
182200
map.set(entity.collection.id, collection);
183201
} else if ('session' in entity) {
184-
map.set(entity.session.id, null);
202+
const client = map.getEntity('client', entity.session.client);
203+
204+
const options = Object.create(null);
205+
206+
if (entity.session.sessionOptions?.causalConsistency) {
207+
options.causalConsistency = entity.session.sessionOptions?.causalConsistency;
208+
}
209+
210+
if (entity.session.sessionOptions?.defaultTransactionOptions) {
211+
options.defaultTransactionOptions = Object.create(null);
212+
const defaultOptions = entity.session.sessionOptions.defaultTransactionOptions;
213+
if (defaultOptions.readConcern) {
214+
options.defaultTransactionOptions.readConcern = ReadConcern.fromOptions(
215+
defaultOptions.readConcern
216+
);
217+
}
218+
if (defaultOptions.writeConcern) {
219+
options.defaultTransactionOptions.writeConcern = WriteConcern.fromOptions(
220+
defaultOptions
221+
);
222+
}
223+
if (defaultOptions.readPreference) {
224+
options.defaultTransactionOptions.readPreference = ReadPreference.fromOptions(
225+
defaultOptions.readPreference
226+
);
227+
}
228+
if (typeof defaultOptions.maxCommitTimeMS === 'number') {
229+
options.defaultTransactionOptions.maxCommitTimeMS = defaultOptions.maxCommitTimeMS;
230+
}
231+
}
232+
233+
const session = client.startSession(options) as UnifiedClientSession;
234+
// targetedFailPoint operations need to access the client the session came from
235+
session.client = client;
236+
237+
map.set(entity.session.id, session);
185238
} else if ('bucket' in entity) {
186-
map.set(entity.bucket.id, null);
239+
const db = map.getEntity('db', entity.bucket.database);
240+
241+
const options = Object.create(null);
242+
243+
if (entity.bucket.bucketOptions?.bucketName) {
244+
options.bucketName = entity.bucket.bucketOptions?.bucketName;
245+
}
246+
if (entity.bucket.bucketOptions?.chunkSizeBytes) {
247+
options.chunkSizeBytes = entity.bucket.bucketOptions?.chunkSizeBytes;
248+
}
249+
if (entity.bucket.bucketOptions?.readPreference) {
250+
options.readPreference = entity.bucket.bucketOptions?.readPreference;
251+
}
252+
253+
map.set(entity.bucket.id, new GridFSBucket(db, options));
187254
} else if ('stream' in entity) {
188-
map.set(entity.stream.id, null);
255+
throw new Error(`Unsupported Entity ${JSON.stringify(entity)}`);
189256
} else {
190257
throw new Error(`Unsupported Entity ${JSON.stringify(entity)}`);
191258
}

0 commit comments

Comments
 (0)