Hello community, here is the log from the commit of package python-stestr for openSUSE:Factory checked in at 2019-03-29 20:35:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-stestr (Old) and /work/SRC/openSUSE:Factory/.python-stestr.new.25356 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-stestr" Fri Mar 29 20:35:44 2019 rev:9 rq:685817 version:2.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-stestr/python-stestr.changes 2019-01-28 20:45:54.802065005 +0100 +++ /work/SRC/openSUSE:Factory/.python-stestr.new.25356/python-stestr.changes 2019-03-29 20:35:45.594521189 +0100 @@ -1,0 +2,15 @@ +Sun Mar 17 15:17:55 UTC 2019 - Tomáš Chvátal <tchva...@suse.com> + +- Add patch to work with PyYAML 5.x series: + * pyyaml5.patch + +------------------------------------------------------------------- +Wed Mar 13 12:40:42 UTC 2019 - Tomáš Chvátal <tchva...@suse.com> + +- Update to 2.3.1: + * tests expansion + * metadata updates + * minor bugfixes +- Enable and run tests + +------------------------------------------------------------------- Old: ---- stestr-2.2.0.tar.gz New: ---- pyyaml5.patch stestr-2.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-stestr.spec ++++++ --- /var/tmp/diff_new_pack.4LBE32/_old 2019-03-29 20:35:46.674521613 +0100 +++ /var/tmp/diff_new_pack.4LBE32/_new 2019-03-29 20:35:46.682521618 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-stestr # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,20 +18,24 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-stestr -Version: 2.2.0 +Version: 2.3.1 Release: 0 Summary: A test runner runner similar to testrepository License: Apache-2.0 Group: Development/Languages/Python URL: https://github.com/mtreinish/stestr Source: https://files.pythonhosted.org/packages/source/s/stestr/stestr-%{version}.tar.gz +Patch0: pyyaml5.patch BuildRequires: %{python_module PyYAML >= 3.10.0} +BuildRequires: %{python_module SQLAlchemy} BuildRequires: %{python_module cliff >= 2.8.0} BuildRequires: %{python_module coverage >= 4.0} BuildRequires: %{python_module ddt >= 1.0.1} BuildRequires: %{python_module fixtures >= 3.0.0} BuildRequires: %{python_module future} +BuildRequires: %{python_module mock >= 2.0} BuildRequires: %{python_module pbr >= 2.0.0} +BuildRequires: %{python_module pytest} BuildRequires: %{python_module python-subunit >= 1.3.0} BuildRequires: %{python_module setuptools} BuildRequires: %{python_module six >= 1.10.0} @@ -39,6 +43,7 @@ BuildRequires: %{python_module voluptuous >= 0.8.9} BuildRequires: fdupes BuildRequires: python-rpm-macros +BuildRequires: python3-dbm Requires: python-PyYAML >= 3.10.0 Requires: python-cliff >= 2.8.0 Requires: python-fixtures >= 3.0.0 @@ -49,12 +54,13 @@ Requires: python-testtools >= 2.2.0 Requires: python-voluptuous >= 0.8.9 %ifpython3 -Requires: python3-dbm +Requires: python-dbm %endif Requires(post): update-alternatives Requires(postun): update-alternatives %if !0%{?_no_weakdeps} -Suggests: python-subunit2sql >= 1.8.0 +Recommends: python-SQLAlchemy +Recommends: python-subunit2sql >= 1.8.0 %endif BuildArch: noarch %python_subpackages @@ -69,6 +75,9 @@ %prep %setup -q -n stestr-%{version} +%patch0 -p1 +# do not test sql +rm stestr/tests/repository/test_sql.py %build %python_build @@ -78,6 +87,19 @@ %python_clone -a %{buildroot}%{_bindir}/stestr %python_expand %fdupes %{buildroot}%{$python_sitelib} +%check +%{python_expand mkdir build/bin +for filepath in %{buildroot}/%{_bindir}/stestr*-%{$python_bin_suffix}; do + filename=$(basename $filepath) + unsuffixed=${filename/-%{$python_bin_suffix}/} + cp $filepath build/bin/$unsuffixed +done +export PATH="$(pwd)/build/bin:$PATH" +export PYTHONPATH=%{buildroot}%{$python_sitelib} +py.test-%{$python_bin_suffix} -v stestr/tests +rm -r build/bin +} + %post %python_install_alternative stestr ++++++ pyyaml5.patch ++++++ >From f0c8c1112677367345e9b672ed6716b7b9e4d919 Mon Sep 17 00:00:00 2001 From: Masayuki Igawa <masay...@igawa.io> Date: Sat, 16 Mar 2019 10:47:47 +0800 Subject: [PATCH] Use yaml.safe_load instead of yaml.load yaml.load(input) is deprecated from PyYAML 5.1[0]. Therefore, some warnings are showed up in a stestr unit test case which causes a failure in test_load_from_stdin_quiet() because it expects empty string. This commit makes it to use yaml.safe_load instead of yaml.load. Because it doesn't show the deprecation warnings. [0] https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation Closes: #234 --- stestr/scheduler.py | 2 +- stestr/tests/test_scheduler.py | 12 ++++++------ stestr/tests/test_user_config.py | 8 +++++--- stestr/user_config.py | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/stestr/scheduler.py b/stestr/scheduler.py index 71a4468..b7c5631 100644 --- a/stestr/scheduler.py +++ b/stestr/scheduler.py @@ -155,7 +155,7 @@ def generate_worker_partitions(ids, worker_path, repository=None, :returns: A list where each element is a distinct subset of test_ids. """ with open(worker_path, 'r') as worker_file: - workers_desc = yaml.load(worker_file.read()) + workers_desc = yaml.safe_load(worker_file.read()) worker_groups = [] for worker in workers_desc: if isinstance(worker, dict) and 'worker' in worker.keys(): diff --git a/stestr/tests/test_scheduler.py b/stestr/tests/test_scheduler.py index 2df3593..5959759 100644 --- a/stestr/tests/test_scheduler.py +++ b/stestr/tests/test_scheduler.py @@ -124,7 +124,7 @@ def test_generate_worker_partitions(self): {'worker': ['test_']}, {'worker': ['test']}, ] - with mock.patch('yaml.load', return_value=fake_worker_yaml): + with mock.patch('yaml.safe_load', return_value=fake_worker_yaml): groups = scheduler.generate_worker_partitions(test_ids, 'fakepath') expected_grouping = [ ['test_a', 'test_b'], @@ -139,7 +139,7 @@ def test_generate_worker_partitions_group_without_list(self): {'worker': ['test_']}, {'worker': 'test'}, ] - with mock.patch('yaml.load', return_value=fake_worker_yaml): + with mock.patch('yaml.safe_load', return_value=fake_worker_yaml): self.assertRaises(TypeError, scheduler.generate_worker_partitions, test_ids, 'fakepath') @@ -150,7 +150,7 @@ def test_generate_worker_partitions_no_worker_tag(self): {'worker-foo': ['test_']}, {'worker': ['test']}, ] - with mock.patch('yaml.load', return_value=fake_worker_yaml): + with mock.patch('yaml.safe_load', return_value=fake_worker_yaml): self.assertRaises(TypeError, scheduler.generate_worker_partitions, test_ids, 'fakepath') @@ -162,7 +162,7 @@ def test_generate_worker_partitions_group_without_match(self): {'worker': ['test']}, {'worker': ['foo']} ] - with mock.patch('yaml.load', return_value=fake_worker_yaml): + with mock.patch('yaml.safe_load', return_value=fake_worker_yaml): groups = scheduler.generate_worker_partitions(test_ids, 'fakepath') expected_grouping = [ ['test_a', 'test_b'], @@ -178,7 +178,7 @@ def test_generate_worker_partitions_with_count(self): {'worker': ['test']}, {'worker': ['a_thing'], 'concurrency': 2}, ] - with mock.patch('yaml.load', return_value=fake_worker_yaml): + with mock.patch('yaml.safe_load', return_value=fake_worker_yaml): groups = scheduler.generate_worker_partitions(test_ids, 'fakepath') expected_grouping = [ ['test_a', 'test_b'], @@ -196,7 +196,7 @@ def test_generate_worker_partitions_with_count_1(self): {'worker': ['test_']}, {'worker': ['test'], 'count': 1}, ] - with mock.patch('yaml.load', return_value=fake_worker_yaml): + with mock.patch('yaml.safe_load', return_value=fake_worker_yaml): groups = scheduler.generate_worker_partitions(test_ids, 'fakepath') expected_grouping = [ ['test_a', 'test_b'], diff --git a/stestr/tests/test_user_config.py b/stestr/tests/test_user_config.py index 2758f76..ef329a2 100644 --- a/stestr/tests/test_user_config.py +++ b/stestr/tests/test_user_config.py @@ -96,13 +96,14 @@ def fake_isfile(path): user_config.get_user_config() user_mock.assert_called_once_with(self.home_path) - @mock.patch('yaml.load', return_value={}) + @mock.patch('yaml.safe_load', return_value={}) @mock.patch('six.moves.builtins.open', mock.mock_open()) def test_user_config_empty_schema(self, yaml_mock): user_conf = user_config.UserConfig('/path') self.assertEqual({}, user_conf.config) - @mock.patch('yaml.load', return_value={'init': {'subunit-trace': True}}) + @mock.patch('yaml.safe_load', + return_value={'init': {'subunit-trace': True}}) @mock.patch('sys.exit') @mock.patch('six.moves.builtins.open', mock.mock_open()) def test_user_config_invalid_command(self, exit_mock, yaml_mock): @@ -111,7 +112,8 @@ def test_user_config_invalid_command(self, exit_mock, yaml_mock): "extra keys not allowed @ data['init']") exit_mock.assert_called_once_with(error_string) - @mock.patch('yaml.load', return_value={'run': {'subunit-trace': True}}) + @mock.patch('yaml.safe_load', + return_value={'run': {'subunit-trace': True}}) @mock.patch('sys.exit') @mock.patch('six.moves.builtins.open', mock.mock_open()) def test_user_config_invalid_option(self, exit_mock, yaml_mock): diff --git a/stestr/user_config.py b/stestr/user_config.py index c54be1b..02ef026 100644 --- a/stestr/user_config.py +++ b/stestr/user_config.py @@ -66,7 +66,7 @@ def __init__(self, path): } }) with open(path, 'r') as fd: - self.config = yaml.load(fd.read()) + self.config = yaml.safe_load(fd.read()) if self.config is None: self.config = {} try: ++++++ stestr-2.2.0.tar.gz -> stestr-2.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/AUTHORS new/stestr-2.3.1/AUTHORS --- old/stestr-2.2.0/AUTHORS 2018-11-30 02:32:07.000000000 +0100 +++ new/stestr-2.3.1/AUTHORS 2019-03-06 02:23:39.000000000 +0100 @@ -23,8 +23,10 @@ Monty Taylor <mord...@inaugust.com> Robert Collins <robe...@robertcollins.net> Sean McGinnis <sean.mcgin...@huawei.com> +Sergey Vilgelm <ser...@vilgelm.info> Sorin Sbarnea <ssbar...@users.noreply.github.com> Steve Heyman <steve.hey...@rackspace.com> Thomas Bechtold <tbecht...@suse.com> +Tony Breeds <t...@bakeyournoodle.com> Zane Bitter <zbit...@redhat.com> afrittoli <afritt...@users.noreply.github.com> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/ChangeLog new/stestr-2.3.1/ChangeLog --- old/stestr-2.2.0/ChangeLog 2018-11-30 02:32:07.000000000 +0100 +++ new/stestr-2.3.1/ChangeLog 2019-03-06 02:23:39.000000000 +0100 @@ -1,6 +1,37 @@ CHANGES ======= +2.3.1 +----- + +* Add sanity check unittests +* Use to\_int in both CLI and Python API +* Ensure concurrency is always an int + +2.3.0 +----- + +* Update package metadata in setup.cfg +* Inline CONTRIBUTING.rst in README.rst and add to docs +* Add links to GitHub repo and project-urls to metadata +* Move from get\_description() to class docstrings part-2 +* Switch from get\_descripition() to class docstrings +* Fix whitespace lint +* Gracefully handle the case when sys.executable is None +* Add error message for invalid concurrency value +* Use default user config in unit tests +* Turn on debug loggin by default +* Run commands through the same python used for stestr +* Improved test coverage for stestr run --subunit 0 exit status +* Update docs for exit codes with --subunit flags +* Put in quotes the top\_dir and test\_path +* Clarify group\_regex explanation +* Update MANUAL.rst for parallel\_class option +* Update doc/source/MANUAL.rst +* Update MANUAL.rst for parallel\_class option +* Introduce parallel-class option +* Tweak the README for readability + 2.2.0 ----- @@ -311,6 +342,10 @@ * Pivot repo to stestr * Release 0.0.20 * Tests will be reliably tagged with worker-%d + +0.0.19 +------ + * Release 0.0.19 * Fix 0 timestamps for enumerated but not run tests * Update docs for the move to github @@ -324,10 +359,22 @@ * Improve error rendering of listing issues * \* When list-tests encounters an error, a much clearer response will now be shown. (Robert Collins, #1271133) * \* \`\`run\`\` was outputting bad MIME types - test/plain, not text/plain. (Robert Collins) + +0.0.18 +------ + * Release 0.0.18 * \* \`\`run\`\` now accepts \`\`--isolated\`\` as a parameter, which will cause each selected test to be run independently. This can be useful to both workaround isolation bugs and detect tests that can not be run independently. (Robert Collins) * \* \`\`capture\_ids\`\` in test\_run now returns a list of captures, permitting tests that need to test multiple runs to do so. (Robert Collins) + +0.0.17 +------ + * 0.0.17 ++++++ + +0.0.16 +------ + * Release 0.0.16 * \* When test listing fails, testr will now report an error rather than incorrectly trying to run zero tests. A test listing failure is detected by the returncode of the test listing process. (Robert Collins, #1185231) * \* A new testr.conf option \`\`group\_regex\`\` can be used for grouping tests so that they get run in the same backend runner. (Matthew Treinish) @@ -353,6 +400,10 @@ * Drop the ExtendedToStream wrapping around UI.make\_result * Move tag based test filtering into the UI: many test things won't be filtered, such as slow tests and pdb debugging, so the UI has to see the tests. Moving the responsibility into the UI may lead to repetition in other UI's if not made easy to reuse, but that seems like the lesser of evils for now * Simplify commands.failing + +0.0.15 +------ + * Release 0.0.15, with minimal subunit v2 support * Fix subunit v1 parallel test execution * Add test for --subunit support - the UI was previously only loosely tested @@ -367,21 +418,41 @@ * Use ConcurrentStreamResult always * Start getting streamresult into the innards * \* Expects subunit v2 if the local library has v2 support in the subunit library. This should be seamless if the system under test shares the Python libraries. If it doesn't, either arrange to use \`\`subunit-2to1\`\` or upgrade the subunit libraries for the system under test. (Robert Collins) + +0.0.14 +------ + * Update releasing docs and really release 0.0.14 * 0.0.14 ++++++ + +0.0.13 +------ + * Release 0.0.13 * \* \`\`setup.py testr\`\` was not indicating test failures via it's return code. (Monty Taylor) * Actually return from \_run\_testr + +0.0.12 +------ + * Release 0.0.12 * \* There is now a setuptools extension provided by \`\`testrespository\`\` making it easy to invoke testr from setup.py driven workflows. (Monty Taylor, Robert Collins) * \* BSD license file incorrectly claimed copyright by subunit contributors. (Monty Taylor) * Correct a typo in setup.py * \* .testr.conf is now shipped in the source distribution to aid folk wanting to validate that testrepository works correctly on their machine. (Robert Collins) * Add setuptools commands for running testr and coverage + +0.0.11 +------ + * Release 0.0.11 * Tweak docs * \* Fix another incompatability with Mac OS X - gdbm dbm modules don't support get. (Robert Collins, #1094330) * ReST fixes for docs + +0.0.10 +------ + * Release 0.0.10 * \* It's now possible to configure \`\`test\_run\_concurrency\`\` in \`\`.testr.conf\`\` to have concurrency defined by a callout. (Robert Collins) * Update testr help run docs for new options @@ -395,6 +466,10 @@ * \* TestCommand is now a fixture. This is used to ensure cached test instances are disposed of - if using the object to run or list tests, you will need to adjust your calls. (Robert Collins) * \* It's now possible to configure \`\`test\_run\_concurrency\`\` in \`\`.testr.conf\`\` to have concurrency defined by a callout. (Robert Collins) * Document overview + +0.0.9 +----- + * Release 0.0.9 * \* On OSX the \`\`anydbm\`\` module by default returns an implementation that doesn't support update(). Workaround that by falling back to a loop. (Robert Collins, #1091500) * Document workaround @@ -403,6 +478,10 @@ * \* \`\`testr --analyze-improvements\`\` now honours test regex filters and only analyzes matching tests. (Robert Collins) * Better documentation for setup of .testr.conf * Better keywords + +0.0.8 +----- + * Release 0.0.8 * \* \`\`testr run --analyze-isolation\`\` will search the current failing tests for spurious failures caused by interactions with other tests. (Robert Collins, #684069) * First, horribly untested, version of --analyze-failures diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/PKG-INFO new/stestr-2.3.1/PKG-INFO --- old/stestr-2.2.0/PKG-INFO 2018-11-30 02:32:07.000000000 +0100 +++ new/stestr-2.3.1/PKG-INFO 2019-03-06 02:23:39.000000000 +0100 @@ -1,11 +1,14 @@ Metadata-Version: 2.1 Name: stestr -Version: 2.2.0 +Version: 2.3.1 Summary: A parallel Python test runner built around subunit Home-page: http://stestr.readthedocs.io/en/latest/ Author: Matthew Treinish Author-email: mtrein...@kortar.org License: UNKNOWN +Project-URL: Documentation, https://stestr.readthedocs.io +Project-URL: Source Code, https://github.com/mtreinish/stestr +Project-URL: Bug Tracker, https://github.com/mtreinish/stestr/issues Description: stestr ====== @@ -25,7 +28,8 @@ :target: https://pypi.python.org/pypi/stestr :alt: Latest Version - You can see the full rendered docs at: http://stestr.readthedocs.io/en/latest/ + * You can see the full rendered docs at: http://stestr.readthedocs.io/en/latest/ + * The code of the project is on Github: https://github.com/mtreinish/stestr Overview -------- @@ -40,19 +44,16 @@ .. _unittest: https://docs.python.org/3/library/unittest.html .. _subunit: https://github.com/testing-cabal/subunit - stestr originally started as a fork of the `testrepository`_ that concentrates - on being a dedicated test runner for python projects. The generic abstraction - layers which enabled testrepository to work with any subunit emitting runner - are gone. stestr hard codes python-subunit-isms into how it works. The code - base is also designed to try and be explicit, and to provide a python api that - is documented and has examples. + stestr originally started as a fork of the `testrepository`_ project. But, + instead of being an interface for any test runner that used subunit, like + testrepository, stestr concentrated on being a dedicated test runner for python + projects. While stestr was originally forked from testrepository it is not + backwards compatible with testrepository. At a high level the basic concepts of + operation are shared between the two projects but the actual usage is not + exactly the same. .. _testrepository: https://testrepository.readthedocs.org/en/latest - While stestr was originally forked from testrepository it is not 100% backwards - compatible with testrepository. At a high level the basic concepts of operation - are shared between the 2 projects but the actual usage between the 2 is not - exactly the same. Installing stestr ----------------- @@ -73,7 +74,7 @@ ------------ After you install stestr to use it to run tests is pretty straightforward. The - first thing you'll need to do is create a ``.stestr.conf`` file for your + first thing you'll want to do is create a ``.stestr.conf`` file for your project. This file is used to tell stestr where to find tests and basic information about how tests are run. A basic minimal example of the contents of this is:: @@ -83,25 +84,20 @@ which just tells stestr the relative path for the directory to use for test discovery. This is the same as ``--start-directory`` in the standard - `unittest discovery`_ + `unittest discovery`_. .. _unittest discovery: https://docs.python.org/3/library/unittest.html#test-discovery After this file is created you should be all set to start using stestr to run - tests. You can create a repository for test results with the stestr init - command, just run:: - - stestr init - - and it will create a .stestr directory in your cwd that will be used to store - test run results. (if you run stestr run it will create this if it doesn't - exist) Then to run tests just use:: + tests. To run tests just use:: stestr run - it will then execute all the tests found by test discovery. If you're just - running a single test (or module) and want to avoid the overhead of doing test - discovery you can use the ``--no-discover``/``-n`` option. + it will first create a results repository at ``.stestr/`` in the current + working directory and then execute all the tests found by test discovery. If + you're just running a single test (or module) and want to avoid the overhead of + doing test discovery you can use the ``--no-discover``/``-n`` option to specify + that test. For all the details on these commands and more thorough explanation of options see the stestr manual: https://stestr.readthedocs.io/en/latest/MANUAL.html @@ -134,13 +130,28 @@ which will generate the troff file in doc/build/man/stestr.1 which is ready to be packaged and or put in your system's man pages. + Contributing + ------------ + + To browse the latest code, see: https://github.com/mtreinish/stestr + To clone the latest code, use: ``git clone https://github.com/mtreinish/stestr.git`` + + Guidelines for contribution are documented at: http://stestr.readthedocs.io/en/latest/developer_guidelines.html + + Use `github pull requests`_ to submit patches. Before you submit a pull request + ensure that all the automated testing will pass by running ``tox`` locally. + This will run the test suite and also the automated style rule checks just as + they will in CI. If CI fails on your change it will not be able to merge. + + .. _github pull requests: https://help.github.com/articles/about-pull-requests/ + Platform: UNKNOWN Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Apache Software License -Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 @@ -150,5 +161,5 @@ Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Software Development :: Quality Assurance -Provides-Extra: test Provides-Extra: sql +Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/README.rst new/stestr-2.3.1/README.rst --- old/stestr-2.2.0/README.rst 2018-11-29 21:57:37.000000000 +0100 +++ new/stestr-2.3.1/README.rst 2019-03-01 19:22:55.000000000 +0100 @@ -17,7 +17,8 @@ :target: https://pypi.python.org/pypi/stestr :alt: Latest Version -You can see the full rendered docs at: http://stestr.readthedocs.io/en/latest/ +* You can see the full rendered docs at: http://stestr.readthedocs.io/en/latest/ +* The code of the project is on Github: https://github.com/mtreinish/stestr Overview -------- @@ -32,19 +33,16 @@ .. _unittest: https://docs.python.org/3/library/unittest.html .. _subunit: https://github.com/testing-cabal/subunit -stestr originally started as a fork of the `testrepository`_ that concentrates -on being a dedicated test runner for python projects. The generic abstraction -layers which enabled testrepository to work with any subunit emitting runner -are gone. stestr hard codes python-subunit-isms into how it works. The code -base is also designed to try and be explicit, and to provide a python api that -is documented and has examples. +stestr originally started as a fork of the `testrepository`_ project. But, +instead of being an interface for any test runner that used subunit, like +testrepository, stestr concentrated on being a dedicated test runner for python +projects. While stestr was originally forked from testrepository it is not +backwards compatible with testrepository. At a high level the basic concepts of +operation are shared between the two projects but the actual usage is not +exactly the same. .. _testrepository: https://testrepository.readthedocs.org/en/latest -While stestr was originally forked from testrepository it is not 100% backwards -compatible with testrepository. At a high level the basic concepts of operation -are shared between the 2 projects but the actual usage between the 2 is not -exactly the same. Installing stestr ----------------- @@ -65,7 +63,7 @@ ------------ After you install stestr to use it to run tests is pretty straightforward. The -first thing you'll need to do is create a ``.stestr.conf`` file for your +first thing you'll want to do is create a ``.stestr.conf`` file for your project. This file is used to tell stestr where to find tests and basic information about how tests are run. A basic minimal example of the contents of this is:: @@ -75,25 +73,20 @@ which just tells stestr the relative path for the directory to use for test discovery. This is the same as ``--start-directory`` in the standard -`unittest discovery`_ +`unittest discovery`_. .. _unittest discovery: https://docs.python.org/3/library/unittest.html#test-discovery After this file is created you should be all set to start using stestr to run -tests. You can create a repository for test results with the stestr init -command, just run:: - - stestr init - -and it will create a .stestr directory in your cwd that will be used to store -test run results. (if you run stestr run it will create this if it doesn't -exist) Then to run tests just use:: +tests. To run tests just use:: stestr run -it will then execute all the tests found by test discovery. If you're just -running a single test (or module) and want to avoid the overhead of doing test -discovery you can use the ``--no-discover``/``-n`` option. +it will first create a results repository at ``.stestr/`` in the current +working directory and then execute all the tests found by test discovery. If +you're just running a single test (or module) and want to avoid the overhead of +doing test discovery you can use the ``--no-discover``/``-n`` option to specify +that test. For all the details on these commands and more thorough explanation of options see the stestr manual: https://stestr.readthedocs.io/en/latest/MANUAL.html @@ -125,3 +118,18 @@ which will generate the troff file in doc/build/man/stestr.1 which is ready to be packaged and or put in your system's man pages. + +Contributing +------------ + +To browse the latest code, see: https://github.com/mtreinish/stestr +To clone the latest code, use: ``git clone https://github.com/mtreinish/stestr.git`` + +Guidelines for contribution are documented at: http://stestr.readthedocs.io/en/latest/developer_guidelines.html + +Use `github pull requests`_ to submit patches. Before you submit a pull request +ensure that all the automated testing will pass by running ``tox`` locally. +This will run the test suite and also the automated style rule checks just as +they will in CI. If CI fails on your change it will not be able to merge. + +.. _github pull requests: https://help.github.com/articles/about-pull-requests/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/doc/source/CONTRIBUTING.rst new/stestr-2.3.1/doc/source/CONTRIBUTING.rst --- old/stestr-2.2.0/doc/source/CONTRIBUTING.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/stestr-2.3.1/doc/source/CONTRIBUTING.rst 2017-12-08 22:00:26.000000000 +0100 @@ -0,0 +1,14 @@ +Contributing +============ + +To browse the latest code, see: https://github.com/mtreinish/stestr +To clone the latest code, use: ``git clone https://github.com/mtreinish/stestr.git`` + +Guidelines for contribution are documented at: http://stestr.readthedocs.io/en/latest/developer_guidelines.html + +Use `github pull requests`_ to submit patches. Before you submit a pull request +ensure that all the automated testing will pass by running ``tox`` locally. +This will run the test suite and also the automated style rule checks just as +they will in CI. If CI fails on your change it will not be able to merge. + +.. _github pull requests: https://help.github.com/articles/about-pull-requests/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/doc/source/MANUAL.rst new/stestr-2.3.1/doc/source/MANUAL.rst --- old/stestr-2.2.0/doc/source/MANUAL.rst 2018-11-27 21:49:05.000000000 +0100 +++ new/stestr-2.3.1/doc/source/MANUAL.rst 2018-12-13 21:15:15.000000000 +0100 @@ -73,6 +73,11 @@ The ``group_regex`` option is used to specify is used to provide a scheduler hint for how tests should be divided between test runners. See the :ref:`group_regex` section for more information on how this works. +You can also specify the ``parallel_class=True`` instead of +group_regex to group tests in the stestr scheduler together by +class. Since this is a common use case this enables that without +needing to memorize the complicated regex for ``group_regex`` to do +this. There is also an option to specify all the options in the config file via the CLI. This way you can run stestr directly without having to write a config file @@ -352,6 +357,22 @@ group_regex=([^\.]+\.)+ +However, because grouping tests at the class level is a common use +case there is also a config option, ``parallel_class``, to do +this. For example, you can use:: + + parallel_class=True + +and it will group tests in the same class together. + +.. note:: + This ``parallel_class`` option takes priority over the + ``group_regex`` option. And if both on the CLI and in the config + are set, we use the option on the CLI not in a config file. For + example, ``--group-regex`` on the CLI and ``parallel-class`` in a + config file are set, ``--group-regex`` is higer priority than + ``parallel-class`` in this case. + Test Scheduling --------------- By default stestr schedules the tests by first checking if there is any diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/doc/source/README.rst new/stestr-2.3.1/doc/source/README.rst --- old/stestr-2.2.0/doc/source/README.rst 2018-11-29 21:57:37.000000000 +0100 +++ new/stestr-2.3.1/doc/source/README.rst 2019-03-01 19:22:55.000000000 +0100 @@ -17,7 +17,8 @@ :target: https://pypi.python.org/pypi/stestr :alt: Latest Version -You can see the full rendered docs at: http://stestr.readthedocs.io/en/latest/ +* You can see the full rendered docs at: http://stestr.readthedocs.io/en/latest/ +* The code of the project is on Github: https://github.com/mtreinish/stestr Overview -------- @@ -32,19 +33,16 @@ .. _unittest: https://docs.python.org/3/library/unittest.html .. _subunit: https://github.com/testing-cabal/subunit -stestr originally started as a fork of the `testrepository`_ that concentrates -on being a dedicated test runner for python projects. The generic abstraction -layers which enabled testrepository to work with any subunit emitting runner -are gone. stestr hard codes python-subunit-isms into how it works. The code -base is also designed to try and be explicit, and to provide a python api that -is documented and has examples. +stestr originally started as a fork of the `testrepository`_ project. But, +instead of being an interface for any test runner that used subunit, like +testrepository, stestr concentrated on being a dedicated test runner for python +projects. While stestr was originally forked from testrepository it is not +backwards compatible with testrepository. At a high level the basic concepts of +operation are shared between the two projects but the actual usage is not +exactly the same. .. _testrepository: https://testrepository.readthedocs.org/en/latest -While stestr was originally forked from testrepository it is not 100% backwards -compatible with testrepository. At a high level the basic concepts of operation -are shared between the 2 projects but the actual usage between the 2 is not -exactly the same. Installing stestr ----------------- @@ -65,7 +63,7 @@ ------------ After you install stestr to use it to run tests is pretty straightforward. The -first thing you'll need to do is create a ``.stestr.conf`` file for your +first thing you'll want to do is create a ``.stestr.conf`` file for your project. This file is used to tell stestr where to find tests and basic information about how tests are run. A basic minimal example of the contents of this is:: @@ -75,25 +73,20 @@ which just tells stestr the relative path for the directory to use for test discovery. This is the same as ``--start-directory`` in the standard -`unittest discovery`_ +`unittest discovery`_. .. _unittest discovery: https://docs.python.org/3/library/unittest.html#test-discovery After this file is created you should be all set to start using stestr to run -tests. You can create a repository for test results with the stestr init -command, just run:: - - stestr init - -and it will create a .stestr directory in your cwd that will be used to store -test run results. (if you run stestr run it will create this if it doesn't -exist) Then to run tests just use:: +tests. To run tests just use:: stestr run -it will then execute all the tests found by test discovery. If you're just -running a single test (or module) and want to avoid the overhead of doing test -discovery you can use the ``--no-discover``/``-n`` option. +it will first create a results repository at ``.stestr/`` in the current +working directory and then execute all the tests found by test discovery. If +you're just running a single test (or module) and want to avoid the overhead of +doing test discovery you can use the ``--no-discover``/``-n`` option to specify +that test. For all the details on these commands and more thorough explanation of options see the stestr manual: https://stestr.readthedocs.io/en/latest/MANUAL.html @@ -125,3 +118,18 @@ which will generate the troff file in doc/build/man/stestr.1 which is ready to be packaged and or put in your system's man pages. + +Contributing +------------ + +To browse the latest code, see: https://github.com/mtreinish/stestr +To clone the latest code, use: ``git clone https://github.com/mtreinish/stestr.git`` + +Guidelines for contribution are documented at: http://stestr.readthedocs.io/en/latest/developer_guidelines.html + +Use `github pull requests`_ to submit patches. Before you submit a pull request +ensure that all the automated testing will pass by running ``tox`` locally. +This will run the test suite and also the automated style rule checks just as +they will in CI. If CI fails on your change it will not be able to merge. + +.. _github pull requests: https://help.github.com/articles/about-pull-requests/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/doc/source/index.rst new/stestr-2.3.1/doc/source/index.rst --- old/stestr-2.2.0/doc/source/index.rst 2018-02-18 00:39:04.000000000 +0100 +++ new/stestr-2.3.1/doc/source/index.rst 2019-03-01 19:22:55.000000000 +0100 @@ -13,12 +13,12 @@ README MANUAL + CONTRIBUTING developer_guidelines internal_arch api - Indices and tables ================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/setup.cfg new/stestr-2.3.1/setup.cfg --- old/stestr-2.2.0/setup.cfg 2018-11-30 02:32:07.000000000 +0100 +++ new/stestr-2.3.1/setup.cfg 2019-03-06 02:23:39.000000000 +0100 @@ -11,7 +11,7 @@ Intended Audience :: System Administrators Intended Audience :: Developers License :: OSI Approved :: Apache Software License - Operating System :: POSIX :: Linux + Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 @@ -21,6 +21,11 @@ Programming Language :: Python :: 3.7 Topic :: Software Development :: Testing Topic :: Software Development :: Quality Assurance +project_urls = + Documentation = https://stestr.readthedocs.io + Source Code = https://github.com/mtreinish/stestr + Bug Tracker = https://github.com/mtreinish/stestr/issues +requires-python = >=2.7 [files] packages = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/cli.py new/stestr-2.3.1/stestr/cli.py --- old/stestr-2.2.0/stestr/cli.py 2018-04-07 23:15:34.000000000 +0200 +++ new/stestr-2.3.1/stestr/cli.py 2019-02-15 20:02:23.000000000 +0100 @@ -30,10 +30,14 @@ ) def initialize_app(self, argv): + self.options.debug = True self.LOG.debug('initialize_app') def prepare_to_run_command(self, cmd): self.LOG.debug('prepare_to_run_command %s', cmd.__class__.__name__) + group_regex = '([^\.]*\.)*' \ + if cmd.app_args.parallel_class else cmd.app_args.group_regex + cmd.app_args.group_regex = group_regex def clean_up(self, cmd, result, err): self.LOG.debug('clean_up %s', cmd.__class__.__name__) @@ -92,6 +96,12 @@ " together in the stestr scheduler. If " "both this and the corresponding config file " "option are set this value will be used.") + parser.add_argument('--parallel-class', '-p', + action='store_true', + default=False, + help="Set the flag to group tests by class. NOTE: " + "This flag takes priority over the " + "`--group-regex` option even if it's set.") return parser diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/commands/failing.py new/stestr-2.3.1/stestr/commands/failing.py --- old/stestr-2.2.0/stestr/commands/failing.py 2018-08-09 14:40:52.000000000 +0200 +++ new/stestr-2.3.1/stestr/commands/failing.py 2019-03-01 19:22:55.000000000 +0100 @@ -24,8 +24,18 @@ class Failing(command.Command): - def get_description(self): - return "Show the current failures known by the repository" + """Show the current failures known by the repository. + + Without --subunit, the process exit code will be non-zero if the + previous test run was not successful and test failures are shown. But, + with --subunit, the process exit code is non-zero only if the subunit + stream could not be generated successfully from any failures. The test + results and run status are included in the subunit stream emitted for + the failed tests, so the stream should be used for interpretting the + failing tests. If no subunit stream is emitted with --subunit and a + zero exit code then there were no failures in the most recent run in + the repository. + """ def get_parser(self, prog_name): parser = super(Failing, self).get_parser(prog_name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/commands/init.py new/stestr-2.3.1/stestr/commands/init.py --- old/stestr-2.2.0/stestr/commands/init.py 2018-02-18 00:39:04.000000000 +0100 +++ new/stestr-2.3.1/stestr/commands/init.py 2019-03-01 19:22:55.000000000 +0100 @@ -20,13 +20,11 @@ class Init(command.Command): + """Create a new repository.""" + def take_action(self, parsed_args): init(self.app_args.repo_type, self.app_args.repo_url) - def get_description(self): - help_str = "Create a new repository." - return help_str - def init(repo_type='file', repo_url=None, stdout=sys.stdout): """Initialize a new repository diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/commands/last.py new/stestr-2.3.1/stestr/commands/last.py --- old/stestr-2.2.0/stestr/commands/last.py 2018-08-09 14:40:52.000000000 +0200 +++ new/stestr-2.3.1/stestr/commands/last.py 2019-03-01 19:22:55.000000000 +0100 @@ -25,17 +25,18 @@ class Last(command.Command): - def get_description(self): - help_str = """Show the last run loaded into a repository. + """Show the last run loaded into a repository. - Failing tests are shown on the console and a summary of the run is - printed at the end. + Failing tests are shown on the console and a summary of the run is + printed at the end. - Without --subunit, the process exit code will be non-zero if the test - run was not successful. With --subunit, the process exit code is - non-zero if the subunit stream could not be generated successfully. - """ - return help_str + Without --subunit, the process exit code will be non-zero if the test + run was not successful. With --subunit, the process exit code is + non-zero only if the subunit stream could not be generated + successfully. The test results and run status are included in the + subunit stream, so the stream should be used to determining the result + of the run instead of the exit code when using the --subunit flag. + """ def get_parser(self, prog_name): parser = super(Last, self).get_parser(prog_name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/commands/list.py new/stestr-2.3.1/stestr/commands/list.py --- old/stestr-2.2.0/stestr/commands/list.py 2018-02-18 00:39:04.000000000 +0100 +++ new/stestr-2.3.1/stestr/commands/list.py 2019-03-01 19:22:55.000000000 +0100 @@ -22,12 +22,11 @@ class List(command.Command): + """List the tests for a project. - def get_description(self): - help_str = ("List the tests for a project. You can use a filter just " - "like with the run command to see exactly what tests " - "match") - return help_str + You can use a filter just like with the run command to see exactly what + tests match. + """ def get_parser(self, prog_name): parser = super(List, self).get_parser(prog_name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/commands/load.py new/stestr-2.3.1/stestr/commands/load.py --- old/stestr-2.2.0/stestr/commands/load.py 2018-11-27 21:49:05.000000000 +0100 +++ new/stestr-2.3.1/stestr/commands/load.py 2019-03-01 19:22:55.000000000 +0100 @@ -32,6 +32,19 @@ class Load(command.Command): + """Load a subunit stream into a repository. + + Failing tests are shown on the console and a summary of the stream + is printed at the end. + + Without --subunit, the process exit code will be non-zero if the test + run was not successful. With --subunit, the process exit code is + non-zero if the subunit stream could not be generated successfully. + The test results and run status are included in the subunit stream, so + the stream should be used to determining the result of the run instead + of the exit code when using the --subunit flag. + """ + def get_parser(self, prog_name): parser = super(Load, self).get_parser(prog_name) parser.add_argument("files", nargs="*", default=False, @@ -70,14 +83,6 @@ 'execution') return parser - def get_description(self): - help_str = """Load a subunit stream into a repository. - - Failing tests are shown on the console and a summary of the stream - is printed at the end. - """ - return help_str - def take_action(self, parsed_args): user_conf = user_config.get_user_config(self.app_args.user_config) args = parsed_args diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/commands/run.py new/stestr-2.3.1/stestr/commands/run.py --- old/stestr-2.2.0/stestr/commands/run.py 2018-11-27 21:49:05.000000000 +0100 +++ new/stestr-2.3.1/stestr/commands/run.py 2019-03-06 02:22:28.000000000 +0100 @@ -34,7 +34,28 @@ from stestr import user_config +def _to_int(possible, default=0, out=sys.stderr): + try: + i = int(possible) + except ValueError: + i = default + msg = ('Unable to convert "%s" to an integer. Using %d.\n' % + (possible, default)) + out.write(six.text_type(msg)) + return i + + class Run(command.Command): + """Run the tests for a project and store them into the repository. + + Without --subunit, the process exit code will be non-zero if the test + run was not successful. However, with --subunit, the process exit code + is non-zero only if the subunit stream could not be generated + successfully. The test results and run status are included in the + subunit stream, so the stream should be used to determining the result + of the run instead of the exit code when using the --subunit flag. + """ + def get_parser(self, prog_name): parser = super(Run, self).get_parser(prog_name) parser.add_argument("filters", nargs="*", default=None, @@ -133,11 +154,6 @@ 'execution') return parser - def get_description(self): - help_str = ( - "Run the tests for a project and store them into the repository.") - return help_str - def take_action(self, parsed_args): user_conf = user_config.get_user_config(self.app_args.user_config) filters = parsed_args.filters @@ -172,6 +188,13 @@ suppress_attachments = args.suppress_attachments verbose_level = self.app.options.verbose_level stdout = open(os.devnull, 'w') if verbose_level == 0 else sys.stdout + # Make sure all (python) callers have provided an int() + concurrency = _to_int(concurrency) + if concurrency and concurrency < 0: + msg = ("The provided concurrency value: %s is not valid. An " + "integer >= 0 must be used.\n" % concurrency) + stdout.write(msg) + return 2 result = run_command( config=self.app_args.config, repo_type=self.app_args.repo_type, repo_url=self.app_args.repo_url, @@ -308,6 +331,13 @@ exit(1) repo = util.get_repo_initialise(repo_type, repo_url) combine_id = None + concurrency = _to_int(concurrency) + + if concurrency and concurrency < 0: + msg = ("The provided concurrency value: %s is not valid. An integer " + ">= 0 must be used.\n" % concurrency) + stdout.write(msg) + return 2 if combine: latest_id = repo.latest_id() combine_id = six.text_type(latest_id) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/commands/slowest.py new/stestr-2.3.1/stestr/commands/slowest.py --- old/stestr-2.2.0/stestr/commands/slowest.py 2018-02-18 00:39:04.000000000 +0100 +++ new/stestr-2.3.1/stestr/commands/slowest.py 2019-03-01 19:22:55.000000000 +0100 @@ -23,13 +23,10 @@ class Slowest(command.Command): - def get_description(self): - help_str = """Show the slowest tests from the last test run. + """Show the slowest tests from the last test run. - This command shows a table, with the longest running - tests at the top. - """ - return help_str + This command shows a table, with the longest running tests at the top. + """ def get_parser(self, prog_name): parser = super(Slowest, self).get_parser(prog_name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/config_file.py new/stestr-2.3.1/stestr/config_file.py --- old/stestr-2.2.0/stestr/config_file.py 2018-11-27 21:49:05.000000000 +0100 +++ new/stestr-2.3.1/stestr/config_file.py 2019-03-01 19:22:55.000000000 +0100 @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +import os import re import sys @@ -38,7 +39,7 @@ serial=False, worker_path=None, concurrency=0, blacklist_file=None, whitelist_file=None, black_regex=None, - randomize=False): + randomize=False, parallel_class=None): """Get a test_processor.TestProcessorFixture for this config file Any parameters about running tests will be used for initialize the @@ -81,6 +82,10 @@ test list. :param bool randomize: Randomize the test order after they are partitioned into separate workers + :param bool parallel_class: Set the flag to group tests together in the + stestr scheduler by class. If both this and the corresponding + config file option which includes `group-regex` are set, this value + will be used. :returns: a TestProcessorFixture object for the specified config file and any arguments passed into this function @@ -99,13 +104,34 @@ elif not top_dir: top_dir = './' - python = 'python' if sys.platform == 'win32' else '${PYTHON:-python}' - command = "%s -m subunit.run discover -t" \ - " %s %s $LISTOPT $IDOPTION" % (python, top_dir, test_path) + stestr_python = sys.executable + # let's try to be explicit, even if it means a longer set of ifs + if sys.platform == 'win32': + # it may happen, albeit rarely + if not stestr_python: + raise RuntimeError("The Python interpreter was not found") + python = stestr_python + else: + if os.environ.get('PYTHON'): + python = '${PYTHON}' + elif stestr_python: + python = stestr_python + else: + raise RuntimeError("The Python interpreter was not found and " + "PYTHON is not set") + + command = '%s -m subunit.run discover -t "%s" "%s" ' \ + '$LISTOPT $IDOPTION' % (python, top_dir, test_path) listopt = "--list" idoption = "--load-list $IDFILE" # If the command contains $IDOPTION read that command from config # Use a group regex if one is defined + if parallel_class: + group_regex = '([^\.]*\.)*' + if not group_regex \ + and self.parser.has_option('DEFAULT', 'parallel_class') \ + and self.parser.getboolean('DEFAULT', 'parallel_class'): + group_regex = '([^\.]*\.)*' if not group_regex and self.parser.has_option('DEFAULT', 'group_regex'): group_regex = self.parser.get('DEFAULT', 'group_regex') @@ -116,7 +142,6 @@ return match.group(0) else: group_callback = None - # Handle the results repository repository = util.get_repo_open(repo_type, repo_url) return test_processor.TestProcessorFixture( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/tests/test_bisect_return_codes.py new/stestr-2.3.1/stestr/tests/test_bisect_return_codes.py --- old/stestr-2.2.0/stestr/tests/test_bisect_return_codes.py 2018-11-27 21:49:05.000000000 +0100 +++ new/stestr-2.3.1/stestr/tests/test_bisect_return_codes.py 2019-02-15 20:02:23.000000000 +0100 @@ -33,10 +33,12 @@ self.setup_cfg_file = os.path.join(self.directory, 'setup.cfg') self.init_file = os.path.join(self.test_dir, '__init__.py') self.setup_py = os.path.join(self.directory, 'setup.py') + self.user_config = os.path.join(self.directory, 'stestr.yaml') shutil.copy('stestr/tests/files/testr-conf', self.testr_conf_file) shutil.copy('setup.py', self.setup_py) shutil.copy('stestr/tests/files/setup.cfg', self.setup_cfg_file) shutil.copy('stestr/tests/files/__init__.py', self.init_file) + shutil.copy('stestr/tests/files/stestr.yaml', self.user_config) # Move around the test code self.serial_fail_file = os.path.join(self.test_dir, @@ -58,8 +60,8 @@ 'stestr run returned an unexpected return code' 'Stdout: %s\nStderr: %s' % (out, err)) p_analyze = subprocess.Popen( - "stestr run --analyze-isolation", shell=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) + "stestr --user-config stestr.yaml run --analyze-isolation", + shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p_analyze.communicate() out = out.decode('utf-8') # For debugging potential failures diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/tests/test_config_file.py new/stestr-2.3.1/stestr/tests/test_config_file.py --- old/stestr-2.2.0/stestr/tests/test_config_file.py 2017-07-28 00:22:49.000000000 +0200 +++ new/stestr-2.3.1/stestr/tests/test_config_file.py 2019-03-01 19:22:55.000000000 +0100 @@ -29,30 +29,81 @@ @mock.patch.object(config_file, 'sys') def _check_get_run_command(self, mock_sys, mock_TestProcessorFixture, mock_get_repo_open, platform='win32', - expected_python='python'): + group_regex='.*', parallel_class=False, + sys_executable='/usr/bin/python', + expected_python='/usr/bin/python', + expected_group_callback=mock.ANY, + environment=None): mock_sys.platform = platform + mock_sys.executable = sys_executable + if environment is None: + environment = {'PYTHON': ''} - fixture = self._testr_conf.get_run_command(test_path='fake_test_path', - top_dir='fake_top_dir', - group_regex='.*') + with mock.patch.dict('os.environ', environment): + fixture = \ + self._testr_conf.get_run_command(test_path='fake_test_path', + top_dir='fake_top_dir', + group_regex=group_regex, + parallel_class=parallel_class) self.assertEqual(mock_TestProcessorFixture.return_value, fixture) mock_get_repo_open.assert_called_once_with('file', None) - command = "%s -m subunit.run discover -t %s %s $LISTOPT $IDOPTION" % ( - expected_python, 'fake_top_dir', 'fake_test_path') + command = '%s -m subunit.run discover -t "%s" "%s" ' \ + '$LISTOPT $IDOPTION' % (expected_python, 'fake_top_dir', + 'fake_test_path') # Ensure TestProcessorFixture is created with defaults except for where # we specfied and with the correct python. mock_TestProcessorFixture.assert_called_once_with( None, command, "--list", "--load-list $IDFILE", mock_get_repo_open.return_value, black_regex=None, - blacklist_file=None, concurrency=0, group_callback=mock.ANY, + blacklist_file=None, concurrency=0, + group_callback=expected_group_callback, test_filters=None, randomize=False, serial=False, whitelist_file=None, worker_path=None) + @mock.patch.object(config_file, 'sys') + def _check_get_run_command_exception(self, mock_sys, platform='win32', + sys_executable='/usr/bin/python', + environment=None): + mock_sys.platform = platform + mock_sys.executable = sys_executable + if environment is None: + environment = {'PYTHON': ''} + + with mock.patch.dict('os.environ', environment): + self.assertRaises(RuntimeError, self._testr_conf.get_run_command, + test_path='fake_test_path', + top_dir='fake_top_dir') + def test_get_run_command_linux(self): - self._check_get_run_command(platform='linux2', - expected_python='${PYTHON:-python}') + self._check_get_run_command( + platform='linux2', + expected_python='/usr/bin/python') + + def test_get_run_command_emptysysexecutable_noenv(self): + self._check_get_run_command_exception( + platform='linux2', + sys_executable=None) + + def test_get_run_command_emptysysexecutable_win32(self): + self._check_get_run_command_exception( + platform='win32', sys_executable=None, + environment={'PYTHON': 'python3'}) + + def test_get_run_command_emptysysexecutable_withenv(self): + self._check_get_run_command( + platform='linux2', sys_executable=None, + expected_python='${PYTHON}', + environment={'PYTHON': '/usr/bin/python3'}) def test_get_run_command_win32(self): self._check_get_run_command() + + def test_get_run_command_parallel_class(self): + self._check_get_run_command(parallel_class=True) + + def test_get_run_command_nogroup_regex_noparallel_class(self): + self._testr_conf.parser.has_option.return_value = False + self._check_get_run_command(group_regex='', + expected_group_callback=None) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/tests/test_return_codes.py new/stestr-2.3.1/stestr/tests/test_return_codes.py --- old/stestr-2.2.0/stestr/tests/test_return_codes.py 2018-11-27 21:49:05.000000000 +0100 +++ new/stestr-2.3.1/stestr/tests/test_return_codes.py 2019-03-06 02:22:28.000000000 +0100 @@ -46,12 +46,14 @@ self.failing_file = os.path.join(self.test_dir, 'test_failing.py') self.init_file = os.path.join(self.test_dir, '__init__.py') self.setup_py = os.path.join(self.directory, 'setup.py') + self.user_config = os.path.join(self.directory, 'stestr.yaml') shutil.copy('stestr/tests/files/testr-conf', self.testr_conf_file) shutil.copy('stestr/tests/files/passing-tests', self.passing_file) shutil.copy('stestr/tests/files/failing-tests', self.failing_file) shutil.copy('setup.py', self.setup_py) shutil.copy('stestr/tests/files/setup.cfg', self.setup_cfg_file) shutil.copy('stestr/tests/files/__init__.py', self.init_file) + shutil.copy('stestr/tests/files/stestr.yaml', self.user_config) self.stdout = StringIO() self.stderr = StringIO() @@ -172,12 +174,20 @@ self.assertRunExit(cmd, 0) def test_serial_subunit_passing(self): - self.assertRunExit('stestr run --subunit passing', 0, - subunit=True) + self.assertRunExit('stestr --user-config stestr.yaml run --subunit ' + '--serial passing', 0, subunit=True) + + def test_serial_subunit_failing(self): + self.assertRunExit('stestr --user-config stestr.yaml run --subunit ' + '--serial failing', 0, subunit=True) def test_parallel_subunit_passing(self): - self.assertRunExit('stestr run --subunit passing', 0, - subunit=True) + self.assertRunExit('stestr --user-config stestr.yaml run --subunit ' + 'passing', 0, subunit=True) + + def test_parallel_subunit_failing(self): + self.assertRunExit('stestr --user-config stestr.yaml run --subunit ' + 'failing', 0, subunit=True) def test_slowest_passing(self): self.assertRunExit('stestr run --slowest passing', 0) @@ -189,8 +199,15 @@ self.assertRunExit('stestr run --until-failure', 1) def test_until_failure_with_subunit_fails(self): - self.assertRunExit('stestr run --until-failure --subunit', 1, - subunit=True) + self.assertRunExit('stestr --user-config stestr.yaml run ' + '--until-failure --subunit', 1, subunit=True) + + def test_with_parallel_class(self): + # NOTE(masayukig): Ideally, it's better to figure out the + # difference between with --parallel-class and without + # --parallel-class. However, it's difficult to make such a + # test from a command line based test. + self.assertRunExit('stestr --parallel-class run passing', 0) def test_list(self): self.assertRunExit('stestr list', 0) @@ -233,13 +250,14 @@ self.assertRunExit('stestr load', 0, stdin=stream) def test_load_from_stdin_quiet(self): - out, err = self.assertRunExit('stestr -q run passing', 0) + out, err = self.assertRunExit('stestr --user-config stestr.yaml -q ' + 'run passing', 0) self.assertEqual(out.decode('utf-8'), '') # FIXME(masayukig): We get some warnings when we run a coverage job. # So, just ignore 'err' here. - stream = self._get_cmd_stdout( - 'stestr last --subunit')[0] - out, err = self.assertRunExit('stestr -q load', 0, stdin=stream) + stream = self._get_cmd_stdout('stestr last --subunit')[0] + out, err = self.assertRunExit('stestr --user-config stestr.yaml -q ' + 'load', 0, stdin=stream) self.assertEqual(out.decode('utf-8'), '') self.assertEqual(err.decode('utf-8'), '') @@ -275,6 +293,19 @@ self.assertEqual(0, run.run_command(filters=['passing'], serial=True, stdout=stdout.stream)) + def test_str_concurrency_passing_from_func(self): + stdout = fixtures.StringStream('stdout') + self.useFixture(stdout) + self.assertEqual(0, run.run_command(filters=['passing'], + concurrency='1', + stdout=stdout.stream)) + + def test_str_concurrency_fails_from_func(self): + stdout = fixtures.StringStream('stdout') + self.useFixture(stdout) + self.assertEqual(1, run.run_command(concurrency='1', + stdout=stdout.stream)) + def test_serial_fails_from_func(self): stdout = fixtures.StringStream('stdout') self.useFixture(stdout) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr/tests/test_run.py new/stestr-2.3.1/stestr/tests/test_run.py --- old/stestr-2.2.0/stestr/tests/test_run.py 1970-01-01 01:00:00.000000000 +0100 +++ new/stestr-2.3.1/stestr/tests/test_run.py 2019-03-06 02:22:28.000000000 +0100 @@ -0,0 +1,39 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import io + +from stestr.commands import run +from stestr.tests import base + + +class TestRunCommand(base.TestCase): + def test_to_int_positive_int(self): + self.assertEqual(29, run._to_int(29)) + + def test_to_int_positive_int_str(self): + self.assertEqual(42, run._to_int('42')) + + def test_to_int_negative_int(self): + self.assertEqual(-2, run._to_int(-2)) + + def test_to_int_negative_int_str(self): + self.assertEqual(-45, run._to_int('-45')) + + def test_to_int_invalid_str(self): + fake_stderr = io.StringIO() + out = run._to_int('I am not an int', out=fake_stderr) + expected = ( + 'Unable to convert "I am not an int" to an integer. ' + 'Using 0.\n') + self.assertEqual(fake_stderr.getvalue(), expected) + self.assertEqual(0, out) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr.egg-info/PKG-INFO new/stestr-2.3.1/stestr.egg-info/PKG-INFO --- old/stestr-2.2.0/stestr.egg-info/PKG-INFO 2018-11-30 02:32:05.000000000 +0100 +++ new/stestr-2.3.1/stestr.egg-info/PKG-INFO 2019-03-06 02:23:37.000000000 +0100 @@ -1,11 +1,14 @@ Metadata-Version: 2.1 Name: stestr -Version: 2.2.0 +Version: 2.3.1 Summary: A parallel Python test runner built around subunit Home-page: http://stestr.readthedocs.io/en/latest/ Author: Matthew Treinish Author-email: mtrein...@kortar.org License: UNKNOWN +Project-URL: Documentation, https://stestr.readthedocs.io +Project-URL: Source Code, https://github.com/mtreinish/stestr +Project-URL: Bug Tracker, https://github.com/mtreinish/stestr/issues Description: stestr ====== @@ -25,7 +28,8 @@ :target: https://pypi.python.org/pypi/stestr :alt: Latest Version - You can see the full rendered docs at: http://stestr.readthedocs.io/en/latest/ + * You can see the full rendered docs at: http://stestr.readthedocs.io/en/latest/ + * The code of the project is on Github: https://github.com/mtreinish/stestr Overview -------- @@ -40,19 +44,16 @@ .. _unittest: https://docs.python.org/3/library/unittest.html .. _subunit: https://github.com/testing-cabal/subunit - stestr originally started as a fork of the `testrepository`_ that concentrates - on being a dedicated test runner for python projects. The generic abstraction - layers which enabled testrepository to work with any subunit emitting runner - are gone. stestr hard codes python-subunit-isms into how it works. The code - base is also designed to try and be explicit, and to provide a python api that - is documented and has examples. + stestr originally started as a fork of the `testrepository`_ project. But, + instead of being an interface for any test runner that used subunit, like + testrepository, stestr concentrated on being a dedicated test runner for python + projects. While stestr was originally forked from testrepository it is not + backwards compatible with testrepository. At a high level the basic concepts of + operation are shared between the two projects but the actual usage is not + exactly the same. .. _testrepository: https://testrepository.readthedocs.org/en/latest - While stestr was originally forked from testrepository it is not 100% backwards - compatible with testrepository. At a high level the basic concepts of operation - are shared between the 2 projects but the actual usage between the 2 is not - exactly the same. Installing stestr ----------------- @@ -73,7 +74,7 @@ ------------ After you install stestr to use it to run tests is pretty straightforward. The - first thing you'll need to do is create a ``.stestr.conf`` file for your + first thing you'll want to do is create a ``.stestr.conf`` file for your project. This file is used to tell stestr where to find tests and basic information about how tests are run. A basic minimal example of the contents of this is:: @@ -83,25 +84,20 @@ which just tells stestr the relative path for the directory to use for test discovery. This is the same as ``--start-directory`` in the standard - `unittest discovery`_ + `unittest discovery`_. .. _unittest discovery: https://docs.python.org/3/library/unittest.html#test-discovery After this file is created you should be all set to start using stestr to run - tests. You can create a repository for test results with the stestr init - command, just run:: - - stestr init - - and it will create a .stestr directory in your cwd that will be used to store - test run results. (if you run stestr run it will create this if it doesn't - exist) Then to run tests just use:: + tests. To run tests just use:: stestr run - it will then execute all the tests found by test discovery. If you're just - running a single test (or module) and want to avoid the overhead of doing test - discovery you can use the ``--no-discover``/``-n`` option. + it will first create a results repository at ``.stestr/`` in the current + working directory and then execute all the tests found by test discovery. If + you're just running a single test (or module) and want to avoid the overhead of + doing test discovery you can use the ``--no-discover``/``-n`` option to specify + that test. For all the details on these commands and more thorough explanation of options see the stestr manual: https://stestr.readthedocs.io/en/latest/MANUAL.html @@ -134,13 +130,28 @@ which will generate the troff file in doc/build/man/stestr.1 which is ready to be packaged and or put in your system's man pages. + Contributing + ------------ + + To browse the latest code, see: https://github.com/mtreinish/stestr + To clone the latest code, use: ``git clone https://github.com/mtreinish/stestr.git`` + + Guidelines for contribution are documented at: http://stestr.readthedocs.io/en/latest/developer_guidelines.html + + Use `github pull requests`_ to submit patches. Before you submit a pull request + ensure that all the automated testing will pass by running ``tox`` locally. + This will run the test suite and also the automated style rule checks just as + they will in CI. If CI fails on your change it will not be able to merge. + + .. _github pull requests: https://help.github.com/articles/about-pull-requests/ + Platform: UNKNOWN Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Apache Software License -Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 @@ -150,5 +161,5 @@ Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Software Development :: Quality Assurance -Provides-Extra: test Provides-Extra: sql +Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr.egg-info/SOURCES.txt new/stestr-2.3.1/stestr.egg-info/SOURCES.txt --- old/stestr-2.2.0/stestr.egg-info/SOURCES.txt 2018-11-30 02:32:07.000000000 +0100 +++ new/stestr-2.3.1/stestr.egg-info/SOURCES.txt 2019-03-06 02:23:38.000000000 +0100 @@ -15,6 +15,7 @@ tox.ini .github/issue_template.md .travis/coveralls.sh +doc/source/CONTRIBUTING.rst doc/source/MANUAL.rst doc/source/README.rst doc/source/api.rst @@ -84,6 +85,7 @@ stestr/tests/test_bisect_tests.py stestr/tests/test_config_file.py stestr/tests/test_return_codes.py +stestr/tests/test_run.py stestr/tests/test_scheduler.py stestr/tests/test_selection.py stestr/tests/test_slowest.py @@ -97,6 +99,7 @@ stestr/tests/files/failing-tests stestr/tests/files/passing-tests stestr/tests/files/setup.cfg +stestr/tests/files/stestr.yaml stestr/tests/files/testr-conf stestr/tests/repository/__init__.py stestr/tests/repository/test_file.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.2.0/stestr.egg-info/pbr.json new/stestr-2.3.1/stestr.egg-info/pbr.json --- old/stestr-2.2.0/stestr.egg-info/pbr.json 2018-11-30 02:32:06.000000000 +0100 +++ new/stestr-2.3.1/stestr.egg-info/pbr.json 2019-03-06 02:23:37.000000000 +0100 @@ -1 +1 @@ -{"git_version": "8d35dcb", "is_release": true} \ No newline at end of file +{"git_version": "4ae2b23", "is_release": true} \ No newline at end of file