summaryrefslogtreecommitdiff
path: root/src/mongo/db/s/collection_range_deleter_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/s/collection_range_deleter_test.cpp')
-rw-r--r--src/mongo/db/s/collection_range_deleter_test.cpp298
1 files changed, 123 insertions, 175 deletions
diff --git a/src/mongo/db/s/collection_range_deleter_test.cpp b/src/mongo/db/s/collection_range_deleter_test.cpp
index 2927379ff1c..a5b4813d5e6 100644
--- a/src/mongo/db/s/collection_range_deleter_test.cpp
+++ b/src/mongo/db/s/collection_range_deleter_test.cpp
@@ -30,55 +30,84 @@
#include "mongo/db/s/collection_range_deleter.h"
+#include "mongo/bson/bsonobj.h"
+#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/client/query.h"
+#include "mongo/client/remote_command_targeter_mock.h"
#include "mongo/db/client.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/keypattern.h"
#include "mongo/db/repl/replication_coordinator_global.h"
#include "mongo/db/repl/replication_coordinator_mock.h"
#include "mongo/db/s/collection_sharding_state.h"
#include "mongo/db/s/sharding_state.h"
#include "mongo/db/service_context_d_test_fixture.h"
+#include "mongo/s/catalog/dist_lock_catalog_impl.h"
+#include "mongo/s/catalog/dist_lock_manager_mock.h"
+#include "mongo/s/catalog/sharding_catalog_client_mock.h"
#include "mongo/s/chunk_version.h"
+#include "mongo/s/client/shard_registry.h"
+#include "mongo/s/sharding_mongod_test_fixture.h"
namespace mongo {
using unittest::assertGet;
-
-const NamespaceString kNamespaceString = NamespaceString("foo", "bar");
+const NamespaceString kNss = NamespaceString("foo", "bar");
const std::string kPattern = "_id";
const BSONObj kKeyPattern = BSON(kPattern << 1);
+const std::string kShardName{"a"};
+const HostAndPort dummyHost("dummy", 123);
-class CollectionRangeDeleterTest : public ServiceContextMongoDTest {
+class CollectionRangeDeleterTest : public ShardingMongodTestFixture {
protected:
- ServiceContext::UniqueOperationContext _opCtx;
- MetadataManager* _metadataManager;
- std::unique_ptr<DBDirectClient> _dbDirectClient;
+ bool next(CollectionRangeDeleter& rangeDeleter, int maxToDelete) {
+ return CollectionRangeDeleter::cleanUpNextRange(
+ operationContext(), kNss, maxToDelete, &rangeDeleter);
+ }
+ std::shared_ptr<RemoteCommandTargeterMock> configTargeter() {
+ return RemoteCommandTargeterMock::get(shardRegistry()->getConfigShard()->getTargeter());
+ }
- OperationContext* operationContext();
private:
void setUp() override;
void tearDown() override;
+
+ std::unique_ptr<DistLockCatalog> makeDistLockCatalog(ShardRegistry* shardRegistry) override {
+ invariant(shardRegistry);
+ return stdx::make_unique<DistLockCatalogImpl>(shardRegistry);
+ }
+
+ std::unique_ptr<DistLockManager> makeDistLockManager(
+ std::unique_ptr<DistLockCatalog> distLockCatalog) override {
+ return stdx::make_unique<DistLockManagerMock>(std::move(distLockCatalog));
+ }
+
+ std::unique_ptr<ShardingCatalogClient> makeShardingCatalogClient(
+ std::unique_ptr<DistLockManager> distLockManager) override {
+ return stdx::make_unique<ShardingCatalogClientMock>(std::move(distLockManager));
+ }
};
void CollectionRangeDeleterTest::setUp() {
- ServiceContextMongoDTest::setUp();
- const repl::ReplSettings replSettings = {};
- repl::setGlobalReplicationCoordinator(
- new repl::ReplicationCoordinatorMock(getServiceContext(), replSettings));
- repl::getGlobalReplicationCoordinator()->setFollowerMode(repl::MemberState::RS_PRIMARY);
- _opCtx = getServiceContext()->makeOperationContext(&cc());
- _dbDirectClient = stdx::make_unique<DBDirectClient>(operationContext());
+ serverGlobalParams.clusterRole = ClusterRole::ShardServer;
+ ShardingMongodTestFixture::setUp();
+ replicationCoordinator()->alwaysAllowWrites(true);
+ initializeGlobalShardingStateForMongodForTest(ConnectionString(dummyHost));
+ // RemoteCommandTargeterMock::get(shardRegistry()->getConfigShard()->getTargeter())
+ // ->setConnectionStringReturnValue(kConfigConnStr);
+
+ configTargeter()->setFindHostReturnValue(dummyHost);
+
+ DBDirectClient(operationContext()).createCollection(kNss.ns());
{
+ AutoGetCollection autoColl(operationContext(), kNss, MODE_IX);
+ auto collectionShardingState = CollectionShardingState::get(operationContext(), kNss);
const OID epoch = OID::gen();
-
- AutoGetCollection autoColl(operationContext(), kNamespaceString, MODE_IX);
- auto collectionShardingState =
- CollectionShardingState::get(operationContext(), kNamespaceString);
collectionShardingState->refreshMetadata(
operationContext(),
stdx::make_unique<CollectionMetadata>(
@@ -86,208 +115,127 @@ void CollectionRangeDeleterTest::setUp() {
ChunkVersion(1, 0, epoch),
ChunkVersion(0, 0, epoch),
SimpleBSONObjComparator::kInstance.makeBSONObjIndexedMap<CachedChunkInfo>()));
- _metadataManager = collectionShardingState->getMetadataManagerForTest();
}
}
void CollectionRangeDeleterTest::tearDown() {
{
- AutoGetCollection autoColl(operationContext(), kNamespaceString, MODE_IX);
- auto collectionShardingState =
- CollectionShardingState::get(operationContext(), kNamespaceString);
+ AutoGetCollection autoColl(operationContext(), kNss, MODE_IX);
+ auto collectionShardingState = CollectionShardingState::get(operationContext(), kNss);
collectionShardingState->refreshMetadata(operationContext(), nullptr);
}
- _dbDirectClient.reset();
- _opCtx.reset();
- ServiceContextMongoDTest::tearDown();
- repl::setGlobalReplicationCoordinator(nullptr);
-}
-
-OperationContext* CollectionRangeDeleterTest::operationContext() {
- invariant(_opCtx);
- return _opCtx.get();
+ ShardingMongodTestFixture::tearDown();
}
namespace {
// Tests the case that there is nothing in the database.
TEST_F(CollectionRangeDeleterTest, EmptyDatabase) {
- CollectionRangeDeleter rangeDeleter(kNamespaceString);
- ASSERT_FALSE(rangeDeleter.cleanupNextRange(operationContext(), 1));
+ CollectionRangeDeleter rangeDeleter;
+ ASSERT_FALSE(next(rangeDeleter, 1));
}
// Tests the case that there is data, but it is not in a range to clean.
TEST_F(CollectionRangeDeleterTest, NoDataInGivenRangeToClean) {
- CollectionRangeDeleter rangeDeleter(kNamespaceString);
+ CollectionRangeDeleter rangeDeleter;
const BSONObj insertedDoc = BSON(kPattern << 25);
+ DBDirectClient dbclient(operationContext());
+ dbclient.insert(kNss.toString(), insertedDoc);
+ ASSERT_BSONOBJ_EQ(insertedDoc, dbclient.findOne(kNss.toString(), QUERY(kPattern << 25)));
- _dbDirectClient->insert(kNamespaceString.toString(), insertedDoc);
- ASSERT_BSONOBJ_EQ(insertedDoc,
- _dbDirectClient->findOne(kNamespaceString.toString(), QUERY(kPattern << 25)));
+ rangeDeleter.add(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
+ ASSERT_TRUE(next(rangeDeleter, 1));
- _metadataManager->addRangeToClean(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
- ASSERT_FALSE(rangeDeleter.cleanupNextRange(operationContext(), 1));
+ ASSERT_BSONOBJ_EQ(insertedDoc, dbclient.findOne(kNss.toString(), QUERY(kPattern << 25)));
- ASSERT_BSONOBJ_EQ(insertedDoc,
- _dbDirectClient->findOne(kNamespaceString.toString(), QUERY(kPattern << 25)));
+ ASSERT_FALSE(next(rangeDeleter, 1));
}
// Tests the case that there is a single document within a range to clean.
TEST_F(CollectionRangeDeleterTest, OneDocumentInOneRangeToClean) {
- CollectionRangeDeleter rangeDeleter(kNamespaceString);
+ CollectionRangeDeleter rangeDeleter;
const BSONObj insertedDoc = BSON(kPattern << 5);
+ DBDirectClient dbclient(operationContext());
+ dbclient.insert(kNss.toString(), BSON(kPattern << 5));
+ ASSERT_BSONOBJ_EQ(insertedDoc, dbclient.findOne(kNss.toString(), QUERY(kPattern << 5)));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 5));
- ASSERT_BSONOBJ_EQ(insertedDoc,
- _dbDirectClient->findOne(kNamespaceString.toString(), QUERY(kPattern << 5)));
-
- _metadataManager->addRangeToClean(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
+ rangeDeleter.add(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 1));
- ASSERT_TRUE(
- _dbDirectClient->findOne(kNamespaceString.toString(), QUERY(kPattern << 5)).isEmpty());
-
- ASSERT_FALSE(rangeDeleter.cleanupNextRange(operationContext(), 1));
+ ASSERT_TRUE(next(rangeDeleter, 1));
+ ASSERT_TRUE(next(rangeDeleter, 1));
+ ASSERT_TRUE(dbclient.findOne(kNss.toString(), QUERY(kPattern << 5)).isEmpty());
+ ASSERT_FALSE(next(rangeDeleter, 1));
}
// Tests the case that there are multiple documents within a range to clean.
TEST_F(CollectionRangeDeleterTest, MultipleDocumentsInOneRangeToClean) {
- CollectionRangeDeleter rangeDeleter(kNamespaceString);
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 1));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 2));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 3));
- ASSERT_EQUALS(3ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 5)));
-
- _metadataManager->addRangeToClean(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 100));
- ASSERT_EQUALS(0ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 5)));
-
- ASSERT_FALSE(rangeDeleter.cleanupNextRange(operationContext(), 100));
+ CollectionRangeDeleter rangeDeleter;
+ DBDirectClient dbclient(operationContext());
+ dbclient.insert(kNss.toString(), BSON(kPattern << 1));
+ dbclient.insert(kNss.toString(), BSON(kPattern << 2));
+ dbclient.insert(kNss.toString(), BSON(kPattern << 3));
+ ASSERT_EQUALS(3ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 5)));
+
+ rangeDeleter.add(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
+
+ ASSERT_TRUE(next(rangeDeleter, 100));
+ ASSERT_TRUE(next(rangeDeleter, 100));
+ ASSERT_EQUALS(0ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 5)));
+ ASSERT_FALSE(next(rangeDeleter, 100));
}
// Tests the case that there are multiple documents within a range to clean, and the range deleter
// has a max deletion rate of one document per run.
-TEST_F(CollectionRangeDeleterTest, MultipleCleanupNextRangeCallsToCleanOneRange) {
- CollectionRangeDeleter rangeDeleter(kNamespaceString);
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 1));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 2));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 3));
- ASSERT_EQUALS(3ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 5)));
-
- _metadataManager->addRangeToClean(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 1));
- ASSERT_EQUALS(2ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 5)));
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 1));
- ASSERT_EQUALS(1ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 5)));
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 1));
- ASSERT_EQUALS(0ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 5)));
-
- ASSERT_FALSE(rangeDeleter.cleanupNextRange(operationContext(), 1));
+TEST_F(CollectionRangeDeleterTest, MultipleCleanupNextRangeCalls) {
+ CollectionRangeDeleter rangeDeleter;
+ DBDirectClient dbclient(operationContext());
+ dbclient.insert(kNss.toString(), BSON(kPattern << 1));
+ dbclient.insert(kNss.toString(), BSON(kPattern << 2));
+ dbclient.insert(kNss.toString(), BSON(kPattern << 3));
+ ASSERT_EQUALS(3ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 5)));
+
+ rangeDeleter.add(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
+
+ ASSERT_TRUE(next(rangeDeleter, 1));
+ ASSERT_EQUALS(2ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 5)));
+
+ ASSERT_TRUE(next(rangeDeleter, 1));
+ ASSERT_EQUALS(1ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 5)));
+
+ ASSERT_TRUE(next(rangeDeleter, 1));
+ ASSERT_TRUE(next(rangeDeleter, 1));
+ ASSERT_EQUALS(0ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 5)));
+ ASSERT_FALSE(next(rangeDeleter, 1));
}
// Tests the case that there are two ranges to clean, each containing multiple documents.
TEST_F(CollectionRangeDeleterTest, MultipleDocumentsInMultipleRangesToClean) {
- CollectionRangeDeleter rangeDeleter(kNamespaceString);
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 1));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 2));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 3));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 4));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 5));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 6));
- ASSERT_EQUALS(6ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
+ CollectionRangeDeleter rangeDeleter;
+ DBDirectClient dbclient(operationContext());
+ dbclient.insert(kNss.toString(), BSON(kPattern << 1));
+ dbclient.insert(kNss.toString(), BSON(kPattern << 2));
+ dbclient.insert(kNss.toString(), BSON(kPattern << 3));
+ dbclient.insert(kNss.toString(), BSON(kPattern << 4));
+ dbclient.insert(kNss.toString(), BSON(kPattern << 5));
+ dbclient.insert(kNss.toString(), BSON(kPattern << 6));
+ ASSERT_EQUALS(6ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 10)));
const ChunkRange chunkRange1 = ChunkRange(BSON(kPattern << 0), BSON(kPattern << 4));
const ChunkRange chunkRange2 = ChunkRange(BSON(kPattern << 4), BSON(kPattern << 7));
- _metadataManager->addRangeToClean(chunkRange1);
- _metadataManager->addRangeToClean(chunkRange2);
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 100));
- ASSERT_EQUALS(0ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 4)));
- ASSERT_EQUALS(3ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 100));
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 100));
- ASSERT_EQUALS(0ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
-
- ASSERT_FALSE(rangeDeleter.cleanupNextRange(operationContext(), 1));
-}
-
-// Tests the case that there is a range to clean, and halfway through a deletion a chunk
-// within the range is received
-TEST_F(CollectionRangeDeleterTest, MultipleCallstoCleanupNextRangeWithChunkReceive) {
- CollectionRangeDeleter rangeDeleter(kNamespaceString);
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 1));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 2));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 3));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 4));
- const BSONObj insertedDoc5 = BSON(kPattern << 5); // not to be deleted
- _dbDirectClient->insert(kNamespaceString.toString(), insertedDoc5);
- ASSERT_EQUALS(5ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
-
- _metadataManager->addRangeToClean(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 2));
- ASSERT_EQUALS(3ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
-
- _metadataManager->beginReceive(ChunkRange(BSON(kPattern << 5), BSON(kPattern << 6)));
-
- // insertedDoc5 is no longer eligible for deletion
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 2));
- ASSERT_EQUALS(1ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 2));
- ASSERT_EQUALS(1ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
-
- ASSERT_FALSE(rangeDeleter.cleanupNextRange(operationContext(), 2));
-
- ASSERT_BSONOBJ_EQ(
- insertedDoc5,
- _dbDirectClient->findOne(kNamespaceString.toString(), QUERY(kPattern << GT << 0)));
-}
-
-TEST_F(CollectionRangeDeleterTest, CalltoCleanupNextRangeWithChunkReceive) {
- CollectionRangeDeleter rangeDeleter(kNamespaceString);
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 1));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 2));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 3));
- _dbDirectClient->insert(kNamespaceString.toString(), BSON(kPattern << 4));
- ASSERT_EQUALS(4ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
-
- _metadataManager->addRangeToClean(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
-
- ASSERT_TRUE(rangeDeleter.cleanupNextRange(operationContext(), 2));
- ASSERT_EQUALS(2ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
-
- _metadataManager->beginReceive(ChunkRange(BSON(kPattern << 0), BSON(kPattern << 10)));
-
- ASSERT_FALSE(rangeDeleter.cleanupNextRange(operationContext(), 2));
-
- ASSERT_EQUALS(2ULL,
- _dbDirectClient->count(kNamespaceString.toString(), BSON(kPattern << LT << 10)));
+ rangeDeleter.add(chunkRange1);
+ rangeDeleter.add(chunkRange2);
+
+ ASSERT_TRUE(next(rangeDeleter, 100));
+ ASSERT_EQUALS(0ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 4)));
+ ASSERT_EQUALS(3ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 10)));
+
+ ASSERT_TRUE(next(rangeDeleter, 100)); // discover there are no more < 4, pop range 1
+ ASSERT_TRUE(next(rangeDeleter, 100)); // delete the remaining documents
+ ASSERT_TRUE(next(rangeDeleter, 1)); // discover there are no more, pop range 2
+ ASSERT_EQUALS(0ULL, dbclient.count(kNss.toString(), BSON(kPattern << LT << 10)));
+ ASSERT_FALSE(next(rangeDeleter, 1)); // discover there are no more ranges
}
} // unnamed namespace
-
} // namespace mongo