summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/SConscript2
-rw-r--r--src/mongo/db/SConscript22
-rw-r--r--src/mongo/db/logical_session_cache_factory_mongod.cpp2
-rw-r--r--src/mongo/db/sessions_collection_config_server.h2
-rw-r--r--src/mongo/s/SConscript18
-rw-r--r--src/mongo/s/catalog_cache_test_fixture.cpp4
-rw-r--r--src/mongo/s/server.cpp2
-rw-r--r--src/mongo/s/sessions_collection_sharded.cpp (renamed from src/mongo/db/sessions_collection_sharded.cpp)6
-rw-r--r--src/mongo/s/sessions_collection_sharded.h (renamed from src/mongo/db/sessions_collection_sharded.h)0
-rw-r--r--src/mongo/s/sessions_collection_sharded_test.cpp207
10 files changed, 238 insertions, 27 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index ebb3149f3ac..074207fcda5 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -556,7 +556,6 @@ mongos = env.Program(
'db/server_options_base',
'db/service_liaison_mongos',
'db/session_catalog',
- 'db/sessions_collection_sharded',
'db/startup_warnings_common',
'db/stats/counters',
'db/windows_options' if env.TargetOSIs('windows') else [],
@@ -566,6 +565,7 @@ mongos = env.Program(
's/coreshard',
's/is_mongos',
's/query/cluster_cursor_cleanup_job',
+ 's/sessions_collection_sharded',
's/sharding_egress_metadata_hook_for_mongos',
's/sharding_initialization',
's/sharding_router_api',
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index 186c683abfa..561122013e4 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -1333,22 +1333,6 @@ env.Library(
)
env.Library(
- target='sessions_collection_sharded',
- source=[
- 'sessions_collection_sharded.cpp',
- ],
- LIBDEPS=[
- '$BUILD_DIR/mongo/base',
- 'logical_session_id',
- 'sessions_collection',
- ],
- LIBDEPS_PRIVATE=[
- '$BUILD_DIR/mongo/s/sharding_api',
- 'sessions_collection_rs',
- ],
-)
-
-env.Library(
target='sessions_collection_config_server',
source=[
'sessions_collection_config_server.cpp',
@@ -1356,9 +1340,9 @@ env.Library(
LIBDEPS=[
'$BUILD_DIR/mongo/s/client/sharding_client',
'$BUILD_DIR/mongo/s/coreshard',
+ '$BUILD_DIR/mongo/s/sessions_collection_sharded',
'dbdirectclient',
- 'sessions_collection',
- 'sessions_collection_sharded',
+ 'sessions_collection'
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/s/sharding_router_api',
@@ -1431,12 +1415,12 @@ envWithAsio.Library(
'logical_session_cache_factory_mongod.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/s/sessions_collection_sharded',
'logical_session_cache',
'logical_session_cache_impl',
'service_liaison_mongod',
'sessions_collection_config_server',
'sessions_collection_rs',
- 'sessions_collection_sharded',
'sessions_collection_standalone',
],
LIBDEPS_PRIVATE=[
diff --git a/src/mongo/db/logical_session_cache_factory_mongod.cpp b/src/mongo/db/logical_session_cache_factory_mongod.cpp
index 0bde403ab26..d95858462ef 100644
--- a/src/mongo/db/logical_session_cache_factory_mongod.cpp
+++ b/src/mongo/db/logical_session_cache_factory_mongod.cpp
@@ -40,8 +40,8 @@
#include "mongo/db/session_catalog_mongod.h"
#include "mongo/db/sessions_collection_config_server.h"
#include "mongo/db/sessions_collection_rs.h"
-#include "mongo/db/sessions_collection_sharded.h"
#include "mongo/db/sessions_collection_standalone.h"
+#include "mongo/s/sessions_collection_sharded.h"
namespace mongo {
diff --git a/src/mongo/db/sessions_collection_config_server.h b/src/mongo/db/sessions_collection_config_server.h
index 2deeac82549..9f09df55117 100644
--- a/src/mongo/db/sessions_collection_config_server.h
+++ b/src/mongo/db/sessions_collection_config_server.h
@@ -29,8 +29,8 @@
#pragma once
-#include "mongo/db/sessions_collection_sharded.h"
#include "mongo/platform/mutex.h"
+#include "mongo/s/sessions_collection_sharded.h"
namespace mongo {
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index 9909f41fe6a..4adfd50ab8e 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -436,6 +436,22 @@ env.Library(
]
)
+env.Library(
+ target='sessions_collection_sharded',
+ source=[
+ 'sessions_collection_sharded.cpp',
+ ],
+ LIBDEPS=[
+ '$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/logical_session_id',
+ '$BUILD_DIR/mongo/db/sessions_collection',
+ ],
+ LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/sessions_collection_rs',
+ 'sharding_api',
+ ],
+)
+
env.CppUnitTest(
target='s_test',
source=[
@@ -475,6 +491,7 @@ env.CppUnitTest(
'request_types/split_chunk_request_test.cpp',
'request_types/update_zone_key_range_request_test.cpp',
'routing_table_history_test.cpp',
+ 'sessions_collection_sharded_test.cpp',
'shard_id_test.cpp',
'shard_key_pattern_test.cpp',
'sharding_task_executor_test.cpp',
@@ -502,6 +519,7 @@ env.CppUnitTest(
'cluster_last_error_info',
'common_s',
'coreshard',
+ 'sessions_collection_sharded',
'shard_server_test_fixture',
'sharding_router_test_fixture',
'sharding_task_executor',
diff --git a/src/mongo/s/catalog_cache_test_fixture.cpp b/src/mongo/s/catalog_cache_test_fixture.cpp
index 702e84c7a3c..302df27fb68 100644
--- a/src/mongo/s/catalog_cache_test_fixture.cpp
+++ b/src/mongo/s/catalog_cache_test_fixture.cpp
@@ -211,7 +211,9 @@ CachedCollectionRoutingInfo CatalogCacheTestFixture::loadRoutingTableWithTwoChun
auto future = scheduleRoutingInfoForcedRefresh(nss);
// Mock the expected config server queries.
- expectGetDatabase(nss);
+ if (!nss.isAdminDB() && !nss.isConfigDB()) {
+ expectGetDatabase(nss);
+ }
expectGetCollection(nss, epoch, shardKeyPattern);
expectGetCollection(nss, epoch, shardKeyPattern);
expectFindSendBSONObjVector(kConfigHostAndPort, [&]() {
diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp
index 448e12ba7fe..1c2e7b94545 100644
--- a/src/mongo/s/server.cpp
+++ b/src/mongo/s/server.cpp
@@ -67,7 +67,6 @@
#include "mongo/db/service_context.h"
#include "mongo/db/service_liaison_mongos.h"
#include "mongo/db/session_killer.h"
-#include "mongo/db/sessions_collection_sharded.h"
#include "mongo/db/startup_warnings_common.h"
#include "mongo/db/wire_version.h"
#include "mongo/executor/task_executor_pool.h"
@@ -90,6 +89,7 @@
#include "mongo/s/query/cluster_cursor_manager.h"
#include "mongo/s/service_entry_point_mongos.h"
#include "mongo/s/session_catalog_router.h"
+#include "mongo/s/sessions_collection_sharded.h"
#include "mongo/s/sharding_egress_metadata_hook_for_mongos.h"
#include "mongo/s/sharding_initialization.h"
#include "mongo/s/sharding_uptime_reporter.h"
diff --git a/src/mongo/db/sessions_collection_sharded.cpp b/src/mongo/s/sessions_collection_sharded.cpp
index df1bb8c54dd..d41f71bd617 100644
--- a/src/mongo/db/sessions_collection_sharded.cpp
+++ b/src/mongo/s/sessions_collection_sharded.cpp
@@ -29,7 +29,7 @@
#include "mongo/platform/basic.h"
-#include "mongo/db/sessions_collection_sharded.h"
+#include "mongo/s/sessions_collection_sharded.h"
#include "mongo/db/matcher/extensions_callback_noop.h"
#include "mongo/db/operation_context.h"
@@ -143,7 +143,7 @@ void SessionsCollectionSharded::refreshSessions(OperationContext* opCtx,
BatchWriteExecStats stats;
ClusterWriter::write(opCtx, request, &stats, &response);
- return response.toStatus();
+ uassertStatusOK(response.toStatus());
};
_doRefresh(NamespaceString::kLogicalSessionsNamespace,
@@ -162,7 +162,7 @@ void SessionsCollectionSharded::removeRecords(OperationContext* opCtx,
BatchWriteExecStats stats;
ClusterWriter::write(opCtx, request, &stats, &response);
- return response.toStatus();
+ uassertStatusOK(response.toStatus());
};
_doRemove(NamespaceString::kLogicalSessionsNamespace,
diff --git a/src/mongo/db/sessions_collection_sharded.h b/src/mongo/s/sessions_collection_sharded.h
index c43c1b67fa6..c43c1b67fa6 100644
--- a/src/mongo/db/sessions_collection_sharded.h
+++ b/src/mongo/s/sessions_collection_sharded.h
diff --git a/src/mongo/s/sessions_collection_sharded_test.cpp b/src/mongo/s/sessions_collection_sharded_test.cpp
new file mode 100644
index 00000000000..ea2a7c29fdf
--- /dev/null
+++ b/src/mongo/s/sessions_collection_sharded_test.cpp
@@ -0,0 +1,207 @@
+/**
+ * Copyright (C) 2020-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/bson/bsonobjbuilder.h"
+#include "mongo/client/remote_command_targeter_factory_mock.h"
+#include "mongo/client/remote_command_targeter_mock.h"
+#include "mongo/db/commands.h"
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/logical_session_id.h"
+#include "mongo/db/s/sharding_state.h"
+#include "mongo/s/catalog/type_shard.h"
+#include "mongo/s/catalog_cache_test_fixture.h"
+#include "mongo/s/client/shard_registry.h"
+#include "mongo/s/session_catalog_router.h"
+#include "mongo/s/sessions_collection_sharded.h"
+#include "mongo/s/sharding_router_test_fixture.h"
+#include "mongo/s/stale_exception.h"
+#include "mongo/s/write_ops/batched_command_request.h"
+#include "mongo/s/write_ops/batched_command_response.h"
+#include "mongo/unittest/unittest.h"
+#include "mongo/util/concurrency/thread_pool.h"
+
+namespace mongo {
+namespace {
+
+using executor::RemoteCommandRequest;
+
+LogicalSessionRecord makeRecord(Date_t time = Date_t::now()) {
+ auto record = makeLogicalSessionRecordForTest();
+ record.setLastUse(time);
+ return record;
+}
+
+/**
+ * Mimics a two shards backend.
+ */
+class SessionsCollectionShardedTest : public CatalogCacheTestFixture {
+public:
+ SessionsCollectionShardedTest() = default;
+ ~SessionsCollectionShardedTest() = default;
+
+ void setUp() override {
+ CatalogCacheTestFixture::setUp();
+
+ _shards = {std::move(setupNShards(2))};
+ }
+
+ SessionsCollectionSharded _collection;
+ std::vector<ShardType> _shards;
+};
+
+TEST_F(SessionsCollectionShardedTest, RefreshOneSessionOKTest) {
+ // Set up routing table for the logical sessions collection.
+ loadRoutingTableWithTwoChunksAndTwoShardsImpl(NamespaceString::kLogicalSessionsNamespace,
+ BSON("_id" << 1));
+ auto future = launchAsync([&] {
+ auto now = Date_t::now();
+ auto thePast = now - Minutes(5);
+
+ auto record1 = makeRecord(thePast);
+ _collection.refreshSessions(operationContext(), {record1});
+ });
+
+ onCommandForPoolExecutor([&](const RemoteCommandRequest& request) {
+ BatchedCommandResponse response;
+ response.setStatus(Status::OK());
+ response.setNModified(1);
+
+ return response.toBSON();
+ });
+
+ future.default_timed_get();
+}
+
+
+TEST_F(SessionsCollectionShardedTest, RefreshOneSessionStatusErrTest) {
+ // Set up routing table for the logical sessions collection.
+ loadRoutingTableWithTwoChunksAndTwoShardsImpl(NamespaceString::kLogicalSessionsNamespace,
+ BSON("_id" << 1));
+ auto future = launchAsync([&] {
+ auto now = Date_t::now();
+ auto thePast = now - Minutes(5);
+
+ auto record1 = makeRecord(thePast);
+ _collection.refreshSessions(operationContext(), {record1});
+ });
+
+ onCommandForPoolExecutor([&](const RemoteCommandRequest& request) {
+ return Status(ErrorCodes::BSONObjectTooLarge, "BSON size limit hit while parsing message");
+ });
+
+ ASSERT_THROWS_CODE(future.default_timed_get(), DBException, ErrorCodes::BSONObjectTooLarge);
+}
+
+TEST_F(SessionsCollectionShardedTest, RefreshOneSessionWriteErrTest) {
+ // Set up routing table for the logical sessions collection.
+ loadRoutingTableWithTwoChunksAndTwoShardsImpl(NamespaceString::kLogicalSessionsNamespace,
+ BSON("_id" << 1));
+ auto future = launchAsync([&] {
+ auto now = Date_t::now();
+ auto thePast = now - Minutes(5);
+
+ auto record1 = makeRecord(thePast);
+ _collection.refreshSessions(operationContext(), {record1});
+ });
+
+ onCommandForPoolExecutor([&](const RemoteCommandRequest& request) {
+ BatchedCommandResponse response;
+ response.setStatus(Status::OK());
+ response.setNModified(0);
+ response.addToErrDetails([&] {
+ WriteErrorDetail* errDetail = new WriteErrorDetail();
+ errDetail->setIndex(0);
+ errDetail->setStatus({ErrorCodes::NotMaster, "not master"});
+ return errDetail;
+ }());
+ return response.toBSON();
+ });
+
+ ASSERT_THROWS_CODE(future.default_timed_get(), DBException, ErrorCodes::NotMaster);
+}
+
+TEST_F(SessionsCollectionShardedTest, RemoveOneSessionOKTest) {
+ // Set up routing table for the logical sessions collection.
+ loadRoutingTableWithTwoChunksAndTwoShardsImpl(NamespaceString::kLogicalSessionsNamespace,
+ BSON("_id" << 1));
+ auto future = launchAsync(
+ [&] { _collection.removeRecords(operationContext(), {makeLogicalSessionIdForTest()}); });
+
+ onCommandForPoolExecutor([&](const RemoteCommandRequest& request) {
+ BatchedCommandResponse response;
+ response.setStatus(Status::OK());
+ response.setNModified(0);
+ response.setNModified(1);
+ return response.toBSON();
+ });
+
+ future.default_timed_get();
+}
+
+TEST_F(SessionsCollectionShardedTest, RemoveOneSessionStatusErrTest) {
+ // Set up routing table for the logical sessions collection.
+ loadRoutingTableWithTwoChunksAndTwoShardsImpl(NamespaceString::kLogicalSessionsNamespace,
+ BSON("_id" << 1));
+ auto future = launchAsync(
+ [&] { _collection.removeRecords(operationContext(), {makeLogicalSessionIdForTest()}); });
+
+ onCommandForPoolExecutor([&](const RemoteCommandRequest& request) {
+ return Status(ErrorCodes::BSONObjectTooLarge, "BSON size limit hit while parsing message");
+ });
+
+ ASSERT_THROWS_CODE(future.default_timed_get(), DBException, ErrorCodes::BSONObjectTooLarge);
+}
+
+TEST_F(SessionsCollectionShardedTest, RemoveOneSessionWriteErrTest) {
+ // Set up routing table for the logical sessions collection.
+ loadRoutingTableWithTwoChunksAndTwoShardsImpl(NamespaceString::kLogicalSessionsNamespace,
+ BSON("_id" << 1));
+ auto future = launchAsync(
+ [&] { _collection.removeRecords(operationContext(), {makeLogicalSessionIdForTest()}); });
+
+ onCommandForPoolExecutor([&](const RemoteCommandRequest& request) {
+ BatchedCommandResponse response;
+ response.setStatus(Status::OK());
+ response.setNModified(0);
+ response.addToErrDetails([&] {
+ WriteErrorDetail* errDetail = new WriteErrorDetail();
+ errDetail->setIndex(0);
+ errDetail->setStatus({ErrorCodes::NotMaster, "not master"});
+ return errDetail;
+ }());
+ return response.toBSON();
+ });
+
+ ASSERT_THROWS_CODE(future.default_timed_get(), DBException, ErrorCodes::NotMaster);
+}
+
+} // namespace
+} // namespace mongo \ No newline at end of file