Skip to content

Commit

Permalink
MONGOCRYPT-317 cache listCollections results with no JSON schema (#190)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinAlbs authored Sep 3, 2021
1 parent 2d3d1ca commit 8eeeee9
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 3 deletions.
18 changes: 18 additions & 0 deletions src/mongocrypt-ctx-encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ _set_schema_from_collinfo (mongocrypt_ctx_t *ctx, bson_t *collinfo)
}
}

if (!found_jsonschema) {
bson_t empty = BSON_INITIALIZER;

_mongocrypt_buffer_steal_from_bson (&ectx->schema, &empty);
}


return true;
}
Expand Down Expand Up @@ -120,6 +126,18 @@ _mongo_done_collinfo (mongocrypt_ctx_t *ctx)
_mongocrypt_ctx_encrypt_t *ectx;

ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
if (_mongocrypt_buffer_empty (&ectx->schema)) {
bson_t empty_collinfo = BSON_INITIALIZER;

/* If no collinfo was fed, cache an empty collinfo. */
if (!_mongocrypt_cache_add_copy (
&ctx->crypt->cache_collinfo, ectx->ns, &empty_collinfo, ctx->status)) {
bson_destroy (&empty_collinfo);
return _mongocrypt_ctx_fail (ctx);
}
bson_destroy (&empty_collinfo);
}

ectx->parent.state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
return true;
}
Expand Down
13 changes: 13 additions & 0 deletions test/data/collection-info-no-validator.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name" : "test",
"type" : "collection",
"options" : {},
"info" : {},
"idIndex" : {
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
}
}
66 changes: 66 additions & 0 deletions test/test-mongocrypt-ctx-encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,70 @@ _test_encrypt_with_aws_session_token (_mongocrypt_tester_t *tester)
mongocrypt_destroy (crypt);
}

static void
_test_encrypt_caches_empty_collinfo (_mongocrypt_tester_t *tester)
{
mongocrypt_t *crypt;
mongocrypt_ctx_t *ctx;

crypt = _mongocrypt_tester_mongocrypt ();
ctx = mongocrypt_ctx_new (crypt);
ASSERT_OK (mongocrypt_ctx_encrypt_init (
ctx, "test", -1, TEST_FILE ("./test/example/cmd.json")),
ctx);
ASSERT_STATE_EQUAL (mongocrypt_ctx_state (ctx), MONGOCRYPT_CTX_NEED_MONGO_COLLINFO);
/* Do not feed anything for collinfo. */
ASSERT_OK (mongocrypt_ctx_mongo_done (ctx), ctx);
_mongocrypt_tester_run_ctx_to (tester, ctx, MONGOCRYPT_CTX_DONE);
mongocrypt_ctx_destroy (ctx);

/* Create another encryption context on the same namespace test.test. It
* should not transition to the MONGOCRYPT_CTX_NEED_MONGO_COLLINFO state. */
ctx = mongocrypt_ctx_new (crypt);
ASSERT_OK (mongocrypt_ctx_encrypt_init (
ctx, "test", -1, TEST_FILE ("./test/example/cmd.json")),
ctx);
ASSERT_STATE_EQUAL (mongocrypt_ctx_state (ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS);
_mongocrypt_tester_run_ctx_to (tester, ctx, MONGOCRYPT_CTX_DONE);
mongocrypt_ctx_destroy (ctx);

mongocrypt_destroy (crypt);
}

static void
_test_encrypt_caches_collinfo_without_jsonschema (_mongocrypt_tester_t *tester)
{
mongocrypt_t *crypt;
mongocrypt_ctx_t *ctx;

crypt = _mongocrypt_tester_mongocrypt ();
ctx = mongocrypt_ctx_new (crypt);
ASSERT_OK (mongocrypt_ctx_encrypt_init (
ctx, "test", -1, TEST_FILE ("./test/example/cmd.json")),
ctx);
ASSERT_STATE_EQUAL (mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_COLLINFO);
ASSERT_OK (
mongocrypt_ctx_mongo_feed (
ctx, TEST_FILE ("./test/data/collection-info-no-validator.json")),
ctx);
ASSERT_OK (mongocrypt_ctx_mongo_done (ctx), ctx);
ASSERT_STATE_EQUAL (mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS);
_mongocrypt_tester_run_ctx_to (tester, ctx, MONGOCRYPT_CTX_DONE);
mongocrypt_ctx_destroy (ctx);

/* Create another encryption context on the same namespace test.test. It
* should not transition to the MONGOCRYPT_CTX_NEED_MONGO_COLLINFO state. */
ctx = mongocrypt_ctx_new (crypt);
ASSERT_OK (mongocrypt_ctx_encrypt_init (
ctx, "test", -1, TEST_FILE ("./test/example/cmd.json")),
ctx);
ASSERT_STATE_EQUAL (mongocrypt_ctx_state (ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS);
_mongocrypt_tester_run_ctx_to (tester, ctx, MONGOCRYPT_CTX_DONE);
mongocrypt_ctx_destroy (ctx);

mongocrypt_destroy (crypt);
}

void
_mongocrypt_tester_install_ctx_encrypt (_mongocrypt_tester_t *tester)
{
Expand All @@ -1485,4 +1549,6 @@ _mongocrypt_tester_install_ctx_encrypt (_mongocrypt_tester_t *tester)
INSTALL_TEST (_test_encrypt_empty_aws);
INSTALL_TEST (_test_encrypt_custom_endpoint);
INSTALL_TEST (_test_encrypt_with_aws_session_token);
INSTALL_TEST (_test_encrypt_caches_empty_collinfo);
INSTALL_TEST (_test_encrypt_caches_collinfo_without_jsonschema);
}
26 changes: 23 additions & 3 deletions test/test-mongocrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,17 +356,17 @@ _mongocrypt_tester_run_ctx_to (_mongocrypt_tester_t *tester,
fprintf (stderr,
"Got error: %s\n",
mongocrypt_status_message (status, NULL));
BSON_ASSERT (state == stop_state);
ASSERT_STATE_EQUAL (state, stop_state);
mongocrypt_status_destroy (status);
return;
case MONGOCRYPT_CTX_DONE:
BSON_ASSERT (state == stop_state);
ASSERT_STATE_EQUAL (state, stop_state);
mongocrypt_status_destroy (status);
return;
}
state = mongocrypt_ctx_state (ctx);
}
BSON_ASSERT (state == stop_state);
ASSERT_STATE_EQUAL (state, stop_state);
mongocrypt_status_destroy (status);
}

