def test_thread_wrapper_can_be_exited_if_started(self): mock = Mock() tw = ThreadWrapper(lambda x: None) tw.on_stopped(mock) tw.start() tw.exit() self.assertEqual(1, mock.call_count)
def test_callback_is_called_when_thread_stops(self): mock = Mock(return_value=None) tw = ThreadWrapper(lambda _: None) tw.on_stopped(mock) try: for i in range(3): tw.start() tw.stop().wait() self.assertEqual(ThreadWrapper.STOPPED, tw.state) self.assertNotEqual(0, mock.call_count) finally: tw.exit()
def test_exiting_thread_can_not_be_restarted(self): counter = 0 def thread_func(ctx): nonlocal counter counter += 1 while not ctx.stop_requested: ctx.sleep(0.1) def _try_restart(): self.assertRaises(AssertionError, tw.start) tw = ThreadWrapper(thread_func) tw.on_stopped(_try_restart) tw.start() tw.exit() self.assertEqual(1, counter)
def test_stop_callbacks_called_when_thread_fn_exits(self): evt = Event() def test_fn(_): pass tw = ThreadWrapper(test_fn) try: for i in range(1, 3): with self.subTest(f'Run #{i}'): tw.on_stopped(evt.set) evt.clear() tw.start() if not evt.wait(2): self.fail('Thread function has not exited properly') finally: tw.exit()
def test_exception_stops_properly(self): evt = Event() def _dummy_thread_fn(): # wrong signature, results in TypeError pass tw = ThreadWrapper(_dummy_thread_fn) try: for i in range(1, 3): with self.subTest(f'Run #{i}'): tw.on_stopped(evt.set) # set callback first to verify it will be called after clear evt.clear() if not tw.start().wait(2): self.fail('Thread was not started properly') if not evt.wait(2): self.fail('Thread was not stopped properly') finally: tw.exit()