summaryrefslogtreecommitdiff
path: root/jstests/replsets/mr_nonrepl_coll_in_local_db.js
blob: 8348b65e09a0d41d834c3defd050f2286e7e7484 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// All collections created during a map-reduce should be replicated to secondaries unless they are
// in the "local" or "admin" databases. Any collection outside of "local" that does not get
// replicated is a potential problem for workloads with transactions (see SERVER-35365 and
// SERVER-35282).
//
// We verify this requirement by running a map-reduce, examining the logs to find the names of
// all collections created, and checking the oplog for entries logging the creation of each of those
// collections.
(function() {
"use strict";

load("jstests/libs/check_log.js");

const name = "mr_nonrepl_coll_in_local_db";
const replSet = new ReplSetTest({name: name, nodes: 2});
replSet.startSet();
replSet.initiate();

const dbName = name;
const collName = "test";

const primary = replSet.getPrimary();
const primaryDB = primary.getDB(dbName);
const coll = primaryDB[collName];

// Insert 1000 documents in the "test" collection.
const bulk = coll.initializeUnorderedBulkOp();
for (let i = 0; i < 1000; i++) {
    const array = Array.from({lengthToInsert: 10000}, _ => Math.floor(Math.random() * 100));
    bulk.insert({arr: array});
}
assert.writeOK(bulk.execute());

// Run a simple map-reduce.
const result = coll.mapReduce(
    function map() {
        return this.arr.forEach(element => emit(element, 1));
    },
    function reduce(key, values) {
        return Array.sum(values);
    },
    {query: {arr: {$exists: true}}, out: "mr_result"});
assert.commandWorked(result);

// Examine the logs to find a list of created collections.
const logLines = checkLog.getGlobalLog(primaryDB);
let createdCollections = [];
logLines.forEach(function(line) {
    let matchResult = line.match(/createCollection: (.+) with/);
    if (matchResult) {
        createdCollections.push(matchResult[1]);
    }
});

createdCollections.forEach(function(createdCollectionName) {
    if (createdCollectionName.startsWith("admin.")) {
        // Although the "admin.system.version" collection is replicated, no "c" entry gets
        // created for it in the oplog, so this test would see it as unreplicated. In general,
        // this test is not concerned with the "admin" database, so we don't examine any "admin"
        // collections.
        return;
    }

    // Search for a log entry for the creation of this collection.
    const oplogEntries = primaryDB.getSiblingDB("local")["oplog.rs"]
                             .find({op: "c", "o.idIndex.ns": createdCollectionName})
                             .toArray();
    if (createdCollectionName.startsWith("local.")) {
        // We do not want to see any replication of "local" collections.
        assert.eq(oplogEntries.length,
                  0,
                  "Found unexpected oplog entry for creation of " + createdCollectionName + ": " +
                      tojson(oplogEntries));
    } else {
        assert.eq(oplogEntries.length,
                  1,
                  "Found no oplog entry or too many entries for creation of " +
                      createdCollectionName + ": " + tojson(oplogEntries));
    }
});

replSet.stopSet();
}());