From 039b03aa7575efc7e62f59b1410e85b3a7d7b4d3 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Tue, 16 Jan 2018 16:50:08 -0500 Subject: [PATCH] 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 --- oslotest/output.py | 24 +++++++++++++++---- oslotest/tests/unit/test_base.py | 2 +- oslotest/tests/unit/test_output.py | 24 +++++++++++++++++-- ...lling-output-capture-e47c66bbca4a694a.yaml | 6 +++++ 4 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/controlling-output-capture-e47c66bbca4a694a.yaml diff --git a/oslotest/output.py b/oslotest/output.py index 2ba8e13..668af42 100644 --- a/oslotest/output.py +++ b/oslotest/output.py @@ -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)) diff --git a/oslotest/tests/unit/test_base.py b/oslotest/tests/unit/test_base.py index 9a83601..93c3c52 100644 --- a/oslotest/tests/unit/test_base.py +++ b/oslotest/tests/unit/test_base.py @@ -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') diff --git a/oslotest/tests/unit/test_output.py b/oslotest/tests/unit/test_output.py index 3ed6fdf..b4abcf0 100644 --- a/oslotest/tests/unit/test_output.py +++ b/oslotest/tests/unit/test_output.py @@ -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) diff --git a/releasenotes/notes/controlling-output-capture-e47c66bbca4a694a.yaml b/releasenotes/notes/controlling-output-capture-e47c66bbca4a694a.yaml new file mode 100644 index 0000000..3b50241 --- /dev/null +++ b/releasenotes/notes/controlling-output-capture-e47c66bbca4a694a.yaml @@ -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.