Belle II Software  release-05-01-25
test_iov.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 # Test the classes to handle iovs
5 
6 import math
7 import random
8 import unittest
9 import doctest
10 from conditions_db.iov import IntervalOfValidity, IoVSet
11 from conditions_db import iov
12 
13 
14 class TestIntervalOfValidity(unittest.TestCase):
15  """Helper class to test an IoV"""
16 
17  def iovify(self, iov):
18  """Helper function to turn a tuple/None/list(tuple) into iov instances"""
19  if isinstance(iov, list):
20  return tuple(IntervalOfValidity(i) for i in iov)
21  elif iov is not None:
22  return IntervalOfValidity(iov)
23  else:
24  return None
25 
26  def test_create(self):
27  """Test that we get errors when creating invalid iovs"""
28  with self.assertRaises(ValueError):
29  iov = IntervalOfValidity(0)
30  with self.assertRaises(ValueError):
31  iov = IntervalOfValidity(-1, 0, 0, 0)
32  with self.assertRaises(ValueError):
33  iov = IntervalOfValidity(0, -1, 0, 0)
34  with self.assertRaises(ValueError):
35  iov = IntervalOfValidity(-1, -1, 0, 0)
36  with self.assertRaises(ValueError):
37  iov = IntervalOfValidity(1, 0, 0, 0)
38  with self.assertRaises(ValueError):
39  iov = IntervalOfValidity(0, 1, 0, 0)
40  with self.assertRaises(ValueError):
41  iov = IntervalOfValidity(10, 0, 7, 4)
42  with self.assertRaises(ValueError):
43  iov = IntervalOfValidity(0, 0, -1, 4)
44  iov = IntervalOfValidity(0, 0, -1, -1)
45  self.assertEqual(iov.final, (math.inf, math.inf))
46  iov = IntervalOfValidity(0, 0, 1, -1)
47  self.assertEqual(iov.final, (1, math.inf))
48  self.assertEqual(IntervalOfValidity(0, 1, 2, 3), IntervalOfValidity((0, 1, 2, 3)))
49 
50  def test_intersection(self):
51  """Test that we can intersect iovs"""
52  iov = IntervalOfValidity
53  for a, b, c in [
54  [(0, 0, 10, 0), (11, 10, 11, 12), None],
55  [(0, 0, 10, 0), (8, 0, 10, 12), (8, 0, 10, 0)],
56  [(0, 0, 0, 0), (0, 0, -1, -1), (0, 0, 0, 0)],
57  [(0, 0, -1, -1), (20, 12, 21, 234), (20, 12, 21, 234)],
58  [(0, 0, 2, -1), (1, 1, 2, 8), (1, 1, 2, 8)],
59  [(1, 2, 2, -1), (0, 0, 2, 8), (1, 2, 2, 8)],
60  [(1, 0, 3, -1), (0, 0, 2, -1), (1, 0, 2, -1)],
61  [(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)],
62  ]:
63  self.assertEqual(iov(a) & iov(b), self.iovify(c), f'{a} & {b} = {c}')
64  self.assertEqual(iov(b) & iov(a), self.iovify(c), f'{a} & {b} = {c}')
65 
66  def test_union(self):
67  """Test that we can calculate the union of iovs"""
68  iov = IntervalOfValidity
69  for a, b, c in [
70  [(0, 0, 10, 0), (11, 10, 11, 12), None],
71  [(0, 0, 10, 0), (8, 0, 10, 12), (0, 0, 10, 12)],
72  [(0, 0, 0, 0), (0, 0, -1, -1), (0, 0, -1, -1)],
73  [(0, 0, -1, -1), (20, 12, 21, 234), (0, 0, -1, -1)],
74  [(0, 0, 2, -1), (1, 1, 2, 8), (0, 0, 2, -1)],
75  [(1, 2, 2, -1), (0, 0, 2, 8), (0, 0, 2, -1)],
76  [(1, 0, 3, -1), (0, 0, 2, -1), (0, 0, 3, -1)],
77  [(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)],
78  [(0, 0, 1, 1), (1, 2, 1, 3), (0, 0, 1, 3)],
79  [(0, 0, 1, 1), (1, 3, 1, 4), None],
80  [(0, 0, 1, -1), (2, 0, 2, 1), (0, 0, 2, 1)],
81  [(0, 0, 1, -1), (2, 0, 2, 1), (0, 0, 2, 1)],
82  [(0, 0, 1, -1), (2, 1, 2, 1), None],
83  [(0, 0, 1, -1), (1, 9999, 2, 1), (0, 0, 2, 1)],
84  ]:
85  self.assertEqual(iov(a) | iov(b), self.iovify(c), f'{a} | {b} = {c}')
86  self.assertEqual(iov(b) | iov(a), self.iovify(c), f'{a} | {b} = {c}')
87 
89  """Test that we can calculate the union starting at run 1 as well"""
90  iov = IntervalOfValidity
91  self.assertEqual(iov(0, 0, 1, -1).union(iov(2, 1, 2, -1)), None)
92  self.assertEqual(iov(0, 0, 1, -1).union(iov(2, 1, 2, -1), True), iov(0, 0, 2, -1))
93 
94  def test_subtract(self):
95  """Test subtracting iovs from another"""
96  iov = IntervalOfValidity
97  for a, b, c, d in [
98  [(0, 0, 10, 0), (11, 10, 11, 12), (0, 0, 10, 0), (11, 10, 11, 12)],
99  [(0, 0, 10, 0), (8, 0, 10, 12), (0, 0, 7, -1), (10, 1, 10, 12)],
100  [(0, 0, 0, 0), (0, 0, -1, -1), None, (0, 1, -1, -1)],
101  [(0, 0, -1, -1), (20, 12, 21, 234), [(0, 0, 20, 11), (21, 235, -1, -1)], None],
102  [(0, 0, 2, -1), (1, 1, 2, 8), [(0, 0, 1, 0), (2, 9, 2, -1)], None],
103  [(1, 2, 2, -1), (0, 0, 2, 8), (2, 9, 2, -1), (0, 0, 1, 1)],
104  [(1, 0, 3, -1), (0, 0, 2, -1), (3, 0, 3, -1), (0, 0, 0, -1)],
105  [(0, 0, -1, -1), (0, 0, -1, -1), None, None],
106  [(0, 0, 1, -1), (0, 0, 1, -1), None, None],
107  [(0, 0, 0, 0), (0, 0, 0, 0), None, None],
108  [(0, 0, 1, -1), (2, 0, 2, -1), (0, 0, 1, -1), (2, 0, 2, -1)],
109  [(11, 0, 12, 86), (0, 0, 11, -1), (12, 0, 12, 86), (0, 0, 10, -1)],
110  ]:
111  self.assertEqual(iov(a) - iov(b), self.iovify(c), f'{a} - {b} = {c}')
112  self.assertEqual(iov(b) - iov(a), self.iovify(d), f'{b} - {a} = {d}')
113 
114 
115 class TestIoVSet(unittest.TestCase):
116  """Helper class to test a set of IoVs"""
117 
118  def test_add(self):
119  """Test adding iovs to a set"""
120  inputs = [
121  [(0, 0, 0, -1), (1, 0, 1, -1), (2, 1, 2, -1), (3, 1, 3, 1), (3, 2, 3, 2), (3, 3, 3, 6), (3, 8, 3, 8)],
122  [(0, i, 0, i) for i in range(0, 100)],
123  [(0, i, 0, i) for i in range(0, 100, 2)],
124  ]
125  results = [
126  [(0, 0, 1, -1), (2, 1, 2, -1), (3, 1, 3, 6), (3, 8, 3, 8)],
127  [(0, 0, 0, 99)],
128  [(0, i, 0, i) for i in range(0, 100, 2)],
129  ]
130 
131  for _ in range(10):
132  for input, output in zip(inputs, results):
133  s = IoVSet()
134  for iov in random.sample(input, len(input)):
135  s.add(iov)
136  output = {IntervalOfValidity(e) for e in output}
137  self.assertEqual(s.iovs, output)
138 
139  def test_remove(self):
140  """Test removing iovs from a set"""
141  s = IoVSet()
142  s.add((0, 0, 0, 100))
143  to_remove = [(0, i, 0, i) for i in range(0, 100, 2)]
144  result = {IntervalOfValidity(0, i, 0, i) for i in range(1, 99, 2)}
145  result.add(IntervalOfValidity(0, 99, 0, 100))
146  for _ in range(10):
147  for iov in random.sample(to_remove, len(to_remove)):
148  s.remove(iov)
149  self.assertEqual(s.iovs, result)
150 
151  def test_intersection(self):
152  """Test intersecting two sets"""
153  iovs = []
154  for i in range(6):
155  iovs.append((i, 0, i+5, -1))
156  result = {IntervalOfValidity(5, 0, 5, -1)}
157  for _ in range(10):
158  a = IoVSet([IntervalOfValidity.always()])
159  for iov in random.sample(iovs, len(iovs)):
160  a = a.intersect(iov)
161  self.assertEqual(a.iovs, result)
162  full = IoVSet(iovs, allow_overlaps=True)
163  self.assertEqual(full.iovs, {IntervalOfValidity(0, 0, 10, -1)})
164 
165 
166 def load_tests(loader, tests, ignore):
167  """Add the doctests to the list of tests"""
168  tests.addTests(doctest.DocTestSuite(iov))
169  return tests
170 
171 if __name__ == "__main__":
172  # test everything
173  unittest.main()
test_iov.TestIoVSet.test_add
def test_add(self)
Definition: test_iov.py:118
test_iov.TestIntervalOfValidity.test_create
def test_create(self)
Definition: test_iov.py:26
conditions_db.iov.IntervalOfValidity
Definition: iov.py:16
test_iov.TestIntervalOfValidity.iovify
def iovify(self, iov)
Definition: test_iov.py:17
test_iov.TestIntervalOfValidity.test_union_startone
def test_union_startone(self)
Definition: test_iov.py:88
test_iov.TestIntervalOfValidity
Definition: test_iov.py:14
conditions_db.iov
Definition: iov.py:1
test_iov.TestIoVSet.test_intersection
def test_intersection(self)
Definition: test_iov.py:151
test_iov.TestIoVSet
Definition: test_iov.py:115
test_iov.TestIntervalOfValidity.test_intersection
def test_intersection(self)
Definition: test_iov.py:50
test_iov.TestIoVSet.test_remove
def test_remove(self)
Definition: test_iov.py:139
conditions_db.iov.IoVSet
Definition: iov.py:269
test_iov.TestIntervalOfValidity.test_subtract
def test_subtract(self)
Definition: test_iov.py:94
test_iov.TestIntervalOfValidity.test_union
def test_union(self)
Definition: test_iov.py:66