Belle II Software  release-05-02-19
python_dbinterface.py
1 import basf2
2 from basf2 import _constwrapper
3 from b2test_utils import configure_logging_for_tests
4 import ROOT
5 from ROOT import Belle2
6 import multiprocessing
7 import unittest
8 
9 # @cond internal_test
10 
11 
12 class DBInterface(unittest.TestCase):
13  def assertDeath(self, function, *args, **kwargs):
14  """Run function in child process and check if it died. Only way to check for B2FATAL"""
15  ctx = multiprocessing.get_context("fork")
16  p = ctx.Process(target=function, args=args, kwargs=kwargs)
17  p.start()
18  p.join()
19  self.assertNotEqual(p.exitcode, 0)
20 
21  def setUp(self):
22  configure_logging_for_tests()
23 
24  def tearDown(self):
25  Belle2.DBStore.Instance().reset()
26 
27  def test_obj(self):
28  """Test object interface"""
29  bp = Belle2.PyDBObj("BeamParameters")
30  # no such thing, should be invalid
31  self.assertFalse(bp.isValid())
32 
33  # create a mock dbstore entry
34  override_object = Belle2.BeamParameters()
35  vertex = ROOT.TVector3(1, 2, 3)
36  # sadly root does not handle the overloads correctly so we don't have an
37  # overload without the covariance matrix
38  override_object.setVertex(vertex, ROOT.std.vector("double")())
39  Belle2.DBStore.Instance().addConstantOverride("BeamParameters", override_object, False)
40 
41  # must be valid now
42  self.assertTrue(bp.isValid())
43 
44  # make sure type checking works: no access array<->obj or with wrong
45  # type or both
46  self.assertDeath(lambda: Belle2.PyDBObj("BeamParameters", Belle2.PXDSimHit.Class()))
47  self.assertDeath(lambda: Belle2.PyDBArray("BeamParameters"))
48  self.assertDeath(lambda: Belle2.PyDBArray("BeamParameters", Belle2.PXDSimHit.Class()))
49 
50  # check for correct vertex
51  self.assertEqual(bp.obj().getVertex(), vertex)
52  # and also "indirection" should work
53  self.assertEqual(bp.getVertex(), vertex)
54  # and it should be read only
55  with self.assertRaises(AttributeError):
56  # aka no setters
57  bp.obj().setVertex()
58  with self.assertRaises(AttributeError):
59  # random new attributes
60  bp.obj().foo = "bar"
61  with self.assertRaises(AttributeError):
62  # or changing existing ones
63  bp.obj().getVertex = "bar"
64 
65  # but static members like Class should work
66  bp.obj().Class()
67 
68  # make a copy
69  copy = Belle2.BeamParameters(bp.obj())
70  # and compare
71  self.assertEqual(copy, bp.obj())
72 
73  # ok, finally we want to make sure we can convert it back to non-const.
74  # Hopefully nobody finds this :D
75  e = _constwrapper._make_tobject_nonconst(bp.obj())
76  e.setVertex(ROOT.TVector3(0, 0, 0), ROOT.std.vector("double")())
77  self.assertEqual(bp.obj().getVertex(), ROOT.TVector3(0, 0, 0))
78 
79  def test_array(self):
80  bplist = Belle2.PyDBArray("BeamParameterList")
81  # no such thing, should be invalid
82  self.assertFalse(bplist.isValid())
83  # create a mock dbstore entry
84  override_array = ROOT.TClonesArray("Belle2::BeamParameters")
85  override_array.ExpandCreate(3)
86  for i in range(override_array.GetEntriesFast()):
87  override_array[i].setVertex(ROOT.TVector3(i, i, i), ROOT.std.vector("double")())
88 
89  # must be valid now
90  Belle2.DBStore.Instance().addConstantOverride("BeamParameterList", override_array, False)
91 
92  self.assertTrue(bplist.isValid())
93  # make sure type checking works: no access array<->obj or with wrong
94  # type or both
95  self.assertDeath(lambda: Belle2.PyDBArray("BeamParameterList", Belle2.PXDSimHit.Class()))
96  self.assertDeath(lambda: Belle2.PyDBObj("BeamParameterList"))
97  self.assertDeath(lambda: Belle2.PyDBObj("BeamParameterList", Belle2.PXDSimHit.Class()))
98  # make sure the number of entries is consistent
99  self.assertEqual(len(bplist), override_array.GetEntriesFast())
100 
101  # try looping over this and keep track about the number of elements
102  for i, e in enumerate(bplist):
103  # make sure the vertex is what we put in
104  self.assertEqual(int(e.getVertex()[0]), i)
105  # and that it's in general equal to the original one
106  self.assertEqual(e, override_array[i])
107  # and itself :D
108  self.assertEqual(e, bplist[i])
109  # and to a copy
110  copy = Belle2.BeamParameters(e)
111  self.assertEqual(e, copy)
112  # unless we change the copy
113  copy.setVertex(ROOT.TVector3(1, 2, 3), ROOT.std.vector("double")())
114  self.assertNotEqual(e, copy)
115  # and check that modification is blocked
116  with self.assertRaises(AttributeError):
117  e.setVertex(ROOT.TVector3(1, 2, 3), ROOT.std.vector("double")())
118  with self.assertRaises(AttributeError):
119  e.getVertex = "foo"
120  with self.assertRaises(AttributeError):
121  e.foo = "bar"
122 
123  self.assertEqual(i + 1, len(bplist))
124 
125  # make sure item assignment is off
126  with self.assertRaises(TypeError):
127  bplist[0] = Belle2.BeamParameters()
128 
129 
130 if __name__ == "__main__":
131  unittest.main()
132 
133 # @endcond
Belle2::PyDBObj
Class to access a DBObjPtr from Python.
Definition: PyDBObj.h:50
Belle2::DBStore::Instance
static DBStore & Instance()
Instance of a singleton DBStore.
Definition: DBStore.cc:36
Belle2::PyDBArray
Class to access a DB Array from Python.
Definition: PyDBArray.h:43
Belle2::BeamParameters
This class contains the nominal beam parameters and the parameters used for smearing of the primary v...
Definition: BeamParameters.h:33