summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Mulrow <jack.mulrow@mongodb.com>2018-05-18 17:34:06 -0400
committerJack Mulrow <jack.mulrow@mongodb.com>2018-06-13 12:07:47 -0400
commit3225e5f0784b8306c700a6280bbb986634129291 (patch)
tree52cad5049c1ee1e82e1c186806a1dc24209f0859
parent6e13aec0f42bc9774496401e921db76a19527092 (diff)
downloadmongo-3225e5f0784b8306c700a6280bbb986634129291.tar.gz
SERVER-32064 Requests from the shell should use an implicit session by default
(cherry picked from commit 8817328f87564a29e9be2ed1a746cf40e89587eb)
-rw-r--r--buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml20
-rw-r--r--buildscripts/resmokeconfig/suites/core_auth.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml4
-rw-r--r--buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml4
-rw-r--r--buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml3
-rw-r--r--jstests/auth/auth1.js3
-rw-r--r--jstests/auth/authentication_restrictions.js3
-rw-r--r--jstests/auth/authentication_restrictions_role.js3
-rw-r--r--jstests/auth/basic_role_auth.js2
-rw-r--r--jstests/auth/commands_builtin_roles.js4
-rw-r--r--jstests/auth/commands_user_defined_roles.js4
-rw-r--r--jstests/auth/copyauth.js4
-rw-r--r--jstests/auth/getMore.js3
-rw-r--r--jstests/auth/kill_cursors.js3
-rw-r--r--jstests/auth/kill_sessions.js4
-rw-r--r--jstests/auth/list_all_local_sessions.js4
-rw-r--r--jstests/auth/list_all_sessions.js4
-rw-r--r--jstests/auth/list_local_sessions.js4
-rw-r--r--jstests/auth/list_sessions.js4
-rw-r--r--jstests/auth/refresh_logical_session_cache_with_long_usernames.js4
-rw-r--r--jstests/auth/rename.js5
-rw-r--r--jstests/auth/repl_auth.js4
-rw-r--r--jstests/auth/resource_pattern_matching.js5
-rw-r--r--jstests/auth/secondary_invalidation.js3
-rw-r--r--jstests/auth/views_authz.js3
-rw-r--r--jstests/core/auth1.js7
-rw-r--r--jstests/core/connection_status.js5
-rw-r--r--jstests/core/evalb.js3
-rw-r--r--jstests/core/profile1.js7
-rw-r--r--jstests/core/profile3.js1
-rw-r--r--jstests/core/txns/multi_statement_transaction_command_args.js3
-rw-r--r--jstests/core/user_management_helpers.js5
-rw-r--r--jstests/multiVersion/mixed_storage_version_replication.js13
-rw-r--r--jstests/noPassthrough/aggregation_cursor_invalidations.js4
-rw-r--r--jstests/noPassthrough/count_helper_read_preference.js7
-rw-r--r--jstests/noPassthrough/currentop_includes_await_time.js4
-rw-r--r--jstests/noPassthrough/currentop_query.js4
-rw-r--r--jstests/noPassthrough/end_sessions_command.js4
-rw-r--r--jstests/noPassthrough/implicit_sessions.js265
-rw-r--r--jstests/noPassthrough/kill_pinned_cursor.js5
-rw-r--r--jstests/noPassthrough/kill_sessions.js4
-rw-r--r--jstests/noPassthrough/log_format_slowms_samplerate_loglevel.js4
-rw-r--r--jstests/noPassthrough/refresh_logical_session_cache_now.js4
-rw-r--r--jstests/noPassthrough/refresh_sessions_command.js4
-rw-r--r--jstests/noPassthrough/sessions_collection_auto_healing.js4
-rw-r--r--jstests/noPassthrough/shell_can_use_read_concern.js3
-rw-r--r--jstests/noPassthrough/snapshot_cursor_integrity.js3
-rw-r--r--jstests/noPassthrough/start_session_command.js5
-rw-r--r--jstests/noPassthrough/transaction_reaper.js4
-rw-r--r--jstests/noPassthrough/verify_session_cache_updates.js4
-rw-r--r--jstests/noPassthroughWithMongod/tailable_getmore_does_not_timeout.js4
-rw-r--r--jstests/replsets/auth1.js5
-rw-r--r--jstests/replsets/refresh_sessions_rs.js3
-rw-r--r--jstests/replsets/retryable_writes_direct_write_to_config_transactions.js3
-rw-r--r--jstests/replsets/rollback_auth.js3
-rw-r--r--jstests/replsets/sessions_collection_auto_healing.js4
-rw-r--r--jstests/replsets/user_management_wc.js4
-rw-r--r--jstests/sharding/advance_cluster_time_action_type.js3
-rw-r--r--jstests/sharding/authCommands.js3
-rw-r--r--jstests/sharding/auth_repl.js3
-rw-r--r--jstests/sharding/cleanup_orphaned_auth.js3
-rw-r--r--jstests/sharding/commands_that_write_accept_wc_configRS.js4
-rw-r--r--jstests/sharding/kill_pinned_cursor.js3
-rw-r--r--jstests/sharding/kill_sessions.js4
-rw-r--r--jstests/sharding/mongod_returns_no_cluster_time_without_keys.js7
-rw-r--r--jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js3
-rw-r--r--jstests/sharding/mrShardedOutputAuth.js3
-rw-r--r--jstests/sharding/refresh_sessions.js3
-rw-r--r--jstests/sharding/sessions_collection_auto_healing.js4
-rw-r--r--jstests/sharding/sharding_options.js3
-rw-r--r--jstests/sharding/snapshot_aggregate_mongos.js4
-rw-r--r--jstests/sharding/snapshot_find_mongos.js4
-rw-r--r--src/mongo/shell/mongo.js23
-rw-r--r--src/mongo/shell/query.js9
-rw-r--r--src/mongo/shell/session.js11
-rw-r--r--src/mongo/shell/shell_utils.cpp5
-rw-r--r--src/mongo/shell/utils.js13
77 files changed, 599 insertions, 25 deletions
diff --git a/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml b/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml
index 34218fa2665..e09d9791c5f 100644
--- a/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml
+++ b/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml
@@ -157,6 +157,17 @@ selector:
# sync source if the RestartCatalog command kills its oplog fetching cursor, which blocks
# secondary majority reads.
- jstests/core/restart_catalog.js
+
+ # These include operations the root user auth'd on the test database is not authorized to perform,
+ # e.g. dropping or creating system collections.
+ - jstests/core/cannot_create_system_dot_indexes.js
+ - jstests/core/list_collections_no_views.js
+ - jstests/core/rename8.js
+ - jstests/core/views/duplicate_ns.js
+ - jstests/core/views/invalid_system_views.js
+ - jstests/core/views/views_creation.js
+ - jstests/core/views/views_drop.js
+ - jstests/core/views/views_rename.js
exclude_with_any_tags:
- assumes_against_mongod_not_mongos
##
@@ -168,7 +179,11 @@ selector:
# "Cowardly refusing to run test with overridden read preference when it reads from a
# non-replicated collection: ..."
- assumes_read_preference_unchanged
+ # TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ - creates_and_authenticates_user
- requires_collstats
+ # This suite runs as the root user, but eval requires universal privileges with authentication on.
+ - requires_eval_command
executor:
archive:
@@ -192,7 +207,7 @@ executor:
const res = db.runCommand({
createUser: username,
pwd: password,
- roles: ["dbOwner"],
+ roles: [{role: "root", db: jsTest.options().authenticationDatabase}]
});
if (res.ok === 1) {
@@ -203,7 +218,8 @@ executor:
assert.commandFailedWithCode(res, ErrorCodes.DuplicateKey);
}
- db.logout();
+ // Log out as the __system user and auth as the newly created user.
+ db.getSiblingDB(jsTest.options().authenticationDatabase).logout();
db.auth(username, password);
})();
load("jstests/libs/override_methods/enable_causal_consistency.js");
diff --git a/buildscripts/resmokeconfig/suites/core_auth.yml b/buildscripts/resmokeconfig/suites/core_auth.yml
index 0304de42ad2..d5290825547 100644
--- a/buildscripts/resmokeconfig/suites/core_auth.yml
+++ b/buildscripts/resmokeconfig/suites/core_auth.yml
@@ -20,6 +20,9 @@ selector:
- jstests/core/**/*[aA]uth*.js
# Commands using UUIDs are not compatible with name-based auth
- jstests/core/commands_with_uuid.js
+ exclude_with_any_tags:
+ # TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ - creates_and_authenticates_user
executor:
archive:
diff --git a/buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml b/buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml
index 6c1c85d9014..6584273afa8 100644
--- a/buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml
+++ b/buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml
@@ -13,6 +13,10 @@ executor:
config:
shell_options:
readMode: commands
+ global_vars:
+ TestData:
+ # Other fuzzers test commands against replica sets with logical session ids.
+ disableImplicitSessions: true
hooks:
# The CheckReplDBHash hook waits until all operations have replicated to and have been applied
# on the secondaries, so we run the ValidateCollections hook after it to ensure we're
diff --git a/buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml b/buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml
index 394b0af4ff6..65b093116eb 100644
--- a/buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml
+++ b/buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml
@@ -11,6 +11,10 @@ executor:
- ValidateCollections
config:
shell_options:
+ global_vars:
+ TestData:
+ # Other fuzzers test commands against sharded clusters with logical session ids.
+ disableImplicitSessions: true
readMode: commands
hooks:
- class: CheckReplDBHash
diff --git a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml
index b0491cec3e9..f5d2c288232 100644
--- a/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml
+++ b/buildscripts/resmokeconfig/suites/replica_sets_multi_stmt_txn_jscore_passthrough.yml
@@ -223,6 +223,9 @@ selector:
- jstests/core/json_schema/misc_validation.js
- jstests/core/views/views_all_commands.js
+ # Fails with implicit sessions because it will use multiple sessions on the same Mongo connection.
+ - jstests/core/dropdb.js
+
# Committing a transaction when the server is fsync locked fails.
- jstests/core/fsync.js
diff --git a/jstests/auth/auth1.js b/jstests/auth/auth1.js
index 183317414df..6eff329e341 100644
--- a/jstests/auth/auth1.js
+++ b/jstests/auth/auth1.js
@@ -1,6 +1,9 @@
// test read/write permissions
// skip this test on 32-bit platforms
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
+
function setupTest() {
print("START auth1.js");
baseName = "jstests_auth_auth1";
diff --git a/jstests/auth/authentication_restrictions.js b/jstests/auth/authentication_restrictions.js
index ad12fd33f35..1f08b3e6d6d 100644
--- a/jstests/auth/authentication_restrictions.js
+++ b/jstests/auth/authentication_restrictions.js
@@ -6,6 +6,9 @@
(function() {
'use strict';
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
function testConnection(
conn, eventuallyConsistentConn, sleepUntilUserDataPropagated, sleepUntilUserDataRefreshed) {
load("jstests/libs/host_ipaddr.js");
diff --git a/jstests/auth/authentication_restrictions_role.js b/jstests/auth/authentication_restrictions_role.js
index 41e3a133cab..3f23cfdcb92 100644
--- a/jstests/auth/authentication_restrictions_role.js
+++ b/jstests/auth/authentication_restrictions_role.js
@@ -6,6 +6,9 @@
(function() {
'use strict';
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
function testRestrictionCreationAndEnforcement(
conn, eventuallyConsistentConn, sleepUntilUserDataPropagated, sleepUntilUserDataRefreshed) {
load("jstests/libs/host_ipaddr.js");
diff --git a/jstests/auth/basic_role_auth.js b/jstests/auth/basic_role_auth.js
index 9f8abffae40..81e1518152c 100644
--- a/jstests/auth/basic_role_auth.js
+++ b/jstests/auth/basic_role_auth.js
@@ -493,7 +493,7 @@ var runTests = function(conn) {
testFunc.test(newConn);
} catch (x) {
failures.push(testFunc.name);
- jsTestLog(x);
+ jsTestLog(tojson(x));
}
});
diff --git a/jstests/auth/commands_builtin_roles.js b/jstests/auth/commands_builtin_roles.js
index 93eef01bcd6..cee5957d354 100644
--- a/jstests/auth/commands_builtin_roles.js
+++ b/jstests/auth/commands_builtin_roles.js
@@ -9,6 +9,10 @@ in jstests/auth/commands.js.
*/
+// TODO SERVER-35447: This test involves killing all sessions, which will not work as expected if
+// the kill command is sent with an implicit session.
+TestData.disableImplicitSessions = true;
+
load("jstests/auth/lib/commands_lib.js");
var roles = [
diff --git a/jstests/auth/commands_user_defined_roles.js b/jstests/auth/commands_user_defined_roles.js
index ad75b5e1d83..034694c96bb 100644
--- a/jstests/auth/commands_user_defined_roles.js
+++ b/jstests/auth/commands_user_defined_roles.js
@@ -9,6 +9,10 @@ in jstests/auth/commands.js.
*/
+// TODO SERVER-35447: This test involves killing all sessions, which will not work as expected if
+// the kill command is sent with an implicit session.
+TestData.disableImplicitSessions = true;
+
// constants
var testUser = "userDefinedRolesTestUser";
var testRole = "userDefinedRolesTestRole";
diff --git a/jstests/auth/copyauth.js b/jstests/auth/copyauth.js
index faf5badd5ff..9caa51a6e87 100644
--- a/jstests/auth/copyauth.js
+++ b/jstests/auth/copyauth.js
@@ -195,6 +195,10 @@ function copydbBetweenClustersTest(configObj) {
assert.eq(1, target.conn.getDB(baseName)[baseName].count());
assert.eq(1, target.conn.getDB(baseName)[baseName].findOne().i);
+ if (configObj.isTargetUsingAuth) {
+ target.conn.getDB("admin").logout();
+ }
+
// 4. Do any necessary cleanup
source.stop();
target.stop();
diff --git a/jstests/auth/getMore.js b/jstests/auth/getMore.js
index 999fa733be8..cbb84c4a687 100644
--- a/jstests/auth/getMore.js
+++ b/jstests/auth/getMore.js
@@ -3,6 +3,9 @@
(function() {
"use strict";
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
function runTest(conn) {
let adminDB = conn.getDB("admin");
let isMaster = adminDB.runCommand("ismaster");
diff --git a/jstests/auth/kill_cursors.js b/jstests/auth/kill_cursors.js
index 2fd3d7054f8..3264bbcc15b 100644
--- a/jstests/auth/kill_cursors.js
+++ b/jstests/auth/kill_cursors.js
@@ -3,6 +3,9 @@
(function() {
'use strict';
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
function runTest(mongod) {
/**
* Open a cursor on `db` while authenticated as `authUsers`.
diff --git a/jstests/auth/kill_sessions.js b/jstests/auth/kill_sessions.js
index b2090d28609..b07364bc0c2 100644
--- a/jstests/auth/kill_sessions.js
+++ b/jstests/auth/kill_sessions.js
@@ -3,6 +3,10 @@ load("jstests/libs/kill_sessions.js");
(function() {
'use strict';
+ // TODO SERVER-35447: This test involves killing all sessions, which will not work as expected
+ // if the kill command is sent with an implicit session.
+ TestData.disableImplicitSessions = true;
+
var forExec = MongoRunner.runMongod({nojournal: "", auth: ""});
var forKill = new Mongo(forExec.host);
var forVerify = new Mongo(forExec.host);
diff --git a/jstests/auth/list_all_local_sessions.js b/jstests/auth/list_all_local_sessions.js
index 8e889feb4e2..3b7c19d1cbe 100644
--- a/jstests/auth/list_all_local_sessions.js
+++ b/jstests/auth/list_all_local_sessions.js
@@ -5,6 +5,10 @@
'use strict';
load('jstests/aggregation/extras/utils.js');
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
function runListAllLocalSessionsTest(mongod) {
assert(mongod);
const admin = mongod.getDB("admin");
diff --git a/jstests/auth/list_all_sessions.js b/jstests/auth/list_all_sessions.js
index 35a4e3b3c06..1337fc2e94c 100644
--- a/jstests/auth/list_all_sessions.js
+++ b/jstests/auth/list_all_sessions.js
@@ -5,6 +5,10 @@
'use strict';
load('jstests/aggregation/extras/utils.js');
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
function runListAllSessionsTest(mongod) {
assert(mongod);
const admin = mongod.getDB("admin");
diff --git a/jstests/auth/list_local_sessions.js b/jstests/auth/list_local_sessions.js
index 4693d694666..b943ba45955 100644
--- a/jstests/auth/list_local_sessions.js
+++ b/jstests/auth/list_local_sessions.js
@@ -4,6 +4,10 @@
'use strict';
load('jstests/aggregation/extras/utils.js');
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
function runListLocalSessionsTest(mongod) {
assert(mongod);
const admin = mongod.getDB('admin');
diff --git a/jstests/auth/list_sessions.js b/jstests/auth/list_sessions.js
index e6c14a11c4c..2b6c8a0f8f1 100644
--- a/jstests/auth/list_sessions.js
+++ b/jstests/auth/list_sessions.js
@@ -7,6 +7,10 @@
'use strict';
load('jstests/aggregation/extras/utils.js');
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
function runListSessionsTest(mongod) {
assert(mongod);
const admin = mongod.getDB('admin');
diff --git a/jstests/auth/refresh_logical_session_cache_with_long_usernames.js b/jstests/auth/refresh_logical_session_cache_with_long_usernames.js
index d9bbed5324f..e584a1b8345 100644
--- a/jstests/auth/refresh_logical_session_cache_with_long_usernames.js
+++ b/jstests/auth/refresh_logical_session_cache_with_long_usernames.js
@@ -4,6 +4,10 @@
(function() {
'use strict';
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
const mongod = MongoRunner.runMongod({auth: ""});
const refresh = {refreshLogicalSessionCacheNow: 1};
diff --git a/jstests/auth/rename.js b/jstests/auth/rename.js
index a8120d22322..0ae3eac3113 100644
--- a/jstests/auth/rename.js
+++ b/jstests/auth/rename.js
@@ -1,5 +1,8 @@
// test renameCollection with auth
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
+
var m = MongoRunner.runMongod({auth: ""});
var db1 = m.getDB("foo");
@@ -42,4 +45,4 @@ assert.eq(db1.a.count(), 0);
assert.eq(db1.b.count(), 0);
assert.eq(db2.a.count(), 1);
-MongoRunner.stopMongod(m, null, {user: 'admin', pwd: 'password'}); \ No newline at end of file
+MongoRunner.stopMongod(m, null, {user: 'admin', pwd: 'password'});
diff --git a/jstests/auth/repl_auth.js b/jstests/auth/repl_auth.js
index 17a6e13bd4b..fea8f227366 100644
--- a/jstests/auth/repl_auth.js
+++ b/jstests/auth/repl_auth.js
@@ -65,4 +65,8 @@ for (var x = 0; x < 20; x++) {
assert.eq(1, explain.executionStats.nReturned);
}
+admin.logout();
+fooDB0.logout();
+barDB1.logout();
+
rsTest.stopSet();
diff --git a/jstests/auth/resource_pattern_matching.js b/jstests/auth/resource_pattern_matching.js
index 0fd30650982..ca3c9b50195 100644
--- a/jstests/auth/resource_pattern_matching.js
+++ b/jstests/auth/resource_pattern_matching.js
@@ -3,6 +3,11 @@
* @tags: [requires_replication, requires_sharding]
*/
+// TODO SERVER-35447: This test logs in users on the admin database, but doesn't log them out, which
+// can fail with implicit sessions and ReplSetTest when the fixture attempts to verify data hashes
+// at shutdown by authenticating as the __system user.
+TestData.disableImplicitSessions = true;
+
function setup_users(granter) {
var admindb = granter.getSiblingDB("admin");
admindb.runCommand({
diff --git a/jstests/auth/secondary_invalidation.js b/jstests/auth/secondary_invalidation.js
index 8500322751f..16f2938ebbf 100644
--- a/jstests/auth/secondary_invalidation.js
+++ b/jstests/auth/secondary_invalidation.js
@@ -31,4 +31,7 @@ assert.doesNotThrow(function() {
secondaryFoo.col.findOne();
}, [], "Secondary read did not work with permissions");
+admin.logout();
+secondaryFoo.logout();
+
rsTest.stopSet();
diff --git a/jstests/auth/views_authz.js b/jstests/auth/views_authz.js
index e22dcf86cb6..080a4b2bfcd 100644
--- a/jstests/auth/views_authz.js
+++ b/jstests/auth/views_authz.js
@@ -6,6 +6,9 @@
(function() {
"use strict";
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
function runTest(conn) {
// Create the admin user.
let adminDB = conn.getDB("admin");
diff --git a/jstests/core/auth1.js b/jstests/core/auth1.js
index 05450d14ddc..4f2a869ab44 100644
--- a/jstests/core/auth1.js
+++ b/jstests/core/auth1.js
@@ -1,4 +1,9 @@
-// @tags: [requires_non_retryable_commands, requires_auth, assumes_write_concern_unchanged]
+// @tags: [
+// assumes_write_concern_unchanged,
+// creates_and_authenticates_user,
+// requires_auth,
+// requires_non_retryable_commands,
+// ]
var mydb = db.getSiblingDB('auth1_db');
mydb.dropAllUsers();
diff --git a/jstests/core/connection_status.js b/jstests/core/connection_status.js
index df1c59ab234..33d11149657 100644
--- a/jstests/core/connection_status.js
+++ b/jstests/core/connection_status.js
@@ -1,7 +1,8 @@
// @tags: [
-// requires_non_retryable_commands,
+// assumes_write_concern_unchanged,
+// creates_and_authenticates_user,
// requires_auth,
-// assumes_write_concern_unchanged
+// requires_non_retryable_commands,
// ]
// Tests the connectionStatus command
diff --git a/jstests/core/evalb.js b/jstests/core/evalb.js
index 92fbb81f31c..96f2bbd7358 100644
--- a/jstests/core/evalb.js
+++ b/jstests/core/evalb.js
@@ -2,10 +2,11 @@
// contents are logged in the profile log.
//
// @tags: [
+// assumes_read_preference_unchanged,
+// creates_and_authenticates_user,
// does_not_support_stepdowns,
// requires_eval_command,
// requires_non_retryable_commands,
-// assumes_read_preference_unchanged
// ]
// Use a reserved database name to avoid a conflict in the parallel test suite.
diff --git a/jstests/core/profile1.js b/jstests/core/profile1.js
index 4109c3ac55d..730bb91a33a 100644
--- a/jstests/core/profile1.js
+++ b/jstests/core/profile1.js
@@ -1,4 +1,9 @@
-// @tags: [does_not_support_stepdowns, requires_non_retryable_commands, requires_collstats]
+// @tags: [
+// creates_and_authenticates_user,
+// does_not_support_stepdowns,
+// requires_collstats,
+// requires_non_retryable_commands,
+// ]
(function() {
"use strict";
diff --git a/jstests/core/profile3.js b/jstests/core/profile3.js
index 35e37d0917d..f55256783ab 100644
--- a/jstests/core/profile3.js
+++ b/jstests/core/profile3.js
@@ -1,4 +1,5 @@
// @tags: [
+// creates_and_authenticates_user
// # profile command is not available on embedded
// incompatible_with_embedded,
// ]
diff --git a/jstests/core/txns/multi_statement_transaction_command_args.js b/jstests/core/txns/multi_statement_transaction_command_args.js
index fe139e2f16d..8246d1030a5 100644
--- a/jstests/core/txns/multi_statement_transaction_command_args.js
+++ b/jstests/core/txns/multi_statement_transaction_command_args.js
@@ -8,6 +8,9 @@
"use strict";
load('jstests/libs/uuid_util.js');
+ // Makes assertions on commands run without logical session ids.
+ TestData.disableImplicitSessions = true;
+
const dbName = "test";
const collName = "multi_statement_transaction_command_args";
const testDB = db.getSiblingDB(dbName);
diff --git a/jstests/core/user_management_helpers.js b/jstests/core/user_management_helpers.js
index 6e3ee9187c0..3d3b1b49c68 100644
--- a/jstests/core/user_management_helpers.js
+++ b/jstests/core/user_management_helpers.js
@@ -1,7 +1,8 @@
// @tags: [
-// requires_non_retryable_commands,
+// assumes_write_concern_unchanged,
+// creates_and_authenticates_user,
// requires_auth,
-// assumes_write_concern_unchanged
+// requires_non_retryable_commands,
// ]
// This test is a basic sanity check of the shell helpers for manipulating user objects
diff --git a/jstests/multiVersion/mixed_storage_version_replication.js b/jstests/multiVersion/mixed_storage_version_replication.js
index c67de845e77..d9f2e880e0c 100644
--- a/jstests/multiVersion/mixed_storage_version_replication.js
+++ b/jstests/multiVersion/mixed_storage_version_replication.js
@@ -4,6 +4,11 @@
* storage engines, do a bunch of random work, and assert that it replicates the same way on all
* nodes.
*/
+
+// This test randomly generates operations, which may include direct writes against
+// config.transactions, which are not allowed to run under a session.
+TestData.disableImplicitSessions = true;
+
load('jstests/libs/parallelTester.js');
load("jstests/replsets/rslib.js");
@@ -570,6 +575,10 @@ function assertSameData(primary, conns) {
* function to pass to a thread to make it start doing random commands/CRUD operations.
*/
function startCmds(randomOps, host) {
+ // This test randomly generates operations, which may include direct writes against
+ // config.transactions, which are not allowed to run under a session.
+ TestData = {disableImplicitSessions: true};
+
var ops = [
"insert",
"remove",
@@ -596,6 +605,10 @@ function startCmds(randomOps, host) {
* function to pass to a thread to make it start doing random CRUD operations.
*/
function startCRUD(randomOps, host) {
+ // This test randomly generates operations, which may include direct writes against
+ // config.transactions, which are not allowed to run under a session.
+ TestData = {disableImplicitSessions: true};
+
var m = new Mongo(host);
var numOps = 500;
Random.setRandomSeed();
diff --git a/jstests/noPassthrough/aggregation_cursor_invalidations.js b/jstests/noPassthrough/aggregation_cursor_invalidations.js
index e35598dc2dd..ecc4fe160c9 100644
--- a/jstests/noPassthrough/aggregation_cursor_invalidations.js
+++ b/jstests/noPassthrough/aggregation_cursor_invalidations.js
@@ -12,6 +12,10 @@
(function() {
'use strict';
+ // This test runs a getMore in a parallel shell, which will not inherit the implicit session of
+ // the cursor establishing command.
+ TestData.disableImplicitSessions = true;
+
// The DocumentSourceCursor which wraps PlanExecutors will batch results internally. We use the
// 'internalDocumentSourceCursorBatchSizeBytes' parameter to disable this behavior so that we
// can easily pause a pipeline in a state where it will need to request more results from the
diff --git a/jstests/noPassthrough/count_helper_read_preference.js b/jstests/noPassthrough/count_helper_read_preference.js
index 63b5faed2ce..619773c3563 100644
--- a/jstests/noPassthrough/count_helper_read_preference.js
+++ b/jstests/noPassthrough/count_helper_read_preference.js
@@ -19,7 +19,12 @@
commandsRan.push({db: db, cmd: cmd, opts: opts});
return {ok: 1, n: 100};
};
- var db = new DB(new MockMongo(), "test");
+
+ const mockMongo = new MockMongo();
+ var db = new DB(mockMongo, "test");
+
+ // Attach a dummy implicit session because the mock connection cannot create sessions.
+ db._session = new _DummyDriverSession(mockMongo);
assert.eq(commandsRan.length, 0);
diff --git a/jstests/noPassthrough/currentop_includes_await_time.js b/jstests/noPassthrough/currentop_includes_await_time.js
index 0c34999a512..a8ec126f6d7 100644
--- a/jstests/noPassthrough/currentop_includes_await_time.js
+++ b/jstests/noPassthrough/currentop_includes_await_time.js
@@ -5,6 +5,10 @@
(function() {
"use test";
+ // This test runs a getMore in a parallel shell, which will not inherit the implicit session of
+ // the cursor establishing command.
+ TestData.disableImplicitSessions = true;
+
const conn = MongoRunner.runMongod({});
assert.neq(null, conn, "mongod was unable to start up");
const testDB = conn.getDB("test");
diff --git a/jstests/noPassthrough/currentop_query.js b/jstests/noPassthrough/currentop_query.js
index 7d39fcaed21..b05e66d1af0 100644
--- a/jstests/noPassthrough/currentop_query.js
+++ b/jstests/noPassthrough/currentop_query.js
@@ -6,6 +6,10 @@
(function() {
"use strict";
+ // This test runs manual getMores using different connections, which will not inherit the
+ // implicit session of the cursor establishing command.
+ TestData.disableImplicitSessions = true;
+
load("jstests/libs/fixture_helpers.js"); // For FixtureHelpers.
// Set up a 2-shard cluster. Configure 'internalQueryExecYieldIterations' on both shards such
diff --git a/jstests/noPassthrough/end_sessions_command.js b/jstests/noPassthrough/end_sessions_command.js
index 1ed1c471557..e4ee14b8ecb 100644
--- a/jstests/noPassthrough/end_sessions_command.js
+++ b/jstests/noPassthrough/end_sessions_command.js
@@ -1,6 +1,10 @@
(function() {
"use script";
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
var res;
var refresh = {refreshLogicalSessionCacheNow: 1};
var startSession = {startSession: 1};
diff --git a/jstests/noPassthrough/implicit_sessions.js b/jstests/noPassthrough/implicit_sessions.js
new file mode 100644
index 00000000000..350571164b9
--- /dev/null
+++ b/jstests/noPassthrough/implicit_sessions.js
@@ -0,0 +1,265 @@
+/**
+ * Verifies behavior around implicit sessions in the mongo shell.
+ */
+(function() {
+ "use strict";
+
+ /**
+ * Runs the given function, inspecting the outgoing command object and making assertions about
+ * its logical session id.
+ */
+ function inspectCommandForSessionId(func, {shouldIncludeId, expectedId, differentFromId}) {
+ const mongoRunCommandOriginal = Mongo.prototype.runCommand;
+
+ const sentinel = {};
+ let cmdObjSeen = sentinel;
+
+ Mongo.prototype.runCommand = function runCommandSpy(dbName, cmdObj, options) {
+ cmdObjSeen = cmdObj;
+ return mongoRunCommandOriginal.apply(this, arguments);
+ };
+
+ try {
+ assert.doesNotThrow(func);
+ } finally {
+ Mongo.prototype.runCommand = mongoRunCommandOriginal;
+ }
+
+ if (cmdObjSeen === sentinel) {
+ throw new Error("Mongo.prototype.runCommand() was never called: " + func.toString());
+ }
+
+ // If the command is in a wrapped form, then we look for the actual command object inside
+ // the query/$query object.
+ let cmdName = Object.keys(cmdObjSeen)[0];
+ if (cmdName === "query" || cmdName === "$query") {
+ cmdObjSeen = cmdObjSeen[cmdName];
+ cmdName = Object.keys(cmdObjSeen)[0];
+ }
+
+ if (shouldIncludeId) {
+ assert(cmdObjSeen.hasOwnProperty("lsid"),
+ "Expected operation " + tojson(cmdObjSeen) + " to have a logical session id.");
+
+ if (expectedId) {
+ assert(bsonBinaryEqual(expectedId, cmdObjSeen.lsid),
+ "The sent session id did not match the expected, sent: " +
+ tojson(cmdObjSeen.lsid) + ", expected: " + tojson(expectedId));
+ }
+
+ if (differentFromId) {
+ assert(!bsonBinaryEqual(differentFromId, cmdObjSeen.lsid),
+ "The sent session id was not different from the expected, sent: " +
+ tojson(cmdObjSeen.lsid) + ", expected: " + tojson(differentFromId));
+ }
+
+ } else {
+ assert(
+ !cmdObjSeen.hasOwnProperty("lsid"),
+ "Expected operation " + tojson(cmdObjSeen) + " to not have a logical session id.");
+ }
+
+ return cmdObjSeen.lsid;
+ }
+
+ // Tests regular behavior of implicit sessions.
+ function runTest() {
+ const conn = MongoRunner.runMongod();
+
+ // Commands run on a database without an explicit session should use an implicit one.
+ const testDB = conn.getDB("test");
+ const coll = testDB.getCollection("foo");
+ const implicitId = inspectCommandForSessionId(function() {
+ assert.writeOK(coll.insert({x: 1}));
+ }, {shouldIncludeId: true});
+
+ assert(bsonBinaryEqual(testDB.getSession().getSessionId(), implicitId),
+ "Expected the id of the database's implicit session to match the one sent, sent: " +
+ tojson(implicitId) + " db session id: " +
+ tojson(testDB.getSession().getSessionId()));
+
+ // Implicit sessions are not causally consistent.
+ assert(!testDB.getSession().getOptions().isCausalConsistency(),
+ "Expected the database's implicit session to not be causally consistent");
+
+ // Further commands run on the same database should reuse the implicit session.
+ inspectCommandForSessionId(function() {
+ assert.writeOK(coll.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: implicitId});
+
+ // New collections from the same database should inherit the implicit session.
+ const collTwo = testDB.getCollection("bar");
+ inspectCommandForSessionId(function() {
+ assert.writeOK(collTwo.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: implicitId});
+
+ // Sibling databases should inherit the implicit session.
+ let siblingColl = testDB.getSiblingDB("foo").getCollection("bar");
+ inspectCommandForSessionId(function() {
+ assert.writeOK(siblingColl.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: implicitId});
+
+ // A new database from the same connection should inherit the implicit session.
+ const newCollSameConn = conn.getDB("testTwo").getCollection("foo");
+ inspectCommandForSessionId(function() {
+ assert.writeOK(newCollSameConn.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: implicitId});
+
+ // A new database from a new connection should use a different implicit session.
+ const newCollNewConn = new Mongo(conn.host).getDB("test").getCollection("foo");
+ inspectCommandForSessionId(function() {
+ assert.writeOK(newCollNewConn.insert({x: 1}));
+ }, {shouldIncludeId: true, differentFromId: implicitId});
+
+ // The original implicit session should still live on the first database.
+ inspectCommandForSessionId(function() {
+ assert.writeOK(coll.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: implicitId});
+
+ // Databases created from an explicit session should override any implicit sessions.
+ const session = conn.startSession();
+ const sessionColl = session.getDatabase("test").getCollection("foo");
+ const explicitId = inspectCommandForSessionId(function() {
+ assert.writeOK(sessionColl.insert({x: 1}));
+ }, {shouldIncludeId: true, differentFromId: implicitId});
+
+ assert(bsonBinaryEqual(session.getSessionId(), explicitId),
+ "Expected the id of the explicit session to match the one sent, sent: " +
+ tojson(explicitId) + " explicit session id: " + tojson(session.getSessionId()));
+ assert(bsonBinaryEqual(sessionColl.getDB().getSession().getSessionId(), explicitId),
+ "Expected id of the database's session to match the explicit session's id, sent: " +
+ tojson(sessionColl.getDB().getSession().getSessionId()) +
+ ", explicit session id: " + tojson(session.getSessionId()));
+
+ // The original implicit session should still live on the first database.
+ inspectCommandForSessionId(function() {
+ assert.writeOK(coll.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: implicitId});
+
+ // New databases on the same connection as the explicit session should still inherit the
+ // original implicit session.
+ const newCollSameConnAfter = conn.getDB("testThree").getCollection("foo");
+ inspectCommandForSessionId(function() {
+ assert.writeOK(newCollSameConnAfter.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: implicitId});
+
+ session.endSession();
+ MongoRunner.stopMongod(conn);
+ }
+
+ // Tests behavior when the test flag to disable implicit sessions is changed.
+ function runTestTransitionToDisabled() {
+ const conn = MongoRunner.runMongod();
+
+ // Existing implicit sessions should be erased when the disable flag is set.
+ const coll = conn.getDB("test").getCollection("foo");
+ const implicitId = inspectCommandForSessionId(function() {
+ assert.writeOK(coll.insert({x: 1}));
+ }, {shouldIncludeId: true});
+
+ TestData.disableImplicitSessions = true;
+
+ inspectCommandForSessionId(function() {
+ assert.writeOK(coll.insert({x: 1}));
+ }, {shouldIncludeId: false});
+
+ // After the flag is unset, databases using existing connections with implicit sessions will
+ // use the original implicit sessions again and new connections will create and use new
+ // implicit sessions.
+ TestData.disableImplicitSessions = false;
+
+ inspectCommandForSessionId(function() {
+ assert.writeOK(coll.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: implicitId});
+
+ const newColl = conn.getDB("test").getCollection("foo");
+ inspectCommandForSessionId(function() {
+ assert.writeOK(newColl.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: implicitId});
+
+ const newCollNewConn = new Mongo(conn.host).getDB("test").getCollection("foo");
+ inspectCommandForSessionId(function() {
+ assert.writeOK(newCollNewConn.insert({x: 1}));
+ }, {shouldIncludeId: true, differentFromId: implicitId});
+
+ // Explicit sessions should not be affected by the disable flag being set.
+ const session = conn.startSession();
+ const sessionColl = session.getDatabase("test").getCollection("foo");
+ const explicitId = inspectCommandForSessionId(function() {
+ assert.writeOK(sessionColl.insert({x: 1}));
+ }, {shouldIncludeId: true});
+
+ TestData.disableImplicitSessions = true;
+
+ inspectCommandForSessionId(function() {
+ assert.writeOK(sessionColl.insert({x: 1}));
+ }, {shouldIncludeId: true, expectedId: explicitId});
+
+ session.endSession();
+ MongoRunner.stopMongod(conn);
+ }
+
+ // Tests for the shell parameter, and the function that exposes it, for disabling implicit
+ // sessions.
+ function runTestGlobalFlag() {
+ const conn = MongoRunner.runMongod();
+ const testDB = conn.getDB("test");
+
+ // The native disabled function should return false in the mongo shell by default.
+ assert(_shouldUseImplicitSessions());
+
+ // Commands run in eval should never use implicit sessions.
+ const evalFunc = function() {
+ assert(!_shouldUseImplicitSessions(),
+ "expected implicit sessions to be disabled inside eval");
+
+ inspectCommandForSessionId(function() {
+ assert.writeOK(db.foo.insert({x: 1}));
+ }, {shouldIncludeId: false});
+ };
+ testDB.eval("inspectCommandForSessionId = " + inspectCommandForSessionId.toString() +
+ "; (" + evalFunc.toString() + ")()");
+
+ MongoRunner.stopMongod(conn);
+ }
+
+ // Tests behavior of implicit sessions when they are disabled via a test flag.
+ function runTestDisabled() {
+ const conn = MongoRunner.runMongod();
+
+ // Commands run without an explicit session should not use an implicit one.
+ const coll = conn.getDB("test").getCollection("foo");
+ inspectCommandForSessionId(function() {
+ assert.writeOK(coll.insert({x: 1}));
+ }, {shouldIncludeId: false});
+
+ // Explicit sessions should still include session ids.
+ const session = conn.startSession();
+ const sessionColl = session.getDatabase("test").getCollection("foo");
+ inspectCommandForSessionId(function() {
+ assert.writeOK(sessionColl.insert({x: 1}));
+ }, {shouldIncludeId: true});
+
+ // Commands run in a parallel shell inherit the disable flag.
+ TestData.inspectCommandForSessionId = inspectCommandForSessionId;
+ const awaitShell = startParallelShell(function() {
+ const parallelColl = db.getCollection("foo");
+ TestData.inspectCommandForSessionId(function() {
+ assert.writeOK(parallelColl.insert({x: 1}));
+ }, {shouldIncludeId: false});
+ }, conn.port);
+ awaitShell();
+
+ session.endSession();
+ MongoRunner.stopMongod(conn);
+ }
+
+ runTest();
+
+ runTestTransitionToDisabled();
+
+ runTestGlobalFlag();
+
+ TestData.disableImplicitSessions = true;
+ runTestDisabled();
+})();
diff --git a/jstests/noPassthrough/kill_pinned_cursor.js b/jstests/noPassthrough/kill_pinned_cursor.js
index d8ecd4998d2..e70f7f98dfb 100644
--- a/jstests/noPassthrough/kill_pinned_cursor.js
+++ b/jstests/noPassthrough/kill_pinned_cursor.js
@@ -12,6 +12,11 @@
(function() {
"use strict";
+
+ // This test runs manual getMores using different connections, which will not inherit the
+ // implicit session of the cursor establishing command.
+ TestData.disableImplicitSessions = true;
+
load("jstests/libs/fixture_helpers.js"); // For "isMongos".
const st = new ShardingTest({shards: 2});
diff --git a/jstests/noPassthrough/kill_sessions.js b/jstests/noPassthrough/kill_sessions.js
index bd804fa4528..16cb100d31e 100644
--- a/jstests/noPassthrough/kill_sessions.js
+++ b/jstests/noPassthrough/kill_sessions.js
@@ -3,6 +3,10 @@ load("jstests/libs/kill_sessions.js");
(function() {
'use strict';
+ // TODO SERVER-35447: This test involves killing all sessions, which will not work as expected
+ // if the kill command is sent with an implicit session.
+ TestData.disableImplicitSessions = true;
+
var conn = MongoRunner.runMongod({nojournal: ""});
KillSessionsTestHelper.runNoAuth(conn, conn, [conn]);
MongoRunner.stopMongod(conn);
diff --git a/jstests/noPassthrough/log_format_slowms_samplerate_loglevel.js b/jstests/noPassthrough/log_format_slowms_samplerate_loglevel.js
index 37afb165dd8..786f28c9d6b 100644
--- a/jstests/noPassthrough/log_format_slowms_samplerate_loglevel.js
+++ b/jstests/noPassthrough/log_format_slowms_samplerate_loglevel.js
@@ -7,6 +7,10 @@
(function() {
"use strict";
+ // This test looks for exact matches in log output, which does not account for implicit
+ // sessions.
+ TestData.disableImplicitSessions = true;
+
load("jstests/libs/fixture_helpers.js"); // For FixtureHelpers.
load("jstests/libs/check_log.js"); // For formatAsLogLine.
diff --git a/jstests/noPassthrough/refresh_logical_session_cache_now.js b/jstests/noPassthrough/refresh_logical_session_cache_now.js
index 294a16043d2..59d181845fe 100644
--- a/jstests/noPassthrough/refresh_logical_session_cache_now.js
+++ b/jstests/noPassthrough/refresh_logical_session_cache_now.js
@@ -1,6 +1,10 @@
(function() {
"use script";
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
var res;
var refresh = {refreshLogicalSessionCacheNow: 1};
var startSession = {startSession: 1};
diff --git a/jstests/noPassthrough/refresh_sessions_command.js b/jstests/noPassthrough/refresh_sessions_command.js
index 80b249faca7..1f7b1a4c301 100644
--- a/jstests/noPassthrough/refresh_sessions_command.js
+++ b/jstests/noPassthrough/refresh_sessions_command.js
@@ -1,6 +1,10 @@
(function() {
"use strict";
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
var conn;
var admin;
var result;
diff --git a/jstests/noPassthrough/sessions_collection_auto_healing.js b/jstests/noPassthrough/sessions_collection_auto_healing.js
index 58c64561161..21eb3d221a3 100644
--- a/jstests/noPassthrough/sessions_collection_auto_healing.js
+++ b/jstests/noPassthrough/sessions_collection_auto_healing.js
@@ -3,6 +3,10 @@ load('jstests/libs/sessions_collection.js');
(function() {
"use strict";
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
var startSession = {startSession: 1};
var conn = MongoRunner.runMongod({nojournal: ""});
diff --git a/jstests/noPassthrough/shell_can_use_read_concern.js b/jstests/noPassthrough/shell_can_use_read_concern.js
index 65cf66c06cc..049e7cad818 100644
--- a/jstests/noPassthrough/shell_can_use_read_concern.js
+++ b/jstests/noPassthrough/shell_can_use_read_concern.js
@@ -6,6 +6,9 @@
(function() {
"use strict";
+ // This test makes assertions on commands run without logical session ids.
+ TestData.disableImplicitSessions = true;
+
const rst = new ReplSetTest({nodes: 1});
rst.startSet();
rst.initiate();
diff --git a/jstests/noPassthrough/snapshot_cursor_integrity.js b/jstests/noPassthrough/snapshot_cursor_integrity.js
index d5d0678a641..fa1a44a6699 100644
--- a/jstests/noPassthrough/snapshot_cursor_integrity.js
+++ b/jstests/noPassthrough/snapshot_cursor_integrity.js
@@ -4,6 +4,9 @@
(function() {
"use strict";
+ // This test makes assertions on commands run without logical session ids.
+ TestData.disableImplicitSessions = true;
+
const dbName = "test";
const collName = "coll";
diff --git a/jstests/noPassthrough/start_session_command.js b/jstests/noPassthrough/start_session_command.js
index 4564cf5ab54..bfdd053179d 100644
--- a/jstests/noPassthrough/start_session_command.js
+++ b/jstests/noPassthrough/start_session_command.js
@@ -1,5 +1,10 @@
(function() {
'use strict';
+
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
var conn;
var admin;
var foo;
diff --git a/jstests/noPassthrough/transaction_reaper.js b/jstests/noPassthrough/transaction_reaper.js
index cdf58ec481e..71a0977f972 100644
--- a/jstests/noPassthrough/transaction_reaper.js
+++ b/jstests/noPassthrough/transaction_reaper.js
@@ -2,6 +2,10 @@
(function() {
'use strict';
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
load("jstests/libs/retryable_writes_util.js");
if (!RetryableWritesUtil.storageEngineSupportsRetryableWrites(jsTest.options().storageEngine)) {
diff --git a/jstests/noPassthrough/verify_session_cache_updates.js b/jstests/noPassthrough/verify_session_cache_updates.js
index 0f4e6cb39c1..22674cb1ecb 100644
--- a/jstests/noPassthrough/verify_session_cache_updates.js
+++ b/jstests/noPassthrough/verify_session_cache_updates.js
@@ -3,6 +3,10 @@
(function() {
'use strict';
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
function runTest(conn) {
for (var i = 0; i < 10; ++i) {
conn.getDB("test").test.save({a: i});
diff --git a/jstests/noPassthroughWithMongod/tailable_getmore_does_not_timeout.js b/jstests/noPassthroughWithMongod/tailable_getmore_does_not_timeout.js
index 0e8d05db09b..19a0452febb 100644
--- a/jstests/noPassthroughWithMongod/tailable_getmore_does_not_timeout.js
+++ b/jstests/noPassthroughWithMongod/tailable_getmore_does_not_timeout.js
@@ -4,6 +4,10 @@
(function() {
"use strict";
+ // This test runs a getMore in a parallel shell, which will not inherit the implicit session of
+ // the cursor establishing command.
+ TestData.disableImplicitSessions = true;
+
const coll = db.tailable_getmore_no_timeout;
coll.drop();
diff --git a/jstests/replsets/auth1.js b/jstests/replsets/auth1.js
index 81d3ddca816..9a9f36939b2 100644
--- a/jstests/replsets/auth1.js
+++ b/jstests/replsets/auth1.js
@@ -6,6 +6,11 @@
load("jstests/replsets/rslib.js");
(function() {
+ "use strict";
+
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
var name = "rs_auth1";
var port = allocatePorts(5);
var path = "jstests/libs/";
diff --git a/jstests/replsets/refresh_sessions_rs.js b/jstests/replsets/refresh_sessions_rs.js
index 307915d2faa..9bd4527c7bf 100644
--- a/jstests/replsets/refresh_sessions_rs.js
+++ b/jstests/replsets/refresh_sessions_rs.js
@@ -1,6 +1,9 @@
(function() {
"use strict";
+ // This test makes assertions about the number of logical session records.
+ TestData.disableImplicitSessions = true;
+
var refresh = {refreshLogicalSessionCacheNow: 1};
var startSession = {startSession: 1};
diff --git a/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js b/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js
index 6739915ec56..0a89dcc7390 100644
--- a/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js
+++ b/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js
@@ -2,6 +2,9 @@
(function() {
'use strict';
+ // Direct writes to config.transactions cannot be part of a session.
+ TestData.disableImplicitSessions = true;
+
load("jstests/libs/retryable_writes_util.js");
if (!RetryableWritesUtil.storageEngineSupportsRetryableWrites(jsTest.options().storageEngine)) {
diff --git a/jstests/replsets/rollback_auth.js b/jstests/replsets/rollback_auth.js
index e3b03ad40b2..7d78484fdf1 100644
--- a/jstests/replsets/rollback_auth.js
+++ b/jstests/replsets/rollback_auth.js
@@ -20,6 +20,9 @@
// TODO SERVER-32639: remove this flag.
TestData.skipGossipingClusterTime = true;
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
// helper function for verifying contents at the end of the test
var checkFinalResults = function(db) {
assert.commandWorked(db.runCommand({dbStats: 1}));
diff --git a/jstests/replsets/sessions_collection_auto_healing.js b/jstests/replsets/sessions_collection_auto_healing.js
index e77b99f4059..f4f147a5dd3 100644
--- a/jstests/replsets/sessions_collection_auto_healing.js
+++ b/jstests/replsets/sessions_collection_auto_healing.js
@@ -3,6 +3,10 @@ load('jstests/libs/sessions_collection.js');
(function() {
"use strict";
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
var replTest = new ReplSetTest({name: 'refresh', nodes: 3});
var nodes = replTest.startSet();
diff --git a/jstests/replsets/user_management_wc.js b/jstests/replsets/user_management_wc.js
index a0796b4fcbf..e24c4c74eae 100644
--- a/jstests/replsets/user_management_wc.js
+++ b/jstests/replsets/user_management_wc.js
@@ -10,6 +10,10 @@ load('jstests/multiVersion/libs/auth_helpers.js');
(function() {
"use strict";
+
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
var replTest = new ReplSetTest(
{name: 'UserManagementWCSet', nodes: 3, settings: {chainingAllowed: false}});
replTest.startSet();
diff --git a/jstests/sharding/advance_cluster_time_action_type.js b/jstests/sharding/advance_cluster_time_action_type.js
index fac7f803774..1f3f00a2abb 100644
--- a/jstests/sharding/advance_cluster_time_action_type.js
+++ b/jstests/sharding/advance_cluster_time_action_type.js
@@ -5,6 +5,9 @@
(function() {
"use strict";
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
let st = new ShardingTest({
mongos: 1,
diff --git a/jstests/sharding/authCommands.js b/jstests/sharding/authCommands.js
index 8ad74f23db3..efd285869ab 100644
--- a/jstests/sharding/authCommands.js
+++ b/jstests/sharding/authCommands.js
@@ -4,6 +4,9 @@
(function() {
'use strict';
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
load("jstests/replsets/rslib.js");
// Replica set nodes started with --shardsvr do not enable key generation until they are added
diff --git a/jstests/sharding/auth_repl.js b/jstests/sharding/auth_repl.js
index 9e1ddb06873..0c8e976bd48 100644
--- a/jstests/sharding/auth_repl.js
+++ b/jstests/sharding/auth_repl.js
@@ -1,3 +1,6 @@
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
+
var replTest = new ReplSetTest({nodes: 3, useHostName: false, keyFile: 'jstests/libs/key1'});
replTest.startSet({oplogSize: 10});
replTest.initiate();
diff --git a/jstests/sharding/cleanup_orphaned_auth.js b/jstests/sharding/cleanup_orphaned_auth.js
index 4943643c33d..f32a66ee242 100644
--- a/jstests/sharding/cleanup_orphaned_auth.js
+++ b/jstests/sharding/cleanup_orphaned_auth.js
@@ -5,6 +5,9 @@
(function() {
'use strict';
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
function assertUnauthorized(res, msg) {
if (assert._debug && msg)
print("in assert for: " + msg);
diff --git a/jstests/sharding/commands_that_write_accept_wc_configRS.js b/jstests/sharding/commands_that_write_accept_wc_configRS.js
index 1f436cc163b..ba2f3f559c6 100644
--- a/jstests/sharding/commands_that_write_accept_wc_configRS.js
+++ b/jstests/sharding/commands_that_write_accept_wc_configRS.js
@@ -17,6 +17,10 @@ load('jstests/multiVersion/libs/auth_helpers.js');
(function() {
"use strict";
+
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
var st = new ShardingTest({
shards: {
rs0: {nodes: 3, settings: {chainingAllowed: false}},
diff --git a/jstests/sharding/kill_pinned_cursor.js b/jstests/sharding/kill_pinned_cursor.js
index 417ed66817e..d7e4017d273 100644
--- a/jstests/sharding/kill_pinned_cursor.js
+++ b/jstests/sharding/kill_pinned_cursor.js
@@ -9,6 +9,9 @@
(function() {
"use strict";
+ // This test manually simulates a session, which is not compatible with implicit sessions.
+ TestData.disableImplicitSessions = true;
+
const kFailPointName = "waitAfterPinningCursorBeforeGetMoreBatch";
const kFailpointOptions = {shouldCheckForInterrupt: true};
diff --git a/jstests/sharding/kill_sessions.js b/jstests/sharding/kill_sessions.js
index d5bb39213f1..a3ad23139a0 100644
--- a/jstests/sharding/kill_sessions.js
+++ b/jstests/sharding/kill_sessions.js
@@ -3,6 +3,10 @@ load("jstests/libs/kill_sessions.js");
(function() {
'use strict';
+ // TODO SERVER-35447: This test involves killing all sessions, which will not work as expected
+ // if the kill command is sent with an implicit session.
+ TestData.disableImplicitSessions = true;
+
function runTests(needAuth) {
var other = {
rs: true,
diff --git a/jstests/sharding/mongod_returns_no_cluster_time_without_keys.js b/jstests/sharding/mongod_returns_no_cluster_time_without_keys.js
index b9ac2deda07..8cb8fe8f7fb 100644
--- a/jstests/sharding/mongod_returns_no_cluster_time_without_keys.js
+++ b/jstests/sharding/mongod_returns_no_cluster_time_without_keys.js
@@ -9,6 +9,10 @@
(function() {
"use strict";
+ // This test uses authentication and runs commands without authenticating, which is not
+ // compatible with implicit sessions.
+ TestData.disableImplicitSessions = true;
+
load("jstests/multiVersion/libs/multi_rs.js");
// TODO SERVER-32672: remove this flag.
@@ -46,6 +50,7 @@
priRSConn.auth(rUser.username, rUser.password);
const resWithKeys = priRSConn.runCommand({isMaster: 1});
assertContainsValidLogicalTime(resWithKeys);
+ priRSConn.logout();
// Enable the failpoint, remove all keys, and restart the config servers with the failpoint
// still enabled to guarantee there are no keys.
@@ -60,6 +65,7 @@
});
assert(adminDB.system.keys.count() == 0, "expected there to be no keys on the config server");
+ adminDB.logout();
st.configRS.stopSet(null /* signal */, true /* forRestart */);
st.configRS.startSet(
@@ -72,6 +78,7 @@
priRSConn = st.rs0.getPrimary().getDB("admin");
priRSConn.auth(rUser.username, rUser.password);
const resNoKeys = assert.commandWorked(priRSConn.runCommand({isMaster: 1}));
+ priRSConn.logout();
assert.eq(resNoKeys.hasOwnProperty("$clusterTime"), false);
assert.eq(resNoKeys.hasOwnProperty("operationTime"), false);
diff --git a/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js b/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js
index 774c1d7dd01..5ce56f9f546 100644
--- a/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js
+++ b/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js
@@ -24,6 +24,9 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
// TODO SERVER-32672: remove this flag.
TestData.skipGossipingClusterTime = true;
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
+
var options = {rs: true, rsOptions: {nodes: 2}, keyFile: "jstests/libs/key1"};
var st = new ShardingTest({shards: 3, mongos: 1, other: options});
diff --git a/jstests/sharding/mrShardedOutputAuth.js b/jstests/sharding/mrShardedOutputAuth.js
index 3dc02da7072..0536c6a51b9 100644
--- a/jstests/sharding/mrShardedOutputAuth.js
+++ b/jstests/sharding/mrShardedOutputAuth.js
@@ -6,6 +6,9 @@
(function() {
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
function doMapReduce(connection, outputDb) {
// clean output db and run m/r
outputDb.numbers_out.drop();
diff --git a/jstests/sharding/refresh_sessions.js b/jstests/sharding/refresh_sessions.js
index 8199ffb4563..ee4ee125db3 100644
--- a/jstests/sharding/refresh_sessions.js
+++ b/jstests/sharding/refresh_sessions.js
@@ -1,6 +1,9 @@
(function() {
"use strict";
+ // This test makes assumptions about the number of logical sessions.
+ TestData.disableImplicitSessions = true;
+
var sessionsDb = "config";
var refresh = {refreshLogicalSessionCacheNow: 1};
var startSession = {startSession: 1};
diff --git a/jstests/sharding/sessions_collection_auto_healing.js b/jstests/sharding/sessions_collection_auto_healing.js
index 5dcf6d66590..61271bd8dc5 100644
--- a/jstests/sharding/sessions_collection_auto_healing.js
+++ b/jstests/sharding/sessions_collection_auto_healing.js
@@ -3,6 +3,10 @@ load('jstests/libs/sessions_collection.js');
(function() {
"use strict";
+ // This test makes assertions about the number of sessions, which are not compatible with
+ // implicit sessions.
+ TestData.disableImplicitSessions = true;
+
var st = new ShardingTest({shards: 0});
var configSvr = st.configRS.getPrimary();
var configAdmin = configSvr.getDB("admin");
diff --git a/jstests/sharding/sharding_options.js b/jstests/sharding/sharding_options.js
index 8af7bf01c53..190d78a1e94 100644
--- a/jstests/sharding/sharding_options.js
+++ b/jstests/sharding/sharding_options.js
@@ -1,3 +1,6 @@
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
+
var baseName = "jstests_sharding_sharding_options";
load('jstests/libs/command_line/test_parsed_options.js');
diff --git a/jstests/sharding/snapshot_aggregate_mongos.js b/jstests/sharding/snapshot_aggregate_mongos.js
index b0480fc534c..43ce65a7672 100644
--- a/jstests/sharding/snapshot_aggregate_mongos.js
+++ b/jstests/sharding/snapshot_aggregate_mongos.js
@@ -3,6 +3,10 @@
(function() {
"use strict";
+ // This test intentionally runs commands without a logical session id, which is not compatible
+ // with implicit sessions.
+ TestData.disableImplicitSessions = true;
+
load("jstests/libs/global_snapshot_reads_util.js");
const dbName = "test";
diff --git a/jstests/sharding/snapshot_find_mongos.js b/jstests/sharding/snapshot_find_mongos.js
index 92b5b679730..0c7bf4c59f4 100644
--- a/jstests/sharding/snapshot_find_mongos.js
+++ b/jstests/sharding/snapshot_find_mongos.js
@@ -4,6 +4,10 @@
(function() {
"use strict";
+ // This test intentionally runs commands without a logical session id, which is not compatible
+ // with implicit sessions.
+ TestData.disableImplicitSessions = true;
+
load("jstests/libs/global_snapshot_reads_util.js");
const dbName = "test";
diff --git a/src/mongo/shell/mongo.js b/src/mongo/shell/mongo.js
index bfb1e04f7cf..0a78e9db761 100644
--- a/src/mongo/shell/mongo.js
+++ b/src/mongo/shell/mongo.js
@@ -58,7 +58,9 @@ Mongo.prototype.getDB = function(name) {
Mongo.prototype.getDBs = function(driverSession = this._getDefaultSession()) {
var cmdObj = {listDatabases: 1};
- cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ if (driverSession._isExplicit || !jsTest.options().disableImplicitSessions) {
+ cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ }
var res = this.adminCommand(cmdObj);
if (!res.ok)
@@ -75,7 +77,9 @@ Mongo.prototype.adminCommand = function(cmd) {
*/
Mongo.prototype.getLogComponents = function(driverSession = this._getDefaultSession()) {
var cmdObj = {getParameter: 1, logComponentVerbosity: 1};
- cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ if (driverSession._isExplicit || !jsTest.options().disableImplicitSessions) {
+ cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ }
var res = this.adminCommand(cmdObj);
if (!res.ok)
@@ -106,7 +110,9 @@ Mongo.prototype.setLogLevel = function(
}
var cmdObj = {setParameter: 1, logComponentVerbosity: vDoc};
- cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ if (driverSession._isExplicit || !jsTest.options().disableImplicitSessions) {
+ cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
+ }
var res = this.adminCommand(cmdObj);
if (!res.ok)
@@ -426,11 +432,14 @@ Mongo.prototype.startSession = function startSession(options = {}) {
};
Mongo.prototype._getDefaultSession = function getDefaultSession() {
- // We implicitly associate a Mongo connection object with a DriverSession so that tests which
- // call DB.prototype.getMongo() and then Mongo.prototype.getDB() to get a different DB instance
- // are still causally consistent.
+ // We implicitly associate a Mongo connection object with a real session so all requests include
+ // a logical session id. These implicit sessions are intentionally not causally consistent. If
+ // implicit sessions have been globally disabled, a dummy session is used instead of a real one.
if (!this.hasOwnProperty("_defaultSession")) {
- this._defaultSession = new _DummyDriverSession(this);
+ this._defaultSession = _shouldUseImplicitSessions()
+ ? this.startSession({causalConsistency: false})
+ : new _DummyDriverSession(this);
+ this._defaultSession._isExplicit = false;
}
return this._defaultSession;
};
diff --git a/src/mongo/shell/query.js b/src/mongo/shell/query.js
index fcbcd5a39b3..60785e4b417 100644
--- a/src/mongo/shell/query.js
+++ b/src/mongo/shell/query.js
@@ -112,10 +112,11 @@ DBQuery.prototype._exec = function() {
var cmdRes = this._db.runReadCommand(findCmd, null, this._options);
this._cursor = new DBCommandCursor(this._db, cmdRes, this._batchSize);
} else {
- // Note that depending on how SERVER-32064 is implemented, we may need to alter this
- // check to account for implicit sessions, so that exhaust cursors can still be used in
- // the shell.
- if (this._db.getSession().getSessionId() !== null) {
+ // The exhaust cursor option is disallowed under a session because it doesn't work as
+ // expected, but all requests from the shell use implicit sessions, so to allow users
+ // to continue using exhaust cursors through the shell, they are only disallowed with
+ // explicit sessions.
+ if (this._db.getSession()._isExplicit) {
throw new Error("Cannot run a legacy query on a session.");
}
diff --git a/src/mongo/shell/session.js b/src/mongo/shell/session.js
index b7e77d8e9f2..07720d49047 100644
--- a/src/mongo/shell/session.js
+++ b/src/mongo/shell/session.js
@@ -209,7 +209,14 @@ var {
}
function prepareCommandRequest(driverSession, cmdObj) {
- if (serverSupports(kWireVersionSupportingLogicalSession)) {
+ if (serverSupports(kWireVersionSupportingLogicalSession) &&
+ // Always attach sessionId from explicit sessions.
+ (driverSession._isExplicit ||
+ // Check that implicit sessions are not disabled. The client must be using read
+ // commands because aggregations always use runCommand() to establish cursors but
+ // may use OP_GET_MORE (and therefore not have a session id attached) to retrieve
+ // subsequent batches.
+ (!jsTest.options().disableImplicitSessions && client.useReadCommands()))) {
cmdObj = driverSession._serverSession.injectSessionId(cmdObj);
}
@@ -836,6 +843,8 @@ var {
this._serverSession = implMethods.createServerSession(client);
+ this._isExplicit = true;
+
this.getClient = function getClient() {
return client;
};
diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp
index 5a9742d3935..f441f0ba4ab 100644
--- a/src/mongo/shell/shell_utils.cpp
+++ b/src/mongo/shell/shell_utils.cpp
@@ -253,6 +253,10 @@ BSONObj shouldRetryWrites(const BSONObj&, void* data) {
return BSON("" << shellGlobalParams.shouldRetryWrites);
}
+BSONObj shouldUseImplicitSessions(const BSONObj&, void* data) {
+ return BSON("" << true);
+}
+
BSONObj interpreterVersion(const BSONObj& a, void* data) {
uassert(16453, "interpreterVersion accepts no arguments", a.nFields() == 0);
return BSON("" << getGlobalScriptEngine()->getInterpreterVersionString());
@@ -290,6 +294,7 @@ void initScope(Scope& scope) {
scope.injectNative("_writeMode", writeMode);
scope.injectNative("_readMode", readMode);
scope.injectNative("_shouldRetryWrites", shouldRetryWrites);
+ scope.injectNative("_shouldUseImplicitSessions", shouldUseImplicitSessions);
scope.externalSetup();
mongo::shell_utils::installShellUtils(scope);
scope.execSetup(JSFiles::servers);
diff --git a/src/mongo/shell/utils.js b/src/mongo/shell/utils.js
index 3820eac4f36..79c5433b892 100644
--- a/src/mongo/shell/utils.js
+++ b/src/mongo/shell/utils.js
@@ -313,7 +313,8 @@ jsTestOptions = function() {
skipCheckDBHashes: TestData.skipCheckDBHashes || false,
traceExceptions: TestData.hasOwnProperty("traceExceptions") ? TestData.traceExceptions
: true,
- transactionLifetimeLimitSeconds: TestData.transactionLifetimeLimitSeconds
+ transactionLifetimeLimitSeconds: TestData.transactionLifetimeLimitSeconds,
+ disableImplicitSessions: TestData.disableImplicitSessions || false,
});
}
return _jsTestOptions;
@@ -559,6 +560,16 @@ if (typeof _shouldRetryWrites === 'undefined') {
};
}
+if (typeof _shouldUseImplicitSessions === 'undefined') {
+ // We ensure the _shouldUseImplicitSessions() function is always defined, in case the JavaScript
+ // engine is being used from someplace other than the mongo shell (e.g. map-reduce). If the
+ // function was not defined, implicit sessions are disabled to prevent unnecessary sessions from
+ // being created.
+ _shouldUseImplicitSessions = function _shouldUseImplicitSessions() {
+ return false;
+ };
+}
+
shellPrintHelper = function(x) {
if (typeof(x) == "undefined") {
// Make sure that we have a db var before we use it