jstests/libs/clustered_collections/clustered_capped_utils.js
// Validate tailable cursor operation along with TTL deletion.
Validate tailable cursor operation along with TTL deletion.
Validate tailable cursor operation along with TTL deletion .
static testClusteredTailableCursorWithTTL(db, collName, clusterKey, isReplicated, awaitData) {
        jsTest.log(
            "Validating tailable cursor operation on capped clustered collection (isReplicated: " +
            isReplicated + ", awaitData: " + awaitData + ")");
        assert.commandWorked(db.adminCommand({setParameter: 1, ttlMonitorEnabled: false}));
        const oneDayInSeconds = 60 * 60 * 24;
        const oneHourInMilliseconds = 60 * 60 * 1000;
        const nineDaysInMilliseconds = 9 * oneDayInSeconds * 1000;
        const tenDaysInMilliseconds = 10 * oneDayInSeconds * 1000;
        const now = new Date();
        const oneHourAgo = new Date(now - oneHourInMilliseconds);
        const nineDaysAgo = new Date(now - nineDaysInMilliseconds);
        const tenDaysAgo = new Date(now - tenDaysInMilliseconds);
        assert.commandWorked(db.createCollection(collName, {
            clusteredIndex: {key: {[clusterKey]: 1}, unique: true},
            capped: true,
            expireAfterSeconds: oneDayInSeconds
        }));
        assert.commandWorked(
            db.getCollection(collName).insertOne({[clusterKey]: tenDaysAgo, info: "10 days ago"}));
        assert.commandWorked(
            db.getCollection(collName).insertOne({[clusterKey]: nineDaysAgo, info: "9 days ago"}));
        assert.commandWorked(db.getCollection(collName).insertOne(
            {[clusterKey]: oneHourAgo, info: "1 hour ago - surviving"}));
        assert.commandWorked(
            db.getCollection(collName).insertOne({[clusterKey]: now, info: "now - surviving"}));
        let tailCommand = {find: collName, batchSize: 1, tailable: true, awaitData: awaitData};
        if (isReplicated) {
            tailCommand['readConcern'] = {level: "majority"};
        } else {
            tailCommand['readConcern'] = {level: "local"};
        }
        const tailable = db.runCommand(tailCommand);
        assert.commandWorked(tailable);
        const cursorId = tailable.cursor.id;
        assert(!bsonBinaryEqual({cursorId: cursorId}, {cursorId: NumberLong(0)}));
        assert.eq("10 days ago", tailable.cursor.firstBatch[0].info);
        {
            let getMore = db.runCommand({getMore: cursorId, collection: collName, batchSize: 1});
            assert.commandWorked(getMore);
            assert.eq("9 days ago", getMore.cursor.nextBatch[0].info);
        }
        {
            let getMore = db.runCommand({getMore: cursorId, collection: collName, batchSize: 1});
            assert.commandWorked(getMore);
            assert.eq("1 hour ago - surviving", getMore.cursor.nextBatch[0].info);
        }
        assert.eq(4, db.getCollection(collName).find().itcount());
        assert.commandWorked(db.adminCommand({setParameter: 1, ttlMonitorEnabled: true}));
        ClusteredCollectionUtil.waitForTTL(db);
        assert.eq(2, db.getCollection(collName).find().itcount());
        {
            let getMore = db.runCommand({getMore: cursorId, collection: collName, batchSize: 1});
            assert.commandWorked(getMore);
            assert.eq("now - surviving", getMore.cursor.nextBatch[0].info);
        }
        {
            let getMore = db.runCommand({getMore: cursorId, collection: collName});
            assert.commandWorked(getMore);
            assert.eq(0, getMore.cursor.nextBatch.length);
        }
        db.getCollection(collName).drop();
    }
