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