make the CaptureOutput fixture easier to control

The default behavior of the CaptureOutput fixture relies on
environment variables that many projects may not set. This change
allows the behavior to be controlled by passing parameters to the
fixture when it is initialized.

Change-Id: I110a9062210b0bc92a2f102e3be4558eea8b9f05
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
Doug Hellmann 2018-01-16 16:50:08 -05:00
parent 05397ad224
commit 039b03aa75
4 changed files with 49 additions and 7 deletions

View File

@ -20,12 +20,18 @@ _TRUE_VALUES = ('True', 'true', '1', 'yes')
class CaptureOutput(fixtures.Fixture):
"""Optionally capture the output streams.
The behavior is managed through two environment variables. If
The behavior is managed through arguments to the constructor. The
default behavior is controlled via two environment variables. If
``OS_STDOUT_CAPTURE`` is true then stdout is captured and if
``OS_STDERR_CAPTURE`` is true then stderr is captured.
"True" values include ``True``, ``true``, ``1``, and ``yes``.
:param do_stdout: Whether to capture stdout.
:type do_stdout: bool
:param do_stderr: Whether to capture stderr.
:type do_stderr: bool
.. py:attribute:: stdout
The ``stream`` attribute from a :class:`StringStream` instance
@ -38,18 +44,28 @@ class CaptureOutput(fixtures.Fixture):
"""
def __init__(self):
def __init__(self, do_stdout=None, do_stderr=None):
super(CaptureOutput, self).__init__()
if do_stdout is None:
self.do_stdout = (os.environ.get('OS_STDOUT_CAPTURE')
in _TRUE_VALUES)
else:
self.do_stdout = do_stdout
if do_stderr is None:
self.do_stderr = (os.environ.get('OS_STDERR_CAPTURE')
in _TRUE_VALUES)
else:
self.do_stderr = do_stderr
self.stdout = None
self.stderr = None
def setUp(self):
super(CaptureOutput, self).setUp()
if os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES:
if self.do_stdout:
self._stdout_fixture = fixtures.StringStream('stdout')
self.stdout = self.useFixture(self._stdout_fixture).stream
self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout))
if os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES:
if self.do_stderr:
self._stderr_fixture = fixtures.StringStream('stderr')
self.stderr = self.useFixture(self._stderr_fixture).stream
self.useFixture(fixtures.MonkeyPatch('sys.stderr', self.stderr))

View File

@ -72,7 +72,7 @@ class TestBaseTestCase(testtools.TestCase):
def test_fake_logs_with_log_cap(self, fixture_mock, env_get_mock):
env_get_mock.side_effect = lambda value: {'OS_DEBUG': 0,
'OS_LOG_CAPTURE': 'True'
}[value]
}.get(value)
tc = self.FakeTestCase("test_fake_test")
tc.setUp()
env_get_mock.assert_any_call('OS_LOG_CAPTURE')

View File

@ -23,7 +23,7 @@ import testtools
class CaptureOutputTest(testtools.TestCase):
@mock.patch('os.environ')
def test_disabled(self, mock_env):
def test_disabled_env(self, mock_env):
mock_env.get.return_value = ''
f = output.CaptureOutput()
f.setUp()
@ -33,7 +33,7 @@ class CaptureOutputTest(testtools.TestCase):
self.assertIsNot(sys.stderr, f.stderr)
@mock.patch('os.environ')
def test_enabled(self, mock_env):
def test_enabled_env(self, mock_env):
mock_env.get.return_value = 'True'
f = output.CaptureOutput()
f.setUp()
@ -41,3 +41,23 @@ class CaptureOutputTest(testtools.TestCase):
self.assertIsNotNone(f.stderr)
self.assertIs(sys.stdout, f.stdout)
self.assertIs(sys.stderr, f.stderr)
@mock.patch('os.environ')
def test_disabled_explicit(self, mock_env):
mock_env.get.side_effect = AssertionError('should not be called')
f = output.CaptureOutput(do_stdout=False, do_stderr=False)
f.setUp()
self.assertIsNone(f.stdout)
self.assertIsNone(f.stderr)
self.assertIsNot(sys.stdout, f.stdout)
self.assertIsNot(sys.stderr, f.stderr)
@mock.patch('os.environ')
def test_ensabled_explicit(self, mock_env):
mock_env.get.side_effect = AssertionError('should not be called')
f = output.CaptureOutput(do_stdout=True, do_stderr=True)
f.setUp()
self.assertIsNotNone(f.stdout)
self.assertIsNotNone(f.stderr)
self.assertIs(sys.stdout, f.stdout)
self.assertIs(sys.stderr, f.stderr)

View File

@ -0,0 +1,6 @@
---
features:
- |
Change the API for the CaptureOutput fixture so that tests may
enable it explicitly instead of purely relying on the environment
variables to control it.