Skip to content

Commit 527e22d

Browse files
kevinAlbskatcharov
andauthored
DRIVERS-3082 add prose tests for $lookup (#1757)
Co-authored-by: Maxim Katcharov <[email protected]>
1 parent 347f24f commit 527e22d

File tree

6 files changed

+378
-0
lines changed

6 files changed

+378
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"_id": {
3+
"$binary": {
4+
"base64": "EjRWeBI0mHYSNBI0VniQEg==",
5+
"subType": "04"
6+
}
7+
},
8+
"keyMaterial": {
9+
"$binary": {
10+
"base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==",
11+
"subType": "00"
12+
}
13+
},
14+
"creationDate": {
15+
"$date": {
16+
"$numberLong": "1648914851981"
17+
}
18+
},
19+
"updateDate": {
20+
"$date": {
21+
"$numberLong": "1648914851981"
22+
}
23+
},
24+
"status": {
25+
"$numberInt": "0"
26+
},
27+
"masterKey": {
28+
"provider": "local"
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"properties": {
3+
"csfle": {
4+
"encrypt": {
5+
"keyId": [
6+
{
7+
"$binary": {
8+
"base64": "EjRWeBI0mHYSNBI0VniQEg==",
9+
"subType": "04"
10+
}
11+
}
12+
],
13+
"bsonType": "string",
14+
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
15+
}
16+
}
17+
},
18+
"bsonType": "object"
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"properties": {
3+
"csfle2": {
4+
"encrypt": {
5+
"keyId": [
6+
{
7+
"$binary": {
8+
"base64": "EjRWeBI0mHYSNBI0VniQEg==",
9+
"subType": "04"
10+
}
11+
}
12+
],
13+
"bsonType": "string",
14+
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
15+
}
16+
}
17+
},
18+
"bsonType": "object"
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"escCollection": "enxcol_.qe.esc",
3+
"ecocCollection": "enxcol_.qe.ecoc",
4+
"fields": [
5+
{
6+
"keyId": {
7+
"$binary": {
8+
"base64": "EjRWeBI0mHYSNBI0VniQEg==",
9+
"subType": "04"
10+
}
11+
},
12+
"path": "qe",
13+
"bsonType": "string",
14+
"queries": {
15+
"queryType": "equality",
16+
"contention": 0
17+
}
18+
}
19+
]
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"escCollection": "enxcol_.qe2.esc",
3+
"ecocCollection": "enxcol_.qe2.ecoc",
4+
"fields": [
5+
{
6+
"keyId": {
7+
"$binary": {
8+
"base64": "EjRWeBI0mHYSNBI0VniQEg==",
9+
"subType": "04"
10+
}
11+
},
12+
"path": "qe2",
13+
"bsonType": "string",
14+
"queries": {
15+
"queryType": "equality",
16+
"contention": 0
17+
}
18+
}
19+
]
20+
}

source/client-side-encryption/tests/README.md

+270
Original file line numberDiff line numberDiff line change
@@ -3413,3 +3413,273 @@ Repeat this test with the `azure` and `gcp` masterKeys.
34133413
2. Call `client_encryption.createDataKey()` with "aws" as the provider. Expect this to fail.
34143414

34153415
Repeat this test with the `azure` and `gcp` masterKeys.
3416+
3417+
### 25. Test $lookup
3418+
3419+
All tests require libmongocrypt 1.13.0, server 7.0+, and must be skipped on standalone. Tests define more constraints.
3420+
3421+
The syntax `<filename.json>` is used to refer to the content of the corresponding file in `../etc/data/lookup`.
3422+
3423+
#### Setup
3424+
3425+
Create an encrypted MongoClient named `encryptedClient` configured with:
3426+
3427+
```python
3428+
AutoEncryptionOpts(
3429+
keyVaultNamespace="db.keyvault",
3430+
kmsProviders={"local": { "key": "<base64 decoding of LOCAL_MASTERKEY>" }}
3431+
)
3432+
```
3433+
3434+
Use `encryptedClient` to drop `db.keyvault`. Insert `<key-doc.json>` into `db.keyvault` with majority write concern.
3435+
3436+
Use `encryptedClient` to drop and create the following collections:
3437+
3438+
- `db.csfle` with options: `{ "validator": { "$jsonSchema": "<schema-csfle.json>"}}`.
3439+
- `db.csfle2` with options: `{ "validator": { "$jsonSchema": "<schema-csfle2.json>"}}`.
3440+
- `db.qe` with options: `{ "encryptedFields": "<schema-qe.json>"}`.
3441+
- `db.qe2` with options: `{ "encryptedFields": "<schema-qe2.json>"}`.
3442+
- `db.no_schema` with no options.
3443+
- `db.no_schema2` with no options.
3444+
3445+
Create an unencrypted MongoClient named `unencryptedClient`.
3446+
3447+
Insert documents with `encryptedClient`:
3448+
3449+
- `{"csfle": "csfle"}` into `db.csfle`
3450+
- Use `unencryptedClient` to retrieve it. Assert the `csfle` field is BSON binary.
3451+
- `{"csfle2": "csfle2"}` into `db.csfle2`
3452+
- Use `unencryptedClient` to retrieve it. Assert the `csfle2` field is BSON binary.
3453+
- `{"qe": "qe"}` into `db.qe`
3454+
- Use `unencryptedClient` to retrieve it. Assert the `qe` field is BSON binary.
3455+
- `{"qe2": "qe2"}` into `db.qe2`
3456+
- Use `unencryptedClient` to retrieve it. Assert the `qe2` field is BSON binary.
3457+
- `{"no_schema": "no_schema"}` into `db.no_schema`
3458+
- `{"no_schema2": "no_schema2"}` into `db.no_schema2`
3459+
3460+
#### Case 1: `db.csfle` joins `db.no_schema`
3461+
3462+
Test requires server 8.1+ and mongocryptd/crypt_shared 8.1+.
3463+
3464+
Recreate `encryptedClient` with the same `AutoEncryptionOpts` as the setup. (Recreating prevents schema caching from
3465+
impacting the test).
3466+
3467+
Run an aggregate operation on `db.csfle` with the following pipeline:
3468+
3469+
```json
3470+
[
3471+
{"$match" : {"csfle" : "csfle"}},
3472+
{
3473+
"$lookup" : {
3474+
"from" : "no_schema",
3475+
"as" : "matched",
3476+
"pipeline" : [ {"$match" : {"no_schema" : "no_schema"}}, {"$project" : {"_id" : 0}} ]
3477+
}
3478+
},
3479+
{"$project" : {"_id" : 0}}
3480+
]
3481+
```
3482+
3483+
Expect one document to be returned matching: `{"csfle" : "csfle", "matched" : [ {"no_schema" : "no_schema"} ]}`.
3484+
3485+
#### Case 2: `db.qe` joins `db.no_schema`
3486+
3487+
Test requires server 8.1+ and mongocryptd/crypt_shared 8.1+.
3488+
3489+
Recreate `encryptedClient` with the same `AutoEncryptionOpts` as the setup. (Recreating prevents schema caching from
3490+
impacting the test).
3491+
3492+
Run an aggregate operation on `db.qe` with the following pipeline:
3493+
3494+
```json
3495+
[
3496+
{"$match" : {"qe" : "qe"}},
3497+
{
3498+
"$lookup" : {
3499+
"from" : "no_schema",
3500+
"as" : "matched",
3501+
"pipeline" :
3502+
[ {"$match" : {"no_schema" : "no_schema"}}, {"$project" : {"_id" : 0, "__safeContent__" : 0}} ]
3503+
}
3504+
},
3505+
{"$project" : {"_id" : 0, "__safeContent__" : 0}}
3506+
]
3507+
```
3508+
3509+
Expect one document to be returned matching: `{"qe" : "qe", "matched" : [ {"no_schema" : "no_schema"} ]}`.
3510+
3511+
#### Case 3: `db.no_schema` joins `db.csfle`
3512+
3513+
Test requires server 8.1+ and mongocryptd/crypt_shared 8.1+.
3514+
3515+
Recreate `encryptedClient` with the same `AutoEncryptionOpts` as the setup. (Recreating prevents schema caching from
3516+
impacting the test).
3517+
3518+
Run an aggregate operation on `db.no_schema` with the following pipeline:
3519+
3520+
```json
3521+
[
3522+
{"$match" : {"no_schema" : "no_schema"}},
3523+
{
3524+
"$lookup" : {
3525+
"from" : "csfle",
3526+
"as" : "matched",
3527+
"pipeline" : [ {"$match" : {"csfle" : "csfle"}}, {"$project" : {"_id" : 0}} ]
3528+
}
3529+
},
3530+
{"$project" : {"_id" : 0}}
3531+
]
3532+
```
3533+
3534+
Expect one document to be returned matching: `{"no_schema" : "no_schema", "matched" : [ {"csfle" : "csfle"} ]}`.
3535+
3536+
#### Case 4: `db.no_schema` joins `db.qe`
3537+
3538+
Test requires server 8.1+ and mongocryptd/crypt_shared 8.1+.
3539+
3540+
Recreate `encryptedClient` with the same `AutoEncryptionOpts` as the setup. (Recreating prevents schema caching from
3541+
impacting the test).
3542+
3543+
Run an aggregate operation on `db.no_schema` with the following pipeline:
3544+
3545+
```json
3546+
[
3547+
{"$match" : {"no_schema" : "no_schema"}},
3548+
{
3549+
"$lookup" : {
3550+
"from" : "qe",
3551+
"as" : "matched",
3552+
"pipeline" : [ {"$match" : {"qe" : "qe"}}, {"$project" : {"_id" : 0, "__safeContent__" : 0}} ]
3553+
}
3554+
},
3555+
{"$project" : {"_id" : 0}}
3556+
]
3557+
```
3558+
3559+
Expect one document to be returned matching: `{"no_schema" : "no_schema", "matched" : [ {"qe" : "qe"} ]}`.
3560+
3561+
#### Case 5: `db.csfle` joins `db.csfle2`
3562+
3563+
Test requires server 8.1+ and mongocryptd/crypt_shared 8.1+.
3564+
3565+
Recreate `encryptedClient` with the same `AutoEncryptionOpts` as the setup. (Recreating prevents schema caching from
3566+
impacting the test).
3567+
3568+
Run an aggregate operation on `db.csfle` with the following pipeline:
3569+
3570+
```json
3571+
[
3572+
{"$match" : {"csfle" : "csfle"}},
3573+
{
3574+
"$lookup" : {
3575+
"from" : "csfle2",
3576+
"as" : "matched",
3577+
"pipeline" : [ {"$match" : {"csfle2" : "csfle2"}}, {"$project" : {"_id" : 0}} ]
3578+
}
3579+
},
3580+
{"$project" : {"_id" : 0}}
3581+
]
3582+
```
3583+
3584+
Expect one document to be returned matching: `{"csfle" : "csfle", "matched" : [ {"csfle2" : "csfle2"} ]}`.
3585+
3586+
#### Case 6: `db.qe` joins `db.qe2`
3587+
3588+
Test requires server 8.1+ and mongocryptd/crypt_shared 8.1+.
3589+
3590+
Recreate `encryptedClient` with the same `AutoEncryptionOpts` as the setup. (Recreating prevents schema caching from
3591+
impacting the test).
3592+
3593+
Run an aggregate operation on `db.qe` with the following pipeline:
3594+
3595+
```json
3596+
[
3597+
{"$match" : {"qe" : "qe"}},
3598+
{
3599+
"$lookup" : {
3600+
"from" : "qe2",
3601+
"as" : "matched",
3602+
"pipeline" : [ {"$match" : {"qe2" : "qe2"}}, {"$project" : {"_id" : 0, "__safeContent__" : 0}} ]
3603+
}
3604+
},
3605+
{"$project" : {"_id" : 0, "__safeContent__" : 0}}
3606+
]
3607+
```
3608+
3609+
Expect one document to be returned matching: `{"qe" : "qe", "matched" : [ {"qe2" : "qe2"} ]}`.
3610+
3611+
#### Case 7: `db.no_schema` joins `db.no_schema2`
3612+
3613+
Test requires server 8.1+ and mongocryptd/crypt_shared 8.1+.
3614+
3615+
Recreate `encryptedClient` with the same `AutoEncryptionOpts` as the setup. (Recreating prevents schema caching from
3616+
impacting the test).
3617+
3618+
Run an aggregate operation on `db.no_schema` with the following pipeline:
3619+
3620+
```json
3621+
[
3622+
{"$match" : {"no_schema" : "no_schema"}},
3623+
{
3624+
"$lookup" : {
3625+
"from" : "no_schema2",
3626+
"as" : "matched",
3627+
"pipeline" : [ {"$match" : {"no_schema2" : "no_schema2"}}, {"$project" : {"_id" : 0}} ]
3628+
}
3629+
},
3630+
{"$project" : {"_id" : 0}}
3631+
]
3632+
```
3633+
3634+
Expect one document to be returned matching:
3635+
`{"no_schema" : "no_schema", "matched" : [ {"no_schema2" : "no_schema2"} ]}`.
3636+
3637+
#### Case 8: `db.csfle` joins `db.qe`
3638+
3639+
Test requires server 8.1+ and mongocryptd/crypt_shared 8.1+.
3640+
3641+
Recreate `encryptedClient` with the same `AutoEncryptionOpts` as the setup. (Recreating prevents schema caching from
3642+
impacting the test).
3643+
3644+
Run an aggregate operation on `db.csfle` with the following pipeline:
3645+
3646+
```json
3647+
[
3648+
{"$match" : {"csfle" : "qe"}},
3649+
{
3650+
"$lookup" : {
3651+
"from" : "qe",
3652+
"as" : "matched",
3653+
"pipeline" : [ {"$match" : {"qe" : "qe"}}, {"$project" : {"_id" : 0}} ]
3654+
}
3655+
},
3656+
{"$project" : {"_id" : 0}}
3657+
]
3658+
```
3659+
3660+
Expect an exception to be thrown with a message containing the substring `not supported`.
3661+
3662+
#### Case 9: test error with \<8.1
3663+
3664+
This case requires mongocryptd/crypt_shared \<8.1.
3665+
3666+
Recreate `encryptedClient` with the same `AutoEncryptionOpts` as the setup. (Recreating prevents schema caching from
3667+
impacting the test).
3668+
3669+
Run an aggregate operation on `db.csfle` with the following pipeline:
3670+
3671+
```json
3672+
[
3673+
{"$match" : {"csfle" : "csfle"}},
3674+
{
3675+
"$lookup" : {
3676+
"from" : "no_schema",
3677+
"as" : "matched",
3678+
"pipeline" : [ {"$match" : {"no_schema" : "no_schema"}}, {"$project" : {"_id" : 0}} ]
3679+
}
3680+
},
3681+
{"$project" : {"_id" : 0}}
3682+
]
3683+
```
3684+
3685+
Expect an exception to be thrown with a message containing the substring `Upgrade`.

0 commit comments

Comments
 (0)