Belle II Software  release-05-02-19
database.cc
1 #include <framework/database/IntervalOfValidity.h>
2 #include <framework/database/Database.h>
3 #include <framework/database/Configuration.h>
4 #include <framework/database/DBObjPtr.h>
5 #include <framework/database/DBArray.h>
6 #include <framework/database/EventDependency.h>
7 #include <framework/database/PayloadFile.h>
8 #include <framework/database/DBPointer.h>
9 #include <framework/datastore/StoreObjPtr.h>
10 #include <framework/dataobjects/EventMetaData.h>
11 #include <framework/utilities/TestHelpers.h>
12 #include <framework/geometry/BFieldManager.h>
13 #include <framework/dbobjects/MagneticField.h>
14 #include <framework/dbobjects/MagneticFieldComponentConstant.h>
15 
16 #include <TNamed.h>
17 #include <TClonesArray.h>
18 
19 #include <gtest/gtest.h>
20 
21 #include <boost/filesystem.hpp>
22 #include <list>
23 #include <cstdio>
24 
25 using namespace std;
26 using namespace Belle2;
27 
28 namespace {
29 
31  class DataBaseTest : public ::testing::Test {
32  protected:
33 
35  enum EDatabaseType {c_local, c_central, c_chain, c_default};
36 
38  EDatabaseType m_dbType = c_local;
39 
40  TestHelpers::TempDirCreator m_tempDir;
43  void SetUp() override
44  {
46  DataStore::Instance().setInitializeActive(true);
47  evtPtr.registerInDataStore();
48  DataStore::Instance().setInitializeActive(false);
49  evtPtr.construct(0, 0, 1);
50 
51  auto& c = Conditions::Configuration::getInstance();
52  switch (m_dbType) {
53  case c_local:
54  c.setGlobalTags({});
55  c.overrideGlobalTags();
56  c.setMetadataProviders({});
57  c.setNewPayloadLocation("testPayloads/TestDatabase.txt");
58  c.appendTestingPayloadLocation("testPayloads/TestDatabase.txt");
59  break;
60  case c_central:
61  c.setGlobalTags({"default"});
62  c.overrideGlobalTags();
63  break;
64  case c_chain:
65  c.setGlobalTags({"default"});
66  c.overrideGlobalTags();
67  c.setMetadataProviders({});
68  c.setNewPayloadLocation("testPayloads/TestDatabase.txt");
69  c.appendTestingPayloadLocation("testPayloads/TestDatabase.txt");
70  break;
71  case c_default:
72  break;
73  }
74 
75  if (m_dbType != c_central) {
76  list<Database::DBImportQuery> query;
77  TClonesArray array("TObject");
78  for (int experiment = 1; experiment <= 5; experiment++) {
79  IntervalOfValidity iov(experiment, -1, experiment, -1);
80 
81  TString name = "Experiment ";
82  name += experiment;
83  query.push_back(Database::DBImportQuery("TNamed", new TNamed(name, name), iov));
84 
85  new(array[experiment - 1]) TObject;
86  array[experiment - 1]->SetUniqueID(experiment);
87  Database::Instance().storeData("TObjects", &array, iov);
88 
89  FILE* f = fopen("file.xml", "w");
90  fprintf(f, "Experiment %d\n", experiment);
91  fclose(f);
92  Database::Instance().addPayload("file.xml", "file.xml", iov);
93  }
94  if (m_dbType != c_chain) {
95  Database::Instance().storeData(query);
96  }
97 
98  EventDependency intraRunDep(new TNamed("A", "A"));
99  intraRunDep.add(10, new TNamed("B", "B"));
100  intraRunDep.add(50, new TNamed("C", "C"));
101  IntervalOfValidity iov1(1, 1, 1, 1);
102  Database::Instance().storeData("IntraRun", &intraRunDep, iov1);
103  IntervalOfValidity iov2(1, 2, 1, -1);
104  Database::Instance().storeData("IntraRun", new TNamed("X", "X"), iov2);
105  }
106  }
107 
109  void TearDown() override
110  {
111  if (m_dbType != c_central) boost::filesystem::remove_all("testPayloads");
112  Database::reset();
113  DataStore::Instance().reset();
114  }
115 
116  };
117 
119  TEST_F(DataBaseTest, IntervalOfValidity)
120  {
121  EXPECT_TRUE(IntervalOfValidity().empty());
122  EXPECT_FALSE(IntervalOfValidity(1, -1, -1, -1).empty());
123  EXPECT_FALSE(IntervalOfValidity(-1, -1, 1, -1).empty());
124  EXPECT_FALSE(IntervalOfValidity(1, 2, 3, 4).empty());
125 
126  EventMetaData event(0, 8, 15); // experiment 15, run 8
127  EXPECT_FALSE(IntervalOfValidity().contains(event));
128  EXPECT_FALSE(IntervalOfValidity(16, 1, -1, -1).contains(event));
129  EXPECT_FALSE(IntervalOfValidity(16, -1, -1, -1).contains(event));
130  EXPECT_FALSE(IntervalOfValidity(15, 9, -1, -1).contains(event));
131  EXPECT_TRUE(IntervalOfValidity(15, 8, -1, -1).contains(event));
132  EXPECT_TRUE(IntervalOfValidity(15, 8, 15, -1).contains(event));
133  EXPECT_TRUE(IntervalOfValidity(15, 8, 15, 8).contains(event));
134  EXPECT_TRUE(IntervalOfValidity(15, -1, 15, 8).contains(event));
135  EXPECT_TRUE(IntervalOfValidity(-1, -1, 15, 8).contains(event));
136  EXPECT_FALSE(IntervalOfValidity(-1, -1, 15, 7).contains(event));
137  EXPECT_FALSE(IntervalOfValidity(-1, -1, 14, -1).contains(event));
138  EXPECT_FALSE(IntervalOfValidity(-1, -1, 14, 1).contains(event));
139  }
140 
142  TEST_F(DataBaseTest, IntervalOfValidityOperations)
143  {
144  IntervalOfValidity iov(1, 1, 3, 10);
145  EXPECT_TRUE(IntervalOfValidity(1, 1, 3, 10).contains(iov));
146  EXPECT_TRUE(IntervalOfValidity(1, -1, 3, 10).contains(iov));
147  EXPECT_TRUE(IntervalOfValidity(-1, -1, 3, 10).contains(iov));
148  EXPECT_TRUE(IntervalOfValidity(1, 1, 3, -1).contains(iov));
149  EXPECT_TRUE(IntervalOfValidity(1, 1, -1, -1).contains(iov));
150  EXPECT_FALSE(IntervalOfValidity(1, 2, 3, 10).contains(iov));
151  EXPECT_FALSE(IntervalOfValidity(2, -1, 3, 10).contains(iov));
152  EXPECT_FALSE(IntervalOfValidity(1, 1, 3, 9).contains(iov));
153  EXPECT_FALSE(IntervalOfValidity(1, 1, 2, -1).contains(iov));
154  EXPECT_TRUE(iov.contains(IntervalOfValidity(2, -1, 2, -1)));
155  EXPECT_FALSE(iov.contains(IntervalOfValidity(1, -1, 2, 1)));
156  EXPECT_FALSE(iov.contains(IntervalOfValidity(-1, -1, 3, 10)));
157  EXPECT_FALSE(iov.contains(IntervalOfValidity(1, 1, 3, -1)));
158  EXPECT_FALSE(iov.contains(IntervalOfValidity(1, 1, -1, -1)));
159 
160  EXPECT_TRUE(IntervalOfValidity(1, 1, 3, 10).overlaps(iov));
161  EXPECT_TRUE(IntervalOfValidity(1, -1, 1, 1).overlaps(iov));
162  EXPECT_TRUE(IntervalOfValidity(-1, -1, 1, 1).overlaps(iov));
163  EXPECT_TRUE(IntervalOfValidity(-1, -1, 1, -1).overlaps(iov));
164  EXPECT_TRUE(IntervalOfValidity(3, -1, -1, -1).overlaps(iov));
165  EXPECT_TRUE(IntervalOfValidity(3, 10, -1, -1).overlaps(iov));
166  EXPECT_FALSE(IntervalOfValidity(-1, -1, -1, -1).overlaps(iov));
167  EXPECT_FALSE(IntervalOfValidity(-1, -1, 0, -1).overlaps(iov));
168  EXPECT_FALSE(IntervalOfValidity(-1, -1, 1, 0).overlaps(iov));
169  EXPECT_FALSE(IntervalOfValidity(3, 11, 3, -1).overlaps(iov));
170  EXPECT_FALSE(IntervalOfValidity(4, -1, 4, -1).overlaps(iov));
171 
172  IntervalOfValidity iov1, iov2;
173  iov1 = IntervalOfValidity(1, 1, 3, 10);
174  iov2 = IntervalOfValidity(1, 1, 3, 10);
175  EXPECT_TRUE(iov1.trimOverlap(iov2, true));
176  EXPECT_TRUE(iov1.empty());
177  EXPECT_TRUE(iov2 == IntervalOfValidity(1, 1, 3, 10));
178 
179  iov1 = IntervalOfValidity(1, 1, 3, 10);
180  iov2 = IntervalOfValidity(2, -1, 4, -1);
181  EXPECT_TRUE(iov1.trimOverlap(iov2, true));
182  EXPECT_TRUE(iov1 == IntervalOfValidity(1, 1, 1, -1));
183  EXPECT_TRUE(iov2 == IntervalOfValidity(2, -1, 4, -1));
184 
185  iov1 = IntervalOfValidity(1, 1, 3, 11);
186  iov2 = IntervalOfValidity(1, 1, 3, 10);
187  EXPECT_FALSE(iov1.trimOverlap(iov2, true));
188  EXPECT_TRUE(iov1 == IntervalOfValidity(1, 1, 3, 11));
189  EXPECT_TRUE(iov2 == IntervalOfValidity(1, 1, 3, 10));
190 
191  iov1 = IntervalOfValidity(1, 1, 3, 10);
192  iov2 = IntervalOfValidity(1, 1, 3, 10);
193  EXPECT_TRUE(iov1.trimOverlap(iov2, false));
194  EXPECT_TRUE(iov1 == IntervalOfValidity(1, 1, 3, 10));
195  EXPECT_TRUE(iov2.empty());
196 
197  iov1 = IntervalOfValidity(1, 1, 3, 10);
198  iov2 = IntervalOfValidity(2, -1, 4, -1);
199  EXPECT_TRUE(iov1.trimOverlap(iov2, false));
200  EXPECT_TRUE(iov1 == IntervalOfValidity(1, 1, 3, 10));
201  EXPECT_TRUE(iov2 == IntervalOfValidity(3, 11, 4, -1));
202 
203  // Validity is larger than we want on the lower edge
204  iov1 = IntervalOfValidity(11, 0, 12, 86);
205  // Want to trim off everything below exp=12
206  iov2 = IntervalOfValidity(0, 0, 11, -1);
207  EXPECT_TRUE(iov1.trimOverlap(iov2, false));
208  EXPECT_EQ(iov1, IntervalOfValidity(12, 0, 12, 86));
209  EXPECT_EQ(iov2, IntervalOfValidity(0, 0, 11, -1));
210  }
211 
213  TEST_F(DataBaseTest, DBObjPtr)
214  {
216  DBObjPtr<TNamed> named;
217 
218  evtPtr->setExperiment(1);
219  DBStore::Instance().update();
220  ASSERT_TRUE(named);
221  EXPECT_TRUE(strcmp(named->GetName(), "Experiment 1") == 0);
222  evtPtr->setExperiment(4);
223  EXPECT_TRUE(strcmp(named->GetName(), "Experiment 1") == 0);
224  DBStore::Instance().update();
225  EXPECT_TRUE(strcmp(named->GetName(), "Experiment 4") == 0);
226  evtPtr->setExperiment(7);
227  DBStore::Instance().update();
228  EXPECT_FALSE(named);
229  }
230 
232  TEST_F(DataBaseTest, DBArray)
233  {
235  DBArray<TObject> objects;
236  DBArray<TObject> missing("notexisting");
237  // check iteration on fresh object
238  {
239  int i = 0;
240  for (const auto& o : missing) {
241  (void)o;
242  ++i;
243  }
244  EXPECT_EQ(i, 0);
245  }
246 
247 
248  evtPtr->setExperiment(1);
249  DBStore::Instance().update();
250  EXPECT_TRUE(objects);
251  EXPECT_FALSE(missing);
252  EXPECT_EQ(objects.getEntries(), 1);
253  EXPECT_EQ(objects[0]->GetUniqueID(), 1);
254  evtPtr->setExperiment(4);
255  EXPECT_EQ(objects.getEntries(), 1);
256  DBStore::Instance().update();
257  EXPECT_EQ(objects.getEntries(), 4);
258  // check iteration on existing
259  {
260  int i = 0;
261  for (const auto& o : objects) {
262  EXPECT_EQ(o.GetUniqueID(), ++i);
263  }
264  EXPECT_EQ(i, 4);
265  }
266 
267  // check iteration on missing object
268  {
269  int i = 0;
270  for (const auto& o : missing) {
271  (void)o;
272  ++i;
273  }
274  EXPECT_EQ(i, 0);
275  }
276  evtPtr->setExperiment(7);
277  DBStore::Instance().update();
278  EXPECT_FALSE(objects);
279  // check iteration over missing but previously existing
280  {
281  int i = 0;
282  for (const auto& o : objects) {
283  EXPECT_EQ(o.GetUniqueID(), ++i);
284  }
285  EXPECT_EQ(i, 0);
286  }
287  }
288 
290  TEST_F(DataBaseTest, DBArrayRange)
291  {
293  DBArray<TObject> objects;
294 
295  evtPtr->setExperiment(3);
296  DBStore::Instance().update();
297  EXPECT_THROW(objects[-1], std::out_of_range);
298  EXPECT_THROW(objects[3], std::out_of_range);
299  }
300 
302  TEST_F(DataBaseTest, TypeCheck)
303  {
304  DBObjPtr<TNamed> named;
305  EXPECT_B2FATAL(DBObjPtr<EventMetaData> wrongType("TNamed"));
306 
307  DBArray<TObject> objects;
308  EXPECT_B2FATAL(DBArray<EventMetaData> wrongType("TObjects"));
309  }
310 
312  TEST_F(DataBaseTest, IntraRun)
313  {
315  DBObjPtr<TNamed> intraRun("IntraRun");
316 
317  evtPtr->setExperiment(1);
318  evtPtr->setRun(1);
319  evtPtr->setEvent(9);
320  DBStore::Instance().update();
321  DBStore::Instance().updateEvent();
322  EXPECT_TRUE(strcmp(intraRun->GetName(), "A") == 0);
323 
324  evtPtr->setEvent(10);
325  DBStore::Instance().updateEvent();
326  EXPECT_TRUE(strcmp(intraRun->GetName(), "B") == 0);
327 
328  evtPtr->setEvent(49);
329  DBStore::Instance().updateEvent();
330  EXPECT_TRUE(strcmp(intraRun->GetName(), "B") == 0);
331 
332  //let's run an update in between and make sure intra run continues to work
333  DBStore::Instance().update();
334  EXPECT_TRUE(strcmp(intraRun->GetName(), "B") == 0);
335 
336  evtPtr->setEvent(50);
337  DBStore::Instance().updateEvent();
338  EXPECT_TRUE(strcmp(intraRun->GetName(), "C") == 0);
339 
340  evtPtr->setRun(2);
341  DBStore::Instance().update();
342  EXPECT_TRUE(strcmp(intraRun->GetName(), "X") == 0);
343  }
344 
346  TEST_F(DataBaseTest, HasChanged)
347  {
349  evtPtr->setExperiment(0);
350  DBStore::Instance().update();
351 
352  DBObjPtr<TNamed> named;
353  EXPECT_FALSE(named.hasChanged());
354 
355  evtPtr->setExperiment(1);
356  EXPECT_FALSE(named.hasChanged());
357 
358  DBStore::Instance().update();
359  EXPECT_TRUE(named.hasChanged());
360 
361  evtPtr->setRun(8);
362  DBStore::Instance().update();
363  EXPECT_FALSE(named.hasChanged());
364 
365  evtPtr->setExperiment(5);
366  DBStore::Instance().update();
367  EXPECT_TRUE(named.hasChanged());
368 
369  evtPtr->setExperiment(7);
370  DBStore::Instance().update();
371  EXPECT_TRUE(named.hasChanged());
372 
373  evtPtr->setExperiment(1);
374  evtPtr->setRun(1);
375  evtPtr->setEvent(1);
376  DBObjPtr<TNamed> intraRun("IntraRun");
377  DBStore::Instance().update();
378  DBStore::Instance().updateEvent();
379  EXPECT_TRUE(intraRun.hasChanged());
380 
381  evtPtr->setEvent(2);
382  DBStore::Instance().updateEvent();
383  EXPECT_FALSE(intraRun.hasChanged());
384 
385  evtPtr->setEvent(10);
386  DBStore::Instance().updateEvent();
387  EXPECT_TRUE(intraRun.hasChanged());
388 
389  evtPtr->setEvent(1000);
390  DBStore::Instance().updateEvent();
391  EXPECT_TRUE(intraRun.hasChanged());
392 
393  evtPtr->setRun(4);
394  DBStore::Instance().update();
395  DBStore::Instance().updateEvent();
396  EXPECT_TRUE(intraRun.hasChanged());
397  }
398 
400  TEST_F(DataBaseTest, PayloadFile)
401  {
403  DBObjPtr<PayloadFile> payload("file.xml");
404 
405  evtPtr->setExperiment(1);
406  DBStore::Instance().update();
407  EXPECT_EQ(payload->getContent(), "Experiment 1\n") << payload->getFileName();
408  evtPtr->setExperiment(4);
409  DBStore::Instance().update();
410  EXPECT_EQ(payload->getContent(), "Experiment 4\n") << payload->getFileName();
411  evtPtr->setExperiment(7);
412  DBStore::Instance().update();
413  EXPECT_FALSE(payload);
414  }
415 
416  //disable (wrong) warnings about unused functions
417 #if defined(__INTEL_COMPILER)
418 #pragma warning disable 177
419 #endif
420 
422  int callbackCounter = 0;
423 
424  void callback()
425  {
426  callbackCounter++;
427  }
428 
429  class Callback {
430  public:
431  void callback()
432  {
433  callbackCounter++;
434  }
435  };
436  Callback callbackObject;
437 
438  TEST_F(DataBaseTest, Callbacks)
439  {
441  evtPtr->setRun(1);
442  evtPtr->setEvent(1);
443  callbackCounter = 0;
444 
445  DBObjPtr<TNamed> named;
446  named.addCallback(&callback);
447  EXPECT_EQ(callbackCounter, 0);
448 
449  evtPtr->setExperiment(2);
450  DBStore::Instance().update();
451  EXPECT_EQ(callbackCounter, 1);
452 
453  evtPtr->setExperiment(4);
454  DBStore::Instance().update();
455  EXPECT_EQ(callbackCounter, 2);
456  DBStore::Instance().update();
457  EXPECT_EQ(callbackCounter, 2);
458 
459  evtPtr->setExperiment(6);
460  DBStore::Instance().update();
461  EXPECT_EQ(callbackCounter, 3);
462 
463  evtPtr->setExperiment(7);
464  DBStore::Instance().update();
465  EXPECT_EQ(callbackCounter, 3);
466 
467  DBArray<TObject> objects;
468  objects.addCallback(&callback);
469 
470  evtPtr->setExperiment(1);
471  DBStore::Instance().update();
472  // callbacks will now be called once for each payload so there is an extra call
473  EXPECT_EQ(callbackCounter, 5);
474 
475  DBObjPtr<TNamed> intraRun("IntraRun");
476  intraRun.addCallback(&callbackObject, &Callback::callback);
477 
478  //There won't be any callback here because the correct object is already set on creation
479  evtPtr->setEvent(1);
480  DBStore::Instance().updateEvent();
481  EXPECT_EQ(callbackCounter, 5);
482 
483  evtPtr->setEvent(2);
484  DBStore::Instance().updateEvent();
485  EXPECT_EQ(callbackCounter, 5);
486 
487  evtPtr->setEvent(10);
488  DBStore::Instance().updateEvent();
489  EXPECT_EQ(callbackCounter, 6);
490 
491  evtPtr->setEvent(1);
492  DBStore::Instance().updateEvent();
493  EXPECT_EQ(callbackCounter, 7);
494  }
495 
497  TEST_F(DataBaseTest, KeyAccess)
498  {
500  evtPtr->setExperiment(1);
501  DBStore::Instance().update();
502 
503  DBArray<TObject> objects;
504  EXPECT_EQ(objects.getByKey<unsigned int>(&TObject::GetUniqueID, 1)->GetUniqueID(), 1);
505  EXPECT_EQ(objects.getByKey<unsigned int>(&TObject::GetUniqueID, 2), nullptr);
506  EXPECT_EQ(objects.getByKey(&TObject::IsFolder, false)->GetUniqueID(), 1);
507  EXPECT_EQ(objects.getByKey(&TObject::IsFolder, true), nullptr);
508 
509  evtPtr->setExperiment(2);
510  DBStore::Instance().update();
511 
512  EXPECT_EQ(objects.getByKey<unsigned int>(&TObject::GetUniqueID, 1)->GetUniqueID(), 1);
513  EXPECT_EQ(objects.getByKey<unsigned int>(&TObject::GetUniqueID, 2)->GetUniqueID(), 2);
514  }
515 
517  TEST_F(DataBaseTest, DBPointer)
518  {
520  evtPtr->setExperiment(2);
521  DBStore::Instance().update();
522 
524  EXPECT_EQ(ptr.key(), 1);
525  EXPECT_TRUE(ptr.isValid());
526  EXPECT_EQ(ptr->GetUniqueID(), 1);
527  ptr = 2;
528  EXPECT_EQ(ptr->GetUniqueID(), 2);
529  ptr = 3;
530  EXPECT_FALSE(ptr.isValid());
531  }
532 
533  TEST_F(DataBaseTest, CleanupReattachDeathtest)
534  {
536  evtPtr->setExperiment(2);
537  DBStore::Instance().update();
538 
539  DBObjPtr<TNamed> named;
540  EXPECT_TRUE(named.isValid());
541  double Bz = BFieldManager::getFieldInTesla({0, 0, 0}).Z();
542  EXPECT_EQ(Bz, 1.5);
543  DBStore::Instance().reset();
544  //Ok, on next access the DBObjPtr should try to reconnect
545  EXPECT_TRUE(named.isValid());
546  //Which means the magnetic field should die a horrible death: It's not
547  //found in the database during testing, just a override.
548  EXPECT_B2FATAL(BFieldManager::getFieldInTesla({0, 0, 0}));
549  //Unless we add a new one
550  auto* field = new Belle2::MagneticField();
551  field->addComponent(new Belle2::MagneticFieldComponentConstant({0, 0, 1.5 * Belle2::Unit::T}));
552  Belle2::DBStore::Instance().addConstantOverride("MagneticField", field, false);
553  //So now it should work again
554  Bz = BFieldManager::getFieldInTesla({0, 0, 0}).Z();
555  EXPECT_EQ(Bz, 1.5);
556  }
557 
560  class DataBaseNoDataStoreTest : public ::testing::Test {
561  protected:
562 
564  enum EDatabaseType {c_local, c_central, c_chain, c_default};
565 
567  EDatabaseType m_dbType = c_local;
568 
569  TestHelpers::TempDirCreator m_tempDir;
571  EventMetaData m_event;
572 
573  DataBaseNoDataStoreTest() : m_event(0, 0, 1) {};
574 
576  void SetUp() override
577  {
578  auto& c = Conditions::Configuration::getInstance();
579  switch (m_dbType) {
580  case c_local:
581  c.setGlobalTags({});
582  c.overrideGlobalTags();
583  c.setMetadataProviders({});
584  c.setNewPayloadLocation("testPayloads/TestDatabase.txt");
585  c.appendTestingPayloadLocation("testPayloads/TestDatabase.txt");
586  break;
587  case c_central:
588  c.setGlobalTags({"default"});
589  c.overrideGlobalTags();
590  break;
591  case c_chain:
592  c.setGlobalTags({"default"});
593  c.overrideGlobalTags();
594  c.setMetadataProviders({});
595  c.setNewPayloadLocation("testPayloads/TestDatabase.txt");
596  c.appendTestingPayloadLocation("testPayloads/TestDatabase.txt");
597  break;
598  case c_default:
599  break;
600  }
601 
602  if (m_dbType != c_central) {
603  list<Database::DBImportQuery> query;
604  TClonesArray array("TObject");
605  for (int experiment = 1; experiment <= 5; experiment++) {
606  IntervalOfValidity iov(experiment, -1, experiment, -1);
607 
608  TString name = "Experiment ";
609  name += experiment;
610  query.push_back(Database::DBImportQuery("TNamed", new TNamed(name, name), iov));
611 
612  new(array[experiment - 1]) TObject;
613  array[experiment - 1]->SetUniqueID(experiment);
614  Database::Instance().storeData("TObjects", &array, iov);
615 
616  FILE* f = fopen("file.xml", "w");
617  fprintf(f, "Experiment %d\n", experiment);
618  fclose(f);
619  Database::Instance().addPayload("file.xml", "file.xml", iov);
620  }
621  if (m_dbType != c_chain) {
622  Database::Instance().storeData(query);
623  }
624 
625  EventDependency intraRunDep(new TNamed("A", "A"));
626  intraRunDep.add(10, new TNamed("B", "B"));
627  intraRunDep.add(50, new TNamed("C", "C"));
628  IntervalOfValidity iov1(1, 1, 1, 1);
629  Database::Instance().storeData("IntraRun", &intraRunDep, iov1);
630  IntervalOfValidity iov2(1, 2, 1, -1);
631  Database::Instance().storeData("IntraRun", new TNamed("X", "X"), iov2);
632  }
633  }
634 
636  void TearDown() override
637  {
638  if (m_dbType != c_central) boost::filesystem::remove_all("testPayloads");
639  Database::reset();
640  }
641 
642  };
643 
645  TEST_F(DataBaseNoDataStoreTest, DBObjPtr)
646  {
647  DBStore::Instance().update(m_event); // The DBStore takes a reference to an EventMetaData object
648  DBObjPtr<TNamed> named;
649  m_event.setExperiment(1);
650  DBStore::Instance().update(m_event); // The DBStore takes a reference to an EventMetaData object
651  ASSERT_TRUE(named);
652  EXPECT_TRUE(strcmp(named->GetName(), "Experiment 1") == 0);
653  m_event.setExperiment(4);
654  EXPECT_TRUE(strcmp(named->GetName(), "Experiment 1") == 0);
655  DBStore::Instance().update(m_event);
656  EXPECT_TRUE(strcmp(named->GetName(), "Experiment 4") == 0);
657  m_event.setExperiment(7);
658  DBStore::Instance().update(m_event);
659  EXPECT_FALSE(named);
660  }
661 
663  TEST_F(DataBaseNoDataStoreTest, DBArray)
664  {
665  DBStore::Instance().update(m_event);
666  DBArray<TObject> objects;
667  DBArray<TObject> missing("notexisting");
668  // check iteration on fresh object
669  {
670  int i = 0;
671  for (const auto& o : missing) {
672  (void)o;
673  ++i;
674  }
675  EXPECT_EQ(i, 0);
676  }
677 
678 
679  m_event.setExperiment(1);
680  DBStore::Instance().update(m_event);
681  EXPECT_TRUE(objects);
682  EXPECT_FALSE(missing);
683  EXPECT_EQ(objects.getEntries(), 1);
684  EXPECT_EQ(objects[0]->GetUniqueID(), 1);
685  m_event.setExperiment(4);
686  EXPECT_EQ(objects.getEntries(), 1);
687  DBStore::Instance().update(m_event);
688  EXPECT_EQ(objects.getEntries(), 4);
689  // check iteration on existing
690  {
691  int i = 0;
692  for (const auto& o : objects) {
693  EXPECT_EQ(o.GetUniqueID(), ++i);
694  }
695  EXPECT_EQ(i, 4);
696  }
697 
698  // check iteration on missing object
699  {
700  int i = 0;
701  for (const auto& o : missing) {
702  (void)o;
703  ++i;
704  }
705  EXPECT_EQ(i, 0);
706  }
707  m_event.setExperiment(7);
708  DBStore::Instance().update(m_event);
709  EXPECT_FALSE(objects);
710  // check iteration over missing but previously existing
711  {
712  int i = 0;
713  for (const auto& o : objects) {
714  EXPECT_EQ(o.GetUniqueID(), ++i);
715  }
716  EXPECT_EQ(i, 0);
717  }
718  }
719 
721  TEST_F(DataBaseNoDataStoreTest, DBArrayRange)
722  {
723  DBArray<TObject> objects;
724 
725  m_event.setExperiment(3);
726  DBStore::Instance().update(m_event);
727  EXPECT_THROW(objects[-1], std::out_of_range);
728  EXPECT_THROW(objects[3], std::out_of_range);
729  }
730 
732  TEST_F(DataBaseNoDataStoreTest, TypeCheck)
733  {
734  DBObjPtr<TNamed> named;
735  EXPECT_B2FATAL(DBObjPtr<EventMetaData> wrongType("TNamed"));
736 
737  DBArray<TObject> objects;
738  EXPECT_B2FATAL(DBArray<EventMetaData> wrongType("TObjects"));
739  }
740 
742  TEST_F(DataBaseNoDataStoreTest, IntraRun)
743  {
744  DBObjPtr<TNamed> intraRun("IntraRun");
745 
746  m_event.setExperiment(1);
747  m_event.setRun(1);
748  m_event.setEvent(9);
749  DBStore::Instance().update(m_event);
750  DBStore::Instance().updateEvent(m_event.getEvent());
751  EXPECT_TRUE(strcmp(intraRun->GetName(), "A") == 0);
752 
753  m_event.setEvent(10);
754  DBStore::Instance().updateEvent(m_event.getEvent());
755  EXPECT_TRUE(strcmp(intraRun->GetName(), "B") == 0);
756 
757  m_event.setEvent(49);
758  DBStore::Instance().updateEvent(m_event.getEvent());
759  EXPECT_TRUE(strcmp(intraRun->GetName(), "B") == 0);
760 
761  //let's run an update in between and make sure intra run continues to work
762  DBStore::Instance().update(m_event);
763  EXPECT_TRUE(strcmp(intraRun->GetName(), "B") == 0);
764 
765  m_event.setEvent(50);
766  DBStore::Instance().updateEvent(m_event.getEvent());
767  EXPECT_TRUE(strcmp(intraRun->GetName(), "C") == 0);
768 
769  m_event.setRun(2);
770  DBStore::Instance().update(m_event);
771  EXPECT_TRUE(strcmp(intraRun->GetName(), "X") == 0);
772  }
773 
775  TEST_F(DataBaseNoDataStoreTest, HasChanged)
776  {
777  m_event.setExperiment(0);
778  DBStore::Instance().update(m_event);
779 
780  DBObjPtr<TNamed> named;
781  EXPECT_FALSE(named.hasChanged());
782 
783  m_event.setExperiment(1);
784  EXPECT_FALSE(named.hasChanged());
785 
786  DBStore::Instance().update(m_event);
787  EXPECT_TRUE(named.hasChanged());
788 
789  m_event.setRun(8);
790  DBStore::Instance().update(m_event);
791  EXPECT_FALSE(named.hasChanged());
792 
793  m_event.setExperiment(5);
794  DBStore::Instance().update(m_event);
795  EXPECT_TRUE(named.hasChanged());
796 
797  m_event.setExperiment(7);
798  DBStore::Instance().update(m_event);
799  EXPECT_TRUE(named.hasChanged());
800 
801  m_event.setExperiment(1);
802  m_event.setRun(1);
803  m_event.setEvent(1);
804  DBObjPtr<TNamed> intraRun("IntraRun");
805  DBStore::Instance().update(m_event);
806  DBStore::Instance().updateEvent(m_event.getEvent());
807  EXPECT_TRUE(intraRun.hasChanged());
808 
809  m_event.setEvent(2);
810  DBStore::Instance().updateEvent(m_event.getEvent());
811  EXPECT_FALSE(intraRun.hasChanged());
812 
813  m_event.setEvent(10);
814  DBStore::Instance().updateEvent(m_event.getEvent());
815  EXPECT_TRUE(intraRun.hasChanged());
816 
817  m_event.setEvent(1000);
818  DBStore::Instance().updateEvent(m_event.getEvent());
819  EXPECT_TRUE(intraRun.hasChanged());
820 
821  m_event.setRun(4);
822  DBStore::Instance().update(m_event);
823  DBStore::Instance().updateEvent(m_event.getEvent());
824  EXPECT_TRUE(intraRun.hasChanged());
825  }
826 
828  TEST_F(DataBaseNoDataStoreTest, PayloadFile)
829  {
830  DBStore::Instance().update(m_event);
831  DBObjPtr<PayloadFile> payload("file.xml");
832  m_event.setExperiment(1);
833  DBStore::Instance().update(m_event);
834  EXPECT_EQ(payload->getContent(), "Experiment 1\n") << payload->getFileName();
835  m_event.setExperiment(4);
836  DBStore::Instance().update(m_event);
837  EXPECT_EQ(payload->getContent(), "Experiment 4\n") << payload->getFileName();
838  m_event.setExperiment(7);
839  DBStore::Instance().update(m_event);
840  EXPECT_FALSE(payload);
841  }
842 
845  TEST_F(DataBaseNoDataStoreTest, Callbacks)
846  {
847  m_event.setRun(1);
848  m_event.setEvent(1);
849  callbackCounter = 0;
850 
851  DBObjPtr<TNamed> named;
852  named.addCallback(&callback);
853  EXPECT_EQ(callbackCounter, 0);
854 
855  m_event.setExperiment(2);
856  DBStore::Instance().update(m_event);
857  EXPECT_EQ(callbackCounter, 1);
858 
859  m_event.setExperiment(4);
860  DBStore::Instance().update(m_event);
861  EXPECT_EQ(callbackCounter, 2);
862  DBStore::Instance().update(m_event);
863  EXPECT_EQ(callbackCounter, 2);
864 
865  m_event.setExperiment(6);
866  DBStore::Instance().update(m_event);
867  EXPECT_EQ(callbackCounter, 3);
868 
869  m_event.setExperiment(7);
870  DBStore::Instance().update(m_event);
871  EXPECT_EQ(callbackCounter, 3);
872 
873  DBArray<TObject> objects;
874  objects.addCallback(&callback);
875 
876  m_event.setExperiment(1);
877  DBStore::Instance().update(m_event);
878  // callbacks will now be called once for each payload so there is an extra call
879  EXPECT_EQ(callbackCounter, 5);
880 
881  DBObjPtr<TNamed> intraRun("IntraRun");
882  intraRun.addCallback(&callbackObject, &Callback::callback);
883 
884  //There won't be any callback here because the correct object is already set on creation
885  m_event.setEvent(1);
886  DBStore::Instance().updateEvent(m_event.getEvent());
887  EXPECT_EQ(callbackCounter, 5);
888 
889  m_event.setEvent(2);
890  DBStore::Instance().updateEvent(m_event.getEvent());
891  EXPECT_EQ(callbackCounter, 5);
892 
893  m_event.setEvent(10);
894  DBStore::Instance().updateEvent(m_event.getEvent());
895  EXPECT_EQ(callbackCounter, 6);
896 
897  m_event.setEvent(1);
898  DBStore::Instance().updateEvent(m_event.getEvent());
899  EXPECT_EQ(callbackCounter, 7);
900  }
901 
903  TEST_F(DataBaseNoDataStoreTest, KeyAccess)
904  {
905  m_event.setExperiment(1);
906  DBStore::Instance().update(m_event);
907 
908  DBArray<TObject> objects;
909  EXPECT_EQ(objects.getByKey<unsigned int>(&TObject::GetUniqueID, 1)->GetUniqueID(), 1);
910  EXPECT_EQ(objects.getByKey<unsigned int>(&TObject::GetUniqueID, 2), nullptr);
911  EXPECT_EQ(objects.getByKey(&TObject::IsFolder, false)->GetUniqueID(), 1);
912  EXPECT_EQ(objects.getByKey(&TObject::IsFolder, true), nullptr);
913 
914  m_event.setExperiment(2);
915  DBStore::Instance().update(m_event);
916 
917  EXPECT_EQ(objects.getByKey<unsigned int>(&TObject::GetUniqueID, 1)->GetUniqueID(), 1);
918  EXPECT_EQ(objects.getByKey<unsigned int>(&TObject::GetUniqueID, 2)->GetUniqueID(), 2);
919  }
920 
921  TEST_F(DataBaseNoDataStoreTest, DBPointer)
922  {
923  m_event.setExperiment(2);
924  DBStore::Instance().update(m_event);
925 
927  EXPECT_EQ(ptr.key(), 1);
928  EXPECT_TRUE(ptr.isValid());
929  EXPECT_EQ(ptr->GetUniqueID(), 1);
930  ptr = 2;
931  EXPECT_EQ(ptr->GetUniqueID(), 2);
932  ptr = 3;
933  EXPECT_FALSE(ptr.isValid());
934  }
935 
936 } // namespace
Belle2::IntervalOfValidity
A class that describes the interval of experiments/runs for which an object in the database is valid.
Definition: IntervalOfValidity.h:35
Belle2::DBAccessorBase::hasChanged
bool hasChanged()
Check whether the object has changed since the last call to hasChanged of the accessor).
Definition: DBAccessorBase.h:92
Belle2::DBObjPtr< PayloadFile >
Specialization of DBObjPtr in case of PayloadFiles.
Definition: PayloadFile.h:64
Belle2::Callback
Definition: Callback.h:17
Belle2::EventMetaData::getEvent
unsigned int getEvent() const
Event Getter.
Definition: EventMetaData.h:155
Belle2::DBStore::addConstantOverride
void addConstantOverride(const std::string &name, TObject *obj, bool oneRun=false)
Add constant override payload.
Definition: DBStore.cc:204
Belle2::EventMetaData::setEvent
void setEvent(unsigned int event)
Event Setter.
Definition: EventMetaData.h:65
Belle2::EventMetaData::setExperiment
void setExperiment(int experiment)
Experiment Setter.
Definition: EventMetaData.h:83
Belle2::DBArray
Class for accessing arrays of objects in the database.
Definition: DBArray.h:36
Belle2::TestHelpers::TempDirCreator
changes working directory into a newly created directory, and removes it (and contents) on destructio...
Definition: TestHelpers.h:57
Belle2::DBObjPtr
Class for accessing objects in the database.
Definition: DBObjPtr.h:31
Belle2::EventDependency
Class for handling changing conditions as a function of event number.
Definition: EventDependency.h:32
Belle2::Unit::T
static const double T
[tesla]
Definition: Unit.h:130
Belle2::StoreObjPtr::construct
bool construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
Definition: StoreObjPtr.h:128
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::StoreObjPtr
Type-safe access to single objects in the data store.
Definition: ParticleList.h:33
Belle2::DBPointer
Class for pointing to an element in an array stored in the database.
Definition: DBPointer.h:34
Belle2::TEST_F
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:65
Belle2::DBStore::Instance
static DBStore & Instance()
Instance of a singleton DBStore.
Definition: DBStore.cc:36
Belle2::IntervalOfValidity::trimOverlap
bool trimOverlap(IntervalOfValidity &iov, bool trimOlder=true)
Remove the overlap between two intervals of validity by shortening one of them.
Definition: IntervalOfValidity.cc:114
Belle2::MagneticField
Magnetic field map.
Definition: MagneticField.h:43
Belle2::EventMetaData::setRun
void setRun(int run)
Run Setter.
Definition: EventMetaData.h:71
Belle2::DBAccessorBase::isValid
bool isValid() const
Check whether a valid object was obtained from the database.
Definition: DBAccessorBase.h:75
Belle2::EventMetaData
Store event, run, and experiment numbers.
Definition: EventMetaData.h:43
Belle2::MagneticFieldComponentConstant
Describe one component of the Geometry.
Definition: MagneticFieldComponentConstant.h:29
Belle2::Database::DBImportQuery
Struct for bulk write queries.
Definition: Database.h:79
Belle2::PayloadFile
A wrapper class for payload files used by the Database and DBStore classes.
Definition: PayloadFile.h:33
Belle2::IntervalOfValidity::empty
bool empty() const
Function that checks whether the validity interval is empty.
Definition: IntervalOfValidity.h:65
Belle2::DBAccessorBase::addCallback
void addCallback(std::function< void(const std::string &)> callback, bool onDestruction=false)
Add a callback method.
Definition: DBAccessorBase.h:108