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