Project
Loading...
Searching...
No Matches
unittest_DataSpecUtils.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14#include <catch_amalgamated.hpp>
15
16#include <string>
17
18using namespace o2;
19using namespace o2::framework;
20
21TEST_CASE("ConcreteData")
22{
24 OutputSpec spec{
25 "TEST",
26 "FOOO",
27 1,
28 Lifetime::Timeframe};
29
30 InputSpec inputSpec{
31 "binding",
32 "TEST",
33 "FOOO",
34 1,
35 Lifetime::Timeframe};
36
37 REQUIRE(DataSpecUtils::validate(inputSpec));
38
39 {
41 CHECK(std::string(concrete.origin.as<std::string>()) == "TEST");
42 CHECK(std::string(concrete.description.as<std::string>()) == "FOOO");
43 CHECK(concrete.subSpec == 1);
44 CHECK(DataSpecUtils::describe(spec) == "TEST/FOOO/1");
45 CHECK(DataSpecUtils::describe(spec) == "TEST/FOOO/1");
47
49 CHECK(std::string(dataType.origin.as<std::string>()) == "TEST");
50 CHECK(std::string(dataType.description.as<std::string>()) == "FOOO");
51
52 CHECK(DataSpecUtils::match(spec, ConcreteDataMatcher{"TEST", "FOOO", 1}));
53 CHECK(DataSpecUtils::match(spec, ConcreteDataMatcher{"TEST", "FOOO", 0}) == false);
55 CHECK(DataSpecUtils::match(spec, ConcreteDataMatcher{"TEST", "FOOO", 0}) == true);
56 CHECK(DataSpecUtils::match(inputSpec, ConcreteDataMatcher{"TEST", "FOOO", 1}));
57 CHECK(DataSpecUtils::match(inputSpec, ConcreteDataMatcher{"TEST", "FOOO", 0}) == false);
59 CHECK(DataSpecUtils::match(inputSpec, ConcreteDataMatcher{"TEST", "FOOO", 0}) == true);
60 }
61}
62
63TEST_CASE("DescribeUsingBuffer")
64{
66 OutputSpec spec{
67 "TEST",
68 "FOOO",
69 1,
70 Lifetime::Timeframe};
71
72 InputSpec inputSpec{
73 "binding",
74 "TEST",
75 "FOOO",
76 1,
77 Lifetime::Timeframe};
78
79 REQUIRE(DataSpecUtils::validate(inputSpec));
80
81 {
82 char buffer[1024];
83
85 CHECK(std::string(concrete.origin.as<std::string>()) == "TEST");
86 CHECK(std::string(concrete.description.as<std::string>()) == "FOOO");
87 CHECK(concrete.subSpec == 1);
88 auto size = DataSpecUtils::describe(buffer, 1024, spec);
89 CHECK(std::string_view(buffer, size) == "TEST/FOOO/1");
90 size = DataSpecUtils::describe(buffer, 1024, spec);
91 CHECK(std::string_view(buffer, size) == "TEST/FOOO/1");
93
94 char buffer2[1024];
95 size = DataSpecUtils::describe(buffer2, 5, spec);
96 // We always nullterminate the string
97 CHECK(std::string_view(buffer2, size) == "TEST");
98 }
99}
100
101TEST_CASE("WithWildCards")
102{
103 OutputSpec spec{
104 {"TEST", "FOOO"},
105 Lifetime::Timeframe};
106
107 CHECK_THROWS_AS(DataSpecUtils::asConcreteDataMatcher(spec), std::bad_variant_access);
108 auto dataType = DataSpecUtils::asConcreteDataTypeMatcher(spec);
109
110 CHECK(std::string(dataType.origin.as<std::string>()) == "TEST");
111 CHECK(std::string(dataType.description.as<std::string>()) == "FOOO");
112
113 CHECK(DataSpecUtils::match(spec, ConcreteDataMatcher{"TEST", "FOOO", 1}));
114 CHECK(DataSpecUtils::match(spec, ConcreteDataMatcher{"TEST", "FOOO", 0}));
115 CHECK(DataSpecUtils::describe(spec) == "TEST/FOOO");
116
117 CHECK(DataSpecUtils::getOptionalSubSpec(spec) == std::nullopt);
118}
119
120TEST_CASE("WithWildCardsBuffer")
121{
122 char buffer[1024];
123 OutputSpec spec{
124 {"TEST", "FOOO"},
125 Lifetime::Timeframe};
126
127 auto size = DataSpecUtils::describe(buffer, 1024, spec);
128 CHECK(std::string_view(buffer, size) == "<matcher query: TEST/FOOO>");
129
130 char buffer2[1024];
131 size = DataSpecUtils::describe(buffer2, 5, spec);
132 // We always null terminate the buffer.
133 CHECK(std::string_view(buffer2, size) == "<mat");
134}
135
136TEST_CASE("MatchingInputs")
137{
138 OutputSpec fullySpecified{
139 "TEST",
140 "FOOO",
141 1,
142 Lifetime::Timeframe};
143
144 OutputSpec partialMatching{
145 {"TEST", "FOOO"},
146 Lifetime::Timeframe};
147
148 auto matchingInput1 = DataSpecUtils::matchingInput(fullySpecified);
150
151 CHECK(std::string(concrete.origin.as<std::string>()) == "TEST");
152 CHECK(std::string(concrete.description.as<std::string>()) == "FOOO");
153 CHECK(concrete.subSpec == 1);
154
155 auto matchingInput2 = DataSpecUtils::matchingInput(partialMatching);
156 // CHECK_THROW(DataSpecUtils::asConcreteDataMatcher(matchingInput), std::bad_variant_access);
157 // We need a ConcreteDataMatcher to check if the generated input is
158 // correct, because a ConcreteDataTypeMatcher has one extra degree of
159 // freedom.
160 ConcreteDataMatcher concreteExample1{
161 "TEST",
162 "FOOO",
163 0};
164 ConcreteDataMatcher concreteExample2{
165 "TEST",
166 "FOOO",
167 1};
168 ConcreteDataMatcher concreteExample3{
169 "BAR",
170 "FOOO",
171 0};
172 ConcreteDataMatcher concreteExample4{
173 "TEST",
174 "BAR",
175 0};
176 CHECK(DataSpecUtils::match(matchingInput2, concreteExample1) == true);
177 CHECK(DataSpecUtils::match(matchingInput2, concreteExample2) == true);
178 CHECK(DataSpecUtils::match(matchingInput2, concreteExample3) == false);
179 CHECK(DataSpecUtils::match(matchingInput2, concreteExample4) == false);
180
181 CHECK_THROWS_AS(DataSpecUtils::asConcreteDataMatcher(matchingInput2), std::runtime_error);
182 CHECK(concrete.origin.as<std::string>() == "TEST");
183 CHECK(concrete.description.as<std::string>() == "FOOO");
184 CHECK(concrete.subSpec == 1);
185}
186
187TEST_CASE("MatchingOutputs")
188{
189 OutputSpec output1{
190 "TST", "A1", 0, Lifetime::Timeframe};
191
192 OutputSpec output2{
193 "TST", "B1", 0, Lifetime::Timeframe};
194
195 OutputSpec output3{
196 {"TST", "A1"}, Lifetime::Timeframe};
197
198 InputSpec input1{
199 "binding", "TST", "A1", 0, Lifetime::Timeframe};
200
201 InputSpec input2{
202 "binding", "TST", "A1", 1, Lifetime::Timeframe};
203
204 InputSpec input3{
205 "binding", "TST", "B1", 0, Lifetime::Timeframe};
206
207 InputSpec input4{
208 "binding", {"TST", "A1"}, Lifetime::Timeframe};
209
210 // matching inputs to outputs
211 CHECK(DataSpecUtils::match(input1, output1) == true);
212 CHECK(DataSpecUtils::match(input1, output2) == false);
213 CHECK(DataSpecUtils::match(input1, output3) == false); // Wildcard on output!
214 CHECK(DataSpecUtils::match(input2, output1) == false);
215 CHECK(DataSpecUtils::match(input2, output2) == false);
216 CHECK(DataSpecUtils::match(input2, output3) == false); // Wildcard on output!
217 CHECK(DataSpecUtils::match(input3, output1) == false);
218 CHECK(DataSpecUtils::match(input3, output2) == true);
219 CHECK(DataSpecUtils::match(input3, output3) == false); // Wildcard on output!
220 CHECK(DataSpecUtils::match(input4, output1) == true); // Wildcard in input!
221 CHECK(DataSpecUtils::match(input4, output2) == false);
222 CHECK(DataSpecUtils::match(input4, output3) == true); // Wildcard on both!
223
224 // matching outputs to output definitions
225 // ConcreteDataMatcher on both sides
226 CHECK(DataSpecUtils::match(output1, OutputSpec{"TST", "A1", 0}) == true);
227 CHECK(DataSpecUtils::match(output1, OutputSpec{"TST", "A1", 1}) == false);
228
229 // ConcreteDataMatcher left, ConcreteDataTypeMatcher right (subspec ignored)
230 CHECK(DataSpecUtils::match(output1, OutputSpec{"TST", "A1"}) == true);
231
232 // ConcreteDataTypeMatcher left (subspec ignored), ConcreteDataMatcher right
233 CHECK(DataSpecUtils::match(output3, OutputSpec{"TST", "A1", 0}) == true);
234 CHECK(DataSpecUtils::match(output3, OutputSpec{"TST", "A1", 1}) == true);
235
236 // ConcreteDataTypeMatcher on both sides
237 CHECK(DataSpecUtils::match(output3, OutputSpec{"TST", "A1"}) == true);
238}
239
240TEST_CASE("PartialMatching")
241{
242 OutputSpec fullySpecifiedOutput{
243 "TEST",
244 "FOOO",
245 1,
246 Lifetime::Timeframe};
247
248 InputSpec fullySpecifiedInput{
249 "binding",
250 "TSET",
251 "FOOO",
252 1,
253 Lifetime::Timeframe};
254
255 CHECK(DataSpecUtils::partialMatch(fullySpecifiedOutput, header::DataOrigin("TEST")));
256 CHECK(DataSpecUtils::partialMatch(fullySpecifiedInput, header::DataOrigin("TSET")));
257
258 CHECK(DataSpecUtils::partialMatch(fullySpecifiedOutput, header::DataOrigin("FOO")) == false);
259 CHECK(DataSpecUtils::partialMatch(fullySpecifiedInput, header::DataOrigin("FOO")) == false);
260
261 CHECK(DataSpecUtils::partialMatch(fullySpecifiedOutput, header::DataDescription("TEST")) == false);
262 CHECK(DataSpecUtils::partialMatch(fullySpecifiedInput, header::DataDescription("TSET")) == false);
263
264 CHECK(DataSpecUtils::partialMatch(fullySpecifiedOutput, header::DataDescription("FOOO")) == true);
265 CHECK(DataSpecUtils::partialMatch(fullySpecifiedInput, header::DataDescription("FOOO")) == true);
266}
267
268TEST_CASE("GetOptionalSubSpecWithMatcher")
269{
270 InputSpec fullInputSpec{
271 "binding",
272 "TSET", "FOOO", 1,
273 Lifetime::Timeframe};
274
275 InputSpec wildcardInputSpec{
276 "binding",
277 {"TSET", "FOOO"},
278 Lifetime::Timeframe};
279
280 auto fromQueryInputSpec = DataDescriptorQueryBuilder::parse("x:TST/A1/77;y:STS/A2;z:FOO/A3");
281
282 CHECK(*DataSpecUtils::getOptionalSubSpec(fullInputSpec) == 1);
283 CHECK(DataSpecUtils::getOptionalSubSpec(wildcardInputSpec) == std::nullopt);
284 REQUIRE(fromQueryInputSpec.size() == 3);
285 CHECK(DataSpecUtils::getOptionalSubSpec(fromQueryInputSpec[0]) != std::nullopt);
286 CHECK(DataSpecUtils::getOptionalSubSpec(fromQueryInputSpec[0]) == 77);
287 CHECK(DataSpecUtils::getOptionalSubSpec(fromQueryInputSpec[1]) == std::nullopt);
288 CHECK(DataSpecUtils::getOptionalSubSpec(fromQueryInputSpec[2]) == std::nullopt);
289 DataSpecUtils::updateMatchingSubspec(fromQueryInputSpec[2], 10);
290 CHECK(DataSpecUtils::getOptionalSubSpec(fromQueryInputSpec[2]) == 10);
291
292 auto dataType1 = DataSpecUtils::asConcreteDataTypeMatcher(fullInputSpec);
293 CHECK(std::string(dataType1.origin.as<std::string>()) == "TSET");
294 CHECK(std::string(dataType1.description.as<std::string>()) == "FOOO");
295
296 auto dataType2 = DataSpecUtils::asConcreteDataTypeMatcher(wildcardInputSpec);
297 CHECK(std::string(dataType2.origin.as<std::string>()) == "TSET");
298 CHECK(std::string(dataType2.description.as<std::string>()) == "FOOO");
299}
300
301TEST_CASE("TestMatcherFromDescription")
302{
303 auto fromQueryInputSpec = DataSpecUtils::dataDescriptorMatcherFrom(header::DataDescription{"TSET"});
304 InputSpec ddSpec{
305 "binding",
306 std::move(fromQueryInputSpec)};
307
308 CHECK(DataSpecUtils::asConcreteDataDescription(ddSpec).as<std::string>() == "TSET");
309}
310
311TEST_CASE("TestMatcherFromConcrete")
312{
313 auto fromQueryInputSpec = DataSpecUtils::dataDescriptorMatcherFrom(ConcreteDataMatcher{"TSET", "FOO", 1});
314 InputSpec ddSpec{
315 "binding",
316 std::move(fromQueryInputSpec)};
317
318 auto concrete = DataSpecUtils::asConcreteDataMatcher(ddSpec);
319
320 CHECK(concrete.origin.as<std::string>() == "TSET");
321 CHECK(concrete.description.as<std::string>() == "FOO");
322 CHECK(concrete.subSpec == 1);
323}
324
325TEST_CASE("FindOutputSpec")
326{
327 std::vector<OutputSpec> specs = {
328 {"TST", "DATA1", 0},
329 {"TST", "DATA2", 0}};
330
331 auto spec = DataSpecUtils::find(specs, {"TST"}, {"DATA1"}, 0);
332 CHECK(spec == specs[0]);
333 CHECK(DataSpecUtils::find(specs, {"TST"}, {"DATA3"}, 0) == std::nullopt);
334}
335
336TEST_CASE("FindInputSpec")
337{
338 std::vector<InputSpec> specs = {
339 {"x", "TST", "DATA1", 0},
340 {"y", "TST", "DATA2", 0}};
341
342 auto spec = DataSpecUtils::find(specs, {"TST"}, {"DATA1"}, 0);
343 CHECK(spec == specs[0]);
344 CHECK(DataSpecUtils::find(specs, {"TST"}, {"DATA3"}, 0) == std::nullopt);
345}
346
347TEST_CASE("GettingConcreteMembers")
348{
349 InputSpec fullySpecifiedInput{
350 "binding",
351 "TSET",
352 "FOOO",
353 1,
354 Lifetime::Timeframe};
355
356 InputSpec wildcardInputSpec{
357 "binding",
358 {"TSET", "FOOO"},
359 Lifetime::Timeframe};
360
361 auto justOriginInputSpec = DataDescriptorQueryBuilder::parse("x:TST");
362
363 CHECK(DataSpecUtils::asConcreteOrigin(fullySpecifiedInput).as<std::string>() == "TSET");
364 CHECK(DataSpecUtils::asConcreteDataDescription(fullySpecifiedInput).as<std::string>() == "FOOO");
365
366 CHECK(DataSpecUtils::asConcreteOrigin(wildcardInputSpec).as<std::string>() == "TSET");
367 CHECK(DataSpecUtils::asConcreteDataDescription(wildcardInputSpec).as<std::string>() == "FOOO");
368
369 REQUIRE(justOriginInputSpec.size() == 1);
370 CHECK(DataSpecUtils::asConcreteOrigin(justOriginInputSpec.at(0)).as<std::string>() == "TST");
371 CHECK_THROWS_AS(DataSpecUtils::asConcreteDataDescription(justOriginInputSpec.at(0)).as<std::string>(), RuntimeErrorRef);
372}
373
374TEST_CASE("Includes")
375{
376 InputSpec concreteInput1{"binding", "TSET", "FOOO", 1, Lifetime::Timeframe};
377 InputSpec concreteInput2{"binding", "TSET", "BAAAR", 1, Lifetime::Timeframe};
378 InputSpec wildcardInput1{"binding", {"TSET", "FOOO"}, Lifetime::Timeframe};
379 InputSpec wildcardInput2{"binding", {"TSET", "BAAAR"}, Lifetime::Timeframe};
380
381 // wildcard and concrete
382 CHECK(DataSpecUtils::includes(wildcardInput1, concreteInput1));
383 CHECK(!DataSpecUtils::includes(wildcardInput1, concreteInput2));
384 CHECK(!DataSpecUtils::includes(concreteInput1, wildcardInput1));
385 CHECK(!DataSpecUtils::includes(concreteInput2, wildcardInput1));
386
387 // concrete and concrete
388 CHECK(DataSpecUtils::includes(concreteInput1, concreteInput1));
389 CHECK(!DataSpecUtils::includes(concreteInput1, concreteInput2));
390 CHECK(!DataSpecUtils::includes(concreteInput2, concreteInput1));
391
392 // wildcard and wildcard
393 CHECK(DataSpecUtils::includes(wildcardInput1, wildcardInput1));
394 CHECK(!DataSpecUtils::includes(wildcardInput1, wildcardInput2));
395 CHECK(!DataSpecUtils::includes(wildcardInput2, wildcardInput1));
396
397 auto inputsFromQuery = DataDescriptorQueryBuilder::parse("b0:TST/FOO/0;b1:TST/FOO/1");
398 CHECK(!DataSpecUtils::includes(inputsFromQuery[0], inputsFromQuery[1]));
399 CHECK(!DataSpecUtils::includes(inputsFromQuery[1], inputsFromQuery[0]));
400}
401
402TEST_CASE("optionalConcreteDataMatcherFrom")
403{
404 using namespace data_matcher;
405
406 // the standard structure of fully qualified data descriptor
407 DataDescriptorMatcher matcher1{
408 DataDescriptorMatcher::Op::And,
409 OriginValueMatcher{"TPC"},
410 std::make_unique<DataDescriptorMatcher>(
411 DataDescriptorMatcher::Op::And,
412 DescriptionValueMatcher{"CLUSTERS"},
413 std::make_unique<DataDescriptorMatcher>(
414 DataDescriptorMatcher::Op::And,
416 std::make_unique<DataDescriptorMatcher>(
417 DataDescriptorMatcher::Op::Just,
418 StartTimeValueMatcher(ContextRef{ContextPos::STARTTIME_POS}))))};
419
420 // also fully qualified, but interchanged components
421 DataDescriptorMatcher matcher2{
422 DataDescriptorMatcher::Op::And,
423 DescriptionValueMatcher{"CLUSTERS"},
424 std::make_unique<DataDescriptorMatcher>(
425 DataDescriptorMatcher::Op::And,
426 OriginValueMatcher{"TPC"},
427 std::make_unique<DataDescriptorMatcher>(
428 DataDescriptorMatcher::Op::And,
430 std::make_unique<DataDescriptorMatcher>(
431 DataDescriptorMatcher::Op::Just,
432 StartTimeValueMatcher(ContextRef{ContextPos::STARTTIME_POS}))))};
433
434 // matcher with no unique subSpec
435 DataDescriptorMatcher matcher3{
436 DataDescriptorMatcher::Op::And,
437 OriginValueMatcher{"TPC"},
438 std::make_unique<DataDescriptorMatcher>(
439 DataDescriptorMatcher::Op::And,
440 DescriptionValueMatcher{"CLUSTERS"},
441 std::make_unique<DataDescriptorMatcher>(
442 DataDescriptorMatcher::Op::And,
443 std::make_unique<DataDescriptorMatcher>(
444 DataDescriptorMatcher::Op::Not,
446 std::make_unique<DataDescriptorMatcher>(
447 DataDescriptorMatcher::Op::Just,
448 StartTimeValueMatcher(ContextRef{ContextPos::STARTTIME_POS}))))};
449
450 // another matcher with no unique subSpec
451 DataDescriptorMatcher matcher4{
452 DataDescriptorMatcher::Op::And,
453 OriginValueMatcher{"TPC"},
454 std::make_unique<DataDescriptorMatcher>(
455 DataDescriptorMatcher::Op::And,
456 DescriptionValueMatcher{"CLUSTERS"},
457 std::make_unique<DataDescriptorMatcher>(
458 DataDescriptorMatcher::Op::And,
459 std::make_unique<DataDescriptorMatcher>(
460 DataDescriptorMatcher::Op::Or,
463 std::make_unique<DataDescriptorMatcher>(
464 DataDescriptorMatcher::Op::Just,
465 StartTimeValueMatcher(ContextRef{ContextPos::STARTTIME_POS}))))};
466
467 // unique origin and description only
468 DataDescriptorMatcher matcher5{
469 DataDescriptorMatcher::Op::And,
470 OriginValueMatcher{"TPC"},
471 std::make_unique<DataDescriptorMatcher>(
472 DataDescriptorMatcher::Op::And,
473 DescriptionValueMatcher{"CLUSTERS"},
474 std::make_unique<DataDescriptorMatcher>(
475 DataDescriptorMatcher::Op::And,
477 std::make_unique<DataDescriptorMatcher>(
478 DataDescriptorMatcher::Op::Just,
479 StartTimeValueMatcher(ContextRef{ContextPos::STARTTIME_POS}))))};
480
481 // no subspec in the matcher
482 DataDescriptorMatcher matcher6{
483 DataDescriptorMatcher::Op::And,
484 OriginValueMatcher{"TPC"},
485 std::make_unique<DataDescriptorMatcher>(
486 DataDescriptorMatcher::Op::And,
487 DescriptionValueMatcher{"CLUSTERS"},
488 std::make_unique<DataDescriptorMatcher>(
489 DataDescriptorMatcher::Op::And,
491 std::make_unique<DataDescriptorMatcher>(
492 DataDescriptorMatcher::Op::Just,
493 StartTimeValueMatcher(ContextRef{ContextPos::STARTTIME_POS}))))};
494
497
498 auto check = [](DataDescriptorMatcher const& matcher, bool expectConcreteDataMatcher, ConcreteDataMatcher compare = {"", "", 0}) {
499 auto concrete = DataSpecUtils::optionalConcreteDataMatcherFrom(matcher);
500 CHECK(concrete.has_value() == expectConcreteDataMatcher);
501 if (concrete.has_value()) {
502 CHECK(*concrete == compare);
503 }
504 };
505
506 check(matcher1, true, ConcreteDataMatcher{"TPC", "CLUSTERS", 1});
507 check(matcher2, true, ConcreteDataMatcher{"TPC", "CLUSTERS", 1});
508 check(matcher3, false);
509 check(matcher4, false);
510 check(matcher5, false);
511 check(matcher6, false);
512 check(matcher7, true, ConcreteDataMatcher{"ITS", "RAWDATA", 0});
513 check(matcher8, false);
514
515 REQUIRE(DataSpecUtils::asOptionalConcreteDataMatcher(ConcreteDataMatcher{"ITS", "RAWDATA", 0}) == ConcreteDataMatcher{"ITS", "RAWDATA", 0});
516 REQUIRE(DataSpecUtils::asOptionalConcreteDataMatcher(ConcreteDataTypeMatcher{"ITS", "RAWDATA"}) == std::nullopt);
517}
518
519// Testcase for DataSpecUtils::updateOutputList
520TEST_CASE("UpdateOutputList")
521{
522 // Empty vector of output specs should simply add the new spec
523 std::vector<OutputSpec> outputSpecs;
524 DataSpecUtils::updateOutputList(outputSpecs, {"TST", "DATA1", 0});
525 CHECK(outputSpecs.size() == 1);
526
527 // Adding the same spec again should not change the size
528 DataSpecUtils::updateOutputList(outputSpecs, {"TST", "DATA1", 0});
529 CHECK(outputSpecs.size() == 1);
530
531 // Adding a different spec should increase the size
532 DataSpecUtils::updateOutputList(outputSpecs, {"TST", "DATA2", 0});
533 CHECK(outputSpecs.size() == 2);
534
535 // Adding again the same spec again should not change the size
536 DataSpecUtils::updateOutputList(outputSpecs, {"TST", "DATA1", 0});
537 CHECK(outputSpecs.size() == 2);
538 // Check with something real..
539 ConcreteDataMatcher dstf{"FLP", "DISTSUBTIMEFRAME", 0xccdb};
540 DataSpecUtils::updateOutputList(outputSpecs, OutputSpec{{"ccdb-diststf"}, dstf, Lifetime::Timeframe});
541 CHECK(outputSpecs.size() == 3);
542 DataSpecUtils::updateOutputList(outputSpecs, OutputSpec{{"ccdb-diststf"}, dstf, Lifetime::Timeframe});
543 CHECK(outputSpecs.size() == 3);
544 // Label does not matter
545 DataSpecUtils::updateOutputList(outputSpecs, OutputSpec{{"ccdb2-diststf"}, dstf, Lifetime::Timeframe});
546 CHECK(outputSpecs.size() == 3);
547}
Something which can be matched against a header::DataDescription.
Something which can be matched against a header::DataOrigin.
Matcher on actual time, as reported in the DataProcessingHeader.
Something which can be matched against a header::SubSpecificationType.
#define CHECK
GLuint buffer
Definition glcorearb.h:655
GLsizeiptr size
Definition glcorearb.h:659
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
void check(const std::vector< std::string > &arguments, const std::vector< ConfigParamSpec > &workflowOptions, const std::vector< DeviceSpec > &deviceSpecs, CheckMatrix &matrix)
TEST_CASE("test_prepareArguments")
void clean_all_runtime_errors()
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
header::DataHeader::SubSpecificationType subSpec
static std::vector< InputSpec > parse(const char *s="")
static std::optional< ConcreteDataMatcher > asOptionalConcreteDataMatcher(OutputSpec const &spec)
static bool partialMatch(InputSpec const &spec, o2::header::DataOrigin const &origin)
static std::string describe(InputSpec const &spec)
static void updateOutputList(std::vector< OutputSpec > &list, OutputSpec &&input)
Updates list of OutputSpecs by merging metadata (or adding output).
static ConcreteDataTypeMatcher asConcreteDataTypeMatcher(OutputSpec const &spec)
static bool validate(InputSpec const &input)
static std::optional< typename ContainerT::value_type > find(ContainerT const &container, const o2::header::DataOrigin &origin, const o2::header::DataDescription &description, const o2::header::DataHeader::SubSpecificationType &subSpec)
static ConcreteDataMatcher asConcreteDataMatcher(InputSpec const &input)
static std::optional< header::DataHeader::SubSpecificationType > getOptionalSubSpec(OutputSpec const &spec)
Get the subspec, if available.
static InputSpec matchingInput(OutputSpec const &spec)
static data_matcher::DataDescriptorMatcher dataDescriptorMatcherFrom(ConcreteDataMatcher const &concrete)
Build a DataDescriptMatcher which does not care about the subSpec.
static std::optional< framework::ConcreteDataMatcher > optionalConcreteDataMatcherFrom(data_matcher::DataDescriptorMatcher const &matcher)
static void updateMatchingSubspec(InputSpec &in, header::DataHeader::SubSpecificationType subSpec)
static bool includes(const InputSpec &left, const InputSpec &right)
Checks if left includes right (or is equal to)
static header::DataOrigin asConcreteOrigin(InputSpec const &spec)
static header::DataDescription asConcreteDataDescription(InputSpec const &spec)
static bool match(InputSpec const &spec, ConcreteDataMatcher const &target)
A typesafe reference to an element of the context.
std::enable_if_t< std::is_same< T, std::string >::value==true, T > as() const
get the descriptor as std::string
Definition DataHeader.h:301
void compare(std::string_view s1, std::string_view s2)