Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: adds exception check for debug_setHead #2217

Merged
merged 17 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions src/ape/pytest/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PytestApeFixtures(ManagerAccessMixin):
# for fixtures, as they are used in output from the command
# `ape test -q --fixture` (`pytest -q --fixture`).

_warned_for_unimplemented_snapshot = False
_supports_snapshot: bool = True
receipt_capture: "ReceiptCapture"

def __init__(self, config_wrapper: ConfigWrapper, receipt_capture: "ReceiptCapture"):
Expand Down Expand Up @@ -86,10 +86,13 @@ def _isolation(self) -> Iterator[None]:
Isolation logic used to implement isolation fixtures for each pytest scope.
When tracing support is available, will also assist in capturing receipts.
"""
try:
snapshot_id = self._snapshot()
except BlockNotFoundError:
snapshot_id = None
snapshot_id = None

if self._supports_snapshot:
try:
snapshot_id = self._snapshot()
except BlockNotFoundError:
self._supports_snapshot = False

if self._track_transactions:
did_yield = False
Expand Down Expand Up @@ -121,21 +124,28 @@ def _snapshot(self) -> Optional[SnapshotID]:
try:
return self.chain_manager.snapshot()
except NotImplementedError:
if not self._warned_for_unimplemented_snapshot:
logger.warning(
"The connected provider does not support snapshotting. "
"Tests will not be completely isolated."
)
self._warned_for_unimplemented_snapshot = True
logger.warning(
"The connected provider does not support snapshotting. "
"Tests will not be completely isolated."
)
# To avoid trying again
self._supports_snapshot = False

return None

@allow_disconnected
def _restore(self, snapshot_id: SnapshotID):
if snapshot_id not in self.chain_manager._snapshots:
return

self.chain_manager.restore(snapshot_id)
try:
self.chain_manager.restore(snapshot_id)
except NotImplementedError:
logger.warning(
"The connected provider does not support snapshotting. "
"Tests will not be completely isolated."
)
# To avoid trying again
self._supports_snapshot = False


class ReceiptCapture(ManagerAccessMixin):
Expand Down
31 changes: 31 additions & 0 deletions tests/functional/test_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,34 @@ def test_isolation(isolation, receipt_capture):
assert next(isolation) is None
with pytest.raises(StopIteration):
next(isolation)


def test_isolation_restore_not_implemented(mocker, networks, fixtures):
isolation = fixtures._isolation()
mock_provider = mocker.MagicMock()
mock_provider.restore.side_effect = NotImplementedError
mock_provider.snapshot.return_value = 123
orig_provider = networks.active_provider
networks.active_provider = mock_provider
fixtures._supports_snapshot = True

try:
_ = next(isolation)
assert mock_provider.snapshot.call_count == 1
with pytest.raises(StopIteration):
_ = next(isolation)

# Is false because of the not-implemented error side-effect.
assert fixtures._supports_snapshot is False

isolation = fixtures._isolation()
_ = next(isolation)
# It does not call snapshot again.
assert mock_provider.snapshot.call_count == 1
with pytest.raises(StopIteration):
_ = next(isolation)

assert mock_provider.snapshot.call_count == 1

finally:
networks.active_provider = orig_provider
Loading