Skip to content

Commit

Permalink
Get rid of async-timeout
Browse files Browse the repository at this point in the history
`async-timeout` was used in tests for 2 purposes:

* Extra safety against hanging the test-run if some tests are designed improperly. This function is now taken by `pytest-timeout` (see the previous commit).
* As a part of test design to limit the expectedly infinite or long sleep.

`async-timeout` was convenient to put on the same line as the `pytest.raises(asyncio.TimeoutError)` that it causes. Since `async-timeout` stopped supporting sync context manager protocol, it now requires a separate `async with` and an additional level of indenting — so, it became less useful, or not useful at all. This job is better done by the native `asyncio.wait_for(…, timeout=…)`.

This change will also simplify the tests in the coming refactoring with the fake (simulated) time of event loops.

Signed-off-by: Sergey Vasilyev <nolar@nolar.info>
  • Loading branch information
nolar committed Dec 25, 2021
1 parent ae3411f commit 2964d0b
Show file tree
Hide file tree
Showing 15 changed files with 94 additions and 167 deletions.
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
-e .
aresponses
astpath[xpath]
async-timeout
asynctest
certbuilder
certvalidator
Expand Down
37 changes: 16 additions & 21 deletions tests/handling/indexing/test_blocking_until_indexed.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import asyncio
import logging

import async_timeout
import pytest

