summaryrefslogtreecommitdiff
path: root/jstests/core/collmod_convert_to_unique_violations.js
blob: d9e2de0abb9b423b79e40525a65810ec44f09719 (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
/**
 * Tests that the CannotEnableIndexConstraint error returned when collmod fails to convert an index
 * to unique contains correct information about violations found.
 *
 * @tags: [
 *  # Cannot implicitly shard accessed collections because of collection existing when none
 *  # expected.
 *  assumes_no_implicit_collection_creation_after_drop,  # common tag in collMod tests.
 *  requires_fcv_52,
 *  requires_non_retryable_commands, # common tag in collMod tests.
 *  # TODO(SERVER-61181): Fix validation errors under ephemeralForTest.
 *  incompatible_with_eft,
 *  # TODO(SERVER-61182): Fix WiredTigerKVEngine::alterIdentMetadata() under inMemory.
 *  requires_persistence,
 * ]
 */

(function() {
'use strict';

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

const collModIndexUniqueEnabled = assert
                                      .commandWorked(db.getMongo().adminCommand(
                                          {getParameter: 1, featureFlagCollModIndexUnique: 1}))
                                      .featureFlagCollModIndexUnique.value;

if (!collModIndexUniqueEnabled) {
    jsTestLog('Skipping test because the collMod unique index feature flag is disabled.');
    return;
}

function sortViolationsArray(arr) {
    // Sorting unsorted arrays of unsorted arrays -- Sort subarrays, then sort main array by first
    // key of subarray.
    for (let i = 0; i < arr.length; i++) {
        arr[i].ids = arr[i].ids.sort();
    }
    return arr.sort(function(a, b) {
        if (a.ids[0] < b.ids[0]) {
            return -1;
        }
        if (a.ids[0] > b.ids[0]) {
            return 1;
        }
        return 0;
    });
}

// Checks that the violations match what we expect.
function assertFailedWithViolations(result, violations) {
    assert.commandFailedWithCode(result, ErrorCodes.CannotEnableIndexConstraint);
    assert.eq(
        bsonWoCompare(sortViolationsArray(result.violations), sortViolationsArray(violations)),
        0,
        tojson(result));
}

const collName = 'collmod_convert_to_unique_violations';
const coll = db.getCollection(collName);
coll.drop();
assert.commandWorked(db.createCollection(collName));

// Create regular indexes and try to use collMod to convert them to unique indexes.
assert.commandWorked(coll.createIndex({a: 1}));
assert.commandWorked(coll.createIndex({a: 1, b: 1}));

// Conversion should fail when there are existing duplicates, reporting correct number of
// violations.
assert.commandWorked(coll.insert({_id: 1, a: 100, b: 1}));
assert.commandWorked(coll.insert({_id: 2, a: 100, b: 2}));
assertFailedWithViolations(
    db.runCommand({collMod: collName, index: {keyPattern: {a: 1}, unique: true}}), [{ids: [1, 2]}]);

assert.commandWorked(coll.insert({_id: 3, a: 100, b: 3}));
assertFailedWithViolations(
    db.runCommand({collMod: collName, index: {keyPattern: {a: 1}, unique: true}}),
    [{ids: [1, 2, 3]}]);

assert.commandWorked(coll.insert({_id: 4, a: 101, b: 4}));
assertFailedWithViolations(
    db.runCommand({collMod: collName, index: {keyPattern: {a: 1}, unique: true}}),
    [{ids: [1, 2, 3]}]);

assert.commandWorked(coll.insert({_id: 5, a: 105, b: 5}));
assert.commandWorked(coll.insert({_id: 6, a: 105, b: 6}));
assertFailedWithViolations(
    db.runCommand({collMod: collName, index: {keyPattern: {a: 1}, unique: true}}),
    [{ids: [1, 2, 3]}, {ids: [5, 6]}]);

// Test that compound indexes work as expected.
assert.commandWorked(coll.insert({_id: 7, a: 105, b: 6}));
assertFailedWithViolations(
    db.runCommand({collMod: collName, index: {keyPattern: {a: 1, b: 1}, unique: true}}),
    [{ids: [6, 7]}]);

assert.commandWorked(coll.insert({_id: 8, a: 105, b: 6}));
assertFailedWithViolations(
    db.runCommand({collMod: collName, index: {keyPattern: {a: 1, b: 1}, unique: true}}),
    [{ids: [6, 7, 8]}]);

assert.commandWorked(coll.insert({_id: 9, a: 101, b: 4}));
assertFailedWithViolations(
    db.runCommand({collMod: collName, index: {keyPattern: {a: 1, b: 1}, unique: true}}),
    [{ids: [4, 9]}, {ids: [6, 7, 8]}]);

assert.commandWorked(coll.insert({_id: "10", a: 101, b: 4}));
assertFailedWithViolations(
    db.runCommand({collMod: collName, index: {keyPattern: {a: 1, b: 1}, unique: true}}),
    [{ids: [4, 9, "10"]}, {ids: [6, 7, 8]}]);
})();