summaryrefslogtreecommitdiff
path: root/jstests/sharding/mongos_validate_writes.js
blob: d9114a6033f6df457a7b216a6e530b370139f77e (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
//
// Tests that mongos validating writes when stale does not DOS config servers
//
// Note that this is *unsafe* with broadcast removes and updates
//
(function() {
    'use strict';

    var st = new ShardingTest({shards: 2, mongos: 3, other: {shardOptions: {verbose: 2}}});

    var mongos = st.s0;
    var staleMongosA = st.s1;
    var staleMongosB = st.s2;

    var admin = mongos.getDB("admin");
    var config = mongos.getDB("config");
    var coll = mongos.getCollection("foo.bar");
    var staleCollA = staleMongosA.getCollection(coll + "");
    var staleCollB = staleMongosB.getCollection(coll + "");

    assert.commandWorked(admin.runCommand({enableSharding: coll.getDB() + ""}));
    st.ensurePrimaryShard(coll.getDB().getName(), st.shard1.shardName);
    coll.ensureIndex({a: 1});

    // Shard the collection on {a: 1} and move one chunk to another shard. Updates need to be across
    // two shards to trigger an error, otherwise they are versioned and will succeed after raising
    // a StaleConfigException.
    st.shardColl(coll, {a: 1}, {a: 0}, {a: 1}, coll.getDB(), true);

    // Let the stale mongos see the collection state
    staleCollA.findOne();
    staleCollB.findOne();

    // Change the collection sharding state
    coll.drop();
    coll.ensureIndex({b: 1});
    st.shardColl(coll, {b: 1}, {b: 0}, {b: 1}, coll.getDB(), true);

    // Make sure that we can successfully insert, even though we have stale state
    assert.writeOK(staleCollA.insert({b: "b"}));

    // Make sure we unsuccessfully insert with old info
    assert.writeError(staleCollB.insert({a: "a"}));

    // Change the collection sharding state
    coll.drop();
    coll.ensureIndex({c: 1});
    st.shardColl(coll, {c: 1}, {c: 0}, {c: 1}, coll.getDB(), true);

    // Make sure we can successfully upsert, even though we have stale state
    assert.writeOK(staleCollA.update({c: "c"}, {c: "c"}, true));

    // Make sure we unsuccessfully upsert with old info
    assert.writeError(staleCollB.update({b: "b"}, {b: "b"}, true));

    // Change the collection sharding state
    coll.drop();
    coll.ensureIndex({d: 1});
    st.shardColl(coll, {d: 1}, {d: 0}, {d: 1}, coll.getDB(), true);

    // Make sure we can successfully update, even though we have stale state
    assert.writeOK(coll.insert({d: "d"}));

    assert.writeOK(staleCollA.update({d: "d"}, {$set: {x: "x"}}, false, false));
    assert.eq(staleCollA.findOne().x, "x");

    // Make sure we unsuccessfully update with old info
    assert.writeError(staleCollB.update({c: "c"}, {$set: {x: "y"}}, false, false));
    assert.eq(staleCollB.findOne().x, "x");

    // Change the collection sharding state
    coll.drop();
    coll.ensureIndex({e: 1});
    // Deletes need to be across two shards to trigger an error.
    st.ensurePrimaryShard(coll.getDB().getName(), st.shard0.shardName);
    st.shardColl(coll, {e: 1}, {e: 0}, {e: 1}, coll.getDB(), true);

    // Make sure we can successfully remove, even though we have stale state
    assert.writeOK(coll.insert({e: "e"}));

    assert.writeOK(staleCollA.remove({e: "e"}, true));
    assert.eq(null, staleCollA.findOne());

    // Make sure we unsuccessfully remove with old info
    assert.writeError(staleCollB.remove({d: "d"}, true));

    st.stop();
})();