summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/collmod_convert_to_unique_sharded.js
blob: 5f486497b755b6dece22a88fd2c3cee3054e25cf (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
/**
 * Tests collMod unique conversion ensures consistent index specs across all shards.
 *
 * @tags: [
 *   # TODO(SERVER-61182): Fix WiredTigerKVEngine::alterIdentMetadata() under inMemory.
 *   requires_persistence,
 *   requires_sharding,
 * ]
 */
(function() {
'use strict';

function countUniqueIndexes(coll, key) {
    const all = coll.getIndexes().filter(function(z) {
        return z.unique && friendlyEqual(z.key, key);
    });
    return all.length;
}

function countPrepareUniqueIndexes(coll, key) {
    const all = coll.getIndexes().filter(function(z) {
        return z.prepareUnique && friendlyEqual(z.key, key);
    });
    return all.length;
}

const st = new ShardingTest({shards: 2});
const mongos = st.s;

const db = mongos.getDB(jsTestName());
assert.commandWorked(
    mongos.adminCommand({enableSharding: db.getName(), primaryShard: st.shard0.name}));

const shardedColl = db.sharded;

assert.commandWorked(
    mongos.adminCommand({shardCollection: shardedColl.getFullName(), key: {a: 1}}));

// Move {a: 1} to shard0 and {a: 2} to shard1.
assert.commandWorked(st.splitAt(shardedColl.getFullName(), {a: 2}));
assert.commandWorked(mongos.adminCommand(
    {moveChunk: shardedColl.getFullName(), find: {a: 1}, to: st.shard0.shardName}));
assert.commandWorked(mongos.adminCommand(
    {moveChunk: shardedColl.getFullName(), find: {a: 2}, to: st.shard1.shardName}));

assert.commandWorked(shardedColl.createIndex({a: 1}));

assert.commandWorked(shardedColl.insert({_id: 0, a: 1}));
assert.commandWorked(shardedColl.insert({_id: 1, a: 2}));
assert.commandWorked(shardedColl.insert({_id: 2, a: 2}));

// Setting the indexes to 'prepareUnique' ensures no new duplicates will be inserted.
assert.commandWorked(db.runCommand(
    {collMod: shardedColl.getName(), index: {keyPattern: {a: 1}, prepareUnique: true}}));
assert.commandFailedWithCode(shardedColl.insert({_id: 3, a: 1}), ErrorCodes.DuplicateKey);
assert.commandFailedWithCode(shardedColl.insert({_id: 4, a: 2}), ErrorCodes.DuplicateKey);

// Try converting the index to unique and make sure no indexes are converted on any shards.
assert.commandFailedWithCode(
    db.runCommand({collMod: shardedColl.getName(), index: {keyPattern: {a: 1}, unique: true}}),
    ErrorCodes.CannotConvertIndexToUnique);

const s0Coll = st.shard0.getDB(jsTestName()).getCollection("sharded");
const s1Coll = st.shard1.getDB(jsTestName()).getCollection("sharded");
assert.eq(countUniqueIndexes(s0Coll, {a: 1}),
          0,
          'index should not be unique: ' + tojson(s0Coll.getIndexes()));
assert.eq(countUniqueIndexes(s1Coll, {a: 1}),
          0,
          'index should not be unique: ' + tojson(s1Coll.getIndexes()));
assert.eq(countPrepareUniqueIndexes(s0Coll, {a: 1}),
          1,
          'index should be prepareUnique: ' + tojson(s0Coll.getIndexes()));
assert.eq(countPrepareUniqueIndexes(s1Coll, {a: 1}),
          1,
          'index should be prepareUnique: ' + tojson(s1Coll.getIndexes()));

// Remove the duplicate and confirm the indexes are converted.
assert.commandWorked(shardedColl.deleteOne({_id: 2}));
assert.commandWorked(
    db.runCommand({collMod: shardedColl.getName(), index: {keyPattern: {a: 1}, unique: true}}));
assert.eq(countUniqueIndexes(s0Coll, {a: 1}),
          1,
          'index should be unique: ' + tojson(s0Coll.getIndexes()));
assert.eq(countUniqueIndexes(s1Coll, {a: 1}),
          1,
          'index should be unique: ' + tojson(s1Coll.getIndexes()));

st.stop();
})();