Hello community, here is the log from the commit of package python-python-subunit for openSUSE:Factory checked in at 2014-01-17 11:08:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-python-subunit (Old) and /work/SRC/openSUSE:Factory/.python-python-subunit.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-subunit" Changes: -------- --- /work/SRC/openSUSE:Factory/python-python-subunit/python-python-subunit.changes 2013-09-03 22:04:06.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-python-subunit.new/python-python-subunit.changes 2014-01-23 15:54:39.000000000 +0100 @@ -1,0 +2,15 @@ +Mon Jan 13 13:28:11 UTC 2014 - dmuel...@suse.com + +- update to 0.0.16: + * Perl files should now honour perl system config. + * Python 3.1 and 3.2 have an inconsistent memoryview implementation which + required a workaround for NUL byte detection. (Robert Collins, #1216246) + * The test suite was failing 6 tests due to testtools changing it's output + formatting of exceptions. (Robert Collins) + * V2 parser errors now set appropriate mime types for the encapsulated packet + data and the error message. (Robert Collins) + * When tests fail to import ``python subunit.run -l ...`` will now write a + subunit file attachment listing the failed imports and exit 2 +- Fix package requires + +------------------------------------------------------------------- Old: ---- python-subunit-0.0.15.tar.gz New: ---- python-subunit-0.0.16.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-python-subunit.spec ++++++ --- /var/tmp/diff_new_pack.qCEIS2/_old 2014-01-23 15:54:40.000000000 +0100 +++ /var/tmp/diff_new_pack.qCEIS2/_new 2014-01-23 15:54:40.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-python-subunit # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: python-python-subunit -Version: 0.0.15 +Version: 0.0.16 Release: 0 Summary: Python implementation of subunit test streaming protocol License: Apache-2.0 or BSD-3-Clause @@ -27,6 +27,7 @@ BuildRequires: python-devel BuildRequires: python-nose Requires: python-extras +Requires: python-testtools >= 0.9.34 BuildRoot: %{_tmppath}/%{name}-%{version}-build %if 0%{?suse_version} && 0%{?suse_version} <= 1110 %{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} ++++++ python-subunit-0.0.15.tar.gz -> python-subunit-0.0.16.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/NEWS new/python-subunit-0.0.16/NEWS --- old/python-subunit-0.0.15/NEWS 2013-08-24 16:09:29.000000000 +0200 +++ new/python-subunit-0.0.16/NEWS 2013-11-30 03:04:01.000000000 +0100 @@ -5,6 +5,35 @@ NEXT (In development) --------------------- +0.0.16 +------ + +BUG FIXES +~~~~~~~~~ + +* Perl files should now honour perl system config. + (Benedikt Morbach, #1233198) + +* Python 3.1 and 3.2 have an inconsistent memoryview implementation which + required a workaround for NUL byte detection. (Robert Collins, #1216246) + +* The test suite was failing 6 tests due to testtools changing it's output + formatting of exceptions. (Robert Collins) + +* V2 parser errors now set appropriate mime types for the encapsulated packet + data and the error message. (Robert Collins) + +* When tests fail to import ``python subunit.run -l ...`` will now write a + subunit file attachment listing the failed imports and exit 2, rather than + listing the stub objects from the importer and exiting 0. + (Robert Collins, #1245672) + +IMPROVEMENTS +~~~~~~~~~~~~ + +* Most filters will now accept a file path argument instead of only reading + from stdin. (Robert Collins, #409206) + 0.0.15 ------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/PKG-INFO new/python-subunit-0.0.16/PKG-INFO --- old/python-subunit-0.0.15/PKG-INFO 2013-08-24 16:12:08.000000000 +0200 +++ new/python-subunit-0.0.16/PKG-INFO 2013-11-30 10:17:05.000000000 +0100 @@ -1,6 +1,6 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.0 Name: python-subunit -Version: 0.0.15 +Version: 0.0.16 Summary: Python implementation of subunit test streaming protocol Home-page: http://launchpad.net/subunit Author: Robert Collins @@ -14,7 +14,7 @@ license at the users choice. A copy of both licenses are available in the project source as Apache-2.0 and BSD. You may not use this file except in compliance with one of these two licences. - + Unless required by applicable law or agreed to in writing, software distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -98,7 +98,7 @@ subunit via the ``subunit.run`` module:: $ python -m subunit.run mypackage.tests.test_suite - + For more information on the Python support Subunit offers , please see ``pydoc subunit``, or the source in ``python/subunit/`` @@ -351,7 +351,7 @@ Version 1 (and 1.1) =================== - Version 1 (and 1.1) are mostly human readable protocols. + Version 1 (and 1.1) are mostly human readable protocols. Sample subunit wire contents ---------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/README new/python-subunit-0.0.16/README --- old/python-subunit-0.0.15/README 2013-04-08 12:28:36.000000000 +0200 +++ new/python-subunit-0.0.16/README 2013-11-25 02:50:04.000000000 +0100 @@ -6,7 +6,7 @@ license at the users choice. A copy of both licenses are available in the project source as Apache-2.0 and BSD. You may not use this file except in compliance with one of these two licences. - + Unless required by applicable law or agreed to in writing, software distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -90,7 +90,7 @@ subunit via the ``subunit.run`` module:: $ python -m subunit.run mypackage.tests.test_suite - + For more information on the Python support Subunit offers , please see ``pydoc subunit``, or the source in ``python/subunit/`` @@ -343,7 +343,7 @@ Version 1 (and 1.1) =================== -Version 1 (and 1.1) are mostly human readable protocols. +Version 1 (and 1.1) are mostly human readable protocols. Sample subunit wire contents ---------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/filters/subunit-1to2 new/python-subunit-0.0.16/filters/subunit-1to2 --- old/python-subunit-0.0.15/filters/subunit-1to2 2013-04-08 12:28:36.000000000 +0200 +++ new/python-subunit-0.0.16/filters/subunit-1to2 2013-08-25 11:55:01.000000000 +0200 @@ -22,7 +22,7 @@ from testtools import ExtendedToStreamDecorator from subunit import StreamResultToBytes -from subunit.filters import run_tests_from_stream +from subunit.filters import find_stream, run_tests_from_stream def make_options(description): @@ -33,7 +33,7 @@ def main(): parser = make_options(__doc__) (options, args) = parser.parse_args() - run_tests_from_stream(sys.stdin, + run_tests_from_stream(find_stream(sys.stdin, args), ExtendedToStreamDecorator(StreamResultToBytes(sys.stdout))) sys.exit(0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/filters/subunit-2to1 new/python-subunit-0.0.16/filters/subunit-2to1 --- old/python-subunit-0.0.15/filters/subunit-2to1 2013-04-08 12:28:36.000000000 +0200 +++ new/python-subunit-0.0.16/filters/subunit-2to1 2013-08-25 11:55:39.000000000 +0200 @@ -22,7 +22,7 @@ from testtools import StreamToExtendedDecorator from subunit import ByteStreamToStreamResult, TestProtocolClient -from subunit.filters import run_tests_from_stream +from subunit.filters import find_stream, run_tests_from_stream def make_options(description): @@ -33,7 +33,8 @@ def main(): parser = make_options(__doc__) (options, args) = parser.parse_args() - case = ByteStreamToStreamResult(sys.stdin, non_subunit_name='stdout') + case = ByteStreamToStreamResult( + find_stream(sys.stdin, args), non_subunit_name='stdout') result = StreamToExtendedDecorator(TestProtocolClient(sys.stdout)) # What about stdout chunks? result.startTestRun() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/filters/subunit-filter new/python-subunit-0.0.16/filters/subunit-filter --- old/python-subunit-0.0.15/filters/subunit-filter 2013-04-08 12:28:36.000000000 +0200 +++ new/python-subunit-0.0.16/filters/subunit-filter 2013-08-25 11:58:23.000000000 +0200 @@ -38,7 +38,7 @@ StreamResultToBytes, read_test_list, ) -from subunit.filters import filter_by_result +from subunit.filters import filter_by_result, find_stream from subunit.test_results import ( and_predicates, make_tag_filter, @@ -156,7 +156,8 @@ output_path=None, passthrough=(not options.no_passthrough), forward=False, - protocol_version=2) + protocol_version=2, + input_stream=find_stream(sys.stdin, args)) sys.exit(0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/filters/subunit-ls new/python-subunit-0.0.16/filters/subunit-ls --- old/python-subunit-0.0.15/filters/subunit-ls 2013-04-08 12:28:36.000000000 +0200 +++ new/python-subunit-0.0.16/filters/subunit-ls 2013-08-25 12:05:03.000000000 +0200 @@ -24,7 +24,7 @@ StreamSummary) from subunit import ByteStreamToStreamResult -from subunit.filters import run_tests_from_stream +from subunit.filters import find_stream, run_tests_from_stream from subunit.test_results import ( CatFiles, TestIdPrintingResult, @@ -41,7 +41,8 @@ parser.add_option("--no-passthrough", action="store_true", help="Hide all non subunit input.", default=False, dest="no_passthrough") (options, args) = parser.parse_args() -test = ByteStreamToStreamResult(sys.stdin, non_subunit_name="stdout") +test = ByteStreamToStreamResult( + find_stream(sys.stdin, args), non_subunit_name="stdout") result = TestIdPrintingResult(sys.stdout, options.times, options.exists) if not options.no_passthrough: result = StreamResultRouter(result) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/filters/subunit-tags new/python-subunit-0.0.16/filters/subunit-tags --- old/python-subunit-0.0.15/filters/subunit-tags 2009-12-15 10:58:23.000000000 +0100 +++ new/python-subunit-0.0.16/filters/subunit-tags 2013-08-25 12:07:56.000000000 +0200 @@ -23,4 +23,5 @@ import sys from subunit import tag_stream + sys.exit(tag_stream(sys.stdin, sys.stdout, sys.argv[1:])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/filters/subunit2gtk new/python-subunit-0.0.16/filters/subunit2gtk --- old/python-subunit-0.0.15/filters/subunit2gtk 2013-04-08 12:28:36.000000000 +0200 +++ new/python-subunit-0.0.16/filters/subunit2gtk 2013-08-25 12:11:18.000000000 +0200 @@ -142,7 +142,7 @@ def stopTest(self, test): super(GTKTestResult, self).stopTest(test) - gobject.idle_add(self._stopTest) + gobject.idle_add(self._stopTest) def _stopTest(self): self.progress_model.advance() @@ -159,26 +159,26 @@ super(GTKTestResult, self).stopTestRun() except AttributeError: pass - gobject.idle_add(self.pbar.set_text, 'Finished') + gobject.idle_add(self.pbar.set_text, 'Finished') def addError(self, test, err): super(GTKTestResult, self).addError(test, err) - gobject.idle_add(self.update_counts) + gobject.idle_add(self.update_counts) def addFailure(self, test, err): super(GTKTestResult, self).addFailure(test, err) - gobject.idle_add(self.update_counts) + gobject.idle_add(self.update_counts) def addSuccess(self, test): super(GTKTestResult, self).addSuccess(test) - gobject.idle_add(self.update_counts) + gobject.idle_add(self.update_counts) def addSkip(self, test, reason): # addSkip is new in Python 2.7/3.1 addSkip = getattr(super(GTKTestResult, self), 'addSkip', None) if callable(addSkip): addSkip(test, reason) - gobject.idle_add(self.update_counts) + gobject.idle_add(self.update_counts) def addExpectedFailure(self, test, err): # addExpectedFailure is new in Python 2.7/3.1 @@ -186,7 +186,7 @@ 'addExpectedFailure', None) if callable(addExpectedFailure): addExpectedFailure(test, err) - gobject.idle_add(self.update_counts) + gobject.idle_add(self.update_counts) def addUnexpectedSuccess(self, test): # addUnexpectedSuccess is new in Python 2.7/3.1 @@ -194,7 +194,7 @@ 'addUnexpectedSuccess', None) if callable(addUnexpectedSuccess): addUnexpectedSuccess(test) - gobject.idle_add(self.update_counts) + gobject.idle_add(self.update_counts) def progress(self, offset, whence): if whence == PROGRESS_PUSH: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/filters/subunit2pyunit new/python-subunit-0.0.16/filters/subunit2pyunit --- old/python-subunit-0.0.15/filters/subunit2pyunit 2013-04-08 12:28:36.000000000 +0200 +++ new/python-subunit-0.0.16/filters/subunit2pyunit 2013-08-25 12:26:45.000000000 +0200 @@ -24,6 +24,7 @@ from testtools import StreamToExtendedDecorator, DecorateTestCaseResult, StreamResultRouter from subunit import ByteStreamToStreamResult +from subunit.filters import find_stream from subunit.test_results import CatFiles parser = OptionParser(description=__doc__) @@ -33,7 +34,8 @@ help="Use bzrlib's test reporter (requires bzrlib)", default=False) (options, args) = parser.parse_args() -test = ByteStreamToStreamResult(sys.stdin, non_subunit_name='stdout') +test = ByteStreamToStreamResult( + find_stream(sys.stdin, args), non_subunit_name='stdout') def wrap_result(result): result = StreamToExtendedDecorator(result) if not options.no_passthrough: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python/subunit/__init__.py new/python-subunit-0.0.16/python/subunit/__init__.py --- old/python-subunit-0.0.15/python/subunit/__init__.py 2013-08-24 16:08:44.000000000 +0200 +++ new/python-subunit-0.0.16/python/subunit/__init__.py 2013-11-30 03:02:19.000000000 +0100 @@ -133,13 +133,6 @@ try: from testtools.testresult.real import _StringException RemoteException = _StringException - # For testing: different pythons have different str() implementations. - if sys.version_info > (3, 0): - _remote_exception_str = "testtools.testresult.real._StringException" - _remote_exception_str_chunked = "34\r\n" + _remote_exception_str - else: - _remote_exception_str = "_StringException" - _remote_exception_str_chunked = "1A\r\n" + _remote_exception_str except ImportError: raise ImportError ("testtools.testresult.real does not contain " "_StringException, check your version.") @@ -160,7 +153,7 @@ # If the releaselevel is 'final', then the tarball will be major.minor.micro. # Otherwise it is major.minor.micro~$(revno). -__version__ = (0, 0, 15, 'final', 0) +__version__ = (0, 0, 16, 'final', 0) PROGRESS_SET = 0 PROGRESS_CUR = 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python/subunit/filters.py new/python-subunit-0.0.16/python/subunit/filters.py --- old/python-subunit-0.0.15/python/subunit/filters.py 2013-06-16 21:53:31.000000000 +0200 +++ new/python-subunit-0.0.16/python/subunit/filters.py 2013-08-25 12:07:00.000000000 +0200 @@ -179,7 +179,8 @@ result = filter_by_result( result_factory, options.output_to, not options.no_passthrough, options.forward, protocol_version=protocol_version, - passthrough_subunit=passthrough_subunit) + passthrough_subunit=passthrough_subunit, + input_stream=find_stream(sys.stdin, args)) if post_run_hook: post_run_hook(result) if not safe_hasattr(result, 'wasSuccessful'): @@ -188,3 +189,18 @@ sys.exit(0) else: sys.exit(1) + + +def find_stream(stdin, argv): + """Find a stream to use as input for filters. + + :param stdin: Standard in - used if no files are named in argv. + :param argv: Command line arguments after option parsing. If one file + is named, that is opened in read only binary mode and returned. + A missing file will raise an exception, as will multiple file names. + """ + assert len(argv) < 2, "Too many filenames." + if argv: + return open(argv[0], 'rb') + else: + return stdin diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python/subunit/run.py new/python-subunit-0.0.16/python/subunit/run.py --- old/python-subunit-0.0.15/python/subunit/run.py 2013-06-16 21:24:39.000000000 +0200 +++ new/python-subunit-0.0.16/python/subunit/run.py 2013-11-30 02:53:54.000000000 +0100 @@ -33,6 +33,7 @@ BUFFEROUTPUT, CATCHBREAK, FAILFAST, + list_test, TestProgram, USAGE_AS_MAIN, ) @@ -51,7 +52,7 @@ def run(self, test): "Run the given test case or test suite." - result = self._list(test) + result, _ = self._list(test) result = ExtendedToStreamDecorator(result) result = AutoTimingTestResultDecorator(result) if self.failfast is not None: @@ -65,9 +66,15 @@ def list(self, test): "List the test." - self._list(test) + result, errors = self._list(test) + if errors: + failed_descr = '\n'.join(errors).encode('utf8') + result.status(file_name="import errors", runnable=False, + file_bytes=failed_descr, mime_type="text/plain;charset=utf8") + sys.exit(2) def _list(self, test): + test_ids, errors = list_test(test) try: fileno = self.stream.fileno() except: @@ -77,9 +84,9 @@ else: stream = self.stream result = StreamResultToBytes(stream) - for case in iterate_tests(test): - result.status(test_id=case.id(), test_status='exists') - return result + for test_id in test_ids: + result.status(test_id=test_id, test_status='exists') + return result, errors class SubunitTestProgram(TestProgram): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python/subunit/tests/__init__.py new/python-subunit-0.0.16/python/subunit/tests/__init__.py --- old/python-subunit-0.0.15/python/subunit/tests/__init__.py 2013-06-16 11:57:24.000000000 +0200 +++ new/python-subunit-0.0.16/python/subunit/tests/__init__.py 2013-11-25 03:34:32.000000000 +0100 @@ -6,7 +6,7 @@ # license at the users choice. A copy of both licenses are available in the # project source as Apache-2.0 and BSD. You may not use this file except in # compliance with one of these two licences. -# +# # Unless required by applicable law or agreed to in writing, software # distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -14,11 +14,26 @@ # limitations under that license. # +import sys from unittest import TestLoader + +# Before the test module imports to avoid circularity. +# For testing: different pythons have different str() implementations. +if sys.version_info > (3, 0): + _remote_exception_repr = "testtools.testresult.real._StringException" + _remote_exception_str = "Traceback (most recent call last):\ntesttools.testresult.real._StringException" + _remote_exception_str_chunked = "57\r\n" + _remote_exception_str + ": boo qux\n0\r\n" +else: + _remote_exception_repr = "_StringException" + _remote_exception_str = "Traceback (most recent call last):\n_StringException" + _remote_exception_str_chunked = "3D\r\n" + _remote_exception_str + ": boo qux\n0\r\n" + + from subunit.tests import ( test_chunked, test_details, + test_filters, test_progress_model, test_run, test_subunit_filter, @@ -30,10 +45,12 @@ test_test_results, ) + def test_suite(): loader = TestLoader() result = loader.loadTestsFromModule(test_chunked) result.addTest(loader.loadTestsFromModule(test_details)) + result.addTest(loader.loadTestsFromModule(test_filters)) result.addTest(loader.loadTestsFromModule(test_progress_model)) result.addTest(loader.loadTestsFromModule(test_test_results)) result.addTest(loader.loadTestsFromModule(test_test_protocol)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python/subunit/tests/test_filters.py new/python-subunit-0.0.16/python/subunit/tests/test_filters.py --- old/python-subunit-0.0.15/python/subunit/tests/test_filters.py 1970-01-01 01:00:00.000000000 +0100 +++ new/python-subunit-0.0.16/python/subunit/tests/test_filters.py 2013-08-25 11:53:35.000000000 +0200 @@ -0,0 +1,35 @@ +# +# subunit: extensions to Python unittest to get test results from subprocesses. +# Copyright (C) 2013 Robert Collins <robe...@robertcollins.net> +# +# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause +# license at the users choice. A copy of both licenses are available in the +# project source as Apache-2.0 and BSD. You may not use this file except in +# compliance with one of these two licences. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# license you chose for the specific language governing permissions and +# limitations under that license. +# + +import sys +from tempfile import NamedTemporaryFile + +from testtools import TestCase + +from subunit.filters import find_stream + + +class TestFindStream(TestCase): + + def test_no_argv(self): + self.assertEqual('foo', find_stream('foo', [])) + + def test_opens_file(self): + f = NamedTemporaryFile() + f.write(b'foo') + f.flush() + stream = find_stream('bar', [f.name]) + self.assertEqual(b'foo', stream.read()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python/subunit/tests/test_run.py new/python-subunit-0.0.16/python/subunit/tests/test_run.py --- old/python-subunit-0.0.15/python/subunit/tests/test_run.py 2013-06-16 11:58:23.000000000 +0200 +++ new/python-subunit-0.0.16/python/subunit/tests/test_run.py 2013-11-30 02:58:58.000000000 +0100 @@ -17,14 +17,15 @@ from testtools.compat import BytesIO import unittest -from testtools import PlaceHolder +from testtools import PlaceHolder, TestCase from testtools.testresult.doubles import StreamResult import subunit +from subunit import run from subunit.run import SubunitTestRunner -class TestSubunitTestRunner(unittest.TestCase): +class TestSubunitTestRunner(TestCase): def test_includes_timing_output(self): io = BytesIO() @@ -52,3 +53,12 @@ ('status', 'name1', 'exists'), ('status', 'name2', 'exists'), ], [event[:3] for event in eventstream._events[:2]]) + + def test_list_errors_if_errors_from_list_test(self): + io = BytesIO() + runner = SubunitTestRunner(stream=io) + def list_test(test): + return [], ['failed import'] + self.patch(run, 'list_test', list_test) + exc = self.assertRaises(SystemExit, runner.list, None) + self.assertEqual((2,), exc.args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python/subunit/tests/test_test_protocol.py new/python-subunit-0.0.16/python/subunit/tests/test_test_protocol.py --- old/python-subunit-0.0.15/python/subunit/tests/test_test_protocol.py 2013-08-23 23:06:16.000000000 +0200 +++ new/python-subunit-0.0.16/python/subunit/tests/test_test_protocol.py 2013-11-23 23:54:11.000000000 +0100 @@ -37,7 +37,11 @@ from testtools.matchers import Contains import subunit -from subunit import _remote_exception_str, _remote_exception_str_chunked +from subunit.tests import ( + _remote_exception_repr, + _remote_exception_str, + _remote_exception_str_chunked, + ) import subunit.iso8601 as iso8601 @@ -105,10 +109,10 @@ bing = subunit.RemotedTestCase("bing crosby") an_error = subunit.RemotedTestCase("an error") self.assertEqual(client.errors, - [(an_error, _remote_exception_str + '\n')]) + [(an_error, _remote_exception_repr + '\n')]) self.assertEqual( client.failures, - [(bing, _remote_exception_str + ": " + [(bing, _remote_exception_repr + ": " + details_to_str({'traceback': text_content(traceback)}) + "\n")]) self.assertEqual(client.testsRun, 3) @@ -963,7 +967,7 @@ "'A test description'>", "%r" % test) result = unittest.TestResult() test.run(result) - self.assertEqual([(test, _remote_exception_str + ": " + self.assertEqual([(test, _remote_exception_repr + ": " "Cannot run RemotedTestCases.\n\n")], result.errors) self.assertEqual(1, result.testsRun) @@ -1199,15 +1203,15 @@ "something\n" "F\r\nserialised\nform0\r\n" "Content-Type: text/x-traceback;charset=utf8,language=python\n" - "traceback\n" + _remote_exception_str_chunked + ": boo qux\n0\r\n" + "traceback\n" + _remote_exception_str_chunked + "]\n") % self.test.id()), _b(("failure: %s [ multipart\n" "Content-Type: text/plain\n" "something\n" "F\r\nserialised\nform0\r\n" "Content-Type: text/x-traceback;language=python,charset=utf8\n" - "traceback\n" + _remote_exception_str_chunked + ": boo qux\n0\r\n" - "]\n") % self.test.id()) + "traceback\n" + _remote_exception_str_chunked + + "]\n") % self.test.id()), ], Contains(self.io.getvalue())), @@ -1231,14 +1235,14 @@ "something\n" "F\r\nserialised\nform0\r\n" "Content-Type: text/x-traceback;charset=utf8,language=python\n" - "traceback\n" + _remote_exception_str_chunked + ": boo qux\n0\r\n" + "traceback\n" + _remote_exception_str_chunked + "]\n") % self.test.id()), _b(("error: %s [ multipart\n" "Content-Type: text/plain\n" "something\n" "F\r\nserialised\nform0\r\n" "Content-Type: text/x-traceback;language=python,charset=utf8\n" - "traceback\n" + _remote_exception_str_chunked + ": boo qux\n0\r\n" + "traceback\n" + _remote_exception_str_chunked + "]\n") % self.test.id()), ], Contains(self.io.getvalue())), @@ -1263,14 +1267,14 @@ "something\n" "F\r\nserialised\nform0\r\n" "Content-Type: text/x-traceback;charset=utf8,language=python\n" - "traceback\n" + _remote_exception_str_chunked + ": boo qux\n0\r\n" + "traceback\n" + _remote_exception_str_chunked + "]\n") % self.test.id()), _b(("xfail: %s [ multipart\n" "Content-Type: text/plain\n" "something\n" "F\r\nserialised\nform0\r\n" "Content-Type: text/x-traceback;language=python,charset=utf8\n" - "traceback\n" + _remote_exception_str_chunked + ": boo qux\n0\r\n" + "traceback\n" + _remote_exception_str_chunked + "]\n") % self.test.id()), ], Contains(self.io.getvalue())), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python/subunit/tests/test_test_protocol2.py new/python-subunit-0.0.16/python/subunit/tests/test_test_protocol2.py --- old/python-subunit-0.0.15/python/subunit/tests/test_test_protocol2.py 2013-08-24 15:43:18.000000000 +0200 +++ new/python-subunit-0.0.16/python/subunit/tests/test_test_protocol2.py 2013-08-25 02:01:39.000000000 +0200 @@ -335,20 +335,24 @@ bad_file_length_content = b'\xb3!@\x13\x06barney\x04woo\xdc\xe2\xdb\x35' self.check_events(bad_file_length_content, [ self._event(test_id="subunit.parser", eof=True, - file_name="Packet data", file_bytes=bad_file_length_content), + file_name="Packet data", file_bytes=bad_file_length_content, + mime_type="application/octet-stream"), self._event(test_id="subunit.parser", test_status="fail", eof=True, file_name="Parser Error", - file_bytes=b"File content extends past end of packet: claimed 4 bytes, 3 available"), + file_bytes=b"File content extends past end of packet: claimed 4 bytes, 3 available", + mime_type="text/plain;charset=utf8"), ]) def test_packet_length_4_word_varint(self): packet_data = b'\xb3!@\xc0\x00\x11' self.check_events(packet_data, [ self._event(test_id="subunit.parser", eof=True, - file_name="Packet data", file_bytes=packet_data), + file_name="Packet data", file_bytes=packet_data, + mime_type="application/octet-stream"), self._event(test_id="subunit.parser", test_status="fail", eof=True, file_name="Parser Error", - file_bytes=b"3 byte maximum given but 4 byte value found."), + file_bytes=b"3 byte maximum given but 4 byte value found.", + mime_type="text/plain;charset=utf8"), ]) def test_mime(self): @@ -377,42 +381,50 @@ file_bytes = CONSTANT_MIME[:-1] + b'\x00' self.check_events( file_bytes, [ self._event(test_id="subunit.parser", eof=True, - file_name="Packet data", file_bytes=file_bytes), + file_name="Packet data", file_bytes=file_bytes, + mime_type="application/octet-stream"), self._event(test_id="subunit.parser", test_status="fail", eof=True, file_name="Parser Error", file_bytes=b'Bad checksum - calculated (0x78335115), ' - b'stored (0x78335100)'), + b'stored (0x78335100)', + mime_type="text/plain;charset=utf8"), ]) def test_not_utf8_in_string(self): file_bytes = CONSTANT_ROUTE_CODE[:5] + b'\xb4' + CONSTANT_ROUTE_CODE[6:-4] + b'\xce\x56\xc6\x17' self.check_events(file_bytes, [ self._event(test_id="subunit.parser", eof=True, - file_name="Packet data", file_bytes=file_bytes), + file_name="Packet data", file_bytes=file_bytes, + mime_type="application/octet-stream"), self._event(test_id="subunit.parser", test_status="fail", eof=True, file_name="Parser Error", - file_bytes=b'UTF8 string at offset 2 is not UTF8'), + file_bytes=b'UTF8 string at offset 2 is not UTF8', + mime_type="text/plain;charset=utf8"), ]) def test_NULL_in_string(self): file_bytes = CONSTANT_ROUTE_CODE[:6] + b'\x00' + CONSTANT_ROUTE_CODE[7:-4] + b'\xd7\x41\xac\xfe' self.check_events(file_bytes, [ self._event(test_id="subunit.parser", eof=True, - file_name="Packet data", file_bytes=file_bytes), + file_name="Packet data", file_bytes=file_bytes, + mime_type="application/octet-stream"), self._event(test_id="subunit.parser", test_status="fail", eof=True, file_name="Parser Error", - file_bytes=b'UTF8 string at offset 2 contains NUL byte'), + file_bytes=b'UTF8 string at offset 2 contains NUL byte', + mime_type="text/plain;charset=utf8"), ]) def test_bad_utf8_stringlength(self): file_bytes = CONSTANT_ROUTE_CODE[:4] + b'\x3f' + CONSTANT_ROUTE_CODE[5:-4] + b'\xbe\x29\xe0\xc2' self.check_events(file_bytes, [ self._event(test_id="subunit.parser", eof=True, - file_name="Packet data", file_bytes=file_bytes), + file_name="Packet data", file_bytes=file_bytes, + mime_type="application/octet-stream"), self._event(test_id="subunit.parser", test_status="fail", eof=True, file_name="Parser Error", file_bytes=b'UTF8 string at offset 2 extends past end of ' - b'packet: claimed 63 bytes, 10 available'), + b'packet: claimed 63 bytes, 10 available', + mime_type="text/plain;charset=utf8"), ]) def test_route_code_and_file_content(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python/subunit/v2.py new/python-subunit-0.0.16/python/subunit/v2.py --- old/python-subunit-0.0.15/python/subunit/v2.py 2013-08-24 16:05:13.000000000 +0200 +++ new/python-subunit-0.0.16/python/subunit/v2.py 2013-08-25 02:38:39.000000000 +0200 @@ -50,6 +50,24 @@ FLAG_FILE_CONTENT = 0x0040 EPOCH = datetime.datetime.utcfromtimestamp(0).replace(tzinfo=iso8601.Utc()) NUL_ELEMENT = b'\0'[0] +# Contains True for types for which 'nul in thing' falsely returns false. +_nul_test_broken = {} + + +def has_nul(buffer_or_bytes): + """Return True if a null byte is present in buffer_or_bytes.""" + # Simple "if NUL_ELEMENT in utf8_bytes:" fails on Python 3.1 and 3.2 with + # memoryviews. See https://bugs.launchpad.net/subunit/+bug/1216246 + buffer_type = type(buffer_or_bytes) + broken = _nul_test_broken.get(buffer_type) + if broken is None: + reference = buffer_type(b'\0') + broken = not NUL_ELEMENT in reference + _nul_test_broken[buffer_type] = broken + if broken: + return b'\0' in buffer_or_bytes + else: + return NUL_ELEMENT in buffer_or_bytes class ParseError(Exception): @@ -326,10 +344,12 @@ self._parse(packet, result) except ParseError as error: result.status(test_id="subunit.parser", eof=True, - file_name="Packet data", file_bytes=b''.join(packet)) + file_name="Packet data", file_bytes=b''.join(packet), + mime_type="application/octet-stream") result.status(test_id="subunit.parser", test_status='fail', eof=True, file_name="Parser Error", - file_bytes=(error.args[0]).encode('utf8')) + file_bytes=(error.args[0]).encode('utf8'), + mime_type="text/plain;charset=utf8") def _to_bytes(self, data, pos, length): """Return a slice of data from pos for length as bytes.""" @@ -460,7 +480,7 @@ 'UTF8 string at offset %d extends past end of packet: ' 'claimed %d bytes, %d available' % (pos - 2, length, len(utf8_bytes))) - if NUL_ELEMENT in utf8_bytes: + if has_nul(utf8_bytes): raise ParseError('UTF8 string at offset %d contains NUL byte' % ( pos-2,)) try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python_subunit.egg-info/PKG-INFO new/python-subunit-0.0.16/python_subunit.egg-info/PKG-INFO --- old/python-subunit-0.0.15/python_subunit.egg-info/PKG-INFO 2013-08-24 16:12:07.000000000 +0200 +++ new/python-subunit-0.0.16/python_subunit.egg-info/PKG-INFO 2013-11-30 10:17:04.000000000 +0100 @@ -1,6 +1,6 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.0 Name: python-subunit -Version: 0.0.15 +Version: 0.0.16 Summary: Python implementation of subunit test streaming protocol Home-page: http://launchpad.net/subunit Author: Robert Collins @@ -14,7 +14,7 @@ license at the users choice. A copy of both licenses are available in the project source as Apache-2.0 and BSD. You may not use this file except in compliance with one of these two licences. - + Unless required by applicable law or agreed to in writing, software distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -98,7 +98,7 @@ subunit via the ``subunit.run`` module:: $ python -m subunit.run mypackage.tests.test_suite - + For more information on the Python support Subunit offers , please see ``pydoc subunit``, or the source in ``python/subunit/`` @@ -351,7 +351,7 @@ Version 1 (and 1.1) =================== - Version 1 (and 1.1) are mostly human readable protocols. + Version 1 (and 1.1) are mostly human readable protocols. Sample subunit wire contents ---------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python_subunit.egg-info/SOURCES.txt new/python-subunit-0.0.16/python_subunit.egg-info/SOURCES.txt --- old/python-subunit-0.0.15/python_subunit.egg-info/SOURCES.txt 2013-08-24 16:12:08.000000000 +0200 +++ new/python-subunit-0.0.16/python_subunit.egg-info/SOURCES.txt 2013-11-30 10:17:05.000000000 +0100 @@ -27,6 +27,7 @@ python/subunit/tests/sample-two-script.py python/subunit/tests/test_chunked.py python/subunit/tests/test_details.py +python/subunit/tests/test_filters.py python/subunit/tests/test_progress_model.py python/subunit/tests/test_run.py python/subunit/tests/test_subunit_filter.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/python_subunit.egg-info/requires.txt new/python-subunit-0.0.16/python_subunit.egg-info/requires.txt --- old/python-subunit-0.0.15/python_subunit.egg-info/requires.txt 2013-08-24 16:12:07.000000000 +0200 +++ new/python-subunit-0.0.16/python_subunit.egg-info/requires.txt 2013-11-30 10:17:04.000000000 +0100 @@ -1,2 +1,2 @@ extras -testtools>=0.9.30 \ No newline at end of file +testtools>=0.9.34 \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-subunit-0.0.15/setup.py new/python-subunit-0.0.16/setup.py --- old/python-subunit-0.0.15/setup.py 2013-04-08 12:28:36.000000000 +0200 +++ new/python-subunit-0.0.16/setup.py 2013-11-30 10:15:03.000000000 +0100 @@ -10,7 +10,7 @@ extra = { 'install_requires': [ 'extras', - 'testtools>=0.9.30', + 'testtools>=0.9.34', ] } -- To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org For additional commands, e-mail: opensuse-commit+h...@opensuse.org