diff options
-rw-r--r-- | src/mongo/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/SConscript | 22 | ||||
-rw-r--r-- | src/mongo/db/logical_session_cache_factory_mongod.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/sessions_collection_config_server.h | 2 | ||||
-rw-r--r-- | src/mongo/s/SConscript | 18 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache_test_fixture.cpp | 4 | ||||
-rw-r--r-- | src/mongo/s/server.cpp | 2 | ||||
-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.cpp | 207 |
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 |