Skip to content

Commit 8194a43

Browse files
restructure tests
1 parent 5e00103 commit 8194a43

1 file changed

Lines changed: 143 additions & 220 deletions

File tree

test/integration/node-specific/auto_encrypter.test.ts

Lines changed: 143 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ import {
1818
StateMachine
1919
} from '../../mongodb';
2020
import { ClientSideEncryptionFilter } from '../../tools/runner/filters/client_encryption_filter';
21-
import { getEncryptExtraOptions } from '../../tools/utils';
2221

2322
const { EJSON } = BSON;
24-
const cryptShared = (status: 'enabled' | 'disabled') => () => {
23+
export const cryptShared = (status: 'enabled' | 'disabled') => () => {
2524
const isCryptSharedLoaded = ClientSideEncryptionFilter.cryptShared != null;
2625

2726
if (status === 'enabled') {
@@ -51,7 +50,7 @@ const MOCK_MONGOCRYPTD_RESPONSE = readExtendedJsonToBuffer(dataPath(`mongocryptd
5150
const MOCK_KEYDOCUMENT_RESPONSE = readExtendedJsonToBuffer(dataPath(`key-document.json`));
5251
const MOCK_KMS_DECRYPT_REPLY = readHttpResponse(dataPath(`kms-decrypt-reply.txt`));
5352

54-
describe.only('crypt_shared library', function () {
53+
describe.only('mongocryptd auto spawn', function () {
5554
let client: MongoClient;
5655
let autoEncrypter: AutoEncrypter | undefined;
5756

@@ -92,227 +91,151 @@ describe.only('crypt_shared library', function () {
9291
sandbox.restore();
9392
});
9493

95-
describe('autoSpawn', function () {
96-
it(
97-
'should autoSpawn a mongocryptd on init by default',
98-
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
99-
100-
async function () {
101-
autoEncrypter = new AutoEncrypter(client, {
102-
keyVaultNamespace: 'admin.datakeys',
103-
kmsProviders: {
104-
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
105-
local: { key: Buffer.alloc(96) }
106-
}
107-
});
108-
109-
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
110-
111-
const localMcdm = autoEncrypter._mongocryptdManager;
112-
sandbox.spy(localMcdm, 'spawn');
113-
114-
await autoEncrypter.init();
115-
expect(localMcdm.spawn).to.have.been.calledOnce;
116-
}
117-
);
118-
119-
it(
120-
'should not attempt to kick off mongocryptd on a normal error',
121-
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
122-
async function () {
123-
let called = false;
124-
StateMachine.prototype.markCommand.callsFake(async (_client, _ns, _filter) => {
125-
if (!called) {
126-
called = true;
127-
throw new Error('msg');
128-
}
129-
130-
return MOCK_MONGOCRYPTD_RESPONSE;
131-
});
132-
133-
autoEncrypter = new AutoEncrypter(client, {
134-
keyVaultNamespace: 'admin.datakeys',
135-
kmsProviders: {
136-
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
137-
local: { key: Buffer.alloc(96) }
138-
}
139-
});
140-
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
141-
142-
const localMcdm = autoEncrypter._mongocryptdManager;
143-
await autoEncrypter.init();
144-
145-
sandbox.spy(localMcdm, 'spawn');
146-
147-
const err = await autoEncrypter.encrypt('test.test', TEST_COMMAND).catch(e => e);
148-
expect(localMcdm.spawn).to.not.have.been.called;
149-
expect(err).to.be.an.instanceOf(Error);
150-
}
151-
);
152-
153-
it(
154-
'should restore the mongocryptd and retry once if a MongoNetworkTimeoutError is experienced',
155-
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
156-
async function () {
157-
let called = false;
158-
StateMachine.prototype.markCommand.callsFake(async (_client, _ns, _filter) => {
159-
if (!called) {
160-
called = true;
161-
throw new MongoNetworkTimeoutError('msg');
162-
}
163-
164-
return MOCK_MONGOCRYPTD_RESPONSE;
165-
});
166-
167-
autoEncrypter = new AutoEncrypter(client, {
168-
keyVaultNamespace: 'admin.datakeys',
169-
kmsProviders: {
170-
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
171-
local: { key: Buffer.alloc(96) }
172-
}
173-
});
174-
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
175-
176-
const localMcdm = autoEncrypter._mongocryptdManager;
177-
await autoEncrypter.init();
178-
179-
sandbox.spy(localMcdm, 'spawn');
180-
181-
await autoEncrypter.encrypt('test.test', TEST_COMMAND);
182-
expect(localMcdm.spawn).to.have.been.calledOnce;
183-
}
184-
);
185-
186-
it(
187-
'should propagate error if MongoNetworkTimeoutError is experienced twice in a row',
188-
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
189-
async function () {
190-
let counter = 2;
191-
StateMachine.prototype.markCommand.callsFake(async (_client, _ns, _filter) => {
192-
if (counter) {
193-
counter -= 1;
194-
throw new MongoNetworkTimeoutError('msg');
195-
}
196-
197-
return MOCK_MONGOCRYPTD_RESPONSE;
198-
});
199-
200-
autoEncrypter = new AutoEncrypter(client, {
201-
keyVaultNamespace: 'admin.datakeys',
202-
kmsProviders: {
203-
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
204-
local: { key: Buffer.alloc(96) }
205-
}
206-
});
207-
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
208-
209-
const localMcdm = autoEncrypter._mongocryptdManager;
210-
await autoEncrypter.init();
211-
212-
sandbox.spy(localMcdm, 'spawn');
213-
214-
const err = await autoEncrypter.encrypt('test.test', TEST_COMMAND).catch(e => e);
215-
expect(localMcdm.spawn).to.have.been.calledOnce;
216-
expect(err).to.be.an.instanceof(MongoNetworkTimeoutError);
217-
}
218-
);
219-
220-
it(
221-
'should return a useful message if mongocryptd fails to autospawn',
222-
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
223-
async function () {
224-
autoEncrypter = new AutoEncrypter(client, {
225-
keyVaultNamespace: 'admin.datakeys',
226-
kmsProviders: {
227-
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
228-
local: { key: Buffer.alloc(96) }
229-
},
230-
extraOptions: {
231-
mongocryptdURI: 'mongodb://something.invalid:27020/'
232-
}
233-
});
234-
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
235-
236-
sandbox.stub(MongocryptdManager.prototype, 'spawn').resolves();
237-
238-
const err = await autoEncrypter.init().catch(e => e);
239-
expect(err).to.exist;
240-
expect(err).to.be.instanceOf(MongoError);
241-
}
242-
);
243-
});
94+
it(
95+
'should autoSpawn a mongocryptd on init by default',
96+
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
24497

245-
describe('crypt shared library', () => {
246-
it('should fail if no library can be found in the search path and cryptSharedLibRequired is set', async function () {
247-
const env = {
248-
MONGODB_URI: this.configuration.url(),
249-
EXTRA_OPTIONS: JSON.stringify({
250-
cryptSharedLibSearchPaths: ['/nonexistent'],
251-
cryptSharedLibRequired: true
252-
})
253-
};
254-
const file = `${__dirname}/../../tools/fixtures/shared_library_test.js`;
255-
const { stderr } = spawnSync(process.execPath, [file], {
256-
env,
257-
encoding: 'utf-8'
98+
async function () {
99+
autoEncrypter = new AutoEncrypter(client, {
100+
keyVaultNamespace: 'admin.datakeys',
101+
kmsProviders: {
102+
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
103+
local: { key: Buffer.alloc(96) }
104+
}
258105
});
259106

260-
expect(stderr).to.include('`cryptSharedLibRequired` set but no crypt_shared library loaded');
261-
});
107+
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
108+
109+
const localMcdm = autoEncrypter._mongocryptdManager;
110+
sandbox.spy(localMcdm, 'spawn');
111+
112+
await autoEncrypter.init();
113+
expect(localMcdm.spawn).to.have.been.calledOnce;
114+
}
115+
);
116+
117+
it(
118+
'should not attempt to kick off mongocryptd on a normal error',
119+
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
120+
async function () {
121+
let called = false;
122+
StateMachine.prototype.markCommand.callsFake(async (_client, _ns, _filter) => {
123+
if (!called) {
124+
called = true;
125+
throw new Error('msg');
126+
}
127+
128+
return MOCK_MONGOCRYPTD_RESPONSE;
129+
});
262130

263-
it(
264-
'should load a shared library by specifying its path',
265-
{
266-
requires: {
267-
predicate: cryptShared('enabled')
131+
autoEncrypter = new AutoEncrypter(client, {
132+
keyVaultNamespace: 'admin.datakeys',
133+
kmsProviders: {
134+
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
135+
local: { key: Buffer.alloc(96) }
268136
}
269-
},
270-
async function () {
271-
const env = {
272-
MONGODB_URI: this.configuration.url(),
273-
EXTRA_OPTIONS: JSON.stringify({
274-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
275-
cryptSharedLibPath: getEncryptExtraOptions().cryptSharedLibPath!
276-
})
277-
};
278-
const file = `${__dirname}/../../tools/fixtures/shared_library_test.js`;
279-
const { stdout } = spawnSync(process.execPath, [file], { env, encoding: 'utf-8' });
280-
281-
const response = EJSON.parse(stdout, { useBigInt64: true });
282-
283-
expect(response).not.to.be.null;
284-
285-
expect(response).to.have.property('version').that.is.a('bigint');
286-
expect(response).to.have.property('versionStr').that.is.a('string');
287-
}
288-
);
289-
290-
it(
291-
'should load a shared library by specifying a search path',
292-
{
293-
requires: {
294-
predicate: cryptShared('enabled')
137+
});
138+
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
139+
140+
const localMcdm = autoEncrypter._mongocryptdManager;
141+
await autoEncrypter.init();
142+
143+
sandbox.spy(localMcdm, 'spawn');
144+
145+
const err = await autoEncrypter.encrypt('test.test', TEST_COMMAND).catch(e => e);
146+
expect(localMcdm.spawn).to.not.have.been.called;
147+
expect(err).to.be.an.instanceOf(Error);
148+
}
149+
);
150+
151+
it(
152+
'should restore the mongocryptd and retry once if a MongoNetworkTimeoutError is experienced',
153+
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
154+
async function () {
155+
let called = false;
156+
StateMachine.prototype.markCommand.callsFake(async (_client, _ns, _filter) => {
157+
if (!called) {
158+
called = true;
159+
throw new MongoNetworkTimeoutError('msg');
295160
}
296-
},
297-
async function () {
298-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
299-
const cryptDir = dirname(getEncryptExtraOptions().cryptSharedLibPath!);
300-
const env = {
301-
MONGODB_URI: this.configuration.url(),
302-
EXTRA_OPTIONS: JSON.stringify({
303-
cryptSharedLibSearchPaths: [cryptDir]
304-
})
305-
};
306-
const file = `${__dirname}/../../tools/fixtures/shared_library_test.js`;
307-
const { stdout } = spawnSync(process.execPath, [file], { env, encoding: 'utf-8' });
308-
309-
const response = EJSON.parse(stdout, { useBigInt64: true });
310-
311-
expect(response).not.to.be.null;
312-
313-
expect(response).to.have.property('version').that.is.a('bigint');
314-
expect(response).to.have.property('versionStr').that.is.a('string');
315-
}
316-
);
317-
});
161+
162+
return MOCK_MONGOCRYPTD_RESPONSE;
163+
});
164+
165+
autoEncrypter = new AutoEncrypter(client, {
166+
keyVaultNamespace: 'admin.datakeys',
167+
kmsProviders: {
168+
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
169+
local: { key: Buffer.alloc(96) }
170+
}
171+
});
172+
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
173+
174+
const localMcdm = autoEncrypter._mongocryptdManager;
175+
await autoEncrypter.init();
176+
177+
sandbox.spy(localMcdm, 'spawn');
178+
179+
await autoEncrypter.encrypt('test.test', TEST_COMMAND);
180+
expect(localMcdm.spawn).to.have.been.calledOnce;
181+
}
182+
);
183+
184+
it(
185+
'should propagate error if MongoNetworkTimeoutError is experienced twice in a row',
186+
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
187+
async function () {
188+
let counter = 2;
189+
StateMachine.prototype.markCommand.callsFake(async (_client, _ns, _filter) => {
190+
if (counter) {
191+
counter -= 1;
192+
throw new MongoNetworkTimeoutError('msg');
193+
}
194+
195+
return MOCK_MONGOCRYPTD_RESPONSE;
196+
});
197+
198+
autoEncrypter = new AutoEncrypter(client, {
199+
keyVaultNamespace: 'admin.datakeys',
200+
kmsProviders: {
201+
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
202+
local: { key: Buffer.alloc(96) }
203+
}
204+
});
205+
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
206+
207+
const localMcdm = autoEncrypter._mongocryptdManager;
208+
await autoEncrypter.init();
209+
210+
sandbox.spy(localMcdm, 'spawn');
211+
212+
const err = await autoEncrypter.encrypt('test.test', TEST_COMMAND).catch(e => e);
213+
expect(localMcdm.spawn).to.have.been.calledOnce;
214+
expect(err).to.be.an.instanceof(MongoNetworkTimeoutError);
215+
}
216+
);
217+
218+
it(
219+
'should return a useful message if mongocryptd fails to autospawn',
220+
{ requires: { clientSideEncryption: true, predicate: cryptShared('disabled') } },
221+
async function () {
222+
autoEncrypter = new AutoEncrypter(client, {
223+
keyVaultNamespace: 'admin.datakeys',
224+
kmsProviders: {
225+
aws: { accessKeyId: 'example', secretAccessKey: 'example' },
226+
local: { key: Buffer.alloc(96) }
227+
},
228+
extraOptions: {
229+
mongocryptdURI: 'mongodb://something.invalid:27020/'
230+
}
231+
});
232+
expect(autoEncrypter).to.have.property('cryptSharedLibVersionInfo', null);
233+
234+
sandbox.stub(MongocryptdManager.prototype, 'spawn').resolves();
235+
236+
const err = await autoEncrypter.init().catch(e => e);
237+
expect(err).to.exist;
238+
expect(err).to.be.instanceOf(MongoError);
239+
}
240+
);
318241
});

0 commit comments

Comments
 (0)