diff options
Diffstat (limited to 'jstests/core/ddl/collmod_convert_to_unique_apply_ops.js')
-rw-r--r-- | jstests/core/ddl/collmod_convert_to_unique_apply_ops.js | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/jstests/core/ddl/collmod_convert_to_unique_apply_ops.js b/jstests/core/ddl/collmod_convert_to_unique_apply_ops.js new file mode 100644 index 00000000000..65838299994 --- /dev/null +++ b/jstests/core/ddl/collmod_convert_to_unique_apply_ops.js @@ -0,0 +1,101 @@ +/** + * Basic js tests for applying the collMod command converting regular indexes to unique indexes. + * + * The test runs commands that are not allowed with security token: applyOps. + * @tags: [ + * not_allowed_with_security_token, + * # applyOps is not supported on mongos + * assumes_against_mongod_not_mongos, + * # 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. + * # applyOps uses the oplog that require replication support + * requires_replication, + * # 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"); + +if (!FeatureFlagUtil.isEnabled(db, "CollModIndexUnique")) { + jsTestLog('Skipping test because the collMod unique index feature flag is disabled.'); + return; +} + +const collName = 'collmod_convert_to_unique_apply_ops'; +const coll = db.getCollection(collName); +coll.drop(); +assert.commandWorked(db.createCollection(collName)); + +function countUnique(key) { + const all = coll.getIndexes().filter(function(z) { + return z.unique && friendlyEqual(z.key, key); + }); + return all.length; +} + +// Creates a regular index and use collMod to convert it to a unique index. +assert.commandWorked(coll.createIndex({a: 1})); + +// applyOps version of the following collMod command to convert index to unique: +// {collMod: collName, index: {keyPattern: {a: 1}, unique: true}} +const applyOpsCmd = { + applyOps: [ + { + op: 'c', + ns: db.$cmd.getFullName(), + o: { + collMod: coll.getName(), + index: { + keyPattern: {a: 1}, + unique: true, + }, + }, + }, + ] +}; + +// Conversion should fail when there are existing duplicates. +assert.commandWorked(coll.insert({_id: 1, a: 100})); +assert.commandWorked(coll.insert({_id: 2, a: 100})); +// First sets 'prepareUnique' before converting the index to unique. +assert.commandWorked( + db.runCommand({collMod: collName, index: {keyPattern: {a: 1}, prepareUnique: true}})); +const cannotConvertIndexToUniqueError = assert.commandFailedWithCode( + db.adminCommand(applyOpsCmd), ErrorCodes.CannotConvertIndexToUnique); +jsTestLog('Cannot enable index constraint error from failed conversion: ' + + tojson(cannotConvertIndexToUniqueError)); +assert.eq(1, cannotConvertIndexToUniqueError.applied, tojson(cannotConvertIndexToUniqueError)); +assert.commandWorked(coll.remove({_id: 2})); + +// Dry run mode is not supported for running collMod through applyOps. +// There should not be existing oplog entries with dryRun=true to route +// through applyOps. +const dryRunCmd = Object.extend({}, applyOpsCmd, true /* deep */); +dryRunCmd.applyOps[0].o.dryRun = true; +jsTestLog('Running collMod in dry run mode through applyOps: ' + tojson(dryRunCmd)); +const dryRunError = + assert.commandFailedWithCode(db.adminCommand(dryRunCmd), ErrorCodes.InvalidOptions); +jsTestLog('Rejected dry run mode result: ' + tojson(dryRunError)); + +// Successfully converts to a unique index. +const result = assert.commandWorked(db.adminCommand(applyOpsCmd)); + +// Check applyOps result. +assert.eq(1, result.applied, tojson(result)); +assert.sameMembers([true], result.results, tojson(result)); + +// Look up index details in listIndexes output. +assert.eq(countUnique({a: 1}), 1, 'index should be unique now: ' + tojson(coll.getIndexes())); + +// Test uniqueness constraint. +assert.commandFailedWithCode(coll.insert({_id: 100, a: 100}), ErrorCodes.DuplicateKey); +})(); |