from kopf._cogs.aiokits.aiotoggles import ToggleSet
Expand All @@ -22,7 +21,7 @@ async def test_reporting_on_resource_readiness(

operator_indexed = ToggleSet(all)
resource_indexed = await operator_indexed.make_toggle()
async with timer, async_timeout.timeout(0.5) as timeout:
with timer:
await process_resource_event(
lifecycle=all_at_once,
registry=registry,
Expand All @@ -36,7 +35,6 @@ async def test_reporting_on_resource_readiness(
operator_indexed=operator_indexed,
resource_indexed=resource_indexed,
)
assert not timeout.expired
assert timer.seconds < 0.2 # asap, nowait
assert operator_indexed.is_on()
assert set(operator_indexed) == set() # save RAM
Expand All @@ -51,22 +49,20 @@ async def test_blocking_when_operator_is_not_ready(
operator_indexed = ToggleSet(all)
resource_listed = await operator_indexed.make_toggle()
resource_indexed = await operator_indexed.make_toggle()
with pytest.raises(asyncio.TimeoutError):
async with timer, async_timeout.timeout(0.2) as timeout:
await process_resource_event(
lifecycle=all_at_once,
registry=registry,
settings=settings,
resource=resource,
indexers=indexers,
memories=ResourceMemories(),
memobase=Memo(),
raw_event={'type': event_type, 'object': {}},
event_queue=asyncio.Queue(),
operator_indexed=operator_indexed,
resource_indexed=resource_indexed,
)
assert timeout.expired
with pytest.raises(asyncio.TimeoutError), timer:
await asyncio.wait_for(process_resource_event(
lifecycle=all_at_once,
registry=registry,
settings=settings,
resource=resource,
indexers=indexers,
memories=ResourceMemories(),
memobase=Memo(),
raw_event={'type': event_type, 'object': {}},
event_queue=asyncio.Queue(),
operator_indexed=operator_indexed,
resource_indexed=resource_indexed,
), timeout=0.2)
assert 0.2 < timer.seconds < 0.4
assert operator_indexed.is_off()
assert set(operator_indexed) == {resource_listed}
Expand All @@ -85,7 +81,7 @@ async def delayed_readiness(delay: float):
operator_indexed = ToggleSet(all)
resource_listed = await operator_indexed.make_toggle()
resource_indexed = await operator_indexed.make_toggle()
async with timer, async_timeout.timeout(1.0) as timeout:
with timer:
asyncio.create_task(delayed_readiness(0.2))
await process_resource_event(
lifecycle=all_at_once,
Expand All @@ -100,7 +96,6 @@ async def delayed_readiness(delay: float):
operator_indexed=operator_indexed,
resource_indexed=resource_indexed,
)
assert not timeout.expired
assert 0.2 < timer.seconds < 0.4
assert operator_indexed.is_on()
assert set(operator_indexed) == {resource_listed}
Expand Down
20 changes: 9 additions & 11 deletions tests/k8s/test_watching_with_freezes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import asyncio
import logging

import async_timeout
import pytest

from kopf._cogs.aiokits.aiotoggles import ToggleSet
Expand All @@ -15,15 +14,14 @@ async def test_pausing_is_ignored_if_turned_off(
operator_paused = ToggleSet(any)
await operator_paused.make_toggle(False)

async with timer, async_timeout.timeout(0.5) as timeout:
with timer:
async with streaming_block(
resource=resource,
namespace=namespace,
operator_paused=operator_paused,
):
pass

assert not timeout.expired
assert timer.seconds < 0.2 # no waits, exits as soon as possible
assert_logs([], prohibited=[
r"Pausing the watch-stream for",
Expand All @@ -38,16 +36,17 @@ async def test_pausing_waits_forever_if_not_resumed(
operator_paused = ToggleSet(any)
await operator_paused.make_toggle(True)

with pytest.raises(asyncio.TimeoutError):
async with timer, async_timeout.timeout(0.5) as timeout:
async with streaming_block(
async def do_it():
async with streaming_block(
resource=resource,
namespace=namespace,
operator_paused=operator_paused,
):
pass
):
pass

with pytest.raises(asyncio.TimeoutError), timer:
await asyncio.wait_for(do_it(), timeout=0.5)

assert timeout.expired
assert timer.seconds >= 0.5
assert_logs([
r"Pausing the watch-stream for",
Expand All @@ -67,7 +66,7 @@ async def delayed_resuming(delay: float):
await asyncio.sleep(delay)
await conflicts_found.turn_to(False)

async with timer, async_timeout.timeout(1.0) as timeout:
with timer:
asyncio.create_task(delayed_resuming(0.2))
async with streaming_block(
resource=resource,
Expand All @@ -76,7 +75,6 @@ async def delayed_resuming(delay: float):
):
pass

assert not timeout.expired
assert timer.seconds >= 0.2
assert timer.seconds <= 0.5
assert_logs([
Expand Down
11 changes: 4 additions & 7 deletions tests/observation/test_processing_of_namespaces.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import asyncio

import async_timeout
import pytest

from kopf._cogs.structs.bodies import RawBody, RawEvent
Expand All @@ -19,11 +18,9 @@ async def delayed_injection(delay: float):

task = asyncio.create_task(delayed_injection(0))
with pytest.raises(asyncio.TimeoutError):
async with async_timeout.timeout(0.1) as timeout:
async with insights.revised:
await insights.revised.wait()
async with insights.revised:
await asyncio.wait_for(insights.revised.wait(), timeout=0.1)
await task
assert timeout.expired
assert not insights.namespaces


Expand All @@ -38,7 +35,7 @@ async def delayed_injection(delay: float):
insights=insights, raw_event=e1, namespaces=['ns*'])

task = asyncio.create_task(delayed_injection(0.1))
async with timer, async_timeout.timeout(1):
with timer:
async with insights.revised:
await insights.revised.wait()
await task
Expand All @@ -58,7 +55,7 @@ async def delayed_injection(delay: float):
insights=insights, raw_event=e1, namespaces=['ns*'])

task = asyncio.create_task(delayed_injection(0.1))
async with timer, async_timeout.timeout(1):
with timer:
async with insights.revised:
await insights.revised.wait()
await task
Expand Down
17 changes: 7 additions & 10 deletions tests/observation/test_processing_of_resources.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import asyncio

import aiohttp.web
import async_timeout
import pytest

import kopf
Expand Down Expand Up @@ -126,7 +125,7 @@ async def delayed_injection(delay: float):
insights=insights, raw_event=e1, registry=registry, settings=settings)

task = asyncio.create_task(delayed_injection(0.1))
async with timer, async_timeout.timeout(1.0):
with timer:
async with insights.revised:
await insights.revised.wait()
await task
Expand All @@ -148,11 +147,9 @@ async def delayed_injection(delay: float):

task = asyncio.create_task(delayed_injection(0))
with pytest.raises(asyncio.TimeoutError):
async with async_timeout.timeout(0.1) as timeout:
async with insights.revised:
await insights.revised.wait()
async with insights.revised:
await asyncio.wait_for(insights.revised.wait(), timeout=0.1)
await task
assert timeout.expired
assert not insights.indexed_resources
assert not insights.watched_resources
assert not insights.webhook_resources
Expand All @@ -173,7 +170,7 @@ async def delayed_injection(delay: float):
insights=insights, raw_event=e1, registry=registry, settings=settings)

task = asyncio.create_task(delayed_injection(0.1))
async with timer, async_timeout.timeout(1.0):
with timer:
async with insights.revised:
await insights.revised.wait()
await task
Expand All @@ -198,7 +195,7 @@ async def delayed_injection(delay: float):
insights=insights, raw_event=e1, registry=registry, settings=settings)

task = asyncio.create_task(delayed_injection(0.1))
async with timer, async_timeout.timeout(1.0):
with timer:
async with insights.revised:
await insights.revised.wait()
await task
Expand All @@ -222,7 +219,7 @@ async def delayed_injection(delay: float):
insights=insights, raw_event=e1, registry=registry, settings=settings)

task = asyncio.create_task(delayed_injection(0.1))
async with timer, async_timeout.timeout(1.0):
with timer:
async with insights.revised:
await insights.revised.wait()
await task
Expand All @@ -244,7 +241,7 @@ async def delayed_injection(delay: float):
insights=insights, raw_event=e1, registry=registry, settings=settings)

task = asyncio.create_task(delayed_injection(0.1))
async with timer, async_timeout.timeout(1.0):
with timer:
await insights.backbone.wait_for(NAMESPACES)
await task
assert 0.1 < timer.seconds < 1.0
Expand Down
5 changes: 1 addition & 4 deletions tests/posting/test_poster.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import asyncio
import logging

import async_timeout
import pytest
from asynctest import call

from kopf import event, exception, info, warn
from kopf._cogs.structs.references import Backbone, Resource
Expand Down Expand Up @@ -45,8 +43,7 @@ def _cancel(*args, **kwargs):

# A way to cancel a `while True` cycle by timing, even if the routines are not called.
with pytest.raises(asyncio.CancelledError):
async with async_timeout.timeout(0.5):
await poster(event_queue=event_queue, backbone=backbone, settings=settings)
await poster(event_queue=event_queue, backbone=backbone, settings=settings)

assert post.call_count == 2
assert post.call_args_list[0][1]['url'] == '/api/v1/namespaces/ns1/events'
Expand Down
13 changes: 3 additions & 10 deletions tests/primitives/test_conditions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import asyncio

import async_timeout
import pytest

from kopf._cogs.aiokits.aiobindings import condition_chain
Expand All @@ -11,14 +10,9 @@ async def test_no_triggering():
target = asyncio.Condition()
task = asyncio.create_task(condition_chain(source, target))
try:

with pytest.raises(asyncio.TimeoutError):
async with async_timeout.timeout(0.1) as timeout:
async with target:
await target.wait()

assert timeout.expired

async with target:
await asyncio.wait_for(target.wait(), timeout=0.1)
finally:
task.cancel()
await asyncio.wait([task])
Expand All @@ -36,11 +30,10 @@ async def delayed_trigger():

event_loop.call_later(0.1, asyncio.create_task, delayed_trigger())

async with timer, async_timeout.timeout(10) as timeout:
with timer:
async with target:
await target.wait()

assert not timeout.expired
assert 0.1 <= timer.seconds <= 0.2

finally:
Expand Down
22 changes: 6 additions & 16 deletions tests/primitives/test_containers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import asyncio

import async_timeout
import pytest

from kopf._cogs.aiokits.aiovalues import Container
Expand All @@ -9,9 +8,7 @@
async def test_empty_by_default():
container = Container()
with pytest.raises(asyncio.TimeoutError):
async with async_timeout.timeout(0.1) as timeout:
await container.wait()
assert timeout.expired
await asyncio.wait_for(container.wait(), timeout=0.1)


async def test_does_not_wake_up_when_reset(event_loop, timer):
Expand All @@ -23,20 +20,16 @@ async def reset_it():
event_loop.call_later(0.05, asyncio.create_task, reset_it())

with pytest.raises(asyncio.TimeoutError):
async with async_timeout.timeout(0.1) as timeout:
await container.wait()

assert timeout.expired
await asyncio.wait_for(container.wait(), timeout=0.1)


async def test_wakes_up_when_preset(event_loop, timer):
container = Container()
await container.set(123)

async with timer, async_timeout.timeout(10) as timeout:
with timer:
result = await container.wait()

assert not timeout.expired
assert timer.seconds <= 0.1
assert result == 123

Expand All @@ -49,10 +42,9 @@ async def set_it():

event_loop.call_later(0.1, asyncio.create_task, set_it())

async with timer, async_timeout.timeout(10) as timeout:
with timer:
result = await container.wait()

assert not timeout.expired
assert 0.1 <= timer.seconds <= 0.2
assert result == 123

Expand All @@ -67,13 +59,12 @@ async def set_it(v):
event_loop.call_later(0.2, asyncio.create_task, set_it(234))

values = []
async with timer, async_timeout.timeout(10) as timeout:
with timer:
async for value in container.as_changed():
values.append(value)
if value == 234:
break

assert not timeout.expired
assert 0.2 <= timer.seconds <= 0.3
assert values == [123, 234]

Expand All @@ -83,11 +74,10 @@ async def test_iterates_when_preset(event_loop, timer):
await container.set(123)

values = []
async with timer, async_timeout.timeout(10) as timeout:
with timer:
async for value in container.as_changed():
values.append(value)
break

assert not timeout.expired
assert timer.seconds <= 0.1
assert values == [123]
Loading

0 comments on commit 2964d0b

Please sign in to comment.