Expand Down Expand Up @@ -745,6 +745,26 @@ _test_setopt_kms_providers (_mongocrypt_tester_t *tester)
}
}

const char* mongocrypt_ctx_state_to_string (mongocrypt_ctx_state_t state) {
switch (state) {
case MONGOCRYPT_CTX_ERROR:
return "MONGOCRYPT_CTX_ERROR";
case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
return "MONGOCRYPT_CTX_NEED_MONGO_COLLINFO";
case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
return "MONGOCRYPT_CTX_NEED_MONGO_MARKINGS";
case MONGOCRYPT_CTX_NEED_MONGO_KEYS:
return "MONGOCRYPT_CTX_NEED_MONGO_KEYS";
case MONGOCRYPT_CTX_NEED_KMS:
return "MONGOCRYPT_CTX_NEED_KMS";
case MONGOCRYPT_CTX_READY:
return "MONGOCRYPT_CTX_READY";
case MONGOCRYPT_CTX_DONE:
return "MONGOCRYPT_CTX_DONE";
default:
return "UNKNOWN";
}
}

int
main (int argc, char **argv)
Expand Down
16 changes: 16 additions & 0 deletions test/test-mongocrypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,22 @@ _assert_bin_bson_equal (mongocrypt_binary_t *bin_a, mongocrypt_binary_t *bin_b);
void
_assert_match_bson (const bson_t *doc, const bson_t *pattern);

const char* mongocrypt_ctx_state_to_string (mongocrypt_ctx_state_t state);

#define ASSERT_STATE_EQUAL(actual, expected) \
do { \
if (actual != expected) { \
fprintf (stderr, \
"%s:%d %s() actual state: %s, but expected state: %s\n", \
__FILE__, \
__LINE__, \
BSON_FUNC, \
mongocrypt_ctx_state_to_string (actual), \
mongocrypt_ctx_state_to_string (expected)); \
abort (); \
} \
} while (0)

typedef enum {
CRYPTO_REQUIRED,
CRYPTO_OPTIONAL,
Expand Down

0 comments on commit 8eeeee9

Please sign in to comment.