summaryrefslogtreecommitdiff
path: root/src/mongo/db/s/balancer/balancer_policy_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/s/balancer/balancer_policy_test.cpp')
-rw-r--r--src/mongo/db/s/balancer/balancer_policy_test.cpp510
1 files changed, 256 insertions, 254 deletions
diff --git a/src/mongo/db/s/balancer/balancer_policy_test.cpp b/src/mongo/db/s/balancer/balancer_policy_test.cpp
index 7441dfab2c7..8f3b340c82d 100644
--- a/src/mongo/db/s/balancer/balancer_policy_test.cpp
+++ b/src/mongo/db/s/balancer/balancer_policy_test.cpp
@@ -46,11 +46,9 @@ using std::stringstream;
using std::vector;
using ShardStatistics = ClusterStatistics::ShardStatistics;
-typedef std::map<ShardId, std::vector<ChunkType>> ShardToChunksMap;
const auto emptyTagSet = std::set<std::string>();
const std::string emptyShardVersion = "";
-const auto kConfigId = ShardId("config");
const auto kShardId0 = ShardId("shard0");
const auto kShardId1 = ShardId("shard1");
const auto kShardId2 = ShardId("shard2");
@@ -59,36 +57,6 @@ const auto kShardId4 = ShardId("shard4");
const auto kShardId5 = ShardId("shard5");
const NamespaceString kNamespace("TestDB", "TestColl");
const uint64_t kNoMaxSize = 0;
-const KeyPattern kSKeyPattern(BSON("x" << 1));
-const boost::optional<Timestamp> kCollTimestamp;
-const OID kCollEpoch;
-
-RoutingTableHistory makeRoutingTable(const std::vector<ChunkType>& chunks) {
- static const UUID kCollectionUUID{UUID::gen()};
-
- return RoutingTableHistory::makeNew(kNamespace,
- kCollectionUUID,
- kSKeyPattern,
- nullptr,
- false,
- kCollEpoch,
- kCollTimestamp,
- boost::none /* timeseriesFields */,
- boost::none /* reshardingFields */,
- true,
- chunks);
-}
-
-ChunkManager makeChunkManager(const std::vector<ChunkType>& chunks) {
- DatabaseVersion dbVersion;
- auto rt = std::make_shared<RoutingTableHistory>(makeRoutingTable(chunks));
-
- return {kConfigId, std::move(dbVersion), {std::move(rt)}, kCollTimestamp};
-}
-
-DistributionStatus makeDistStatus(const ChunkManager& cm, ZoneInfo zoneInfo = ZoneInfo()) {
- return {kNamespace, std::move(zoneInfo), cm};
-}
/**
* Constructs a shard statistics vector and a consistent mapping of chunks to shards given the
@@ -97,7 +65,7 @@ DistributionStatus makeDistStatus(const ChunkManager& cm, ZoneInfo zoneInfo = Zo
*
* [MinKey, 1), [1, 2), [2, 3) ... [N - 1, MaxKey)
*/
-std::pair<std::pair<ShardStatisticsVector, ShardToChunksMap>, ChunkManager> generateCluster(
+std::pair<ShardStatisticsVector, ShardToChunksMap> generateCluster(
const vector<std::pair<ShardStatistics, size_t>>& shardsAndNumChunks) {
int64_t totalNumChunks = 0;
for (const auto& entry : shardsAndNumChunks) {
@@ -109,9 +77,9 @@ std::pair<std::pair<ShardStatisticsVector, ShardToChunksMap>, ChunkManager> gene
int64_t currentChunk = 0;
- ChunkVersion chunkVersion(1, 0, kCollEpoch, kCollTimestamp);
+ ChunkVersion chunkVersion(1, 0, OID::gen(), boost::none /* timestamp */);
- std::vector<ChunkType> chunks;
+ const KeyPattern shardKeyPattern(BSON("x" << 1));
for (auto it = shardsAndNumChunks.begin(); it != shardsAndNumChunks.end(); it++) {
ShardStatistics shard = std::move(it->first);
@@ -124,23 +92,22 @@ std::pair<std::pair<ShardStatisticsVector, ShardToChunksMap>, ChunkManager> gene
ChunkType chunk;
chunk.setNS(kNamespace);
- chunk.setMin(currentChunk == 0 ? kSKeyPattern.globalMin() : BSON("x" << currentChunk));
- chunk.setMax(currentChunk == totalNumChunks - 1 ? kSKeyPattern.globalMax()
+ chunk.setMin(currentChunk == 0 ? shardKeyPattern.globalMin()
+ : BSON("x" << currentChunk));
+ chunk.setMax(currentChunk == totalNumChunks - 1 ? shardKeyPattern.globalMax()
: BSON("x" << currentChunk + 1));
chunk.setShard(shard.shardId);
chunk.setVersion(chunkVersion);
chunkVersion.incMajor();
- chunkMap[shard.shardId].push_back(chunk);
- chunks.push_back(std::move(chunk));
+ chunkMap[shard.shardId].push_back(std::move(chunk));
}
shardStats.push_back(std::move(shard));
}
- return std::make_pair(std::make_pair(std::move(shardStats), std::move(chunkMap)),
- makeChunkManager(chunks));
+ return std::make_pair(std::move(shardStats), std::move(chunkMap));
}
std::vector<MigrateInfo> balanceChunks(const ShardStatisticsVector& shardStats,
@@ -158,12 +125,13 @@ std::vector<MigrateInfo> balanceChunks(const ShardStatisticsVector& shardStats,
}
TEST(BalancerPolicy, Basic) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
{ShardStatistics(kShardId2, kNoMaxSize, 3, false, emptyTagSet, emptyShardVersion), 3}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
@@ -173,12 +141,13 @@ TEST(BalancerPolicy, Basic) {
}
TEST(BalancerPolicy, SmallClusterShouldBePerfectlyBalanced) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 1, false, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId1, kNoMaxSize, 2, false, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId2, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId1, migrations[0].from);
ASSERT_EQ(kShardId2, migrations[0].to);
@@ -188,33 +157,46 @@ TEST(BalancerPolicy, SmallClusterShouldBePerfectlyBalanced) {
}
TEST(BalancerPolicy, SingleChunkShouldNotMove) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 1, false, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- ASSERT(balanceChunks(cluster.first, makeDistStatus(cm), true, false).empty());
- ASSERT(balanceChunks(cluster.first, makeDistStatus(cm), false, false).empty());
+ ASSERT(
+ balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), true, false)
+ .empty());
+ ASSERT(
+ balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false)
+ .empty());
}
TEST(BalancerPolicy, BalanceThresholdObeyed) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, false, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId1, kNoMaxSize, 2, false, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId2, kNoMaxSize, 1, false, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId3, kNoMaxSize, 1, false, emptyTagSet, emptyShardVersion), 1}});
- ASSERT(balanceChunks(cluster.first, makeDistStatus(cm), true, false).empty());
- ASSERT(balanceChunks(cluster.first, makeDistStatus(cm), false, false).empty());
+ ASSERT(
+ balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), true, false)
+ .empty());
+ ASSERT(
+ balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false)
+ .empty());
}
TEST(BalancerPolicy, ParallelBalancing) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId1, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
{ShardStatistics(kShardId3, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(2U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -231,7 +213,7 @@ TEST(BalancerPolicy, ParallelBalancing) {
}
TEST(BalancerPolicy, ParallelBalancingDoesNotPutChunksOnShardsAboveTheOptimal) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 100, false, emptyTagSet, emptyShardVersion), 100},
{ShardStatistics(kShardId1, kNoMaxSize, 90, false, emptyTagSet, emptyShardVersion), 90},
{ShardStatistics(kShardId2, kNoMaxSize, 90, false, emptyTagSet, emptyShardVersion), 90},
@@ -239,7 +221,8 @@ TEST(BalancerPolicy, ParallelBalancingDoesNotPutChunksOnShardsAboveTheOptimal) {
{ShardStatistics(kShardId4, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
{ShardStatistics(kShardId5, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(2U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -256,13 +239,14 @@ TEST(BalancerPolicy, ParallelBalancingDoesNotPutChunksOnShardsAboveTheOptimal) {
}
TEST(BalancerPolicy, ParallelBalancingDoesNotMoveChunksFromShardsBelowOptimal) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 100, false, emptyTagSet, emptyShardVersion), 100},
{ShardStatistics(kShardId1, kNoMaxSize, 30, false, emptyTagSet, emptyShardVersion), 30},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 5},
{ShardStatistics(kShardId3, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -273,7 +257,7 @@ TEST(BalancerPolicy, ParallelBalancingDoesNotMoveChunksFromShardsBelowOptimal) {
}
TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseSourceShardsWithMoveNecessary) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 8, false, emptyTagSet, emptyShardVersion), 8},
{ShardStatistics(kShardId1, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
@@ -282,7 +266,10 @@ TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseSourceShardsWithMoveNe
// Here kShardId0 would have been selected as a donor
stdx::unordered_set<ShardId> availableShards{kShardId1, kShardId2, kShardId3};
const auto migrations(
- BalancerPolicy::balance(cluster.first, makeDistStatus(cm), &availableShards, false));
+ BalancerPolicy::balance(cluster.first,
+ DistributionStatus(kNamespace, cluster.second, ZoneInfo()),
+ &availableShards,
+ false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId1, migrations[0].from);
@@ -293,7 +280,7 @@ TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseSourceShardsWithMoveNe
}
TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseSourceShardsWithMoveNotNecessary) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 12, false, emptyTagSet, emptyShardVersion), 12},
{ShardStatistics(kShardId1, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
@@ -302,12 +289,15 @@ TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseSourceShardsWithMoveNo
// Here kShardId0 would have been selected as a donor
stdx::unordered_set<ShardId> availableShards{kShardId1, kShardId2, kShardId3};
const auto migrations(
- BalancerPolicy::balance(cluster.first, makeDistStatus(cm), &availableShards, false));
+ BalancerPolicy::balance(cluster.first,
+ DistributionStatus(kNamespace, cluster.second, ZoneInfo()),
+ &availableShards,
+ false));
ASSERT_EQ(0U, migrations.size());
}
TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseDestinationShards) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId1, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
@@ -316,7 +306,10 @@ TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseDestinationShards) {
// Here kShardId2 would have been selected as a recipient
stdx::unordered_set<ShardId> availableShards{kShardId0, kShardId1, kShardId3};
const auto migrations(
- BalancerPolicy::balance(cluster.first, makeDistStatus(cm), &availableShards, false));
+ BalancerPolicy::balance(cluster.first,
+ DistributionStatus(kNamespace, cluster.second, ZoneInfo()),
+ &availableShards,
+ false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -326,115 +319,68 @@ TEST(BalancerPolicy, ParallelBalancingNotSchedulingOnInUseDestinationShards) {
ASSERT_EQ(MigrateInfo::chunksImbalance, migrations[0].reason);
}
-TEST(BalancerPolicy, JumboChunksNotMovedWhileEnforcingZones) {
- auto [cluster, cm] = generateCluster(
- {{ShardStatistics(kShardId0, kNoMaxSize, 3, false, emptyTagSet, emptyShardVersion), 3},
- {ShardStatistics(kShardId1, kNoMaxSize, 3, false, {"a"}, emptyShardVersion), 3}});
-
- // construct a new chunk map where all the chunks are jumbo except this one
- const auto& jumboChunk = cluster.second[kShardId0][1];
-
- std::vector<ChunkType> chunks;
- cm.forEachChunk([&](const auto& chunk) {
- ChunkType ct{kNamespace, chunk.getRange(), chunk.getLastmod(), chunk.getShardId()};
- if (chunk.getLastmod() == jumboChunk.getVersion())
- ct.setJumbo(false);
- else
- ct.setJumbo(true);
- chunks.emplace_back(std::move(ct));
- return true;
- });
-
- ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(
- ZoneRange(kSKeyPattern.globalMin(), kSKeyPattern.globalMax(), "a")));
- const auto distribution = makeDistStatus(makeChunkManager(chunks), std::move(zoneInfo));
-
- const auto migrations(balanceChunks(cluster.first, distribution, false, false));
- ASSERT_EQ(1U, migrations.size());
- ASSERT_EQ(kShardId0, migrations[0].from);
- ASSERT_EQ(kShardId1, migrations[0].to);
- ASSERT_BSONOBJ_EQ(jumboChunk.getMin(), migrations[0].minKey);
- ASSERT_BSONOBJ_EQ(jumboChunk.getMax(), migrations[0].maxKey);
- ASSERT_EQ(MigrateInfo::zoneViolation, migrations[0].reason);
-}
-
TEST(BalancerPolicy, JumboChunksNotMoved) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- // construct a new chunk map where all the chunks are jumbo except this one
- const auto& jumboChunk = cluster.second[kShardId0][1];
-
- std::vector<ChunkType> chunks;
- cm.forEachChunk([&](const auto& chunk) {
- ChunkType ct{kNamespace, chunk.getRange(), chunk.getLastmod(), chunk.getShardId()};
- if (chunk.getLastmod() == jumboChunk.getVersion())
- ct.setJumbo(false);
- else
- ct.setJumbo(true);
- chunks.emplace_back(std::move(ct));
- return true;
- });
+ cluster.second[kShardId0][0].setJumbo(true);
+ cluster.second[kShardId0][1].setJumbo(false); // Only chunk 1 is not jumbo
+ cluster.second[kShardId0][2].setJumbo(true);
+ cluster.second[kShardId0][3].setJumbo(true);
- const auto migrations(
- balanceChunks(cluster.first, makeDistStatus(makeChunkManager(chunks)), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
- ASSERT_BSONOBJ_EQ(jumboChunk.getMin(), migrations[0].minKey);
- ASSERT_BSONOBJ_EQ(jumboChunk.getMax(), migrations[0].maxKey);
+ ASSERT_BSONOBJ_EQ(cluster.second[kShardId0][1].getMin(), migrations[0].minKey);
+ ASSERT_BSONOBJ_EQ(cluster.second[kShardId0][1].getMax(), migrations[0].maxKey);
ASSERT_EQ(MigrateInfo::chunksImbalance, migrations[0].reason);
}
TEST(BalancerPolicy, JumboChunksNotMovedParallel) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0},
{ShardStatistics(kShardId2, kNoMaxSize, 2, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId3, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 0}});
- // construct a new chunk map where all the chunks are jumbo except the ones listed below
- const auto& jumboChunk0 = cluster.second[kShardId0][1];
- const auto& jumboChunk1 = cluster.second[kShardId2][2];
-
- std::vector<ChunkType> chunks;
- cm.forEachChunk([&](const auto& chunk) {
- ChunkType ct{kNamespace, chunk.getRange(), chunk.getLastmod(), chunk.getShardId()};
- if (chunk.getLastmod() == jumboChunk0.getVersion() ||
- chunk.getLastmod() == jumboChunk1.getVersion())
- ct.setJumbo(false);
- else
- ct.setJumbo(true);
- chunks.emplace_back(std::move(ct));
- return true;
- });
+ cluster.second[kShardId0][0].setJumbo(true);
+ cluster.second[kShardId0][1].setJumbo(false); // Only chunk 1 is not jumbo
+ cluster.second[kShardId0][2].setJumbo(true);
+ cluster.second[kShardId0][3].setJumbo(true);
- const auto migrations(
- balanceChunks(cluster.first, makeDistStatus(makeChunkManager(chunks)), false, false));
+ cluster.second[kShardId2][0].setJumbo(true);
+ cluster.second[kShardId2][1].setJumbo(true);
+ cluster.second[kShardId2][2].setJumbo(false); // Only chunk 1 is not jumbo
+ cluster.second[kShardId2][3].setJumbo(true);
+
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(2U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
- ASSERT_BSONOBJ_EQ(jumboChunk0.getMin(), migrations[0].minKey);
- ASSERT_BSONOBJ_EQ(jumboChunk0.getMax(), migrations[0].maxKey);
+ ASSERT_BSONOBJ_EQ(cluster.second[kShardId0][1].getMin(), migrations[0].minKey);
+ ASSERT_BSONOBJ_EQ(cluster.second[kShardId0][1].getMax(), migrations[0].maxKey);
ASSERT_EQ(MigrateInfo::chunksImbalance, migrations[0].reason);
ASSERT_EQ(kShardId2, migrations[1].from);
ASSERT_EQ(kShardId3, migrations[1].to);
- ASSERT_BSONOBJ_EQ(jumboChunk1.getMin(), migrations[1].minKey);
- ASSERT_BSONOBJ_EQ(jumboChunk1.getMax(), migrations[1].maxKey);
+ ASSERT_BSONOBJ_EQ(cluster.second[kShardId2][2].getMin(), migrations[1].minKey);
+ ASSERT_BSONOBJ_EQ(cluster.second[kShardId2][2].getMax(), migrations[1].maxKey);
ASSERT_EQ(MigrateInfo::chunksImbalance, migrations[1].reason);
}
TEST(BalancerPolicy, DrainingSingleChunk) {
// shard0 is draining and chunks will go to shard1, even though it has a lot more chunks
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, true, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 5}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
@@ -445,13 +391,14 @@ TEST(BalancerPolicy, DrainingSingleChunk) {
TEST(BalancerPolicy, DrainingSingleChunkPerShard) {
// shard0 and shard2 are draining and chunks will go to shard1 and shard3 in parallel
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, true, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 5},
{ShardStatistics(kShardId2, kNoMaxSize, 2, true, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId3, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 5}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(2U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
@@ -469,11 +416,12 @@ TEST(BalancerPolicy, DrainingSingleChunkPerShard) {
TEST(BalancerPolicy, DrainingWithTwoChunksFirstOneSelected) {
// shard0 is draining and chunks will go to shard1, even though it has a lot more chunks
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, true, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId1, kNoMaxSize, 0, false, emptyTagSet, emptyShardVersion), 5}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
@@ -485,12 +433,13 @@ TEST(BalancerPolicy, DrainingWithTwoChunksFirstOneSelected) {
TEST(BalancerPolicy, DrainingMultipleShardsFirstOneSelected) {
// shard0 and shard1 are both draining with very little chunks in them and chunks will go to
// shard2, even though it has a lot more chunks that the other two
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 5, true, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId1, kNoMaxSize, 5, true, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 16}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId0, migrations[0].from);
ASSERT_EQ(kShardId2, migrations[0].to);
@@ -501,17 +450,18 @@ TEST(BalancerPolicy, DrainingMultipleShardsFirstOneSelected) {
TEST(BalancerPolicy, DrainingMultipleShardsWontAcceptChunks) {
// shard0 has many chunks, but can't move them to shard1 or shard2 because they are draining
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId1, kNoMaxSize, 0, true, emptyTagSet, emptyShardVersion), 0},
{ShardStatistics(kShardId2, kNoMaxSize, 0, true, emptyTagSet, emptyShardVersion), 0}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT(migrations.empty());
}
TEST(BalancerPolicy, DrainingSingleAppropriateShardFoundDueToTag) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, false, {"NYC"}, emptyShardVersion), 4},
{ShardStatistics(kShardId1, kNoMaxSize, 2, false, {"LAX"}, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 1, true, {"LAX"}, emptyShardVersion), 1}});
@@ -519,7 +469,7 @@ TEST(BalancerPolicy, DrainingSingleAppropriateShardFoundDueToTag) {
ZoneInfo zoneInfo;
ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(
cluster.second[kShardId2][0].getMin(), cluster.second[kShardId2][0].getMax(), "LAX")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -531,7 +481,7 @@ TEST(BalancerPolicy, DrainingSingleAppropriateShardFoundDueToTag) {
}
TEST(BalancerPolicy, DrainingNoAppropriateShardsFoundDueToTag) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, false, {"NYC"}, emptyShardVersion), 4},
{ShardStatistics(kShardId1, kNoMaxSize, 2, false, {"LAX"}, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 1, true, {"SEA"}, emptyShardVersion), 1}});
@@ -539,7 +489,7 @@ TEST(BalancerPolicy, DrainingNoAppropriateShardsFoundDueToTag) {
ZoneInfo zoneInfo;
ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(
cluster.second[kShardId2][0].getMin(), cluster.second[kShardId2][0].getMax(), "SEA")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT(migrations.empty());
@@ -547,12 +497,13 @@ TEST(BalancerPolicy, DrainingNoAppropriateShardsFoundDueToTag) {
TEST(BalancerPolicy, NoBalancingDueToAllNodesEitherDrainingOrMaxedOut) {
// shard0 and shard2 are draining, shard1 is maxed out
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 2, true, emptyTagSet, emptyShardVersion), 1},
{ShardStatistics(kShardId1, 1, 1, false, emptyTagSet, emptyShardVersion), 6},
{ShardStatistics(kShardId2, kNoMaxSize, 1, true, emptyTagSet, emptyShardVersion), 1}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT(migrations.empty());
}
@@ -560,12 +511,13 @@ TEST(BalancerPolicy, BalancerRespectsMaxShardSizeOnlyBalanceToNonMaxed) {
// Note that maxSize of shard0 is 1, and it is therefore overloaded with currSize = 3. Other
// shards have maxSize = 0 = unset. Even though the overloaded shard has the least number of
// less chunks, we shouldn't move chunks to that shard.
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, 1, 3, false, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 5},
{ShardStatistics(kShardId2, kNoMaxSize, 10, false, emptyTagSet, emptyShardVersion), 10}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT_EQ(1U, migrations.size());
ASSERT_EQ(kShardId2, migrations[0].from);
ASSERT_EQ(kShardId1, migrations[0].to);
@@ -577,26 +529,27 @@ TEST(BalancerPolicy, BalancerRespectsMaxShardSizeWhenAllBalanced) {
// Note that maxSize of shard0 is 1, and it is therefore overloaded with currSize = 4. Other
// shards have maxSize = 0 = unset. We check that being over the maxSize is NOT equivalent to
// draining, we don't want to empty shards for no other reason than they are over this limit.
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, 1, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId1, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4},
{ShardStatistics(kShardId2, kNoMaxSize, 4, false, emptyTagSet, emptyShardVersion), 4}});
- const auto migrations(balanceChunks(cluster.first, makeDistStatus(cm), false, false));
+ const auto migrations(balanceChunks(
+ cluster.first, DistributionStatus(kNamespace, cluster.second, ZoneInfo()), false, false));
ASSERT(migrations.empty());
}
TEST(BalancerPolicy, BalancerRespectsTagsWhenDraining) {
// shard1 drains the proper chunk to shard0, even though it is more loaded than shard2
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 6},
- {ShardStatistics(kShardId1, kNoMaxSize, 5, true, {"a", "b"}, emptyShardVersion), 1},
+ {ShardStatistics(kShardId1, kNoMaxSize, 5, true, {"a", "b"}, emptyShardVersion), 2},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, {"b"}, emptyShardVersion), 2}});
ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 7), "a")));
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 8), kSKeyPattern.globalMax(), "b")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 7), "a")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 8), kMaxBSONKey, "b")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -610,14 +563,14 @@ TEST(BalancerPolicy, BalancerRespectsTagsWhenDraining) {
TEST(BalancerPolicy, BalancerRespectsTagPolicyBeforeImbalance) {
// There is a large imbalance between shard0 and shard1, but the balancer must first fix the
// chunks, which are on a wrong shard due to tag policy
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 2},
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 6},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 2}});
ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 100), "a")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 100), "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -631,15 +584,15 @@ TEST(BalancerPolicy, BalancerRespectsTagPolicyBeforeImbalance) {
TEST(BalancerPolicy, BalancerFixesIncorrectTagsWithCrossShardViolationOfTags) {
// The zone policy dictates that the same shard must donate and also receive chunks. The test
// validates that the same shard is not used as a donor and recipient as part of the same round.
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3},
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, {"b"}, emptyShardVersion), 3}});
ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 1), "b")));
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 8), kSKeyPattern.globalMax(), "a")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 1), "b")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 8), kMaxBSONKey, "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -652,14 +605,14 @@ TEST(BalancerPolicy, BalancerFixesIncorrectTagsWithCrossShardViolationOfTags) {
TEST(BalancerPolicy, BalancerFixesIncorrectTagsInOtherwiseBalancedCluster) {
// Chunks are balanced across shards, but there are wrong tags, which need to be fixed
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3},
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3}});
ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 10), "a")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 10), "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -672,30 +625,29 @@ TEST(BalancerPolicy, BalancerFixesIncorrectTagsInOtherwiseBalancedCluster) {
TEST(BalancerPolicy, BalancerTagAlreadyBalanced) {
// Chunks are balanced across shards for the tag.
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 3, false, {"a"}, emptyShardVersion), 2},
{ShardStatistics(kShardId1, kNoMaxSize, 2, false, {"a"}, emptyShardVersion), 2}});
ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(
- ZoneRange(kSKeyPattern.globalMin(), kSKeyPattern.globalMax(), "a")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, kMaxBSONKey, "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
ASSERT(balanceChunks(cluster.first, distribution, false, false).empty());
}
TEST(BalancerPolicy, BalancerMostOverLoadShardHasMultipleTags) {
// shard0 has chunks [MinKey, 1), [1, 2), [2, 3), [3, 4), [4, 5), so two chunks each
// for tag "b" and "c". So [1, 2) is expected to be moved to shard1 in round 1.
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 5, false, {"a", "b", "c"}, emptyShardVersion), 5},
{ShardStatistics(kShardId1, kNoMaxSize, 1, false, {"b"}, emptyShardVersion), 1},
{ShardStatistics(kShardId2, kNoMaxSize, 1, false, {"c"}, emptyShardVersion), 1}});
ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 1), "a")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 1), "a")));
ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 3), "b")));
ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 3), BSON("x" << 5), "c")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(1U, migrations.size());
@@ -710,16 +662,16 @@ TEST(BalancerPolicy, BalancerMostOverLoadShardHasMultipleTagsSkipTagWithShardInU
// shard0 has chunks [MinKey, 1), [1, 2), [2, 3), [3, 4), [4, 5), so two chunks each
// for tag "b" and "c". So [3, 4) is expected to be moved to shard2 because shard1 is
// in use.
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 5, false, {"a", "b", "c"}, emptyShardVersion), 5},
{ShardStatistics(kShardId1, kNoMaxSize, 1, false, {"b"}, emptyShardVersion), 1},
{ShardStatistics(kShardId2, kNoMaxSize, 1, false, {"c"}, emptyShardVersion), 1}});
ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 1), "a")));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 1), "a")));
ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 3), "b")));
ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 3), BSON("x" << 5), "c")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
stdx::unordered_set<ShardId> availableShards{kShardId0, kShardId2, kShardId3};
const auto migrations(
@@ -734,15 +686,15 @@ TEST(BalancerPolicy, BalancerMostOverLoadShardHasMultipleTagsSkipTagWithShardInU
TEST(BalancerPolicy, BalancerFixesIncorrectTagsInOtherwiseBalancedClusterParallel) {
// Chunks are balanced across shards, but there are wrong tags, which need to be fixed
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3},
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3},
{ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3},
{ShardStatistics(kShardId3, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3}});
ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 20), "a")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 20), "a")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
const auto migrations(balanceChunks(cluster.first, distribution, false, false));
ASSERT_EQ(2U, migrations.size());
@@ -760,55 +712,14 @@ TEST(BalancerPolicy, BalancerFixesIncorrectTagsInOtherwiseBalancedClusterParalle
ASSERT_EQ(MigrateInfo::zoneViolation, migrations[0].reason);
}
-TEST(BalancerPolicy, ChunksInNoZoneSpanOnAllShardsWithEmptyZones) {
- // Balanacer is able to move chunks in the noZone to shards with tags
- auto [cluster, cm] = generateCluster(
- {{ShardStatistics(kShardId0, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3},
- {ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 0}});
-
- ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(BSON("x" << 100), kSKeyPattern.globalMax(), "a")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
-
- const auto migrations(balanceChunks(cluster.first, distribution, false, false));
- ASSERT_EQ(1U, migrations.size());
-
- ASSERT_EQ(kShardId0, migrations[0].from);
- ASSERT_EQ(kShardId1, migrations[0].to);
- ASSERT_BSONOBJ_EQ(cluster.second[kShardId0][0].getMin(), migrations[0].minKey);
- ASSERT_BSONOBJ_EQ(cluster.second[kShardId0][0].getMax(), migrations[0].maxKey);
- ASSERT_EQ(MigrateInfo::chunksImbalance, migrations[0].reason);
-}
-
-TEST(BalancerPolicy, BalancingNoZoneIgnoreTotalShardSize) {
- // Shard1 is overloaded and contains:
- // [min, 1) [1, 2) [2, 3] -> zone("a")
- // [3, 4) [4, 5) [5, 6) -> NoZone
- //
- // But it won't donate any chunk since the
- auto [cluster, cm] = generateCluster(
- {{ShardStatistics(kShardId0, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 3},
- {ShardStatistics(kShardId1, kNoMaxSize, 5, false, {"a"}, emptyShardVersion), 6},
- {ShardStatistics(kShardId2, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 3}});
-
- ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 6), "a")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
-
- const auto migrations(balanceChunks(cluster.first, distribution, false, false));
- ASSERT_EQ(0U, migrations.size());
-}
-
-
TEST(BalancerPolicy, BalancerHandlesNoShardsWithTag) {
- auto [cluster, cm] = generateCluster(
+ auto cluster = generateCluster(
{{ShardStatistics(kShardId0, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 2},
{ShardStatistics(kShardId1, kNoMaxSize, 5, false, emptyTagSet, emptyShardVersion), 2}});
ZoneInfo zoneInfo;
- ASSERT_OK(zoneInfo.addRangeToZone(
- ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 7), "NonExistentZone")));
- const auto distribution = makeDistStatus(cm, std::move(zoneInfo));
+ ASSERT_OK(zoneInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 7), "NonExistentZone")));
+ DistributionStatus distribution(kNamespace, cluster.second, std::move(zoneInfo));
ASSERT(balanceChunks(cluster.first, distribution, false, false).empty());
}
@@ -821,7 +732,7 @@ TEST(DistributionStatus, AddTagRangeOverlap) {
ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 20), BSON("x" << 30), "b")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
- zInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << 2), "d")));
+ zInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << 2), "d")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
zInfo.addRangeToZone(ZoneRange(BSON("x" << -1), BSON("x" << 5), "d")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
@@ -833,7 +744,7 @@ TEST(DistributionStatus, AddTagRangeOverlap) {
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
zInfo.addRangeToZone(ZoneRange(BSON("x" << -1), BSON("x" << 32), "d")));
ASSERT_EQ(ErrorCodes::RangeOverlapConflict,
- zInfo.addRangeToZone(ZoneRange(BSON("x" << 25), kSKeyPattern.globalMax(), "d")));
+ zInfo.addRangeToZone(ZoneRange(BSON("x" << 25), kMaxBSONKey, "d")));
}
TEST(DistributionStatus, ChunkTagsSelectorWithRegularKeys) {
@@ -841,37 +752,128 @@ TEST(DistributionStatus, ChunkTagsSelectorWithRegularKeys) {
ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 1), BSON("x" << 10), "a")));
ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 10), BSON("x" << 20), "b")));
ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 20), BSON("x" << 30), "c")));
+ DistributionStatus d(kNamespace, ShardToChunksMap{}, std::move(zInfo));
+
+ {
+ ChunkType chunk;
+ chunk.setMin(kMinBSONKey);
+ chunk.setMax(BSON("x" << 1));
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 0));
+ chunk.setMax(BSON("x" << 1));
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 1));
+ chunk.setMax(BSON("x" << 5));
+ ASSERT_EQUALS("a", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 10));
+ chunk.setMax(BSON("x" << 20));
+ ASSERT_EQUALS("b", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 15));
+ chunk.setMax(BSON("x" << 20));
+ ASSERT_EQUALS("b", d.getTagForChunk(chunk));
+ }
- ASSERT_EQUALS(ZoneInfo::kNoZoneName,
- zInfo.getZoneForChunk({kSKeyPattern.globalMin(), BSON("x" << 1)}));
- ASSERT_EQUALS(ZoneInfo::kNoZoneName, zInfo.getZoneForChunk({BSON("x" << 0), BSON("x" << 1)}));
- ASSERT_EQUALS("a", zInfo.getZoneForChunk({BSON("x" << 1), BSON("x" << 5)}));
- ASSERT_EQUALS("b", zInfo.getZoneForChunk({BSON("x" << 10), BSON("x" << 20)}));
- ASSERT_EQUALS("b", zInfo.getZoneForChunk({BSON("x" << 15), BSON("x" << 20)}));
- ASSERT_EQUALS("c", zInfo.getZoneForChunk({BSON("x" << 25), BSON("x" << 30)}));
- ASSERT_EQUALS(ZoneInfo::kNoZoneName, zInfo.getZoneForChunk({BSON("x" << 35), BSON("x" << 40)}));
- ASSERT_EQUALS(ZoneInfo::kNoZoneName,
- zInfo.getZoneForChunk({BSON("x" << 30), kSKeyPattern.globalMax()}));
- ASSERT_EQUALS(ZoneInfo::kNoZoneName,
- zInfo.getZoneForChunk({BSON("x" << 40), kSKeyPattern.globalMax()}));
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 25));
+ chunk.setMax(BSON("x" << 30));
+ ASSERT_EQUALS("c", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 35));
+ chunk.setMax(BSON("x" << 40));
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 30));
+ chunk.setMax(kMaxBSONKey);
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 40));
+ chunk.setMax(kMaxBSONKey);
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+ }
}
TEST(DistributionStatus, ChunkTagsSelectorWithMinMaxKeys) {
ZoneInfo zInfo;
- ASSERT_OK(zInfo.addRangeToZone(ZoneRange(kSKeyPattern.globalMin(), BSON("x" << -100), "a")));
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(kMinBSONKey, BSON("x" << -100), "a")));
ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << -10), BSON("x" << 10), "b")));
- ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 100), kSKeyPattern.globalMax(), "c")));
-
- ASSERT_EQUALS("a", zInfo.getZoneForChunk({kSKeyPattern.globalMin(), BSON("x" << -100)}));
- ASSERT_EQUALS(ZoneInfo::kNoZoneName,
- zInfo.getZoneForChunk({BSON("x" << -100), BSON("x" << -11)}));
- ASSERT_EQUALS("b", zInfo.getZoneForChunk({BSON("x" << -10), BSON("x" << 0)}));
- ASSERT_EQUALS("b", zInfo.getZoneForChunk({BSON("x" << 0), BSON("x" << 10)}));
- ASSERT_EQUALS(ZoneInfo::kNoZoneName, zInfo.getZoneForChunk({BSON("x" << 10), BSON("x" << 20)}));
- ASSERT_EQUALS(ZoneInfo::kNoZoneName,
- zInfo.getZoneForChunk({BSON("x" << 10), BSON("x" << 100)}));
- ASSERT_EQUALS("c", zInfo.getZoneForChunk({BSON("x" << 200), kSKeyPattern.globalMax()}));
+ ASSERT_OK(zInfo.addRangeToZone(ZoneRange(BSON("x" << 100), kMaxBSONKey, "c")));
+ DistributionStatus d(kNamespace, ShardToChunksMap{}, std::move(zInfo));
+
+ {
+ ChunkType chunk;
+ chunk.setMin(kMinBSONKey);
+ chunk.setMax(BSON("x" << -100));
+ ASSERT_EQUALS("a", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << -100));
+ chunk.setMax(BSON("x" << -11));
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << -10));
+ chunk.setMax(BSON("x" << 0));
+ ASSERT_EQUALS("b", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 0));
+ chunk.setMax(BSON("x" << 10));
+ ASSERT_EQUALS("b", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 10));
+ chunk.setMax(BSON("x" << 20));
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 10));
+ chunk.setMax(BSON("x" << 100));
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+ }
+
+ {
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << 200));
+ chunk.setMax(kMaxBSONKey);
+ ASSERT_EQUALS("c", d.getTagForChunk(chunk));
+ }
}
} // namespace