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-09-27 22:51:17 -0400
commit2e98a18d2122a30549e089bf30b96ac0c3bbf85d (patch)
tree716ac83efa19cdc60810d1f200cc4047f3627547
parent241515814f8bd5dbc7ad3a0682dd531a965537cb (diff)
downloadmongo-2e98a18d2122a30549e089bf30b96ac0c3bbf85d.tar.gz
SERVER-32064 Requests from the shell should use an implicit session by default
(cherry picked from commit 8817328f87564a29e9be2ed1a746cf40e89587eb) SERVER-32064 Disable implicit sessions when checking db version during connect() (cherry picked from commit 8c5002b06fd737f75941a73785ce75e3ca7f5ce1)
-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--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.js8
-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.js3
-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.js9
-rw-r--r--jstests/core/evalb.js2
-rw-r--r--jstests/core/mr_killop.js18
-rw-r--r--jstests/core/profile1.js7
-rw-r--r--jstests/core/profile3.js2
-rw-r--r--jstests/core/user_management_helpers.js9
-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_sessions.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/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/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.js4
-rw-r--r--jstests/replsets/rollback_transaction_table.js4
-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.js4
-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_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--src/mongo/shell/mongo.js46
-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.js11
70 files changed, 612 insertions, 36 deletions
diff --git a/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml b/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml
index a04502f765e..cbb4343774f 100644
--- a/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml
+++ b/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml
@@ -155,8 +155,21 @@ selector:
- jstests/core/explain_upsert.js
# The `dbstats` command builds in-memory structures that are not causally consistent.
- jstests/core/dbstats.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/indexes_on_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
+ # TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ - creates_and_authenticates_user
- requires_collstats
##
# The next tag corresponds to the special error thrown by the set_read_preference_secondary.js
@@ -167,6 +180,8 @@ selector:
# "Cowardly refusing to run test with overridden read preference when it reads from a
# non-replicated collection: ..."
- assumes_read_preference_unchanged
+ # This suite runs as the root user, but eval requires universal privileges with authentication on.
+ - requires_eval_command
executor:
archive:
@@ -190,7 +205,7 @@ executor:
const res = db.runCommand({
createUser: username,
pwd: password,
- roles: ["dbOwner"],
+ roles: [{role: "root", db: jsTest.options().authenticationDatabase}]
});
if (res.ok === 1) {
@@ -201,7 +216,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 198fb6d91a1..88845fcade2 100644
--- a/buildscripts/resmokeconfig/suites/core_auth.yml
+++ b/buildscripts/resmokeconfig/suites/core_auth.yml
@@ -18,6 +18,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 b92121d12eb..c5d6709947f 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/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 17d656c9f05..d1fd44fe597 100644
--- a/jstests/auth/authentication_restrictions.js
+++ b/jstests/auth/authentication_restrictions.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 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 80e9df6c794..759d874de3c 100644
--- a/jstests/auth/authentication_restrictions_role.js
+++ b/jstests/auth/authentication_restrictions_role.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 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 fc4e39089ba..c688f6e41b0 100644
--- a/jstests/auth/basic_role_auth.js
+++ b/jstests/auth/basic_role_auth.js
@@ -3,6 +3,12 @@
* environment. This file covers all types of operations except commands.
*/
+// This test runs connectionStatus on a connection with no logged in users and auth on, which is
+// rejected when run with an implicit session id.
+// TODO SERVER-34820: Remove once connectionStatus can be run with no users authenticated in an
+// implicit session.
+TestData.disableImplicitSessions = true;
+
/**
* Data structure that contains all the users that are going to be used in the tests.
* The structure is as follows:
@@ -492,7 +498,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 14da86a505b..db3d3c3092d 100644
--- a/jstests/auth/commands_builtin_roles.js
+++ b/jstests/auth/commands_builtin_roles.js
@@ -7,6 +7,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 3c8de27192f..765203fe1e4 100644
--- a/jstests/auth/commands_user_defined_roles.js
+++ b/jstests/auth/commands_user_defined_roles.js
@@ -7,6 +7,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 0bad123cb98..6969600fcd2 100644
--- a/jstests/auth/copyauth.js
+++ b/jstests/auth/copyauth.js
@@ -194,6 +194,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 569376740fb..2caf8a03049 100644
--- a/jstests/auth/getMore.js
+++ b/jstests/auth/getMore.js
@@ -2,6 +2,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 146f3253282..4cbd5df0579 100644
--- a/jstests/auth/kill_cursors.js
+++ b/jstests/auth/kill_cursors.js
@@ -2,6 +2,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 05914b2c2e6..fdb40952393 100644
--- a/jstests/auth/list_all_local_sessions.js
+++ b/jstests/auth/list_all_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 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 763178e9ac1..150ae957ba0 100644
--- a/jstests/auth/list_all_sessions.js
+++ b/jstests/auth/list_all_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 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 40cc66d991e..af4fce43aeb 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 b130999a3ef..2b12f77da91 100644
--- a/jstests/auth/list_sessions.js
+++ b/jstests/auth/list_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 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 c397ff1ad4b..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");
diff --git a/jstests/auth/repl_auth.js b/jstests/auth/repl_auth.js
index aa851840bc5..a4958d5f101 100644
--- a/jstests/auth/repl_auth.js
+++ b/jstests/auth/repl_auth.js
@@ -64,4 +64,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 dd83b8bf273..d736a17b2aa 100644
--- a/jstests/auth/resource_pattern_matching.js
+++ b/jstests/auth/resource_pattern_matching.js
@@ -2,6 +2,11 @@
* Tests that resource pattern matching rules work as expected.
*/
+// 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 3752a3aa678..fdd093e63ee 100644
--- a/jstests/auth/secondary_invalidation.js
+++ b/jstests/auth/secondary_invalidation.js
@@ -30,4 +30,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 4134a983ce9..dc1847d4873 100644
--- a/jstests/auth/views_authz.js
+++ b/jstests/auth/views_authz.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 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..536443aaf9b 100644
--- a/jstests/core/connection_status.js
+++ b/jstests/core/connection_status.js
@@ -1,8 +1,9 @@
// @tags: [
-// requires_non_retryable_commands,
-// requires_auth,
-// assumes_write_concern_unchanged
-// ]
+// assumes_write_concern_unchanged,
+// creates_and_authenticates_user,
+// requires_auth,
+// requires_non_retryable_commands,
+// ]
// Tests the connectionStatus command
(function() {
diff --git a/jstests/core/evalb.js b/jstests/core/evalb.js
index d92573eef1c..96f2bbd7358 100644
--- a/jstests/core/evalb.js
+++ b/jstests/core/evalb.js
@@ -2,6 +2,8 @@
// 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,
diff --git a/jstests/core/mr_killop.js b/jstests/core/mr_killop.js
index 25675fa64ab..b2afe735e01 100644
--- a/jstests/core/mr_killop.js
+++ b/jstests/core/mr_killop.js
@@ -18,6 +18,21 @@ function debug(x) {
function op(childLoop) {
p = db.currentOp().inprog;
debug(p);
+
+ let isMapReduce = function(op) {
+ if (!op.command) {
+ return false;
+ }
+ let cmdBody = op.command;
+ if (cmdBody.$truncated) {
+ let stringifiedCmd = cmdBody.$truncated;
+ print('str: ' + tojson(stringifiedCmd));
+ return stringifiedCmd.search('mapreduce') >= 0 &&
+ stringifiedCmd.search('jstests_mr_killop') >= 0;
+ }
+ return cmdBody.mapreduce && cmdBody.mapreduce == "jstests_mr_killop";
+ };
+
for (var i in p) {
var o = p[i];
// Identify a map/reduce or where distinct operation by its collection, whether or not
@@ -28,8 +43,7 @@ function op(childLoop) {
return o.opid;
}
} else {
- if ((o.active || o.waitingForLock) && o.command && o.command.mapreduce &&
- o.command.mapreduce == "jstests_mr_killop") {
+ if ((o.active || o.waitingForLock) && isMapReduce(o)) {
return o.opid;
}
}
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 3a22bd1f952..02c6d272f8e 100644
--- a/jstests/core/profile3.js
+++ b/jstests/core/profile3.js
@@ -1,4 +1,4 @@
-
+// @tags: [creates_and_authenticates_user]
// special db so that it can be run in parallel tests
var stddb = db;
var db = db.getSisterDB("profile3");
diff --git a/jstests/core/user_management_helpers.js b/jstests/core/user_management_helpers.js
index 2b5abe9a388..65d5a37cd43 100644
--- a/jstests/core/user_management_helpers.js
+++ b/jstests/core/user_management_helpers.js
@@ -1,8 +1,9 @@
// @tags: [
-// requires_non_retryable_commands,
-// requires_auth,
-// assumes_write_concern_unchanged
-// ]
+// assumes_write_concern_unchanged,
+// creates_and_authenticates_user,
+// requires_auth,
+// requires_non_retryable_commands,
+// ]
// This test is a basic sanity check of the shell helpers for manipulating user objects
// It is not a comprehensive test of the functionality of the user manipulation commands
diff --git a/jstests/multiVersion/mixed_storage_version_replication.js b/jstests/multiVersion/mixed_storage_version_replication.js
index da0a4309bcc..a62f66a3bb6 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");
@@ -567,6 +572,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",
@@ -593,6 +602,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 887f97b567d..6c4e6ba4a54 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 3dbde751fe4..ff276cc3af6 100644
--- a/jstests/noPassthrough/currentop_query.js
+++ b/jstests/noPassthrough/currentop_query.js
@@ -5,6 +5,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;
+
/**
* @param {string} readMode - The read mode to use for the parallel shell. This allows
* testing currentOp() output for both OP_QUERY and OP_GET_MORE queries, as well as "find" and
diff --git a/jstests/noPassthrough/end_sessions_command.js b/jstests/noPassthrough/end_sessions_command.js
index 07bc9316494..863d14f51ff 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_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/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 2348b8cf2a4..d601c06aea0 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 74e7ff3ad8a..3e3bd3b7b1e 100644
--- a/jstests/noPassthrough/shell_can_use_read_concern.js
+++ b/jstests/noPassthrough/shell_can_use_read_concern.js
@@ -5,6 +5,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/start_session_command.js b/jstests/noPassthrough/start_session_command.js
index a22016053b9..b13b63fb3fb 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 5cce0d17f2f..c4ef142dc27 100644
--- a/jstests/noPassthrough/transaction_reaper.js
+++ b/jstests/noPassthrough/transaction_reaper.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;
+
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 e2d51bd27e5..d57b35a4d28 100644
--- a/jstests/noPassthrough/verify_session_cache_updates.js
+++ b/jstests/noPassthrough/verify_session_cache_updates.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;
+
function runTest(conn) {
for (var i = 0; i < 10; ++i) {
conn.getDB("test").test.save({a: i});
diff --git a/jstests/replsets/auth1.js b/jstests/replsets/auth1.js
index 211beb9016e..ddf0fb9b193 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 338db1bd817..caae49a5801 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 4326437b50b..1fcc8b809b5 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 b30f9833131..1b6916e6d4a 100644
--- a/jstests/replsets/rollback_auth.js
+++ b/jstests/replsets/rollback_auth.js
@@ -12,6 +12,10 @@
(function() {
"use strict";
+
+ // 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/rollback_transaction_table.js b/jstests/replsets/rollback_transaction_table.js
index 6c32be314e8..cd740e41a4b 100644
--- a/jstests/replsets/rollback_transaction_table.js
+++ b/jstests/replsets/rollback_transaction_table.js
@@ -20,6 +20,10 @@
(function() {
"use strict";
+ // This test drops a collection in the config database, which is not allowed under a session. It
+ // also manually simulates a session, which is 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/replsets/sessions_collection_auto_healing.js b/jstests/replsets/sessions_collection_auto_healing.js
index 0b7cd9ef612..c56fb24639a 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: [{rsConfig: {votes: 1, priority: 1}}, {rsConfig: {votes: 0, priority: 0}}]
diff --git a/jstests/replsets/user_management_wc.js b/jstests/replsets/user_management_wc.js
index c8ac612b597..8eba68a4075 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 d01357ec338..87679080b2d 100644
--- a/jstests/sharding/advance_cluster_time_action_type.js
+++ b/jstests/sharding/advance_cluster_time_action_type.js
@@ -5,8 +5,12 @@
(function() {
"use strict";
+ // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+ TestData.disableImplicitSessions = true;
+
let st = new ShardingTest(
{mongos: 1, config: 1, shards: 1, keyFile: 'jstests/libs/key1', mongosWaitsForKeys: true});
+
let adminDB = st.s.getDB('admin');
assert.commandWorked(adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
diff --git a/jstests/sharding/authCommands.js b/jstests/sharding/authCommands.js
index 497a5748466..1ff86edb039 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");
var st = new ShardingTest({
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 834ad613a38..941dafcd44d 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 06326fa7403..ea864435604 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_sessions.js b/jstests/sharding/kill_sessions.js
index 2757ef8935d..2af0a6a0658 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 3c9cf3e6af7..eab329791dd 100644
--- a/jstests/sharding/mongod_returns_no_cluster_time_without_keys.js
+++ b/jstests/sharding/mongod_returns_no_cluster_time_without_keys.js
@@ -8,6 +8,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.
@@ -48,6 +52,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.
@@ -62,6 +67,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(
@@ -74,6 +80,7 @@
priRSConn.auth(rUser.username, rUser.password);
const resNoKeys = priRSConn.runCommand({isMaster: 1});
assert.commandWorked(resNoKeys);
+ 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 a5ae6c62aa6..b8e4e02a279 100644
--- a/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js
+++ b/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js
@@ -15,6 +15,9 @@
// shard does not have a primary.
TestData.skipCheckingUUIDsConsistentAcrossCluster = 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 93164e5e128..63b36a39f4d 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/src/mongo/shell/mongo.js b/src/mongo/shell/mongo.js
index a7c6bf82b76..faf2b624b66 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)
@@ -257,13 +263,22 @@ connect = function(url, user, pass) {
}
}
- // Check server version
- var serverVersion = db.version();
- chatty("MongoDB server version: " + serverVersion);
-
- var shellVersion = version();
- if (serverVersion.slice(0, 3) != shellVersion.slice(0, 3)) {
- chatty("WARNING: shell and server versions do not match");
+ // Implicit sessions should not be used when opening a connection. In particular, the buildInfo
+ // command is erroneously marked as requiring auth in MongoDB 3.6 and therefore fails if a
+ // logical session id is included in the request.
+ const originalTestData = TestData;
+ TestData = Object.merge(originalTestData, {disableImplicitSessions: true});
+ try {
+ // Check server version
+ var serverVersion = db.version();
+ chatty("MongoDB server version: " + serverVersion);
+
+ var shellVersion = version();
+ if (serverVersion.slice(0, 3) != shellVersion.slice(0, 3)) {
+ chatty("WARNING: shell and server versions do not match");
+ }
+ } finally {
+ TestData = originalTestData;
}
return db;
@@ -426,11 +441,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 479668e41c4..864ef774e3a 100644
--- a/src/mongo/shell/query.js
+++ b/src/mongo/shell/query.js
@@ -116,10 +116,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 c3d790346f5..ecd80b288cb 100644
--- a/src/mongo/shell/session.js
+++ b/src/mongo/shell/session.js
@@ -199,7 +199,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);
}
@@ -591,6 +598,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 c13f6291636..196e4060523 100644
--- a/src/mongo/shell/shell_utils.cpp
+++ b/src/mongo/shell/shell_utils.cpp
@@ -217,6 +217,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());
@@ -253,6 +257,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 c6c00fcf0ac..edcd73f1b0c 100644
--- a/src/mongo/shell/utils.js
+++ b/src/mongo/shell/utils.js
@@ -298,6 +298,7 @@ jsTestOptions = function() {
logRetryAttempts: TestData.logRetryAttempts || false,
connectionString: TestData.connectionString || "",
skipCheckDBHashes: TestData.skipCheckDBHashes || false,
+ disableImplicitSessions: TestData.disableImplicitSessions || false,
});
}
return _jsTestOptions;
@@ -543,6 +544,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