17#include "../src/DeviceSpecHelpers.h"
18#include <catch_amalgamated.hpp>
24#include "../src/SimpleResourceManager.h"
25#include "../src/ComputingResourceHelpers.h"
30using CheckMatrix = std::map<std::string, std::vector<std::pair<std::string, std::string>>>;
35 bool foundOption =
false;
36 for (
auto const& execArg : execution.
args) {
37 if (execArg ==
nullptr) {
41 foundOption = option == execArg;
42 }
else if (argument == execArg) {
55 const std::vector<ConfigParamSpec>& workflowOptions,
56 const std::vector<DeviceSpec>& deviceSpecs,
64 std::vector<DeviceExecution> deviceExecutions(deviceSpecs.size());
65 std::vector<DeviceControl> deviceControls(deviceSpecs.size());
66 std::vector<DataProcessorInfo> dataProcessorInfos;
67 for (
auto& [
name, _] : matrix) {
70 .executable =
"executable-name",
72 .workflowOptions = workflowOptions,
85 const auto& deviceSpec = deviceSpecs[
index];
86 const auto& deviceExecution = deviceExecutions[
index];
87 std::stringstream execArgs;
88 for (
const auto& arg : deviceExecution.args) {
93 execArgs <<
" " << arg;
95 for (
auto const& testCase : matrix[deviceSpec.name]) {
96 INFO(std::string(
"can not find option: ") + testCase.first +
" " + testCase.second);
97 REQUIRE(
search(deviceExecution, testCase.first, testCase.second));
104 int lm[1][2] = {{1, 2}};
105 std::vector<ConfigParamSpec> workflowOptions{
110 std::string labeledDefault = R
"({"labels_rows":["r"],"labels_cols":["c1","c2"],"values":[[1,2]]})";
111 std::string labeledOther = R"({"labels_rows":["r"],"labels_cols":["c1","c2"],"values":[[3,4]]})";
118 {
OutputSpec{{
"output"},
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe}},
124 {
InputSpec{
"input",
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe}},
132 std::vector<DeviceSpec> deviceSpecs;
135 auto rm = std::make_unique<SimpleResourceManager>(resources);
146 *rm,
"workflow-id", *configContext);
153 matrix[
"processor0"] = {{
"--depth",
"1"}, {
"--foo",
"bar"}, {
"--mode",
"default"}};
154 matrix[
"processor1"] = matrix[
"processor0"];
155 check({}, workflowOptions, deviceSpecs, matrix);
158 check({
"--unknown",
"option"}, workflowOptions, deviceSpecs, matrix);
161 matrix[
"processor0"] = {{
"--depth",
"1"}, {
"--foo",
"bar"}, {
"--mode",
"silly"}};
162 matrix[
"processor1"] = matrix[
"processor0"];
163 check({
"--mode",
"silly"}, workflowOptions, deviceSpecs, matrix);
166 matrix[
"processor0"] = {{
"--depth",
"1"}, {
"--foo",
"bar"}, {
"--mode",
"silly"}};
167 matrix[
"processor1"] = {{
"--depth",
"1"}, {
"--foo",
"bar"}, {
"--mode",
"default"}};
168 check({
"--processor0",
"--mode silly"}, workflowOptions, deviceSpecs, matrix);
171 matrix[
"processor0"] = {{
"--depth",
"1"}, {
"--foo",
"bar"}, {
"--mode",
"silly"}};
172 matrix[
"processor1"] = {{
"--depth",
"1"}, {
"--foo",
"bar"}, {
"--mode",
"advanced"}};
173 check({
"--mode",
"advanced",
"--processor0",
"--mode silly"}, workflowOptions, deviceSpecs, matrix);
176 matrix[
"processor0"] = {{
"--depth",
"2"}, {
"--foo",
"bar"}, {
"--mode",
"default"}};
177 matrix[
"processor1"] = matrix[
"processor0"];
178 check({
"--depth",
"2"}, workflowOptions, deviceSpecs, matrix);
181 matrix[
"processor0"] = {{
"--depth",
"2"}, {
"--foo",
"bar"}, {
"--mode",
"silly"}};
182 matrix[
"processor1"] = {{
"--depth",
"2"}, {
"--foo",
"bar"}, {
"--mode",
"default"}};
183 check({
"--depth",
"2",
"--processor0",
"--mode silly"}, workflowOptions, deviceSpecs, matrix);
186 matrix[
"processor0"] = {{
"--depth",
"1"}, {
"--labeled", labeledDefault}};
187 matrix[
"processor1"] = matrix[
"processor0"];
188 check({}, workflowOptions, deviceSpecs, matrix);
189 matrix[
"processor0"] = {{
"--depth",
"1"}, {
"--labeled", labeledOther}};
190 matrix[
"processor1"] = matrix[
"processor0"];
191 check({
"--labeled", labeledOther}, workflowOptions, deviceSpecs, matrix);
197 std::vector<DataProcessorInfo> infos = {
198 {.cmdLineArgs = {
"--driver-client-backend",
"foo"}},
201 REQUIRE(infos[0].cmdLineArgs[1] ==
"foo");
202 REQUIRE(infos[1].cmdLineArgs[1] ==
"foo");
205 std::vector<DataProcessorInfo> infos = {
206 {.cmdLineArgs = {
"--driver-client-backend",
"foo"}},
207 {.cmdLineArgs = {
"--driver-client-backend",
"bar"}}};
211 std::vector<DataProcessorInfo> infos = {
212 {.cmdLineArgs = {
"--driver-client-backend",
"foo"}},
213 {.cmdLineArgs = {
"--driver-client-backend",
"foo"}}};
215 REQUIRE(infos[0].cmdLineArgs[1] ==
"foo");
216 REQUIRE(infos[1].cmdLineArgs[1] ==
"foo");
219 std::vector<DataProcessorInfo> infos = {
220 {.cmdLineArgs = {
"foo",
"bar"}},
221 {.cmdLineArgs = {
"fnjcnak",
"foo"}}};
223 REQUIRE(infos[0].cmdLineArgs[3] ==
"stdout://");
224 REQUIRE(infos[1].cmdLineArgs[3] ==
"stdout://");
227 std::vector<DataProcessorInfo> infos = {
228 {.cmdLineArgs = {
"foo",
"bar",
"--driver-client-backend",
"bar"}},
229 {.cmdLineArgs = {
"fnjcnak",
"foo"}}};
231 REQUIRE(infos[0].cmdLineArgs[3] ==
"bar");
232 REQUIRE(infos[1].cmdLineArgs[3] ==
"bar");
239 std::vector<DataProcessorInfo> infos = {
240 {{}, {}, {
"--readers",
"2"}},
243 infos,
"--readers",
nullptr, 1, [](
long long x,
long long y) {
return x >
y ?
x :
y; });
244 REQUIRE(infos[0].cmdLineArgs[1] ==
"2");
245 REQUIRE(infos[1].cmdLineArgs[1] ==
"2");
248 std::vector<DataProcessorInfo> infos = {
252 infos,
"--readers",
nullptr, 1, [](
long long x,
long long y) {
return x >
y ?
x :
y; });
253 REQUIRE(infos[0].cmdLineArgs.size() == 0);
254 REQUIRE(infos[1].cmdLineArgs.size() == 0);
257 std::vector<DataProcessorInfo> infos = {
261 infos,
"--readers", []() {
return 1; }, 3, [](
long long x,
long long y) {
return x >
y ?
x :
y; });
262 REQUIRE(infos[0].cmdLineArgs.size() == 2);
263 REQUIRE(infos[1].cmdLineArgs.size() == 2);
264 REQUIRE(infos[0].cmdLineArgs[1] ==
"1");
265 REQUIRE(infos[1].cmdLineArgs[1] ==
"1");
268 std::vector<DataProcessorInfo> infos = {
269 {{}, {}, {
"--readers",
"2"}},
270 {{}, {}, {
"--readers",
"3"}}};
272 infos,
"--readers", []() {
return 1; }, 1, [](
long long x,
long long y) {
return x >
y ?
x :
y; });
273 REQUIRE(infos[0].cmdLineArgs.size() == 2);
274 REQUIRE(infos[1].cmdLineArgs.size() == 2);
275 REQUIRE(infos[0].cmdLineArgs[1] ==
"3");
276 REQUIRE(infos[1].cmdLineArgs[1] ==
"3");
279 std::vector<DataProcessorInfo> infos = {
280 {{}, {}, {
"--readers",
"3"}},
281 {{}, {}, {
"--readers",
"2"}}};
283 infos,
"--readers", []() {
return 1; }, 1, [](
long long x,
long long y) {
return x >
y ?
x :
y; });
284 REQUIRE(infos[0].cmdLineArgs.size() == 2);
285 REQUIRE(infos[1].cmdLineArgs.size() == 2);
286 REQUIRE(infos[0].cmdLineArgs[1] ==
"3");
287 REQUIRE(infos[1].cmdLineArgs[1] ==
"3");
290 std::vector<DataProcessorInfo> infos = {
291 {.cmdLineArgs = {
"foo",
"bar",
"--readers",
"3"}},
292 {.cmdLineArgs = {
"--readers",
"2"}}};
294 infos,
"--readers", []() {
return 1; }, 1, [](
long long x,
long long y) {
return x >
y ?
x :
y; });
295 REQUIRE(infos[0].cmdLineArgs.size() == 4);
296 REQUIRE(infos[1].cmdLineArgs.size() == 2);
297 REQUIRE(infos[0].cmdLineArgs[3] ==
"3");
298 REQUIRE(infos[1].cmdLineArgs[1] ==
"3");
306 .name =
"processor0",
307 .outputs = {
OutputSpec{{
"output"},
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe}},
310 .name =
"processor1",
311 .inputs = {
InputSpec{
"input",
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe}},
318 .name =
"processor0",
319 .outputs = {
OutputSpec{{
"output"},
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe},
320 OutputSpec{{
"output2"},
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe}},
323 .name =
"processor1",
324 .inputs = {
InputSpec{
"input",
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe}},
331 .name =
"processor0",
332 .outputs = {
OutputSpec{{
"output"},
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe},
333 OutputSpec{{
"output2"},
"TST",
"DUMMYDATA", 2, Lifetime::Sporadic}},
336 .name =
"processor1",
337 .outputs = {
OutputSpec{{
"output"},
"TST",
"DUMMYDATA", 1, Lifetime::Timeframe},
338 OutputSpec{{
"output2"},
"TST",
"DUMMYDATA", 2, Lifetime::Sporadic}},
341 .name =
"processor2",
342 .inputs = {
InputSpec{
"input",
"TST",
"DUMMYDATA", 2, Lifetime::Timeframe}},
349 .name =
"processor0",
350 .outputs = {
OutputSpec{{
"output"},
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe},
351 OutputSpec{{
"output2"},
"TST",
"DUMMYDATA", 2, Lifetime::Sporadic}},
354 .name =
"processor1",
355 .outputs = {
OutputSpec{{
"output"},
"TST",
"DUMMYDATA", 0, Lifetime::Timeframe},
356 OutputSpec{{
"output2"},
"TST",
"DUMMYDATA", 2, Lifetime::Sporadic}},
359 .name =
"processor2",
360 .inputs = {
InputSpec{
"input",
"TST",
"DUMMYDATA", 2, Lifetime::Timeframe}},
369 std::string env =
"FOO={timeslice0}";
371 env =
"FOO={timeslice0} BAR={timeslice4}";
373 env =
"FOO={timeslice0} BAR={timeslice4} BAZ={timeslice5}";
381 env =
"{timeslicepluto";
std::unique_ptr< ConfigContext > makeEmptyConfigContext()
GLuint const GLchar * name
bpo::variables_map arguments
Defining ITS Vertex explicitly as messageable.
void check(const std::vector< std::string > &arguments, const std::vector< ConfigParamSpec > &workflowOptions, const std::vector< DeviceSpec > &deviceSpecs, CheckMatrix &matrix)
TEST_CASE("test_prepareArguments")
bool search(DeviceExecution const &execution, std::string const &option, std::string const &argument)
std::vector< DataProcessorSpec > WorkflowSpec
std::map< std::string, std::vector< std::pair< std::string, std::string > > > CheckMatrix
static std::vector< CallbacksPolicy > createDefaultPolicies()
static std::vector< ChannelConfigurationPolicy > createDefaultPolicies(ConfigContext const &configContext)
Default policies to use, based on the contents of the @configContex content.
static std::vector< CompletionPolicy > createDefaultPolicies()
Helper to create the default configuration.
static ComputingResource getLocalhostResource()
std::string name
Name of the associated DataProcessorSpec.
std::vector< char * > args
The options passed to a given device.
static void validate(WorkflowSpec const &workflow)
static std::string reworkTimeslicePlaceholder(std::string const &str, DeviceSpec const &spec)
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 reworkHomogeneousOption(std::vector< DataProcessorInfo > &infos, char const *name, char const *defaultValue)
static void reworkIntegerOption(std::vector< DataProcessorInfo > &infos, char const *name, std::function< long long()> defaultValueCallback, long long startValue, std::function< long long(long long, long long)> bestValue)
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={})
size_t inputTimesliceId
The time pipelining id of this particular device.