Project
Loading...
Searching...
No Matches
testITSCAConfigPreflight.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
12// Driver configuration validation before constructing any DPL device.
13
14#define BOOST_TEST_MODULE ITSMFT ITSCAConfigPreflight
15#define BOOST_TEST_MAIN
16#define BOOST_TEST_DYN_LINK
17#include <boost/test/unit_test.hpp>
18
19#include <array>
20#include <stdexcept>
21
22#include <boost/property_tree/ptree.hpp>
23#include <fairlogger/Logger.h>
24
33
34using namespace o2::its::ca;
35
36namespace
37{
38struct FatalToExceptionFixture {
39 FatalToExceptionFixture()
40 {
41 fair::Logger::OnFatal([]() { throw std::runtime_error("fatal"); });
42 }
43};
44} // namespace
45
46// --- applyConfigKeyValuesOrFatal(): preflight runs before the update -------
47
48BOOST_FIXTURE_TEST_CASE(LegacyNamespaceIsRejectedBeforeAnyUpdate, FatalToExceptionFixture)
49{
50 // Sentinel: if the rejection did not actually run before
51 // ConfigurableParam::updateFromString(), this legacy-namespace string
52 // would still throw from updateFromString() itself (unknown param), so
53 // this alone would not distinguish "preflight fired first" from "update
54 // itself fatal'd" -- the meaningful assertion is in the next test, which
55 // confirms the dedicated param was NOT mutated by the rejected string.
56 BOOST_CHECK_THROW(applyConfigKeyValuesOrFatal("ITSCATrackerParam.trackFollowerTop=1"), std::runtime_error);
57}
58
59BOOST_FIXTURE_TEST_CASE(RejectedStringNeverReachesConfigurableParamUpdate, FatalToExceptionFixture)
60{
61 // A malicious/confused string mixing a real dedicated-namespace override
62 // with an offending legacy one must not have its dedicated part applied
63 // either -- the whole string is rejected pre-update, atomically.
64 o2::conf::ConfigurableParam::setValue<bool>("ITSCommonCATrackerParam", "useDiamond", false);
65 BOOST_CHECK_THROW(
66 applyConfigKeyValuesOrFatal("ITSCommonCATrackerParam.useDiamond=true;ITSCATrackerParam.trackFollowerTop=1"),
67 std::runtime_error);
69}
70
71BOOST_FIXTURE_TEST_CASE(DedicatedNamespaceIsAcceptedAndApplied, FatalToExceptionFixture)
72{
73 o2::conf::ConfigurableParam::setValue<bool>("ITSCommonCATrackerParam", "useDiamond", false);
74 BOOST_CHECK_NO_THROW(applyConfigKeyValuesOrFatal("ITSCommonCATrackerParam.useDiamond=true"));
76 o2::conf::ConfigurableParam::setValue<bool>("ITSCommonCATrackerParam", "useDiamond", false);
77}
78
79BOOST_FIXTURE_TEST_CASE(EmptyStringIsAcceptedAndApplied, FatalToExceptionFixture)
80{
82}
83
84BOOST_FIXTURE_TEST_CASE(LegacyNamespaceWithoutFieldIsRejected, FatalToExceptionFixture)
85{
86 BOOST_CHECK_THROW(applyConfigKeyValuesOrFatal("ITSCATrackerParam=1"), std::runtime_error);
87}
88
89BOOST_FIXTURE_TEST_CASE(MixedInputRejectsLegacyNamespaceInEitherPosition, FatalToExceptionFixture)
90{
91 for (const auto* config : {"ITSCATrackerParam.trackFollowerTop=1;ITSCommonCATrackerParam.useDiamond=true",
92 "ITSCommonCATrackerParam.useDiamond=true;ITSCATrackerParam.trackFollowerTop=1"}) {
93 o2::conf::ConfigurableParam::setValue<bool>("ITSCommonCATrackerParam", "useDiamond", false);
94 BOOST_CHECK_THROW(applyConfigKeyValuesOrFatal(config), std::runtime_error);
96 }
97}
98
99BOOST_FIXTURE_TEST_CASE(OuterWhitespaceAndInternalKeyWhitespaceKeepNamespace, FatalToExceptionFixture)
100{
101 o2::conf::ConfigurableParam::setValue<bool>("ITSCommonCATrackerParam", "useDiamond", false);
102 BOOST_CHECK_THROW(
103 applyConfigKeyValuesOrFatal(" ITSCommonCATrackerParam.useDiamond=true ; ITSCATrackerParam.trackFollowerTop=1 "),
104 std::runtime_error);
106
107 BOOST_CHECK_THROW(applyConfigKeyValuesOrFatal("ITSCATrackerParam.trackFollowerTop = 1"), std::runtime_error);
108}
109
110BOOST_FIXTURE_TEST_CASE(EmptyEntriesAndUnrelatedNamespacesAreAccepted, FatalToExceptionFixture)
111{
112 o2::conf::ConfigurableParam::setValue<bool>("ITSCommonCATrackerParam", "dropTFUponFailure", false);
113 o2::conf::ConfigurableParam::setValue<int>("ITSVertexerParam", "nIterations", 1);
115 ";;ITSCommonCATrackerParam.dropTFUponFailure=true;;;ITSVertexerParam.nIterations=2;;"));
118 o2::conf::ConfigurableParam::setValue<bool>("ITSCommonCATrackerParam", "dropTFUponFailure", false);
119 o2::conf::ConfigurableParam::setValue<int>("ITSVertexerParam", "nIterations", 1);
120}
121
122BOOST_FIXTURE_TEST_CASE(MalformedTokensRemainConfiguratorErrors, FatalToExceptionFixture)
123{
124 for (const auto* config : {"ITSCATrackerParamNoEquals", "=ITSCATrackerParam.x", "ITSCATrackerParam.x="}) {
125 BOOST_CHECK_THROW(applyConfigKeyValuesOrFatal(config), std::runtime_error);
126 }
127}
128
129BOOST_FIXTURE_TEST_CASE(RepeatedAcceptedAndRejectedCallsRemainDeterministic, FatalToExceptionFixture)
130{
131 for (int i = 0; i < 5; ++i) {
132 o2::conf::ConfigurableParam::setValue<bool>("ITSCommonCATrackerParam", "useDiamond", false);
133 BOOST_CHECK_THROW(applyConfigKeyValuesOrFatal("ITSCATrackerParam.trackFollowerTop=1"), std::runtime_error);
134 BOOST_CHECK_NO_THROW(applyConfigKeyValuesOrFatal("ITSCommonCATrackerParam.useDiamond=true"));
136 }
137 o2::conf::ConfigurableParam::setValue<bool>("ITSCommonCATrackerParam", "useDiamond", false);
138}
139
140// --- requireSupportedTrackingModeOrFatal(): Sync and Async are accepted ---
141
147
148BOOST_FIXTURE_TEST_CASE(UnsupportedModesFailClosed, FatalToExceptionFixture)
149{
150 const std::array<o2::itsmft::TrackingMode::Type, 3> rejected{
152 for (const auto mode : rejected) {
153 BOOST_CHECK_THROW(requireSupportedTrackingModeOrFatal(mode), std::runtime_error);
154 }
155}
156
157BOOST_AUTO_TEST_CASE(VertexSelectionIsExplicitAndLegacyAliasesMustAgree)
158{
159 BOOST_CHECK_THROW(resolveVertexSource("", false, false), std::invalid_argument);
160 BOOST_CHECK_THROW(resolveVertexSource("", true, true), std::invalid_argument);
161 BOOST_CHECK_THROW(resolveVertexSource("truth", true, false), std::invalid_argument);
162 BOOST_CHECK_THROW(resolveVertexSource("diamond", false, true), std::invalid_argument);
163 BOOST_CHECK_THROW(resolveVertexSource("unknown", false, false), std::invalid_argument);
164 BOOST_CHECK(resolveVertexSource("", true, false) == VertexSource::Diamond);
165 BOOST_CHECK(resolveVertexSource("", false, true) == VertexSource::Truth);
166 BOOST_CHECK(resolveVertexSource("diamond", false, false) == VertexSource::Diamond);
167 BOOST_CHECK(resolveVertexSource("truth", false, false) == VertexSource::Truth);
168 BOOST_CHECK(resolveVertexSource("diamond", true, false) == VertexSource::Diamond);
169 BOOST_CHECK(resolveVertexSource("truth", false, true) == VertexSource::Truth);
170}
171
172BOOST_AUTO_TEST_CASE(DriverResolvesTruthContextIndependentlyOfMCLabels)
173{
174 using namespace o2::framework;
175 std::vector<ConfigParamSpec> specs{
176 {"configKeyValues", VariantType::String, "ITSCommonCATrackerParam.useDiamond=false;ITSVertexerParam.useTruthSeeding=false", {"parameters"}},
177 {"tracking-mode", VariantType::String, "async", {"mode"}},
178 {"vertex-source", VariantType::String, "truth", {"vertices"}},
179 {"truth-context", VariantType::String, "custom-context.root", {"context"}},
180 {"disable-mc", VariantType::Bool, true, {"MC labels"}},
181 {"disable-root-output", VariantType::Bool, false, {"output"}},
182 {"use-geom", VariantType::Bool, false, {"geometry"}},
183 {"use-full-geometry", VariantType::Bool, true, {"geometry alias"}}};
184 auto store = std::make_unique<ConfigParamStore>(specs, std::vector<std::unique_ptr<ParamRetriever>>{});
185 store->preload();
186 store->activate();
187 ConfigParamRegistry registry{std::move(store)};
188 ServiceRegistry services;
189 ConfigContext context{registry, ServiceRegistryRef{services}, 0, nullptr};
190 registry.override("configKeyValues", std::string{"ITSCommonCATrackerParam.trackingMode=0"});
192 registry.override("configKeyValues", std::string{"ITSCommonCATrackerParam.trackingMode=-1"});
193 const auto resolved = readWorkflowOptions(context);
195 BOOST_CHECK(resolved.vertexSource == VertexSource::Truth);
196 BOOST_CHECK(!resolved.useMC);
197 BOOST_CHECK(resolved.useFullGeometry);
198 BOOST_CHECK_EQUAL(resolved.truthContext, "custom-context.root");
199 registry.override("truth-context", std::string{});
200 BOOST_CHECK_THROW(readWorkflowOptions(context), std::invalid_argument);
201 registry.override("vertex-source", std::string{"diamond"});
202 BOOST_CHECK(readWorkflowOptions(context).vertexSource == VertexSource::Diamond);
203 registry.override("configKeyValues", std::string{"ITSCommonCATrackerParam.nThreads=0"});
204 BOOST_CHECK_THROW(readWorkflowOptions(context), std::invalid_argument);
205 o2::conf::ConfigurableParam::setValue<int>("ITSCommonCATrackerParam", "nThreads", 1);
206}
Driver-level configuration and vertex-constraint preflight for the ITS common-CA tracker workflow.
int32_t i
GLenum mode
Definition glcorearb.h:266
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
WorkflowOptions readWorkflowOptions(const o2::framework::ConfigContext &)
void requireSupportedTrackingModeOrFatal(o2::itsmft::TrackingMode::Type mode)
void applyConfigKeyValuesOrFatal(const std::string &configKeyValues)
VertexSource resolveVertexSource(const std::string &explicitSource, bool useDiamond, bool useTruth)
BOOST_AUTO_TEST_CASE(VertexSelectionIsExplicitAndLegacyAliasesMustAgree)
BOOST_FIXTURE_TEST_CASE(LegacyNamespaceIsRejectedBeforeAnyUpdate, FatalToExceptionFixture)
BOOST_CHECK_NO_THROW(algorithm::merge(target, other))
BOOST_CHECK(tree)
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())