diff options
author | Suganthi Mani <suganthi.mani@mongodb.com> | 2020-10-29 22:50:40 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-11-06 18:24:35 +0000 |
commit | 259cf7048a5625541af815911192ae61fbbd52df (patch) | |
tree | 874ddcd80b06bb78eb41fae20d46a59a26bc24b6 | |
parent | 3c179e493589356f16641c40647cfd1418473d06 (diff) | |
download | mongo-259cf7048a5625541af815911192ae61fbbd52df.tar.gz |
SERVER-52602 OplogBufferCollection uses write_ops_exec::performInserts() to insert documents to comply with "multi-timestamp" rules.
-rw-r--r-- | src/mongo/db/auth/authorization_session_impl.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/document_validation.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/catalog/document_validation.h | 91 | ||||
-rw-r--r-- | src/mongo/db/ops/insert.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/ops/insert.h | 4 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.h | 3 | ||||
-rw-r--r-- | src/mongo/db/repl/SConscript | 5 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog_applier_impl_test.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog_applier_utils.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog_buffer_collection.cpp | 30 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/repl/tenant_collection_cloner.cpp | 15 | ||||
-rw-r--r-- | src/mongo/dbtests/insert_test.cpp | 12 | ||||
-rw-r--r-- | src/mongo/dbtests/pdfiletests.cpp | 17 |
17 files changed, 160 insertions, 58 deletions
diff --git a/src/mongo/db/auth/authorization_session_impl.cpp b/src/mongo/db/auth/authorization_session_impl.cpp index 5d8d815c1a4..33befa62439 100644 --- a/src/mongo/db/auth/authorization_session_impl.cpp +++ b/src/mongo/db/auth/authorization_session_impl.cpp @@ -340,7 +340,7 @@ Status AuthorizationSessionImpl::checkAuthForGetMore(const NamespaceString& ns, Status AuthorizationSessionImpl::checkAuthForInsert(OperationContext* opCtx, const NamespaceString& ns) { ActionSet required{ActionType::insert}; - if (documentValidationDisabled(opCtx)) { + if (DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()) { required.addAction(ActionType::bypassDocumentValidation); } if (!isAuthorizedForActionsOnNamespace(ns, required)) { @@ -364,7 +364,7 @@ Status AuthorizationSessionImpl::checkAuthForUpdate(OperationContext* opCtx, operationType = "upsert"_sd; } - if (documentValidationDisabled(opCtx)) { + if (DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()) { required.addAction(ActionType::bypassDocumentValidation); } diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp index b5dff5774c0..1ede05ecd60 100644 --- a/src/mongo/db/catalog/collection_impl.cpp +++ b/src/mongo/db/catalog/collection_impl.cpp @@ -426,7 +426,7 @@ Status CollectionImpl::checkValidation(OperationContext* opCtx, const BSONObj& d if (_validationLevel == ValidationLevel::OFF) return Status::OK(); - if (documentValidationDisabled(opCtx)) + if (DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()) return Status::OK(); if (ns().isTemporaryReshardingCollection()) { diff --git a/src/mongo/db/catalog/document_validation.cpp b/src/mongo/db/catalog/document_validation.cpp index 004173f5014..3d660de21ca 100644 --- a/src/mongo/db/catalog/document_validation.cpp +++ b/src/mongo/db/catalog/document_validation.cpp @@ -32,6 +32,6 @@ #include "mongo/db/catalog/document_validation.h" namespace mongo { -const OperationContext::Decoration<bool> documentValidationDisabled = - OperationContext::declareDecoration<bool>(); -} +const OperationContext::Decoration<DocumentValidationSettings> DocumentValidationSettings::get = + OperationContext::declareDecoration<DocumentValidationSettings>(); +} // namespace mongo diff --git a/src/mongo/db/catalog/document_validation.h b/src/mongo/db/catalog/document_validation.h index e27dfb11b66..f236deccd56 100644 --- a/src/mongo/db/catalog/document_validation.h +++ b/src/mongo/db/catalog/document_validation.h @@ -33,12 +33,6 @@ #include "mongo/db/operation_context.h" namespace mongo { -/** - * If true, Collection should do no validation of writes from this OperationContext. - * - * Note that Decorations are value-constructed so this defaults to false. - */ -extern const OperationContext::Decoration<bool> documentValidationDisabled; inline StringData bypassDocumentValidationCommandOption() { return "bypassDocumentValidation"; @@ -49,6 +43,64 @@ inline bool shouldBypassDocumentValidationForCommand(const BSONObj& cmdObj) { } /** + * This container decorates an OperationContext object. It stores the document validation + * settings for writes associated with an OperationContext. By default, document validation (both + * schema and internal) is enabled. DocumentValidationSettings objects are not thread-safe. + * + */ +class DocumentValidationSettings { +public: + enum flag : std::uint8_t { + /* + * Enables document validation (both schema and internal). + */ + kEnableValidation = 0x00, + /* + * Disables the schema validation during document inserts and updates. + * This flag should be enabled if WriteCommandBase::_bypassDocumentValidation + * is set to true. + */ + kDisableSchemaValidation = 0x01, + /* + * Disables any internal validation (like fixDocumentForInsert()). This flag + * should be enabled only for trusted internal writes or internal writes that + * doesn't comply with internal validation rules. + */ + kDisableInternalValidation = 0x02, + }; + + using Flags = std::uint8_t; + + static const OperationContext::Decoration<DocumentValidationSettings> get; + + DocumentValidationSettings() = default; + + void setFlags(Flags flags) { + invariant(flags != kEnableValidation); + _flags |= flags; + } + + void clearFlags() { + _flags = kEnableValidation; + } + + bool isSchemaValidationDisabled() const { + return _flags & kDisableSchemaValidation; + } + + bool isInternalValidationDisabled() const { + return _flags & kDisableInternalValidation; + } + + bool isDocumentValidationEnabled() const { + return _flags == kEnableValidation; + } + +private: + Flags _flags = kEnableValidation; +}; + +/** * Disables document validation on a single OperationContext while in scope. * Resets to original value when leaving scope so they are safe to nest. */ @@ -57,31 +109,36 @@ class DisableDocumentValidation { DisableDocumentValidation& operator=(const DisableDocumentValidation&) = delete; public: - DisableDocumentValidation(OperationContext* opCtx) - : _opCtx(opCtx), _initialState(documentValidationDisabled(_opCtx)) { - documentValidationDisabled(_opCtx) = true; + DisableDocumentValidation(OperationContext* opCtx, + DocumentValidationSettings::Flags flags = + DocumentValidationSettings::kDisableSchemaValidation) + : _opCtx(opCtx) { + auto& documentValidationSettings = DocumentValidationSettings::get(_opCtx); + _initialState = documentValidationSettings; + documentValidationSettings.setFlags(flags); } ~DisableDocumentValidation() { - documentValidationDisabled(_opCtx) = _initialState; + DocumentValidationSettings::get(_opCtx) = _initialState; } private: OperationContext* const _opCtx; - const bool _initialState; + DocumentValidationSettings _initialState; }; /** - * Disables document validation while in scope if the constructor is passed true. + * Disables document schema validation while in scope if the constructor is passed true. */ -class DisableDocumentValidationIfTrue { +class DisableDocumentSchemaValidationIfTrue { public: - DisableDocumentValidationIfTrue(OperationContext* opCtx, bool shouldDisableValidation) { - if (shouldDisableValidation) - _documentValidationDisabler.emplace(opCtx); + DisableDocumentSchemaValidationIfTrue(OperationContext* opCtx, + bool shouldDisableSchemaValidation) { + if (shouldDisableSchemaValidation) + _documentSchemaValidationDisabler.emplace(opCtx); } private: - boost::optional<DisableDocumentValidation> _documentValidationDisabler; + boost::optional<DisableDocumentValidation> _documentSchemaValidationDisabler; }; } // namespace mongo diff --git a/src/mongo/db/ops/insert.cpp b/src/mongo/db/ops/insert.cpp index 9d60154f528..1c6fd65b01a 100644 --- a/src/mongo/db/ops/insert.cpp +++ b/src/mongo/db/ops/insert.cpp @@ -33,6 +33,7 @@ #include <vector> #include "mongo/bson/bson_depth.h" +#include "mongo/db/catalog/document_validation.h" #include "mongo/db/commands/feature_compatibility_version_parser.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/vector_clock_mutable.h" @@ -75,7 +76,10 @@ Status validateDepth(const BSONObj& obj) { } } // namespace -StatusWith<BSONObj> fixDocumentForInsert(ServiceContext* service, const BSONObj& doc) { +StatusWith<BSONObj> fixDocumentForInsert(OperationContext* opCtx, const BSONObj& doc) { + if (DocumentValidationSettings::get(opCtx).isInternalValidationDisabled()) + return StatusWith<BSONObj>(BSONObj()); + if (doc.objsize() > BSONObjMaxUserSize) return StatusWith<BSONObj>(ErrorCodes::BadValue, str::stream() << "object to insert too large" @@ -163,7 +167,7 @@ StatusWith<BSONObj> fixDocumentForInsert(ServiceContext* service, const BSONObj& if (hadId && e.fieldNameStringData() == "_id") { // no-op } else if (e.type() == bsonTimestamp && e.timestampValue() == 0) { - auto nextTime = VectorClockMutable::get(service)->tickClusterTime(1); + auto nextTime = VectorClockMutable::get(opCtx)->tickClusterTime(1); b.append(e.fieldName(), nextTime.asTimestamp()); } else { b.append(e); diff --git a/src/mongo/db/ops/insert.h b/src/mongo/db/ops/insert.h index d21e74ceb1c..bf1cafb40f2 100644 --- a/src/mongo/db/ops/insert.h +++ b/src/mongo/db/ops/insert.h @@ -32,7 +32,7 @@ namespace mongo { -class ServiceContext; +class OperationContext; /** * Validates that 'doc' is legal for insertion, possibly with some modifications. @@ -42,7 +42,7 @@ class ServiceContext; * - an empty BSONObj if 'doc' can be inserted as-is; or * - a non-empty BSONObj representing what should be inserted instead of 'doc'. */ -StatusWith<BSONObj> fixDocumentForInsert(ServiceContext* service, const BSONObj& doc); +StatusWith<BSONObj> fixDocumentForInsert(OperationContext* opCtx, const BSONObj& doc); /** diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index 3f6d70d45a7..7083b5caed9 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -548,7 +548,7 @@ WriteResult performInserts(OperationContext* opCtx, uassertStatusOK(userAllowedWriteNS(wholeOp.getNamespace())); - DisableDocumentValidationIfTrue docValidationDisabler( + DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler( opCtx, wholeOp.getWriteCommandBase().getBypassDocumentValidation()); LastOpFixer lastOpFixer(opCtx, wholeOp.getNamespace()); @@ -567,7 +567,7 @@ WriteResult performInserts(OperationContext* opCtx, for (auto&& doc : wholeOp.getDocuments()) { const bool isLastDoc = (&doc == &wholeOp.getDocuments().back()); - auto fixedDoc = fixDocumentForInsert(opCtx->getServiceContext(), doc); + auto fixedDoc = fixDocumentForInsert(opCtx, doc); if (!fixedDoc.isOK()) { // Handled after we insert anything in the batch to be sure we report errors in the // correct order. In an ordered insert, if one of the docs ahead of us fails, we should @@ -790,7 +790,7 @@ WriteResult performUpdates(OperationContext* opCtx, const write_ops::Update& who (txnParticipant && opCtx->inMultiDocumentTransaction())); uassertStatusOK(userAllowedWriteNS(wholeOp.getNamespace())); - DisableDocumentValidationIfTrue docValidationDisabler( + DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler( opCtx, wholeOp.getWriteCommandBase().getBypassDocumentValidation()); LastOpFixer lastOpFixer(opCtx, wholeOp.getNamespace()); @@ -953,7 +953,7 @@ WriteResult performDeletes(OperationContext* opCtx, const write_ops::Delete& who (txnParticipant && opCtx->inMultiDocumentTransaction())); uassertStatusOK(userAllowedWriteNS(wholeOp.getNamespace())); - DisableDocumentValidationIfTrue docValidationDisabler( + DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler( opCtx, wholeOp.getWriteCommandBase().getBypassDocumentValidation()); LastOpFixer lastOpFixer(opCtx, wholeOp.getNamespace()); diff --git a/src/mongo/db/ops/write_ops_exec.h b/src/mongo/db/ops/write_ops_exec.h index c6f03535198..b50c45dd168 100644 --- a/src/mongo/db/ops/write_ops_exec.h +++ b/src/mongo/db/ops/write_ops_exec.h @@ -69,6 +69,9 @@ struct WriteResult { * that case. This should generally be combined with LastError handling from parse failures. * * 'fromMigrate' indicates whether the operation was induced by a chunk migration + * + * Note: performInserts() gets called for both user and internal (like tenant collection cloner, + * and initial sync/tenant migration oplog buffer) inserts. */ WriteResult performInserts(OperationContext* opCtx, const write_ops::Insert& op, diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript index b03690d1ba3..91581b9b89d 100644 --- a/src/mongo/db/repl/SConscript +++ b/src/mongo/db/repl/SConscript @@ -345,6 +345,10 @@ env.Library( '$BUILD_DIR/mongo/db/service_context', 'storage_interface', ], + LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/catalog/document_validation', + '$BUILD_DIR/mongo/db/ops/write_ops_exec', + ], ) env.Library( @@ -1030,6 +1034,7 @@ env.Library( 'task_runner', ], LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/catalog/document_validation', '$BUILD_DIR/mongo/db/commands/list_collections_filter', '$BUILD_DIR/mongo/db/ops/write_ops_exec', '$BUILD_DIR/mongo/rpc/metadata', diff --git a/src/mongo/db/repl/oplog_applier_impl_test.cpp b/src/mongo/db/repl/oplog_applier_impl_test.cpp index d9fd2797afe..cc42a35967c 100644 --- a/src/mongo/db/repl/oplog_applier_impl_test.cpp +++ b/src/mongo/db/repl/oplog_applier_impl_test.cpp @@ -1532,7 +1532,7 @@ TEST_F(OplogApplierImplTest, onInsertsCalled = true; ASSERT_FALSE(opCtx->writesAreReplicated()); ASSERT_FALSE(opCtx->lockState()->shouldConflictWithSecondaryBatchApplication()); - ASSERT_TRUE(documentValidationDisabled(opCtx)); + ASSERT_TRUE(DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()); return Status::OK(); }; createCollectionWithUuid(_opCtx.get(), nss); diff --git a/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp b/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp index af2c78725f2..65bb60be1d9 100644 --- a/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp +++ b/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp @@ -173,7 +173,7 @@ void OplogApplierImplTest::_testApplyOplogEntryOrGroupedInsertsCrudOperation( ASSERT_TRUE( opCtx->lockState()->isCollectionLockedForMode(NamespaceString("test.t"), MODE_IX)); ASSERT_FALSE(opCtx->writesAreReplicated()); - ASSERT_TRUE(documentValidationDisabled(opCtx)); + ASSERT_TRUE(DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()); }; _opObserver->onInsertsFn = diff --git a/src/mongo/db/repl/oplog_applier_utils.cpp b/src/mongo/db/repl/oplog_applier_utils.cpp index 0f9ce9ac476..0eebd195222 100644 --- a/src/mongo/db/repl/oplog_applier_utils.cpp +++ b/src/mongo/db/repl/oplog_applier_utils.cpp @@ -191,7 +191,7 @@ Status OplogApplierUtils::applyOplogEntryOrGroupedInsertsCommon( OplogApplication::Mode oplogApplicationMode, IncrementOpsAppliedStatsFn incrementOpsAppliedStats, OpCounters* opCounters) { - invariant(documentValidationDisabled(opCtx)); + invariant(DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()); auto op = entryOrGroupedInserts.getOp(); // Count each log op application as a separate operation, for reporting purposes diff --git a/src/mongo/db/repl/oplog_buffer_collection.cpp b/src/mongo/db/repl/oplog_buffer_collection.cpp index a2916eee6e5..fbf3c77b17f 100644 --- a/src/mongo/db/repl/oplog_buffer_collection.cpp +++ b/src/mongo/db/repl/oplog_buffer_collection.cpp @@ -40,7 +40,9 @@ #include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/bson/util/bson_extract.h" #include "mongo/db/catalog/collection_options.h" +#include "mongo/db/catalog/document_validation.h" #include "mongo/db/dbdirectclient.h" +#include "mongo/db/ops/write_ops_exec.h" #include "mongo/db/repl/storage_interface.h" #include "mongo/util/assert_util.h" @@ -153,7 +155,7 @@ void OplogBufferCollection::push(OperationContext* opCtx, return; } size_t numDocs = std::distance(begin, end); - std::vector<InsertStatement> docsToInsert(numDocs); + std::vector<BSONObj> docsToInsert(numDocs); stdx::lock_guard<Latch> lk(_mutex); auto ts = _lastPushedTimestamp; std::transform(begin, end, docsToInsert.begin(), [&ts](const Value& value) { @@ -164,11 +166,31 @@ void OplogBufferCollection::push(OperationContext* opCtx, invariant(ts > previousTimestamp, str::stream() << "ts: " << ts.toString() << ", previous: " << previousTimestamp.toString()); - return InsertStatement(doc); + return doc; }); - auto status = _storageInterface->insertDocuments(opCtx, _nss, docsToInsert); - fassert(40161, status); + // Disabling internal document validation because the oplog buffer document inserts + // can violate max data size limit (which is BSONObjMaxUserSize 16MB) check. Since, the max + // user document size is 16MB, the oplog generated for those writes can exceed 16MB + // (16MB user data + additional bytes for oplog fields like ’’op”, “ns”, “ui”). + DisableDocumentValidation documentValidationDisabler( + opCtx, + DocumentValidationSettings::kDisableSchemaValidation | + DocumentValidationSettings::kDisableInternalValidation); + + write_ops::Insert insertOp(_nss); + insertOp.setDocuments(std::move(docsToInsert)); + insertOp.setWriteCommandBase([] { + write_ops::WriteCommandBase wcb; + wcb.setOrdered(true); + return wcb; + }()); + + auto writeResult = write_ops_exec::performInserts(opCtx, insertOp); + invariant(!writeResult.results.empty()); + // Since the writes are ordered, it's ok to check just the last writeOp result. + fassert(40161, writeResult.results.back()); + _lastPushedTimestamp = ts; _count += numDocs; diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp index 2e9c18d87f6..f0ebaa6b9bb 100644 --- a/src/mongo/db/repl/storage_interface_impl.cpp +++ b/src/mongo/db/repl/storage_interface_impl.cpp @@ -221,7 +221,12 @@ StorageInterfaceImpl::createCollectionForBulkLoading( getGlobalServiceContext()->makeClient(str::stream() << nss.ns() << " loader")); auto opCtx = cc().makeOperationContext(); - documentValidationDisabled(opCtx.get()) = true; + // DocumentValidationSettings::kDisableInternalValidation is currently inert. + // But, it's logically ok to disable internal validation as this function gets called + // only during initial sync. + DocumentValidationSettings::get(opCtx.get()) + .setFlags(DocumentValidationSettings::kDisableSchemaValidation | + DocumentValidationSettings::kDisableInternalValidation); std::unique_ptr<AutoGetCollection> autoColl; // Retry if WCE. diff --git a/src/mongo/db/repl/tenant_collection_cloner.cpp b/src/mongo/db/repl/tenant_collection_cloner.cpp index 02baa2de8c1..af6b1739017 100644 --- a/src/mongo/db/repl/tenant_collection_cloner.cpp +++ b/src/mongo/db/repl/tenant_collection_cloner.cpp @@ -32,6 +32,7 @@ #include "mongo/platform/basic.h" #include "mongo/base/string_data.h" +#include "mongo/db/catalog/document_validation.h" #include "mongo/db/commands/list_collections_filter.h" #include "mongo/db/db_raii.h" #include "mongo/db/ops/write_ops_exec.h" @@ -361,20 +362,28 @@ void TenantCollectionCloner::insertDocumentsCallback( _progressMeter.hit(int(docs.size())); } + // Disabling the internal document validation for inserts on recipient side as those + // validation should have already been performed on donor's primary during tenant + // collection document insertion. + DisableDocumentValidation doumentValidationDisabler( + cbd.opCtx, + DocumentValidationSettings::kDisableSchemaValidation | + DocumentValidationSettings::kDisableInternalValidation); + write_ops::Insert insertOp(_sourceNss); insertOp.setDocuments(std::move(docs)); insertOp.setWriteCommandBase([] { write_ops::WriteCommandBase wcb; wcb.setOrdered(true); - wcb.setBypassDocumentValidation(true); return wcb; }()); // write_ops_exec::PerformInserts() will handle limiting the batch size // that gets inserted in a single WUOW. - auto writeResults = write_ops_exec::performInserts(cbd.opCtx, insertOp); + auto writeResult = write_ops_exec::performInserts(cbd.opCtx, insertOp); + invariant(!writeResult.results.empty()); // Since the writes are ordered, it's ok to check just the last writeOp result. - uassertStatusOKWithContext(writeResults.results.back(), + uassertStatusOKWithContext(writeResult.results.back(), "Tenant collection cloner: insert documents"); tenantMigrationHangDuringCollectionClone.executeIf( diff --git a/src/mongo/dbtests/insert_test.cpp b/src/mongo/dbtests/insert_test.cpp index 957b2764460..9f28bede251 100644 --- a/src/mongo/dbtests/insert_test.cpp +++ b/src/mongo/dbtests/insert_test.cpp @@ -46,7 +46,7 @@ public: _lock(_opCtx.get()), _autoColl(_opCtx.get(), kInsertTestNss, MODE_IX) {} - const OperationContext* getOperationContext() const { + OperationContext* getOperationContext() const { return _opCtx.get(); } @@ -79,21 +79,21 @@ BSONArray makeNestedArray(size_t depth) { } TEST_F(InsertTest, FixDocumentForInsertAcceptsEmptyDocuments) { - ASSERT_OK(fixDocumentForInsert(getOperationContext()->getServiceContext(), BSONObj())); + ASSERT_OK(fixDocumentForInsert(getOperationContext(), BSONObj())); } TEST_F(InsertTest, FixDocumentForInsertAcceptsDocumentsAtStorageDepthLimit) { - ASSERT_OK(fixDocumentForInsert(getOperationContext()->getServiceContext(), + ASSERT_OK(fixDocumentForInsert(getOperationContext(), makeNestedObject(BSONDepth::getMaxDepthForUserStorage()))); - ASSERT_OK(fixDocumentForInsert(getOperationContext()->getServiceContext(), + ASSERT_OK(fixDocumentForInsert(getOperationContext(), makeNestedArray(BSONDepth::getMaxDepthForUserStorage()))); } TEST_F(InsertTest, FixDocumentForInsertFailsOnDeeplyNestedDocuments) { - ASSERT_EQ(fixDocumentForInsert(getOperationContext()->getServiceContext(), + ASSERT_EQ(fixDocumentForInsert(getOperationContext(), makeNestedObject(BSONDepth::getMaxDepthForUserStorage() + 1)), ErrorCodes::Overflow); - ASSERT_EQ(fixDocumentForInsert(getOperationContext()->getServiceContext(), + ASSERT_EQ(fixDocumentForInsert(getOperationContext(), makeNestedArray(BSONDepth::getMaxDepthForUserStorage() + 1)), ErrorCodes::Overflow); } diff --git a/src/mongo/dbtests/pdfiletests.cpp b/src/mongo/dbtests/pdfiletests.cpp index a083e3e08ac..5fd4540a6c3 100644 --- a/src/mongo/dbtests/pdfiletests.cpp +++ b/src/mongo/dbtests/pdfiletests.cpp @@ -84,7 +84,7 @@ public: OpDebug* const nullOpDebug = nullptr; ASSERT(!coll->insertDocument(&_opCtx, InsertStatement(x), nullOpDebug, true).isOK()); - StatusWith<BSONObj> fixed = fixDocumentForInsert(_opCtx.getServiceContext(), x); + StatusWith<BSONObj> fixed = fixDocumentForInsert(&_opCtx, x); ASSERT(fixed.isOK()); x = fixed.getValue(); ASSERT(x["_id"].type() == jstOID); @@ -101,7 +101,7 @@ public: b.append("_id", 1); BSONObj o = b.done(); - BSONObj fixed = fixDocumentForInsert(_opCtx.getServiceContext(), o).getValue(); + BSONObj fixed = fixDocumentForInsert(&_opCtx, o).getValue(); ASSERT_EQUALS(2, fixed.nFields()); ASSERT(fixed.firstElement().fieldNameStringData() == "_id"); ASSERT(fixed.firstElement().number() == 1); @@ -126,7 +126,7 @@ public: o = b.obj(); } - BSONObj fixed = fixDocumentForInsert(_opCtx.getServiceContext(), o).getValue(); + BSONObj fixed = fixDocumentForInsert(&_opCtx, o).getValue(); ASSERT_EQUALS(3, fixed.nFields()); ASSERT(fixed.firstElement().fieldNameStringData() == "_id"); ASSERT(fixed.firstElement().number() == 1); @@ -148,13 +148,10 @@ public: class ValidId : public Base { public: void run() { - ASSERT(fixDocumentForInsert(_opCtx.getServiceContext(), BSON("_id" << 5)).isOK()); - ASSERT( - fixDocumentForInsert(_opCtx.getServiceContext(), BSON("_id" << BSON("x" << 5))).isOK()); - ASSERT(!fixDocumentForInsert(_opCtx.getServiceContext(), BSON("_id" << BSON("$x" << 5))) - .isOK()); - ASSERT(!fixDocumentForInsert(_opCtx.getServiceContext(), BSON("_id" << BSON("$oid" << 5))) - .isOK()); + ASSERT(fixDocumentForInsert(&_opCtx, BSON("_id" << 5)).isOK()); + ASSERT(fixDocumentForInsert(&_opCtx, BSON("_id" << BSON("x" << 5))).isOK()); + ASSERT(!fixDocumentForInsert(&_opCtx, BSON("_id" << BSON("$x" << 5))).isOK()); + ASSERT(!fixDocumentForInsert(&_opCtx, BSON("_id" << BSON("$oid" << 5))).isOK()); } }; } // namespace Insert |