Skip to content

Expand the looptime magic to multi-scoped non-running loops #11

@nolar

Description

@nolar

Pytest-asyncio 1.0.0 introduced and enforced the new concept with multiple event loops co-existing at the same time at different scopes. Looptime has slightly adapted to this change, but only to cover the running event loop. However, async fixtures are now excluded from the time magic of looptime now. Only the tests are covered. If there were any sleeps or scheduling happening in fixtures, they will run in true time (wall-clock time).

See these PRs for explanations:

Consider extending the magic of time compaction to other event loops in the test suite.

Implementing this behaviour is extremely challenging on the conceptual level — i.e. understanding the intentions of the declared markers — up to the point that I cannot draft a sample test suite of 2-3 tests and declare such intentions there.


How to declare the intentions for these higher-scoped fixtures?

The higher-scoped fixtures — e.g. session-scoped — is set up only once in one test, the first one to use it. As such, only the scope-targetting settings of that test will be used. The scope-targeting settings of other tests that use this fixture (2nd, 3rd, etc) will be ignored. It will be difficult to guess which tests affect the event loop behaviour, especially in partial test runs.

The looptime configuration should be applied to fixtures themselves, but there are no marks for fixtures in pytest. At all. They are ignored. The marks only work for tests. As a result, we will have to invent our own decorators — the same as e.g. @pytest_asyncio.fixture(…) does. This is not much more difficult that enabling the magic explicitly:

import looptime
import pytest


@pytest.fixture()
def fixt():
    running_loop = cast(looptime.LooptimeEventLoop, asyncio.get_running_loop())
    running_loop.setup_looptime(start=123)
    with running_loop.looptime_enabled():
        await do_things()
        yield
        await do_things()


def test_me(fixt):
    pass

Making such a decorator seems like a good feature, but should be thought thoroughly.


When and how to activate the time compaction?

Auto-enabling the magic since creation will affect all the multi-scoped loops, not just the running loop, which might lead to undesired side effects in event loops indirectly used by many tests (via their fixtures). I am not mentally able to comprehend this kind of test-suite design at this moment.

There might be a way to enable for selected async fixtures in pytest_fixture_setup, but there is no way to enable the magic for the finalizers of these same fixtures (after the yield statement); pytest_fixture_post_finalizer happens after the finalizer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions