Project
Loading...
Searching...
No Matches
test_WorkflowSerialization.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
13#include "../src/WorkflowSerializationHelpers.h"
14#include <catch_amalgamated.hpp>
15
16using namespace o2::framework;
17
18TEST_CASE("TestVerifyWorkflowSerialization")
19{
20 using namespace o2::framework;
21 int lm[2][2] = {{1, 2}, {3, 4}};
22 LabeledArray<int> labeled{&lm[0][0], 2, 2, {"r1", "r2"}, {"c1", "c2"}};
23 WorkflowSpec w0{ //
24 DataProcessorSpec{"A", //
25 {InputSpec{"foo", "A", "COLLISIONCONTEXT", 1, Lifetime::Condition, {
26 ConfigParamSpec{"aUrl", VariantType::String, "foo/bar", {"A InputSpec option"}}, //
27 ConfigParamSpec{"bUrl", VariantType::String, "foo/foo", {"Another InputSpec option"}}, //
28 }}}, //
29 {OutputSpec{{"bar"}, "C", "D", 2, Lifetime::Timeframe}}, //
30 AlgorithmSpec{[](ProcessingContext& /*ctx*/) {}}, //
31 { //
32 ConfigParamSpec{"aInt", VariantType::Int, 0, {"An Int"}}, //
33 ConfigParamSpec{"aFloat", VariantType::Float, 1.3, {"A Float"}}, //
34 ConfigParamSpec{"aBool", VariantType::Bool, true, {"A Bool"}}, //
35 ConfigParamSpec{"aString", VariantType::String, "some string", {"A String"}}, //
36 ConfigParamSpec{"aLabeledArray", VariantType::LabeledArrayInt, labeled, {"A LabeledArray"}}}}, // //
37 DataProcessorSpec{"B", //
38 {InputSpec{"foo", "C", "D"}}, //
39 { //
40 OutputSpec{{"bar1"}, "E", "F", 0}, //
41 OutputSpec{{"bar2"}, "E", "F", 1}}, //
42 AlgorithmSpec{[](ProcessingContext& /*ctx*/) {}}, //
43 {}}, //
44 DataProcessorSpec{"C", {}, //
45 { //
46 OutputSpec{{"bar"}, "G", "H"}}, //
47 AlgorithmSpec{[](ProcessingContext& /*ctx*/) {}}, //
48 {}}, //
49 DataProcessorSpec{"D", {InputSpec{"foo", {"C", "D"}}}, //
50 {OutputSpec{{"bar"}, {"I", "L"}}}, //
51 AlgorithmSpec{[](ProcessingContext& /*ctx*/) {}}, //
52 {}, //
54 {{"label a"}, {"label \"b\""}},
55 {{"key1", "v\"al'1"}, {"", "val2"}, {"key3", ""}, {"", ""}}}};
56
57 std::vector<DataProcessorInfo> dataProcessorInfoOut{
58 {.name = "A", .executable = "test_Framework_test_SerializationWorkflow", .cmdLineArgs = {"foo"}, .workflowOptions = {ConfigParamSpec{"aBool", VariantType::Bool, true, {"A Bool"}}, ConfigParamSpec{"aLabeledArray", VariantType::LabeledArrayInt, labeled, {"A LabeledArray"}}}},
59 {.name = "B", .executable = "test_Framework_test_SerializationWorkflow", .cmdLineArgs = {"b-bar", "bfoof", "fbdbfaso"}},
60 {.name = "C", .executable = "test_Framework_test_SerializationWorkflow"},
61 {.name = "D", .executable = "test_Framework_test_SerializationWorkflow"},
62 };
63
64 CommandInfo commandInfoOut{"o2-dpl-workflow -b --option 1 --option 2"};
65
66 std::vector<DataProcessorInfo> dataProcessorInfoIn{};
67 CommandInfo commandInfoIn;
68
69 std::ostringstream firstDump;
70 WorkflowSerializationHelpers::dump(firstDump, w0, dataProcessorInfoOut, commandInfoOut);
71 std::istringstream is;
72 is.str(firstDump.str());
73 WorkflowSpec w1;
74 WorkflowSerializationHelpers::import(is, w1, dataProcessorInfoIn, commandInfoIn);
75
76 std::ostringstream secondDump;
77 WorkflowSerializationHelpers::dump(secondDump, w1, dataProcessorInfoIn, commandInfoIn);
78
79 REQUIRE(w0.size() == 4);
80 REQUIRE(w0.size() == w1.size());
81 REQUIRE(firstDump.str() == secondDump.str());
82 REQUIRE(commandInfoIn.command == commandInfoOut.command);
83
84 // also check if the conversion to ConcreteDataMatcher is working at import
85 REQUIRE(std::get_if<ConcreteDataMatcher>(&w1[0].inputs[0].matcher) != nullptr);
86
87 // LabeledArray options survive the round trip, both as processor and as workflow options
88 auto checkLabeled = [&](ConfigParamSpec const& spec) {
89 REQUIRE(spec.name == "aLabeledArray");
90 REQUIRE(spec.type == VariantType::LabeledArrayInt);
91 auto la = spec.defaultValue.get<LabeledArray<int>>();
92 REQUIRE(la.getLabelsRows() == labeled.getLabelsRows());
93 REQUIRE(la.getLabelsCols() == labeled.getLabelsCols());
94 REQUIRE(la.get("r2", "c1") == 3);
95 };
96 checkLabeled(w1[0].options.back());
97 REQUIRE(dataProcessorInfoIn[0].workflowOptions.size() == 2);
98 checkLabeled(dataProcessorInfoIn[0].workflowOptions.back());
99}
100
103TEST_CASE("TestVerifyWildcard")
104{
105 using namespace o2::framework;
106 WorkflowSpec w0{
108 .name = "A",
109 .inputs = {{"clbPayload", "CLP"}, {"clbWrapper", "CLW"}},
110 }};
111
112 std::vector<DataProcessorInfo> dataProcessorInfoOut{
113 {.name = "A", .executable = "test_Framework_test_SerializationWorkflow"},
114 };
115
116 CommandInfo commandInfoOut{"o2-dpl-workflow -b --option 1 --option 2"};
117
118 std::vector<DataProcessorInfo> dataProcessorInfoIn{};
119 CommandInfo commandInfoIn;
120
121 std::ostringstream firstDump;
122 WorkflowSerializationHelpers::dump(firstDump, w0, dataProcessorInfoOut, commandInfoOut);
123 std::istringstream is;
124 is.str(firstDump.str());
125 WorkflowSpec w1;
126 WorkflowSerializationHelpers::import(is, w1, dataProcessorInfoIn, commandInfoIn);
127
128 std::ostringstream secondDump;
129 WorkflowSerializationHelpers::dump(secondDump, w1, dataProcessorInfoIn, commandInfoIn);
130
131 REQUIRE(w0.size() == 1);
132 REQUIRE(w0.size() == w1.size());
133 REQUIRE(firstDump.str() == secondDump.str());
134 REQUIRE(commandInfoIn.command == commandInfoOut.command);
135
136 // also check if the conversion to ConcreteDataMatcher is working at import
137 // REQUIRE(std::get_if<ConcreteDataTypeMatcher>(&w1[0].inputs[0].matcher) != nullptr);;
138}
139
140TEST_CASE("TestInputOutputSpecMetadata")
141{
142 WorkflowSpec wso{
144 .name = "S1",
145 .outputs = {OutputSpec{OutputLabel{"o1"}, o2::header::DataOrigin{"TST"}, "OUTPUT1", 0, Lifetime::Timeframe, {{"param1", VariantType::Bool, true, ConfigParamSpec::HelpString{"\"\""}}, {"param2", VariantType::Bool, true, ConfigParamSpec::HelpString{"\"\""}}}},
146 OutputSpec{OutputLabel{"o2"}, o2::header::DataOrigin{"TST"}, "OUTPUT2"}}}};
147
148 std::vector<DataProcessorInfo> dataProcessorInfoOut{
149 {.name = "S1", .executable = "test_Framework_test_SerializationWorkflow"},
150 };
151
152 CommandInfo commandInfoOut{"o2-dpl-workflow -b"};
153
154 std::vector<DataProcessorInfo> dataProcessorInfoIn{};
155 CommandInfo commandInfoIn;
156
157 std::ostringstream firstDump;
158 WorkflowSerializationHelpers::dump(firstDump, wso, dataProcessorInfoOut, commandInfoOut);
159 std::istringstream is;
160 is.str(firstDump.str());
161
162 WorkflowSpec wsi;
163 WorkflowSerializationHelpers::import(is, wsi, dataProcessorInfoIn, commandInfoIn);
164
165 REQUIRE(wsi[0].outputs[0].metadata.size() == 2);
166 REQUIRE(wsi[0].outputs[1].metadata.size() == 0);
167 REQUIRE(wso[0].outputs[0].metadata.size() == wsi[0].outputs[0].metadata.size());
168 REQUIRE(wso[0].outputs[1].metadata.size() == wsi[0].outputs[1].metadata.size());
169 REQUIRE(wso[0].outputs[0].metadata[0] == wsi[0].outputs[0].metadata[0]);
170 REQUIRE(wso[0].outputs[0].metadata[1] == wsi[0].outputs[0].metadata[1]);
171}
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
TEST_CASE("test_prepareArguments")
std::vector< DataProcessorSpec > WorkflowSpec
static std::vector< ServiceSpec > defaultServices(std::string extraPlugins="", int numWorkers=0)
Split a string into a vector of strings using : as a separator.
static void dump(std::ostream &o, std::vector< DataProcessorSpec > const &workflow, std::vector< DataProcessorInfo > const &metadata, CommandInfo const &commandInfo)
static bool import(std::istream &s, std::vector< DataProcessorSpec > &workflow, std::vector< DataProcessorInfo > &metadata, CommandInfo &command)