diff options
author | Yuhong Zhang <yuhong.zhang@mongodb.com> | 2022-06-28 02:46:39 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-06-28 03:16:45 +0000 |
commit | 6f4ad824d65ab928f04356e6e1a2fefc15499884 (patch) | |
tree | 8dde7a5fa06fc621aa53e272d4441637af673701 /jstests | |
parent | a5382fb01bb2d023c80c2eb1af807eca1f145c43 (diff) | |
download | mongo-6f4ad824d65ab928f04356e6e1a2fefc15499884.tar.gz |
SERVER-67045 Create a testing interface to insert non-conformant BSON documents
Diffstat (limited to 'jstests')
-rw-r--r-- | jstests/disk/libs/wt_file_helper.js | 49 | ||||
-rw-r--r-- | jstests/disk/validate_bson_inconsistency.js | 39 |
2 files changed, 88 insertions, 0 deletions
diff --git a/jstests/disk/libs/wt_file_helper.js b/jstests/disk/libs/wt_file_helper.js index 862d189c85d..b94420434f7 100644 --- a/jstests/disk/libs/wt_file_helper.js +++ b/jstests/disk/libs/wt_file_helper.js @@ -234,3 +234,52 @@ let truncateUriAndRestartMongod = function(uri, conn, mongodOptions) { runWiredTigerTool("-h", conn.dbpath, "truncate", uri); return startMongodOnExistingPath(conn.dbpath, mongodOptions); }; + +/** + * Stops the given mongod, dumps the table with the uri, modifies the content, and loads it back to + * the table. + */ +let rewriteTable = function(uri, conn, modifyData) { + MongoRunner.stopMongod(conn, null, {skipValidation: true}); + const tempDumpFile = conn.dbpath + "/temp_dump"; + const newTableFile = conn.dbpath + "/new_table_file"; + runWiredTigerTool("-h", + conn.dbpath, + "-r", + "-C", + "log=(compressor=snappy,path=journal)", + "dump", + "-x", + "-f", + tempDumpFile, + "table:" + uri); + let dumpLines = cat(tempDumpFile).split("\n"); + modifyData(dumpLines); + writeFile(newTableFile, dumpLines.join("\n")); + runWiredTigerTool("-h", conn.dbpath, "load", "-f", newTableFile, "-r", uri); +}; + +// In WiredTiger table dumps, the first seven lines are the header and key that we don't want to +// modify. We will skip them and start from the line containing the first value. +const wtHeaderLines = 7; + +/** + * Inserts the documents with duplicate field names into the MongoDB server. + */ +let insertDocDuplicateFieldName = function(coll, uri, conn, numDocs) { + for (let i = 0; i < numDocs; ++i) { + coll.insert({a: "aaaaaaa", b: "bbbbbbb"}); + } + // The format of the BSON documents will be {_id: ObjectId(), a: "aaaaaaa", a: "bbbbbbb"}. + let makeDuplicateFieldNames = function(lines) { + // The offset of the document's field name 'b' in the hex string dumped by wt tool. + const offsetToFieldB = 75; + // Each record takes two lines with a key and a value. We will only modify the values. + for (let i = wtHeaderLines; i < lines.length; i += 2) { + // Switch the field name 'b' to 'a' to create a duplicate field name. + lines[i] = lines[i].substring(0, offsetToFieldB) + "1" + + lines[i].substring(offsetToFieldB + 1); + } + }; + rewriteTable(uri, conn, makeDuplicateFieldNames); +};
\ No newline at end of file diff --git a/jstests/disk/validate_bson_inconsistency.js b/jstests/disk/validate_bson_inconsistency.js new file mode 100644 index 00000000000..a91eb8d7695 --- /dev/null +++ b/jstests/disk/validate_bson_inconsistency.js @@ -0,0 +1,39 @@ +/** + * Tests that the validate command detects various types of BSON inconsistencies. + */ + +(function() { + +load('jstests/disk/libs/wt_file_helper.js'); + +const baseName = "validate_bson_inconsistency"; +const collNamePrefix = "test_"; +let count = 0; +const dbpath = MongoRunner.dataPath + baseName + "/"; + +resetDbpath(dbpath); + +(function validateDocumentsDuplicateFieldNames() { + jsTestLog("Validate documents with duplicate field names"); + + let mongod = startMongodOnExistingPath(dbpath); + let db = mongod.getDB(baseName); + const collName = collNamePrefix + count++; + db.createCollection(collName); + let testColl = db[collName]; + + let uri = getUriForColl(testColl); + const numDocs = 10; + insertDocDuplicateFieldName(testColl, uri, mongod, numDocs); + + mongod = startMongodOnExistingPath(dbpath); + db = mongod.getDB(baseName); + testColl = db[collName]; + + let res = assert.commandWorked(testColl.validate()); + assert(res.valid, tojson(res)); + // TODO: Check the warnings that the documents with duplicate field names are detected. + + MongoRunner.stopMongod(mongod, null, {skipValidation: true}); +})(); +})(); |