Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NODE-6390): Add timeoutMS support to auto encryption #4265

Open
wants to merge 118 commits into
base: NODE-6090
Choose a base branch
from

Conversation

aditi-khare-mongoDB
Copy link
Contributor

@aditi-khare-mongoDB aditi-khare-mongoDB commented Oct 2, 2024

Description

Auto encryption encrypt and decrypt helpers now respect timeoutMS.

What is changing?

  • Added timeoutContext to stateMachine.execute call in AutoEncrypter.encrypt/decrypt
  • Integration tests for StateMachine helpers respecting timeoutMS
  • Integration tests for CryptoConnection.command respecting timeoutMS
  • Spec unit test for Auto Encryption
Is there new documentation needed for these changes?

No

What is the motivation for this change?

CSOT

Release Highlight

Double check the following

  • Ran npm run check:lint script
  • Self-review completed using the steps outlined here
  • PR title follows the correct format: type(NODE-xxxx)[!]: description
    • Example: feat(NODE-1234)!: rewriting everything in coffeescript
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

W-A-James and others added 30 commits September 12, 2024 13:43
lint

fix

prose test 2
…4243)

Co-authored-by: Warren James <[email protected]>
Co-authored-by: Neal Beeken <[email protected]>
Co-authored-by: Bailey Pearson <[email protected]>
});
childProcess = spawn(
'mongocryptd',
['--port', mongocryptdTestPort, '--ipv6', '--pidfilepath', new ObjectId().toHexString()],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a random pidfilepath ensure it doesn't use the default mongod pid path which can cause it to randomly fail

@aditi-khare-mongoDB aditi-khare-mongoDB marked this pull request as ready for review October 15, 2024 14:47
@baileympearson baileympearson self-assigned this Oct 15, 2024
@baileympearson baileympearson added the Primary Review In Review with primary reviewer, not yet ready for team's eyes label Oct 15, 2024
Copy link
Contributor

@baileympearson baileympearson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because evergreen is frozen today, I can't test the pidfile changes. But I think they should work.

await stateMachine.execute(
this,
context,
options.timeoutContext?.csotEnabled() ? options.timeoutContext : undefined
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
options.timeoutContext?.csotEnabled() ? options.timeoutContext : undefined
options.timeoutContext

It doesn't matter if the context is a csot context or a legacy context, we should be able to pass it in regardless.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

@@ -0,0 +1,251 @@
import { expect } from 'chai';
import * as sinon from 'sinon';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is poorly named, but driver.test.ts contains Node-driver specific tests for FLE. Can we move the tests from this file into driver.test.ts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved them!

});
childProcess = spawn(
'mongocryptd',
['--port', mongocryptdTestPort, '--ipv6', '--pidfilepath', new ObjectId().toHexString()],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we create the file in the temporary directory instead of the current directory?

const pidFile = path.join(
	os.tmpDir(),
 	new ObjectId().toHexString()
)

Also - how would you feel about making this change to the two other places our tests spawn mongocryptd? (search for spawn('mongo and three results should appear).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, made the change to the other instances too; I think it's a good call.

});
});

describe('State machine', function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have coverage for fetchCollectionInfo as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just added it in, good catch!

Comment on lines 138 to +141
client = new MongoClient(`mongodb://localhost:${mongocryptdTestPort}/?timeoutMS=1000`, {
monitorCommands: true
family: 6,
monitorCommands: true,
serverSelectionTimeoutMS: 2000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was nice-to-have for debugging locally, but doesn't need to be in the test permanently.

Suggested change
client = new MongoClient(`mongodb://localhost:${mongocryptdTestPort}/?timeoutMS=1000`, {
monitorCommands: true
family: 6,
monitorCommands: true,
serverSelectionTimeoutMS: 2000
client = new MongoClient(`mongodb://localhost:${mongocryptdTestPort}/?timeoutMS=1000`, {
monitorCommands: true,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted, just removed them!

});

it(
'the command should fail due to a timeout error',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test needs to fail something inside encryption. Otherwise, we don't have any coverage that asserts that we correctly pass the timeout context from CryptoConnection.command() -> AutoEncrypter.encrypt()/decrypt() -> StateMachine.execute() - this test currently ensures that we pass the timeout context from CryptoConnection.command() -> Connection.command().

I think this could pretty easily be achieved by configuring an auto encrypted client to use the same cluster as the keyvault (we can provided a keyvault client to the MongoClient when configuring auto encryption), and setting a failpoint on a find (used for list keys).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, made the change - added in data key creation

{
autoEncryption: {
keyVaultNamespace: 'admin.datakeys',
kmsProviders: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually obtain kmsProviders from the CSFLE_KMS_PROVIDERS environment variable (you can search for other usages of this in tests. I think range explicit encryption prose tests use this for a local kms provider, which is what you'd want). This requires FLE secrets to run locally - I can help you set this up if you'd like.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can set up FLE secrets locally another day - I'm fine just testing on EVG for this work. Switched it over to use CSFLE_KMS_PROVIDERS + require FLE variables to run.

});

context('when client is provided timeoutMS and command hangs', function () {
let encryptedClient;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(just a suggestion)

Suggested change
let encryptedClient;
let encryptedClient: MongoClient;

Then you get red underlines and type hinting when writing tests using the client.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made the change in the other parts of the file too!

Comment on lines 100 to 106
const err = await encryptedClient
.db('test')
.collection('test')
.aggregate([])
.toArray()
.catch(e => e);
expect(err).to.deep.equal([]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually, if we expect something not to fail, we don't catch the error because mocha considers a test to fail if an error is thrown:

Suggested change
const err = await encryptedClient
.db('test')
.collection('test')
.aggregate([])
.toArray()
.catch(e => e);
expect(err).to.deep.equal([]);
await encryptedClient
.db('test')
.collection('test')
.aggregate([])
.toArray()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this applies to other "should not fail" tests in this file too)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Primary Review In Review with primary reviewer, not yet ready for team's eyes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants