YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/integration-tests/sys_catalog_respect_affinity-test.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
#include <gtest/gtest.h>
14
15
#include "yb/consensus/consensus.pb.h"
16
#include "yb/consensus/consensus.proxy.h"
17
18
#include "yb/integration-tests/external_mini_cluster.h"
19
#include "yb/integration-tests/mini_cluster.h"
20
#include "yb/integration-tests/yb_table_test_base.h"
21
22
#include "yb/master/master_cluster.proxy.h"
23
24
#include "yb/tools/yb-admin_client.h"
25
26
#include "yb/util/monotime.h"
27
#include "yb/util/result.h"
28
29
DECLARE_int32(catalog_manager_bg_task_wait_ms);
30
31
using namespace std::literals;
32
using strings::Substitute;
33
34
namespace yb {
35
namespace integration_tests {
36
37
const auto kDefaultTimeout = 30000ms;
38
39
class SysCatalogRespectAffinityTest : public YBTableTestBase {
40
 protected:
41
10
  bool use_yb_admin_client() override { return true; }
42
43
25
  bool use_external_mini_cluster() override { return true; }
44
45
25
  size_t num_masters() override {
46
25
    return 3;
47
25
  }
48
49
15
  size_t num_tablet_servers() override {
50
15
    return 3;
51
15
  }
52
53
5
  bool enable_ysql() override {
54
5
    return false;
55
5
  }
56
57
  Result<bool> IsMasterLeaderInZone(
58
      const std::string& placement_cloud,
59
      const std::string& placement_region,
60
0
      const std::string& placement_zone) {
61
0
    master::ListMastersRequestPB req;
62
0
    master::ListMastersResponsePB resp;
63
0
    rpc::RpcController rpc;
64
0
    rpc.set_timeout(kDefaultTimeout);
65
0
    auto proxy = GetMasterLeaderProxy<master::MasterClusterProxy>();
66
0
    RETURN_NOT_OK(proxy.ListMasters(req, &resp, &rpc));
67
68
0
    for (const ServerEntryPB& master : resp.masters()) {
69
0
      if (master.role() == yb::PeerRole::LEADER) {
70
0
        auto cloud_info = master.registration().cloud_info();
71
0
        return (cloud_info.placement_cloud() == placement_cloud &&
72
0
                cloud_info.placement_region() == placement_region &&
73
0
                cloud_info.placement_zone() == placement_zone);
74
0
      }
75
0
    }
76
77
0
    return false;
78
0
  }
79
80
0
  Result<std::string> GetMasterLeaderZone() {
81
0
    master::GetMasterRegistrationRequestPB req;
82
0
    master::GetMasterRegistrationResponsePB resp;
83
0
    rpc::RpcController rpc;
84
0
    rpc.set_timeout(kDefaultTimeout);
85
0
    auto proxy = GetMasterLeaderProxy<master::MasterClusterProxy>();
86
0
    RETURN_NOT_OK(proxy.GetMasterRegistration(req, &resp, &rpc));
87
0
    return resp.registration().cloud_info().placement_zone();
88
0
  }
89
90
5
  void CustomizeExternalMiniCluster(ExternalMiniClusterOptions* opts) override {
91
5
    opts->extra_master_flags.push_back("--sys_catalog_respect_affinity_task=true");
92
5
    opts->extra_master_flags.push_back("--placement_cloud=c");
93
5
    opts->extra_master_flags.push_back("--placement_region=r");
94
5
    opts->extra_master_flags.push_back("--placement_zone=z${index}");
95
5
  }
96
};
97
98
1
TEST_F(SysCatalogRespectAffinityTest, TestNoPreferredZones) {
99
1
  ASSERT_OK(yb_admin_client_->ModifyPlacementInfo("c.r.z0,c.r.z1,c.r.z2", 3, ""));
100
0
  std::string leader_zone = ASSERT_RESULT(GetMasterLeaderZone());
101
0
  ASSERT_OK(WaitFor([&]() {
102
0
    return IsMasterLeaderInZone("c", "r", leader_zone);
103
0
  }, kDefaultTimeout, "Master leader zone"));
104
105
0
  SleepFor(MonoDelta::FromMilliseconds(2 * FLAGS_catalog_manager_bg_task_wait_ms));
106
107
0
  ASSERT_OK(WaitFor([&]() {
108
0
    return IsMasterLeaderInZone("c", "r", leader_zone);
109
0
  }, kDefaultTimeout, "Master leader zone"));
110
0
}
111
112
1
TEST_F(SysCatalogRespectAffinityTest, TestInPreferredZone) {
113
1
  ASSERT_OK(yb_admin_client_->ModifyPlacementInfo("c.r.z0,c.r.z1,c.r.z2", 3, ""));
114
0
  std::string leader_zone = ASSERT_RESULT(GetMasterLeaderZone());
115
0
  ASSERT_OK(yb_admin_client_->SetPreferredZones({ Substitute("c.r.$0", leader_zone) }));
116
0
  ASSERT_OK(WaitFor([&]() {
117
0
    return IsMasterLeaderInZone("c", "r", leader_zone);
118
0
  }, kDefaultTimeout, "Master leader stepdown"));
119
0
}
120
121
1
TEST_F(SysCatalogRespectAffinityTest, TestMoveToPreferredZone) {
122
1
  ASSERT_OK(yb_admin_client_->ModifyPlacementInfo("c.r.z0,c.r.z1,c.r.z2", 3, ""));
123
0
  std::string leader_zone = ASSERT_RESULT(GetMasterLeaderZone());
124
0
  int leader_zone_idx = leader_zone[1] - '0';
125
0
  std::string next_zone = Substitute("z$0", (leader_zone_idx + 1) % 3);
126
0
  ASSERT_OK(yb_admin_client_->SetPreferredZones({ Substitute("c.r.$0", next_zone) }));
127
0
  ASSERT_OK(WaitFor([&]() {
128
0
    return IsMasterLeaderInZone("c", "r", next_zone);
129
0
  }, kDefaultTimeout, "Master leader stepdown"));
130
0
}
131
132
// Note for these tests: there is an edge case where the master goes down between ListMasters
133
// and StepDown, which is not tested here. The behavior should be the same, however.
134
135
1
TEST_F(SysCatalogRespectAffinityTest, TestPreferredZoneMasterDown) {
136
1
  ASSERT_OK(yb_admin_client_->ModifyPlacementInfo("c.r.z0,c.r.z1,c.r.z2", 3, ""));
137
0
  std::string leader_zone = ASSERT_RESULT(GetMasterLeaderZone());
138
0
  int leader_zone_idx = leader_zone[1] - '0';
139
0
  int next_zone_idx = (leader_zone_idx + 1) % 3;
140
141
0
  external_mini_cluster()->master(next_zone_idx)->Shutdown();
142
0
  ASSERT_OK(yb_admin_client_->SetPreferredZones({ Substitute("c.r.z$0", next_zone_idx)}));
143
0
  SleepFor(MonoDelta::FromMilliseconds(2000));
144
0
  ASSERT_OK(WaitFor([&]() {
145
0
    return IsMasterLeaderInZone("c", "r", leader_zone);
146
0
  }, kDefaultTimeout, "Master leader stepdown"));
147
0
}
148
149
1
TEST_F(SysCatalogRespectAffinityTest, TestMultiplePreferredZones) {
150
1
  ASSERT_OK(yb_admin_client_->ModifyPlacementInfo("c.r.z0,c.r.z1,c.r.z2", 3, ""));
151
0
  std::string leader_zone = ASSERT_RESULT(GetMasterLeaderZone());
152
0
  int leader_zone_idx = leader_zone[1] - '0';
153
0
  int first_zone_idx = (leader_zone_idx + 1) % 3;
154
0
  int second_zone_idx = (leader_zone_idx + 2) % 3;
155
156
0
  external_mini_cluster()->master(first_zone_idx)->Shutdown();
157
0
  ASSERT_OK(yb_admin_client_->SetPreferredZones(
158
0
      { Substitute("c.r.z$0", first_zone_idx), Substitute("c.r.z$0", second_zone_idx) }));
159
0
  ASSERT_OK(WaitFor([&]() {
160
0
    return IsMasterLeaderInZone("c", "r", Substitute("z$0", second_zone_idx));
161
0
  }, kDefaultTimeout, "Master leader stepdown"));
162
0
}
163
164
} // namespace integration_tests
165
} // namespace yb