Skip to content

Commit

Permalink
CI - fix flakiness of stream_manager_test on Windows (#6749)
Browse files Browse the repository at this point in the history
Some tests in cirq_google.engine.stream_manager_test show
non-reproducible TimeoutError failures on CI runners, which
typically go away on retry.  Here we retry them by default.

Fixes #6741
  • Loading branch information
pavoljuhas authored Oct 2, 2024
1 parent ce1d903 commit 95f6a3f
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
3 changes: 2 additions & 1 deletion cirq-core/cirq/testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@

from cirq.testing.order_tester import OrderTester as OrderTester

from cirq.testing.pytest_randomly_utils import (
from cirq.testing.pytest_utils import (
retry_once_after_timeout as retry_once_after_timeout,
retry_once_with_later_random_values as retry_once_with_later_random_values,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,25 @@
from typing import Any, Callable


def retry_once_after_timeout(testfunc: Callable) -> Callable:
"""Marks a test function for one retry if it fails with TimeoutError.
This decorator is intended for test functions which occasionally fail
with TimeoutError.
"""

@functools.wraps(testfunc)
def wrapped_func(*args, **kwargs) -> Any:
try:
return testfunc(*args, **kwargs)
except TimeoutError:
pass
warnings.warn("Retrying in case we have a transitive TimeoutError")
return testfunc(*args, **kwargs)

return wrapped_func


def retry_once_with_later_random_values(testfunc: Callable) -> Callable:
"""Marks a test function for one retry with later random values.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
import cirq


def test_retry_once_after_timeout():
testfunc = Mock(side_effect=[TimeoutError("first call fails"), None])
decoratedfunc = cirq.testing.retry_once_after_timeout(testfunc)
with pytest.warns(UserWarning, match="Retrying.*transitive TimeoutError"):
decoratedfunc()
assert testfunc.call_count == 2


def test_retry_once_with_later_random_values():
testfunc = Mock(side_effect=[AssertionError("first call fails"), None])
decoratedfunc = cirq.testing.retry_once_with_later_random_values(testfunc)
Expand Down
3 changes: 3 additions & 0 deletions cirq-google/cirq_google/engine/stream_manager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import pytest
import google.api_core.exceptions as google_exceptions

import cirq
from cirq_google.engine.asyncio_executor import AsyncioExecutor
from cirq_google.engine.stream_manager import (
_get_retry_request_or_raise,
Expand Down Expand Up @@ -368,6 +369,7 @@ async def test():
],
)
@mock.patch.object(quantum, 'QuantumEngineServiceAsyncClient', autospec=True)
@cirq.testing.retry_once_after_timeout
def test_submit_with_retryable_stream_breakage_expects_get_result_request(
self, client_constructor, error
):
Expand Down Expand Up @@ -407,6 +409,7 @@ async def test():
],
)
@mock.patch.object(quantum, 'QuantumEngineServiceAsyncClient', autospec=True)
@cirq.testing.retry_once_after_timeout
def test_submit_with_non_retryable_stream_breakage_raises_error(
self, client_constructor, error
):
Expand Down

0 comments on commit 95f6a3f

Please sign in to comment.