From 41d4f0d8e9944a47e9a1e5385aa3303b921382cc Mon Sep 17 00:00:00 2001 From: Warren James Date: Thu, 11 May 2023 11:46:32 -0400 Subject: [PATCH] test(NODE-4772): mongocryptd is not spawned when shared library is loaded (#3661) Co-authored-by: Bailey Pearson --- .evergreen/run-kms-servers.sh | 2 + .../client_side_encryption.prose.test.js | 80 ++++++++++++++++++- test/tools/utils.ts | 9 ++- 3 files changed, 88 insertions(+), 3 deletions(-) mode change 100644 => 100755 .evergreen/run-kms-servers.sh diff --git a/.evergreen/run-kms-servers.sh b/.evergreen/run-kms-servers.sh old mode 100644 new mode 100755 index 94bd0c7b35..7b54123173 --- a/.evergreen/run-kms-servers.sh +++ b/.evergreen/run-kms-servers.sh @@ -1,3 +1,5 @@ +#!/bin/bash + cd ${DRIVERS_TOOLS}/.evergreen/csfle . ./activate-kmstlsvenv.sh # by default it always runs on port 5698 diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.test.js b/test/integration/client-side-encryption/client_side_encryption.prose.test.js index eca048150d..047101bf77 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.test.js +++ b/test/integration/client-side-encryption/client_side_encryption.prose.test.js @@ -9,11 +9,15 @@ const { dropCollection, APMEventCollector } = require('../shared'); const { EJSON } = BSON; const { LEGACY_HELLO_COMMAND } = require('../../mongodb'); -const { MongoServerError } = require('../../mongodb'); +const { MongoServerError, MongoServerSelectionError, MongoClient } = require('../../mongodb'); const { getEncryptExtraOptions } = require('../../tools/utils'); const { installNodeDNSWorkaroundHooks } = require('../../tools/runner/hooks/configuration'); const { coerce, gte } = require('semver'); +const { + externalSchema +} = require('../../spec/client-side-encryption/external/external-schema.json'); + const getKmsProviders = (localKey, kmipEndpoint, azureEndpoint, gcpEndpoint) => { const result = BSON.EJSON.parse(process.env.CSFLE_KMS_PROVIDERS || '{}'); if (localKey) { @@ -1106,6 +1110,80 @@ describe('Client Side Encryption Prose Tests', metadata, function () { it.skip('Via bypassAutoEncryption', () => {}).skipReason = 'TODO(NODE-2422): Implement "Bypass spawning mongocryptd" tests'; + + describe('via loading shared library', function () { + let clientEncrypted; + let client; + beforeEach(function () { + const { cryptSharedLibPath } = getEncryptExtraOptions(); + if (!cryptSharedLibPath) { + this.currentTest.skipReason = + 'test requires that the shared library is present, but CRYPT_SHARED_LIB_PATH is unset.'; + this.skip(); + } + }); + + // Setup + beforeEach(async function () { + const { cryptSharedLibPath } = getEncryptExtraOptions(); + // 1. Create a MongoClient configured with auto encryption (referred to as `client_encrypted`) + clientEncrypted = this.configuration.newClient( + {}, + { + // 2. Configure the required options. use the `local` KMS provider as follows: + // ```javascript + // { "local" : {"key": } } + // ``` + // configure with the `keyVaultNamespace` set to `keyvault.datakeys` + // configure with `client_encrypted` to use the schema `external/external-schema.json` for + // `db.coll` by setting a schema map like `{"db.coll": ", + // "cryptSharedRequired": true + // } + extraOptions: { + mongocryptdURI: 'mongodb://localhost:27021/db?serverSelectionTimeoutMS=1000', + mongocryptdSpawnArgs: [ + '--pidfilepath=bypass-spawning-mongocryptd.pid', + '--port=27021' + ], + cryptdSharedLibRequired: true, + cryptSharedLibPath + }, + schemaMap: externalSchema + } + } + ); + // 3. Use `client_encrypted` to insert the document `{"unencrypted": "test"}` into `db.coll` + // expect this to succeed + await clientEncrypted.connect(); + const insertResult = await clientEncrypted + .db(dataDbName) + .collection(dataCollName) + .insertOne({ unencrypted: 'test' }); + expect(insertResult).to.have.property('insertedId'); + }); + + afterEach(async function () { + await clientEncrypted?.close(); + await client?.close(); + }); + + // 4. Validate that mongocryptd was not spawned. Create a MongoClient to localhost:27021 (or + // whatever was passed via `--port` with serverSelectionTimeoutMS=1000.) Run a handshake + // command and ensure it fails with a server selection timeout + it('should not spawn mongocryptd', metadata, async function () { + client = new MongoClient('mongodb://localhost:27021/db?serverSelectionTimeoutMS=1000'); + const error = await client.connect().catch(e => e); + expect(error).to.be.instanceOf(MongoServerSelectionError, /'Server selection timed out'/i); + }); + }); }); describe('Deadlock tests', () => { diff --git a/test/tools/utils.ts b/test/tools/utils.ts index fc19a6a6e5..e062ff930a 100644 --- a/test/tools/utils.ts +++ b/test/tools/utils.ts @@ -93,8 +93,13 @@ export class EventCollector { } } -export function getEncryptExtraOptions() { - if (process.env.CRYPT_SHARED_LIB_PATH) { +export function getEncryptExtraOptions(): { + cryptSharedLibPath?: string; +} { + if ( + typeof process.env.CRYPT_SHARED_LIB_PATH === 'string' && + process.env.CRYPT_SHARED_LIB_PATH.length > 0 + ) { return { cryptSharedLibPath: process.env.CRYPT_SHARED_LIB_PATH }; } return {};