3
3
#include < ydb/public/sdk/cpp/client/ydb_topic/topic.h>
4
4
#include < ydb/public/sdk/cpp/client/ydb_table/table.h>
5
5
#include < ydb/public/sdk/cpp/client/ydb_persqueue_public/ut/ut_utils/ut_utils.h>
6
+ #include < ydb/core/cms/console/console.h>
6
7
#include < ydb/core/keyvalue/keyvalue_events.h>
7
8
#include < ydb/core/persqueue/key.h>
8
9
#include < ydb/core/persqueue/blob.h>
@@ -42,8 +43,14 @@ class TFixture : public NUnitTest::TBaseFixture {
42
43
void WaitForEvent ();
43
44
};
44
45
46
+ struct TFeatureFlags {
47
+ bool EnablePQConfigTransactionsAtSchemeShard = true ;
48
+ };
49
+
45
50
void SetUp (NUnitTest::TTestContext&) override ;
46
51
52
+ void NotifySchemeShard (const TFeatureFlags& flags);
53
+
47
54
NTable::TSession CreateTableSession ();
48
55
NTable::TTransaction BeginTx (NTable::TSession& session);
49
56
void CommitTx (NTable::TTransaction& tx, EStatus status = EStatus::SUCCESS);
@@ -67,6 +74,8 @@ class TFixture : public NUnitTest::TBaseFixture {
67
74
std::optional<size_t > maxPartitionCount = std::nullopt);
68
75
void DescribeTopic (const TString& path);
69
76
77
+ void AddConsumer (const TString& topic, const TVector<TString>& consumers);
78
+
70
79
void WriteToTopicWithInvalidTxId (bool invalidTxId);
71
80
72
81
TTopicWriteSessionPtr CreateTopicWriteSession (const TString& topicPath,
@@ -101,6 +110,8 @@ class TFixture : public NUnitTest::TBaseFixture {
101
110
NYdb::EStatus status);
102
111
void CloseTopicWriteSession (const TString& topicPath,
103
112
const TString& messageGroupId);
113
+ void CloseTopicReadSession (const TString& topicPath,
114
+ const TString& consumerName);
104
115
105
116
enum EEndOfTransaction {
106
117
Commit,
@@ -181,6 +192,8 @@ class TFixture : public NUnitTest::TBaseFixture {
181
192
ui64 tabletId,
182
193
const NPQ::TWriteId& writeId);
183
194
195
+ ui64 GetSchemeShardTabletId (const TActorId& actorId);
196
+
184
197
std::unique_ptr<TTopicSdkTestSetup> Setup;
185
198
std::unique_ptr<TDriver> Driver;
186
199
@@ -198,11 +211,27 @@ void TFixture::SetUp(NUnitTest::TTestContext&)
198
211
{
199
212
NKikimr::Tests::TServerSettings settings = TTopicSdkTestSetup::MakeServerSettings ();
200
213
settings.SetEnableTopicServiceTx (true );
214
+
201
215
Setup = std::make_unique<TTopicSdkTestSetup>(TEST_CASE_NAME, settings);
202
216
203
217
Driver = std::make_unique<TDriver>(Setup->MakeDriver ());
204
218
}
205
219
220
+ void TFixture::NotifySchemeShard (const TFeatureFlags& flags)
221
+ {
222
+ auto request = std::make_unique<NConsole::TEvConsole::TEvConfigNotificationRequest>();
223
+ *request->Record .MutableConfig () = *Setup->GetServer ().ServerSettings .AppConfig ;
224
+ request->Record .MutableConfig ()->MutableFeatureFlags ()->SetEnablePQConfigTransactionsAtSchemeShard (flags.EnablePQConfigTransactionsAtSchemeShard );
225
+
226
+ auto & runtime = Setup->GetRuntime ();
227
+ auto actorId = runtime.AllocateEdgeActor ();
228
+
229
+ ui64 ssId = GetSchemeShardTabletId (actorId);
230
+
231
+ runtime.SendToPipe (ssId, actorId, request.release ());
232
+ runtime.GrabEdgeEvent <NConsole::TEvConsole::TEvConfigNotificationResponse>();
233
+ }
234
+
206
235
NTable::TSession TFixture::CreateTableSession ()
207
236
{
208
237
NTable::TTableClient client (GetDriver ());
@@ -329,6 +358,20 @@ void TFixture::CreateTopic(const TString& path,
329
358
Setup->CreateTopic (path, consumer, partitionCount, maxPartitionCount);
330
359
}
331
360
361
+ void TFixture::AddConsumer (const TString& path,
362
+ const TVector<TString>& consumers)
363
+ {
364
+ NTopic::TTopicClient client (GetDriver ());
365
+ NTopic::TAlterTopicSettings settings;
366
+
367
+ for (const auto & consumer : consumers) {
368
+ settings.BeginAddConsumer (consumer);
369
+ }
370
+
371
+ auto result = client.AlterTopic (path, settings).GetValueSync ();
372
+ UNIT_ASSERT_C (result.IsSuccess (), result.GetIssues ().ToString ());
373
+ }
374
+
332
375
void TFixture::DescribeTopic (const TString& path)
333
376
{
334
377
Setup->DescribeTopic (path);
@@ -663,6 +706,13 @@ void TFixture::CloseTopicWriteSession(const TString& topicPath,
663
706
TopicWriteSessions.erase (key);
664
707
}
665
708
709
+ void TFixture::CloseTopicReadSession (const TString& topicPath,
710
+ const TString& consumerName)
711
+ {
712
+ Y_UNUSED (consumerName);
713
+ TopicReadSessions.erase (topicPath);
714
+ }
715
+
666
716
void TFixture::WriteToTopic (const TString& topicPath,
667
717
const TString& messageGroupId,
668
718
const TString& message,
@@ -779,6 +829,37 @@ void TFixture::WaitForSessionClose(const TString& topicPath,
779
829
UNIT_ASSERT (context.AckCount () <= context.WriteCount );
780
830
}
781
831
832
+ ui64 TFixture::GetSchemeShardTabletId (const TActorId& actorId)
833
+ {
834
+ auto navigate = std::make_unique<NSchemeCache::TSchemeCacheNavigate>();
835
+ navigate->DatabaseName = " /Root" ;
836
+
837
+ NSchemeCache::TSchemeCacheNavigate::TEntry entry;
838
+ entry.Path = SplitPath (" /Root" );
839
+ entry.SyncVersion = true ;
840
+ entry.ShowPrivatePath = true ;
841
+ entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpList;
842
+
843
+ navigate->ResultSet .push_back (std::move (entry));
844
+ // navigate->UserToken = "root@builtin";
845
+ navigate->Cookie = 12345 ;
846
+
847
+ auto & runtime = Setup->GetRuntime ();
848
+
849
+ runtime.Send (MakeSchemeCacheID (), actorId,
850
+ new TEvTxProxySchemeCache::TEvNavigateKeySet (navigate.release ()),
851
+ 0 ,
852
+ true );
853
+ auto response = runtime.GrabEdgeEvent <TEvTxProxySchemeCache::TEvNavigateKeySetResult>();
854
+
855
+ UNIT_ASSERT_VALUES_EQUAL (response->Request ->Cookie , 12345 );
856
+ UNIT_ASSERT_VALUES_EQUAL (response->Request ->ErrorCount , 0 );
857
+
858
+ auto & front = response->Request ->ResultSet .front ();
859
+
860
+ return front.Self ->Info .GetSchemeshardId ();
861
+ }
862
+
782
863
ui64 TFixture::GetTopicTabletId (const TActorId& actorId, const TString& topicPath, ui32 partition)
783
864
{
784
865
auto navigate = std::make_unique<NSchemeCache::TSchemeCacheNavigate>();
@@ -2016,6 +2097,41 @@ Y_UNIT_TEST_F(WriteToTopic_Demo_38, TFixture)
2016
2097
WriteMessagesInTx (0 , 1 );
2017
2098
}
2018
2099
2100
+ Y_UNIT_TEST_F (ReadRuleGeneration, TFixture)
2101
+ {
2102
+ // There was a server
2103
+ NotifySchemeShard ({.EnablePQConfigTransactionsAtSchemeShard = false });
2104
+
2105
+ // Users have created their own topic on it
2106
+ CreateTopic (TEST_TOPIC);
2107
+
2108
+ // And they wrote their messages into it
2109
+ WriteToTopic (TEST_TOPIC, TEST_MESSAGE_GROUP_ID, " message-1" );
2110
+ WriteToTopic (TEST_TOPIC, TEST_MESSAGE_GROUP_ID, " message-2" );
2111
+ WriteToTopic (TEST_TOPIC, TEST_MESSAGE_GROUP_ID, " message-3" );
2112
+
2113
+ // And he had a consumer
2114
+ AddConsumer (TEST_TOPIC, {" consumer-1" });
2115
+
2116
+ // We read messages from the topic and committed offsets
2117
+ auto messages = ReadFromTopic (TEST_TOPIC, " consumer-1" , TDuration::Seconds (2 ));
2118
+ UNIT_ASSERT_VALUES_EQUAL (messages.size (), 3 );
2119
+ CloseTopicReadSession (TEST_TOPIC, " consumer-1" );
2120
+
2121
+ // And then the Logbroker team turned on the feature flag
2122
+ NotifySchemeShard ({.EnablePQConfigTransactionsAtSchemeShard = true });
2123
+
2124
+ // Users continued to write to the topic
2125
+ WriteToTopic (TEST_TOPIC, TEST_MESSAGE_GROUP_ID, " message-4" );
2126
+
2127
+ // Users have added new consumers
2128
+ AddConsumer (TEST_TOPIC, {" consumer-2" });
2129
+
2130
+ // And they wanted to continue reading their messages
2131
+ messages = ReadFromTopic (TEST_TOPIC, " consumer-1" , TDuration::Seconds (2 ));
2132
+ UNIT_ASSERT_VALUES_EQUAL (messages.size (), 1 );
2133
+ }
2134
+
2019
2135
}
2020
2136
2021
2137
}
0 commit comments