Skip to content

Commit c387e05

Browse files
authored
[QC-437] Make optional all the categories in QC config file (#502)
1 parent 60f2d3c commit c387e05

4 files changed

Lines changed: 74 additions & 42 deletions

File tree

Framework/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ install(PROGRAMS script/RepoCleaner/1_per_hour.py script/RepoCleaner/Ccdb.py scr
401401

402402
set(TEST_FILES
403403
"testSharedConfig.json"
404+
"testEmptyConfig.json"
404405
"testCheckWorkflow.json"
405406
"testTrendingTask.json"
406407
"testWorkflow.json")

Framework/src/InfrastructureGenerator.cxx

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ framework::WorkflowSpec InfrastructureGenerator::generateStandaloneInfrastructur
5151
printVersion();
5252

5353
TaskRunnerFactory taskRunnerFactory;
54-
for (const auto& [taskName, taskConfig] : config->getRecursive("qc.tasks")) {
55-
if (taskConfig.get<bool>("active", true)) {
56-
workflow.emplace_back(taskRunnerFactory.create(taskName, configurationSource, 0));
54+
if (config->getRecursive("qc").count("tasks")) {
55+
for (const auto& [taskName, taskConfig] : config->getRecursive("qc.tasks")) {
56+
if (taskConfig.get<bool>("active", true)) {
57+
workflow.emplace_back(taskRunnerFactory.create(taskName, configurationSource, 0));
58+
}
5759
}
5860
}
59-
6061
generateCheckRunners(workflow, configurationSource);
6162

6263
return workflow;
@@ -76,6 +77,10 @@ WorkflowSpec InfrastructureGenerator::generateLocalInfrastructure(std::string co
7677
auto config = ConfigurationFactory::getConfiguration(configurationSource);
7778
printVersion();
7879

80+
if (config->getRecursive("qc").count("tasks") == 0) {
81+
return workflow;
82+
}
83+
7984
for (const auto& [taskName, taskConfig] : config->getRecursive("qc.tasks")) {
8085
if (taskConfig.get<bool>("active")) {
8186
if (taskConfig.get<std::string>("location") == "local") {
@@ -143,48 +148,50 @@ o2::framework::WorkflowSpec InfrastructureGenerator::generateRemoteInfrastructur
143148
auto config = ConfigurationFactory::getConfiguration(configurationSource);
144149
printVersion();
145150

146-
TaskRunnerFactory taskRunnerFactory;
147-
for (const auto& [taskName, taskConfig] : config->getRecursive("qc.tasks")) {
148-
if (taskConfig.get<bool>("active", true)) {
151+
if (config->getRecursive("qc").count("tasks")) {
152+
TaskRunnerFactory taskRunnerFactory;
153+
for (const auto& [taskName, taskConfig] : config->getRecursive("qc.tasks")) {
154+
if (taskConfig.get<bool>("active", true)) {
149155

150-
if (taskConfig.get<std::string>("location") == "local") {
151-
// if tasks are LOCAL, generate input proxies + mergers + checkers
156+
if (taskConfig.get<std::string>("location") == "local") {
157+
// if tasks are LOCAL, generate input proxies + mergers + checkers
152158

153-
size_t numberOfLocalMachines = taskConfig.get_child("localMachines").size() > 1 ? taskConfig.get_child("localMachines").size() : 1;
159+
size_t numberOfLocalMachines = taskConfig.get_child("localMachines").size() > 1 ? taskConfig.get_child("localMachines").size() : 1;
154160

155-
// Generate an input proxy
156-
// These should be removed when we are able to declare dangling inputs in normal DPL devices
157-
generateLocalTaskRemoteProxy(workflow, taskName, numberOfLocalMachines, taskConfig.get<std::string>("remotePort"));
161+
// Generate an input proxy
162+
// These should be removed when we are able to declare dangling inputs in normal DPL devices
163+
generateLocalTaskRemoteProxy(workflow, taskName, numberOfLocalMachines, taskConfig.get<std::string>("remotePort"));
158164

159-
// Generate a Merger only when there is a need to merge something - there is more than one machine with the QC Task
160-
// I don't expect the list of machines to be reconfigured - all of them should be declared beforehand,
161-
// even if some of them will be on standby.
162-
if (numberOfLocalMachines > 1) {
163-
generateMergers(workflow, taskName, numberOfLocalMachines, taskConfig.get<double>("cycleDurationSeconds"));
164-
}
165+
// Generate a Merger only when there is a need to merge something - there is more than one machine with the QC Task
166+
// I don't expect the list of machines to be reconfigured - all of them should be declared beforehand,
167+
// even if some of them will be on standby.
168+
if (numberOfLocalMachines > 1) {
169+
generateMergers(workflow, taskName, numberOfLocalMachines, taskConfig.get<double>("cycleDurationSeconds"));
170+
}
165171

166-
} else if (taskConfig.get<std::string>("location") == "remote") {
172+
} else if (taskConfig.get<std::string>("location") == "remote") {
167173

168-
// -- if tasks are REMOTE, generate dispatcher proxies + tasks + checkers
169-
// (for the time being we don't foresee parallel tasks on QC servers, so no mergers here)
174+
// -- if tasks are REMOTE, generate dispatcher proxies + tasks + checkers
175+
// (for the time being we don't foresee parallel tasks on QC servers, so no mergers here)
170176

171-
// fixme: ideally we should check if we are on the right remote machine, but now we support only n -> 1 setups,
172-
// so there is no point. Also, I expect that we should be able to generate one big topology or its parts
173-
// and we would place it among QC servers using AliECS, not by configuration files.
177+
// fixme: ideally we should check if we are on the right remote machine, but now we support only n -> 1 setups,
178+
// so there is no point. Also, I expect that we should be able to generate one big topology or its parts
179+
// and we would place it among QC servers using AliECS, not by configuration files.
174180

175-
// Collecting Data Sampling Policies
176-
auto dataSourceTree = taskConfig.get_child("dataSource");
177-
std::string type = dataSourceTree.get<std::string>("type");
178-
if (type == "dataSamplingPolicy") {
179-
samplingPoliciesUsed.insert(dataSourceTree.get<std::string>("name"));
180-
} else if (type == "direct") {
181-
throw std::runtime_error("Configuration error: Remote QC tasks such as " + taskName + " cannot use direct data sources");
182-
} else {
183-
throw std::runtime_error("Configuration error: dataSource type unknown : " + type);
184-
}
181+
// Collecting Data Sampling Policies
182+
auto dataSourceTree = taskConfig.get_child("dataSource");
183+
std::string type = dataSourceTree.get<std::string>("type");
184+
if (type == "dataSamplingPolicy") {
185+
samplingPoliciesUsed.insert(dataSourceTree.get<std::string>("name"));
186+
} else if (type == "direct") {
187+
throw std::runtime_error("Configuration error: Remote QC tasks such as " + taskName + " cannot use direct data sources");
188+
} else {
189+
throw std::runtime_error("Configuration error: dataSource type unknown : " + type);
190+
}
185191

186-
// Creating the remote task
187-
workflow.emplace_back(taskRunnerFactory.create(taskName, configurationSource, 0));
192+
// Creating the remote task
193+
workflow.emplace_back(taskRunnerFactory.create(taskName, configurationSource, 0));
194+
}
188195
}
189196
}
190197
}
@@ -347,11 +354,12 @@ void InfrastructureGenerator::generateCheckRunners(framework::WorkflowSpec& work
347354

348355
auto config = ConfigurationFactory::getConfiguration(configurationSource);
349356

350-
// Build tasksOutputMap based on active tasks in the config
351-
for (const auto& [taskName, taskConfig] : config->getRecursive("qc.tasks")) {
352-
if (taskConfig.get<bool>("active", true)) {
353-
InputSpec taskOutput{ taskName, TaskRunner::createTaskDataOrigin(), TaskRunner::createTaskDataDescription(taskName) };
354-
tasksOutputMap.insert({ DataSpecUtils::label(taskOutput), taskOutput });
357+
if (config->getRecursive("qc").count("tasks")) {
358+
for (const auto& [taskName, taskConfig] : config->getRecursive("qc.tasks")) {
359+
if (taskConfig.get<bool>("active", true)) {
360+
InputSpec taskOutput{ taskName, TaskRunner::createTaskDataOrigin(), TaskRunner::createTaskDataDescription(taskName) };
361+
tasksOutputMap.insert({ DataSpecUtils::label(taskOutput), taskOutput });
362+
}
355363
}
356364
}
357365

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"qc": {}
3+
}

Framework/test/testInfrastructureGenerator.cxx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,24 @@ BOOST_AUTO_TEST_CASE(qc_factory_standalone_test)
187187
d.inputs.size() == 1;
188188
});
189189
BOOST_REQUIRE_EQUAL(checkRunnerCount, 3);
190+
}
191+
192+
BOOST_AUTO_TEST_CASE(qc_factory_empty_config)
193+
{
194+
std::string configFilePath = std::string("json://") + getTestDataDirectory() + "testEmptyConfig.json";
195+
{
196+
WorkflowSpec workflow;
197+
BOOST_REQUIRE_NO_THROW(InfrastructureGenerator::generateStandaloneInfrastructure(workflow, configFilePath));
198+
BOOST_CHECK_EQUAL(workflow.size(), 0);
199+
}
200+
{
201+
WorkflowSpec workflow;
202+
BOOST_REQUIRE_NO_THROW(InfrastructureGenerator::generateLocalInfrastructure(workflow, configFilePath, "asdf"));
203+
BOOST_CHECK_EQUAL(workflow.size(), 0);
204+
}
205+
{
206+
WorkflowSpec workflow;
207+
BOOST_REQUIRE_NO_THROW(InfrastructureGenerator::generateRemoteInfrastructure(workflow, configFilePath));
208+
BOOST_CHECK_EQUAL(workflow.size(), 0);
209+
}
190210
}

0 commit comments

Comments
 (0)