Don't extend the passed in targets

If the caller passes in a value for targets, copy it before extending
it with our own targets.  Because the argument is a reference, our
extending the list here may cause the list to be extended again if
the caller creates another ReadSubunit instance reusing the same
argument.

This caused "ValueError: I/O operation on closed file" errors because
the pares_outcome callback of every previous instantiation was being
called for each new outcome.

Change-Id: Iadd7b063e61590869dbea6ce9db9ffe611fbae0a
This commit is contained in:
James E. Blair 2016-03-02 08:24:15 -08:00
parent 5201d60a09
commit b7b7979cf3
2 changed files with 17 additions and 0 deletions

View File

@ -37,6 +37,8 @@ class ReadSubunit(object):
targets=None):
if targets is None:
targets = []
else:
targets = targets[:]
self.stream_file = stream_file
self.stream = subunit.ByteStreamToStreamResult(self.stream_file)
starts = testtools.StreamResult()

View File

@ -175,3 +175,18 @@ class TestReadSubunit(base.TestCase):
def test_targets_added_to_result(self, ttc_mock):
subunit.ReadSubunit(mock.MagicMock(), targets=['foo'])
self.assertIn('foo', ttc_mock.call_args[0][0])
@mock.patch('testtools.CopyStreamResult')
def test_targets_not_modified(self, ttc_mock):
# A regression test that verifies that the subunit reader does
# not modify the passed in value of targets.
targets = ['foo']
subunit.ReadSubunit(mock.MagicMock(), targets=targets)
ntargets1 = len(ttc_mock.call_args[0][0])
subunit.ReadSubunit(mock.MagicMock(), targets=targets)
ntargets2 = len(ttc_mock.call_args[0][0])
self.assertEqual(ntargets1, ntargets2)
self.assertEqual(targets, ['foo'])