Skip to content

Commit 9f90819

Browse files
committed
[yugabyte#24121] xCluster: Fix xcluster_outbound_replication_group-itest TestGetStreamByTableId
Summary: Test should wait for replication group creation before running DDLs. Refactored the test and added helper functions that will create a replication group and wait for it to be created. Fixed a bug in `GetNamespaceCheckpointInfo` where a variable was incorrectly used after move. Fixes yugabyte#24121 Jira: DB-13013 Test Plan: xcluster_outbound_replication_group-itest Reviewers: jhe, xCluster Reviewed By: jhe Subscribers: ybase Differential Revision: https://phorge.dev.yugabyte.com/D38399
1 parent 44ae377 commit 9f90819

File tree

2 files changed

+60
-65
lines changed

2 files changed

+60
-65
lines changed

src/yb/integration-tests/xcluster/xcluster_outbound_replication_group-itest.cc

Lines changed: 59 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,42 @@ class XClusterOutboundReplicationGroupTest : public XClusterYsqlTestBase {
7676
return table_info->id();
7777
}
7878

79+
// Create a new OutboundReplicationGroup. Use GetXClusterStreams, or IsBootstrapRequired to wait
80+
// for the new group to be ready.
81+
Status CreateOutboundReplicationGroupAsync(
82+
const xcluster::ReplicationGroupId& replication_group_id,
83+
const std::vector<NamespaceId>& namespace_ids) {
84+
return XClusterClient().CreateOutboundReplicationGroup(
85+
replication_group_id, namespace_ids, UseAutomaticMode());
86+
}
87+
88+
Status CreateOutboundReplicationGroupSync(
89+
const xcluster::ReplicationGroupId& replication_group_id = kReplicationGroupId,
90+
const std::vector<NamespaceId>& namespace_ids = {}) {
91+
auto namespace_ids_copy = namespace_ids;
92+
if (namespace_ids_copy.empty()) {
93+
namespace_ids_copy.push_back(namespace_id_);
94+
}
95+
96+
RETURN_NOT_OK(CreateOutboundReplicationGroupAsync(replication_group_id, namespace_ids_copy));
97+
for (const auto& namespace_id : namespace_ids_copy) {
98+
RETURN_NOT_OK(GetXClusterStreams(replication_group_id, namespace_id));
99+
}
100+
return Status::OK();
101+
}
102+
103+
Result<bool> IsBootstrapRequired(
104+
const xcluster::ReplicationGroupId& replication_group_id = kReplicationGroupId,
105+
const NamespaceId& namespace_id = {}) {
106+
std::promise<Result<bool>> promise;
107+
RETURN_NOT_OK(XClusterClient().IsBootstrapRequired(
108+
CoarseMonoClock::Now() + kDeadline, replication_group_id,
109+
namespace_id.empty() ? namespace_id_ : namespace_id,
110+
[&promise](Result<bool> result) { promise.set_value(std::move(result)); }));
111+
112+
return promise.get_future().get();
113+
}
114+
79115
// Cleanup streams marked for deletion and get the list of xcluster streams.
80116
std::unordered_set<xrepl::StreamId> CleanupAndGetAllXClusterStreams() {
81117
catalog_manager_->RunXReplBgTasks(epoch_);
@@ -132,7 +168,12 @@ class XClusterOutboundReplicationGroupTest : public XClusterYsqlTestBase {
132168
CoarseMonoClock::Now() + kDeadline, replication_group_id, namespace_id, table_names,
133169
pg_schema_names, [&promise](const auto& resp) { promise.set_value(resp); }));
134170

135-
return promise.get_future().get();
171+
auto resp = VERIFY_RESULT(promise.get_future().get());
172+
if (resp.has_error()) {
173+
return StatusFromPB(resp.error().status());
174+
}
175+
176+
return resp;
136177
}
137178

