summaryrefslogtreecommitdiff
path: root/jstests/core/ddl/collmod_convert_to_unique_violations.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/core/ddl/collmod_convert_to_unique_violations.js')
-rw-r--r--jstests/core/ddl/collmod_convert_to_unique_violations.js101
1 files changed, 101 insertions, 0 deletions
diff --git a/jstests/core/ddl/collmod_convert_to_unique_violations.js b/jstests/core/ddl/collmod_convert_to_unique_violations.js
new file mode 100644
index 00000000000..53b8abeec6e
--- /dev/null
+++ b/jstests/core/ddl/collmod_convert_to_unique_violations.js
@@ -0,0 +1,101 @@
+/**
+ * Tests that the CannotConvertIndexToUnique 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-61182): Fix WiredTigerKVEngine::alterIdentMetadata() under inMemory.
+ * requires_persistence,
+ * # The 'prepareUnique' field may cause the migration to fail.
+ * tenant_migration_incompatible,
+ * ]
+ */
+
+(function() {
+'use strict';
+
+load("jstests/libs/feature_flag_util.js");
+load("jstests/libs/fixture_helpers.js"); // For 'isMongos'
+
+if (!FeatureFlagUtil.isEnabled(db, "CollModIndexUnique")) {
+ 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;
+ });
+}
+
+const collName = 'collmod_convert_to_unique_violations';
+const coll = db.getCollection(collName);
+coll.drop();
+
+// Checks that the violations match what we expect.
+function assertFailedWithViolations(keyPattern, violations) {
+ // First sets 'prepareUnique' before converting the index to unique.
+ assert.commandWorked(
+ db.runCommand({collMod: collName, index: {keyPattern: keyPattern, prepareUnique: true}}));
+ const result =
+ db.runCommand({collMod: collName, index: {keyPattern: keyPattern, unique: true}});
+ assert.commandFailedWithCode(result, ErrorCodes.CannotConvertIndexToUnique);
+ assert.eq(
+ bsonWoCompare(sortViolationsArray(result.violations), sortViolationsArray(violations)),
+ 0,
+ tojson(result));
+ // Resets 'prepareUnique'.
+ assert.commandWorked(
+ db.runCommand({collMod: collName, index: {keyPattern: keyPattern, prepareUnique: false}}));
+}
+
+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({a: 1}, [{ids: [1, 2]}]);
+
+assert.commandWorked(coll.insert({_id: 3, a: 100, b: 3}));
+assertFailedWithViolations({a: 1}, [{ids: [1, 2, 3]}]);
+
+assert.commandWorked(coll.insert({_id: 4, a: 101, b: 4}));
+assertFailedWithViolations({a: 1}, [{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({a: 1}, [{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({a: 1, b: 1}, [{ids: [6, 7]}]);
+
+assert.commandWorked(coll.insert({_id: 8, a: 105, b: 6}));
+assertFailedWithViolations({a: 1, b: 1}, [{ids: [6, 7, 8]}]);
+
+assert.commandWorked(coll.insert({_id: 9, a: 101, b: 4}));
+assertFailedWithViolations({a: 1, b: 1}, [{ids: [4, 9]}, {ids: [6, 7, 8]}]);
+
+assert.commandWorked(coll.insert({_id: "10", a: 101, b: 4}));
+assertFailedWithViolations({a: 1, b: 1}, [{ids: [4, 9, "10"]}, {ids: [6, 7, 8]}]);
+})();