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 #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
00092 };
00093
00094 MPRGlobalTestFixture::MPRGlobalTestFixture()
00095 :
00096 branchKeys_()
00097 , processConfigurations_()
00098 , productRegistry_()
00099
00100 {
00101
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();
00179 art::ModuleDescription md(fhicl::ParameterSet().id(),
00180 "_NAMEERROR_",
00181 "_LABELERROR_",
00182 *gf().processConfigurations_["daq"]);
00183
00184
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);
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
00455
00456
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
00466
00467
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()