Example #1
0
async def test_composite_assertion():
    """Test an assertion that calls sub-assertions.

    In early versions of assertion implementation, each `async for`
    with a given `stream` created a new generator, but all generators
    shared the internal state of the underlying `Assertion` object
    in an incorrect way, which could lead to one `async for` seeing
    the same event the previous `async for` have seen already. For example,
    in the following scenario the event `1` would be seen by three times,
    by each invocation of `assert_1`.
    """
    events = []

    async def assert_1(stream):
        async for e in stream:
            if e == 1:
                return True
        return False

    async def assert_111(stream):
        one = await assert_1(stream)
        two = await assert_1(stream)
        three = await assert_1(stream)
        return one, two, three

    assertion = Assertion(events, assert_111)
    assertion.start()

    events.append(1)
    await asyncio.sleep(0.1)
    await assertion.update_events()
    await asyncio.sleep(0.1)
    await assertion.update_events(events_ended=True)

    assert assertion.result() == (True, False, False)
Example #2
0
async def test_eventually_with_timeout(timeout, accept, result_predicate):
    """Test whether the `eventually` operator handles timeouts correctly."""
    events = []

    if timeout is not None:

        async def func(stream):
            return await eventually(stream, lambda e: e % 2 == 0, timeout=timeout)

    else:

        async def func(stream):
            return await eventually(stream, lambda e: e % 2 == 0)

    assertion = Assertion(events, func)
    assertion.start()

    for n in [1, 3, 4, 5]:
        await asyncio.sleep(0.1)
        events.append(n)
        await assertion.update_events()
    await assertion.update_events(events_ended=True)

    assert assertion.accepted is accept
    try:
        result = assertion.result()
    except Exception as error:
        result = error
    assert result_predicate(result)
Example #3
0
async def test_assertion_consumes_three():
    """Test if an assertion keeps state when events tickle in."""

    events = []

    async def func(stream):
        count = 0
        sum = 0
        async for e in stream:
            sum += e
            count += 1
            if count == 3:
                return sum

    assertion = Assertion(events, func)
    assertion.start()
    events.append(1)
    await assertion.update_events()
    assert not assertion.done

    events.append(2)
    await assertion.update_events()
    assert not assertion.done

    events.append(3)
    await assertion.update_events()
    assert assertion.accepted
    assert assertion.result() == 6
Example #4
0
async def test_past_events():
    """Test if `past_events` matches the events given to this assertion before."""

    events = []

    async def func(stream):

        _events = []

        async for e in stream:
            _events.append(e)
            assert _events == stream.past_events

        return _events

    assertion = Assertion(events, func)
    assertion.start()

    for n in range(3, 0, -1):
        events.append(n)
        await assertion.update_events()
    await assertion.update_events(events_ended=True)

    assert assertion.accepted
    assert assertion.result() == [3, 2, 1]
Example #5
0
async def test_while_eventually(timeout, accept):
    """Test an assertion that calls `eventually` in a `while` loop.

    This test used to fail when the implementation of assertions was not
    guaranteed to update the assertion state (in particular, set it as
    done) before returning from the `update_events()` method.
    """
    events = []

    async def func(stream):
        while not stream.events_ended:
            try:
                await eventually(stream, lambda e: e % 2 == 0, timeout=timeout)
            except asyncio.TimeoutError:
                raise AssertionError("Timeout")
        return True

    assertion = Assertion(events, func)
    assertion.start()

    for n in range(5):
        await asyncio.sleep(0.2)
        events.append(n)
        await assertion.update_events()
    await asyncio.sleep(0.2)
    await assertion.update_events(events_ended=True)

    assert assertion.done
    assert assertion.accepted == accept
Example #6
0
async def test_start_twice_raises():
    """Test whether starting an already started assertion raises a `RuntimeError`."""
    events = []

    async def func(_stream):
        return

    assertion = Assertion(events, func)
    assertion.start()
    with pytest.raises(RuntimeError):
        assertion.start()
Example #7
0
async def test_wait_for_result_already_done():
    """Test that `wait_for_result()` returns the result of a done assertion."""

    async def func(_stream):
        return 6

    assertion = Assertion([], func)
    assertion.start()

    result = await assertion.wait_for_result()
    assert result == 6
Example #8
0
    def add_assertion(
        self,
        assertion_func: AssertionFunction[E],
        name: Optional[str] = None,
        log_level: LogLevel = logging.INFO,
    ) -> Assertion:
        """Add an assertion function to this monitor."""

        assertion = Assertion(self._events, assertion_func, name=name)
        assertion.start()
        self._logger.debug("Assertion '%s' started", assertion.name)
        self.assertions[assertion] = log_level
        return assertion
Example #9
0
async def test_wait_for_result_timeout_failure():
    """Test that `wait_for_result` with timeout raises the assertion's exception."""

    async def func(stream):
        await asyncio.sleep(0.1)
        raise AssertionError()

    assertion = Assertion([], func)
    assertion.start()

    assert not assertion.done
    with pytest.raises(AssertionError):
        await assertion.wait_for_result(timeout=1.0)
Example #10
0
async def test_wait_for_result_success():
    """Test that `wait_for_result()` waits for the assertion's result."""

    async def func(_stream):
        await asyncio.sleep(0.1)
        return 7

    assertion = Assertion([], func)
    assertion.start()

    assert not assertion.done
    result = await assertion.wait_for_result()
    assert result == 7
