1
1
#include < ydb/tests/fq/pq_async_io/ut_helpers.h>
2
2
3
+ #include < yql/essentials/minikql/mkql_string_util.h>
4
+ #include < yql/essentials/providers/common/schema/mkql/yql_mkql_schema.h>
5
+ #include < yql/essentials/public/issue/yql_issue_message.h>
3
6
#include < yql/essentials/utils/yql_panic.h>
4
7
5
- #include < library/cpp/testing/unittest/registar.h>
6
8
#include < ydb/core/fq/libs/row_dispatcher/events/data_plane.h>
7
9
#include < ydb/library/actors/testlib/test_runtime.h>
8
10
#include < ydb/library/yql/dq/actors/common/retry_queue.h>
11
+ #include < ydb/library/yql/dq/common/rope_over_buffer.h>
9
12
#include < library/cpp/testing/unittest/gtest.h>
13
+ #include < library/cpp/testing/unittest/registar.h>
10
14
11
15
#include < thread>
12
16
@@ -15,7 +19,6 @@ namespace NYql::NDq {
15
19
const ui64 PartitionId = 666 ;
16
20
17
21
struct TFixture : public TPqIoTestFixture {
18
-
19
22
TFixture () {
20
23
LocalRowDispatcherId = CaSetup->Runtime ->AllocateEdgeActor ();
21
24
Coordinator1Id = CaSetup->Runtime ->AllocateEdgeActor ();
@@ -43,6 +46,7 @@ struct TFixture : public TPqIoTestFixture {
43
46
44
47
NYql::NPq::NProto::TDqPqTopicSource copySettings = settings;
45
48
auto [dqSource, dqSourceAsActor] = CreateDqPqRdReadActor (
49
+ actor.TypeEnv ,
46
50
std::move (copySettings),
47
51
0 ,
48
52
NYql::NDq::TCollectStatsLevel::None,
@@ -132,12 +136,36 @@ struct TFixture : public TPqIoTestFixture {
132
136
});
133
137
}
134
138
135
- void MockMessageBatch (ui64 offset, const std::vector<TString>& jsons, NActors::TActorId rowDispatcherId, ui64 generation = 1 ) {
139
+ TRope SerializeValue (TFakeActor& actor, const NUdf::TUnboxedValue& value, const TString& type) {
140
+ NKikimr::NMiniKQL::TType* typeMkql = NYql::NCommon::ParseTypeFromYson (TStringBuf (type), actor.ProgramBuilder , Cerr);
141
+ UNIT_ASSERT_C (typeMkql, " Invalid mkql type: " << type);
142
+
143
+ NKikimr::NMiniKQL::TValuePackerTransport<false > packer (typeMkql);
144
+ return NYql::MakeReadOnlyRope (packer.Pack (value));
145
+ }
146
+
147
+ TRope SerializeInt (TFakeActor& actor, ui64 item) {
148
+ with_lock (actor.Alloc ) {
149
+ NUdf::TUnboxedValue value = NUdf::TUnboxedValuePod (item);
150
+ return SerializeValue (actor, value, " [DataType; Uint64]" );
151
+ }
152
+ }
153
+
154
+ TRope SerializeString (TFakeActor& actor, const TString& item) {
155
+ with_lock (actor.Alloc ) {
156
+ NUdf::TUnboxedValue value = NKikimr::NMiniKQL::MakeString (item);
157
+ return SerializeValue (actor, value, " [DataType; String]" );
158
+ }
159
+ }
160
+
161
+ // Supported schema (Uint64, String)
162
+ void MockMessageBatch (ui64 offset, const std::vector<std::pair<ui64, TString>>& messages, NActors::TActorId rowDispatcherId, ui64 generation = 1 ) {
136
163
CaSetup->Execute ([&](TFakeActor& actor) {
137
164
auto event = new NFq::TEvRowDispatcher::TEvMessageBatch ();
138
- for (const auto & json :jsons ) {
165
+ for (const auto & item : messages ) {
139
166
NFq::NRowDispatcherProto::TEvMessage message;
140
- message.SetJson (json);
167
+ message.AddColumnsPayload (event->AddPayload (SerializeInt (actor, item.first )));
168
+ message.AddColumnsPayload (event->AddPayload (SerializeString (actor, item.second )));
141
169
message.SetOffset (offset++);
142
170
*event->Record .AddMessages () = message;
143
171
}
@@ -150,7 +178,8 @@ struct TFixture : public TPqIoTestFixture {
150
178
void MockSessionError () {
151
179
CaSetup->Execute ([&](TFakeActor& actor) {
152
180
auto event = new NFq::TEvRowDispatcher::TEvSessionError ();
153
- event->Record .SetMessage (" A problem has been detected and session has been shut down to prevent damage your life" );
181
+ event->Record .SetStatusCode (::NYql::NDqProto::StatusIds::BAD_REQUEST);
182
+ IssueToMessage (TIssue (" A problem has been detected and session has been shut down to prevent damage your life" ), event->Record .AddIssues ());
154
183
event->Record .SetPartitionId (PartitionId);
155
184
CaSetup->Runtime ->Send (new NActors::IEventHandle (*actor.DqAsyncInputActorId , RowDispatcher1, event, 0 , 1 ));
156
185
});
@@ -177,7 +206,7 @@ struct TFixture : public TPqIoTestFixture {
177
206
watermarksBeforeIter == watermarkBeforePositions.end () ||
178
207
*watermarksBeforeIter > expectedPos,
179
208
" Watermark before item on position " << expectedPos << " was expected" );
180
- UNIT_ASSERT_EQUAL (std::get<T>(item), expected.at (expectedPos));
209
+ UNIT_ASSERT_VALUES_EQUAL (std::get<T>(item), expected.at (expectedPos));
181
210
expectedPos++;
182
211
}
183
212
}
@@ -206,7 +235,7 @@ struct TFixture : public TPqIoTestFixture {
206
235
207
236
void StartSession (NYql::NPq::NProto::TDqPqTopicSource& settings, i64 freeSpace = 1_MB) {
208
237
InitRdSource (settings, freeSpace);
209
- SourceRead<TString>(UVParser );
238
+ SourceRead<std::pair<ui64, TString>>(UVPairParser );
210
239
ExpectCoordinatorChangesSubscribe ();
211
240
212
241
MockCoordinatorChanged (Coordinator1Id);
@@ -217,21 +246,21 @@ struct TFixture : public TPqIoTestFixture {
217
246
MockAck (RowDispatcher1);
218
247
}
219
248
220
- void ProcessSomeJsons (ui64 offset, const std::vector<TString>& jsons , NActors::TActorId rowDispatcherId,
221
- std::function<std::vector<TString>(const NUdf::TUnboxedValue&)> uvParser = UVParser , ui64 generation = 1) {
249
+ void ProcessSomeMessages (ui64 offset, const std::vector<std::pair<ui64, TString>>& messages , NActors::TActorId rowDispatcherId,
250
+ std::function<std::vector<std::pair<ui64, TString>> (const NUdf::TUnboxedValue&)> uvParser = UVPairParser , ui64 generation = 1) {
222
251
MockNewDataArrived (rowDispatcherId, generation);
223
252
ExpectGetNextBatch (rowDispatcherId);
224
253
225
- MockMessageBatch (offset, jsons , rowDispatcherId, generation);
254
+ MockMessageBatch (offset, messages , rowDispatcherId, generation);
226
255
227
- auto result = SourceReadDataUntil<TString>(uvParser, jsons .size ());
228
- AssertDataWithWatermarks (result, jsons , {});
256
+ auto result = SourceReadDataUntil<std::pair<ui64, TString>> (uvParser, messages .size ());
257
+ AssertDataWithWatermarks (result, messages , {});
229
258
}
230
259
231
- const TString Json1 = " { \" dt \" : 100,\" value \" : \" value1\" } " ;
232
- const TString Json2 = " { \" dt \" : 200,\" value \" : \" value2\" } " ;
233
- const TString Json3 = " { \" dt \" : 300,\" value \" : \" value3\" } " ;
234
- const TString Json4 = " { \" dt \" : 400,\" value \" : \" value4\" } " ;
260
+ const std::pair<ui64, TString> Message1 = { 100 , " value1" } ;
261
+ const std::pair<ui64, TString> Message2 = { 200 , " value2" } ;
262
+ const std::pair<ui64, TString> Message3 = { 300 , " value3" } ;
263
+ const std::pair<ui64, TString> Message4 = { 400 , " value4" } ;
235
264
236
265
NYql::NPq::NProto::TDqPqTopicSource Source1 = BuildPqTopicSourceSettings(" topicName" );
237
266
@@ -245,7 +274,7 @@ struct TFixture : public TPqIoTestFixture {
245
274
Y_UNIT_TEST_SUITE (TDqPqRdReadActorTests) {
246
275
Y_UNIT_TEST_F (TestReadFromTopic, TFixture) {
247
276
StartSession (Source1);
248
- ProcessSomeJsons (0 , {Json1, Json2 }, RowDispatcher1);
277
+ ProcessSomeMessages (0 , {Message1, Message2 }, RowDispatcher1);
249
278
}
250
279
251
280
Y_UNIT_TEST_F (SessionError, TFixture) {
@@ -257,7 +286,7 @@ Y_UNIT_TEST_SUITE(TDqPqRdReadActorTests) {
257
286
258
287
bool failured = false ;
259
288
while (Now () < deadline) {
260
- SourceRead<TString>(UVParser );
289
+ SourceRead<std::pair<ui64, TString>>(UVPairParser );
261
290
if (future.HasValue ()) {
262
291
UNIT_ASSERT_STRING_CONTAINS (future.GetValue ().ToOneLineString (), " damage your life" );
263
292
failured = true ;
@@ -273,17 +302,18 @@ Y_UNIT_TEST_SUITE(TDqPqRdReadActorTests) {
273
302
MockNewDataArrived (RowDispatcher1);
274
303
ExpectGetNextBatch (RowDispatcher1);
275
304
276
- const std::vector<TString> data1 = {Json1, Json2 };
305
+ const std::vector<std::pair<ui64, TString>> data1 = {Message1, Message2 };
277
306
MockMessageBatch (0 , data1, RowDispatcher1);
278
307
279
- const std::vector<TString> data2 = {Json3, Json4 };
308
+ const std::vector<std::pair<ui64, TString>> data2 = {Message3, Message4 };
280
309
MockMessageBatch (2 , data2, RowDispatcher1);
281
310
282
- auto result = SourceReadDataUntil<TString>(UVParser , 1 , 1 );
283
- std::vector<TString> expected{data1};
311
+ auto result = SourceReadDataUntil<std::pair<ui64, TString>>(UVPairParser , 1 , 1 );
312
+ std::vector<std::pair<ui64, TString> > expected{data1};
284
313
AssertDataWithWatermarks (result, expected, {});
285
314
286
- UNIT_ASSERT_EQUAL (SourceRead<TString>(UVParser, 0 ).size (), 0 );
315
+ auto readSize = SourceRead<std::pair<ui64, TString>>(UVPairParser, 0 ).size ();
316
+ UNIT_ASSERT_VALUES_EQUAL (readSize, 0 );
287
317
}
288
318
289
319
Y_UNIT_TEST (TestSaveLoadPqRdRead) {
@@ -292,17 +322,17 @@ Y_UNIT_TEST_SUITE(TDqPqRdReadActorTests) {
292
322
{
293
323
TFixture f;
294
324
f.StartSession (f.Source1 );
295
- f.ProcessSomeJsons (0 , {f.Json1 , f.Json2 }, f.RowDispatcher1 ); // offsets: 0, 1
325
+ f.ProcessSomeMessages (0 , {f.Message1 , f.Message2 }, f.RowDispatcher1 ); // offsets: 0, 1
296
326
297
327
f.SaveSourceState (CreateCheckpoint (), state);
298
328
Cerr << " State saved" << Endl;
299
329
}
300
330
{
301
331
TFixture f;
302
332
f.InitRdSource (f.Source1 );
303
- f.SourceRead <TString>(UVParser );
333
+ f.SourceRead <std::pair<ui64, TString>>(UVPairParser );
304
334
f.LoadSource (state);
305
- f.SourceRead <TString>(UVParser );
335
+ f.SourceRead <std::pair<ui64, TString>>(UVPairParser );
306
336
f.ExpectCoordinatorChangesSubscribe ();
307
337
308
338
f.MockCoordinatorChanged (f.Coordinator1Id );
@@ -312,17 +342,17 @@ Y_UNIT_TEST_SUITE(TDqPqRdReadActorTests) {
312
342
f.ExpectStartSession (2 , f.RowDispatcher1 );
313
343
f.MockAck (f.RowDispatcher1 );
314
344
315
- f.ProcessSomeJsons (2 , {f.Json3 }, f.RowDispatcher1 ); // offsets: 2
345
+ f.ProcessSomeMessages (2 , {f.Message3 }, f.RowDispatcher1 ); // offsets: 2
316
346
state.Data .clear ();
317
347
f.SaveSourceState (CreateCheckpoint (), state);
318
348
Cerr << " State saved" << Endl;
319
349
}
320
350
{
321
351
TFixture f;
322
352
f.InitRdSource (f.Source1 );
323
- f.SourceRead <TString>(UVParser );
353
+ f.SourceRead <std::pair<ui64, TString>>(UVPairParser );
324
354
f.LoadSource (state);
325
- f.SourceRead <TString>(UVParser );
355
+ f.SourceRead <std::pair<ui64, TString>>(UVPairParser );
326
356
f.ExpectCoordinatorChangesSubscribe ();
327
357
328
358
f.MockCoordinatorChanged (f.Coordinator1Id );
@@ -332,29 +362,29 @@ Y_UNIT_TEST_SUITE(TDqPqRdReadActorTests) {
332
362
f.ExpectStartSession (3 , f.RowDispatcher1 );
333
363
f.MockAck (f.RowDispatcher1 );
334
364
335
- f.ProcessSomeJsons (3 , {f.Json4 }, f.RowDispatcher1 ); // offsets: 3
365
+ f.ProcessSomeMessages (3 , {f.Message4 }, f.RowDispatcher1 ); // offsets: 3
336
366
}
337
367
}
338
368
339
369
Y_UNIT_TEST_F (CoordinatorChanged, TFixture) {
340
370
StartSession (Source1);
341
- ProcessSomeJsons (0 , {Json1, Json2 }, RowDispatcher1);
342
- MockMessageBatch (2 , {Json3 }, RowDispatcher1);
371
+ ProcessSomeMessages (0 , {Message1, Message2 }, RowDispatcher1);
372
+ MockMessageBatch (2 , {Message3 }, RowDispatcher1);
343
373
344
374
// change active Coordinator
345
375
MockCoordinatorChanged (Coordinator2Id);
346
376
ExpectStopSession (RowDispatcher1);
347
377
348
- auto result = SourceReadDataUntil<TString>(UVParser , 1 );
349
- AssertDataWithWatermarks (result, {Json3 }, {});
378
+ auto result = SourceReadDataUntil<std::pair<ui64, TString>>(UVPairParser , 1 );
379
+ AssertDataWithWatermarks (result, {Message3 }, {});
350
380
351
381
auto req = ExpectCoordinatorRequest (Coordinator2Id);
352
382
MockCoordinatorResult (RowDispatcher2, req->Cookie );
353
383
354
384
ExpectStartSession (3 , RowDispatcher2, 2 );
355
385
MockAck (RowDispatcher2, 2 );
356
386
357
- ProcessSomeJsons (3 , {Json4 }, RowDispatcher2, UVParser , 2 );
387
+ ProcessSomeMessages (3 , {Message4 }, RowDispatcher2, UVPairParser , 2 );
358
388
359
389
MockHeartbeat (RowDispatcher1, 1 ); // old generation
360
390
ExpectStopSession (RowDispatcher1);
@@ -363,30 +393,30 @@ Y_UNIT_TEST_SUITE(TDqPqRdReadActorTests) {
363
393
Y_UNIT_TEST_F (Backpressure, TFixture) {
364
394
StartSession (Source1, 2_KB);
365
395
366
- TString json (900 , ' c' );
367
- ProcessSomeJsons (0 , {json }, RowDispatcher1);
396
+ std::pair<ui64, TString> message = { 100500 , TString (900 , ' c' )} ;
397
+ ProcessSomeMessages (0 , {message }, RowDispatcher1);
368
398
369
399
MockNewDataArrived (RowDispatcher1);
370
400
ExpectGetNextBatch (RowDispatcher1);
371
- MockMessageBatch (0 , {json, json, json }, RowDispatcher1);
401
+ MockMessageBatch (0 , {message, message, message }, RowDispatcher1);
372
402
373
403
MockNewDataArrived (RowDispatcher1);
374
404
ASSERT_THROW (
375
405
CaSetup->Runtime ->GrabEdgeEvent <NFq::TEvRowDispatcher::TEvGetNextBatch>(RowDispatcher1, TDuration::Seconds (0 )),
376
406
NActors::TEmptyEventQueueException);
377
407
378
- auto result = SourceReadDataUntil<TString>(UVParser , 3 );
379
- AssertDataWithWatermarks (result, {json, json, json }, {});
408
+ auto result = SourceReadDataUntil<std::pair<ui64, TString>>(UVPairParser , 3 );
409
+ AssertDataWithWatermarks (result, {message, message, message }, {});
380
410
ExpectGetNextBatch (RowDispatcher1);
381
411
382
- MockMessageBatch (3 , {Json1 }, RowDispatcher1);
383
- result = SourceReadDataUntil<TString>(UVParser , 1 );
384
- AssertDataWithWatermarks (result, {Json1 }, {});
412
+ MockMessageBatch (3 , {Message1 }, RowDispatcher1);
413
+ result = SourceReadDataUntil<std::pair<ui64, TString>>(UVPairParser , 1 );
414
+ AssertDataWithWatermarks (result, {Message1 }, {});
385
415
}
386
416
387
417
Y_UNIT_TEST_F (RowDispatcherIsRestarted, TFixture) {
388
418
StartSession (Source1);
389
- ProcessSomeJsons (0 , {Json1, Json2 }, RowDispatcher1);
419
+ ProcessSomeMessages (0 , {Message1, Message2 }, RowDispatcher1);
390
420
MockDisconnected ();
391
421
MockConnected ();
392
422
MockUndelivered ();
@@ -396,7 +426,7 @@ Y_UNIT_TEST_SUITE(TDqPqRdReadActorTests) {
396
426
ExpectStartSession (2 , RowDispatcher1, 2 );
397
427
MockAck (RowDispatcher1, 2 );
398
428
399
- ProcessSomeJsons (2 , {Json3 }, RowDispatcher1, UVParser , 2 );
429
+ ProcessSomeMessages (2 , {Message3 }, RowDispatcher1, UVPairParser , 2 );
400
430
}
401
431
402
432
Y_UNIT_TEST_F (IgnoreMessageIfNoSessions, TFixture) {
@@ -406,15 +436,22 @@ Y_UNIT_TEST_SUITE(TDqPqRdReadActorTests) {
406
436
}
407
437
408
438
Y_UNIT_TEST_F (MetadataFields, TFixture) {
439
+ auto metadataUVParser = [](const NUdf::TUnboxedValue& item) -> std::vector<std::pair<ui64, TString>> {
440
+ UNIT_ASSERT_VALUES_EQUAL (item.GetListLength (), 3 );
441
+ auto stringElement = item.GetElement (2 );
442
+ return { {item.GetElement (1 ).Get <ui64>(), TString (stringElement.AsStringRef ())} };
443
+ };
444
+
409
445
auto source = BuildPqTopicSourceSettings (" topicName" );
410
446
source.AddMetadataFields (" _yql_sys_create_time" );
447
+ source.SetRowType (" [StructType; [[_yql_sys_create_time; [DataType; Uint32]]; [dt; [DataType; Uint64]]; [value; [DataType; String]]]]" );
411
448
StartSession (source);
412
- ProcessSomeJsons (0 , {Json1 }, RowDispatcher1, UVParserWithMetadatafields );
449
+ ProcessSomeMessages (0 , {Message1 }, RowDispatcher1, metadataUVParser );
413
450
}
414
451
415
452
Y_UNIT_TEST_F (IgnoreCoordinatorResultIfWrongState, TFixture) {
416
453
StartSession (Source1);
417
- ProcessSomeJsons (0 , {Json1, Json2 }, RowDispatcher1);
454
+ ProcessSomeMessages (0 , {Message1, Message2 }, RowDispatcher1);
418
455
419
456
MockCoordinatorChanged (Coordinator2Id);
420
457
auto req = ExpectCoordinatorRequest (Coordinator2Id);
0 commit comments