Skip to content

Commit b2b2486

Browse files
committed
chore: move to assertion errors
1 parent bbf57f7 commit b2b2486

File tree

5 files changed

+57
-35
lines changed

5 files changed

+57
-35
lines changed

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { expect } from 'chai';
1+
import { AssertionError, expect } from 'chai';
22
import { EventEmitter } from 'events';
33

44
import {
@@ -303,7 +303,7 @@ export class UnifiedMongoClient extends MongoClient {
303303
case 'all':
304304
return [...this.commandEvents, ...this.cmapEvents, ...this.sdamEvents];
305305
default:
306-
throw new Error(`Unknown eventType: ${eventType}`);
306+
throw new AssertionError(`Unknown eventType: ${eventType}`);
307307
}
308308
}
309309

@@ -490,7 +490,7 @@ export class EntitiesMap<E = Entity> extends Map<string, E> {
490490
mapOf(type: EntityTypeId): EntitiesMap<Entity> {
491491
const ctor = ENTITY_CTORS.get(type);
492492
if (!ctor) {
493-
throw new Error(`Unknown type ${type}`);
493+
throw new AssertionError(`Unknown type ${type}`);
494494
}
495495
return new EntitiesMap(Array.from(this.entries()).filter(([, e]) => e instanceof ctor));
496496
}
@@ -522,7 +522,7 @@ export class EntitiesMap<E = Entity> extends Map<string, E> {
522522
getEntity(type: EntityTypeId, key: string, assertExists = true): Entity | undefined {
523523
const entity = this.get(key);
524524
if (!entity) {
525-
if (assertExists) throw new Error(`Entity '${key}' does not exist`);
525+
if (assertExists) throw new AssertionError(`Entity '${key}' does not exist`);
526526
return undefined;
527527
}
528528
if (NO_INSTANCE_CHECK.includes(type)) {
@@ -531,10 +531,10 @@ export class EntitiesMap<E = Entity> extends Map<string, E> {
531531
}
532532
const ctor = ENTITY_CTORS.get(type);
533533
if (!ctor) {
534-
throw new Error(`Unknown type ${type}`);
534+
throw new AssertionError(`Unknown type ${type}`);
535535
}
536536
if (!(entity instanceof ctor)) {
537-
throw new Error(`${key} is not an instance of ${type}`);
537+
throw new AssertionError(`${key} is not an instance of ${type}`);
538538
}
539539
return entity;
540540
}
@@ -672,13 +672,13 @@ export class EntitiesMap<E = Entity> extends Map<string, E> {
672672
} else if ('thread' in entity) {
673673
map.set(entity.thread.id, new UnifiedThread(entity.thread.id));
674674
} else if ('stream' in entity) {
675-
throw new Error(`Unsupported Entity ${JSON.stringify(entity)}`);
675+
throw new AssertionError(`Unsupported Entity ${JSON.stringify(entity)}`);
676676
} else if ('clientEncryption' in entity) {
677677
const clientEncryption = await createClientEncryption(map, entity.clientEncryption);
678678

679679
map.set(entity.clientEncryption.id, clientEncryption);
680680
} else {
681-
throw new Error(`Unsupported Entity ${JSON.stringify(entity)}`);
681+
throw new AssertionError(`Unsupported Entity ${JSON.stringify(entity)}`);
682682
}
683683
}
684684
return map;

test/tools/unified-spec-runner/entity_event_registry.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { AssertionError } from 'chai';
2+
13
import {
24
COMMAND_FAILED,
35
COMMAND_STARTED,
@@ -61,7 +63,7 @@ export class EntityEventRegistry {
6163
if (this.clientEntity.storeEventsAsEntities) {
6264
for (const { id, events } of this.clientEntity.storeEventsAsEntities) {
6365
if (this.entitiesMap.has(id) || this.clientEntity.id === id) {
64-
throw new Error(`Duplicate id ${id} found while storing events as entities`);
66+
throw new AssertionError(`Duplicate id ${id} found while storing events as entities`);
6567
}
6668
this.entitiesMap.set(id, []);
6769
for (const eventName of events) {

test/tools/unified-spec-runner/operations.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ type RunOperationFn = (
4444
) => Promise<Document | boolean | number | null | void | string>;
4545
export const operations = new Map<string, RunOperationFn>();
4646

47-
export class MalformedOperationError extends Error {}
47+
export class MalformedOperationError extends AssertionError {}
4848

4949
operations.set('createEntities', async ({ entities, operation, testConfig }) => {
5050
if (!operation.arguments?.entities) {
51-
throw new Error('encountered createEntities operation without entities argument');
51+
throw new AssertionError('encountered createEntities operation without entities argument');
5252
}
5353
await EntitiesMap.createEntities(testConfig, null, operation.arguments.entities!, entities);
5454
});
@@ -61,7 +61,7 @@ operations.set('abortTransaction', async ({ entities, operation }) => {
6161
operations.set('aggregate', async ({ entities, operation }) => {
6262
const dbOrCollection = entities.get(operation.object) as Db | Collection;
6363
if (!(dbOrCollection instanceof Db || dbOrCollection instanceof Collection)) {
64-
throw new Error(`Operation object '${operation.object}' must be a db or collection`);
64+
throw new AssertionError(`Operation object '${operation.object}' must be a db or collection`);
6565
}
6666
const { pipeline, ...opts } = operation.arguments!;
6767
const cursor = dbOrCollection.aggregate(pipeline, opts);
@@ -230,7 +230,7 @@ operations.set('close', async ({ entities, operation }) => {
230230
} catch {}
231231
/* eslint-enable no-empty */
232232

233-
throw new Error(`No closable entity with key ${operation.object}`);
233+
throw new AssertionError(`No closable entity with key ${operation.object}`);
234234
});
235235

236236
operations.set('commitTransaction', async ({ entities, operation }) => {
@@ -241,7 +241,7 @@ operations.set('commitTransaction', async ({ entities, operation }) => {
241241
operations.set('createChangeStream', async ({ entities, operation }) => {
242242
const watchable = entities.get(operation.object);
243243
if (watchable == null || !('watch' in watchable)) {
244-
throw new Error(`Entity ${operation.object} must be watchable`);
244+
throw new AssertionError(`Entity ${operation.object} must be watchable`);
245245
}
246246

247247
const { pipeline, ...args } = operation.arguments!;
@@ -587,7 +587,7 @@ operations.set('waitForEvent', async ({ entities, operation }) => {
587587
eventPromise,
588588
sleep(10000).then(() =>
589589
Promise.reject(
590-
new Error(
590+
new AssertionError(
591591
`Timed out waiting for ${eventName}; captured [${mongoClient
592592
.getCapturedEvents('all')
593593
.map(e => e.constructor.name)
@@ -682,7 +682,7 @@ operations.set('waitForPrimaryChange', async ({ entities, operation }) => {
682682
await Promise.race([
683683
newPrimaryPromise,
684684
sleep(timeoutMS ?? 10000).then(() =>
685-
Promise.reject(new Error(`Timed out waiting for primary change on ${client}`))
685+
Promise.reject(new AssertionError(`Timed out waiting for primary change on ${client}`))
686686
)
687687
]);
688688
});
@@ -702,7 +702,9 @@ operations.set('waitForThread', async ({ entities, operation }) => {
702702
const thread = entities.getEntity('thread', threadId, true);
703703
await Promise.race([
704704
thread.finish(),
705-
sleep(10000).then(() => Promise.reject(new Error(`Timed out waiting for thread: ${threadId}`)))
705+
sleep(10000).then(() =>
706+
Promise.reject(new AssertionError(`Timed out waiting for thread: ${threadId}`))
707+
)
706708
]);
707709
});
708710

@@ -755,10 +757,11 @@ operations.set('estimatedDocumentCount', async ({ entities, operation }) => {
755757
operations.set('runCommand', async ({ entities, operation }: OperationFunctionParams) => {
756758
const db = entities.getEntity('db', operation.object);
757759

758-
if (operation.arguments?.command == null) throw new Error('runCommand requires a command');
760+
if (operation.arguments?.command == null)
761+
throw new AssertionError('runCommand requires a command');
759762
const { command } = operation.arguments;
760763

761-
if (operation.arguments.timeoutMS != null) throw new Error('timeoutMS not supported');
764+
if (operation.arguments.timeoutMS != null) throw new AssertionError('timeoutMS not supported');
762765

763766
const options = {
764767
readPreference: operation.arguments.readPreference,

test/tools/unified-spec-runner/runner.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
/* eslint-disable @typescript-eslint/no-non-null-assertion */
2-
import { expect } from 'chai';
2+
import { AssertionError, expect } from 'chai';
33
import { gte as semverGte, satisfies as semverSatisfies } from 'semver';
44

55
import type { MongoClient } from '../../mongodb';
6-
import { MONGODB_ERROR_CODES, ns, ReadPreference, TopologyType } from '../../mongodb';
6+
import {
7+
MONGODB_ERROR_CODES,
8+
MongoParseError,
9+
MongoServerError,
10+
ns,
11+
ReadPreference,
12+
TopologyType
13+
} from '../../mongodb';
714
import { ejson } from '../utils';
815
import { AstrolabeResultsWriter } from './astrolabe_results_writer';
916
import { EntitiesMap, type UnifiedMongoClient } from './entities';
@@ -317,7 +324,14 @@ export function runUnifiedSuite(
317324
const error = await runUnifiedTest(this, unifiedSuite, test, skipFilter).catch(
318325
error => error
319326
);
320-
expect(error).to.exist;
327+
expect(error).to.satisfy(value => {
328+
return (
329+
value instanceof AssertionError ||
330+
value instanceof MongoServerError ||
331+
value instanceof TypeError ||
332+
value instanceof MongoParseError
333+
);
334+
});
321335
} else {
322336
await runUnifiedTest(this, unifiedSuite, test, skipFilter);
323337
}

test/tools/unified-spec-runner/unified-utils.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { EJSON } from 'bson';
2-
import { expect } from 'chai';
2+
import { AssertionError, expect } from 'chai';
33
import ConnectionString from 'mongodb-connection-string-url';
44
import { gte as semverGte, lte as semverLte } from 'semver';
55
import { isDeepStrictEqual } from 'util';
@@ -53,7 +53,7 @@ export async function topologySatisfies(
5353
}[config.topologyType];
5454

5555
if (!Array.isArray(r.topologies)) {
56-
throw new Error('Topology specification must be an array');
56+
throw new AssertionError('Topology specification must be an array');
5757
}
5858

5959
if (r.topologies.includes('sharded-replicaset') && topologyType === 'sharded') {
@@ -63,7 +63,7 @@ export async function topologySatisfies(
6363
skipReason = `requires sharded-replicaset but shards.length=${shards.length}`;
6464
}
6565
} else {
66-
if (!topologyType) throw new Error(`Topology undiscovered: ${config.topologyType}`);
66+
if (!topologyType) throw new AssertionError(`Topology undiscovered: ${config.topologyType}`);
6767
ok &&= r.topologies.includes(topologyType);
6868
if (!ok && skipReason == null) {
6969
skipReason = `requires ${r.topologies} but discovered a ${topologyType} topology`;
@@ -85,7 +85,8 @@ export async function topologySatisfies(
8585
}
8686

8787
if (r.serverParameters) {
88-
if (!config.parameters) throw new Error('Configuration does not have server parameters');
88+
if (!config.parameters)
89+
throw new AssertionError('Configuration does not have server parameters');
8990
for (const [name, value] of Object.entries(r.serverParameters)) {
9091
if (name in config.parameters) {
9192
ok &&= isDeepStrictEqual(config.parameters[name], value);
@@ -258,7 +259,7 @@ export function getCSFLETestDataFromEnvironment(environment: Record<string, stri
258259
tlsOptions: AutoEncryptionOptions['tlsOptions'];
259260
} {
260261
if (environment.CSFLE_KMS_PROVIDERS == null) {
261-
throw new Error(
262+
throw new AssertionError(
262263
'CSFLE_KMS_PROVIDERS is required to run the csfle tests. Please make sure it is set in the environment.'
263264
);
264265
}
@@ -268,17 +269,17 @@ export function getCSFLETestDataFromEnvironment(environment: Record<string, stri
268269
relaxed: false
269270
});
270271
} catch {
271-
throw new Error('Malformed CSFLE_KMS_PROVIDERS provided to unified tests.');
272+
throw new AssertionError('Malformed CSFLE_KMS_PROVIDERS provided to unified tests.');
272273
}
273274

274275
if (environment.KMIP_TLS_CA_FILE == null) {
275-
throw new Error(
276+
throw new AssertionError(
276277
'KMIP_TLS_CA_FILE is required to run the csfle tests. Please make sure it is set in the environment.'
277278
);
278279
}
279280

280281
if (environment.KMIP_TLS_CERT_FILE == null) {
281-
throw new Error(
282+
throw new AssertionError(
282283
'KMIP_TLS_CERT_FILE is required to run the csfle tests. Please make sure it is set in the environment.'
283284
);
284285
}
@@ -351,7 +352,9 @@ export function mergeKMSProviders(
351352
: test['sessionToken']);
352353

353354
if (!awsProviders['accessKeyId'] || !awsProviders['secretAccessKey']) {
354-
throw new Error('AWS KMS providers must constain "accessKeyId" and "secretAccessKey"');
355+
throw new AssertionError(
356+
'AWS KMS providers must constain "accessKeyId" and "secretAccessKey"'
357+
);
355358
}
356359

357360
return awsProviders;
@@ -385,7 +388,7 @@ export function mergeKMSProviders(
385388
!azureProviders['clientId'] ||
386389
!azureProviders['clientSecret']
387390
) {
388-
throw new Error(
391+
throw new AssertionError(
389392
'Azure KMS providers must contain "tenantId", "clientId", and "clientSecret"'
390393
);
391394
}
@@ -409,7 +412,7 @@ export function mergeKMSProviders(
409412
: test['endPoint']);
410413

411414
if (!gcpProviders['email'] || !gcpProviders['privateKey']) {
412-
throw new Error('GCP KMS providers must contain "email" and "privateKey"');
415+
throw new AssertionError('GCP KMS providers must contain "email" and "privateKey"');
413416
}
414417

415418
return gcpProviders;
@@ -514,7 +517,7 @@ export function mergeKMSProviders(
514517
}
515518

516519
if (Object.keys(providers).length === 0) {
517-
throw new Error('Found empty KMS providers in test');
520+
throw new AssertionError('Found empty KMS providers in test');
518521
}
519522

520523
return providers;
@@ -535,7 +538,7 @@ export async function createClientEncryption(
535538

536539
const clientEntity = map.getEntity('client', keyVaultClient, false);
537540
if (!clientEntity) {
538-
throw new Error(
541+
throw new AssertionError(
539542
'unable to get client entity required by client encryption entity in unified test'
540543
);
541544
}

0 commit comments

Comments
 (0)