@@ -155,7 +155,7 @@ class TFormatHadlerFixture : public TBaseFixture {
155
155
FormatHandler = CreateTestFormatHandler (config, settings);
156
156
}
157
157
158
- TStatus MakeClient (const TVector<TSchemaColumn>& columns, const TString& whereFilter, TCallback callback, ui64 expectedFilteredRows = 1 ) {
158
+ [[nodiscard]] TStatus MakeClient (const TVector<TSchemaColumn>& columns, const TString& whereFilter, TCallback callback, ui64 expectedFilteredRows = 1 ) {
159
159
ClientIds.emplace_back (ClientIds.size (), 0 , 0 , 0 );
160
160
161
161
auto client = MakeIntrusive<TClientDataConsumer>(ClientIds.back (), columns, whereFilter, callback, expectedFilteredRows);
@@ -202,6 +202,30 @@ class TFormatHadlerFixture : public TBaseFixture {
202
202
FormatHandler->RemoveClient (clientId);
203
203
}
204
204
205
+ public:
206
+ static TCallback EmptyCheck () {
207
+ return [&](TQueue<std::pair<TRope, TVector<ui64>>>&& data) {};
208
+ }
209
+
210
+ static TCallback OneBatchCheck (std::function<void (TRope&& messages, TVector<ui64>&& offsets)> callback) {
211
+ return [callback](TQueue<std::pair<TRope, TVector<ui64>>>&& data) {
212
+ UNIT_ASSERT_VALUES_EQUAL (data.size (), 1 );
213
+ auto [messages, offsets] = data.front ();
214
+
215
+ UNIT_ASSERT (!offsets.empty ());
216
+ callback (std::move (messages), std::move (offsets));
217
+ };
218
+ }
219
+
220
+ TCallback OneRowCheck (ui64 offset, const TRow& row) const {
221
+ return OneBatchCheck ([this , offset, row](TRope&& messages, TVector<ui64>&& offsets) {
222
+ UNIT_ASSERT_VALUES_EQUAL (offsets.size (), 1 );
223
+ UNIT_ASSERT_VALUES_EQUAL (offsets.front (), offset);
224
+
225
+ CheckMessageBatch (messages, TBatch ().AddRow (row));
226
+ });
227
+ }
228
+
205
229
private:
206
230
void ExtractClientsData () {
207
231
for (auto & client : Clients) {
@@ -233,33 +257,13 @@ Y_UNIT_TEST_SUITE(TestFormatHandler) {
233
257
CheckSuccess (MakeClient (
234
258
{commonColumn, {" col_first" , " [DataType; String]" }},
235
259
" WHERE col_first = \" str_first__large__\" " ,
236
- [&](TQueue<std::pair<TRope, TVector<ui64>>>&& data) {
237
- UNIT_ASSERT_VALUES_EQUAL (data.size (), 1 );
238
-
239
- auto [messages, offsets] = data.front ();
240
- UNIT_ASSERT_VALUES_EQUAL (offsets.size (), 1 );
241
- UNIT_ASSERT_VALUES_EQUAL (offsets.front (), firstOffset + 1 );
242
-
243
- CheckMessageBatch (messages, TBatch ().AddRow (
244
- TRow ().AddString (" event2" ).AddString (" str_first__large__" )
245
- ));
246
- }
260
+ OneRowCheck (firstOffset + 1 , TRow ().AddString (" event2" ).AddString (" str_first__large__" ))
247
261
));
248
262
249
263
CheckSuccess (MakeClient (
250
264
{commonColumn, {" col_second" , " [DataType; String]" }},
251
265
" WHERE col_second = \" str_second\" " ,
252
- [&](TQueue<std::pair<TRope, TVector<ui64>>>&& data) {
253
- UNIT_ASSERT_VALUES_EQUAL (data.size (), 1 );
254
-
255
- auto [messages, offsets] = data.front ();
256
- UNIT_ASSERT_VALUES_EQUAL (offsets.size (), 1 );
257
- UNIT_ASSERT_VALUES_EQUAL (offsets.front (), firstOffset);
258
-
259
- CheckMessageBatch (messages, TBatch ().AddRow (
260
- TRow ().AddString (" event1" ).AddString (" str_second" )
261
- ));
262
- }
266
+ OneRowCheck (firstOffset, TRow ().AddString (" event1" ).AddString (" str_second" ))
263
267
));
264
268
265
269
ParseMessages ({
@@ -288,14 +292,10 @@ Y_UNIT_TEST_SUITE(TestFormatHandler) {
288
292
R"( {"col_a": false, "col_b": {"X": "Y"}})"
289
293
};
290
294
291
- CheckSuccess (MakeClient (schema, " WHERE FALSE" , [&](TQueue<std::pair<TRope, TVector<ui64>>>&&) {}, 0 ));
292
-
293
- auto trueChacker = [&](TQueue<std::pair<TRope, TVector<ui64>>>&& data) {
294
- UNIT_ASSERT_VALUES_EQUAL (data.size (), 1 );
295
- auto [messages, offsets] = data.front ();
295
+ CheckSuccess (MakeClient (schema, " WHERE FALSE" , EmptyCheck (), 0 ));
296
296
297
+ const auto trueChacker = OneBatchCheck ([&](TRope&& messages, TVector<ui64>&& offsets) {
297
298
TBatch expectedBatch;
298
- UNIT_ASSERT (!offsets.empty ());
299
299
for (ui64 offset : offsets) {
300
300
UNIT_ASSERT (offset - firstOffset < testData.size ());
301
301
expectedBatch.AddRow (
@@ -304,7 +304,7 @@ Y_UNIT_TEST_SUITE(TestFormatHandler) {
304
304
}
305
305
306
306
CheckMessageBatch (messages, expectedBatch);
307
- };
307
+ }) ;
308
308
CheckSuccess (MakeClient (schema, " WHERE TRUE" , trueChacker, 3 ));
309
309
CheckSuccess (MakeClient (schema, " " , trueChacker, 2 ));
310
310
@@ -323,7 +323,7 @@ Y_UNIT_TEST_SUITE(TestFormatHandler) {
323
323
Y_UNIT_TEST_F (ClientValidation, TFormatHadlerFixture) {
324
324
const TVector<TSchemaColumn> schema = {{" data" , " [DataType; String]" }};
325
325
const TString filter = " WHERE FALSE" ;
326
- const auto callback = [&](TQueue<std::pair<TRope, TVector<ui64>>>&&) {} ;
326
+ const auto callback = EmptyCheck () ;
327
327
CheckSuccess (MakeClient (schema, filter, callback, 0 ));
328
328
329
329
CheckError (
@@ -349,27 +349,12 @@ Y_UNIT_TEST_SUITE(TestFormatHandler) {
349
349
const ui64 firstOffset = 42 ;
350
350
const TSchemaColumn commonColumn = {" com_col" , " [DataType; String]" };
351
351
352
- CheckSuccess (MakeClient (
353
- {commonColumn, {" col_first" , " [OptionalType; [DataType; Uint8]]" }},
354
- " WHERE TRUE" ,
355
- [&](TQueue<std::pair<TRope, TVector<ui64>>>&& data) {},
356
- 0
357
- ));
352
+ CheckSuccess (MakeClient ({commonColumn, {" col_first" , " [OptionalType; [DataType; Uint8]]" }}, " WHERE TRUE" , EmptyCheck (), 0 ));
358
353
359
354
CheckSuccess (MakeClient (
360
355
{commonColumn, {" col_second" , " [DataType; String]" }},
361
356
" WHERE col_second = \" str_second\" " ,
362
- [&](TQueue<std::pair<TRope, TVector<ui64>>>&& data) {
363
- UNIT_ASSERT_VALUES_EQUAL (data.size (), 1 );
364
-
365
- auto [messages, offsets] = data.front ();
366
- UNIT_ASSERT_VALUES_EQUAL (offsets.size (), 1 );
367
- UNIT_ASSERT_VALUES_EQUAL (offsets.front (), firstOffset);
368
-
369
- CheckMessageBatch (messages, TBatch ().AddRow (
370
- TRow ().AddString (" event1" ).AddString (" str_second" )
371
- ));
372
- }
357
+ OneRowCheck (firstOffset, TRow ().AddString (" event1" ).AddString (" str_second" ))
373
358
));
374
359
375
360
CheckClientError (
@@ -379,6 +364,26 @@ Y_UNIT_TEST_SUITE(TestFormatHandler) {
379
364
TStringBuilder () << " Failed to parse json string at offset " << firstOffset << " , got parsing error for column 'col_first' with type [OptionalType; [DataType; Uint8]]"
380
365
);
381
366
}
367
+
368
+ Y_UNIT_TEST_F (ClientErrorWithEmptyFilter, TFormatHadlerFixture) {
369
+ const ui64 firstOffset = 42 ;
370
+ const TSchemaColumn commonColumn = {" com_col" , " [DataType; String]" };
371
+
372
+ CheckSuccess (MakeClient ({commonColumn, {" col_first" , " [DataType; String]" }}, " " , EmptyCheck (), 0 ));
373
+
374
+ CheckSuccess (MakeClient (
375
+ {commonColumn, {" col_second" , " [DataType; String]" }},
376
+ " WHERE col_second = \" str_second\" " ,
377
+ OneRowCheck (firstOffset, TRow ().AddString (" event1" ).AddString (" str_second" ))
378
+ ));
379
+
380
+ CheckClientError (
381
+ {GetMessage (firstOffset, R"( {"com_col": "event1", "col_second": "str_second"})" )},
382
+ ClientIds[0 ],
383
+ EStatusId::PRECONDITION_FAILED,
384
+ TStringBuilder () << " Failed to parse json messages, found 1 missing values from offset " << firstOffset << " in non optional column 'col_first' with type [DataType; String]"
385
+ );
386
+ }
382
387
}
383
388
384
389
} // namespace NFq::NRowDispatcher::NTests
0 commit comments