Example #11
0
async def test_wait_for_result_timeout_success():
    """Test that `wait_for_result` with timeout returns the assertion's result."""

    async def func(_stream):
        await asyncio.sleep(0.1)
        return 8

    assertion = Assertion([], func)
    assertion.start()

    assert not assertion.done
    result = await assertion.wait_for_result(timeout=1.0)
    assert result == 8
Example #12
0
async def test_assertion_consumes_one():
    """Test if an assertion will consume all given events."""

    events = []

    async def func(stream):
        async for e in stream:
            return e

    assertion = Assertion(events, func)
    assertion.start()
    events.append(2)
    await assertion.update_events()
    assert assertion.accepted
    assert assertion.result() == 2
Example #13
0
async def test_assertion_fails_on_event():
    """Test if an assertion is marked as failed when the result is an AssertionError."""

    events = [1]

    async def func(stream):
        async for _ in stream:
            assert False, "No events expected"

    assertion = Assertion(events, func)
    assertion.start()
    await assertion.update_events()
    assert assertion.failed
    with pytest.raises(AssertionError):
        _ = assertion.result()
Example #14
0
async def test_assertion_end_events():
    """Test if an assertion is accepted and done when no events are passed."""

    events = []

    async def func(stream):
        async for _ in stream:
            raise AssertionError("No events expected")
        return 44

    assertion = Assertion(events, func)
    assertion.start()
    assert not assertion.done

    await assertion.update_events(events_ended=True)
    assert assertion.accepted
    assert assertion.result() == 44
Example #15
0
async def test_result_raises_invalidstateerror():
    """Test that `result()` raises an exception when the result is not ready."""

    async def func(stream):
        async for e in stream:
            if e == 1:
                return

    assertion = Assertion([], func)
    with pytest.raises(asyncio.InvalidStateError):
        assertion.result()

    assertion.start()
    with pytest.raises(asyncio.InvalidStateError):
        assertion.result()

    # In order not to leave assertion's task pending
    await assertion.update_events(events_ended=True)
Example #16
0
async def test_assertion_end_events_raises():
    """Test if an assertion raises when events_ended and the assertion is not met."""

    events = []

    async def func(stream):
        async for _ in stream:
            return
        raise AssertionError("Events expected")

    assertion = Assertion(events, func)
    assertion.start()
    assert not assertion.done

    await assertion.update_events(events_ended=True)
    assert assertion.failed
    with pytest.raises(AssertionError):
        assertion.result()
Example #17
0
async def test_wait_for_result_timeout_raises():
    """Test that `wait_for_result` with timeout raises TimeoutError."""

    async def func(stream):
        await asyncio.sleep(1.0)
        return 9

    assertion = Assertion([], func)
    assertion.start()

    assert not assertion.done
    with pytest.raises(asyncio.TimeoutError):
        await assertion.wait_for_result(timeout=0.1)

    # Assertion is cancelled and should fail with AssertionError("Assertion cancelled")
    assert assertion.failed
    with pytest.raises(AssertionError) as error:
        _ = assertion.result()
    assert "Assertion cancelled" in str(error)
Example #18
0
async def test_events_ended_not_set():
    """Test if events_ended is not set when the assertion breaks out of its loop."""

    events = [1]

    async def func(stream):

        assert not stream.events_ended

        async for _ in stream:
            assert not stream.events_ended
            break

        assert not stream.events_ended

    assertion = Assertion(events, func)
    assertion.start()
    await assertion.update_events()
    assert assertion.done
Example #19
0
async def test_events_ended_set():
    """Test if events_ended is set properly throughout the lifetime of an assertion."""

    events = [1]

    async def func(stream):

        assert not stream.events_ended

        async for _ in stream:
            assert not stream.events_ended

        assert stream.events_ended

    assertion = Assertion(events, func)
    assertion.start()
    await assertion.update_events()
    await assertion.update_events()
    await assertion.update_events(events_ended=True)
    assert assertion.done
Example #20
0
async def test_assertion_consumes_all():
    """Test if an assertion comsumes all events given to it."""

    events = []

    async def func(stream):
        _events = []
        async for e in stream:
            _events.append(e)
        return _events

    assertion = Assertion(events, func)
    assertion.start()

    for n in range(10):
        events.append(n)
        await assertion.update_events()

    await assertion.update_events(events_ended=True)
    assert assertion.done
    assert assertion.result() == events
Example #21
0
async def test_assertion_accept_immediately():
    """Test if an assertion passes when it accepts immediately."""

    events = []

    async def func(_stream):
        return 43

    assertion = Assertion(events, func)
    task = assertion.start()
    await task
    assert assertion.done
    assert assertion.accepted
    assert assertion.result() == 43
Example #22
0
async def test_assertion_accept_with_delay():
    """Test if an assertion passes when it accepts after a delay."""

    events = []

    async def func(_stream):
        await asyncio.sleep(0.2)
        return 43

    assertion = Assertion(events, func)
    task = assertion.start()
    await task
    assert assertion.done
    assert assertion.accepted
    assert assertion.result() == 43
Example #23
0
async def test_assertion_fail_immediately():
    """Test if an assertion raises AND finishes, when it fails immediately."""

    events = []

    async def func(_stream):
        raise AssertionError()

    assertion = Assertion(events, func)
    task = assertion.start()
    # We do `await` here which causes the exception thrown inside the assertion
    # to be re-thrown:
    with pytest.raises(AssertionError):
        await task
    assert assertion.done
    assert assertion.failed