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 art::BranchIDListRegistry::updateFromProductRegistry(productRegistry_);
00122 #endif
00123 art::ProductMetaData::create_instance(productRegistry_);
00124 }
00125
00126 art::ProcessConfiguration*
00127 MPRGlobalTestFixture::
00128 fake_single_module_process(std::string const& tag,
00129 std::string const& processName,
00130 fhicl::ParameterSet const& moduleParams,
00131 std::string const& release
00132 #if ART_HEX_VERSION < 0x20800
00133 , std::string const& pass
00134 #endif
00135 )
00136 {
00137 fhicl::ParameterSet processParams;
00138 processParams.put(processName, moduleParams);
00139 processParams.put<std::string>("process_name",
00140 processName);
00141 auto emplace_pair =
00142 processConfigurations_.emplace(tag,
00143 std::make_unique<art::ProcessConfiguration>(processName, processParams.id(), release, pass));
00144 return emplace_pair.first->second.get();
00145 }
00146
00147 std::unique_ptr<art::BranchDescription>
00148 MPRGlobalTestFixture::
00149 fake_single_process_branch(std::string const& tag,
00150 std::string const& processName,
00151 std::string const& productInstanceName)
00152 {
00153 std::string moduleLabel = processName + "dummyMod";
00154 std::string moduleClass("DummyModule");
00155 fhicl::ParameterSet modParams;
00156 modParams.put<std::string>("module_type", moduleClass);
00157 modParams.put<std::string>("module_label", moduleLabel);
00158 art::ProcessConfiguration* process =
00159 fake_single_module_process(tag, processName, modParams);
00160 art::ModuleDescription mod(modParams.id(),
00161 moduleClass,
00162 moduleLabel,
00163 *process);
00164 art::TypeID dummyType(typeid(int));
00165 art::BranchDescription* result =
00166 new art::BranchDescription(
00167 art::InEvent,
00168 art::TypeLabel(dummyType,
00169 productInstanceName),
00170 mod);
00171
00172
00173 branchKeys_.insert(std::make_pair(tag, art::BranchKey(*result)));
00174 return std::unique_ptr<art::BranchDescription>(result);
00175 }
00176
00180 struct ShmRTestFixture
00181 {
00185 ShmRTestFixture()
00186 {
00187 static bool once(true);
00188 if (once)
00189 {
00190 artdaq::configureMessageFacility("shared_memory_reader_t");
00191 (void)reader();
00192 art::ModuleDescription md(fhicl::ParameterSet().id(),
00193 "_NAMEERROR_",
00194 "_LABELERROR_",
00195 *gf().processConfigurations_["daq"]);
00196
00197
00198 helper().registerProducts(gf().productRegistry_, md);
00199 gf().finalize();
00200 once = false;
00201 }
00202 }
00203
00208 MPRGlobalTestFixture& gf()
00209 {
00210 static MPRGlobalTestFixture mpr;
00211 return mpr;
00212 }
00213
00218 art::ProductRegistryHelper& helper()
00219 {
00220 static art::ProductRegistryHelper s_helper;
00221 return s_helper;
00222 }
00223
00228 art::SourceHelper& source_helper()
00229 {
00230 static std::unique_ptr<art::SourceHelper>
00231 s_source_helper;
00232 if (!s_source_helper)
00233 {
00234 fhicl::ParameterSet sourceParams;
00235 std::string moduleType{ "DummySource" };
00236 std::string moduleLabel{ "daq" };
00237 sourceParams.put<std::string>("module_type", moduleType);
00238 sourceParams.put<std::string>("module_label", moduleLabel);
00239 auto pc_ptr = gf().fake_single_module_process(moduleLabel,
00240 "TEST",
00241 sourceParams);
00242 art::ModuleDescription md(sourceParams.id(),
00243 moduleType,
00244 moduleLabel,
00245 *pc_ptr);
00246 s_source_helper = std::make_unique<art::SourceHelper>(md);
00247 }
00248 return *s_source_helper;
00249 }
00250
00255 uint32_t getKey()
00256 {
00257 static uint32_t key = static_cast<uint32_t>(std::hash<std::string>()("shared_memory_reader_t"));
00258 return key;
00259 }
00264 uint32_t getBroadcastKey()
00265 {
00266 static uint32_t key = static_cast<uint32_t>(std::hash<std::string>()("shared_memory_reader_t BROADCAST"));
00267 return key;
00268 }
00269
00274 artdaq::detail::SharedMemoryReader<>& reader()
00275 {
00276 writer();
00277 fhicl::ParameterSet pset;
00278 pset.put("shared_memory_key", getKey());
00279 pset.put("broadcast_shared_memory_key", getBroadcastKey());
00280 pset.put("max_event_size_bytes", 0x100000);
00281 pset.put("buffer_count", 10);
00282 static artdaq::detail::SharedMemoryReader<>
00283 s_reader(pset,
00284 helper(),
00285 source_helper(),
00286 gf().productRegistry_);
00287 static bool reader_initialized = false;
00288 if (!reader_initialized)
00289 {
00290 s_reader.fragment_type_map_[1] = "ABCDEF";
00291 helper().reconstitutes<artdaq::Fragments, art::InEvent>("daq", "ABCDEF");
00292 reader_initialized = true;
00293 }
00294 return s_reader;
00295 }
00296
00301 artdaq::SharedMemoryEventManager& writer()
00302 {
00303 fhicl::ParameterSet pset;
00304 pset.put("shared_memory_key", getKey());
00305 pset.put("broadcast_shared_memory_key", getBroadcastKey());
00306 pset.put("max_event_size_bytes", 0x100000);
00307 pset.put("art_analyzer_count", 0);
00308 pset.put("stale_buffer_timeout_usec", 100000);
00309 pset.put("expected_fragments_per_event", 1);
00310 pset.put("buffer_count", 10);
00311 static artdaq::SharedMemoryEventManager
00312 s_writer(pset, pset);
00313 return s_writer;
00314
00315 }
00316 };
00317
00318 BOOST_FIXTURE_TEST_SUITE(shared_memory_reader_t, ShmRTestFixture)
00319
00320 namespace
00321 {
00330 void basic_test(artdaq::detail::SharedMemoryReader<>& reader,
00331 artdaq::SharedMemoryEventManager& writer,
00332 std::unique_ptr<art::RunPrincipal>&& run,
00333 std::unique_ptr<art::SubRunPrincipal>&& subrun,
00334 art::EventID const& eventid)
00335 {
00336 BOOST_REQUIRE(run || subrun == nullptr);
00337 std::vector<artdaq::Fragment::value_type> fakeData{ 1, 2, 3, 4 };
00338 artdaq::FragmentPtr
00339 tmpFrag(artdaq::Fragment::dataFrag(eventid.event(),
00340 0,
00341 fakeData.begin(),
00342 fakeData.end()));
00343 tmpFrag->setUserType(1);
00344
00345 writer.startRun(eventid.run());
00346
00347
00348 auto iter = tmpFrag->dataBegin();
00349 std::ostringstream str;
00350 str << "{";
00351 while (iter != tmpFrag->dataEnd())
00352 {
00353 str << std::to_string(*iter) << ", ";
00354 ++iter;
00355
00356 }
00357 str << "}";
00358 TLOG(TLVL_DEBUG) << "Fragment to art: " << str.str();
00359
00360
00361 artdaq::FragmentPtr tempFrag;
00362 auto sts = writer.AddFragment(std::move(tmpFrag), 1000000, tempFrag);
00363 BOOST_REQUIRE_EQUAL(sts, true);
00364
00365 while (writer.GetLockedBufferCount())
00366 {
00367 writer.sendMetrics();
00368 usleep(100000);
00369 }
00370
00371 art::EventPrincipal* newevent = nullptr;
00372 art::SubRunPrincipal* newsubrun = nullptr;
00373 art::RunPrincipal* newrun = nullptr;
00374 bool rc = reader.readNext(run.get(), subrun.get(), newrun, newsubrun, newevent);
00375 BOOST_REQUIRE(rc);
00376 if (run.get() && run->run() == eventid.run())
00377 {
00378 BOOST_CHECK(newrun == nullptr);
00379 }
00380 else
00381 {
00382 BOOST_CHECK(newrun);
00383 BOOST_CHECK(newrun->id() == eventid.runID());
00384 }
00385 if (!newrun && subrun.get() && subrun->subRun() == eventid.subRun())
00386 {
00387 BOOST_CHECK(newsubrun == nullptr);
00388 }
00389 else
00390 {
00391 BOOST_CHECK(newsubrun);
00392 BOOST_CHECK(newsubrun->id() == eventid.subRunID());
00393 }
00394 BOOST_CHECK(newevent);
00395 BOOST_CHECK(newevent->id() == eventid);
00396 art::Event e(*newevent, art::ModuleDescription());
00397 art::Handle<std::vector<artdaq::Fragment>> h;
00398 e.getByLabel("daq", "ABCDEF", h);
00399 BOOST_CHECK(h.isValid());
00400 BOOST_CHECK(h->size() == 1);
00401
00402 auto iter2 = h->front().dataBegin();
00403 std::ostringstream str2;
00404 str2 << "{";
00405 while (iter2 != h->front().dataEnd())
00406 {
00407 str2 << std::to_string(*iter2) << ", ";
00408 ++iter2;
00409
00410 }
00411 str2 << "}";
00412 TLOG(TLVL_DEBUG) << "Fragment from art: " << str2.str();
00413
00414 BOOST_CHECK(std::equal(fakeData.begin(),
00415 fakeData.end(),
00416 h->front().dataBegin()));
00417 delete(newrun);
00418 delete(newsubrun);
00419 delete(newevent);
00420 }
00421 }
00422
00423 BOOST_AUTO_TEST_CASE(nonempty_event)
00424 {
00425 art::EventID eventid(2112, 1, 3);
00426 art::Timestamp now;
00427 basic_test(reader(), writer(),
00428 std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run(), now)),
00429 std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run(), eventid.subRun(), now)),
00430 eventid);
00431 }
00432
00433 BOOST_AUTO_TEST_CASE(first_event)
00434 {
00435 art::EventID eventid(2112, 1, 3);
00436 art::Timestamp now;
00437 basic_test(reader(), writer(),
00438 nullptr,
00439 nullptr,
00440 eventid);
00441 }
00442
00443 BOOST_AUTO_TEST_CASE(new_subrun)
00444 {
00445 art::EventID eventid(2112, 1, 3);
00446 art::Timestamp now;
00447 basic_test(reader(), writer(),
00448 std::unique_ptr<art::RunPrincipal>(source_helper().makeRunPrincipal(eventid.run(), now)),
00449 std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run(), 0, now)),
00450 eventid);
00451 }
00452
00453 BOOST_AUTO_TEST_CASE(new_run)
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() - 1, now)),
00459 std::unique_ptr<art::SubRunPrincipal>(source_helper().makeSubRunPrincipal(eventid.run() - 1,
00460 eventid.subRun(),
00461 now)),
00462 eventid);
00463 }
00464
00465 BOOST_AUTO_TEST_CASE(end_of_data)
00466 {
00467
00468
00469
00470 std::string const fakeFileName("no such file exists");
00471 art::FileBlock* pFile = nullptr;
00472 reader().readFile(fakeFileName, pFile);
00473 BOOST_CHECK(pFile);
00474 BOOST_CHECK(pFile->fileFormatVersion() == art::FileFormatVersion(1, "RawEvent2011"));
00475 BOOST_CHECK(pFile->tree() == nullptr);
00476
00477 BOOST_CHECK(!pFile->fastClonable());
00478
00479
00480
00481 art::RunID runid(2112);
00482 art::SubRunID subrunid(2112, 1);
00483 art::EventID eventid(2112, 1, 3);
00484 art::Timestamp now;
00485 std::unique_ptr<art::RunPrincipal> run(source_helper().makeRunPrincipal(runid.run(), now));
00486 std::unique_ptr<art::SubRunPrincipal> subrun(source_helper().makeSubRunPrincipal(runid.run(), subrunid.subRun(), now));
00487 std::unique_ptr<art::EventPrincipal> event(source_helper().makeEventPrincipal(runid.run(),
00488 subrunid.subRun(),
00489 eventid.event(),
00490 now));
00491 writer().endOfData();
00492 art::EventPrincipal* newevent = nullptr;
00493 art::SubRunPrincipal* newsubrun = nullptr;
00494 art::RunPrincipal* newrun = nullptr;
00495 bool rc = reader().readNext(run.get(), subrun.get(), newrun, newsubrun, newevent);
00496 BOOST_CHECK(!rc);
00497 BOOST_CHECK(newrun == nullptr);
00498 BOOST_CHECK(newsubrun == nullptr);
00499 BOOST_CHECK(newevent == nullptr);
00500 }
00501
00502 BOOST_AUTO_TEST_SUITE_END()