From e83d6608b0eb4a64ea419dacacb3701718d18424 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Sun, 6 Aug 2023 15:06:33 -0400 Subject: [PATCH] Don't run safety checks in null/implicit guardrail mode --- fabric/testing/base.py | 7 +++++++ tests/testing.py | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/fabric/testing/base.py b/fabric/testing/base.py index 2ecfdad2c..97a4b4417 100644 --- a/fabric/testing/base.py +++ b/fabric/testing/base.py @@ -180,6 +180,8 @@ def __init__( "You can't give both 'commands' and individual " "Command parameters!" ) # noqa + # Early test for "did user actually request expectations?" + self.guard_only = not (commands or cmd or transfers) # Fill in values self.host = host self.user = user @@ -304,6 +306,11 @@ def sanity_check(self): return self.safety_check() def safety_check(self): + # Short-circuit if user didn't give any expectations; otherwise our + # assumptions below will be inaccurately violated and explode. + if self.guard_only: + return + # Per-session we expect a single transport get transport = self.client.get_transport transport.assert_called_once_with() diff --git a/tests/testing.py b/tests/testing.py index ec0214c36..eb5f96b6e 100644 --- a/tests/testing.py +++ b/tests/testing.py @@ -10,7 +10,7 @@ https://en.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo) """ -from unittest.mock import Mock +from unittest.mock import Mock, patch from fabric import Connection from fabric.testing.base import MockRemote @@ -18,6 +18,26 @@ class MockRemote_: + class mocks_by_default: + @patch("paramiko.transport.socket") + def prevents_real_ssh_connectivity_via_paramiko_guts(self, socket): + with MockRemote(): + cxn = Connection(host="host") + cxn.run("nope", in_stream=False) + # High level mock... + assert isinstance(cxn.client, Mock) + # ...prevented low level connectivity (would have been at least + # one socket.socket() and one .connect() on result of same) + assert not socket.mock_calls + + def does_not_run_safety_checks_when_nothing_really_expected(self): + with MockRemote(): + cxn = Connection(host="host") + assert isinstance(cxn.client, Mock) + # NOTE: no run() or etc! + # Would explode with old behavior due to always asserting transport + # and connect method calls. + class contextmanager_behavior: def calls_safety_and_stop_on_exit_with_try_finally(self): mr = MockRemote()