Belle II Software  release-08-01-10
datastore.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <framework/dataobjects/EventMetaData.h>
9 #include <framework/dataobjects/ProfileInfo.h>
10 #include <framework/datastore/StoreArray.h>
11 #include <framework/datastore/StoreObjPtr.h>
12 #include <framework/datastore/RelationsObject.h>
13 #include <framework/utilities/TestHelpers.h>
14 
15 #include <gtest/gtest.h>
16 
17 #include <algorithm>
18 
19 using namespace std;
20 using namespace Belle2;
21 
22 namespace {
24  class DataStoreTest : public ::testing::Test {
25  protected:
27  void SetUp() override
28  {
31  StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
32  StoreArray<EventMetaData> evtDataEmpty("Empty");
33  StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
34  StoreArray<ProfileInfo> profileInfo;
35 
36  DataStore::Instance().setInitializeActive(true);
37  evtPtr.registerInDataStore();
38  evtData.registerInDataStore();
39  evtDataDifferentName.registerInDataStore();
40  evtDataEmpty.registerInDataStore();
41  evtDataDifferentDurability.registerInDataStore();
42  profileInfo.registerInDataStore();
43  DataStore::Instance().setInitializeActive(false);
44 
45  evtPtr.create();
46  evtPtr->setEvent(42);
47 
48 
49  ProfileInfo profileInfoObject(128, 64, 60.0);
50  for (int i = 0; i < 10; ++i) {
51  //direct construction
52  EventMetaData* newobj = evtData.appendNew();
53  newobj->setEvent(10 + i);
54 
55  //copy-construction
56  EventMetaData newObj2;
57  newObj2.setEvent(20 + i);
58  evtDataDifferentName.appendNew(newObj2);
59 
60  //fancy constructors
61  newobj = evtDataDifferentDurability.appendNew(30 + i);
62  ASSERT_TRUE(newobj != nullptr);
63 
64  //copy-construct ProfileInfo objects
65  profileInfo.appendNew(profileInfoObject);
66  }
67  }
68 
70  void TearDown() override
71  {
72  DataStore::Instance().reset();
73  }
74 
76  static void verifyContents()
77  {
79  EXPECT_TRUE(evtPtr.isValid());
80  EXPECT_EQ(evtPtr->getEvent(), (unsigned long)42);
81 
83  StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
84  StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
85  StoreArray<ProfileInfo> profileInfo;
86  EXPECT_EQ(evtData.getEntries(), 10);
87  EXPECT_EQ(evtDataDifferentName.getEntries(), 10);
88  EXPECT_EQ(evtDataDifferentDurability.getEntries(), 10);
89  EXPECT_EQ(profileInfo.getEntries(), 10);
90  for (int i = 0; i < 10; ++i) {
91  EXPECT_EQ((int)evtData[i]->getEvent(), 10 + i);
92  EXPECT_EQ((int)evtDataDifferentName[i]->getEvent(), 20 + i);
93  EXPECT_EQ((int)evtDataDifferentDurability[i]->getEvent(), 30 + i);
94 
95  EXPECT_EQ(profileInfo[i]->getVirtualMemory(), 128u);
96  EXPECT_FLOAT_EQ(profileInfo[i]->getTimeInSec(), 60.0);
97  }
98  }
99 
100  };
101 
102  TEST_F(DataStoreTest, EntryNames)
103  {
104  EXPECT_EQ("JustSomeStuff", DataStore::defaultObjectName("JustSomeStuff"));
105  EXPECT_EQ("JustSomeStuff", DataStore::defaultObjectName("Belle2::Foo::JustSomeStuff"));
106  EXPECT_EQ("JustSomeStuffs", DataStore::defaultArrayName("Belle2::Foo::JustSomeStuff"));
107 
108  EXPECT_EQ("MyOwnName", DataStore::arrayName<TObject>("MyOwnName"));
109  EXPECT_EQ("MyOwnName", DataStore::arrayName(TObject::Class(), "MyOwnName"));
110  EXPECT_EQ("TObjects", DataStore::arrayName<TObject>(""));
111  EXPECT_EQ("TObjects", DataStore::arrayName(TObject::Class(), ""));
112 
113  EXPECT_EQ("MyOwnName", DataStore::objectName<TObject>("MyOwnName"));
114  EXPECT_EQ("MyOwnName", DataStore::objectName(TObject::Class(), "MyOwnName"));
115 
116  EXPECT_EQ("TObject", DataStore::objectName<TObject>(""));
117  EXPECT_EQ("TObject", DataStore::objectName(TObject::Class(), ""));
118 
119  EXPECT_EQ("EventMetaDatas", DataStore::arrayName<EventMetaData>(""));
120  EXPECT_EQ("GF2Track", DataStore::defaultObjectName("genfit::Track"));
121 
122  EXPECT_EQ("AToB", DataStore::relationName("A", "B"));
123  auto relname = DataStore::defaultRelationName<EventMetaData, ProfileInfo>();
124  EXPECT_EQ("EventMetaDatasToProfileInfos", relname);
125  }
126 
127  TEST_F(DataStoreTest, GetTClass)
128  {
129  EXPECT_EQ(Belle2::EventMetaData::Class(), DataStore::getTClassFromDefaultObjectName("Belle2::EventMetaData"));
130  EXPECT_EQ(Belle2::EventMetaData::Class(), DataStore::getTClassFromDefaultObjectName("EventMetaData"));
131 
132  EXPECT_EQ(Belle2::EventMetaData::Class(), DataStore::getTClassFromDefaultArrayName("Belle2::EventMetaDatas"));
133  EXPECT_EQ(Belle2::EventMetaData::Class(), DataStore::getTClassFromDefaultArrayName("EventMetaDatas"));
134  }
135 
136 
138  TEST_F(DataStoreTest, AttachTest)
139  {
141  EXPECT_TRUE(evtPtr);
142 
144  EXPECT_TRUE(evtData);
145  StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
146  EXPECT_TRUE(evtDataDifferentName);
147  StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
148  EXPECT_TRUE(evtDataDifferentDurability);
149  StoreArray<ProfileInfo> profileInfo;
150  EXPECT_TRUE(profileInfo);
151  }
152 
154  TEST_F(DataStoreTest, TypeTest)
155  {
156  //attach with incompatible type
157  EXPECT_B2FATAL(StoreArray<ProfileInfo>("EventMetaDatas").isValid());
158  EXPECT_B2FATAL(StoreObjPtr<ProfileInfo>("EventMetaData").isValid());
159 
160  //attaching objects to array and vice versa shouldn't work
161  //neither should the store allow objects with same name/durability
162  //as existing arrays
163  EXPECT_B2FATAL(StoreArray<EventMetaData>("EventMetaData").isValid());
164  EXPECT_B2FATAL(StoreObjPtr<EventMetaData>("EventMetaDatas").isValid());
165 
166  //getting a base class is OK
167  EXPECT_TRUE(StoreArray<TObject>("EventMetaDatas").isValid());
168  StoreObjPtr<TObject> emd("EventMetaData");
169  EXPECT_TRUE(emd.isValid());
170  EXPECT_EQ(std::string("Belle2::EventMetaData"), std::string(emd->GetName()));
171  }
172 
174  TEST_F(DataStoreTest, MetaDataTest)
175  {
177  EXPECT_EQ(evtPtr.getDurability(), DataStore::c_Event);
178  EXPECT_TRUE(evtPtr.getName() == "EventMetaData");
179  EXPECT_FALSE(evtPtr.isArray());
180  EXPECT_TRUE(evtPtr.getClass() == EventMetaData::Class());
181 
183  StoreArray<EventMetaData> evtData2("EventMetaDatas");
184  StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
185  StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
186  EXPECT_TRUE(evtData.getName() == "EventMetaDatas");
187  EXPECT_TRUE(evtData.isArray());
188  EXPECT_TRUE(evtData.getClass() == EventMetaData::Class());
189  EXPECT_EQ(evtData.getDurability(), DataStore::c_Event);
190  EXPECT_TRUE(evtData == evtData2);
191  EXPECT_FALSE(evtData != evtData2);
192  EXPECT_FALSE(evtData == evtDataDifferentName);
193  EXPECT_FALSE(evtData == evtDataDifferentDurability);
194 
195  //different type
196  StoreArray<ProfileInfo> profileInfo{};
197  EXPECT_FALSE(profileInfo == evtData);
198  EXPECT_TRUE(profileInfo != evtData);
199  //note: EXPECT_NE/EQ do things I don't understand. this doesn't work:
200  //EXPECT_NE(profileInfo, evtData);
201  }
202 
204  TEST_F(DataStoreTest, ReadOnlyAttach)
205  {
206  StoreObjPtr<EventMetaData> a("", DataStore::c_Event);
207  EXPECT_TRUE(a);
208  EXPECT_EQ(a->getEvent(), (unsigned long)42);
209  StoreObjPtr<EventMetaData> b("nonexisting", DataStore::c_Event);
210  EXPECT_FALSE(b);
211  StoreObjPtr<EventMetaData> c("", DataStore::c_Persistent);
212  EXPECT_FALSE(c);
213  StoreObjPtr<EventMetaData> d("", DataStore::c_Persistent);
214  EXPECT_FALSE(d);
215 
216  //check we didn't insert a new object with 'd'
217  StoreObjPtr<EventMetaData> e("", DataStore::c_Persistent);
218  EXPECT_FALSE(e);
219  }
220 
222  TEST_F(DataStoreTest, VerifyContents)
223  {
224  verifyContents();
225 
226  //test removing data
228  evtData.clear();
229  EXPECT_TRUE(evtData.isValid());
230  EXPECT_EQ(evtData.getEntries(), 0);
231 
233  evtPtr.clear(); //resets to default-constructed object
234  EXPECT_TRUE(evtPtr.isValid());
235  EXPECT_EQ(evtPtr->getEvent(), 1);
236  }
237  TEST_F(DataStoreTest, InvalidAccessor)
238  {
239  StoreArray<EventMetaData> none("doesntexist");
240  EXPECT_FALSE(none.isValid());
241  EXPECT_THROW(none.getPtr(), std::runtime_error);
242  EXPECT_THROW(none.appendNew(), std::runtime_error);
243  none.clear();
244  EXPECT_THROW(none.getPtr(), std::runtime_error);
245  EXPECT_EQ(0, none.getEntries());
246 
247  StoreObjPtr<EventMetaData> noobj("doesntexist");
248  EXPECT_FALSE(noobj.isValid());
249  EXPECT_THROW(*noobj, std::runtime_error);
250  EXPECT_THROW(noobj->getEvent(), std::runtime_error);
251 
252  }
253  TEST_F(DataStoreTest, RawAccess)
254  {
255  StoreArray<EventMetaData> evtData{};
256  EXPECT_TRUE(evtData.getPtr() != nullptr);
257  }
258 
260  TEST_F(DataStoreTest, ArrayConsistency)
261  {
263  StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
264  StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
265  StoreArray<ProfileInfo> profileInfo;
266  EXPECT_EQ((int)evtData.getPtr()->GetEntries(), 10);
267  EXPECT_EQ((int)evtDataDifferentName.getPtr()->GetEntries(), 10);
268  EXPECT_EQ((int)evtDataDifferentDurability.getPtr()->GetEntries(), 10);
269  EXPECT_EQ((int)profileInfo.getPtr()->GetEntries(), 10);
270  }
271 
273  TEST_F(DataStoreTest, RangeCheck)
274  {
276  EXPECT_TRUE(evtData[0] != nullptr);
277  EXPECT_THROW(evtData[-1], std::out_of_range);
278  EXPECT_THROW(evtData[10], std::out_of_range);
279  }
280 
282  TEST_F(DataStoreTest, ClearMaps)
283  {
285  EXPECT_EQ(evtPtr->getEvent(), (unsigned long)42);
286 
287  //clear event map (evtPtr is now invalid!)
288  DataStore::Instance().invalidateData(DataStore::c_Event);
289 
290  //right now this is NULL, since no object was actually created yet
292  EXPECT_FALSE(a);
293 
295  EXPECT_FALSE(b);
296 
297  //create() should produce a default constructed object
298  b.create();
299  EXPECT_TRUE(*b == EventMetaData());
300  //since a should attach to same object...
301  EXPECT_TRUE(*a == *b);
302 
303  a->setEvent(42);
304  //don't replace existing object
305  a.create(false);
306  EXPECT_EQ(a->getEvent(), (unsigned long)42);
307  //replace existing object
308  a.create(true);
309  EXPECT_NE(a->getEvent(), (unsigned long)42);
310 
311 
312  //cleared arrays must be empty
314  StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
315  StoreArray<ProfileInfo> profileInfo;
316  EXPECT_EQ(evtData.getEntries(), 0);
317  EXPECT_EQ(evtDataDifferentName.getEntries(), 0);
318  EXPECT_EQ(profileInfo.getEntries(), 0);
319 
320  //run durability, should be unaffected
321  StoreArray<EventMetaData> evtDataDifferentDurability("", DataStore::c_Persistent);
322  EXPECT_EQ(evtDataDifferentDurability.getEntries(), 10);
323  }
324 
326  TEST_F(DataStoreTest, RequireObjects)
327  {
328  DataStore::Instance().setInitializeActive(true);
329  EXPECT_TRUE(StoreObjPtr<EventMetaData>().isRequired());
330  EXPECT_FALSE(StoreObjPtr<EventMetaData>("", DataStore::c_Persistent).isRequired());
331  EXPECT_FALSE(StoreObjPtr<EventMetaData>("nonexisting2").isRequired());
332  EXPECT_FALSE(StoreObjPtr<EventMetaData>("", DataStore::c_Persistent).isRequired());
333  //check we didn't create one...
334  EXPECT_FALSE(StoreObjPtr<EventMetaData>("nonexisting2").isRequired());
335 
336  EXPECT_TRUE(StoreArray<EventMetaData>().isRequired());
337  EXPECT_TRUE(StoreArray<EventMetaData>("EventMetaDatas_2").isRequired());
338  EXPECT_TRUE(StoreArray<EventMetaData>("", DataStore::c_Persistent).isRequired());
339  EXPECT_FALSE(StoreArray<EventMetaData>("blah").isRequired());
340  EXPECT_FALSE(StoreArray<EventMetaData>("blah").isRequired());
341  EXPECT_TRUE(StoreArray<ProfileInfo>().isRequired());
342  //check we didn't create one...
343  EXPECT_FALSE(StoreArray<EventMetaData>("blah").isRequired());
344  DataStore::Instance().setInitializeActive(false);
345 
346  EXPECT_B2FATAL(StoreObjPtr<EventMetaData>().isRequired());
347  }
348 
350  TEST_F(DataStoreTest, StoreArrayIteration)
351  {
352  const StoreArray<EventMetaData> evtData;
353  StoreArray<EventMetaData> evtDataNonConst;
354  //array syntax
355  for (int i = 0; i < evtData.getEntries(); i++) {
356  EXPECT_TRUE(evtData[i] != nullptr);
357  }
358 
359  //basic iterator features
360  {
361  //input iterator:
362  StoreArray<EventMetaData>::iterator it = evtDataNonConst.begin();
364  it2 = it;
365 
366  //equality/inequality
367  EXPECT_TRUE(it == it2);
368  EXPECT_FALSE(it != it2);
369 
370  //test postfix
371  EXPECT_TRUE((it++) == it2);
372  ++it2;
373 
374  //test prefix
375  EXPECT_TRUE(it != (++it2));
376 
377  //rvalue deref
378  EventMetaData ev = *it;
379  it->getEvent();
380  it2 = it;
381 
382  //output iterator:
383  //lvalue deref (just overwrite with same object)
384  *it = ev;
385  *it++ = ev;
386 
387  EXPECT_TRUE(ev == *it2);
388  EXPECT_TRUE(it2 != it); //was incremented
389  EXPECT_TRUE(ev != *it); //was incremented
390 
391  //forward iterator (default constructor and multi-pass):
393  it3 = it;
394  ev = *it++;
395  EXPECT_TRUE(ev == *it3);
396  }
397 
398  //algorithm stuff
399  {
400  StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
401  EXPECT_EQ((int)evtDataNonConst[0]->getEvent(), 10);
402  EXPECT_EQ((int)evtDataDifferentName[0]->getEvent(), 20);
403  //swap all members of evtDataNonConst ande evtDataDifferentName (same length!)
404  std::swap_ranges(evtDataNonConst.begin(), evtDataNonConst.end(), evtDataDifferentName.begin());
405  EXPECT_EQ((int)evtDataDifferentName[9]->getEvent(), 19);
406  EXPECT_EQ((int)evtDataNonConst[9]->getEvent(), 29);
407 
408  //undo
409  std::swap_ranges(evtDataDifferentName.begin(), evtDataDifferentName.end(), evtDataNonConst.begin());
410  EXPECT_EQ((int)evtDataNonConst[9]->getEvent(), 19);
411  EXPECT_EQ((int)evtDataDifferentName[9]->getEvent(), 29);
412  }
413 
414  int i = 0;
415  for (StoreArray<EventMetaData>::iterator it = evtDataNonConst.begin(); it != evtDataNonConst.end(); ++it) {
416  EXPECT_TRUE(&(*it) == evtData[i]);
417  EXPECT_EQ((int)it->getEvent(), 10 + i);
418  i++;
419  }
420  EXPECT_EQ(i, evtData.getEntries());
421 
422  //range-based for
423  i = 0;
424  for (EventMetaData& emd : evtDataNonConst) {
425  EXPECT_TRUE(&emd == evtData[i]);
426  i++;
427  }
428  EXPECT_EQ(i, evtData.getEntries());
429 
430  //range-based for (const)
431  i = 0;
432  for (const EventMetaData& emd : evtData) {
433  EXPECT_TRUE(&emd == evtData[i]);
434  i++;
435  }
436  EXPECT_EQ(i, evtData.getEntries());
437 
438  //iteration over registered, but empty array
439  i = 0;
440  StoreArray<EventMetaData> evtDataEmpty("Empty");
441  for (const EventMetaData& emd : evtDataEmpty) {
442  (void)emd;
443  i++;
444  }
445  EXPECT_EQ(i, 0);
446  //iteration over non-existing array
447  i = 0;
448  StoreArray<EventMetaData> nonExistant("doesntexist");
449  for (const EventMetaData& emd : nonExistant) {
450  (void)emd;
451  i++;
452  }
453  EXPECT_EQ(i, 0);
454  }
455 
457  TEST_F(DataStoreTest, DataStoreRegistration)
458  {
459  //emulate Module::initialize()
460  DataStore::Instance().setInitializeActive(true);
461 
462  StoreObjPtr<EventMetaData> evtPtr("abc123");
463  StoreArray<EventMetaData> evtArray("abc123array");
464 
465  //verify that they aren't registered right now
466  EXPECT_FALSE(evtPtr.isOptional());
467  EXPECT_FALSE(evtArray.isOptional());
468  EXPECT_FALSE(evtPtr.isRequired());
469  EXPECT_FALSE(evtArray.isRequired());
470  EXPECT_FALSE(evtPtr.isValid());
471  EXPECT_FALSE(evtArray.isValid());
472  EXPECT_FALSE(StoreObjPtr<EventMetaData>(evtPtr.getName()).isRequired());
473  EXPECT_FALSE(StoreArray<EventMetaData>(evtArray.getName()).isRequired());
474 
475  EXPECT_TRUE(evtPtr.registerInDataStore());
476  EXPECT_TRUE(evtArray.registerInDataStore(DataStore::c_DontWriteOut));
477 
478  //already registered, ok by default
479  EXPECT_TRUE(evtPtr.registerInDataStore());
480  EXPECT_TRUE(evtArray.registerInDataStore(DataStore::c_DontWriteOut));
481 
482  //test c_ErrorIfAlreadyRegistered (return code=false + B2ERROR)
483  EXPECT_B2ERROR(EXPECT_FALSE(evtPtr.registerInDataStore(DataStore::c_ErrorIfAlreadyRegistered)));
484  EXPECT_B2ERROR(EXPECT_FALSE(evtArray.registerInDataStore(DataStore::c_DontWriteOut | DataStore::c_ErrorIfAlreadyRegistered)));
485 
486  //now they should be available:
487  EXPECT_TRUE(evtPtr.isOptional());
488  EXPECT_TRUE(evtArray.isOptional());
489  EXPECT_TRUE(evtPtr.isRequired());
490  EXPECT_TRUE(evtArray.isRequired());
491  EXPECT_FALSE(evtPtr.isValid()); // not valid until created
492  EXPECT_TRUE(evtArray.isValid());
493  EXPECT_TRUE(StoreObjPtr<EventMetaData>(evtPtr.getName()).isRequired());
494  EXPECT_TRUE(StoreArray<EventMetaData>(evtArray.getName()).isRequired());
495  DataStore::Instance().setInitializeActive(false);
496  }
497 
498  TEST_F(DataStoreTest, RegistrationOutsideOfInitializeShouldFail)
499  {
500  //outside initialize(), registration results in an error
501  EXPECT_B2ERROR(StoreArray<EventMetaData>().registerInDataStore("someothernewname"));
502  EXPECT_B2ERROR(StoreArray<EventMetaData>().registerInDataStore("someothernewname", DataStore::c_DontWriteOut));
503  EXPECT_FALSE(StoreArray<EventMetaData>().isOptional("someothernewname"));
504 
505  //accessing unregistered things doesn't work.
506  StoreArray<EventMetaData> someothernewname("someothernewname");
507  EXPECT_FALSE(someothernewname.isValid());
508  }
509 
510  TEST_F(DataStoreTest, ConstructedBeforeInitializeButWithNonDefaultName)
511  {
512  //as a class member, the classes get constructed before initialize(), but we may not have the name yet
514  StoreObjPtr<ProfileInfo> profile;
515  StoreArray<EventMetaData> eventsMetaDatas2;
516 
517  //inialize(), use names from module paramateres
518  DataStore::Instance().setInitializeActive(true);
519  {
520  EXPECT_TRUE(events.registerInDataStore("ThisBeInterestingNameForEvents"));
521  EXPECT_TRUE(profile.registerInDataStore("MyProfileInfoName", DataStore::c_DontWriteOut));
522 
523  //also should work with optional / required
524  EXPECT_TRUE(eventsMetaDatas2.isOptional("EventMetaDatas_2"));
525  EXPECT_TRUE(eventsMetaDatas2.isRequired("EventMetaDatas_2"));
526  }
527  DataStore::Instance().setInitializeActive(false);
528 
529  //ok, our objects should now know their name
530  EXPECT_EQ("ThisBeInterestingNameForEvents", events.getName());
531  EXPECT_TRUE(profile.getName() == "MyProfileInfoName");
532  EXPECT_TRUE(profile.notWrittenOut());
533  EXPECT_TRUE(eventsMetaDatas2.getName() == "EventMetaDatas_2");
534 
535  //accessing data
536  EXPECT_EQ(0, events.getEntries());
537  EXPECT_FALSE(profile.isValid());
538  EXPECT_EQ(10, eventsMetaDatas2.getEntries());
539 
540  //saving data
541  profile.create();
542  EXPECT_TRUE(profile.isValid());
543  StoreObjPtr<ProfileInfo> profileAttachAgain("MyProfileInfoName");
544  EXPECT_TRUE(profileAttachAgain.isValid());
545 
546  events.appendNew();
547  EXPECT_EQ(1, events.getEntries());
548  StoreArray<EventMetaData> eventsAttachAgain("ThisBeInterestingNameForEvents");
549  EXPECT_EQ(1, eventsAttachAgain.getEntries());
550  }
551 
552  TEST_F(DataStoreTest, ArrayList)
553  {
554  std::vector<std::string> arrayList = StoreArray<EventMetaData>::getArrayList();
555  std::vector<std::string> exparrayList = {"Empty", "EventMetaDatas", "EventMetaDatas_2"};
556  EXPECT_EQ(exparrayList, arrayList);
557  }
558 
559  TEST_F(DataStoreTest, ReplaceData)
560  {
562  StoreObjPtr<EventMetaData> evtPtrB("abc123");
564  StoreArray<EventMetaData> evtDataB("otherArray");
565  DataStore::Instance().setInitializeActive(true);
566  evtPtrB.registerInDataStore(DataStore::c_DontWriteOut);
567  evtDataB.registerInDataStore(DataStore::c_DontWriteOut);
568  DataStore::Instance().setInitializeActive(false);
569 
570  {
571  //objects
572  EXPECT_EQ(42, evtPtr->getEvent());
573  EXPECT_FALSE(evtPtrB.isValid());
574  EXPECT_FALSE(evtPtr.notWrittenOut());
575  EXPECT_TRUE(evtPtrB.notWrittenOut());
576 
577  DataStore::Instance().replaceData(evtPtr, evtPtrB);
578  EXPECT_EQ(42, evtPtrB->getEvent());
579  EXPECT_FALSE(evtPtr.isValid());
580 
581  //metadata unchanged
582  EXPECT_FALSE(evtPtr.notWrittenOut());
583  EXPECT_TRUE(evtPtrB.notWrittenOut());
584 
585  //move null object into existing one
586  DataStore::Instance().replaceData(evtPtr, evtPtrB);
587  EXPECT_FALSE(evtPtr.isValid());
588  EXPECT_FALSE(evtPtrB.isValid());
589 
590  //null object to null object
591  DataStore::Instance().replaceData(evtPtr, evtPtrB);
592  EXPECT_FALSE(evtPtr.isValid());
593  EXPECT_FALSE(evtPtrB.isValid());
594  }
595 
596  {
597  //arrays
598  EXPECT_EQ(10, evtData.getEntries());
599  EXPECT_EQ(0, evtDataB.getEntries());
600 
601  DataStore::Instance().replaceData(evtData, evtDataB);
602  EXPECT_EQ(0, evtData.getEntries());
603  EXPECT_EQ(10, evtDataB.getEntries());
604 
605  DataStore::Instance().replaceData(evtData, evtDataB);
606  EXPECT_EQ(0, evtData.getEntries());
607  EXPECT_EQ(0, evtDataB.getEntries());
608 
609  DataStore::Instance().replaceData(evtData, evtDataB);
610  EXPECT_EQ(0, evtData.getEntries());
611  EXPECT_EQ(0, evtDataB.getEntries());
612  }
613  }
614 
615  TEST_F(DataStoreTest, SwitchDataStore)
616  {
617  EXPECT_TRUE("" == DataStore::Instance().currentID());
618  //not created yet
619  EXPECT_THROW(DataStore::Instance().copyContentsTo("foo"), std::out_of_range);
620 
621  //create new DS ID
622  DataStore::Instance().createNewDataStoreID("foo");
623  EXPECT_TRUE("" == DataStore::Instance().currentID());
624  DataStore::Instance().copyContentsTo("foo");
625  EXPECT_TRUE("" == DataStore::Instance().currentID());
626  verifyContents();
627  DataStore::Instance().switchID("foo");
628  EXPECT_TRUE("foo" == DataStore::Instance().currentID());
629  verifyContents(); //still unmodified
630 
631  //change something
633  a->setEvent(1234567);
634 
635  //and restore
636  DataStore::Instance().switchID("");
637  EXPECT_TRUE("" == DataStore::Instance().currentID());
638  verifyContents(); //back to normal
639 
640  //register another object in ""
641  //and try copying (this catches insufficient checks during copying)
642  StoreArray<EventMetaData> evtDataB("otherArray");
643  DataStore::Instance().setInitializeActive(true);
644  evtDataB.registerInDataStore();
645  DataStore::Instance().copyContentsTo("foo");
646  }
647 
648  TEST_F(DataStoreTest, FindStoreEntry)
649  {
650  DataStore::StoreEntry* entry = nullptr;
651  int index = -1;
652 
653  //test TObject-derived arrays
655  StoreArray<EventMetaData> evtDataDifferentName("EventMetaDatas_2");
656 
657  EXPECT_TRUE(DataStore::Instance().findStoreEntry(evtData[5], entry, index));
658  EXPECT_EQ(index, 5);
659  EXPECT_EQ(entry->name, evtData.getName());
660 
661  //entry and index are already correct, should return quickly
662  EXPECT_TRUE(DataStore::Instance().findStoreEntry(evtData[5], entry, index));
663  EXPECT_EQ(index, 5);
664  EXPECT_EQ(entry->name, evtData.getName());
665 
666  //not resetting entry, index here. this should not usually happen, but ought to be harmless
667  EXPECT_TRUE(DataStore::Instance().findStoreEntry(evtDataDifferentName[7], entry, index));
668  EXPECT_EQ(index, 7);
669  EXPECT_EQ(entry->name, evtDataDifferentName.getName());
670 
671  entry = nullptr; index = -1;
672  EXPECT_TRUE(DataStore::Instance().findStoreEntry(evtDataDifferentName[7], entry, index));
673  EXPECT_EQ(index, 7);
674  EXPECT_EQ(entry->name, evtDataDifferentName.getName());
675 
676  entry = nullptr; index = -1;
677  EventMetaData localObj;
678  EXPECT_FALSE(DataStore::Instance().findStoreEntry(&localObj, entry, index));
679  EXPECT_EQ(index, -1);
680  EXPECT_EQ(entry, nullptr);
681 
682 
683  //test RelationsObjects (caches used)
685  StoreArray<RelationsObject> relObjs2("relobs2");
686  DataStore::Instance().setInitializeActive(true);
687  relObjs.registerInDataStore();
688  relObjs2.registerInDataStore();
689  DataStore::Instance().setInitializeActive(false);
690  for (int i = 0; i < 6; i++) {
691  relObjs.appendNew();
692  relObjs2.appendNew();
693  }
694 
695  entry = nullptr; index = -1;
696  EXPECT_TRUE(DataStore::Instance().findStoreEntry(relObjs[5], entry, index));
697  EXPECT_EQ(index, 5);
698  EXPECT_EQ(entry->name, relObjs.getName());
699 
700  //should use cache now
701  entry = nullptr; index = -1;
702  EXPECT_TRUE(DataStore::Instance().findStoreEntry(relObjs[5], entry, index));
703  EXPECT_EQ(index, 5);
704  EXPECT_EQ(entry->name, relObjs.getName());
705 
706  entry = nullptr; index = -1;
707  EXPECT_TRUE(DataStore::Instance().findStoreEntry(relObjs2[2], entry, index));
708  EXPECT_EQ(index, 2);
709  EXPECT_EQ(entry->name, relObjs2.getName());
710 
711  //and caches again
712  entry = nullptr; index = -1;
713  EXPECT_TRUE(DataStore::Instance().findStoreEntry(relObjs2[2], entry, index));
714  EXPECT_EQ(index, 2);
715  EXPECT_EQ(entry->name, relObjs2.getName());
716 
717  //test finding storeobjptr (not implemented, so nothing found)
719  entry = nullptr; index = -1;
720  EXPECT_FALSE(DataStore::Instance().findStoreEntry(&(*evtPtr), entry, index));
721  EXPECT_EQ(index, -1);
722  EXPECT_EQ(entry, nullptr);
723 
724  //searching for nullptr is allowed
725  EXPECT_FALSE(DataStore::Instance().findStoreEntry(nullptr, entry, index));
726  }
727 
728  TEST_F(DataStoreTest, ListEntries)
729  {
731  EXPECT_EQ(0, DataStore::Instance().getListOfRelatedArrays(evtData).size());
732 
733  DataStore::Instance().setInitializeActive(true);
734  StoreArray<ProfileInfo> profileInfo;
735  evtData.registerRelationTo(profileInfo);
736  DataStore::Instance().setInitializeActive(false);
737 
738  EXPECT_TRUE(DataStore::Instance().hasRelation(evtData, profileInfo, DataStore::c_Event, ""));
739  EXPECT_FALSE(DataStore::Instance().hasRelation(profileInfo, evtData, DataStore::c_Event, ""));
740  EXPECT_FALSE(DataStore::Instance().hasRelation(evtData, profileInfo, DataStore::c_Event, "SOMENONSENSE"));
741  EXPECT_FALSE(DataStore::Instance().hasRelation(evtData, profileInfo, DataStore::c_Persistent, ""));
742  EXPECT_FALSE(DataStore::Instance().hasRelation(profileInfo, evtData, DataStore::c_Persistent, ""));
743 
744  EXPECT_EQ(1, DataStore::Instance().getListOfRelatedArrays(evtData).size());
745  EXPECT_EQ(1, DataStore::Instance().getListOfRelatedArrays(profileInfo).size());
746 
747  EXPECT_EQ(1, DataStore::Instance().getListOfArrays(ProfileInfo::Class(), DataStore::c_Event).size());
748  EXPECT_EQ(0, DataStore::Instance().getListOfArrays(ProfileInfo::Class(), DataStore::c_Persistent).size());
749  EXPECT_EQ(1, DataStore::Instance().getListOfArrays(EventMetaData::Class(), DataStore::c_Persistent).size());
750  EXPECT_EQ(3, DataStore::Instance().getListOfArrays(EventMetaData::Class(), DataStore::c_Event).size());
751 
752  EXPECT_EQ(1, DataStore::Instance().getListOfArrays(TObject::Class(), DataStore::c_Persistent).size());
753  EXPECT_EQ(4, DataStore::Instance().getListOfArrays(TObject::Class(), DataStore::c_Event).size());
754 
755  EXPECT_EQ(1, DataStore::Instance().getListOfObjects(EventMetaData::Class(), DataStore::c_Event).size());
756  EXPECT_EQ(0, DataStore::Instance().getListOfObjects(EventMetaData::Class(), DataStore::c_Persistent).size());
757  EXPECT_EQ(1, DataStore::Instance().getListOfObjects(TObject::Class(), DataStore::c_Event).size());
758  EXPECT_EQ(0, DataStore::Instance().getListOfObjects(TObject::Class(), DataStore::c_Persistent).size());
759  }
760 
761  TEST_F(DataStoreTest, Assign)
762  {
764  EXPECT_FALSE(evtData.assign(new EventMetaData(), true));
765  EXPECT_FALSE(evtData.assign(new EventMetaData(), false));
766 
767  EXPECT_TRUE(evtData.isValid());
768  EXPECT_EQ(evtData.getEntries(), 10);
769 
771  auto* newobj = new EventMetaData();
772  newobj->setEvent(123);
773  EXPECT_FALSE(evtPtr.assign(new EventMetaData(), false));
774  EXPECT_FALSE(evtPtr.assign(new ProfileInfo(), true));
775  EXPECT_EQ(evtPtr->getEvent(), 42);
776  EXPECT_TRUE(evtPtr.assign(newobj, true));
777  EXPECT_EQ(evtPtr->getEvent(), 123);
778  }
779 } // namespace
Store event, run, and experiment numbers.
Definition: EventMetaData.h:33
void setEvent(unsigned int event)
Event Setter.
Definition: EventMetaData.h:55
Optimizes class to iterate over TObjArray and classes inheriting from it.
Definition: ArrayIterator.h:23
Store execution time and memory usage.
Definition: ProfileInfo.h:22
DataStore::EDurability getDurability() const
Return durability with which the object is saved in the DataStore.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool notWrittenOut() const
Returns true if this object/array should not be saved by output modules.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
virtual void clear()
Clear contents of this object.
bool assign(TObject *object, bool replace=false)
Assign 'object' to this accessor.
TClass * getClass() const
The underlying object's type.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
bool isArray() const
Is this an accessor for an array?
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
bool isValid() const
Check wether the array was registered.
Definition: StoreArray.h:288
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
iterator end()
Return iterator to last entry +1.
Definition: StoreArray.h:320
iterator begin()
Return iterator to first entry.
Definition: StoreArray.h:318
TClonesArray * getPtr() const
Raw access to the underlying TClonesArray.
Definition: StoreArray.h:311
void clear() override
Delete all entries in this array.
Definition: StoreArray.h:207
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
bool isValid() const
Check whether the object was created.
Definition: StoreObjPtr.h:111
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
bool isValid(EForwardBackward eForwardBackward)
Check whether the given enum instance is one of the valid values.
Abstract base class for different kinds of events.
Wraps a stored array/object, stored under unique (name, durability) key.
Definition: StoreEntry.h:22
std::string name
Name of the entry.
Definition: StoreEntry.h:53