summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/bson_max_limit.js
blob: 99214338665696b517564cb695ebb1f8e2911965 (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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
 * Tests that the server accepts writes that push a bson object to the documented maximum size
 * limit.
 *
 * @tags: [
 *   requires_replication,
 * ]
 */
(function() {
"use strict";

load("jstests/libs/fixture_helpers.js");  // For isReplSet().

function retryableFindAndModify(database, collection, query, update, newImage, upsert, remove) {
    let cmd = {
        findAndModify: collection,
        query: query,
        lsid: {id: UUID()},
        txnNumber: NumberLong(1),
    };
    if (update) {
        cmd["update"] = update;
    }
    if (newImage) {
        cmd["new"] = newImage;
    }
    if (upsert) {
        cmd["upsert"] = upsert;
    }
    if (remove) {
        cmd["remove"] = remove;
    }

    assert.commandWorked(database.runCommand(cmd));
}

function executeTest(db) {
    const MaxBsonSize = db.hello().maxBsonObjectSize;
    let doc = {"_id": 1, "a": ""};
    let leftoverSpace = MaxBsonSize - Object.bsonsize(doc);
    let bigStr = "a".repeat(leftoverSpace);
    doc["a"] = bigStr;
    jsTestLog({"Max bson size": MaxBsonSize, "Doc Size": Object.bsonsize(doc)});
    assert.eq(Object.bsonsize(doc), MaxBsonSize);

    db["coll"].drop();

    // Assert inserting at the MaxBsonSize works.
    assert.commandWorked(db["coll"].insert(doc));
    // Assert a size increasing update up to the MaxBsonSize works.
    assert.commandWorked(db["coll"].update({_id: 1}, {$unset: {a: 1}}));
    assert.commandWorked(db["coll"].update({_id: 1}, {$set: {a: bigStr}}));
    // Assert replacing a MaxBsonSize object with another MaxBsonSize object works.
    assert.commandWorked(db["coll"].update({_id: 1}, {$set: {a: bigStr}}));

    // Reset
    assert.commandWorked(db["coll"].remove({}));
    // Assert inserting at the MaxBsonSize works.
    assert.commandWorked(db["coll"].insert(doc));
    // Assert a size increasing update up to the MaxBsonSize works.
    assert.commandWorked(db["coll"].update({_id: 1}, {$unset: {a: 1}}));
    assert.commandWorked(db["coll"].update({_id: 1}, {$set: {a: bigStr}}));
    // Assert replacing a MaxBsonSize object with another MaxBsonSize object works.
    assert.commandWorked(db["coll"].update({_id: 1}, {$set: {a: bigStr}}));

    if (!FixtureHelpers.isReplSet(db)) {
        return;
    }

    // Reset. Test retryable findAndModify's.
    let sessionDb = db.getMongo().startSession({}).getDatabase("test");
    retryableFindAndModify(db, "coll", {_id: 1}, false, false, false, /*remove=*/true);
    retryableFindAndModify(db, "coll", {_id: 1}, doc, false, /*upsert=*/true, false);
    retryableFindAndModify(db, "coll", {_id: 1}, {$unset: {a: 1}}, false, false, false);
    retryableFindAndModify(
        db, "coll", {_id: 1}, {$set: {a: bigStr}}, /*new(Image)=*/true, false, false);
}

{
    // Run against a standalone
    const conn = MongoRunner.runMongod();
    assert.neq(null, conn, "mongod was unable to start up");
    executeTest(conn.getDB("test"));
    MongoRunner.stopMongod(conn);
}

{
    const rst = new ReplSetTest({
        nodes: [
            {},
            {
                // Disallow elections on secondary.
                rsConfig: {
                    priority: 0,
                    votes: 0,
                },
            }
        ]
    });
    rst.startSet();
    rst.initiate();
    // Test the modern default behavior where storeFindAndModifyImagesInSideCollection is true.
    rst.getPrimary().adminCommand(
        {setParameter: 1, storeFindAndModifyImagesInSideCollection: true});
    executeTest(rst.getPrimary().getDB("test"));

    // Test the legacy behavior where storeFindAndModifyImagesInSideCollection is false.
    rst.getPrimary().adminCommand(
        {setParameter: 1, storeFindAndModifyImagesInSideCollection: false});
    executeTest(rst.getPrimary().getDB("test"));
    rst.stopSet();
}
})();