@@ -556,84 +556,87 @@ Y_UNIT_TEST_SUITE(TCdcStreamWithRebootsTests) {
556
556
});
557
557
}
558
558
559
+ bool CheckRegistrations (TTestActorRuntime& runtime, NKikimrPQ::TMessageGroupInfo::EState expectedState,
560
+ const google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TTablePartition>& tablePartitions,
561
+ const google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TPersQueueGroupDescription::TPartition>& topicPartitions)
562
+ {
563
+ for (const auto & topicPartition : topicPartitions) {
564
+ auto request = MakeHolder<TEvPersQueue::TEvRequest>();
565
+ {
566
+ auto & record = *request->Record .MutablePartitionRequest ();
567
+ record.SetPartition (topicPartition.GetPartitionId ());
568
+ auto & cmd = *record.MutableCmdGetMaxSeqNo ();
569
+ for (const auto & tablePartition : tablePartitions) {
570
+ cmd.AddSourceId (NPQ::NSourceIdEncoding::EncodeSimple (ToString (tablePartition.GetDatashardId ())));
571
+ }
572
+ }
573
+
574
+ const auto & sender = runtime.AllocateEdgeActor ();
575
+ ForwardToTablet (runtime, topicPartition.GetTabletId (), sender, request.Release ());
576
+
577
+ auto response = runtime.GrabEdgeEvent <TEvPersQueue::TEvResponse>(sender);
578
+ {
579
+ const auto & record = response->Get ()->Record .GetPartitionResponse ();
580
+ const auto & result = record.GetCmdGetMaxSeqNoResult ().GetSourceIdInfo ();
581
+
582
+ UNIT_ASSERT_VALUES_EQUAL (result.size (), tablePartitions.size ());
583
+ for (const auto & item: result) {
584
+ if (item.GetState () != expectedState) {
585
+ return false ;
586
+ }
587
+ }
588
+ }
589
+ }
590
+
591
+ return true ;
592
+ }
593
+
559
594
struct TItem {
560
595
TString Path;
561
- ui32 nPartitions ;
596
+ ui32 ExpectedPartitionCount ;
562
597
};
563
598
564
- void CheckRegistrations (TTestActorRuntime& runtime, const TItem& table, const TItem& topic) {
599
+ void CheckRegistrations (TTestActorRuntime& runtime, const TItem& table, const TItem& topic,
600
+ const google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TTablePartition>* initialTablePartitions = nullptr )
601
+ {
565
602
auto tableDesc = DescribePath (runtime, table.Path , true , true );
566
603
const auto & tablePartitions = tableDesc.GetPathDescription ().GetTablePartitions ();
567
- UNIT_ASSERT_VALUES_EQUAL (tablePartitions.size (), table.nPartitions );
604
+ UNIT_ASSERT_VALUES_EQUAL (tablePartitions.size (), table.ExpectedPartitionCount );
568
605
569
606
auto topicDesc = DescribePrivatePath (runtime, topic.Path );
570
607
const auto & topicPartitions = topicDesc.GetPathDescription ().GetPersQueueGroup ().GetPartitions ();
571
- UNIT_ASSERT_VALUES_EQUAL (topicPartitions.size (), topic.nPartitions );
608
+ UNIT_ASSERT_VALUES_EQUAL (topicPartitions.size (), topic.ExpectedPartitionCount );
572
609
573
610
while (true ) {
574
611
runtime.SimulateSleep (TDuration::Seconds (1 ));
575
- bool done = true ;
576
-
577
- for (ui32 i = 0 ; i < topic.nPartitions ; ++i) {
578
- auto request = MakeHolder<TEvPersQueue::TEvRequest>();
579
- {
580
- auto & record = *request->Record .MutablePartitionRequest ();
581
- record.SetPartition (topicPartitions[i].GetPartitionId ());
582
- auto & cmd = *record.MutableCmdGetMaxSeqNo ();
583
- for (const auto & tablePartition : tablePartitions) {
584
- cmd.AddSourceId (NPQ::NSourceIdEncoding::EncodeSimple (ToString (tablePartition.GetDatashardId ())));
585
- }
586
- }
587
-
588
- const auto & sender = runtime.AllocateEdgeActor ();
589
- ForwardToTablet (runtime, topicPartitions[i].GetTabletId (), sender, request.Release ());
590
-
591
- auto response = runtime.GrabEdgeEvent <TEvPersQueue::TEvResponse>(sender);
592
- {
593
- const auto & record = response->Get ()->Record .GetPartitionResponse ();
594
- const auto & result = record.GetCmdGetMaxSeqNoResult ().GetSourceIdInfo ();
595
-
596
- UNIT_ASSERT_VALUES_EQUAL (result.size (), table.nPartitions );
597
- for (const auto & item: result) {
598
- done &= item.GetState () == NKikimrPQ::TMessageGroupInfo::STATE_REGISTERED;
599
- if (!done) {
600
- break ;
601
- }
602
- }
603
- }
604
-
605
- if (!done) {
606
- break ;
607
- }
608
- }
609
-
610
- if (done) {
612
+ if (CheckRegistrations (runtime, NKikimrPQ::TMessageGroupInfo::STATE_REGISTERED, tablePartitions, topicPartitions)) {
611
613
break ;
612
614
}
613
615
}
616
+
617
+ if (initialTablePartitions) {
618
+ UNIT_ASSERT (CheckRegistrations (runtime, NKikimrPQ::TMessageGroupInfo::STATE_UNKNOWN, *initialTablePartitions, topicPartitions));
619
+ }
614
620
}
615
621
616
- Y_UNIT_TEST_WITH_REBOOTS (SplitTable) {
622
+ template <typename T>
623
+ void SplitTable (const TString& cdcStreamDesc) {
617
624
T t;
618
625
t.Run ([&](TTestActorRuntime& runtime, bool & activeZone) {
626
+ NKikimrScheme::TEvDescribeSchemeResult initialTableDesc;
619
627
{
620
628
TInactiveZone inactive (activeZone);
629
+
621
630
TestCreateTable (runtime, ++t.TxId , " /MyRoot" , R"(
622
631
Name: "Table"
623
632
Columns { Name: "key" Type: "Uint32" }
624
633
Columns { Name: "value" Type: "Uint32" }
625
634
KeyColumnNames: ["key"]
626
635
)" );
627
636
t.TestEnv ->TestWaitNotification (runtime, t.TxId );
637
+ initialTableDesc = DescribePath (runtime, " /MyRoot/Table" , true , true );
628
638
629
- TestCreateCdcStream (runtime, ++t.TxId , " /MyRoot" , R"(
630
- TableName: "Table"
631
- StreamDescription {
632
- Name: "Stream"
633
- Mode: ECdcStreamModeKeysOnly
634
- Format: ECdcStreamFormatProto
635
- }
636
- )" );
639
+ TestCreateCdcStream (runtime, ++t.TxId , " /MyRoot" , cdcStreamDesc);
637
640
t.TestEnv ->TestWaitNotification (runtime, t.TxId );
638
641
}
639
642
@@ -651,16 +654,43 @@ Y_UNIT_TEST_SUITE(TCdcStreamWithRebootsTests) {
651
654
TInactiveZone inactive (activeZone);
652
655
UploadRow (runtime, " /MyRoot/Table" , 0 , {1 }, {2 }, {TCell::Make (1u )}, {TCell::Make (1u )});
653
656
UploadRow (runtime, " /MyRoot/Table" , 1 , {1 }, {2 }, {TCell::Make (Max<ui32>())}, {TCell::Make (Max<ui32>())});
654
- CheckRegistrations (runtime, {" /MyRoot/Table" , 2 }, {" /MyRoot/Table/Stream/streamImpl" , 1 });
657
+ CheckRegistrations (runtime, {" /MyRoot/Table" , 2 }, {" /MyRoot/Table/Stream/streamImpl" , 1 },
658
+ &initialTableDesc.GetPathDescription ().GetTablePartitions ());
655
659
}
656
660
});
657
661
}
658
662
659
- Y_UNIT_TEST_WITH_REBOOTS (MergeTable) {
663
+ Y_UNIT_TEST_WITH_REBOOTS (SplitTable) {
664
+ SplitTable<T>(R"(
665
+ TableName: "Table"
666
+ StreamDescription {
667
+ Name: "Stream"
668
+ Mode: ECdcStreamModeKeysOnly
669
+ Format: ECdcStreamFormatProto
670
+ }
671
+ )" );
672
+ }
673
+
674
+ Y_UNIT_TEST_WITH_REBOOTS (SplitTableResolvedTimestamps) {
675
+ SplitTable<T>(R"(
676
+ TableName: "Table"
677
+ StreamDescription {
678
+ Name: "Stream"
679
+ Mode: ECdcStreamModeKeysOnly
680
+ Format: ECdcStreamFormatProto
681
+ ResolvedTimestampsIntervalMs: 1000
682
+ }
683
+ )" );
684
+ }
685
+
686
+ template <typename T>
687
+ void MergeTable (const TString& cdcStreamDesc) {
660
688
T t;
661
689
t.Run ([&](TTestActorRuntime& runtime, bool & activeZone) {
690
+ NKikimrScheme::TEvDescribeSchemeResult initialTableDesc;
662
691
{
663
692
TInactiveZone inactive (activeZone);
693
+
664
694
TestCreateTable (runtime, ++t.TxId , " /MyRoot" , R"(
665
695
Name: "Table"
666
696
Columns { Name: "key" Type: "Uint32" }
@@ -674,15 +704,9 @@ Y_UNIT_TEST_SUITE(TCdcStreamWithRebootsTests) {
674
704
}
675
705
)" );
676
706
t.TestEnv ->TestWaitNotification (runtime, t.TxId );
707
+ initialTableDesc = DescribePath (runtime, " /MyRoot/Table" , true , true );
677
708
678
- TestCreateCdcStream (runtime, ++t.TxId , " /MyRoot" , R"(
679
- TableName: "Table"
680
- StreamDescription {
681
- Name: "Stream"
682
- Mode: ECdcStreamModeKeysOnly
683
- Format: ECdcStreamFormatProto
684
- }
685
- )" );
709
+ TestCreateCdcStream (runtime, ++t.TxId , " /MyRoot" , cdcStreamDesc);
686
710
t.TestEnv ->TestWaitNotification (runtime, t.TxId );
687
711
}
688
712
@@ -696,11 +720,35 @@ Y_UNIT_TEST_SUITE(TCdcStreamWithRebootsTests) {
696
720
TInactiveZone inactive (activeZone);
697
721
UploadRow (runtime, " /MyRoot/Table" , 0 , {1 }, {2 }, {TCell::Make (1u )}, {TCell::Make (1u )});
698
722
UploadRow (runtime, " /MyRoot/Table" , 0 , {1 }, {2 }, {TCell::Make (Max<ui32>())}, {TCell::Make (Max<ui32>())});
699
- CheckRegistrations (runtime, {" /MyRoot/Table" , 1 }, {" /MyRoot/Table/Stream/streamImpl" , 2 });
723
+ CheckRegistrations (runtime, {" /MyRoot/Table" , 1 }, {" /MyRoot/Table/Stream/streamImpl" , 2 },
724
+ &initialTableDesc.GetPathDescription ().GetTablePartitions ());
700
725
}
701
726
});
702
727
}
703
728
729
+ Y_UNIT_TEST_WITH_REBOOTS (MergeTable) {
730
+ MergeTable<T>(R"(
731
+ TableName: "Table"
732
+ StreamDescription {
733
+ Name: "Stream"
734
+ Mode: ECdcStreamModeKeysOnly
735
+ Format: ECdcStreamFormatProto
736
+ }
737
+ )" );
738
+ }
739
+
740
+ Y_UNIT_TEST_WITH_REBOOTS (MergeTableResolvedTimestamps) {
741
+ MergeTable<T>(R"(
742
+ TableName: "Table"
743
+ StreamDescription {
744
+ Name: "Stream"
745
+ Mode: ECdcStreamModeKeysOnly
746
+ Format: ECdcStreamFormatProto
747
+ ResolvedTimestampsIntervalMs: 1000
748
+ }
749
+ )" );
750
+ }
751
+
704
752
Y_UNIT_TEST_WITH_REBOOTS (RacySplitTableAndCreateStream) {
705
753
T t;
706
754
t.Run ([&](TTestActorRuntime& runtime, bool & activeZone) {
0 commit comments