def test_parallel_independent_execution(self): class Component(Runnable): def __init__(self, runtime): super(Component, self).__init__() self.runtime = runtime def next(self, state): time.sleep(self.runtime) return state # make sure all branches really run in parallel n = 5 bs = Branches(*[Component(1) for _ in range(n)]) ss = States(*[State() for _ in range(n)]) with tictoc() as tt: bs.run(ss).result() # total runtime has to be smaller that the sum of individual runtimes self.assertTrue(1 <= tt.dt <= 2)
def test_continuity(self): class Fast(Runnable): def next(self, state): time.sleep(0.1) return state.updated(x=state.x + 1) class Slow(Runnable): def next(self, state): time.sleep(0.2) return state.updated(x=state.x + 2) bs = Branches(Slow(), Fast(), Slow()) ss = States(*[State(x=0) for _ in range(3)]) res = bs.run(ss).result() self.assertEqual([s.x for s in res], [2, 1, 2])
def test_composition(self): class A(Runnable): def next(self, state): return state.updated(x=state.x + 1) class B(Runnable): def next(self, state): return state.updated(x=state.x * 7) a, b = A(), B() # single branch b1 = Branches(a) ss = States(State(x=1)) res = b1.run(ss).result() self.assertEqual(b1.branches, (a, )) self.assertEqual(len(res), 1) self.assertEqual(res[0].x, ss[0].x + 1) # two branches, explicit and implicit construction for b2 in [Branches(a, b), a & b]: ss = States(State(x=1), State(x=1)) res = b2.run(ss).result() self.assertEqual(b2.branches, (a, b)) self.assertEqual(len(res), 2) self.assertEqual(res[0].x, ss[0].x + 1) self.assertEqual(res[1].x, ss[1].x * 7) # appending a branch to branches b3 = b2 & a ss = States(*[State(x=1) for _ in range(3)]) res = b3.run(ss).result() self.assertEqual(b3.branches, (a, b, a)) self.assertEqual(len(res), 3) self.assertEqual(res[0].x, ss[0].x + 1) self.assertEqual(res[1].x, ss[1].x * 7) self.assertEqual(res[2].x, ss[2].x + 1) # prepending a branch to branches b4 = b & b2 ss = States(*[State(x=1) for _ in range(3)]) res = b4.run(ss).result() self.assertEqual(b4.branches, (b, a, b)) self.assertEqual(len(res), 3) self.assertEqual(res[0].x, ss[0].x * 7) self.assertEqual(res[1].x, ss[1].x + 1) self.assertEqual(res[2].x, ss[2].x * 7) # invalid type with self.assertRaises(TypeError): b & 1 with self.assertRaises(TypeError): b1 & 1