Line data Source code
1 : /**
2 : * @file DAQModuleManager_test.cxx DAQModuleManager class Unit Tests
3 : *
4 : * This is part of the DUNE DAQ Application Framework, copyright 2020.
5 : * Licensing/copyright details are in the COPYING file that you should have
6 : * received with this code.
7 : */
8 :
9 : #include "DAQModuleManager.hpp"
10 :
11 : #include "appfwk/cmd/Nljs.hpp"
12 :
13 : #include "cmdlib/cmd/Nljs.hpp"
14 : #include "iomanager/IOManager.hpp"
15 : #include "opmonlib/TestOpMonManager.hpp"
16 :
17 : #define BOOST_TEST_MODULE DAQModuleManager_test // NOLINT
18 :
19 : #include "boost/test/unit_test.hpp"
20 :
21 : #include <memory>
22 : #include <string>
23 : #include <type_traits>
24 :
25 : BOOST_AUTO_TEST_SUITE(DAQModuleManager_test)
26 :
27 : using namespace dunedaq::appfwk;
28 :
29 : struct EnvFixture
30 : {
31 1 : EnvFixture() { setenv("DUNEDAQ_PARTITION", "DAQModulesManager_test", 0); }
32 : };
33 : BOOST_TEST_GLOBAL_FIXTURE(EnvFixture);
34 :
35 : std::shared_ptr<dunedaq::appfwk::ConfigurationManager>
36 4 : make_config_mgr()
37 : {
38 4 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
39 4 : std::string appName = "TestApp";
40 4 : std::string sessionName = "test-session";
41 8 : return std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
42 4 : }
43 :
44 2 : BOOST_AUTO_TEST_CASE(Construct)
45 : {
46 1 : auto mgr = DAQModuleManager("utest_session");
47 1 : }
48 :
49 2 : BOOST_AUTO_TEST_CASE(Initialized)
50 : {
51 1 : dunedaq::get_iomanager()->reset();
52 1 : auto mgr = DAQModuleManager("utest_session");
53 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
54 :
55 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
56 1 : auto cfgMgr = make_config_mgr();
57 1 : mgr.initialize(cfgMgr, opmgr);
58 :
59 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
60 1 : }
61 :
62 2 : BOOST_AUTO_TEST_CASE(NotInitialized)
63 : {
64 1 : dunedaq::get_iomanager()->reset();
65 1 : auto mgr = DAQModuleManager("utest_session");
66 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
67 :
68 1 : DAQModule::CommandData_t cmd_data;
69 :
70 4 : BOOST_REQUIRE_EXCEPTION(mgr.execute("start", cmd_data),
71 : DAQModuleManagerNotInitialized,
72 : [&](DAQModuleManagerNotInitialized) { return true; });
73 1 : }
74 :
75 2 : BOOST_AUTO_TEST_CASE(InitializeModules)
76 : {
77 1 : dunedaq::get_iomanager()->reset();
78 1 : auto mgr = DAQModuleManager("utest_session");
79 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
80 :
81 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
82 1 : auto cfgMgr = make_config_mgr();
83 1 : mgr.initialize(cfgMgr, opmgr);
84 :
85 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
86 1 : }
87 :
88 1 : BOOST_AUTO_TEST_CASE(NoActionPlan)
89 : {
90 0 : if (dunedaq::appfwk::ACTION_PLANS_REQUIRED) {
91 :
92 : dunedaq::get_iomanager()->reset();
93 : auto mgr = DAQModuleManager("utest_session");
94 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
95 :
96 : dunedaq::opmonlib::TestOpMonManager opmgr;
97 : auto cfgMgr = make_config_mgr();
98 : mgr.initialize(cfgMgr, opmgr);
99 :
100 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
101 : DAQModule::CommandData_t cmd_data;
102 : BOOST_REQUIRE_EXCEPTION(
103 : mgr.execute("unknown_cmd", cmd_data), ActionPlanNotFound, [&](ActionPlanNotFound) { return true; });
104 : }
105 0 : }
106 :
107 2 : BOOST_AUTO_TEST_CASE(InvalidActionPlan_MissingModuleApp)
108 : {
109 1 : dunedaq::get_iomanager()->reset();
110 1 : auto mgr = DAQModuleManager("utest_session");
111 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
112 :
113 1 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
114 1 : std::string appName = "MissingModuleApp";
115 1 : std::string sessionName = "test-session";
116 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
117 1 : auto cfgMgr = std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
118 :
119 : // This succeeds, but prints a message
120 1 : mgr.initialize(cfgMgr, opmgr);
121 :
122 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
123 1 : DAQModule::CommandData_t cmd_data;
124 1 : mgr.execute("stuff", cmd_data);
125 :
126 1 : auto metrics = opmgr.collect();
127 1 : auto facility = opmgr.get_backend_facility();
128 1 : auto entries = facility->get_entries(std::regex("dunedaq.appfwk.opmon.DummyModuleInfo"));
129 1 : BOOST_REQUIRE_EQUAL(entries.size(), 0);
130 1 : }
131 :
132 2 : BOOST_AUTO_TEST_CASE(InvalidActionPlan_MissingMethodApp)
133 : {
134 1 : dunedaq::get_iomanager()->reset();
135 1 : auto mgr = DAQModuleManager("utest_session");
136 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
137 :
138 1 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
139 1 : std::string appName = "MissingMethodApp";
140 1 : std::string sessionName = "test-session";
141 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
142 1 : auto cfgMgr = std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
143 :
144 4 : BOOST_REQUIRE_EXCEPTION(
145 : mgr.initialize(cfgMgr, opmgr), ActionPlanValidationFailed, [&](ActionPlanValidationFailed) { return true; });
146 1 : }
147 :
148 2 : BOOST_AUTO_TEST_CASE(InvalidActionPlan_ConflictingActionPlansApp)
149 : {
150 1 : dunedaq::get_iomanager()->reset();
151 1 : auto mgr = DAQModuleManager("utest_session");
152 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
153 :
154 1 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
155 1 : std::string appName = "ConflictingActionPlansApp";
156 1 : std::string sessionName = "test-session";
157 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
158 1 : auto cfgMgr = std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
159 :
160 4 : BOOST_REQUIRE_EXCEPTION(
161 : mgr.initialize(cfgMgr, opmgr), ActionPlanValidationFailed, [&](ActionPlanValidationFailed) { return true; });
162 1 : }
163 :
164 2 : BOOST_AUTO_TEST_CASE(InvalidActionPlan_MissingModuleApp_GroupById)
165 : {
166 1 : dunedaq::get_iomanager()->reset();
167 1 : auto mgr = DAQModuleManager("utest_session");
168 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
169 :
170 1 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
171 1 : std::string appName = "MissingModuleApp_GroupById";
172 1 : std::string sessionName = "test-session";
173 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
174 1 : auto cfgMgr = std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
175 :
176 4 : BOOST_REQUIRE_EXCEPTION(
177 : mgr.initialize(cfgMgr, opmgr), ActionPlanValidationFailed, [&](ActionPlanValidationFailed) { return true; });
178 1 : }
179 :
180 2 : BOOST_AUTO_TEST_CASE(InvalidActionPlan_MissingModuleApp_Optional)
181 : {
182 1 : dunedaq::get_iomanager()->reset();
183 1 : auto mgr = DAQModuleManager("utest_session");
184 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
185 :
186 1 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
187 1 : std::string appName = "MissingModuleApp_Optional";
188 1 : std::string sessionName = "test-session";
189 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
190 1 : auto cfgMgr = std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
191 :
192 : // This succeeds, and doesn't print a message
193 1 : mgr.initialize(cfgMgr, opmgr);
194 :
195 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
196 1 : DAQModule::CommandData_t cmd_data;
197 1 : mgr.execute("stuff", cmd_data);
198 :
199 1 : auto metrics = opmgr.collect();
200 1 : auto facility = opmgr.get_backend_facility();
201 1 : auto entries = facility->get_entries(std::regex("dunedaq.appfwk.opmon.DummyModuleInfo"));
202 1 : BOOST_REQUIRE_EQUAL(entries.size(), 0);
203 1 : }
204 :
205 2 : BOOST_AUTO_TEST_CASE(InvalidActionPlan_MissingModuleApp_GroupById_Optional)
206 : {
207 1 : dunedaq::get_iomanager()->reset();
208 1 : auto mgr = DAQModuleManager("utest_session");
209 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
210 :
211 1 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
212 1 : std::string appName = "MissingModuleApp_GroupById_Optional";
213 1 : std::string sessionName = "test-session";
214 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
215 1 : auto cfgMgr = std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
216 :
217 : // This succeeds, and doesn't print a message
218 1 : mgr.initialize(cfgMgr, opmgr);
219 :
220 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
221 1 : DAQModule::CommandData_t cmd_data;
222 1 : mgr.execute("stuff", cmd_data);
223 1 : }
224 :
225 2 : BOOST_AUTO_TEST_CASE(InvalidActionPlan_ExtraModuleApp)
226 : {
227 1 : dunedaq::get_iomanager()->reset();
228 1 : auto mgr = DAQModuleManager("utest_session");
229 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
230 :
231 1 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
232 1 : std::string appName = "ExtraModuleApp";
233 1 : std::string sessionName = "test-session";
234 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
235 1 : auto cfgMgr = std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
236 :
237 : // This succeeds, but prints a message
238 1 : mgr.initialize(cfgMgr, opmgr);
239 :
240 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
241 1 : DAQModule::CommandData_t cmd_data;
242 1 : mgr.execute("stuff", cmd_data);
243 :
244 1 : auto metrics = opmgr.collect();
245 1 : auto facility = opmgr.get_backend_facility();
246 1 : auto entries = facility->get_entries(std::regex("dunedaq.appfwk.opmon.DummyModuleInfo"));
247 1 : BOOST_REQUIRE_EQUAL(entries.size(), 3);
248 1 : uint64_t total_stuff_calls = 0; // NOLINT(build/unsigned)
249 4 : for (auto& entry : entries) {
250 3 : total_stuff_calls += entry.data().at("stuff_calls").uint8_value(); // NOLINT(build/unsigned)
251 : }
252 1 : BOOST_REQUIRE_EQUAL(total_stuff_calls, 2); // Only 2 of the three modules in the app actually got the stuff command
253 1 : }
254 :
255 2 : BOOST_AUTO_TEST_CASE(InvalidActionPlan_ExtraModuleApp_GroupById)
256 : {
257 1 : dunedaq::get_iomanager()->reset();
258 1 : auto mgr = DAQModuleManager("utest_session");
259 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
260 :
261 1 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
262 1 : std::string appName = "ExtraModuleApp_GroupById";
263 1 : std::string sessionName = "test-session";
264 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
265 1 : auto cfgMgr = std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
266 :
267 : // This succeeds, but prints a message
268 1 : mgr.initialize(cfgMgr, opmgr);
269 :
270 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
271 1 : DAQModule::CommandData_t cmd_data;
272 1 : mgr.execute("stuff", cmd_data);
273 :
274 1 : auto metrics = opmgr.collect();
275 1 : auto facility = opmgr.get_backend_facility();
276 1 : auto entries = facility->get_entries(std::regex("dunedaq.appfwk.opmon.DummyModuleInfo"));
277 1 : BOOST_REQUIRE_EQUAL(entries.size(), 3);
278 1 : uint64_t total_stuff_calls = 0; // NOLINT(build/unsigned)
279 4 : for (auto& entry : entries) {
280 3 : total_stuff_calls += entry.data().at("stuff_calls").uint8_value(); // NOLINT(build/unsigned)
281 : }
282 1 : BOOST_REQUIRE_EQUAL(total_stuff_calls, 2); // Only 2 of the three modules in the app actually got the stuff command
283 1 : }
284 :
285 2 : BOOST_AUTO_TEST_CASE(CommandModules)
286 : {
287 1 : dunedaq::get_iomanager()->reset();
288 1 : auto mgr = DAQModuleManager("utest_session");
289 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
290 :
291 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
292 1 : auto cfgMgr = make_config_mgr();
293 1 : mgr.initialize(cfgMgr, opmgr);
294 :
295 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
296 1 : DAQModule::CommandData_t cmd_data;
297 1 : mgr.execute("stuff", cmd_data);
298 :
299 4 : BOOST_REQUIRE_EXCEPTION(
300 : mgr.execute("bad_stuff", cmd_data), CommandDispatchingFailed, [&](CommandDispatchingFailed) { return true; });
301 1 : }
302 :
303 2 : BOOST_AUTO_TEST_CASE(CommandModules_ById)
304 : {
305 :
306 1 : dunedaq::get_iomanager()->reset();
307 1 : auto mgr = DAQModuleManager("utest_session");
308 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
309 :
310 1 : std::string oksConfig = "oksconflibs:test/config/appSession.data.xml";
311 1 : std::string appName = "TestApp_ById";
312 1 : std::string sessionName = "test-session";
313 :
314 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
315 1 : auto cfgMgr = std::make_shared<dunedaq::appfwk::ConfigurationManager>(oksConfig, appName, sessionName);
316 1 : mgr.initialize(cfgMgr, opmgr);
317 :
318 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
319 1 : DAQModule::CommandData_t cmd_data;
320 1 : mgr.execute("stuff", cmd_data);
321 :
322 4 : BOOST_REQUIRE_EXCEPTION(
323 : mgr.execute("bad_stuff", cmd_data), CommandDispatchingFailed, [&](CommandDispatchingFailed) { return true; });
324 1 : }
325 :
326 2 : BOOST_AUTO_TEST_CASE(CommandMatchingModules)
327 : {
328 1 : dunedaq::get_iomanager()->reset();
329 1 : auto mgr = DAQModuleManager("utest_session");
330 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), false);
331 :
332 1 : dunedaq::opmonlib::TestOpMonManager opmgr;
333 1 : auto cfgMgr = make_config_mgr();
334 1 : mgr.initialize(cfgMgr, opmgr);
335 :
336 1 : BOOST_REQUIRE_EQUAL(mgr.initialized(), true);
337 :
338 1 : dunedaq::appfwk::cmd::CmdObj cmd_obj;
339 1 : nlohmann::json cmd_obj_data;
340 1 : dunedaq::appfwk::cmd::AddressedCmd addr_cmd;
341 1 : addr_cmd.match = "dummy.*";
342 1 : cmd_obj.modules.push_back(addr_cmd);
343 1 : addr_cmd.match = "foo";
344 1 : cmd_obj.modules.push_back(addr_cmd);
345 1 : to_json(cmd_obj_data, cmd_obj);
346 1 : mgr.execute("stuff", static_cast<DAQModule::CommandData_t>(cmd_obj_data));
347 :
348 1 : addr_cmd.match = ".*module.*";
349 1 : cmd_obj.modules.push_back(addr_cmd);
350 1 : to_json(cmd_obj_data, cmd_obj);
351 5 : BOOST_REQUIRE_EXCEPTION(mgr.execute("bad_stuff", static_cast<DAQModule::CommandData_t>(cmd_obj_data)),
352 : ConflictingCommandMatching,
353 : [&](ConflictingCommandMatching) { return true; });
354 1 : }
355 :
356 : BOOST_AUTO_TEST_SUITE_END()
|