diff options
Diffstat (limited to 'src/mongo/db/s/balancer/balancer_policy_test.cpp')
| -rw-r--r-- | src/mongo/db/s/balancer/balancer_policy_test.cpp | 510 |
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 |
