Skip to content

Commit 76634cb

Browse files
committed
pr feedback:
- removed unnecessary test checks - added more export types - made suggested fixes - added comments to tests being skipped
1 parent 7907619 commit 76634cb

11 files changed

Lines changed: 109 additions & 94 deletions

File tree

etc/build-runtime-barrel.mjs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import fs from 'node:fs/promises';
22
import path from 'node:path';
3-
import { fileURLToPath } from 'node:url';
43

54
// eslint-disable-next-line no-restricted-globals
65
const useBundled = process.env.MONGODB_BUNDLED === 'true';
76

8-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
9-
const rootDir = path.join(__dirname, '..');
7+
const rootDir = path.join(import.meta.dirname, '..');
108
const outputBarrelFile = path.join(rootDir, 'test/mongodb.ts');
119
const source = useBundled ? './mongodb_bundled' : './mongodb_all';
1210

etc/bundle-driver.mjs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ await esbuild.build({
2121
format: 'cjs',
2222
target: 'node20',
2323
external: [
24-
'bson',
25-
'mongodb-connection-string-url',
24+
'@aws-sdk/credential-providers',
2625
'@mongodb-js/saslprep',
2726
'@mongodb-js/zstd',
28-
'mongodb-client-encryption',
29-
'snappy',
3027
'@napi-rs/snappy*',
31-
'kerberos',
28+
'bson',
3229
'gcp-metadata',
33-
'@aws-sdk/credential-providers'
30+
'kerberos',
31+
'mongodb-client-encryption',
32+
'mongodb-connection-string-url',
33+
'snappy',
34+
'socks'
3435
],
3536
plugins: [
3637
{

src/client-side-encryption/providers/azure.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,7 @@ export async function fetchAzureKMSToken(
163163
const response = await get(url, { headers });
164164
return await parseResponse(response);
165165
} catch (error) {
166-
if (
167-
error instanceof MongoNetworkTimeoutError ||
168-
(error && error.constructor && error.constructor.name === 'MongoNetworkTimeoutError')
169-
) {
166+
if (error instanceof MongoNetworkTimeoutError) {
170167
throw new MongoCryptAzureKMSRequestError(`[Azure KMS] ${error.message}`);
171168
}
172169
throw error;

test/mongodb_all.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ export * from '../src/sdam/topology_description';
128128
export * from '../src/sessions';
129129
export * from '../src/sort';
130130
export * from '../src/timeout';
131+
export * from '../src/token_bucket';
131132
export * from '../src/transactions';
132133
export * from '../src/utils';
133134
export * from '../src/write_concern';

test/mongodb_bundled.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { loadContextifiedMongoDBModule } from './tools/runner/vm_context_helper'
33
type all = typeof import('./mongodb_all');
44
let exportSource: all;
55
try {
6-
exportSource = loadContextifiedMongoDBModule() as all;
6+
exportSource = loadContextifiedMongoDBModule();
77
} catch (error) {
88
throw new Error(
99
`Failed to load contextified MongoDB module: ${error instanceof Error ? error.message : String(error)}`
@@ -152,6 +152,7 @@ export const {
152152
HEARTBEAT_EVENTS,
153153
HostAddress,
154154
hostMatchesWildcards,
155+
INITIAL_TOKEN_BUCKET_SIZE,
155156
InsertOneOperation,
156157
InsertOperation,
157158
Int32,
@@ -450,8 +451,11 @@ import type {
450451
MongoClient as _MongoClient,
451452
MongoCredentials as _MongoCredentials,
452453
MongoError as _MongoError,
454+
Monitor as _Monitor,
455+
MonitorInterval as _MonitorInterval,
453456
ObjectId as _ObjectId,
454457
OnDemandDocument as _OnDemandDocument,
458+
RTTSampler as _RTTSampler,
455459
Server as _Server,
456460
ServerApiVersion as _ServerApiVersion,
457461
ServerClosedEvent as _ServerClosedEvent,
@@ -508,8 +512,11 @@ export type HostAddress = _HostAddress;
508512
export type MongoClient = _MongoClient;
509513
export type MongoCredentials = _MongoCredentials;
510514
export type MongoError = _MongoError;
515+
export type Monitor = _Monitor;
516+
export type MonitorInterval = _MonitorInterval;
511517
export type ObjectId = _ObjectId;
512518
export type OnDemandDocument = _OnDemandDocument;
519+
export type RTTSampler = _RTTSampler;
513520
export type Server = _Server;
514521
export type ServerApiVersion = _ServerApiVersion;
515522
export type ServerClosedEvent = _ServerClosedEvent;
Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* eslint-disable no-restricted-globals, @typescript-eslint/no-require-imports */
1+
/* eslint-disable @typescript-eslint/no-require-imports */
22

33
import * as fs from 'node:fs';
44
import { isBuiltin } from 'node:module';
@@ -15,10 +15,42 @@ const allowedModules = new Set([
1515
'mongodb-client-encryption',
1616
'mongodb-connection-string-url',
1717
'path',
18-
'snappy'
18+
'snappy',
19+
'socks'
1920
]);
2021
const blockedModules = new Set(['os']);
2122

23+
// TODO: NODE-7460 - Remove Error and other unnecessary exports
24+
const exposedGlobals = new Set([
25+
'AbortController',
26+
'AbortSignal',
27+
'BigInt',
28+
'Buffer',
29+
'Date',
30+
'Error',
31+
'Headers',
32+
'Map',
33+
'Math',
34+
'Promise',
35+
'TextDecoder',
36+
'TextEncoder',
37+
'URL',
38+
'URLSearchParams',
39+
40+
'console',
41+
'crypto',
42+
'performance',
43+
'process',
44+
45+
'clearImmediate',
46+
'clearInterval',
47+
'clearTimeout',
48+
'setImmediate',
49+
'setInterval',
50+
'setTimeout',
51+
'queueMicrotask'
52+
]);
53+
2254
/**
2355
* Creates a require function that blocks access to specified core modules
2456
*/
@@ -34,46 +66,12 @@ function createRestrictedRequire() {
3466
throw new Error(`Access to core module '${moduleName}' is restricted in this context`);
3567
}
3668
return require(moduleName);
37-
} as NodeRequire;
69+
} as NodeJS.Require;
3870
}
3971

40-
// Create a sandbox context with necessary globals
41-
const sandbox = vm.createContext({
72+
const context = {
4273
__proto__: null,
4374

44-
// Console and timing
45-
console: console,
46-
AbortController: AbortController,
47-
AbortSignal: AbortSignal,
48-
Date: global.Date,
49-
Error: global.Error,
50-
URL: global.URL,
51-
URLSearchParams: global.URLSearchParams,
52-
queueMicrotask: queueMicrotask,
53-
performance: global.performance,
54-
setTimeout: global.setTimeout,
55-
clearTimeout: global.clearTimeout,
56-
setInterval: global.setInterval,
57-
clearInterval: global.clearInterval,
58-
setImmediate: global.setImmediate,
59-
clearImmediate: global.clearImmediate,
60-
61-
// Process
62-
process: process,
63-
64-
// TODO: NODE-7460 - Remove Error and other unnecessary exports
65-
66-
// Global objects needed for runtime
67-
Buffer: Buffer,
68-
Headers: global.Headers,
69-
Map: Map,
70-
Promise: Promise,
71-
Math: Math,
72-
TextEncoder: global.TextEncoder,
73-
TextDecoder: global.TextDecoder,
74-
BigInt: global.BigInt,
75-
crypto: global.crypto,
76-
7775
// Custom require that blocks core modules
7876
require: createRestrictedRequire(),
7977

@@ -83,7 +81,17 @@ const sandbox = vm.createContext({
8381
// Needed for some modules
8482
global: undefined as any,
8583
globalThis: undefined as any
86-
});
84+
};
85+
86+
// Expose allowed globals in the context
87+
for (const globalName of exposedGlobals) {
88+
if (globalName in global) {
89+
context[globalName] = (global as any)[globalName];
90+
}
91+
}
92+
93+
// Create a sandbox context with necessary globals
94+
const sandbox = vm.createContext(context);
8795

8896
// Make global and globalThis point to the sandbox
8997
sandbox.global = sandbox;
@@ -93,7 +101,7 @@ sandbox.globalThis = sandbox;
93101
* Load the bundled MongoDB driver module in a VM context
94102
* This allows us to control the globals that the driver has access to
95103
*/
96-
export function loadContextifiedMongoDBModule() {
104+
export function loadContextifiedMongoDBModule(): typeof import('../../mongodb_all') {
97105
const bundlePath = path.join(__dirname, 'bundle/driver-bundle.js');
98106

99107
if (!fs.existsSync(bundlePath)) {
@@ -114,5 +122,5 @@ export function loadContextifiedMongoDBModule() {
114122
// Execute the bundle with the restricted require from the sandbox
115123
fn(moduleContainer.exports, moduleContainer, sandbox.require);
116124

117-
return moduleContainer.exports;
125+
return moduleContainer.exports as unknown as typeof import('../../mongodb_all');
118126
}

test/unit/assorted/server_discovery_and_monitoring.spec.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -195,22 +195,22 @@ describe('Server Discovery and Monitoring (spec)', function () {
195195
let serverConnect: sinon.SinonStub;
196196

197197
before(function () {
198-
if (runNodelessTests) {
199-
this.skip();
200-
}
201-
202198
serverConnect = sinon.stub(Server.prototype, 'connect').callsFake(function () {
203199
this.s.state = 'connected';
204200
this.emit('connect');
205201
});
206202
});
207203

208-
after(() => {
204+
after(function () {
205+
serverConnect.restore();
206+
});
207+
208+
beforeEach(function () {
209209
if (runNodelessTests) {
210-
return;
210+
this.currentTest.skipReason =
211+
'SDAM spec tests rely heavily on stubbing Connection behavior, which is not currently possible in nodeless environments';
212+
this.currentTest.skip();
211213
}
212-
213-
serverConnect.restore();
214214
});
215215

216216
const specTests = collectTests();

test/unit/client-side-encryption/providers/credentialsProvider.test.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import * as sinon from 'sinon';
66
// Intentionally import from src, because we need to stub the `get()` function.
77
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
88
import * as utils from '../../../../src/utils';
9-
import { runNodelessTests } from '../../../mongodb';
109
import {
1110
AWSSDKCredentialProvider,
1211
fetchAzureKMSToken,
@@ -24,12 +23,6 @@ const originalSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
2423
const originalSessionToken = process.env.AWS_SESSION_TOKEN;
2524

2625
describe('#refreshKMSCredentials', function () {
27-
before(function () {
28-
if (runNodelessTests) {
29-
this.skip();
30-
}
31-
});
32-
3326
context('isEmptyCredentials()', () => {
3427
it('returns true for an empty object', () => {
3528
expect(isEmptyCredentials('aws', { aws: {} })).to.be.true;

test/unit/cmap/handshake/client_metadata.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,9 @@ describe('client metadata module', () => {
318318
context('when globalThis indicates alternative runtime', () => {
319319
beforeEach(function () {
320320
if (runNodelessTests) {
321-
this.skip(); // these tests are meant to run in node and will fail in nodeless environments due to the presence of globalThis.Bun or globalThis.Deno
321+
this.currentTest.skipReason =
322+
'These tests are meant to run in node and will fail in nodeless environments';
323+
this.currentTest.skip();
322324
}
323325
});
324326

test/unit/commands.test.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@ import {
1616
} from '../mongodb';
1717

1818
describe('class OpCompressedRequest', () => {
19-
before(function () {
20-
if (runNodelessTests) {
21-
this.skip();
22-
}
23-
});
24-
2519
context('canCompress()', () => {
2620
for (const command of uncompressibleCommands) {
2721
it(`returns true when the command is ${command}`, () => {
@@ -96,20 +90,30 @@ describe('class OpCompressedRequest', () => {
9690
expect(compressedMessage).to.deep.equal(expectedCompressedCommand);
9791
});
9892

99-
it('respects the zlib compression level', async () => {
100-
const spy = sinon.spy(compression, 'compress');
101-
const [messageHeader] = await new OpCompressedRequest(msg, {
102-
agreedCompressor: 'snappy',
103-
zlibCompressionLevel: 3
104-
}).toBin();
93+
describe('zlib compression', function () {
94+
before(function () {
95+
if (runNodelessTests) {
96+
this.currentTest.skipReason =
97+
'This test relies on sinon spying on the compress() function, which is not currently possible in nodeless environments';
98+
this.currentTest.skip();
99+
}
100+
});
105101

106-
expect(messageHeader.readInt32LE(12), 'opcode is not OP_COMPRESSED').to.equal(2012);
102+
it('respects the zlib compression level', async function () {
103+
const spy = sinon.spy(compression, 'compress');
104+
const [messageHeader] = await new OpCompressedRequest(msg, {
105+
agreedCompressor: 'snappy',
106+
zlibCompressionLevel: 3
107+
}).toBin();
107108

108-
expect(spy).to.have.been.called;
109+
expect(messageHeader.readInt32LE(12), 'opcode is not OP_COMPRESSED').to.equal(2012);
109110

110-
expect(spy.args[0][0]).to.deep.equal({
111-
agreedCompressor: 'snappy',
112-
zlibCompressionLevel: 3
111+
expect(spy).to.have.been.called;
112+
113+
expect(spy.args[0][0]).to.deep.equal({
114+
agreedCompressor: 'snappy',
115+
zlibCompressionLevel: 3
116+
});
113117
});
114118
});
115119
});

0 commit comments

Comments
 (0)