summaryrefslogtreecommitdiff
path: root/src/mongo/db/fle_query_interface_mock.cpp
diff options
context:
space:
mode:
authorErwin Pe <erwin.pe@mongodb.com>2022-04-01 03:15:48 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-01 03:43:36 +0000
commit5d448b9565c79235d70d9cf47876ef07d615a0a4 (patch)
tree1b2da67769efc09fc5223ea49a1290a786f14fcd /src/mongo/db/fle_query_interface_mock.cpp
parent92d12679edfc7018a8695df2035dc5635aea96ac (diff)
downloadmongo-5d448b9565c79235d70d9cf47876ef07d615a0a4.tar.gz
SERVER-63468 Add support for ESC compaction
Diffstat (limited to 'src/mongo/db/fle_query_interface_mock.cpp')
-rw-r--r--src/mongo/db/fle_query_interface_mock.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/src/mongo/db/fle_query_interface_mock.cpp b/src/mongo/db/fle_query_interface_mock.cpp
new file mode 100644
index 00000000000..316c7be12f0
--- /dev/null
+++ b/src/mongo/db/fle_query_interface_mock.cpp
@@ -0,0 +1,187 @@
+/**
+ * Copyright (C) 2022-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/fle_query_interface_mock.h"
+
+namespace mongo {
+
+BSONObj FLEQueryInterfaceMock::getById(const NamespaceString& nss, BSONElement element) {
+ auto obj = BSON("_id" << element);
+ auto swDoc = _storage->findById(_opCtx, nss, obj.firstElement());
+ if (swDoc.getStatus() == ErrorCodes::NoSuchKey) {
+ return BSONObj();
+ }
+
+ return uassertStatusOK(swDoc);
+}
+
+BSONObj FLEQueryInterfaceMock::getById(const NamespaceString& nss, PrfBlock block) {
+ auto doc = BSON("v" << BSONBinData(block.data(), block.size(), BinDataGeneral));
+ BSONElement element = doc.firstElement();
+ return getById(nss, element);
+}
+
+uint64_t FLEQueryInterfaceMock::countDocuments(const NamespaceString& nss) {
+ return uassertStatusOK(_storage->getCollectionCount(_opCtx, nss));
+}
+
+StatusWith<write_ops::InsertCommandReply> FLEQueryInterfaceMock::insertDocument(
+ const NamespaceString& nss, BSONObj obj, bool translateDuplicateKey) {
+ repl::TimestampedBSONObj tb;
+ tb.obj = obj;
+
+ auto status = _storage->insertDocument(_opCtx, nss, tb, 0);
+
+ if (!status.isOK()) {
+ return status;
+ }
+
+ return write_ops::InsertCommandReply();
+}
+
+std::pair<write_ops::DeleteCommandReply, BSONObj> FLEQueryInterfaceMock::deleteWithPreimage(
+ const NamespaceString& nss,
+ const EncryptionInformation& ei,
+ const write_ops::DeleteCommandRequest& deleteRequest) {
+ // A limit of the API, we can delete by _id and get the pre-image so we limit our unittests to
+ // this
+ uassert(6346808,
+ "Delete command must have exactly one delete op entry",
+ deleteRequest.getDeletes().size() == 1);
+
+ auto deleteOpEntry = deleteRequest.getDeletes()[0];
+
+ uassert(6346809,
+ "First element field name of delete op entry must be '_id'",
+ "_id"_sd == deleteOpEntry.getQ().firstElementFieldNameStringData());
+
+ BSONElement id = deleteOpEntry.getQ().firstElement();
+ if (id.isABSONObj() && id.Obj().firstElementFieldNameStringData() == "$eq"_sd) {
+ id = id.Obj().firstElement();
+ }
+
+ auto swDoc = _storage->deleteById(_opCtx, nss, id);
+
+ // Some of the unit tests delete documents that do not exist
+ if (swDoc.getStatus() == ErrorCodes::NoSuchKey) {
+ return {write_ops::DeleteCommandReply(), BSONObj()};
+ }
+
+ return {write_ops::DeleteCommandReply(), uassertStatusOK(swDoc)};
+}
+
+std::pair<write_ops::UpdateCommandReply, BSONObj> FLEQueryInterfaceMock::updateWithPreimage(
+ const NamespaceString& nss,
+ const EncryptionInformation& ei,
+ const write_ops::UpdateCommandRequest& updateRequest) {
+ // A limit of the API, we can delete by _id and get the pre-image so we limit our unittests to
+ // this
+ uassert(6346810,
+ "Update command must have exactly one update op entry",
+ updateRequest.getUpdates().size() == 1);
+
+ auto updateOpEntry = updateRequest.getUpdates()[0];
+
+ uassert(6346811,
+ "First element field name of update op entry must be '_id'",
+ "_id"_sd == updateOpEntry.getQ().firstElementFieldNameStringData());
+
+ BSONElement id = updateOpEntry.getQ().firstElement();
+ if (id.isABSONObj() && id.Obj().firstElementFieldNameStringData() == "$eq"_sd) {
+ id = id.Obj().firstElement();
+ }
+ BSONObj preimage = getById(nss, id);
+
+ if (updateOpEntry.getU().type() == write_ops::UpdateModification::Type::kModifier) {
+ uassertStatusOK(
+ _storage->upsertById(_opCtx, nss, id, updateOpEntry.getU().getUpdateModifier()));
+ } else {
+ uassertStatusOK(
+ _storage->upsertById(_opCtx, nss, id, updateOpEntry.getU().getUpdateReplacement()));
+ }
+
+ return {write_ops::UpdateCommandReply(), preimage};
+}
+
+write_ops::FindAndModifyCommandReply FLEQueryInterfaceMock::findAndModify(
+ const NamespaceString& nss,
+ const EncryptionInformation& ei,
+ const write_ops::FindAndModifyCommandRequest& findAndModifyRequest) {
+ // Repl storage interface does not have find and modify support directly. We emulate it, poorly
+ uassert(6346812,
+ "First element field name of findAndModify query must be '_id'",
+ "_id"_sd == findAndModifyRequest.getQuery().firstElementFieldNameStringData());
+ uassert(6346813,
+ "findAndModify 'new' field must be 'false'",
+ findAndModifyRequest.getNew().get_value_or(false) == false);
+
+ BSONObj preimage = getById(nss, findAndModifyRequest.getQuery().firstElement());
+
+ if (findAndModifyRequest.getRemove().get_value_or(false)) {
+ // Remove
+ auto swDoc =
+ _storage->deleteById(_opCtx, nss, findAndModifyRequest.getQuery().firstElement());
+ uassertStatusOK(swDoc);
+
+ } else {
+ uassertStatusOK(
+ _storage->upsertById(_opCtx,
+ nss,
+ findAndModifyRequest.getQuery().firstElement(),
+ findAndModifyRequest.getUpdate()->getUpdateModifier()));
+ }
+
+ write_ops::FindAndModifyCommandReply reply;
+ reply.setValue(preimage);
+ return reply;
+}
+
+std::vector<BSONObj> FLEQueryInterfaceMock::findDocuments(const NamespaceString& nss,
+ BSONObj filter) {
+ std::vector<BSONObj> results;
+ auto docs =
+ uassertStatusOK(_storage->findDocuments(_opCtx,
+ nss,
+ boost::none,
+ repl::StorageInterface::ScanDirection::kForward,
+ {},
+ BoundInclusion::kIncludeStartKeyOnly,
+ std::numeric_limits<size_t>::max()));
+ for (auto& doc : docs) {
+ auto elt = doc.getField(filter.firstElementFieldNameStringData());
+ if (elt.binaryEqual(filter.firstElement())) {
+ results.push_back(doc.getOwned());
+ }
+ }
+ return results;
+}
+
+} // namespace mongo