$treeview $search $mathjax $extrastylesheet
artdaq
v3_04_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #define TRACE_NAME "shared_memory_reader_t" 00002 00003 #include "artdaq/ArtModules/detail/SharedMemoryReader.hh" 00004 #include "artdaq/DAQrate/SharedMemoryEventManager.hh" 00005 00006 #include "art/Framework/Core/FileBlock.h" 00007 //#include "art/Framework/Core/RootDictionaryManager.h" 00008 #include "art/Framework/IO/Sources/SourceHelper.h" 00009 #include "art/Framework/Principal/Event.h" 00010 #include "art/Framework/Principal/EventPrincipal.h" 00011 #include "art/Framework/Principal/Handle.h" 00012 #include "art/Framework/Principal/RunPrincipal.h" 00013 #include "art/Framework/Principal/SubRunPrincipal.h" 00014 //#include "art/Persistency/Provenance/BranchIDListHelper.h" 00015 #include "art/Persistency/Provenance/MasterProductRegistry.h" 00016 #include "art/Persistency/Provenance/ProductMetaData.h" 00017 #include "canvas/Persistency/Provenance/EventID.h" 00018 #include "canvas/Persistency/Provenance/FileFormatVersion.h" 00019 #include "canvas/Persistency/Provenance/ModuleDescription.h" 00020 #include "canvas/Persistency/Provenance/Parentage.h" 00021 #include "canvas/Persistency/Provenance/ProcessConfiguration.h" 00022 #include "canvas/Persistency/Provenance/RunID.h" 00023 #include "canvas/Persistency/Provenance/SubRunID.h" 00024 #include "canvas/Persistency/Provenance/Timestamp.h" 00025 #include "canvas/Utilities/Exception.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 ); 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 //art::RootDictionaryManager rdm_; 00092 }; 00093 00094 MPRGlobalTestFixture::MPRGlobalTestFixture() 00095 : 00096 branchKeys_() 00097 , processConfigurations_() 00098 , productRegistry_()//, 00099 // rdm_() 00100 { 00101 // We can only insert products registered in the MasterProductRegistry. 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 art::ProductMetaData::create_instance(productRegistry_); 00114 } 00115 00116 art::ProcessConfiguration* 00117 MPRGlobalTestFixture:: 00118 fake_single_module_process(std::string const& tag, 00119 std::string const& processName, 00120 fhicl::ParameterSet const& moduleParams, 00121 std::string const& release 00122 ) 00123 { 00124 fhicl::ParameterSet processParams; 00125 processParams.put(processName, moduleParams); 00126 processParams.put<std::string>("process_name", 00127 processName); 00128 auto emplace_pair = 00129 processConfigurations_.emplace(tag, 00130 std::make_unique<art::ProcessConfiguration>(processName, processParams.id(), release, pass)); 00131 return emplace_pair.first->second.get(); 00132 } 00133 00134 std::unique_ptr<art::BranchDescription> 00135 MPRGlobalTestFixture:: 00136 fake_single_process_branch(std::string const& tag, 00137 std::string const& processName, 00138 std::string const& productInstanceName) 00139 { 00140 std::string moduleLabel = processName + "dummyMod"; 00141 std::string moduleClass("DummyModule"); 00142 fhicl::ParameterSet modParams; 00143 modParams.put<std::string>("module_type", moduleClass); 00144 modParams.put<std::string>("module_label", moduleLabel); 00145 art::ProcessConfiguration* process = 00146 fake_single_module_process(tag, processName, modParams); 00147 art::ModuleDescription mod(modParams.id(), 00148 moduleClass, 00149 moduleLabel, 00150 *process); 00151 art::TypeID dummyType(typeid(int)); 00152 art::BranchDescription* result = 00153 new art::BranchDescription( 00154 art::InEvent, 00155 art::TypeLabel(dummyType, 00156 productInstanceName), 00157 mod); 00158 00159 00160 branchKeys_.insert(std::make_pair(tag, art::BranchKey(*result))); 00161 return std::unique_ptr<art::BranchDescription>(result); 00162 } 00163 00167 struct ShmRTestFixture 00168 { 00172 ShmRTestFixture() 00173 { 00174 static bool once(true); 00175 if (once) 00176 { 00177 artdaq::configureMessageFacility("shared_memory_reader_t"); 00178 (void)reader(); // Force initialization. 00179 art::ModuleDescription md(fhicl::ParameterSet().id(), 00180 "_NAMEERROR_", 00181 "_LABELERROR_", 00182 *gf().processConfigurations_["daq"]); 00183 // These _xERROR_ strings should never appear in branch names; they 00184 // are here as tracers to help identify any failures in coding. 00185 helper().registerProducts(gf().productRegistry_, md); 00186 gf().finalize(); 00187 once = false; 00188 } 00189 } 00190 00195 MPRGlobalTestFixture& gf() 00196 { 00197 static MPRGlobalTestFixture mpr; 00198 return mpr; 00199 } 00200 00205 art::ProductRegistryHelper& helper() 00206 { 00207 static art::ProductRegistryHelper s_helper; 00208 return s_helper; 00209 } 00210 00215 art::SourceHelper& source_helper() 00216 { 00217 static std::unique_ptr<art::SourceHelper> 00218 s_source_helper; 00219 if (!s_source_helper) 00220 { 00221 fhicl::ParameterSet sourceParams; 00222 std::string moduleType{ "DummySource" }; 00223 std::string moduleLabel{ "daq" }; 00224 sourceParams.put<std::string>("module_type", moduleType); 00225 sourceParams.put<std::string>("module_label", moduleLabel); 00226 auto pc_ptr = gf().fake_single_module_process(moduleLabel, 00227 "TEST", 00228 sourceParams); 00229 art::ModuleDescription md(sourceParams.id(), 00230 moduleType, 00231 moduleLabel, 00232 *pc_ptr); 00233 s_source_helper = std::make_unique<art::SourceHelper>(md); 00234 } 00235 return *s_source_helper; 00236 } 00237 00242 uint32_t getKey() 00243 { 00244 static uint32_t key = static_cast<uint32_t>(std::hash<std::string>()("shared_memory_reader_t")); 00245 return key; 00246 } 00251 uint32_t getBroadcastKey() 00252 { 00253 static uint32_t key = static_cast<uint32_t>(std::hash<std::string>()("shared_memory_reader_t BROADCAST")); 00254 return key; 00255 } 00256 00261 artdaq::detail::SharedMemoryReader<>& reader() 00262 { 00263 writer(); 00264 fhicl::ParameterSet pset; 00265 pset.put("shared_memory_key", getKey()); 00266 pset.put("broadcast_shared_memory_key", getBroadcastKey()); 00267 pset.put("max_event_size_bytes", 0x100000); 00268 pset.put("buffer_count", 10); 00269 static artdaq::detail::SharedMemoryReader<> 00270 s_reader(pset, 00271 helper(), 00272 source_helper(), 00273 gf().productRegistry_); 00274 static bool reader_initialized = false; 00275 if (!reader_initialized) 00276 { 00277 s_reader.fragment_type_map_[1] = "ABCDEF"; 00278 helper().reconstitutes<artdaq::Fragments, art::InEvent>("daq", "ABCDEF"); 00279 reader_initialized = true; 00280 } 00281 return s_reader; 00282 } 00283 00288 artdaq::SharedMemoryEventManager& writer() 00289 { 00290 fhicl::ParameterSet pset; 00291 pset.put("shared_memory_key", getKey()); 00292 pset.put("broadcast_shared_memory_key", getBroadcastKey()); 00293 pset.put("max_event_size_bytes", 0x100000); 00294 pset.put("art_analyzer_count", 0); 00295 pset.put("stale_buffer_timeout_usec", 100000); 00296 pset.put("expected_fragments_per_event", 1); 00297 pset.put("buffer_count", 10); 00298 static artdaq::SharedMemoryEventManager 00299 s_writer(pset, pset); 00300 return s_writer; 00301 00302 } 00303 }; 00304 00305 BOOST_FIXTURE_TEST_SUITE(shared_memory_reader_t, ShmRTestFixture) 00306 00307 namespace 00308 { 00317 void basic_test(artdaq::detail::SharedMemoryReader<>& reader, 00318 artdaq::SharedMemoryEventManager& writer, 00319 std::unique_ptr<art::RunPrincipal>&& run, 00320 std::unique_ptr<art::SubRunPrincipal>&& subrun, 00321 art::EventID const& eventid) 00322 { 00323 BOOST_REQUIRE(run || subrun == nullptr); // Sanity check. 00324 std::vector<artdaq::Fragment::value_type> fakeData{ 1, 2, 3, 4 }; 00325 artdaq::FragmentPtr 00326 tmpFrag(artdaq::Fragment::dataFrag(eventid.event(), 00327 0, 00328 fakeData.begin(), 00329 fakeData.end())); 00330 tmpFrag->setUserType(1); 00331 00332 writer.startRun(eventid.run()); 00333 00334 00335 auto iter = tmpFrag->dataBegin(); 00336 std::ostringstream str; 00337 str << "{"; 00338 while (iter != tmpFrag->dataEnd()) 00339 { 00340 str << *iter << ", "; 00341 ++iter; 00342 00343 } 00344 str << "}"; 00345 TLOG(TLVL_DEBUG) << "Fragment to art: " << str.str(); 00346 00347 00348 artdaq::FragmentPtr tempFrag; 00349 auto sts = writer.AddFragment(std::move(tmpFrag), 1000000, tempFrag); 00350 BOOST_REQUIRE_EQUAL(sts, true); 00351 00352 while (writer.GetLockedBufferCount()) 00353 { 00354 writer.sendMetrics(); 00355 usleep(100000); 00356 } 00357 00358 art::EventPrincipal* newevent = nullptr; 00359 art::SubRunPrincipal* newsubrun = nullptr; 00360 art::RunPrincipal* newrun = nullptr; 00361 bool rc = reader.readNext(run.get(), subrun.get(), newrun, newsubrun, newevent); 00362 BOOST_REQUIRE(rc); 00363 if (run.get() && run->run() == eventid.run()) 00364 { 00365 BOOST_CHECK(newrun == nullptr); 00366 } 00367 else 00368 { 00369 BOOST_CHECK(newrun); 00370 BOOST_CHECK(newrun->id() == eventid.runID()); 00371 } 00372 if (!newrun && subrun.get() && subrun->subRun() == eventid.subRun()) 00373 { 00374 BOOST_CHECK(newsubrun == nullptr); 00375 } 00376 else 00377 { 00378 BOOST_CHECK(newsubrun); 00379 BOOST_CHECK(newsubrun->id() == eventid.subRunID()); 00380 } 00381 BOOST_CHECK(newevent); 00382 BOOST_CHECK(newevent->id() == eventid); 00383 art::Event e(*newevent, art::ModuleDescription()); 00384 art::Handle<std::vector<artdaq::Fragment>> h; 00385 e.getByLabel("daq", "ABCDEF", h); 00386 BOOST_CHECK(h.isValid()); 00387 BOOST_CHECK(h->size() == 1); 00388 00389 auto iter2 = h->front().dataBegin(); 00390 std::ostringstream str2; 00391 str2 << "{"; 00392 while (iter2 != h->front().dataEnd()) 00393 { 00394 str2 << *iter2 << ", "; 00395 ++iter2; 00396 00397 } 00398 str2 << "}"; 00399 TLOG(TLVL_DEBUG) << "Fragment from art: " << str2.str(); 00400 00401 BOOST_CHECK(std::equal(fakeData.begin(), 00402 fakeData.end(), 00403 h->front().dataBegin())); 00404 delete(newrun); 00405 delete(newsubrun); 00406 delete(newevent); 00407 } 00408 } 00409 00410 BOOST_AUTO_TEST_CASE(nonempty_event) 00411 { 00412 art::EventID eventid(2112, 1, 3); 00413 art::Timestamp now; 00414 basic_test(reader(), writer(), 00415 std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run(), now)), 00416 std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run(), eventid.subRun(), now)), 00417 eventid); 00418 } 00419 00420 BOOST_AUTO_TEST_CASE(first_event) 00421 { 00422 art::EventID eventid(2112, 1, 3); 00423 art::Timestamp now; 00424 basic_test(reader(), writer(), 00425 nullptr, 00426 nullptr, 00427 eventid); 00428 } 00429 00430 BOOST_AUTO_TEST_CASE(new_subrun) 00431 { 00432 art::EventID eventid(2112, 1, 3); 00433 art::Timestamp now; 00434 basic_test(reader(), writer(), 00435 std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run(), now)), 00436 std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run(), 0, now)), 00437 eventid); 00438 } 00439 00440 BOOST_AUTO_TEST_CASE(new_run) 00441 { 00442 art::EventID eventid(2112, 1, 3); 00443 art::Timestamp now; 00444 basic_test(reader(), writer(), 00445 std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run() - 1, now)), 00446 std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run() - 1, 00447 eventid.subRun(), 00448 now)), 00449 eventid); 00450 } 00451 00452 BOOST_AUTO_TEST_CASE(end_of_data) 00453 { 00454 // Tell 'reader' the name of the file we are to read. This is pretty 00455 // much irrelevant for SharedMemoryReader, but we'll stick to the 00456 // interface demanded by Source<T>... 00457 std::string const fakeFileName("no such file exists"); 00458 art::FileBlock* pFile = nullptr; 00459 reader().readFile(fakeFileName, pFile); 00460 BOOST_CHECK(pFile); 00461 BOOST_CHECK(pFile->fileFormatVersion() == art::FileFormatVersion(1, "RawEvent2011")); 00462 BOOST_CHECK(pFile->tree() == nullptr); 00463 00464 BOOST_CHECK(!pFile->fastClonable()); 00465 // Test the end-of-data handling. Reading an end-of-data should result in readNext() returning false, 00466 // and should return null pointers for new-run, -subrun and -event. 00467 // Prepare our 'previous run/subrun/event'.. 00468 art::RunID runid(2112); 00469 art::SubRunID subrunid(2112, 1); 00470 art::EventID eventid(2112, 1, 3); 00471 art::Timestamp now; 00472 std::unique_ptr<art::RunPrincipal> run(source_helper().makeRunPrincipal(runid.run(), now)); 00473 std::unique_ptr<art::SubRunPrincipal> subrun(source_helper().makeSubRunPrincipal(runid.run(), subrunid.subRun(), now)); 00474 std::unique_ptr<art::EventPrincipal> event(source_helper().makeEventPrincipal(runid.run(), 00475 subrunid.subRun(), 00476 eventid.event(), 00477 now)); 00478 writer().endOfData(); 00479 art::EventPrincipal* newevent = nullptr; 00480 art::SubRunPrincipal* newsubrun = nullptr; 00481 art::RunPrincipal* newrun = nullptr; 00482 bool rc = reader().readNext(run.get(), subrun.get(), newrun, newsubrun, newevent); 00483 BOOST_CHECK(!rc); 00484 BOOST_CHECK(newrun == nullptr); 00485 BOOST_CHECK(newsubrun == nullptr); 00486 BOOST_CHECK(newevent == nullptr); 00487 } 00488 00489 BOOST_AUTO_TEST_SUITE_END()