Belle II Software development
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
19using namespace std;
20using namespace Belle2;
21
22namespace {
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
37 evtPtr.registerInDataStore();
38 evtData.registerInDataStore();
39 evtDataDifferentName.registerInDataStore();
40 evtDataEmpty.registerInDataStore();
41 evtDataDifferentDurability.registerInDataStore();
42 profileInfo.registerInDataStore();
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 {
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 {
207 EXPECT_TRUE(a);
208 EXPECT_EQ(a->getEvent(), (unsigned long)42);
210 EXPECT_FALSE(b);
212 EXPECT_FALSE(c);
214 EXPECT_FALSE(d);
215
216 //check we didn't insert a new object with 'd'
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 {
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!)
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 {
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());
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()
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());
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
515 StoreArray<EventMetaData> eventsMetaDatas2;
516
517 //inialize(), use names from module paramateres
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 }
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");
566 evtPtrB.registerInDataStore(DataStore::c_DontWriteOut);
567 evtDataB.registerInDataStore(DataStore::c_DontWriteOut);
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
623 EXPECT_TRUE("" == DataStore::Instance().currentID());
625 EXPECT_TRUE("" == DataStore::Instance().currentID());
626 verifyContents();
628 EXPECT_TRUE("foo" == DataStore::Instance().currentID());
629 verifyContents(); //still unmodified
630
631 //change something
633 a->setEvent(1234567);
634
635 //and restore
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");
644 evtDataB.registerInDataStore();
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");
687 relObjs.registerInDataStore();
688 relObjs2.registerInDataStore();
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
734 StoreArray<ProfileInfo> profileInfo;
735 evtData.registerRelationTo(profileInfo);
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
static std::string objectName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
Definition: DataStore.cc:151
void createNewDataStoreID(const std::string &id)
creates new datastore with given id, copying the registered objects/arrays from the current one.
Definition: DataStore.cc:779
static std::string defaultObjectName()
Return the default storage name for an object of the given type.
Definition: DataStore.h:127
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Definition: DataStore.h:71
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
void switchID(const std::string &id)
switch to DataStore with given ID.
Definition: DataStore.cc:794
static TClass * getTClassFromDefaultArrayName(const std::string &arrayName)
Tries to deduce the TClass from a default array name, which is generally the name of the C++ class wi...
Definition: DataStore.cc:116
static TClass * getTClassFromDefaultObjectName(const std::string &objectName)
Tries to deduce the TClass from a default object name, which is generally the name of the C++ class.
Definition: DataStore.cc:105
static std::string defaultArrayName()
Return the default storage name for an array of the given type.
Definition: DataStore.h:157
void copyContentsTo(const std::string &id, const std::vector< std::string > &entrylist_event={})
copy contents (actual array / object contents) of current DataStore to the DataStore with given ID.
Definition: DataStore.cc:810
@ c_Persistent
Object is available during entire execution time.
Definition: DataStore.h:60
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition: DataStore.h:59
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:54
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:94
static std::string relationName(const std::string &fromName, const std::string &toName, std::string const &namedRelation="")
Return storage name for a relation between two arrays of the given names.
Definition: DataStore.h:180
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition: DataStore.cc:86
void invalidateData(EDurability durability)
Clears all registered StoreEntry objects of a specified durability, invalidating all objects.
Definition: DataStore.cc:715
static std::string arrayName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
Definition: DataStore.cc:164
void replaceData(const StoreAccessorBase &from, const StoreAccessorBase &to)
For two StoreAccessors of same type, move all data in 'from' into 'to', discarding previous contents ...
Definition: DataStore.cc:343
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.
const std::string & getName() const
Return name under 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.
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
static std::vector< std::string > getArrayList(DataStore::EDurability durability=DataStore::c_Event)
Return list of array names with matching type.
Definition: StoreArray.h:275
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
TClonesArray * getPtr() const
Raw access to the underlying TClonesArray.
Definition: StoreArray.h:311
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
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
bool isValid(EForwardBackward eForwardBackward)
Check whether the given enum instance is one of the valid values.
Abstract base class for different kinds of events.
STL namespace.
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