@@ -31,10 +31,15 @@ class TFixture : public NUnitTest::TBaseFixture {
3131 TTopicWriteSessionPtr Session;
3232 TMaybe<NTopic::TContinuationToken> ContinuationToken;
3333 size_t WriteCount = 0 ;
34- size_t AckCount = 0 ;
34+ size_t WrittenAckCount = 0 ;
35+ size_t WrittenInTxAckCount = 0 ;
3536
3637 void WaitForContinuationToken ();
3738 void Write (const TString& message, NTable::TTransaction* tx = nullptr );
39+
40+ size_t AckCount () const { return WrittenAckCount + WrittenInTxAckCount; }
41+
42+ void WaitForEvent ();
3843 };
3944
4045 void SetUp (NUnitTest::TTestContext&) override ;
@@ -88,7 +93,8 @@ class TFixture : public NUnitTest::TBaseFixture {
8893 NTable::TTransaction* tx = nullptr ,
8994 TMaybe<ui32> partitionId = Nothing());
9095 void WaitForAcks (const TString& topicPath,
91- const TString& messageGroupId);
96+ const TString& messageGroupId,
97+ size_t writtenInTxCount = Max<size_t >());
9298 void WaitForSessionClose (const TString& topicPath,
9399 const TString& messageGroupId,
94100 NYdb::EStatus status);
@@ -591,19 +597,31 @@ auto TFixture::GetTopicReadSession(const TString& topicPath,
591597void TFixture::TTopicWriteSessionContext::WaitForContinuationToken ()
592598{
593599 while (!ContinuationToken.Defined ()) {
594- Session->WaitEvent ().Wait ();
595- for (auto & event : Session->GetEvents ()) {
596- if (auto * e = std::get_if<NTopic::TWriteSessionEvent::TReadyToAcceptEvent>(&event)) {
597- ContinuationToken = std::move (e->ContinuationToken );
598- } else if (auto * e = std::get_if<NTopic::TWriteSessionEvent::TAcksEvent>(&event)) {
599- for (auto & ack : e->Acks ) {
600- if (ack.State == NTopic::TWriteSessionEvent::TWriteAck::EES_WRITTEN) {
601- ++AckCount;
602- }
600+ WaitForEvent ();
601+ }
602+ }
603+
604+ void TFixture::TTopicWriteSessionContext::WaitForEvent ()
605+ {
606+ Session->WaitEvent ().Wait ();
607+ for (auto & event : Session->GetEvents ()) {
608+ if (auto * e = std::get_if<NTopic::TWriteSessionEvent::TReadyToAcceptEvent>(&event)) {
609+ ContinuationToken = std::move (e->ContinuationToken );
610+ } else if (auto * e = std::get_if<NTopic::TWriteSessionEvent::TAcksEvent>(&event)) {
611+ for (auto & ack : e->Acks ) {
612+ switch (ack.State ) {
613+ case NTopic::TWriteSessionEvent::TWriteAck::EES_WRITTEN:
614+ ++WrittenAckCount;
615+ break ;
616+ case NTopic::TWriteSessionEvent::TWriteAck::EES_WRITTEN_IN_TX:
617+ ++WrittenInTxAckCount;
618+ break ;
619+ default :
620+ break ;
603621 }
604- } else if (auto * e = std::get_if<NTopic::TSessionClosedEvent>(&event)) {
605- UNIT_FAIL (" " );
606622 }
623+ } else if (auto * e = std::get_if<NTopic::TSessionClosedEvent>(&event)) {
624+ UNIT_FAIL (" " );
607625 }
608626 }
609627}
@@ -691,34 +709,25 @@ TVector<TString> TFixture::ReadFromTopic(const TString& topicPath,
691709 return messages;
692710}
693711
694- void TFixture::WaitForAcks (const TString& topicPath, const TString& messageGroupId)
712+ void TFixture::WaitForAcks (const TString& topicPath, const TString& messageGroupId, size_t writtenInTxCount )
695713{
696714 std::pair<TString, TString> key (topicPath, messageGroupId);
697715 auto i = TopicWriteSessions.find (key);
698716 UNIT_ASSERT (i != TopicWriteSessions.end ());
699717
700718 auto & context = i->second ;
701719
702- UNIT_ASSERT (context.AckCount <= context.WriteCount );
720+ UNIT_ASSERT (context.AckCount () <= context.WriteCount );
703721
704- while (context.AckCount < context.WriteCount ) {
705- context.Session ->WaitEvent ().Wait ();
706- for (auto & event : context.Session ->GetEvents ()) {
707- if (auto * e = std::get_if<NTopic::TWriteSessionEvent::TReadyToAcceptEvent>(&event)) {
708- context.ContinuationToken = std::move (e->ContinuationToken );
709- } else if (auto * e = std::get_if<NTopic::TWriteSessionEvent::TAcksEvent>(&event)) {
710- for (auto & ack : e->Acks ) {
711- if (ack.State == NTopic::TWriteSessionEvent::TWriteAck::EES_WRITTEN) {
712- ++context.AckCount ;
713- }
714- }
715- } else if (auto * e = std::get_if<NTopic::TSessionClosedEvent>(&event)) {
716- UNIT_FAIL (" " );
717- }
718- }
722+ while (context.AckCount () < context.WriteCount ) {
723+ context.WaitForEvent ();
719724 }
720725
721- UNIT_ASSERT (context.AckCount == context.WriteCount );
726+ UNIT_ASSERT ((context.WrittenAckCount + context.WrittenInTxAckCount ) == context.WriteCount );
727+
728+ if (writtenInTxCount != Max<size_t >()) {
729+ UNIT_ASSERT_VALUES_EQUAL (context.WrittenInTxAckCount , writtenInTxCount);
730+ }
722731}
723732
724733void TFixture::WaitForSessionClose (const TString& topicPath,
@@ -731,7 +740,7 @@ void TFixture::WaitForSessionClose(const TString& topicPath,
731740
732741 auto & context = i->second ;
733742
734- UNIT_ASSERT (context.AckCount <= context.WriteCount );
743+ UNIT_ASSERT (context.AckCount () <= context.WriteCount );
735744
736745 for (bool stop = false ; !stop; ) {
737746 context.Session ->WaitEvent ().Wait ();
@@ -740,8 +749,15 @@ void TFixture::WaitForSessionClose(const TString& topicPath,
740749 context.ContinuationToken = std::move (e->ContinuationToken );
741750 } else if (auto * e = std::get_if<NTopic::TWriteSessionEvent::TAcksEvent>(&event)) {
742751 for (auto & ack : e->Acks ) {
743- if (ack.State == NTopic::TWriteSessionEvent::TWriteAck::EES_WRITTEN) {
744- ++context.AckCount ;
752+ switch (ack.State ) {
753+ case NTopic::TWriteSessionEvent::TWriteAck::EES_WRITTEN:
754+ ++context.WrittenAckCount ;
755+ break ;
756+ case NTopic::TWriteSessionEvent::TWriteAck::EES_WRITTEN_IN_TX:
757+ ++context.WrittenInTxAckCount ;
758+ break ;
759+ default :
760+ break ;
745761 }
746762 }
747763 } else if (auto * e = std::get_if<NTopic::TSessionClosedEvent>(&event)) {
@@ -752,7 +768,7 @@ void TFixture::WaitForSessionClose(const TString& topicPath,
752768 }
753769 }
754770
755- UNIT_ASSERT (context.AckCount <= context.WriteCount );
771+ UNIT_ASSERT (context.AckCount () <= context.WriteCount );
756772}
757773
758774ui64 TFixture::GetTopicTabletId (const TActorId& actorId, const TString& topicPath, ui32 partition)
@@ -1852,7 +1868,7 @@ Y_UNIT_TEST_F(WriteToTopic_Demo_27, TFixture)
18521868 CreateTopic (" topic_B" , TEST_CONSUMER);
18531869 CreateTopic (" topic_C" , TEST_CONSUMER);
18541870
1855- for (size_t i = 0 ; i < 2 ; ++i) {
1871+ for (size_t i = 0 , writtenInTx = 0 ; i < 2 ; ++i) {
18561872 WriteToTopic (" topic_A" , TEST_MESSAGE_GROUP_ID, " message #1" , nullptr , 0 );
18571873 WriteToTopic (" topic_B" , TEST_MESSAGE_GROUP_ID, " message #2" , nullptr , 0 );
18581874
@@ -1862,12 +1878,14 @@ Y_UNIT_TEST_F(WriteToTopic_Demo_27, TFixture)
18621878 auto messages = ReadFromTopic (" topic_A" , TEST_CONSUMER, TDuration::Seconds (2 ), &tx, 0 );
18631879 UNIT_ASSERT_VALUES_EQUAL (messages.size (), 1 );
18641880 WriteToTopic (" topic_C" , TEST_MESSAGE_GROUP_ID, messages[0 ], &tx, 0 );
1865- WaitForAcks (" topic_C" , TEST_MESSAGE_GROUP_ID);
1881+ ++writtenInTx;
1882+ WaitForAcks (" topic_C" , TEST_MESSAGE_GROUP_ID, writtenInTx);
18661883
18671884 messages = ReadFromTopic (" topic_B" , TEST_CONSUMER, TDuration::Seconds (2 ), &tx, 0 );
18681885 UNIT_ASSERT_VALUES_EQUAL (messages.size (), 1 );
18691886 WriteToTopic (" topic_C" , TEST_MESSAGE_GROUP_ID, messages[0 ], &tx, 0 );
1870- WaitForAcks (" topic_C" , TEST_MESSAGE_GROUP_ID);
1887+ ++writtenInTx;
1888+ WaitForAcks (" topic_C" , TEST_MESSAGE_GROUP_ID, writtenInTx);
18711889
18721890 CommitTx (tx, EStatus::SUCCESS);
18731891
0 commit comments