Esempio n. 1
0
def test_notification_manager_no_gui_with_threading():
    """
    Direct test of the notification manager.

    This does not test the integration with the gui, but test that
    exceptions and warnings from threads are correctly captured.
    """
    def _warn():
        time.sleep(0.01)
        warnings.showwarning('this is a warning', UserWarning, '', 0)

    def _raise():
        time.sleep(0.01)
        with pytest.raises(PurposefulException):
            raise PurposefulException("this is an exception")

    if PY38_OR_HIGHER:
        previous_threading_exhook = threading.excepthook

    with notification_manager:
        notification_manager.records.clear()
        # save all of the events that get emitted
        store: List[Notification] = []
        _append = lambda e: store.append(e)  # lambda needed on py3.7  # noqa
        notification_manager.notification_ready.connect(_append)

        # Test exception inside threads
        if PY38_OR_HIGHER:
            # `threading.excepthook` available only for Python >= 3.8
            assert (threading.excepthook ==
                    notification_manager.receive_thread_error)

        exception_thread = threading.Thread(target=_raise)
        exception_thread.start()
        time.sleep(0.02)

        if PY38_OR_HIGHER:
            threading.excepthook(sys.exc_info())
        else:
            sys.excepthook(*sys.exc_info())

        assert len(notification_manager.records) == 1
        assert store[-1].type == 'error'

        # Test warning inside threads
        assert warnings.showwarning == notification_manager.receive_warning
        warning_thread = threading.Thread(target=_warn)
        warning_thread.start()
        time.sleep(0.02)
        assert len(notification_manager.records) == 2
        assert store[-1].type == 'warning'

    # make sure we've restored the threading except hook
    if PY38_OR_HIGHER:
        assert threading.excepthook == previous_threading_exhook

    assert all(isinstance(x, Notification) for x in store)
Esempio n. 2
0
def test_notification_manager_no_gui_with_threading():
    """
    Direct test of the notification manager.

    This does not test the integration with the gui, but test that
    exceptions and warnings from threads are correctly captured.
    """
    def _warn():
        warnings.showwarning('this is a warning', UserWarning, '', 0)

    def _raise():
        with pytest.raises(PurposefulException):
            raise PurposefulException("this is an exception")

    previous_threading_exhook = threading.excepthook

    with notification_manager:
        notification_manager.records.clear()
        # save all of the events that get emitted
        store: List[Notification] = []
        notification_manager.notification_ready.connect(store.append)

        # Test exception inside threads
        assert (
            threading.excepthook == notification_manager.receive_thread_error)

        exception_thread = threading.Thread(target=_raise)
        exception_thread.start()
        exception_thread.join(timeout=DEFAULT_TIMEOUT_SECS)

        try:
            raise ValueError("a")
        except ValueError:
            threading.excepthook(sys.exc_info())

        assert len(notification_manager.records) == 1
        assert store[-1].type == 'error'

        # Test warning inside threads
        assert warnings.showwarning == notification_manager.receive_warning
        warning_thread = threading.Thread(target=_warn)
        warning_thread.start()
        warning_thread.join(timeout=DEFAULT_TIMEOUT_SECS)

        assert len(notification_manager.records) == 2
        assert store[-1].type == 'warning'

    # make sure we've restored the threading except hook
    assert threading.excepthook == previous_threading_exhook

    assert all(isinstance(x, Notification) for x in store)
Esempio n. 3
0
    def test_excepthook_thread_None(self):
        # threading.excepthook called with thread=None: log the thread
        # identifier in this case.
        with support.captured_output("stderr") as stderr:
            try:
                raise ValueError("bug")
            except Exception as exc:
                args = threading.ExceptHookArgs([*sys.exc_info(), None])
                threading.excepthook(args)

        stderr = stderr.getvalue().strip()
        self.assertIn(f'Exception in thread {threading.get_ident()}:\n', stderr)
        self.assertIn('Traceback (most recent call last):\n', stderr)
        self.assertIn('  raise ValueError("bug")', stderr)
        self.assertIn('ValueError: bug', stderr)