summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests
diff options
context:
space:
mode:
authorShin Yee Tan <shinyee.tan@mongodb.com>2020-07-08 21:52:28 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-07-09 00:44:00 +0000
commit1ccc744fa34d50ca7a9f7e81c9b8e22f2557ae6e (patch)
treea5fed739241e5e5f1ddf87f49b4003fcf0cdf0d8 /src/mongo/dbtests
parenta2364e8742f0846b8143044d0511825319133049 (diff)
downloadmongo-1ccc744fa34d50ca7a9f7e81c9b8e22f2557ae6e.tar.gz
SERVER-24165 Validate should report records with invalid BSON
Diffstat (limited to 'src/mongo/dbtests')
-rw-r--r--src/mongo/dbtests/validate_tests.cpp106
1 files changed, 71 insertions, 35 deletions
diff --git a/src/mongo/dbtests/validate_tests.cpp b/src/mongo/dbtests/validate_tests.cpp
index 13214d0d2ab..0fee3f366fb 100644
--- a/src/mongo/dbtests/validate_tests.cpp
+++ b/src/mongo/dbtests/validate_tests.cpp
@@ -96,13 +96,6 @@ protected:
_opCtx.recoveryUnit()->setTimestampReadSource(originalReadSource);
});
- // This function will force a checkpoint, so background validation can then read from that
- // checkpoint and see all the new data.
- // Set 'stableCheckpoint' to false, so we checkpoint ALL data, not just up to WT's
- // stable_timestamp.
- _opCtx.recoveryUnit()->waitUntilUnjournaledWritesDurable(&_opCtx,
- /*stableCheckpoint*/ false);
-
auto mode = [&] {
if (_background)
return CollectionValidation::ValidateMode::kBackground;
@@ -1203,13 +1196,6 @@ public:
releaseDb();
{
- // This function will force a checkpoint, so background validation can then read from
- // that checkpoint and see all the new data.
- // Set 'stableCheckpoint' to false, so we checkpoint ALL data, not just up to WT's
- // stable_timestamp.
- _opCtx.recoveryUnit()->waitUntilUnjournaledWritesDurable(&_opCtx,
- /*stableCheckpoint*/ false);
-
ValidateResults results;
BSONObjBuilder output;
@@ -1328,13 +1314,6 @@ public:
}
{
- // This function will force a checkpoint, so background validation can then read from
- // that checkpoint and see all the new data.
- // Set 'stableCheckpoint' to false, so we checkpoint ALL data, not just up to WT's
- // stable_timestamp.
- _opCtx.recoveryUnit()->waitUntilUnjournaledWritesDurable(&_opCtx,
- /*stableCheckpoint*/ false);
-
ValidateResults results;
BSONObjBuilder output;
@@ -1426,13 +1405,6 @@ public:
}
{
- // This function will force a checkpoint, so background validation can then read from
- // that checkpoint and see all the new data.
- // Set 'stableCheckpoint' to false, so we checkpoint ALL data, not just up to WT's
- // stable_timestamp.
- _opCtx.recoveryUnit()->waitUntilUnjournaledWritesDurable(&_opCtx,
- /*stableCheckpoint*/ false);
-
ValidateResults results;
BSONObjBuilder output;
@@ -1599,13 +1571,6 @@ public:
}
{
- // This function will force a checkpoint, so background validation can then read from
- // that checkpoint and see all the new data.
- // Set 'stableCheckpoint' to false, so we checkpoint ALL data, not just up to WT's
- // stable_timestamp.
- _opCtx.recoveryUnit()->waitUntilUnjournaledWritesDurable(&_opCtx,
- /*stableCheckpoint*/ false);
-
// Now we have two missing index entries with the keys { : 1 } since the KeyStrings
// aren't hydrated with their field names.
ensureValidateFailed();
@@ -1776,6 +1741,74 @@ public:
}
};
+template <bool full, bool background>
+class ValidateInvalidBSONResults : public ValidateBase {
+public:
+ ValidateInvalidBSONResults() : ValidateBase(full, background) {}
+
+ void run() {
+ // Cannot run validate with {background:true} if either
+ // - the RecordStore cursor does not retrieve documents in RecordId order
+ // - or the storage engine does not support checkpoints.
+ if (_background && (!_isInRecordIdOrder || !_engineSupportsCheckpoints)) {
+ return;
+ }
+
+ // Create a new collection.
+ lockDb(MODE_X);
+ Collection* coll;
+ {
+ WriteUnitOfWork wunit(&_opCtx);
+ ASSERT_OK(_db->dropCollection(&_opCtx, _nss));
+ coll = _db->createCollection(&_opCtx, _nss);
+ wunit.commit();
+ }
+
+ // Encode an invalid BSON Object with an invalid type, x90 and insert record
+ const char* buffer = "\x0c\x00\x00\x00\x90\x41\x00\x10\x00\x00\x00\x00";
+ BSONObj obj(buffer);
+ lockDb(MODE_X);
+ RecordStore* rs = coll->getRecordStore();
+ RecordId rid;
+ {
+ WriteUnitOfWork wunit(&_opCtx);
+ auto swRecordId = rs->insertRecord(&_opCtx, obj.objdata(), obj.objsize(), Timestamp());
+ ASSERT_OK(swRecordId);
+ rid = swRecordId.getValue();
+ wunit.commit();
+ }
+ releaseDb();
+
+ {
+ ValidateResults results;
+ BSONObjBuilder output;
+
+ ASSERT_OK(
+ CollectionValidation::validate(&_opCtx,
+ _nss,
+ CollectionValidation::ValidateMode::kForeground,
+ &results,
+ &output,
+ kTurnOnExtraLoggingForTest));
+
+ auto dumpOnErrorGuard = makeGuard([&] {
+ StorageDebugUtil::printValidateResults(results);
+ StorageDebugUtil::printCollectionAndIndexTableEntries(&_opCtx, coll->ns());
+ });
+
+ ASSERT_EQ(false, results.valid);
+ ASSERT_EQ(static_cast<size_t>(1), results.errors.size());
+ ASSERT_EQ(static_cast<size_t>(0), results.warnings.size());
+ ASSERT_EQ(static_cast<size_t>(0), results.extraIndexEntries.size());
+ ASSERT_EQ(static_cast<size_t>(0), results.missingIndexEntries.size());
+ ASSERT_EQ(static_cast<size_t>(1), results.corruptRecords.size());
+ ASSERT_EQ(rid, results.corruptRecords[0]);
+
+ dumpOnErrorGuard.dismiss();
+ }
+ }
+};
+
class ValidateTests : public OldStyleSuiteSpecification {
public:
ValidateTests() : OldStyleSuiteSpecification("validate_tests") {}
@@ -1823,6 +1856,9 @@ public:
add<ValidateDuplicateKeysUniqueIndex<false, false>>();
add<ValidateDuplicateKeysUniqueIndex<false, true>>();
+
+ add<ValidateInvalidBSONResults<false, false>>();
+ add<ValidateInvalidBSONResults<false, true>>();
}
};