static testClusteredTailableCursorWithTTL ( db , collName , clusterKey , isReplicated , awaitData ) { jsTest . log ( "Validating tailable cursor operation on capped clustered collection (isReplicated: " + isReplicated + ", awaitData: " + awaitData + ")" ) ; assert . commandWorked ( db . adminCommand ( { setParameter : 1 , ttlMonitorEnabled : false } ) ) ; const oneDayInSeconds = 60 * 60 * 24 ; const oneHourInMilliseconds = 60 * 60 * 1000 ; const nineDaysInMilliseconds = 9 * oneDayInSeconds * 1000 ; const tenDaysInMilliseconds = 10 * oneDayInSeconds * 1000 ; const now = new Date ( ) ; const oneHourAgo = new Date ( now - oneHourInMilliseconds ) ; const nineDaysAgo = new Date ( now - nineDaysInMilliseconds ) ; const tenDaysAgo = new Date ( now - tenDaysInMilliseconds ) ; assert . commandWorked ( db . createCollection ( collName , { clusteredIndex : { key : { [ clusterKey ] : 1 } , unique : true } , capped : true , expireAfterSeconds : oneDayInSeconds } ) ) ; assert . commandWorked ( db . getCollection ( collName ) . insertOne ( { [ clusterKey ] : tenDaysAgo , info : "10 days ago" } ) ) ; assert . commandWorked ( db . getCollection ( collName ) . insertOne ( { [ clusterKey ] : nineDaysAgo , info : "9 days ago" } ) ) ; assert . commandWorked ( db . getCollection ( collName ) . insertOne ( { [ clusterKey ] : oneHourAgo , info : "1 hour ago - surviving" } ) ) ; assert . commandWorked ( db . getCollection ( collName ) . insertOne ( { [ clusterKey ] : now , info : "now - surviving" } ) ) ; let tailCommand = { find : collName , batchSize : 1 , tailable : true , awaitData : awaitData } ; if ( isReplicated ) { tailCommand [ 'readConcern' ] = { level : "majority" } ; } else { tailCommand [ 'readConcern' ] = { level : "local" } ; } const tailable = db . runCommand ( tailCommand ) ; assert . commandWorked ( tailable ) ; const cursorId = tailable . cursor . id ; assert ( ! bsonBinaryEqual ( { cursorId : cursorId } , { cursorId : NumberLong ( 0 ) } ) ) ; assert . eq ( "10 days ago" , tailable . cursor . firstBatch [ 0 ] . info ) ; { let getMore = db . runCommand ( { getMore : cursorId , collection : collName , batchSize : 1 } ) ; assert . commandWorked ( getMore ) ; assert . eq ( "9 days ago" , getMore . cursor . nextBatch [ 0 ] . info ) ; } { let getMore = db . runCommand ( { getMore : cursorId , collection : collName , batchSize : 1 } ) ; assert . commandWorked ( getMore ) ; assert . eq ( "1 hour ago - surviving" , getMore . cursor . nextBatch [ 0 ] . info ) ; } assert . eq ( 4 , db . getCollection ( collName ) . find ( ) . itcount ( ) ) ; assert . commandWorked ( db . adminCommand ( { setParameter : 1 , ttlMonitorEnabled : true } ) ) ; ClusteredCollectionUtil . waitForTTL ( db ) ; assert . eq ( 2 , db . getCollection ( collName ) . find ( ) . itcount ( ) ) ; { let getMore = db . runCommand ( { getMore : cursorId , collection : collName , batchSize : 1 } ) ; assert . commandWorked ( getMore ) ; assert . eq ( "now - surviving" , getMore . cursor . nextBatch [ 0 ] . info ) ; } { let getMore = db . runCommand ( { getMore : cursorId , collection : collName } ) ; assert . commandWorked ( getMore ) ; assert . eq ( 0 , getMore . cursor . nextBatch . length ) ; } db . getCollection ( collName ) . drop ( ) ; }
Validate tailable cursor operation along with TTL deletion.
Validate tailable cursor operation along with TTL deletion .
// Create a clustered capped collection, and insert two old documents subject to imminent // TTL deletion, and two recent document which survive TTL deletion. // Tail just past the first two documents, so the cursor can survive the upcoming TTL // deletion. // TTL delete the two old documents. // Confirm that the tailable getMore can resume from where it was, since the document the // cursor is positioned on hasn't been TTL-removed.