def test_progress_allows_cancellation(self): test_ready = self._context.event() raised = self._context.event() future = submit_progress(self.executor, syncing_progress, test_ready, raised) listener = ProgressFutureListener(future=future) # Wait until we get the first progress message. self.run_until( listener, "progress_items", lambda listener: len(listener.progress) > 0, ) # Cancel, then allow the background task to continue. future.cancel() test_ready.set() self.wait_until_done(future) self.assertTrue(raised.is_set()) self.assertNoResult(future) self.assertNoException(future) self.assertEqual(listener.states, [WAITING, EXECUTING, CANCELLING, CANCELLED]) self.assertEqual(listener.progress, ["first"])
def test_double_cancellation(self): future = submit_progress(self.executor, progress_reporting_sum, [1, 2]) self.assertTrue(future.cancellable) future.cancel() self.assertFalse(future.cancellable) cancelled = future.cancel() self.assertFalse(cancelled)
def test_cancel_raising_task(self): signal = self._context.event() future = submit_progress(self.executor, wait_then_fail, signal) self.wait_for_state(future, EXECUTING) future.cancel() signal.set() self.wait_until_done(future) self.assertNoResult(future) self.assertNoException(future)
def test_failed_progress(self): # Callable that raises. future = submit_progress(self.executor, bad_progress_reporting_function) listener = ProgressFutureListener(future=future) self.wait_until_done(future) self.assertNoResult(future) self.assertException(future, ZeroDivisionError) self.assertEqual(listener.states, [WAITING, EXECUTING, FAILED]) expected_progress = [(5, 10)] self.assertEqual(listener.progress, expected_progress)
def test_progress(self): # Straightforward case. future = submit_progress(self.executor, progress_reporting_sum, [1, 2, 3]) listener = ProgressFutureListener(future=future) self.wait_until_done(future) self.assertResult(future, 6) self.assertNoException(future) self.assertEqual(listener.states, [WAITING, EXECUTING, COMPLETED]) expected_progress = [(0, 3), (1, 3), (2, 3), (3, 3)] self.assertEqual(listener.progress, expected_progress)
def _count_primes(self, event): self._last_limit = self.limit self.future = submit_progress( self.traits_executor, count_primes_less_than, self.limit, chunk_size=self.chunk_size, ) self.result_message = "Counting ..." dialog = ProgressDialog( title="Counting primes\N{HORIZONTAL ELLIPSIS}", future=self.future, ) dialog.open()
def test_progress_messages_after_cancellation(self): signal = self._context.event() future = submit_progress(self.executor, progress_then_signal, signal) listener = ProgressFutureListener(future=future) # Let the background task run to completion; it will have already sent # progress messages. self.assertTrue(signal.wait(timeout=TIMEOUT)) future.cancel() self.wait_until_done(future) self.assertNoResult(future) self.assertNoException(future) self.assertEqual(listener.states, [WAITING, CANCELLING, CANCELLED]) self.assertEqual(listener.progress, [])
def test_cancellation_before_execution(self): event = self._context.event() future = submit_progress(self.executor, event_set_with_progress, event) listener = ProgressFutureListener(future=future) self.assertTrue(event.wait(timeout=TIMEOUT)) self.assertTrue(future.cancellable) future.cancel() self.wait_until_done(future) self.assertNoResult(future) self.assertNoException(future) self.assertEqual( listener.states, [WAITING, CANCELLING, CANCELLED], )
def test_progress_cleanup_on_cancellation(self): acquired = self._context.event() ready = self._context.event() checkpoint = self._context.event() try: future = submit_progress(self.executor, resource_acquirer, acquired, ready, checkpoint) self.wait_for_state(future, EXECUTING) self.assertTrue(checkpoint.wait(timeout=TIMEOUT)) self.assertTrue(acquired.is_set()) future.cancel() finally: ready.set() self.wait_until_done(future) self.assertFalse(acquired.is_set())
def test_cancellation_before_background_task_starts(self): # Test case where the background task is cancelled before # it even starts executing. event = self._context.event() with self.block_worker_pool(): future = submit_progress(self.executor, event_set_with_progress, event) listener = ProgressFutureListener(future=future) future.cancel() self.wait_until_done(future) self.assertFalse(event.is_set()) self.assertNoResult(future) self.assertNoException(future) self.assertEqual(listener.states, [WAITING, CANCELLING, CANCELLED])
def test_progress_with_progress_keyword_argument(self): with self.assertRaises(TypeError): submit_progress(self.executor, progress_reporting_sum, [1, 2, 3], progress=None)