00001 #include "artdaq/ArtModules/detail/SharedMemoryReader.hh"
00002 #include "artdaq/DAQrate/SharedMemoryEventManager.hh"
00003
00004 #include "art/Framework/Core/FileBlock.h"
00005
00006 #include "art/Framework/IO/Sources/SourceHelper.h"
00007 #include "art/Framework/Principal/Event.h"
00008 #include "art/Framework/Principal/EventPrincipal.h"
00009 #include "art/Framework/Principal/Handle.h"
00010 #include "art/Framework/Principal/RunPrincipal.h"
00011 #include "art/Framework/Principal/SubRunPrincipal.h"
00012
00013 #include "art/Persistency/Provenance/BranchIDListRegistry.h"
00014 #include "art/Persistency/Provenance/MasterProductRegistry.h"
00015 #include "art/Persistency/Provenance/ProductMetaData.h"
00016 #include "canvas/Persistency/Provenance/EventID.h"
00017 #include "canvas/Persistency/Provenance/FileFormatVersion.h"
00018 #include "canvas/Persistency/Provenance/ModuleDescription.h"
00019 #include "canvas/Persistency/Provenance/Parentage.h"
00020 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
00021 #include "canvas/Persistency/Provenance/RunID.h"
00022 #include "canvas/Persistency/Provenance/SubRunID.h"
00023 #include "canvas/Persistency/Provenance/Timestamp.h"
00024 #include "canvas/Utilities/Exception.h"
00025 #include "canvas/Utilities/GetPassID.h"
00026 #include "art/Version/GetReleaseVersion.h"
00027 #include "artdaq-core/Data/Fragment.hh"
00028 #include "artdaq-core/Utilities/configureMessageFacility.hh"
00029 #include "fhiclcpp/make_ParameterSet.h"
00030
00031 #define BOOST_TEST_MODULE shared_memory_reader_t
00032 #include <boost/test/auto_unit_test.hpp>
00033
00034 #include <iostream>
00035 #include <memory>
00036 #include <string>
00037
00041 class MPRGlobalTestFixture
00042 {
00043 public:
00047 MPRGlobalTestFixture();
00048
00052 typedef std::map<std::string, art::BranchKey> BKmap_t;
00053
00054 BKmap_t branchKeys_;
00055 std::map<std::string, std::unique_ptr<art::ProcessConfiguration>> processConfigurations_;
00056
00066 art::ProcessConfiguration*
00067 fake_single_module_process(std::string const& tag,
00068 std::string const& processName,
00069 fhicl::ParameterSet const& moduleParams,
00070 std::string const& release = art::getReleaseVersion(),
00071 std::string const& pass = art::getPassID());
00072
00080 std::unique_ptr<art::BranchDescription>
00081 fake_single_process_branch(std::string const& tag,
00082 std::string const& processName,
00083 std::string const& productInstanceName = std::string());
00084
00088 void finalize();
00089
00090 art::MasterProductRegistry productRegistry_;
00091
00092 };
00093
00094 MPRGlobalTestFixture::MPRGlobalTestFixture()
00095 :
00096 branchKeys_()
00097 , processConfigurations_()
00098 , productRegistry_()
00099
00100 {
00101
00102 productRegistry_.addProduct(fake_single_process_branch("hlt", "HLT"));
00103 productRegistry_.addProduct(fake_single_process_branch("prod", "PROD"));
00104 productRegistry_.addProduct(fake_single_process_branch("test", "TEST"));
00105 productRegistry_.addProduct(fake_single_process_branch("user", "USER"));
00106 productRegistry_.addProduct(fake_single_process_branch("rick", "USER2", "rick"));
00107 }
00108
00109 void
00110 MPRGlobalTestFixture::finalize()
00111 {
00112 productRegistry_.setFrozen();
00113 #if ART_HEX_VERSION >= 0x20703
00114 art::BranchIDListRegistry::updateFromProductRegistry(productRegistry_);
00115 #else
00116 art::BranchIDListHelper::updateRegistries(productRegistry_);
00117 #endif
00118 art::ProductMetaData::create_instance(productRegistry_);
00119 }
00120
00121 art::ProcessConfiguration*
00122 MPRGlobalTestFixture::
00123 fake_single_module_process(std::string const& tag,
00124 std::string const& processName,
00125 fhicl::ParameterSet const& moduleParams,
00126 std::string const& release,
00127 std::string const& pass)
00128 {
00129 fhicl::ParameterSet processParams;
00130 processParams.put(processName, moduleParams);
00131 processParams.put<std::string>("process_name",
00132 processName);
00133 auto emplace_pair =
00134 processConfigurations_.emplace(tag,
00135 std::make_unique<art::ProcessConfiguration>(processName, processParams.id(), release, pass));
00136 return emplace_pair.first->second.get();
00137 }
00138
00139 std::unique_ptr<art::BranchDescription>
00140 MPRGlobalTestFixture::
00141 fake_single_process_branch(std::string const& tag,
00142 std::string const& processName,
00143 std::string const& productInstanceName)
00144 {
00145 std::string moduleLabel = processName + "dummyMod";
00146 std::string moduleClass("DummyModule");
00147 fhicl::ParameterSet modParams;
00148 modParams.put<std::string>("module_type", moduleClass);
00149 modParams.put<std::string>("module_label", moduleLabel);
00150 art::ProcessConfiguration* process =
00151 fake_single_module_process(tag, processName, modParams);
00152 art::ModuleDescription mod(modParams.id(),
00153 moduleClass,
00154 moduleLabel,
00155 *process);
00156 art::TypeID dummyType(typeid(int));
00157 art::BranchDescription* result =
00158 new art::BranchDescription(
00159 # if ART_HEX_VERSION >= 0x20703
00160 art::InEvent,
00161 art::TypeLabel(dummyType,
00162 productInstanceName),
00163 # else
00164 art::TypeLabel(art::InEvent,
00165 dummyType,
00166 productInstanceName),
00167 # endif
00168 mod);
00169
00170
00171 branchKeys_.insert(std::make_pair(tag, art::BranchKey(*result)));
00172 return std::unique_ptr<art::BranchDescription>(result);
00173 }
00174
00178 struct ShmRTestFixture
00179 {
00183 ShmRTestFixture()
00184 {
00185 static bool once(true);
00186 if (once)
00187 {
00188 artdaq::configureMessageFacility("shared_memory_reader_t");
00189 (void)reader();
00190 art::ModuleDescription md(fhicl::ParameterSet().id(),
00191 "_NAMEERROR_",
00192 "_LABELERROR_",
00193 *gf().processConfigurations_["daq"]);
00194
00195
00196 helper().registerProducts(gf().productRegistry_, md);
00197 gf().finalize();
00198 once = false;
00199 }
00200 }
00201
00206 MPRGlobalTestFixture& gf()
00207 {
00208 static MPRGlobalTestFixture mpr;
00209 return mpr;
00210 }
00211
00216 art::ProductRegistryHelper& helper()
00217 {
00218 static art::ProductRegistryHelper s_helper;
00219 return s_helper;
00220 }
00221
00226 art::SourceHelper& source_helper()
00227 {
00228 static std::unique_ptr<art::SourceHelper>
00229 s_source_helper;
00230 if (!s_source_helper)
00231 {
00232 fhicl::ParameterSet sourceParams;
00233 std::string moduleType{ "DummySource" };
00234 std::string moduleLabel{ "daq" };
00235 sourceParams.put<std::string>("module_type", moduleType);
00236 sourceParams.put<std::string>("module_label", moduleLabel);
00237 auto pc_ptr = gf().fake_single_module_process(moduleLabel,
00238 "TEST",
00239 sourceParams);
00240 art::ModuleDescription md(sourceParams.id(),
00241 moduleType,
00242 moduleLabel,
00243 *pc_ptr);
00244 s_source_helper = std::make_unique<art::SourceHelper>(md);
00245 }
00246 return *s_source_helper;
00247 }
00248
00253 uint32_t getKey()
00254 {
00255 static uint32_t key = static_cast<uint32_t>(std::hash<std::string>()("shared_memory_reader_t"));
00256 return key;
00257 }
00262 uint32_t getBroadcastKey()
00263 {
00264 static uint32_t key = static_cast<uint32_t>(std::hash<std::string>()("shared_memory_reader_t BROADCAST"));
00265 return key;
00266 }
00267
00272 artdaq::detail::SharedMemoryReader<>& reader()
00273 {
00274 writer();
00275 fhicl::ParameterSet pset;
00276 pset.put("shared_memory_key", getKey());
00277 pset.put("broadcast_shared_memory_key", getBroadcastKey());
00278 pset.put("max_event_size_bytes", 0x100000);
00279 pset.put("buffer_count", 10);
00280 static artdaq::detail::SharedMemoryReader<>
00281 s_reader(pset,
00282 helper(),
00283 source_helper(),
00284 gf().productRegistry_);
00285 static bool reader_initialized = false;
00286 if (!reader_initialized)
00287 {
00288 s_reader.fragment_type_map_[1] = "ABCDEF";
00289 helper().reconstitutes<artdaq::Fragments, art::InEvent>("daq", "ABCDEF");
00290 reader_initialized = true;
00291 }
00292 return s_reader;
00293 }
00294
00299 artdaq::SharedMemoryEventManager& writer()
00300 {
00301 fhicl::ParameterSet pset;
00302 pset.put("shared_memory_key", getKey());
00303 pset.put("broadcast_shared_memory_key", getBroadcastKey());
00304 pset.put("max_event_size_bytes", 0x100000);
00305 pset.put("art_analyzer_count", 0);
00306 pset.put("stale_buffer_timeout_usec", 100000);
00307 pset.put("expected_fragments_per_event", 1);
00308 pset.put("buffer_count", 10);
00309 static artdaq::SharedMemoryEventManager
00310 s_writer(pset,pset);
00311 return s_writer;
00312
00313 }
00314 };
00315
00316 BOOST_FIXTURE_TEST_SUITE(shared_memory_reader_t, ShmRTestFixture)
00317
00318 namespace
00319 {
00328 void basic_test(artdaq::detail::SharedMemoryReader<>& reader,
00329 artdaq::SharedMemoryEventManager& writer,
00330 std::unique_ptr<art::RunPrincipal>&& run,
00331 std::unique_ptr<art::SubRunPrincipal>&& subrun,
00332 art::EventID const& eventid)
00333 {
00334 BOOST_REQUIRE(run || subrun == nullptr);
00335 std::vector<artdaq::Fragment::value_type> fakeData{ 1, 2, 3, 4 };
00336 artdaq::FragmentPtr
00337 tmpFrag(artdaq::Fragment::dataFrag(eventid.event(),
00338 0,
00339 fakeData.begin(),
00340 fakeData.end()));
00341 tmpFrag->setUserType(1);
00342
00343 writer.startRun(eventid.run());
00344
00345
00346 auto iter = tmpFrag->dataBegin();
00347 std::ostringstream str;
00348 str << "{";
00349 while (iter != tmpFrag->dataEnd())
00350 {
00351 str << std::to_string(*iter) << ", ";
00352 ++iter;
00353
00354 }
00355 str << "}";
00356 TLOG_DEBUG("shared_memory_reader_t") <<"Fragment to art: "<< str.str() << TLOG_ENDL;
00357
00358
00359 artdaq::FragmentPtr tempFrag;
00360 auto sts = writer.AddFragment(std::move(tmpFrag), 1000000, tempFrag);
00361 BOOST_REQUIRE_EQUAL(sts,true);
00362
00363 while (writer.GetLockedBufferCount())
00364 {
00365 writer.sendMetrics();
00366 usleep(100000);
00367 }
00368
00369 art::EventPrincipal* newevent = nullptr;
00370 art::SubRunPrincipal* newsubrun = nullptr;
00371 art::RunPrincipal* newrun = nullptr;
00372 bool rc = reader.readNext(run.get(), subrun.get(), newrun, newsubrun, newevent);
00373 BOOST_REQUIRE(rc);
00374 if (run.get() && run->run() == eventid.run())
00375 {
00376 BOOST_CHECK(newrun == nullptr);
00377 }
00378 else
00379 {
00380 BOOST_CHECK(newrun);
00381 BOOST_CHECK(newrun->id() == eventid.runID());
00382 }
00383 if (!newrun && subrun.get() && subrun->subRun() == eventid.subRun())
00384 {
00385 BOOST_CHECK(newsubrun == nullptr);
00386 }
00387 else
00388 {
00389 BOOST_CHECK(newsubrun);
00390 BOOST_CHECK(newsubrun->id() == eventid.subRunID());
00391 }
00392 BOOST_CHECK(newevent);
00393 BOOST_CHECK(newevent->id() == eventid);
00394 art::Event e(*newevent, art::ModuleDescription());
00395 art::Handle<std::vector<artdaq::Fragment>> h;
00396 e.getByLabel("daq", "ABCDEF", h);
00397 BOOST_CHECK(h.isValid());
00398 BOOST_CHECK(h->size() == 1);
00399
00400 auto iter2 = h->front().dataBegin();
00401 std::ostringstream str2;
00402 str2 << "{";
00403 while(iter2 != h->front().dataEnd())
00404 {
00405 str2 << std::to_string(*iter2) << ", ";
00406 ++iter2;
00407
00408 }
00409 str2 << "}";
00410 TLOG_DEBUG("shared_memory_reader_t") << "Fragment from art: " << str2.str() << TLOG_ENDL;
00411
00412 BOOST_CHECK(std::equal(fakeData.begin(),
00413 fakeData.end(),
00414 h->front().dataBegin()));
00415 delete(newrun);
00416 delete(newsubrun);
00417 delete(newevent);
00418 }
00419 }
00420
00421 BOOST_AUTO_TEST_CASE(nonempty_event)
00422 {
00423 art::EventID eventid(2112, 1, 3);
00424 art::Timestamp now;
00425 basic_test(reader(),writer(),
00426 std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run(), now)),
00427 std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run(), eventid.subRun(), now)),
00428 eventid);
00429 }
00430
00431 BOOST_AUTO_TEST_CASE(first_event)
00432 {
00433 art::EventID eventid(2112, 1, 3);
00434 art::Timestamp now;
00435 basic_test(reader(), writer(),
00436 nullptr,
00437 nullptr,
00438 eventid);
00439 }
00440
00441 BOOST_AUTO_TEST_CASE(new_subrun)
00442 {
00443 art::EventID eventid(2112, 1, 3);
00444 art::Timestamp now;
00445 basic_test(reader(), writer(),
00446 std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run(), now)),
00447 std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run(), 0, now)),
00448 eventid);
00449 }
00450
00451 BOOST_AUTO_TEST_CASE(new_run)
00452 {
00453 art::EventID eventid(2112, 1, 3);
00454 art::Timestamp now;
00455 basic_test(reader(), writer(),
00456 std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run() - 1, now)),
00457 std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run() - 1,
00458 eventid.subRun(),
00459 now)),
00460 eventid);
00461 }
00462
00463 BOOST_AUTO_TEST_CASE(end_of_data)
00464 {
00465
00466
00467
00468 std::string const fakeFileName("no such file exists");
00469 art::FileBlock* pFile = nullptr;
00470 reader().readFile(fakeFileName, pFile);
00471 BOOST_CHECK(pFile);
00472 BOOST_CHECK(pFile->fileFormatVersion() == art::FileFormatVersion(1, "RawEvent2011"));
00473 BOOST_CHECK(pFile->tree() == nullptr);
00474
00475 BOOST_CHECK(!pFile->fastClonable());
00476
00477
00478
00479 art::RunID runid(2112);
00480 art::SubRunID subrunid(2112, 1);
00481 art::EventID eventid(2112, 1, 3);
00482 art::Timestamp now;
00483 std::unique_ptr<art::RunPrincipal> run(source_helper().makeRunPrincipal(runid.run(), now));
00484 std::unique_ptr<art::SubRunPrincipal> subrun(source_helper().makeSubRunPrincipal(runid.run(), subrunid.subRun(), now));
00485 std::unique_ptr<art::EventPrincipal> event(source_helper().makeEventPrincipal(runid.run(),
00486 subrunid.subRun(),
00487 eventid.event(),
00488 now));
00489 writer().endOfData();
00490 art::EventPrincipal* newevent = nullptr;
00491 art::SubRunPrincipal* newsubrun = nullptr;
00492 art::RunPrincipal* newrun = nullptr;
00493 bool rc = reader().readNext(run.get(), subrun.get(), newrun, newsubrun, newevent);
00494 BOOST_CHECK(!rc);
00495 BOOST_CHECK(newrun == nullptr);
00496 BOOST_CHECK(newsubrun == nullptr);
00497 BOOST_CHECK(newevent == nullptr);
00498 }
00499
00500 BOOST_AUTO_TEST_SUITE_END()