Skip to content

Commit 15d2c81

Browse files
committed
update prose tests
1 parent a55717d commit 15d2c81

File tree

5 files changed

+256
-20
lines changed

5 files changed

+256
-20
lines changed

.evergreen/config.yml

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ timeout:
2121
binary: bash
2222
args: [ls, -la]
2323
functions:
24-
assume-test-secrets-ec2-role:
25-
- command: ec2.assume_role
26-
params:
27-
role_arn: ${aws_test_secrets_role}
2824
setup-system:
2925
# Executes clone and applies the submitted patch, if any
3026
- command: git.get_project
@@ -550,6 +546,21 @@ functions:
550546
KMS_FAILPOINT_CA_FILE: "${DRIVERS_TOOLS}/.evergreen/x509gen/ca.pem"
551547
KMS_FAILPOINT_SERVER_RUNNING: "true"
552548
args: [*task-runner, evg-test-retry-kms-requests]
549+
run-client-side-encryption-test:
550+
- command: subprocess.exec
551+
params:
552+
binary: "bash"
553+
env:
554+
GO_BUILD_TAGS: cse
555+
include_expansions_in_env: [AUTH, SSL, MONGODB_URI, TOPOLOGY,
556+
MONGO_GO_DRIVER_COMPRESSOR]
557+
args: [*task-runner, setup-test]
558+
- command: subprocess.exec
559+
type: test
560+
retry_on_failure: true
561+
params:
562+
binary: "bash"
563+
args: [*task-runner, evg-test-client-side-encryption]
553564
run-fuzz-tests:
554565
- command: subprocess.exec
555566
type: test
@@ -1452,6 +1463,20 @@ tasks:
14521463
TOPOLOGY: "server"
14531464
AUTH: "noauth"
14541465
SSL: "nossl"
1466+
- name: "test-client-side-encryption"
1467+
tags: ["client-side-encryption-test"]
1468+
commands:
1469+
- func: bootstrap-mongo-orchestration
1470+
vars:
1471+
TOPOLOGY: "replica_set"
1472+
AUTH: "noauth"
1473+
SSL: "nossl"
1474+
- func: start-cse-servers
1475+
- func: run-client-side-encryption-test
1476+
vars:
1477+
TOPOLOGY: "replica_set"
1478+
AUTH: "noauth"
1479+
SSL: "nossl"
14551480
- name: "test-retry-kms-requests"
14561481
tags: ["kms-test"]
14571482
commands:
@@ -2093,6 +2118,11 @@ buildvariants:
20932118
display_name: "KMS TEST ${os-ssl-40}"
20942119
tasks:
20952120
- name: ".kms-test"
2121+
- matrix_name: "client-side-encryption-test"
2122+
matrix_spec: { version: ["latest"], os-ssl-40: ["rhel87-64"] }
2123+
display_name: "Client Side Encryption Tests ${os-ssl-40}"
2124+
tasks:
2125+
- name: ".client-side-encryption-test"
20962126
- matrix_name: "load-balancer-test"
20972127
tags: ["pullrequest"]
20982128
matrix_spec: {version: ["5.0", "6.0", "7.0", "8.0"], os-ssl-40: ["rhel87-64"]}

Taskfile.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ tasks:
102102
- go test -exec "env PKG_CONFIG_PATH=${PKG_CONFIG_PATH} LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" ${BUILD_TAGS} -v -timeout {{.TEST_TIMEOUT}}s ./internal/integration -run TestClientSideEncryptionProse/kms_tls_tests >> test.suite
103103
evg-test-retry-kms-requests:
104104
- go test -exec "env PKG_CONFIG_PATH=${PKG_CONFIG_PATH} LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" ${BUILD_TAGS} -v -timeout {{.TEST_TIMEOUT}}s ./internal/integration -run TestClientSideEncryptionProse/kms_retry_tests >> test.suite
105+
evg-test-client-side-encryption:
106+
- go test -exec "env PKG_CONFIG_PATH=${PKG_CONFIG_PATH} LD_LIBRARY_PATH=${LD_LIBRARY_PATH} DYLD_LIBRARY_PATH=${MACOS_LIBRARY_PATH}" ${BUILD_TAGS} -v -timeout {{.TEST_TIMEOUT}}s ./internal/integration -run TestClientSideEncryptionProse >> test.suite
105107
evg-test-load-balancers:
106108
# Load balancer should be tested with all unified tests as well as tests in the following
107109
# components: retryable reads, retryable writes, change streams, initial DNS seedlist discovery.

internal/integration/client_side_encryption_prose_test.go

