13#include <catch_amalgamated.hpp>
14#include "../src/DDSConfigHelpers.h"
15#include "../src/DeviceSpecHelpers.h"
16#include "../src/SimpleResourceManager.h"
17#include "../src/ComputingResourceHelpers.h"
38 ctx.outputs().make<
int>(
Output{
"TST", what, 0}, 1);
51 std::this_thread::sleep_for(std::chrono::seconds(1));
52 ctx.outputs().make<
int>(
Output{
"TST",
"A1", 0}, 1);
53 ctx.outputs().make<
int>(
Output{
"TST",
"A2", 0}, 1);
72 ConfigParamSpec{
"a-param", VariantType::Int, 1, {
"A parameter which should not be escaped"}},
73 ConfigParamSpec{
"b-param", VariantType::String,
"", {
"a parameter which will be escaped"}},
74 ConfigParamSpec{
"c-param", VariantType::String,
"foo;bar", {
"another parameter which will be escaped"}},
85 std::this_thread::sleep_for(std::chrono::seconds(1));
86 ctx.outputs().make<
int>(
Output{
"TST",
"A1", 0}, 1);
87 ctx.outputs().make<
int>(
Output{
"TST",
"A2", 0}, 1);
106 ConfigParamSpec{
"a-param", VariantType::Int, 1, {
"A parameter which should not be escaped"}},
107 ConfigParamSpec{
"b-param", VariantType::String,
"", {
"a parameter which will be escaped"}},
108 ConfigParamSpec{
"c-param", VariantType::String,
"foo;bar", {
"another parameter which will be escaped"}},
110 .labels = {{
"expendable"}}}};
113char* strdiffchr(
const char*
s1,
const char* s2)
115 while (*
s1 && *
s1 == *s2) {
119 return (*
s1 == *s2) ? nullptr : (
char*)
s1;
126 std::ostringstream ss{
""};
128 auto channelPolicies = makeTrivialChannelPolicies(*configContext);
129 std::vector<DeviceSpec> devices;
135 std::vector<DeviceControl> controls;
136 std::vector<DeviceExecution> executions;
137 controls.resize(devices.size());
138 executions.resize(devices.size());
140 std::vector<ConfigParamSpec> workflowOptions = {
141 ConfigParamSpec{
"jobs", VariantType::Int, 4, {
"number of producer jobs"}}};
143 std::vector<DataProcessorInfo> dataProcessorInfos = {
145 {
"A",
"bcsadc/foo", {}, workflowOptions},
146 {
"B",
"foo", {}, workflowOptions},
147 {
"C",
"foo", {}, workflowOptions},
148 {
"D",
"foo", {}, workflowOptions},
156 devices, executions, controls, {},
160 auto expected = R
"EXPECTED(<topology name="o2-dataflow">
161<asset name="dpl_json" type="inline" visibility="global" value="{
162 "workflow": [
164 "name": "A",
165 "inputs": [],
166 "outputs": [
168 "binding": "TST/A1/0",
169 "origin": "TST",
170 "description": "A1",
171 "subspec": 0,
172 "lifetime": 0
175 "binding": "TST/A2/0",
176 "origin": "TST",
177 "description": "A2",
178 "subspec": 0,
179 "lifetime": 0
182 "options": [],
183 "labels": [],
184 "metadata": [],
186 "nSlots": 1,
187 "inputTimeSliceId": 0,
188 "maxInputTimeslices": 1
191 "name": "B",
192 "inputs": [
194 "binding": "x",
195 "origin": "TST",
196 "description": "A1",
197 "subspec": 0,
198 "lifetime": 0
201 "outputs": [
203 "binding": "TST/B1/0",
204 "origin": "TST",
205 "description": "B1",
206 "subspec": 0,
207 "lifetime": 0
210 "options": [],
211 "labels": [],
212 "metadata": [],
214 "nSlots": 1,
215 "inputTimeSliceId": 0,
216 "maxInputTimeslices": 1
219 "name": "C",
220 "inputs": [
222 "binding": "y",
223 "origin": "TST",
224 "description": "A2",
225 "subspec": 0,
226 "lifetime": 0
229 "outputs": [
231 "binding": "TST/C1/0",
232 "origin": "TST",
233 "description": "C1",
234 "subspec": 0,
235 "lifetime": 0
238 "options": [],
239 "labels": [],
240 "metadata": [],
242 "nSlots": 1,
243 "inputTimeSliceId": 0,
244 "maxInputTimeslices": 1
247 "name": "D",
248 "inputs": [
250 "binding": "x",
251 "origin": "TST",
252 "description": "B1",
253 "subspec": 0,
254 "lifetime": 0
257 "binding": "y",
258 "origin": "TST",
259 "description": "C1",
260 "subspec": 0,
261 "lifetime": 0
264 "outputs": [],
265 "options": [
267 "name": "a-param",
268 "type": "0",
269 "defaultValue": "1",
270 "help": "A parameter which should not be escaped",
271 "kind": "0"
274 "name": "b-param",
275 "type": "4",
276 "defaultValue": "",
277 "help": "a parameter which will be escaped",
278 "kind": "0"
281 "name": "c-param",
282 "type": "4",
283 "defaultValue": "foo;bar",
284 "help": "another parameter which will be escaped",
285 "kind": "0"
288 "labels": [],
289 "metadata": [],
291 "nSlots": 1,
292 "inputTimeSliceId": 0,
293 "maxInputTimeslices": 1
296 "metadata": [
298 "name": "A",
299 "executable": "bcsadc/foo",
300 "cmdLineArgs": [],
301 "workflowOptions": [
303 "name": "jobs",
304 "type": "0",
305 "defaultValue": "4",
306 "help": "number of producer jobs"
309 "channels": []
312 "name": "B",
313 "executable": "foo",
314 "cmdLineArgs": [],
315 "workflowOptions": [
317 "name": "jobs",
318 "type": "0",
319 "defaultValue": "4",
320 "help": "number of producer jobs"
323 "channels": []
326 "name": "C",
327 "executable": "foo",
328 "cmdLineArgs": [],
329 "workflowOptions": [
331 "name": "jobs",
332 "type": "0",
333 "defaultValue": "4",
334 "help": "number of producer jobs"
337 "channels": []
340 "name": "D",
341 "executable": "foo",
342 "cmdLineArgs": [],
343 "workflowOptions": [
345 "name": "jobs",
346 "type": "0",
347 "defaultValue": "4",
348 "help": "number of producer jobs"
351 "channels": []
354 "command": "foo"
357 <assets><name>dpl_json</name></assets>
358 <exe reachable="true">cat ${DDS_LOCATION}/dpl_json.asset | foo --id A_dds%TaskIndex%_%CollectionIndex% --shm-monitor false --log-color false --batch --color false --channel-config "name=from_A_to_B,type=push,method=bind,address=ipc://@localhostworkflow-id_22000,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --channel-config "name=from_A_to_C,type=push,method=bind,address=ipc://@localhostworkflow-id_22001,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --bad-alloc-attempt-interval 50 --bad-alloc-max-attempts 1 --early-forward-policy never --io-threads 1 --jobs 4 --severity info --shm-allocation rbtree_best_fit --shm-metadata-msg-size 0 --shm-mlock-segment false --shm-mlock-segment-on-creation false --shm-no-cleanup false --shm-segment-id 0 --shm-throw-bad-alloc true --shm-zero-segment false --signposts "" --stacktrace-on-signal simple --timeframes-rate-limit 0 --session dpl_workflow-id --plugin odc</exe>
361 <assets><name>dpl_json</name></assets>
362 <exe reachable="true">cat ${DDS_LOCATION}/dpl_json.asset | foo --id B_dds%TaskIndex%_%CollectionIndex% --shm-monitor false --log-color false --batch --color false --channel-config "name=from_B_to_D,type=push,method=bind,address=ipc://@localhostworkflow-id_22002,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --channel-config "name=from_A_to_B,type=pull,method=connect,address=ipc://@localhostworkflow-id_22000,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --bad-alloc-attempt-interval 50 --bad-alloc-max-attempts 1 --early-forward-policy never --io-threads 1 --jobs 4 --severity info --shm-allocation rbtree_best_fit --shm-metadata-msg-size 0 --shm-mlock-segment false --shm-mlock-segment-on-creation false --shm-no-cleanup false --shm-segment-id 0 --shm-throw-bad-alloc true --shm-zero-segment false --signposts "" --stacktrace-on-signal simple --timeframes-rate-limit 0 --session dpl_workflow-id --plugin odc</exe>
365 <assets><name>dpl_json</name></assets>
366 <exe reachable="true">cat ${DDS_LOCATION}/dpl_json.asset | foo --id C_dds%TaskIndex%_%CollectionIndex% --shm-monitor false --log-color false --batch --color false --channel-config "name=from_C_to_D,type=push,method=bind,address=ipc://@localhostworkflow-id_22003,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --channel-config "name=from_A_to_C,type=pull,method=connect,address=ipc://@localhostworkflow-id_22001,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --bad-alloc-attempt-interval 50 --bad-alloc-max-attempts 1 --early-forward-policy never --io-threads 1 --jobs 4 --severity info --shm-allocation rbtree_best_fit --shm-metadata-msg-size 0 --shm-mlock-segment false --shm-mlock-segment-on-creation false --shm-no-cleanup false --shm-segment-id 0 --shm-throw-bad-alloc true --shm-zero-segment false --signposts "" --stacktrace-on-signal simple --timeframes-rate-limit 0 --session dpl_workflow-id --plugin odc</exe>
369 <assets><name>dpl_json</name></assets>
370 <exe reachable="true">cat ${DDS_LOCATION}/dpl_json.asset | foo --id D_dds%TaskIndex%_%CollectionIndex% --shm-monitor false --log-color false --batch --color false --channel-config "name=from_B_to_D,type=pull,method=connect,address=ipc://@localhostworkflow-id_22002,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --channel-config "name=from_C_to_D,type=pull,method=connect,address=ipc://@localhostworkflow-id_22003,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --bad-alloc-attempt-interval 50 --bad-alloc-max-attempts 1 --early-forward-policy never --io-threads 1 --jobs 4 --severity info --shm-allocation rbtree_best_fit --shm-metadata-msg-size 0 --shm-mlock-segment false --shm-mlock-segment-on-creation false --shm-no-cleanup false --shm-segment-id 0 --shm-throw-bad-alloc true --shm-zero-segment false --signposts "" --stacktrace-on-signal simple --timeframes-rate-limit 0 --a-param 1 --b-param "" --c-param "foo;bar" --session dpl_workflow-id --plugin odc</exe>
372 <declcollection name="DPL">
382 REQUIRE(strdiffchr(ss.str().data(), expected) == nullptr);
383 REQUIRE(strdiffchr(ss.str().data(),
expected) == strdiffchr(
expected, ss.str().data()));
389 auto workflow = defineDataProcessingExpendable();
390 std::ostringstream ss{
""};
392 auto channelPolicies = makeTrivialChannelPolicies(*configContext);
393 std::vector<DeviceSpec> devices;
399 std::vector<DeviceControl> controls;
400 std::vector<DeviceExecution> executions;
401 controls.resize(devices.size());
402 executions.resize(devices.size());
404 std::vector<ConfigParamSpec> workflowOptions = {
405 ConfigParamSpec{
"jobs", VariantType::Int, 4, {
"number of producer jobs"}}};
407 std::vector<DataProcessorInfo> dataProcessorInfos = {
409 {
"A",
"bcsadc/foo", {}, workflowOptions},
410 {
"B",
"foo", {}, workflowOptions},
411 {
"C",
"foo", {}, workflowOptions},
412 {
"D",
"foo", {}, workflowOptions},
420 devices, executions, controls, {},
424 auto expected = R
"EXPECTED(<topology name="o2-dataflow">
425<declrequirement name="odc_expendable_task" type="custom" value="true" />
426<asset name="dpl_json" type="inline" visibility="global" value="{
427 "workflow": [
429 "name": "A",
430 "inputs": [],
431 "outputs": [
433 "binding": "TST/A1/0",
434 "origin": "TST",
435 "description": "A1",
436 "subspec": 0,
437 "lifetime": 0
440 "binding": "TST/A2/0",
441 "origin": "TST",
442 "description": "A2",
443 "subspec": 0,
444 "lifetime": 0
447 "options": [],
448 "labels": [],
449 "metadata": [],
451 "nSlots": 1,
452 "inputTimeSliceId": 0,
453 "maxInputTimeslices": 1
456 "name": "B",
457 "inputs": [
459 "binding": "x",
460 "origin": "TST",
461 "description": "A1",
462 "subspec": 0,
463 "lifetime": 0
466 "outputs": [
468 "binding": "TST/B1/0",
469 "origin": "TST",
470 "description": "B1",
471 "subspec": 0,
472 "lifetime": 0
475 "options": [],
476 "labels": [],
477 "metadata": [],
479 "nSlots": 1,
480 "inputTimeSliceId": 0,
481 "maxInputTimeslices": 1
484 "name": "C",
485 "inputs": [
487 "binding": "y",
488 "origin": "TST",
489 "description": "A2",
490 "subspec": 0,
491 "lifetime": 0
494 "outputs": [
496 "binding": "TST/C1/0",
497 "origin": "TST",
498 "description": "C1",
499 "subspec": 0,
500 "lifetime": 0
503 "options": [],
504 "labels": [],
505 "metadata": [],
507 "nSlots": 1,
508 "inputTimeSliceId": 0,
509 "maxInputTimeslices": 1
512 "name": "D",
513 "inputs": [
515 "binding": "x",
516 "origin": "TST",
517 "description": "B1",
518 "subspec": 0,
519 "lifetime": 0
522 "binding": "y",
523 "origin": "TST",
524 "description": "C1",
525 "subspec": 0,
526 "lifetime": 0
529 "outputs": [],
530 "options": [
532 "name": "a-param",
533 "type": "0",
534 "defaultValue": "1",
535 "help": "A parameter which should not be escaped",
536 "kind": "0"
539 "name": "b-param",
540 "type": "4",
541 "defaultValue": "",
542 "help": "a parameter which will be escaped",
543 "kind": "0"
546 "name": "c-param",
547 "type": "4",
548 "defaultValue": "foo;bar",
549 "help": "another parameter which will be escaped",
550 "kind": "0"
553 "labels": [
554 "expendable"
556 "metadata": [],
558 "nSlots": 1,
559 "inputTimeSliceId": 0,
560 "maxInputTimeslices": 1
563 "metadata": [
565 "name": "A",
566 "executable": "bcsadc/foo",
567 "cmdLineArgs": [],
568 "workflowOptions": [
570 "name": "jobs",
571 "type": "0",
572 "defaultValue": "4",
573 "help": "number of producer jobs"
576 "channels": []
579 "name": "B",
580 "executable": "foo",
581 "cmdLineArgs": [],
582 "workflowOptions": [
584 "name": "jobs",
585 "type": "0",
586 "defaultValue": "4",
587 "help": "number of producer jobs"
590 "channels": []
593 "name": "C",
594 "executable": "foo",
595 "cmdLineArgs": [],
596 "workflowOptions": [
598 "name": "jobs",
599 "type": "0",
600 "defaultValue": "4",
601 "help": "number of producer jobs"
604 "channels": []
607 "name": "D",
608 "executable": "foo",
609 "cmdLineArgs": [],
610 "workflowOptions": [
612 "name": "jobs",
613 "type": "0",
614 "defaultValue": "4",
615 "help": "number of producer jobs"
618 "channels": []
621 "command": "foo"
624 <assets><name>dpl_json</name></assets>
625 <exe reachable="true">cat ${DDS_LOCATION}/dpl_json.asset | foo --id A_dds%TaskIndex%_%CollectionIndex% --shm-monitor false --log-color false --batch --color false --channel-config "name=from_A_to_B,type=push,method=bind,address=ipc://@localhostworkflow-id_22000,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --channel-config "name=from_A_to_C,type=push,method=bind,address=ipc://@localhostworkflow-id_22001,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --bad-alloc-attempt-interval 50 --bad-alloc-max-attempts 1 --early-forward-policy never --io-threads 1 --jobs 4 --severity info --shm-allocation rbtree_best_fit --shm-metadata-msg-size 0 --shm-mlock-segment false --shm-mlock-segment-on-creation false --shm-no-cleanup false --shm-segment-id 0 --shm-throw-bad-alloc true --shm-zero-segment false --signposts "" --stacktrace-on-signal simple --timeframes-rate-limit 0 --session dpl_workflow-id --plugin odc</exe>
628 <assets><name>dpl_json</name></assets>
629 <exe reachable="true">cat ${DDS_LOCATION}/dpl_json.asset | foo --id B_dds%TaskIndex%_%CollectionIndex% --shm-monitor false --log-color false --batch --color false --channel-config "name=from_B_to_D,type=push,method=bind,address=ipc://@localhostworkflow-id_22002,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --channel-config "name=from_A_to_B,type=pull,method=connect,address=ipc://@localhostworkflow-id_22000,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --bad-alloc-attempt-interval 50 --bad-alloc-max-attempts 1 --early-forward-policy never --io-threads 1 --jobs 4 --severity info --shm-allocation rbtree_best_fit --shm-metadata-msg-size 0 --shm-mlock-segment false --shm-mlock-segment-on-creation false --shm-no-cleanup false --shm-segment-id 0 --shm-throw-bad-alloc true --shm-zero-segment false --signposts "" --stacktrace-on-signal simple --timeframes-rate-limit 0 --session dpl_workflow-id --plugin odc</exe>
632 <assets><name>dpl_json</name></assets>
633 <exe reachable="true">cat ${DDS_LOCATION}/dpl_json.asset | foo --id C_dds%TaskIndex%_%CollectionIndex% --shm-monitor false --log-color false --batch --color false --channel-config "name=from_C_to_D,type=push,method=bind,address=ipc://@localhostworkflow-id_22003,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --channel-config "name=from_A_to_C,type=pull,method=connect,address=ipc://@localhostworkflow-id_22001,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --bad-alloc-attempt-interval 50 --bad-alloc-max-attempts 1 --early-forward-policy never --io-threads 1 --jobs 4 --severity info --shm-allocation rbtree_best_fit --shm-metadata-msg-size 0 --shm-mlock-segment false --shm-mlock-segment-on-creation false --shm-no-cleanup false --shm-segment-id 0 --shm-throw-bad-alloc true --shm-zero-segment false --signposts "" --stacktrace-on-signal simple --timeframes-rate-limit 0 --session dpl_workflow-id --plugin odc</exe>
636 <assets><name>dpl_json</name></assets>
637 <exe reachable="true">cat ${DDS_LOCATION}/dpl_json.asset | foo --id D_dds%TaskIndex%_%CollectionIndex% --shm-monitor false --log-color false --batch --color false --channel-config "name=from_B_to_D,type=pull,method=connect,address=ipc://@localhostworkflow-id_22002,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --channel-config "name=from_C_to_D,type=pull,method=connect,address=ipc://@localhostworkflow-id_22003,transport=shmem,rateLogging=0,rcvBufSize=1,sndBufSize=1" --bad-alloc-attempt-interval 50 --bad-alloc-max-attempts 1 --early-forward-policy never --io-threads 1 --jobs 4 --severity info --shm-allocation rbtree_best_fit --shm-metadata-msg-size 0 --shm-mlock-segment false --shm-mlock-segment-on-creation false --shm-no-cleanup false --shm-segment-id 0 --shm-throw-bad-alloc true --shm-zero-segment false --signposts "" --stacktrace-on-signal simple --timeframes-rate-limit 0 --a-param 1 --b-param "" --c-param "foo;bar" --session dpl_workflow-id --plugin odc</exe>
639 <name>odc_expendable_task</name>
642 <declcollection name="DPL">
652 REQUIRE(strdiffchr(ss.str().data(), expected) == nullptr);
653 REQUIRE(strdiffchr(ss.str().data(),
expected) == strdiffchr(
expected, ss.str().data()));
WorkflowSpec defineDataProcessing(ConfigContext const &configcontext)
std::unique_ptr< ConfigContext > makeEmptyConfigContext()
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Defining PrimaryVertex explicitly as messageable.
TEST_CASE("test_prepareArguments")
std::vector< DataProcessorSpec > WorkflowSpec
static std::vector< CallbacksPolicy > createDefaultPolicies()
static std::vector< CompletionPolicy > createDefaultPolicies()
Helper to create the default configuration.
static ComputingResource getLocalhostResource()
static void dumpDeviceSpec2DDS(std::ostream &out, DriverMode mode, std::string const &workflowSuffix, std::vector< DataProcessorSpec > const &workflow, std::vector< DataProcessorInfo > const &metadata, std::vector< DeviceSpec > const &specs, std::vector< DeviceExecution > const &executions, CommandInfo const &commandInfo)
static void prepareArguments(bool defaultQuiet, bool defaultStopped, bool intereactive, unsigned short driverPort, DriverConfig const &driverConfig, std::vector< DataProcessorInfo > const &processorInfos, std::vector< DeviceSpec > const &deviceSpecs, std::vector< DeviceExecution > &deviceExecutions, std::vector< DeviceControl > &deviceControls, std::vector< ConfigParamSpec > const &detectedOptions, std::string const &uniqueWorkflowId)
static void dataProcessorSpecs2DeviceSpecs(const WorkflowSpec &workflow, std::vector< ChannelConfigurationPolicy > const &channelPolicies, std::vector< CompletionPolicy > const &completionPolicies, std::vector< DispatchPolicy > const &dispatchPolicies, std::vector< ResourcePolicy > const &resourcePolicies, std::vector< CallbacksPolicy > const &callbacksPolicies, std::vector< SendingPolicy > const &sendingPolicy, std::vector< ForwardingPolicy > const &forwardingPolicies, std::vector< DeviceSpec > &devices, ResourceManager &resourceManager, std::string const &uniqueWorkflowId, ConfigContext const &configContext, bool optimizeTopology=false, unsigned short resourcesMonitoringInterval=0, std::string const &channelPrefix="", OverrideServiceSpecs const &overrideServices={})
bool batch
Whether the driver was started in batch mode or not.
std::map< std::string, ID > expected
AlgorithmSpec simplePipe(o2::header::DataDescription what)