def test_infinite_loop_stops(self): """An infinite loop can be stopped after 10 iterations.""" class Countdown(Runnable): """Countdown runnable that sets a semaphore on reaching zero.""" def __init__(self): super(Countdown, self).__init__() self.ring = threading.Event() def next(self, state): output = state.updated(cnt=state.cnt - 1) if output.cnt <= 0: self.ring.set() return output countdown = Countdown() loop = LoopWhileNoImprovement(countdown) state = loop.run(State(cnt=10)) # stop only AFTER countdown reaches zero (10 iterations) # timeout in case Countdown failed before setting the flag countdown.ring.wait(timeout=1) loop.stop() self.assertTrue(state.result().cnt <= 0)
def test_dynamic_validation(self): class simo(traits.SIMO, Runnable): def next(self, state): return States(state, state) with self.assertRaises(StateDimensionalityError): LoopWhileNoImprovement(simo()).run(State()).result() with self.assertRaises(StateDimensionalityError): LoopWhileNoImprovement(simo()).run(States()).result()
def test_no_improvement_tries(self): class Inc(Runnable): def next(self, state): return state.updated(cnt=state.cnt + 1) loop = LoopWhileNoImprovement(Inc(), max_tries=10, key=lambda _: 0) state = loop.run(State(cnt=0)).result() self.assertEqual(len(loop.runnable.timers['dispatch.next']), 10) self.assertEqual(state.cnt, 1)
def test_terminate_predicate(self): class Inc(Runnable): def next(self, state): return state.updated(cnt=state.cnt + 1) it = LoopWhileNoImprovement(Inc(), key=lambda state: state.cnt, terminate=lambda key: key >= 3) s = it.run(State(cnt=0)).result() self.assertEqual(s.cnt, 3)
def test_end_of_stream_termination(self): class Inc(Runnable): def next(self, state, **kw): cnt = state.cnt + 1 if cnt > state.maxcnt: raise EndOfStream return state.updated(cnt=cnt) loop = LoopWhileNoImprovement(Inc()) state = loop.run(State(cnt=0, maxcnt=3)).result() self.assertEqual(state.cnt, 3)
def test_validation(self): class simo(Runnable, traits.SIMO): def next(self, state): return States(state, state) with self.assertRaises(TypeError): LoopWhileNoImprovement(simo())