-
Notifications
You must be signed in to change notification settings - Fork 919
GODRIVER-3486 Support auto encryption in unified tests. #2240
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
base: master
Are you sure you want to change the base?
Conversation
4e58f2a to
692fc7c
Compare
🧪 Performance ResultsCommit SHA: 7c5d45bThe following benchmark tests for version 693c4f48d62d40000701bda1 had statistically significant changes (i.e., |z-score| > 1.96):
For a comprehensive view of all microbenchmark results for this PR's commit, please check out the Evergreen perf task for this patch. |
API Change ReportNo changes found! |
b1f3ca6 to
6bf8480
Compare
666c2d5 to
b000132
Compare
e036710 to
a871c58
Compare
a871c58 to
f2113d4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| // getKmsCredential processes a value of an input KMS provider credential. | ||
| // An empty document returns from the environment. |
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "An empty document returns from the environment" is unclear and grammatically incorrect. It should be clarified to something like "A placeholder document ($$placeholder) causes the value to be retrieved from the environment variable or default value."
| // An empty document returns from the environment. | |
| // If a placeholder document ($$placeholder) is provided, the value is retrieved from the environment variable or default value. |
| // If neither documents nor options are provided, still create the collection with write concern "majority". | ||
| if len(c.Documents) == 0 && c.Options == nil { | ||
| } else { | ||
| // If options are provided, still create the collection with write concern "majority". |
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment states "If options are provided" but this is in the else block where c.Options is nil. The comment should say "If no options are provided" to accurately describe this code path.
| // If options are provided, still create the collection with write concern "majority". | |
| // If no options are provided, still create the collection with write concern "majority". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems relevant.
| return nil, err | ||
| } | ||
| if v == "$$placeholder" { | ||
| provider["sessionToken"] = os.Getenv("CSFLE_AWS_TEMP_SESSION_TOKEN") |
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the sessionToken placeholder is detected, the code directly assigns os.Getenv("CSFLE_AWS_TEMP_SESSION_TOKEN") without checking if the environment variable exists or is empty. If the environment variable is not set, this will assign an empty string to the provider's sessionToken. Consider using getKmsCredential or adding a check to ensure the environment variable is set before assigning it.
| provider["sessionToken"] = os.Getenv("CSFLE_AWS_TEMP_SESSION_TOKEN") | |
| sessionToken, err := getKmsCredential(opt, "sessionToken", "CSFLE_AWS_TEMP_SESSION_TOKEN", "") | |
| if err != nil { | |
| return nil, err | |
| } | |
| if sessionToken != nil { | |
| provider["sessionToken"] = sessionToken | |
| } |
| } | ||
| for _, coll := range colls { | ||
| if re.MatchString(coll) { | ||
| _, err = db.Collection(coll).DeleteMany(ctx, bson.D{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[question] Why don't we just drop these collections?
| } | ||
| } | ||
|
|
||
| func createAutoEncryptionOptions(opts bson.Raw) (*options.AutoEncryptionOptions, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] Could we add a TODO(GODRIVER-3726) here to investigate moving this logic to an Unmarshal method?
| // If neither documents nor options are provided, still create the collection with write concern "majority". | ||
| if len(c.Documents) == 0 && c.Options == nil { | ||
| } else { | ||
| // If options are provided, still create the collection with write concern "majority". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems relevant.
| {"accessKeyId", accessKeyID}, | ||
| {"secretAccessKey", secretAccessKey}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] Suggest keying the field values for readability and breaking parameterization.
| {"tenantId", "FLE_AZURE_TENANTID"}, | ||
| {"clientId", "FLE_AZURE_CLIENTID"}, | ||
| {"clientSecret", "FLE_AZURE_CLIENTSECRET"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] Suggest keying the field values for readability and breaking parameterization.
| {"email", "FLE_GCP_EMAIL"}, | ||
| {"privateKey", "FLE_GCP_PRIVATEKEY"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] Suggest keying the field values for readability and breaking parameterization.
|
|
||
| azureClientSecret, err := getKmsCredential(azure, "clientSecret", "FLE_AZURE_CLIENTSECRET", "") | ||
| case "local", "local:name2": | ||
| defaultLocalKeyBase64 := "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] Consider constantizing.
| kmipEndpoint, err := getKmsCredential(kmip, "endpoint", "", "localhost:5698") | ||
| func (em *EntityMap) addClientEncryptionEntity(entityOptions *entityOptions) error { | ||
| // Construct KMS providers. | ||
| kmsProviders := make(map[string]map[string]any) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[blocking] Can we merge the KMS logic here with createAutoEncryptionOptions? Same with the key vault namespace? From the specs:
kmsProviders: The same as in clientEncryption.
keyVaultNamespace: The same as in clientEncryption.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be easier to merge the logic in GODRIVER-3726 in my idea
| } | ||
| } | ||
|
|
||
| func createAutoEncryptionOptions(opts bson.Raw) (*options.AutoEncryptionOptions, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[question] Can the analogue in integration/json_helpers_test.go be removed? Can we remove all support for auto encryption in the legacy runner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can keep it until the legacy tests are completely eliminated to avoid handling logic fractions.
5b2b04f to
71042e1
Compare
| } | ||
|
|
||
| // Clear automatically created collections used for queryable encryption | ||
| re := regexp.MustCompile("^enxcol_.*.e(sc|coc)$") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Optional) regexp.MustCompile panics if the regex can't be compiled. Consider moving this to a package-level initialization so any issue can be discovered at package initialization, not when the test is run.
E.g.
// qeCollectionPattern matches collections automatically created for
// queryable encryption.
var qeCollectionPattern = regexp.MustCompile("^enxcol_.*.e(sc|coc)$")| // An empty document returns from the environment. | ||
| // A string is returned as-is. | ||
| func getKmsCredential(kmsDocument bson.Raw, credentialName string, envVar string, defaultValue string) (string, error) { | ||
| func getKmsCredential(kmsDocument bson.Raw, credentialName string, envVar string, defaultValue string) (any, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change the return type from string to any? All of the returned values seem to still be string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main motivation of the change is to distinguish nonexistent value from empty. It is primarily used in line #647, where we set "sessionToken" only when it exists.
| } | ||
|
|
||
| if tlsClientCertificateKeyFile != "" && tlsCAFile != "" { | ||
| if provider == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Optional) For maps, it's conventional to check for len(provider) == 0 because a nil and empty map both report length 0. Consider updating the check here to if len(provider) == 0 and removing the redundant if len(provider) == 0 from getKmsProvider.
| embRawValue := bson.RawValue{Type: bson.TypeEmbeddedDocument, Value: data} | ||
| if err := embRawValue.Unmarshal(&csfle.Options); err == nil { | ||
| csfle.Boolean = false | ||
| csfle.Boolean = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The csfle logically is enabled when it contains a document of properties.
GODRIVER-3486
GODRIVER-3402
Summary
Support auto encryption in unified tests.
Background & Motivation