diff options
-rw-r--r-- | jstests/libs/clustered_collections/clustered_capped_utils.js | 12 | ||||
-rw-r--r-- | jstests/libs/clustered_collections/clustered_collection_util.js | 10 | ||||
-rw-r--r-- | jstests/libs/ttl_util.js | 40 | ||||
-rw-r--r-- | jstests/noPassthrough/clustered_coll_mod.js | 9 | ||||
-rw-r--r-- | jstests/noPassthrough/clustered_coll_mod_arbitrary_key.js | 10 | ||||
-rw-r--r-- | jstests/noPassthrough/clustered_collection_ttl.js | 3 | ||||
-rw-r--r-- | jstests/noPassthrough/collmod_ttl.js | 16 | ||||
-rw-r--r-- | jstests/noPassthrough/timeseries_ttl.js | 13 | ||||
-rw-r--r-- | jstests/noPassthrough/ttl_hidden_index.js | 7 | ||||
-rw-r--r-- | jstests/noPassthrough/ttl_monitor_does_not_unregister_index_during_collection_creation.js | 11 | ||||
-rw-r--r-- | jstests/noPassthrough/ttl_operation_metrics.js | 12 | ||||
-rw-r--r-- | jstests/noPassthrough/ttl_partial_index.js | 7 | ||||
-rw-r--r-- | jstests/noPassthrough/ttl_resharding_collection.js | 7 | ||||
-rw-r--r-- | jstests/noPassthrough/ttl_with_dropIndex.js | 6 |
14 files changed, 87 insertions, 76 deletions
diff --git a/jstests/libs/clustered_collections/clustered_capped_utils.js b/jstests/libs/clustered_collections/clustered_capped_utils.js index 8e6ae836223..e9c136f57fd 100644 --- a/jstests/libs/clustered_collections/clustered_capped_utils.js +++ b/jstests/libs/clustered_collections/clustered_capped_utils.js @@ -1,3 +1,5 @@ +load("jstests/libs/ttl_util.js"); + var ClusteredCappedUtils = class { // Validate TTL-based deletion on a clustered, capped collection. static testClusteredCappedCollectionWithTTL(db, collName, clusterKeyField) { @@ -39,7 +41,8 @@ var ClusteredCappedUtils = class { } assert.commandWorked(coll.insertMany(docs, {ordered: true})); - ClusteredCollectionUtil.waitForTTL(db); + // This test runs with default read concern 'local'. + TTLUtil.waitForPass(db, /*waitForMajorityCommit=*/false); // Only the recent documents survived. assert.eq(coll.find().itcount(), batchSize); @@ -140,7 +143,7 @@ var ClusteredCappedUtils = class { // TTL delete the two old documents. assert.commandWorked(db.adminCommand({setParameter: 1, ttlMonitorEnabled: true})); - ClusteredCollectionUtil.waitForTTL(db); + TTLUtil.waitForPass(db, /*waitForMajorityCommit=*/isReplicated); assert.eq(2, db.getCollection(collName).find().itcount()); // Confirm that the tailable getMore can resume from where it was, since the document the @@ -209,7 +212,7 @@ var ClusteredCappedUtils = class { // TTL delete the two old documents, while the tailable cursor is still on the first one. assert.commandWorked(db.adminCommand({setParameter: 1, ttlMonitorEnabled: true})); - ClusteredCollectionUtil.waitForTTL(db); + TTLUtil.waitForPass(db, /*waitForMajorityCommit=*/isReplicated); assert.eq(1, db.getCollection(collName).find().itcount()); // Confirm that the tailable cursor returns CappedPositionLost, as the document it was @@ -292,7 +295,8 @@ var ClusteredCappedUtils = class { // Expire the document. assert.commandWorked(db.adminCommand({setParameter: 1, ttlMonitorEnabled: true})); - ClusteredCollectionUtil.waitForTTL(db); + // No need to wait for majority commit, as default 'local' read concern is used. + TTLUtil.waitForPass(db, /*waitForMajorityCommit=*/false); assert.eq(0, db.getCollection(collName).find().itcount()); // The TTL deletion has been replicated to the oplog. diff --git a/jstests/libs/clustered_collections/clustered_collection_util.js b/jstests/libs/clustered_collections/clustered_collection_util.js index ad6c0111c8a..c63b5ce56e9 100644 --- a/jstests/libs/clustered_collections/clustered_collection_util.js +++ b/jstests/libs/clustered_collections/clustered_collection_util.js @@ -196,14 +196,4 @@ var ClusteredCollectionUtil = class { assert.eq(1, coll.find({[clusterKey]: NumberLong("42")}).itcount()); coll.drop(); } - - static waitForTTL(db) { - // The 'ttl.passes' metric is incremented when the TTL monitor starts processing the - // indexes, so we wait for it to be incremented twice to know that the TTL monitor finished - // processing the indexes at least once. - const ttlPasses = db.serverStatus().metrics.ttl.passes; - assert.soon(function() { - return db.serverStatus().metrics.ttl.passes > ttlPasses + 1; - }); - } }; diff --git a/jstests/libs/ttl_util.js b/jstests/libs/ttl_util.js new file mode 100644 index 00000000000..59c67be7486 --- /dev/null +++ b/jstests/libs/ttl_util.js @@ -0,0 +1,40 @@ +/** + * Utilities for testing TTL collections. + */ + +load("jstests/libs/fixture_helpers.js"); + +const TTLUtil = class { + /** + * Wait until documents inserted before a call to this function have been visited by a TTL + * monitor pass. On replica sets, by default the function waits for the TTL deletes to become + * visible with read concern 'majority'. + * + * @param {DB} db Database connection. + * @param {boolean} waitForMajorityCommit Only applies when 'db' is from a replica set, set to + * false to disable waiting for TTL deletes to become majority commited. + */ + static waitForPass(db, waitForMajorityCommit = true) { + // The 'ttl.passes' metric is incremented when the TTL monitor has finished a pass. + // Depending on the timing of the pass, seeing an increment of this metric might not + // necessarily imply the data we are expecting to be deleted has been seen, as the TTL pass + // might have been in progress while the data was inserted. Waiting to see two increases of + // this metric guarantees that the TTL has started a new pass after test data insertion. + const ttlPasses = db.serverStatus().metrics.ttl.passes; + assert.soon(function() { + return db.serverStatus().metrics.ttl.passes > ttlPasses + 1; + }); + + // Readers using a "majority" read concern might expect TTL deletes to be visible after + // waitForPass. TTL writes do not imply 'majority' nor 'j: true', and are made durable by + // the journal flusher when a flush cycle happens every 'commitIntervalMs'. Even in single + // node replica sets, depending on journal flush timing, it is possible that TTL deletes + // have not been made durable after returning from this function, and are not considered + // majority commited. We force the majority commit point to include the TTL writes up to + // this point in time. + if (FixtureHelpers.isReplSet(db) && waitForMajorityCommit) { + // waitForMajorityCommit will never be true if 'db' is not part of a replica set. + FixtureHelpers.awaitLastOpCommitted(db); + } + } +}; diff --git a/jstests/noPassthrough/clustered_coll_mod.js b/jstests/noPassthrough/clustered_coll_mod.js index a482cb580e1..997b452436d 100644 --- a/jstests/noPassthrough/clustered_coll_mod.js +++ b/jstests/noPassthrough/clustered_coll_mod.js @@ -10,6 +10,7 @@ "use strict"; load("jstests/libs/clustered_collections/clustered_collection_util.js"); +load("jstests/libs/ttl_util.js"); // Run TTL monitor constantly to speed up this test. const conn = MongoRunner.runMongod({setParameter: 'ttlMonitorSleepSecs=1'}); @@ -40,13 +41,13 @@ function testCollMod(coll, clusterKey, clusterKeyName) { assert.commandWorked(coll.insertMany(docs, {ordered: false})); assert.eq(coll.find().itcount(), batchSize); - ClusteredCollectionUtil.waitForTTL(coll.getDB()); + TTLUtil.waitForPass(coll.getDB()); assert.eq(coll.find().itcount(), batchSize); // Shorten the expireAfterSeconds so all the documents in the collection are expired. assert.commandWorked(coll.getDB().runCommand({collMod: collName, expireAfterSeconds: 1})); - ClusteredCollectionUtil.waitForTTL(coll.getDB()); + TTLUtil.waitForPass(coll.getDB()); // Confirm all documents were deleted once the expireAfterSeconds was shortened. assert.eq(coll.find().itcount(), 0); @@ -55,11 +56,11 @@ function testCollMod(coll, clusterKey, clusterKeyName) { assert.commandWorked(coll.getDB().runCommand({collMod: collName, expireAfterSeconds: "off"})); // Ensure there is no outstanding TTL pass in progress that will still remove entries. - ClusteredCollectionUtil.waitForTTL(coll.getDB()); + TTLUtil.waitForPass(coll.getDB()); assert.commandWorked(coll.insert({[clusterKeyFieldName]: now, info: "unexpired"})); - ClusteredCollectionUtil.waitForTTL(coll.getDB()); + TTLUtil.waitForPass(coll.getDB()); assert.eq(coll.find().itcount(), 1); diff --git a/jstests/noPassthrough/clustered_coll_mod_arbitrary_key.js b/jstests/noPassthrough/clustered_coll_mod_arbitrary_key.js index b5399f07a5c..35ef0ee48d3 100644 --- a/jstests/noPassthrough/clustered_coll_mod_arbitrary_key.js +++ b/jstests/noPassthrough/clustered_coll_mod_arbitrary_key.js @@ -10,6 +10,7 @@ "use strict"; load("jstests/libs/clustered_collections/clustered_collection_util.js"); +load("jstests/libs/ttl_util.js"); // Run TTL monitor constantly to speed up this test. const conn = MongoRunner.runMongod( @@ -41,14 +42,13 @@ function testCollMod(coll, clusterKey, clusterKeyName) { assert.commandWorked(coll.insertMany(docs, {ordered: false})); assert.eq(coll.find().itcount(), batchSize); - ClusteredCollectionUtil.waitForTTL(coll.getDB()); + TTLUtil.waitForPass(coll.getDB()); assert.eq(coll.find().itcount(), batchSize); // Shorten the expireAfterSeconds so all the documents in the collection are expired. assert.commandWorked(coll.getDB().runCommand({collMod: collName, expireAfterSeconds: 1})); - ClusteredCollectionUtil.waitForTTL(coll.getDB()); - + TTLUtil.waitForPass(coll.getDB()); // Confirm all documents were deleted once the expireAfterSeconds was shortened. assert.eq(coll.find().itcount(), 0); @@ -56,11 +56,11 @@ function testCollMod(coll, clusterKey, clusterKeyName) { assert.commandWorked(coll.getDB().runCommand({collMod: collName, expireAfterSeconds: "off"})); // Ensure there is no outstanding TTL pass in progress that will still remove entries. - ClusteredCollectionUtil.waitForTTL(coll.getDB()); + TTLUtil.waitForPass(coll.getDB()); assert.commandWorked(coll.insert({[clusterKeyFieldName]: now, info: "unexpired"})); - ClusteredCollectionUtil.waitForTTL(coll.getDB()); + TTLUtil.waitForPass(coll.getDB()); assert.eq(coll.find().itcount(), 1); diff --git a/jstests/noPassthrough/clustered_collection_ttl.js b/jstests/noPassthrough/clustered_collection_ttl.js index ce4d713c154..de21cccb219 100644 --- a/jstests/noPassthrough/clustered_collection_ttl.js +++ b/jstests/noPassthrough/clustered_collection_ttl.js @@ -10,6 +10,7 @@ "use strict"; load("jstests/libs/clustered_collections/clustered_collection_util.js"); load('jstests/libs/dateutil.js'); +load('jstests/libs/ttl_util.js'); // Run TTL monitor constantly to speed up this test. const conn = MongoRunner.runMongod({setParameter: 'ttlMonitorSleepSecs=1'}); @@ -79,7 +80,7 @@ const insertAndValidateTTL = (coll, ttlFieldName) => { } assert.commandWorked(coll.insertMany(docs, {ordered: false})); - ClusteredCollectionUtil.waitForTTL(coll.getDB("test")); + TTLUtil.waitForPass(coll.getDB("test")); // The unexpired documents should still be preserved. assert.eq(coll.find().itcount(), batchSize * 2); diff --git a/jstests/noPassthrough/collmod_ttl.js b/jstests/noPassthrough/collmod_ttl.js index f68e43b67b5..9464ec3284c 100644 --- a/jstests/noPassthrough/collmod_ttl.js +++ b/jstests/noPassthrough/collmod_ttl.js @@ -11,6 +11,8 @@ (function() { "use strict"; +load("jstests/libs/ttl_util.js"); + // Runs TTL monitor constantly to speed up this test. const conn = MongoRunner.runMongod({setParameter: 'ttlMonitorSleepSecs=1'}); @@ -21,21 +23,11 @@ assert.commandWorked(testDB.createCollection(coll.getName())); coll.createIndex({a: 1}); const expireAfterSeconds = 5; -const waitForTTL = () => { - // The 'ttl.passes' metric is incremented when the TTL monitor starts processing the indexes, so - // we wait for it to be incremented twice to know that the TTL monitor finished processing the - // indexes at least once. - const ttlPasses = testDB.serverStatus().metrics.ttl.passes; - assert.soon(function() { - return testDB.serverStatus().metrics.ttl.passes > ttlPasses + 1; - }); -}; - // Inserts a measurement older than the TTL expiry. The data should be found. const expired = new Date((new Date()).getTime() - (1000 * 10)); assert.commandWorked(coll.insert({a: expired})); -waitForTTL(); +TTLUtil.waitForPass(testDB); assert.eq(1, coll.find().itcount()); // Converts to a TTL index and checks the data is deleted. @@ -47,7 +39,7 @@ assert.commandWorked(testDB.runCommand({ } })); -waitForTTL(); +TTLUtil.waitForPass(testDB); assert.eq(0, coll.find().itcount()); MongoRunner.stopMongod(conn); diff --git a/jstests/noPassthrough/timeseries_ttl.js b/jstests/noPassthrough/timeseries_ttl.js index ebc2cb272f6..087bcd15c21 100644 --- a/jstests/noPassthrough/timeseries_ttl.js +++ b/jstests/noPassthrough/timeseries_ttl.js @@ -11,6 +11,7 @@ (function() { "use strict"; load("jstests/libs/clustered_collections/clustered_collection_util.js"); +load("jstests/libs/ttl_util.js"); // Run TTL monitor constantly to speed up this test. const conn = MongoRunner.runMongod({setParameter: 'ttlMonitorSleepSecs=1'}); @@ -50,7 +51,7 @@ testCase((coll, bucketsColl) => { assert.eq(2, coll.find().itcount()); assert.eq(1, bucketsColl.find().itcount()); - ClusteredCollectionUtil.waitForTTL(coll.getDB("test")); + TTLUtil.waitForPass(coll.getDB("test")); assert.eq(2, coll.find().itcount()); assert.eq(1, bucketsColl.find().itcount()); }); @@ -67,7 +68,7 @@ testCase((coll, bucketsColl) => { assert.eq(2, coll.find().itcount()); assert.eq(1, bucketsColl.find().itcount()); - ClusteredCollectionUtil.waitForTTL(coll.getDB("test")); + TTLUtil.waitForPass(coll.getDB("test")); assert.eq(2, coll.find().itcount()); assert.eq(1, bucketsColl.find().itcount()); }); @@ -81,7 +82,7 @@ testCase((coll, bucketsColl) => { assert.commandWorked(coll.insert({[timeFieldName]: minTime, [metaFieldName]: "localhost"})); assert.commandWorked(coll.insert({[timeFieldName]: maxTime, [metaFieldName]: "localhost"})); - ClusteredCollectionUtil.waitForTTL(coll.getDB("test")); + TTLUtil.waitForPass(coll.getDB("test")); assert.eq(0, coll.find().itcount()); assert.eq(0, bucketsColl.find().itcount()); }); @@ -100,7 +101,7 @@ testCase((coll, bucketsColl) => { assert.eq(2, coll.find().itcount()); assert.eq(1, bucketsColl.find().itcount()); - ClusteredCollectionUtil.waitForTTL(coll.getDB("test")); + TTLUtil.waitForPass(coll.getDB("test")); assert.eq(2, coll.find().itcount()); assert.eq(1, bucketsColl.find().itcount()); }); @@ -116,7 +117,7 @@ testCase((coll, bucketsColl) => { {[timeFieldName]: maxTime, [metaFieldName]: "localhost"} ])); - ClusteredCollectionUtil.waitForTTL(coll.getDB("test")); + TTLUtil.waitForPass(coll.getDB("test")); assert.eq(0, coll.find().itcount()); assert.eq(0, bucketsColl.find().itcount()); }); @@ -149,7 +150,7 @@ testCase((coll, bucketsColl) => { expireAfterSeconds: expireAfterSeconds, })); - ClusteredCollectionUtil.waitForTTL(coll.getDB("test")); + TTLUtil.waitForPass(coll.getDB("test")); assert.eq(0, coll.find().itcount()); assert.eq(0, bucketsColl.find().itcount()); })(); diff --git a/jstests/noPassthrough/ttl_hidden_index.js b/jstests/noPassthrough/ttl_hidden_index.js index b64f4822638..7ef7ecef991 100644 --- a/jstests/noPassthrough/ttl_hidden_index.js +++ b/jstests/noPassthrough/ttl_hidden_index.js @@ -1,6 +1,8 @@ // Make sure the TTL index still work after we hide it (function() { "use strict"; +load("jstests/libs/ttl_util.js"); + let runner = MongoRunner.runMongod({setParameter: "ttlMonitorSleepSecs=1"}); let coll = runner.getDB("test").ttl_hiddenl_index; coll.drop(); @@ -18,10 +20,7 @@ assert.commandWorked(coll.insert({x: now})); // Wait for the TTL monitor to run at least twice (in case we weren't finished setting up our // collection when it ran the first time). -var ttlPass = coll.getDB().serverStatus().metrics.ttl.passes; -assert.soon(function() { - return coll.getDB().serverStatus().metrics.ttl.passes >= ttlPass + 2; -}, "TTL monitor didn't run before timing out."); +TTLUtil.waitForPass(coll.getDB()); assert.eq(coll.count(), 0, "We should get 0 documents after TTL monitor run"); diff --git a/jstests/noPassthrough/ttl_monitor_does_not_unregister_index_during_collection_creation.js b/jstests/noPassthrough/ttl_monitor_does_not_unregister_index_during_collection_creation.js index 9758aec62b3..45478301ac6 100644 --- a/jstests/noPassthrough/ttl_monitor_does_not_unregister_index_during_collection_creation.js +++ b/jstests/noPassthrough/ttl_monitor_does_not_unregister_index_during_collection_creation.js @@ -7,6 +7,7 @@ */ (function() { 'use strict'; +load("jstests/libs/ttl_util.js"); const conn = MongoRunner.runMongod({setParameter: 'ttlMonitorSleepSecs=1'}); @@ -36,10 +37,7 @@ checkLog.containsJson(db.getMongo(), 4664000); // Let the TTL monitor run once. It should not remove the index from the cached TTL information // until the collection is committed. -let ttlPass = assert.commandWorked(db.serverStatus()).metrics.ttl.passes; -assert.soon(function() { - return coll.getDB().serverStatus().metrics.ttl.passes >= ttlPass + 2; -}, "TTL monitor didn't run."); +TTLUtil.waitForPass(coll.getDB()); // Finish the index build. assert.commandWorked(db.adminCommand({configureFailPoint: failPoint, mode: "off"})); @@ -52,10 +50,7 @@ for (let i = 0; i < 10; i++) { } // Let the TTL monitor run once to remove the expired documents. -ttlPass = assert.commandWorked(db.serverStatus()).metrics.ttl.passes; -assert.soon(function() { - return coll.getDB().serverStatus().metrics.ttl.passes >= ttlPass + 2; -}, "TTL monitor didn't run."); +TTLUtil.waitForPass(coll.getDB()); assert.eq(0, coll.find({}).count()); diff --git a/jstests/noPassthrough/ttl_operation_metrics.js b/jstests/noPassthrough/ttl_operation_metrics.js index 0d24af78932..5509c3151b8 100644 --- a/jstests/noPassthrough/ttl_operation_metrics.js +++ b/jstests/noPassthrough/ttl_operation_metrics.js @@ -11,6 +11,7 @@ load('jstests/noPassthrough/libs/index_build.js'); // For IndexBuildTest load("jstests/libs/fail_point_util.js"); +load("jstests/libs/ttl_util.js"); var rst = new ReplSetTest({ nodes: 2, @@ -58,15 +59,6 @@ const assertMetrics = (conn, assertFn) => { } }; -const waitForTtlPass = (db) => { - // Wait for the TTL monitor to run at least twice (in case we weren't finished setting up our - // collection when it ran the first time). - let ttlPass = db.serverStatus().metrics.ttl.passes; - assert.soon(function() { - return db.serverStatus().metrics.ttl.passes >= ttlPass + 2; - }, "TTL monitor didn't run before timing out."); -}; - // Create a TTL index and pause the thread. assert.commandWorked(primaryDB[collName].createIndex({x: 1}, {expireAfterSeconds: 0})); @@ -93,7 +85,7 @@ assertMetrics(primary, (metrics) => { // Clear metrics and wait for a TTL pass to delete the documents. clearMetrics(primary); pauseTtl.off(); -waitForTtlPass(primaryDB); +TTLUtil.waitForPass(primaryDB); // Ensure that the TTL monitor deleted 2 documents on the primary and recorded read and write // metrics. diff --git a/jstests/noPassthrough/ttl_partial_index.js b/jstests/noPassthrough/ttl_partial_index.js index 977eb4aef4c..00125a9bb91 100644 --- a/jstests/noPassthrough/ttl_partial_index.js +++ b/jstests/noPassthrough/ttl_partial_index.js @@ -2,6 +2,8 @@ // SERVER-17984. (function() { "use strict"; +load("jstests/libs/ttl_util.js"); + // Launch mongod with shorter TTL monitor sleep interval. var runner = MongoRunner.runMongod({setParameter: "ttlMonitorSleepSecs=1"}); var coll = runner.getDB("test").ttl_partial_index; @@ -17,10 +19,7 @@ assert.commandWorked(coll.insert({x: now})); // Wait for the TTL monitor to run at least twice (in case we weren't finished setting up our // collection when it ran the first time). -var ttlPass = coll.getDB().serverStatus().metrics.ttl.passes; -assert.soon(function() { - return coll.getDB().serverStatus().metrics.ttl.passes >= ttlPass + 2; -}, "TTL monitor didn't run before timing out."); +TTLUtil.waitForPass(coll.getDB()); assert.eq(0, coll.find({z: {$exists: true}}).hint({x: 1}).itcount(), diff --git a/jstests/noPassthrough/ttl_resharding_collection.js b/jstests/noPassthrough/ttl_resharding_collection.js index 648d1a9b056..cafa433fa5f 100644 --- a/jstests/noPassthrough/ttl_resharding_collection.js +++ b/jstests/noPassthrough/ttl_resharding_collection.js @@ -1,6 +1,8 @@ // Tests that the TTL Monitor is disabled for <database>.system.resharding.* namespaces. (function() { "use strict"; +load("jstests/libs/ttl_util.js"); + // Launch mongod with shorter TTL monitor sleep interval. const runner = MongoRunner.runMongod({setParameter: "ttlMonitorSleepSecs=1"}); const collName = "system.resharding.mycoll"; @@ -14,10 +16,7 @@ assert.commandWorked(coll.insert({x: now})); // Wait for the TTL monitor to run at least twice (in case we weren't finished setting up our // collection when it ran the first time). -const ttlPass = coll.getDB().serverStatus().metrics.ttl.passes; -assert.soon(function() { - return coll.getDB().serverStatus().metrics.ttl.passes >= ttlPass + 2; -}, "TTL monitor didn't run before timing out."); +TTLUtil.waitForPass(coll.getDB()); // Confirm the document was not removed because it was in a <database>.system.resharding.* // namespace. diff --git a/jstests/noPassthrough/ttl_with_dropIndex.js b/jstests/noPassthrough/ttl_with_dropIndex.js index 0461862088f..6bed0fa6b91 100644 --- a/jstests/noPassthrough/ttl_with_dropIndex.js +++ b/jstests/noPassthrough/ttl_with_dropIndex.js @@ -3,6 +3,7 @@ */ (function() { 'use strict'; +load("jstests/libs/ttl_util.js"); let conn = MongoRunner.runMongod({setParameter: 'ttlMonitorSleepSecs=1'}); let db = conn.getDB('test'); @@ -33,10 +34,7 @@ for (let i = 0; i < 50; i++) { assert.commandWorked(db.runCommand({insert: 'ttl_coll', documents: [{x: past}]})); } -var ttlPasses = db.serverStatus().metrics.ttl.passes; -assert.soon(function() { - return db.serverStatus().metrics.ttl.passes > ttlPasses; -}); +TTLUtil.waitForPass(db); assert.eq(coll.find().itcount(), 50); |