138179
Result<master::GetXClusterStreamsResponsePB> GetXClusterStreamsByTableId(
@@ -210,8 +251,7 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, TestMultipleTable) {
210251

211252
ASSERT_NOK(GetXClusterStreams(kReplicationGroupId, namespace_id_));
212253

213-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
214-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
254+
ASSERT_OK(CreateOutboundReplicationGroupSync());
215255

216256
auto resp = ASSERT_RESULT(GetXClusterStreams(kReplicationGroupId, namespace_id_));
217257

@@ -260,8 +300,7 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, AddDeleteNamespaces) {
260300
auto ns2_table_id_1 = ASSERT_RESULT(CreateYsqlTable(namespace_name_2, kTableName1));
261301
auto ns2_table_id_2 = ASSERT_RESULT(CreateYsqlTable(namespace_name_2, kTableName2));
262302

263-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
264-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
303+
ASSERT_OK(CreateOutboundReplicationGroupSync());
265304

266305
// Wait for the new streams to be ready.
267306
auto ns1_info = ASSERT_RESULT(GetXClusterStreams(kReplicationGroupId, namespace_id_));
@@ -324,11 +363,7 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, AddTable) {
324363
auto table_id_1 = ASSERT_RESULT(CreateYsqlTable(kNamespaceName, kTableName1));
325364
ASSERT_OK(VerifyWalRetentionOfTable(table_id_1, 900));
326365

327-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
328-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
329-
330-
// Wait for the new streams to be ready.
331-
ASSERT_OK(GetXClusterStreams(kReplicationGroupId, namespace_id_));
366+
ASSERT_OK(CreateOutboundReplicationGroupSync());
332367

333368
auto all_xcluster_streams_initial = CleanupAndGetAllXClusterStreams();
334369
ASSERT_EQ(all_xcluster_streams_initial.size(), 1 + OverheadStreamsCount());
@@ -349,17 +384,8 @@ TEST_F(XClusterOutboundReplicationGroupTest, IsBootstrapRequiredEmptyTable) {
349384
ANNOTATE_UNPROTECTED_WRITE(FLAGS_max_xcluster_streams_to_checkpoint_in_parallel) = 1;
350385

351386
auto table_id_1 = ASSERT_RESULT(CreateYsqlTable(kNamespaceName, kTableName1));
352-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
353-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
354-
355-
std::promise<Result<bool>> promise;
356-
357-
ASSERT_OK(XClusterClient().IsBootstrapRequired(
358-
CoarseMonoClock::Now() + kDeadline, kReplicationGroupId, namespace_id_,
359-
[&promise](Result<bool> result) { promise.set_value(std::move(result)); }));
360-
361-
auto is_bootstrap_required = ASSERT_RESULT(promise.get_future().get());
362-
ASSERT_FALSE(is_bootstrap_required);
387+
ASSERT_OK(CreateOutboundReplicationGroupSync());
388+
ASSERT_FALSE(ASSERT_RESULT(IsBootstrapRequired()));
363389
}
364390

365391
TEST_F(XClusterOutboundReplicationGroupTest, IsBootstrapRequiredTableWithData) {
@@ -371,17 +397,8 @@ TEST_F(XClusterOutboundReplicationGroupTest, IsBootstrapRequiredTableWithData) {
371397
ASSERT_OK(producer_client()->OpenTable(table_id_2, &table_2));
372398
ASSERT_OK(InsertRowsInProducer(0, 10, table_2));
373399

374-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
375-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
376-
377-
std::promise<Result<bool>> promise;
378-
379-
ASSERT_OK(XClusterClient().IsBootstrapRequired(
380-
CoarseMonoClock::Now() + kDeadline, kReplicationGroupId, namespace_id_,
381-
[&promise](Result<bool> result) { promise.set_value(std::move(result)); }));
382-
383-
auto is_bootstrap_required = ASSERT_RESULT(promise.get_future().get());
384-
ASSERT_TRUE(is_bootstrap_required);
400+
ASSERT_OK(CreateOutboundReplicationGroupSync());
401+
ASSERT_TRUE(ASSERT_RESULT(IsBootstrapRequired()));
385402
}
386403

387404
TEST_F(XClusterOutboundReplicationGroupTest, IsBootstrapRequiredTableWithDeletedData) {
@@ -394,17 +411,9 @@ TEST_F(XClusterOutboundReplicationGroupTest, IsBootstrapRequiredTableWithDeleted
394411
ASSERT_OK(InsertRowsInProducer(0, 10, table_2));
395412
ASSERT_OK(DeleteRowsInProducer(0, 10, table_2));
396413

397-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
398-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
414+
ASSERT_OK(CreateOutboundReplicationGroupSync());
399415

400-
std::promise<Result<bool>> promise;
401-
402-
ASSERT_OK(XClusterClient().IsBootstrapRequired(
403-
CoarseMonoClock::Now() + kDeadline, kReplicationGroupId, namespace_id_,
404-
[&promise](Result<bool> result) { promise.set_value(std::move(result)); }));
405-
406-
auto is_bootstrap_required = ASSERT_RESULT(promise.get_future().get());
407-
ASSERT_FALSE(is_bootstrap_required);
416+
ASSERT_FALSE(ASSERT_RESULT(IsBootstrapRequired()));
408417
}
409418

410419
TEST_P(XClusterOutboundReplicationGroupParameterized, MasterRestartDuringCheckpoint) {
@@ -421,8 +430,7 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, MasterRestartDuringCheckpo
421430

422431
ANNOTATE_UNPROTECTED_WRITE(FLAGS_TEST_block_xcluster_checkpoint_namespace_task) = true;
423432

424-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
425-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
433+
ASSERT_OK(CreateOutboundReplicationGroupAsync(kReplicationGroupId, {namespace_id_}));
426434

427435
std::promise<Result<master::GetXClusterStreamsResponsePB>> promise;
428436
auto future = promise.get_future();
@@ -449,8 +457,7 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, Repair) {
449457
auto table_id_1 = ASSERT_RESULT(CreateYsqlTable(kNamespaceName, kTableName1));
450458
auto table_id_2 = ASSERT_RESULT(CreateYsqlTable(kNamespaceName, kTableName2));
451459

452-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
453-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
460+
ASSERT_OK(CreateOutboundReplicationGroupSync());
454461

455462
auto resp = ASSERT_RESULT(GetXClusterStreams(kReplicationGroupId, namespace_id_));
456463
ASSERT_EQ(resp.table_infos_size(), 2 + OverheadStreamsCount());
@@ -546,8 +553,7 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, RepairWithYbAdmin) {
546553
auto table_id_1 = ASSERT_RESULT(CreateYsqlTable(kNamespaceName, kTableName1));
547554
auto table_id_2 = ASSERT_RESULT(CreateYsqlTable(kNamespaceName, kTableName2));
548555

549-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
550-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
556+
ASSERT_OK(CreateOutboundReplicationGroupSync());
551557

552558
auto resp = ASSERT_RESULT(GetXClusterStreams(kReplicationGroupId, namespace_id_));
553559
ASSERT_EQ(resp.table_infos_size(), 2 + OverheadStreamsCount());
@@ -589,11 +595,8 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, TestListAPIs) {
589595
ASSERT_OK(CreateYsqlTable(namespace_name_2, "table_2"));
590596

591597
// Replication group 1 with two namespaces.
592-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
593-
kReplicationGroupId, {namespace_id_, namespace_id_2}, UseAutomaticMode()));
594-
// Wait for checkpointing to complete.
595-
ASSERT_OK(GetXClusterStreams(kReplicationGroupId, namespace_id_));
596-
ASSERT_OK(GetXClusterStreams(kReplicationGroupId, namespace_id_2));
598+
ASSERT_OK(
599+
CreateOutboundReplicationGroupSync(kReplicationGroupId, {namespace_id_, namespace_id_2}));
597600
{
598601
auto group_info = ASSERT_RESULT(
599602
XClusterClient().GetXClusterOutboundReplicationGroupInfo(kReplicationGroupId));
@@ -606,10 +609,7 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, TestListAPIs) {
606609

607610
// Replication group 2 with one namespace.
608611
const xcluster::ReplicationGroupId replication_group2("rg2");
609-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
610-
replication_group2, {namespace_id_}, UseAutomaticMode()));
611-
ASSERT_OK(GetXClusterStreams(replication_group2, namespace_id_));
612-
// Wait for checkpointing to complete.
612+
ASSERT_OK(CreateOutboundReplicationGroupSync(replication_group2, {namespace_id_}));
613613
{
614614
auto group_info =
615615
ASSERT_RESULT(XClusterClient().GetXClusterOutboundReplicationGroupInfo(replication_group2));
@@ -679,8 +679,7 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, TestListAPIs) {
679679
// Make sure we cleanup the streams of the failed table create.
680680
TEST_P(XClusterOutboundReplicationGroupParameterized, CleanupStreamsOfFailedTableCreate) {
681681
auto table_id_1 = ASSERT_RESULT(CreateYsqlTable(kNamespaceName, kTableName1));
682-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
683-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
682+
ASSERT_OK(CreateOutboundReplicationGroupSync());
684683
int expected_stream_count = 1 + OverheadStreamsCount();
685684

686685
auto check_streams = [&]() -> Status {
@@ -719,11 +718,7 @@ TEST_P(XClusterOutboundReplicationGroupParameterized, CleanupStreamsOfFailedTabl
719718
TEST_P(XClusterOutboundReplicationGroupParameterized, TestGetStreamByTableId) {
720719
auto table_id_1 = ASSERT_RESULT(CreateYsqlTable(kNamespaceName, kTableName1));
721720

722-
ASSERT_OK(XClusterClient().CreateOutboundReplicationGroup(
723-
kReplicationGroupId, {namespace_id_}, UseAutomaticMode()));
724-
725-
// Wait for the namespace to be ready.
726-
ASSERT_OK(GetXClusterStreams(kReplicationGroupId, namespace_id_));
721+
ASSERT_OK(CreateOutboundReplicationGroupSync());
727722

728723
// Delete the table to put it into HIDDEN state.
729724
ASSERT_OK(DropYsqlTable(&producer_cluster_, kNamespaceName, kPgSchemaName, kTableName1));

src/yb/master/xcluster/xcluster_outbound_replication_group.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ XClusterOutboundReplicationGroup::GetNamespaceCheckpointInfo(
645645
auto it = InsertOrReturnExisting(
646646
&table_names_map,
647647
{TableSchemaNamePair(table_descriptor.name(), table_descriptor.pgschema_name()),
648-
std::move(table_descriptor)});
648+
table_descriptor});
649649
SCHECK(
650650
!it, AlreadyPresent,
651651
Format(

0 commit comments

Comments
 (0)