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