summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/change_stream_options.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/noPassthrough/change_stream_options.js')
-rw-r--r--jstests/noPassthrough/change_stream_options.js183
1 files changed, 183 insertions, 0 deletions
diff --git a/jstests/noPassthrough/change_stream_options.js b/jstests/noPassthrough/change_stream_options.js
new file mode 100644
index 00000000000..abc518b9f69
--- /dev/null
+++ b/jstests/noPassthrough/change_stream_options.js
@@ -0,0 +1,183 @@
+// Tests setClusterParameter and getClusterParameter for changeStreamOptions on standalone, replica
+// set and sharded cluster configurations.
+// @tags: [
+// requires_fcv_60,
+// featureFlagClusterWideConfig,
+// ]
+(function() {
+"use strict";
+
+const testDBName = jsTestName();
+
+// Tests set and get change stream options command with 'admin' database.
+function testChangeStreamOptionsWithAdminDB(conn) {
+ const adminDB = conn.getDB("admin");
+
+ // A set command without any parameter options should fail.
+ assert.commandFailedWithCode(
+ adminDB.runCommand({setClusterParameter: {changeStreamOptions: {}}}), ErrorCodes.BadValue);
+
+ // A set request with empty 'preAndPostImages' should fail.
+ assert.commandFailedWithCode(
+ adminDB.runCommand({setClusterParameter: {changeStreamOptions: {preAndPostImages: {}}}}),
+ ErrorCodes.BadValue);
+
+ // An invalid string value of 'expireAfterSeconds' should fail.
+ assert.commandFailedWithCode(adminDB.runCommand({
+ setClusterParameter:
+ {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: "unknown"}}}
+ }),
+ ErrorCodes.BadValue);
+
+ // A negative value of 'expireAfterSeconds' should fail.
+ assert.commandFailedWithCode(adminDB.runCommand({
+ setClusterParameter: {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: -1}}}
+ }),
+ ErrorCodes.BadValue);
+
+ // A zero value of 'expireAfterSeconds' should fail.
+ assert.commandFailedWithCode(adminDB.runCommand({
+ setClusterParameter: {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: 0}}}
+ }),
+ ErrorCodes.BadValue);
+
+ // Disable purging of expired pre- and post-images and validate that the get change stream
+ // options retrieves the expected options.
+ assert.commandWorked(adminDB.runCommand({
+ setClusterParameter: {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: "off"}}}
+ }));
+ const response1 =
+ assert.commandWorked(adminDB.runCommand({getClusterParameter: "changeStreamOptions"}));
+ assert.eq(
+ response1.clusterParameters[0].preAndPostImages, {expireAfterSeconds: "off"}, response1);
+
+ // Set the expiration time for pre- and post-images and validate get change stream options
+ // command.
+ assert.commandWorked(adminDB.runCommand({
+ setClusterParameter:
+ {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: NumberLong(10)}}}
+ }));
+ const response2 =
+ assert.commandWorked(adminDB.runCommand({getClusterParameter: "changeStreamOptions"}));
+ assert.eq(response2.clusterParameters[0].preAndPostImages,
+ {expireAfterSeconds: NumberLong(10)},
+ response2);
+}
+
+// Tests the set and get change stream options on the standalone configuration.
+(function testChangeStreamOptionsOnStandalone() {
+ const standalone = MongoRunner.runMongod();
+ const adminDB = standalone.getDB("admin");
+
+ // Verify that the set and get commands cannot be issued on a standalone server.
+ assert.commandFailedWithCode(adminDB.runCommand({
+ setClusterParameter:
+ {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: NumberLong(10)}}}
+ }),
+ ErrorCodes.IllegalOperation);
+ assert.commandFailedWithCode(adminDB.runCommand({getClusterParameter: "changeStreamOptions"}),
+ ErrorCodes.IllegalOperation);
+
+ MongoRunner.stopMongod(standalone);
+})();
+
+// Tests the set and get change stream options on the replica-set.
+(function testChangeStreamOptionsOnReplicaSet() {
+ const replSetTest = new ReplSetTest({name: "replSet", nodes: 2});
+ replSetTest.startSet();
+ replSetTest.initiate();
+
+ const primary = replSetTest.getPrimary();
+ const secondary = replSetTest.getSecondaries()[0];
+
+ // Verify that the set and get commands cannot be issued on database other than the 'admin'.
+ [primary, secondary].forEach(conn => {
+ assert.commandFailedWithCode(conn.getDB(testDBName).runCommand({
+ setClusterParameter:
+ {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: NumberLong(10)}}}
+ }),
+ ErrorCodes.Unauthorized);
+
+ assert.commandFailedWithCode(
+ conn.getDB(testDBName).runCommand({getClusterParameter: "changeStreamOptions"}),
+ ErrorCodes.Unauthorized);
+ });
+
+ // Tests the set and get commands on the primary node.
+ testChangeStreamOptionsWithAdminDB(primary);
+
+ replSetTest.stopSet();
+})();
+
+// Tests the set and get change stream options on the sharded cluster.
+(function testChangeStreamOptionsOnShardedCluster() {
+ const shardingTest = new ShardingTest({shards: 1, mongos: 1});
+ const adminDB = shardingTest.rs0.getPrimary().getDB("admin");
+
+ // Test that setClusterParameter cannot be issued directly on shards in the sharded cluster,
+ // while getClusterParameter can.
+ assert.commandFailedWithCode(adminDB.runCommand({
+ setClusterParameter:
+ {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: NumberLong(10)}}}
+ }),
+ ErrorCodes.NotImplemented);
+ assert.commandWorked(adminDB.runCommand({getClusterParameter: "changeStreamOptions"}));
+
+ // Run the set and get commands on the mongoS.
+ testChangeStreamOptionsWithAdminDB(shardingTest.s);
+
+ shardingTest.stop();
+})();
+
+// Tests that setClusterParameter and getClusterParameter can only be executed by user with
+// privilege actions 'setClusterParameter' and 'getClusterParameter' respectively.
+(function testClusterParameterChangeStreamOptionsForAuthorization() {
+ const replSetTest =
+ new ReplSetTest({name: "shard", nodes: 1, useHostName: true, waitForKeys: false});
+ replSetTest.startSet({keyFile: "jstests/libs/key1"});
+ replSetTest.initiate();
+
+ const primary = replSetTest.getPrimary();
+
+ // Create a user with admin role on 'admin' database.
+ primary.getDB("admin").createUser({
+ user: "adminUser",
+ pwd: "adminUser",
+ roles: [{role: "userAdminAnyDatabase", db: "admin"}]
+ });
+
+ // Verify that the admin user is unauthorized to execute set and get change stream options
+ // command.
+ assert(primary.getDB("admin").auth("adminUser", "adminUser"));
+ assert.commandFailedWithCode(primary.getDB("admin").runCommand({
+ setClusterParameter:
+ {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: NumberLong(10)}}}
+ }),
+ ErrorCodes.Unauthorized);
+ assert.commandFailedWithCode(
+ primary.getDB("admin").runCommand({getClusterParameter: "changeStreamOptions"}),
+ ErrorCodes.Unauthorized);
+
+ // Create a user with cluster admin role on 'admin' database.
+ primary.getDB("admin").createUser({
+ user: "clusterManager",
+ pwd: "clusterManager",
+ roles: [{role: "clusterManager", db: "admin"}]
+ });
+
+ primary.getDB("admin").logout();
+
+ // Verify that the cluster manager user is authorized to execute set and get change stream
+ // options command.
+ assert(primary.getDB("admin").auth("clusterManager", "clusterManager"));
+ assert.commandWorked(primary.getDB("admin").runCommand({
+ setClusterParameter:
+ {changeStreamOptions: {preAndPostImages: {expireAfterSeconds: NumberLong(10)}}}
+ }));
+ assert.commandWorked(
+ primary.getDB("admin").runCommand({getClusterParameter: "changeStreamOptions"}));
+ primary.getDB("admin").logout();
+
+ replSetTest.stopSet();
+})();
+}());