Lines changed: 212 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3195,27 +3195,27 @@ func TestClientSideEncryptionProse(t *testing.T) {
31953195
{
31963196
collection: "prefix-suffix",
31973197
textOpts: options.Text().
3198+
SetCaseSensitive(true).
3199+
SetDiacriticSensitive(true).
31983200
SetPrefix(options.PrefixOptions{
31993201
StrMaxQueryLength: 10,
32003202
StrMinQueryLength: 2,
32013203
}).
32023204
SetSuffix(options.SuffixOptions{
32033205
StrMaxQueryLength: 10,
32043206
StrMinQueryLength: 2,
3205-
}).
3206-
SetCaseSensitive(true).
3207-
SetDiacriticSensitive(true),
3207+
}),
32083208
},
32093209
{
32103210
collection: "substring",
32113211
textOpts: options.Text().
3212+
SetCaseSensitive(true).
3213+
SetDiacriticSensitive(true).
32123214
SetSubstring(options.SubstringOptions{
32133215
StrMaxLength: 10,
32143216
StrMaxQueryLength: 10,
32153217
StrMinQueryLength: 2,
3216-
}).
3217-
SetCaseSensitive(true).
3218-
SetDiacriticSensitive(true),
3218+
}),
32193219
},
32203220
} {
32213221
coll := encryptedClient.Database("db").Collection(c.collection, options.Collection().SetWriteConcern(mtest.MajorityWc))
@@ -3233,36 +3233,234 @@ func TestClientSideEncryptionProse(t *testing.T) {
32333233
return encryptedClient, clientEncryption
32343234
}
32353235

3236-
mt.Run("Case 1: can decrypt a payload", func(mt *mtest.T) {
3236+
foo := bson.RawValue{Type: bson.TypeString, Value: bsoncore.AppendString(nil, "foo")}
3237+
bar := bson.RawValue{Type: bson.TypeString, Value: bsoncore.AppendString(nil, "bar")}
3238+
baz := bson.RawValue{Type: bson.TypeString, Value: bsoncore.AppendString(nil, "baz")}
3239+
3240+
mt.Run("Case 1: can find a document by prefix", func(mt *mtest.T) {
32373241
encryptedClient, clientEncryption := testSetup()
32383242
defer clientEncryption.Close(context.Background())
32393243
defer encryptedClient.Disconnect(context.Background())
32403244

3241-
foo := bson.RawValue{Type: bson.TypeString, Value: bsoncore.AppendString(nil, "foo")}
32423245
eo := options.Encrypt().
3243-
SetAlgorithm("TextPreview").
32443246
SetKeyID(key1ID).
3247+
SetAlgorithm("TextPreview").
3248+
SetQueryType("prefixPreview").
32453249
SetContentionFactor(0).
32463250
SetTextOptions(options.Text().
3251+
SetCaseSensitive(true).
3252+
SetDiacriticSensitive(true).
32473253
SetPrefix(options.PrefixOptions{
32483254
StrMaxQueryLength: 10,
32493255
StrMinQueryLength: 2,
3250-
}).
3251-
SetCaseSensitive(true).
3252-
SetDiacriticSensitive(true))
3256+
}))
32533257
payload, err := clientEncryption.Encrypt(context.Background(), foo, eo)
32543258
require.NoError(mt, err, "error in Encrypt: %v", err)
32553259
coll := encryptedClient.Database("db").Collection("prefix-suffix")
3256-
got, err := coll.FindOne(context.Background(), bson.D{
3260+
res := coll.FindOne(context.Background(), bson.D{
3261+
{"$expr", bson.D{
3262+
{"$encStrStartsWith", bson.D{
3263+
{"input", "$encryptedText"},
3264+
{"prefix", payload},
3265+
}},
3266+
}},
3267+
})
3268+
require.NoError(mt, err, "error in FindOne: %v", err)
3269+
var got struct {
3270+
Id int `bson:"_id"`
3271+
EncryptedText string `bson:"encryptedText"`
3272+
}
3273+
err = res.Decode(&got)
3274+
require.NoError(mt, err, "error decoding result: %v", err)
3275+
require.Equal(mt, 0, got.Id)
3276+
require.Equal(mt, "foobarbaz", got.EncryptedText)
3277+
})
3278+
mt.Run("Case 2: find a document by suffix", func(mt *mtest.T) {
3279+
encryptedClient, clientEncryption := testSetup()
3280+
defer clientEncryption.Close(context.Background())
3281+
defer encryptedClient.Disconnect(context.Background())
3282+
3283+
eo := options.Encrypt().
3284+
SetKeyID(key1ID).
3285+
SetAlgorithm("TextPreview").
3286+
SetQueryType("suffixPreview").
3287+
SetContentionFactor(0).
3288+
SetTextOptions(options.Text().
3289+
SetCaseSensitive(true).
3290+
SetDiacriticSensitive(true).
3291+
SetSuffix(options.SuffixOptions{
3292+
StrMaxQueryLength: 10,
3293+
StrMinQueryLength: 2,
3294+
}))
3295+
payload, err := clientEncryption.Encrypt(context.Background(), baz, eo)
3296+
require.NoError(mt, err, "error in Encrypt: %v", err)
3297+
coll := encryptedClient.Database("db").Collection("prefix-suffix")
3298+
res := coll.FindOne(context.Background(), bson.D{
3299+
{"$expr", bson.D{
3300+
{"$encStrEndsWith", bson.D{
3301+
{"input", "$encryptedText"},
3302+
{"suffix", payload},
3303+
}},
3304+
}},
3305+
})
3306+
var got struct {
3307+
Id int `bson:"_id"`
3308+
EncryptedText string `bson:"encryptedText"`
3309+
}
3310+
err = res.Decode(&got)
3311+
require.NoError(mt, err, "error decoding result: %v", err)
3312+
require.Equal(mt, 0, got.Id)
3313+
require.Equal(mt, "foobarbaz", got.EncryptedText)
3314+
})
3315+
mt.Run("Case 3: assert no document found by prefix", func(mt *mtest.T) {
3316+
encryptedClient, clientEncryption := testSetup()
3317+
defer clientEncryption.Close(context.Background())
3318+
defer encryptedClient.Disconnect(context.Background())
3319+
3320+
eo := options.Encrypt().
3321+
SetKeyID(key1ID).
3322+
SetAlgorithm("TextPreview").
3323+
SetQueryType("prefixPreview").
3324+
SetContentionFactor(0).
3325+
SetTextOptions(options.Text().
3326+
SetCaseSensitive(true).
3327+
SetDiacriticSensitive(true).
3328+
SetPrefix(options.PrefixOptions{
3329+
StrMaxQueryLength: 10,
3330+
StrMinQueryLength: 2,
3331+
}))
3332+
payload, err := clientEncryption.Encrypt(context.Background(), baz, eo)
3333+
require.NoError(mt, err, "error in Encrypt: %v", err)
3334+
coll := encryptedClient.Database("db").Collection("prefix-suffix")
3335+
_, err = coll.FindOne(context.Background(), bson.D{
32573336
{"$expr", bson.D{
32583337
{"$encStrStartsWith", bson.D{
32593338
{"input", "$encryptedText"},
32603339
{"prefix", payload},
32613340
}},
32623341
}},
32633342
}).Raw()
3343+
require.Error(mt, err, mongo.ErrNoDocuments)
3344+
})
3345+
mt.Run("Case 4: assert no document found by suffix", func(mt *mtest.T) {
3346+
encryptedClient, clientEncryption := testSetup()
3347+
defer clientEncryption.Close(context.Background())
3348+
defer encryptedClient.Disconnect(context.Background())
3349+
3350+
eo := options.Encrypt().
3351+
SetKeyID(key1ID).
3352+
SetAlgorithm("TextPreview").
3353+
SetQueryType("suffixPreview").
3354+
SetContentionFactor(0).
3355+
SetTextOptions(options.Text().
3356+
SetCaseSensitive(true).
3357+
SetDiacriticSensitive(true).
3358+
SetSuffix(options.SuffixOptions{
3359+
StrMaxQueryLength: 10,
3360+
StrMinQueryLength: 2,
3361+
}))
3362+
payload, err := clientEncryption.Encrypt(context.Background(), foo, eo)
3363+
require.NoError(mt, err, "error in Encrypt: %v", err)
3364+
coll := encryptedClient.Database("db").Collection("prefix-suffix")
3365+
_, err = coll.FindOne(context.Background(), bson.D{
3366+
{"$expr", bson.D{
3367+
{"$encStrEndsWith", bson.D{
3368+
{"input", "$encryptedText"},
3369+
{"suffix", payload},
3370+
}},
3371+
}},
3372+
}).Raw()
3373+
require.Error(mt, err, mongo.ErrNoDocuments)
3374+
})
3375+
mt.Run("Case 5: can find a document by substring", func(mt *mtest.T) {
3376+
encryptedClient, clientEncryption := testSetup()
3377+
defer clientEncryption.Close(context.Background())
3378+
defer encryptedClient.Disconnect(context.Background())
3379+
3380+
eo := options.Encrypt().
3381+
SetKeyID(key1ID).
3382+
SetAlgorithm("TextPreview").
3383+
SetQueryType("substringPreview").
3384+
SetContentionFactor(0).
3385+
SetTextOptions(options.Text().
3386+
SetCaseSensitive(true).
3387+
SetDiacriticSensitive(true).
3388+
SetSubstring(options.SubstringOptions{
3389+
StrMaxLength: 10,
3390+
StrMaxQueryLength: 10,
3391+
StrMinQueryLength: 2,
3392+
}))
3393+
payload, err := clientEncryption.Encrypt(context.Background(), bar, eo)
3394+
require.NoError(mt, err, "error in Encrypt: %v", err)
3395+
coll := encryptedClient.Database("db").Collection("substring")
3396+
res := coll.FindOne(context.Background(), bson.D{
3397+
{"$expr", bson.D{
3398+
{"$encStrContains", bson.D{
3399+
{"input", "$encryptedText"},
3400+
{"substring", payload},
3401+
}},
3402+
}},
3403+
})
32643404
require.NoError(mt, err, "error in FindOne: %v", err)
3265-
assert.FailNow(mt, "got: %v", got)
3405+
var got struct {
3406+
Id int `bson:"_id"`
3407+
EncryptedText string `bson:"encryptedText"`
3408+
}
3409+
err = res.Decode(&got)
3410+
require.NoError(mt, err, "error decoding result: %v", err)
3411+
require.Equal(mt, 0, got.Id)
3412+
require.Equal(mt, "foobarbaz", got.EncryptedText)
3413+
})
3414+
mt.Run("Case 6: assert no document found by substring", func(mt *mtest.T) {
3415+
encryptedClient, clientEncryption := testSetup()
3416+
defer clientEncryption.Close(context.Background())
3417+
defer encryptedClient.Disconnect(context.Background())
3418+
3419+
qux := bson.RawValue{Type: bson.TypeString, Value: bsoncore.AppendString(nil, "qux")}
3420+
eo := options.Encrypt().
3421+
SetKeyID(key1ID).
3422+
SetAlgorithm("TextPreview").
3423+
SetQueryType("substringPreview").
3424+
SetContentionFactor(0).
3425+
SetTextOptions(options.Text().
3426+
SetCaseSensitive(true).
3427+
SetDiacriticSensitive(true).
3428+
SetSubstring(options.SubstringOptions{
3429+
StrMaxLength: 10,
3430+
StrMaxQueryLength: 10,
3431+
StrMinQueryLength: 2,
3432+
}))
3433+
payload, err := clientEncryption.Encrypt(context.Background(), qux, eo)
3434+
require.NoError(mt, err, "error in Encrypt: %v", err)
3435+
coll := encryptedClient.Database("db").Collection("substring")
3436+
_, err = coll.FindOne(context.Background(), bson.D{
3437+
{"$expr", bson.D{
3438+
{"$encStrContains", bson.D{
3439+
{"input", "$encryptedText"},
3440+
{"suffix", payload},
3441+
}},
3442+
}},
3443+
}).Raw()
3444+
require.Error(mt, err, mongo.ErrNoDocuments)
3445+
})
3446+
mt.Run("Case 7: assert contentionFactor is required", func(mt *mtest.T) {
3447+
encryptedClient, clientEncryption := testSetup()
3448+
defer clientEncryption.Close(context.Background())
3449+
defer encryptedClient.Disconnect(context.Background())
3450+
3451+
eo := options.Encrypt().
3452+
SetKeyID(key1ID).
3453+
SetAlgorithm("TextPreview").
3454+
SetQueryType("prefixPreview").
3455+
SetTextOptions(options.Text().
3456+
SetCaseSensitive(true).
3457+
SetDiacriticSensitive(true).
3458+
SetPrefix(options.PrefixOptions{
3459+
StrMaxQueryLength: 10,
3460+
StrMinQueryLength: 2,
3461+
}))
3462+
_, err := clientEncryption.Encrypt(context.Background(), baz, eo)
3463+
require.ErrorContains(mt, err, "contention factor is required for textPreview algorithm")
32663464
})
32673465
})
32683466
}

mongo/options/encryptoptions.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func (ro *RangeOptionsBuilder) SetPrecision(precision int32) *RangeOptionsBuilde
9999
return ro
100100
}
101101

102-
// TextOptions specifies index options for a Queryable Encryption field supporting "test" queries.
102+
// TextOptions specifies index options for a Queryable Encryption field supporting "text" queries.
103103
//
104104
// See corresponding setter methods for documentation.
105105
type TextOptions struct {
@@ -110,17 +110,20 @@ type TextOptions struct {
110110
DiacriticSensitive bool
111111
}
112112

113+
// SubstringOptions specifies options to support substring queries.
113114
type SubstringOptions struct {
114115
StrMaxLength int32
115116
StrMinQueryLength int32
116117
StrMaxQueryLength int32
117118
}
118119

120+
// PrefixOptions specifies options to support prefix queries.
119121
type PrefixOptions struct {
120122
StrMinQueryLength int32
121123
StrMaxQueryLength int32
122124
}
123125

126+
// SuffixOptions specifies options to support suffix queries.
124127
type SuffixOptions struct {
125128
StrMinQueryLength int32
126129
StrMaxQueryLength int32

0 commit comments

Comments
 (0)