Hello community, here is the log from the commit of package python-stestr for openSUSE:Factory checked in at 2020-03-08 22:21:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-stestr (Old) and /work/SRC/openSUSE:Factory/.python-stestr.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-stestr" Sun Mar 8 22:21:38 2020 rev:14 rq:780391 version:2.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-stestr/python-stestr.changes 2019-11-22 10:26:00.561263197 +0100 +++ /work/SRC/openSUSE:Factory/.python-stestr.new.26092/python-stestr.changes 2020-03-08 22:21:41.771987083 +0100 @@ -1,0 +2,19 @@ +Fri Feb 28 21:47:29 UTC 2020 - Dirk Mueller <[email protected]> + +- update to 2.6.0: + * Add python 3.8 macOS and windows ci jobs + * Update test\_processor.py + * Update config\_file.py + * Update cli.py + * Remove 3.8 azure pipelines jobs + * Update stestr/scheduler.py + * Update to recent hacking version + * Add Python 3.8 support + * Add --pdb flag to stestr run + * Add unit tests around repo initialize + * Handle empty .stestr directory to initialize + * Update issue templates + * Escape Windows paths + * Stop encoding attachments text + +------------------------------------------------------------------- Old: ---- stestr-2.5.1.tar.gz New: ---- stestr-2.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-stestr.spec ++++++ --- /var/tmp/diff_new_pack.rJ22Yo/_old 2020-03-08 22:21:42.635987616 +0100 +++ /var/tmp/diff_new_pack.rJ22Yo/_new 2020-03-08 22:21:42.635987616 +0100 @@ -1,7 +1,7 @@ # -# spec file for package python-stestr +# spec file for package python # -# Copyright (c) 2019 SUSE LLC +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -26,7 +26,7 @@ %bcond_with test %endif Name: python-stestr%{psuffix} -Version: 2.5.1 +Version: 2.6.0 Release: 0 Summary: A test runner runner similar to testrepository License: Apache-2.0 ++++++ stestr-2.5.1.tar.gz -> stestr-2.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/.github/ISSUE_TEMPLATE/bug_report.md new/stestr-2.6.0/.github/ISSUE_TEMPLATE/bug_report.md --- old/stestr-2.5.1/.github/ISSUE_TEMPLATE/bug_report.md 1970-01-01 01:00:00.000000000 +0100 +++ new/stestr-2.6.0/.github/ISSUE_TEMPLATE/bug_report.md 2019-12-13 19:59:07.000000000 +0100 @@ -0,0 +1,30 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: 'bug' +assignees: '' + +--- + +**Issue description** + +Include a description of the issue encountered, and what the expected behavior +was. Also include any configuration, test suite, or other relevant information +to reproduce the issue. + +Note if you encounter an error message try to re-run the command with --debug to print any tracebacks + +**Expected behavior and actual behavior** + +**Steps to reproduce the problem** + +**Specifications like the version of the project, operating system, or hardware** + +**System information** + - OS: [e.g. Windows10, openSUSE 15.1, Ubuntu 18.04] + - stestr version (`stestr --version`): + - Python release (`python --version`): + - pip packages (`pip freeze`): + +**Additional information** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/.github/ISSUE_TEMPLATE/feature_request.md new/stestr-2.6.0/.github/ISSUE_TEMPLATE/feature_request.md --- old/stestr-2.5.1/.github/ISSUE_TEMPLATE/feature_request.md 1970-01-01 01:00:00.000000000 +0100 +++ new/stestr-2.6.0/.github/ISSUE_TEMPLATE/feature_request.md 2019-12-13 19:59:07.000000000 +0100 @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: 'enhancement' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/.github/issue_template.md new/stestr-2.6.0/.github/issue_template.md --- old/stestr-2.5.1/.github/issue_template.md 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/.github/issue_template.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,24 +0,0 @@ -### Issue description - -Include a description of the issue encountered, and what the expected behavior -was. Also include any configuration, test suite, or other relevant information -to reproduce the issue. - -Note if you encounter an error message try to re-run the command with --debug to print any tracebacks - -#### Expected behavior and actual behavior - -#### Steps to reproduce the problem - -#### Specifications like the version of the project, operating system, or hardware - -### System information - -**stestr version (`stestr --version`):** - -**Python release (`python --version`):** - -**pip packages (`pip freeze`):** - - -### Additional information diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/.travis.yml new/stestr-2.6.0/.travis.yml --- old/stestr-2.5.1/.travis.yml 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/.travis.yml 2019-12-13 19:59:07.000000000 +0100 @@ -7,6 +7,9 @@ - python: "3.6" env: TOXENV=py36 - os: linux + python: 3.8 + env: TOXENV=py38 + - os: linux dist: xenial python: 3.7 env: TOXENV=py37 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/AUTHORS new/stestr-2.6.0/AUTHORS --- old/stestr-2.5.1/AUTHORS 2019-09-03 15:17:27.000000000 +0200 +++ new/stestr-2.6.0/AUTHORS 2019-12-13 19:59:21.000000000 +0100 @@ -1,8 +1,11 @@ Alfredo Moralejo <[email protected]> Chandan Kumar <[email protected]> +Dirk Mueller <[email protected]> +Dirk Mueller <[email protected]> +Lucian Petrut <[email protected]> Luigi Toscano <[email protected]> Masayuki Igawa <[email protected]> Matthew Treinish <[email protected]> Sergey Vilgelm <[email protected]> -Sorin Sbarnea <[email protected]> Tony Breeds <[email protected]> +pvinci <[email protected]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/ChangeLog new/stestr-2.6.0/ChangeLog --- old/stestr-2.5.1/ChangeLog 2019-09-03 15:17:27.000000000 +0200 +++ new/stestr-2.6.0/ChangeLog 2019-12-13 19:59:21.000000000 +0100 @@ -1,6 +1,24 @@ CHANGES ======= +2.6.0 +----- + +* Add python 3.8 macOS and windows ci jobs +* Update test\_processor.py +* Update config\_file.py +* Update cli.py +* Remove 3.8 azure pipelines jobs +* Update stestr/scheduler.py +* Update to recent hacking version +* Add Python 3.8 support +* Add --pdb flag to stestr run +* Add unit tests around repo initialize +* Handle empty .stestr directory to initialize +* Update issue templates +* Escape Windows paths +* Stop encoding attachments text + 2.5.1 ----- @@ -89,28 +107,4 @@ * Change title of project in readme * Add a better description to README Overview section -* Fix discovery import error formatting on py3 * Cleanup unused parameters in \_run\_tests -* Enable doc8 -* Add all stream to repo even if some tests fail -* Extract loading case code to \_load\_case() function -* Make test running serially when just loading -* Fix time measurement for load command too -* Use reported times instead of wall time in subunit-trace -* Add support for test class and method by path on no-discover - -2.1.1 ------ - -* Add support for python 3.7 -* Fix handling of unexpected success results -* Allow stestr to be called as a module (#185) -* Make warning and error messages use stderr -* Add error handling for invalid input regexes -* Cleanup the manpage section on dealing with failed tests -* Cleanup argument help text on load command -* Fix description for the stestr run command - -2.1.0 ------ - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/PKG-INFO new/stestr-2.6.0/PKG-INFO --- old/stestr-2.5.1/PKG-INFO 2019-09-03 15:17:27.000000000 +0200 +++ new/stestr-2.6.0/PKG-INFO 2019-12-13 19:59:21.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: stestr -Version: 2.5.1 +Version: 2.6.0 Summary: A parallel Python test runner built around subunit Home-page: http://stestr.readthedocs.io/en/latest/ Author: Matthew Treinish @@ -176,6 +176,7 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Software Development :: Quality Assurance Provides-Extra: sql diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/azure-pipelines.yml new/stestr-2.6.0/azure-pipelines.yml --- old/stestr-2.5.1/azure-pipelines.yml 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/azure-pipelines.yml 2019-12-13 19:59:07.000000000 +0100 @@ -19,6 +19,8 @@ python.version: '3.6' Python37: python.version: '3.7' + Python38: + python.version: '3.8' steps: - task: UsePythonVersion@0 inputs: @@ -48,6 +50,8 @@ python.version: '3.6' Python37: python.version: '3.7' + Python38: + python.version: '3.8' steps: - task: UsePythonVersion@0 inputs: @@ -59,4 +63,4 @@ pip install -U tox displayName: 'Install dependencies' - script: tox -e py - displayName: 'Run Tox' \ No newline at end of file + displayName: 'Run Tox' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/doc/source/MANUAL.rst new/stestr-2.6.0/doc/source/MANUAL.rst --- old/stestr-2.5.1/doc/source/MANUAL.rst 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/doc/source/MANUAL.rst 2019-12-13 19:59:07.000000000 +0100 @@ -113,6 +113,21 @@ will skip discovery and directly call the test runner on the test method in the specified test class. +Running with pdb +'''''''''''''''' + +If you'd like to run pdb during the execution of the tests you should use the +``--pdb`` flag on ``stestr run``. This flag behaves the same way as the +``--no-discover`` flag except that it does not launch an external process to +run the tests. This enables pdb to work as expected without any issues with the +tradeoff that output from the test runner will occur after tests have finished +execution. + +It's also worth noting that if you are using a fixture to capture stdout (which +is a common practice for parallel test excecution) you'll likely want to +disable that fixture when running with pdb. Those fixtures can often interfere +with pdb's output and will sometimes capture output from pdb. + Test Selection -------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/setup.cfg new/stestr-2.6.0/setup.cfg --- old/stestr-2.5.1/setup.cfg 2019-09-03 15:17:27.000000000 +0200 +++ new/stestr-2.6.0/setup.cfg 2019-12-13 19:59:21.000000000 +0100 @@ -20,6 +20,7 @@ Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 Topic :: Software Development :: Testing Topic :: Software Development :: Quality Assurance project_urls = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/cli.py new/stestr-2.6.0/stestr/cli.py --- old/stestr-2.5.1/stestr/cli.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/cli.py 2019-12-13 19:59:07.000000000 +0100 @@ -36,7 +36,7 @@ def prepare_to_run_command(self, cmd): self.LOG.debug('prepare_to_run_command %s', cmd.__class__.__name__) - group_regex = '([^\.]*\.)*' \ + group_regex = r'([^\.]*\.)*' \ if cmd.app_args.parallel_class else cmd.app_args.group_regex cmd.app_args.group_regex = group_regex diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/commands/init.py new/stestr-2.6.0/stestr/commands/init.py --- old/stestr-2.5.1/stestr/commands/init.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/commands/init.py 2019-12-13 19:59:07.000000000 +0100 @@ -12,6 +12,7 @@ """Initialise a new repository.""" +import errno import sys from cliff import command @@ -47,7 +48,7 @@ try: util.get_repo_initialise(repo_type, repo_url) except OSError as e: - if e.errno != 17: + if e.errno != errno.EEXIST: raise repo_path = repo_url or './stestr' stdout.write('The specified repository directory %s already exists. ' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/commands/load.py new/stestr-2.6.0/stestr/commands/load.py --- old/stestr-2.5.1/stestr/commands/load.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/commands/load.py 2019-12-13 19:59:07.000000000 +0100 @@ -13,6 +13,7 @@ """Load data into a repository.""" +import errno import functools import os import sys @@ -148,7 +149,7 @@ used by the run command to both output the results as well as store the result in the repository. - :param bool force_init: Initialize the specifiedrepository if it hasn't + :param bool force_init: Initialize the specified repository if it hasn't been created. :param list in_streams: A list of file objects that will be saved into the repository @@ -184,7 +185,17 @@ repo = util.get_repo_open(repo_type, repo_url) except repository.RepositoryNotFound: if force_init: - repo = util.get_repo_initialise(repo_type, repo_url) + try: + repo = util.get_repo_initialise(repo_type, repo_url) + except OSError as e: + if e.errno != errno.EEXIST: + raise + repo_path = repo_url or './stestr' + stdout.write('The specified repository directory %s already ' + 'exists. Please check if the repository already ' + 'exists or select a different path\n' + % repo_path) + exit(1) else: raise # Not a full implementation of TestCase, but we only need to iterate diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/commands/run.py new/stestr-2.6.0/stestr/commands/run.py --- old/stestr-2.5.1/stestr/commands/run.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/commands/run.py 2019-12-13 19:59:07.000000000 +0100 @@ -12,6 +12,9 @@ """Run a projects tests and load them into stestr.""" +import errno +import functools +import io import os import subprocess import sys @@ -30,6 +33,8 @@ from stestr.repository import abstract as repository from stestr.repository import util from stestr import results +from stestr.subunit_runner import program +from stestr.subunit_runner import run as subunit_run from stestr.testlist import parse_list from stestr import user_config @@ -121,6 +126,13 @@ help="Takes in a single test to bypasses test " "discover and just execute the test specified. A " "file may be used in place of a test name.") + parser.add_argument('--pdb', default=None, metavar='TEST_ID', + help="Run a single test id with the intent of " + "using pdb. This does not launch any separate " + "processes to ensure pdb works as expected. It " + "will bypass test discovery and just execute the " + "test specified. A file may be used in place of a " + "test name.") parser.add_argument('--random', action="store_true", default=False, help="Randomize the test order after they are " @@ -232,7 +244,7 @@ filters=filters, pretty_out=pretty_out, color=color, stdout=stdout, abbreviate=abbreviate, suppress_attachments=suppress_attachments, - all_attachments=all_attachments) + all_attachments=all_attachments, pdb=args.pdb) # Always output slowest test info if requested, regardless of other # test run options @@ -273,7 +285,7 @@ no_discover=False, random=False, combine=False, filters=None, pretty_out=True, color=False, stdout=sys.stdout, abbreviate=False, suppress_attachments=False, - all_attachments=False): + all_attachments=False, pdb=False): """Function to execute the run command This function implements the run command. It will run the tests specified @@ -336,6 +348,9 @@ will not print attachments on successful test execution. :param bool all_attachments: When set true subunit_trace will print all text attachments on successful test execution. + :param str pdb: Takes in a single test_id to bypasses test + discover and just execute the test specified without launching any + additional processes. A file name may be used in place of a test name. :return return_code: The exit code for the command. 0 for success and > 0 for failures. @@ -354,7 +369,17 @@ "--test-path ") stdout.write(msg) exit(1) - repo = util.get_repo_initialise(repo_type, repo_url) + try: + repo = util.get_repo_initialise(repo_type, repo_url) + except OSError as e: + if e.errno != errno.EEXIST: + raise + repo_path = repo_url or './stestr' + stdout.write('The specified repository directory %s already ' + 'exists. Please check if the repository already ' + 'exists or select a different path\n' % repo_path) + return 1 + combine_id = None concurrency = _to_int(concurrency) @@ -366,6 +391,17 @@ if combine: latest_id = repo.latest_id() combine_id = six.text_type(latest_id) + if no_discover and pdb: + msg = ("--no-discover and --pdb are mutually exclusive options, " + "only specify one at a time") + stdout.write(msg) + return 2 + if pdb and until_failure: + msg = ("pdb mode does not function with the --until-failure flag, " + "only specify one at a time") + stdout.write(msg) + return 2 + if no_discover: ids = no_discover if '::' in ids: @@ -418,6 +454,29 @@ if result: return result + if pdb: + ids = pdb + if '::' in ids: + ids = ids.replace('::', '.') + if ids.find('/') != -1: + root = ids.replace('.py', '') + ids = root.replace('/', '.') + runner = subunit_run.SubunitTestRunner + stream = io.BytesIO() + program.TestProgram(module=None, argv=['stestr', ids], + testRunner=functools.partial(runner, + stdout=stream)) + stream.seek(0) + run_proc = [('subunit', stream)] + return load.load(in_streams=run_proc, + subunit_out=subunit_out, + repo_type=repo_type, + repo_url=repo_url, run_id=combine_id, + pretty_out=pretty_out, + color=color, stdout=stdout, abbreviate=abbreviate, + suppress_attachments=suppress_attachments, + all_attachments=all_attachments) + if failing or analyze_isolation: ids = _find_failing(repo) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/config_file.py new/stestr-2.6.0/stestr/config_file.py --- old/stestr-2.5.1/stestr/config_file.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/config_file.py 2019-12-13 19:59:07.000000000 +0100 @@ -28,11 +28,21 @@ :param str config_file: The path to the config file to use """ + _escape_trailing_backslash_re = re.compile(r'(?<=[^\\])\\$') + def __init__(self, config_file): self.parser = configparser.ConfigParser() self.parser.read(config_file) self.config_file = config_file + def _sanitize_path(self, path): + if os.sep == '\\': + # Trailing backslashes have to be escaped. Othwerise, the + # command we're issuing will be incorrectly interpreted on + # Windows. + path = self._escape_trailing_backslash_re.sub(r'\\\\', path) + return path + def get_run_command(self, test_ids=None, regexes=None, test_path=None, top_dir=None, group_regex=None, repo_type='file', repo_url=None, @@ -104,6 +114,9 @@ elif not top_dir: top_dir = './' + test_path = self._sanitize_path(test_path) + top_dir = self._sanitize_path(top_dir) + stestr_python = sys.executable # let's try to be explicit, even if it means a longer set of ifs if sys.platform == 'win32': @@ -120,6 +133,10 @@ raise RuntimeError("The Python interpreter was not found and " "PYTHON is not set") + # The python binary path may contain whitespaces. + if os.path.exists('"%s"' % python): + python = '"%s"' % python + command = '%s -m stestr.subunit_runner.run discover -t "%s" "%s" ' \ '$LISTOPT $IDOPTION' % (python, top_dir, test_path) listopt = "--list" @@ -127,11 +144,11 @@ # If the command contains $IDOPTION read that command from config # Use a group regex if one is defined if parallel_class: - group_regex = '([^\.]*\.)*' + group_regex = r'([^\.]*\.)*' if not group_regex \ and self.parser.has_option('DEFAULT', 'parallel_class') \ and self.parser.getboolean('DEFAULT', 'parallel_class'): - group_regex = '([^\.]*\.)*' + group_regex = r'([^\.]*\.)*' if not group_regex and self.parser.has_option('DEFAULT', 'group_regex'): group_regex = self.parser.get('DEFAULT', 'group_regex') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/repository/file.py new/stestr-2.6.0/stestr/repository/file.py --- old/stestr-2.5.1/stestr/repository/file.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/repository/file.py 2019-12-13 19:59:07.000000000 +0100 @@ -40,7 +40,14 @@ def initialise(klass, url): """Create a repository at url/path.""" base = os.path.join(os.path.expanduser(url), '.stestr') - os.mkdir(base) + try: + os.mkdir(base) + except OSError as e: + if e.errno == errno.EEXIST and not os.listdir(base): + # It shouldn't be harmful initializing an empty dir + pass + else: + raise with open(os.path.join(base, 'format'), 'wt') as stream: stream.write('1\n') result = Repository(base) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/repository/memory.py new/stestr-2.6.0/stestr/repository/memory.py --- old/stestr-2.5.1/stestr/repository/memory.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/repository/memory.py 2019-12-13 19:59:07.000000000 +0100 @@ -14,7 +14,6 @@ from extras import try_import -OrderedDict = try_import('collections.OrderedDict', dict) from io import BytesIO from operator import methodcaller @@ -23,6 +22,8 @@ from stestr.repository import abstract as repository +OrderedDict = try_import('collections.OrderedDict', dict) + class RepositoryFactory(repository.AbstractRepositoryFactory): """A factory that can initialise and open memory repositories. @@ -152,8 +153,8 @@ duration_delta = stop - start duration_seconds = ( (duration_delta.microseconds + ( - duration_delta.seconds + duration_delta.days - * 24 * 3600) * 10 ** 6) / 10.0 ** 6) + duration_delta.seconds + + duration_delta.days * 24 * 3600) * 10 ** 6) / 10.0 ** 6) self._repository._times[test_dict['id']] = duration_seconds def stopTestRun(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/scheduler.py new/stestr-2.6.0/stestr/scheduler.py --- old/stestr-2.5.1/stestr/scheduler.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/scheduler.py 2019-12-13 19:59:07.000000000 +0100 @@ -46,6 +46,9 @@ :return: A list where each element is a distinct subset of test_ids, and the union of all the elements is equal to set(test_ids). """ + def noop(_): + return None + _group_callback = group_callback partitions = [list() for i in range(concurrency)] timed_partitions = [[0.0, partition] for partition in partitions] @@ -60,7 +63,7 @@ # Group tests: generate group_id -> test_ids. group_ids = collections.defaultdict(list) if _group_callback is None: - group_callback = lambda _: None + group_callback = noop else: group_callback = _group_callback for test_id in test_ids: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/subunit_trace.py new/stestr-2.6.0/stestr/subunit_trace.py --- old/stestr-2.5.1/stestr/subunit_trace.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/subunit_trace.py 2019-12-13 19:59:07.000000000 +0100 @@ -123,7 +123,6 @@ # indent attachment lines 4 spaces to make them visually # offset for line in detail.as_text().split('\n'): - line = line.encode('utf8') stream.write(" %s\n" % line) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/test_processor.py new/stestr-2.6.0/stestr/test_processor.py --- old/stestr-2.5.1/stestr/test_processor.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/test_processor.py 2019-12-13 19:59:07.000000000 +0100 @@ -104,7 +104,7 @@ def setUp(self): super(TestProcessorFixture, self).setUp() - variable_regex = '\$(IDOPTION|IDFILE|IDLIST|LISTOPT)' + variable_regex = r'\$(IDOPTION|IDFILE|IDLIST|LISTOPT)' variables = {} list_variables = {'LISTOPT': self.listopt} cmd = self.template diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/tests/repository/test_file.py new/stestr-2.6.0/stestr/tests/repository/test_file.py --- old/stestr-2.5.1/stestr/tests/repository/test_file.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/tests/repository/test_file.py 2019-12-13 19:59:07.000000000 +0100 @@ -26,9 +26,10 @@ class FileRepositoryFixture(fixtures.Fixture): - def __init__(self, path=None): + def __init__(self, path=None, initialise=True): super(FileRepositoryFixture, self).__init__() self.path = path + self.initialise = initialise def setUp(self): super(FileRepositoryFixture, self).setUp() @@ -37,7 +38,8 @@ else: self.tempdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, self.tempdir) - self.repo = file.RepositoryFactory().initialise(self.tempdir) + if self.initialise: + self.repo = file.RepositoryFactory().initialise(self.tempdir) class HomeDirTempDir(fixtures.Fixture): @@ -70,6 +72,32 @@ contents = stream.read() self.assertEqual("0\n", contents) + def test_initialise_empty_dir(self): + self.useFixture(FileRepositoryFixture(path=self.tempdir, + initialise=False)) + base = os.path.join(self.tempdir, '.stestr') + os.mkdir(base) + self.assertFalse(os.path.isfile(os.path.join(base, 'format'))) + self.repo = file.RepositoryFactory().initialise(self.tempdir) + self.assertTrue(os.path.isdir(base)) + self.assertTrue(os.path.isfile(os.path.join(base, 'format'))) + with open(os.path.join(base, 'format'), 'rt') as stream: + contents = stream.read() + self.assertEqual("1\n", contents) + with open(os.path.join(base, 'next-stream'), 'rt') as stream: + contents = stream.read() + self.assertEqual("0\n", contents) + + def test_initialise_non_empty_dir(self): + self.useFixture(FileRepositoryFixture(path=self.tempdir, + initialise=False)) + base = os.path.join(self.tempdir, '.stestr') + os.mkdir(base) + with open(os.path.join(base, 'foo'), 'wt') as stream: + stream.write('1\n') + factory = file.RepositoryFactory() + self.assertRaises(OSError, factory.initialise, self.tempdir) + # Skip if windows since ~ in a path doesn't work there @testtools.skipIf(os.name == 'nt', "Windows doesn't support '~' expand") def test_initialise_expands_user_directory(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/tests/test_config_file.py new/stestr-2.6.0/stestr/tests/test_config_file.py --- old/stestr-2.5.1/stestr/tests/test_config_file.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/tests/test_config_file.py 2019-12-13 19:59:07.000000000 +0100 @@ -10,12 +10,14 @@ # License for the specific language governing permissions and limitations # under the License. +import ddt import mock from stestr import config_file from stestr.tests import base [email protected] class TestTestrConf(base.TestCase): @mock.patch.object(config_file.configparser, 'ConfigParser') @@ -27,6 +29,7 @@ @mock.patch.object(config_file.util, 'get_repo_open') @mock.patch.object(config_file.test_processor, 'TestProcessorFixture') @mock.patch.object(config_file, 'sys') + @mock.patch('os.path.exists', new=lambda x: True) def _check_get_run_command(self, mock_sys, mock_TestProcessorFixture, mock_get_repo_open, platform='win32', group_regex='.*', parallel_class=False, @@ -49,7 +52,7 @@ self.assertEqual(mock_TestProcessorFixture.return_value, fixture) mock_get_repo_open.assert_called_once_with('file', None) - command = '%s -m stestr.subunit_runner.run discover -t "%s" "%s" ' \ + command = '"%s" -m stestr.subunit_runner.run discover -t "%s" "%s" ' \ '$LISTOPT $IDOPTION' % (expected_python, 'fake_top_dir', 'fake_test_path') # Ensure TestProcessorFixture is created with defaults except for where @@ -107,3 +110,12 @@ self._testr_conf.parser.has_option.return_value = False self._check_get_run_command(group_regex='', expected_group_callback=None) + + @ddt.data(('.\\', '.\\\\'), + ('a\\b\\', 'a\\b\\\\'), + ('a\\b', 'a\\b')) + @ddt.unpack + @mock.patch('os.sep', new='\\') + def test_sanitize_dir_win32(self, path, expected): + sanitized = self._testr_conf._sanitize_path(path) + self.assertEqual(expected, sanitized) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr/tests/test_return_codes.py new/stestr-2.6.0/stestr/tests/test_return_codes.py --- old/stestr-2.5.1/stestr/tests/test_return_codes.py 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/stestr/tests/test_return_codes.py 2019-12-13 19:59:07.000000000 +0100 @@ -209,6 +209,28 @@ # test from a command line based test. self.assertRunExit('stestr --parallel-class run passing', 0) + def test_no_repo_dir(self): + stestr_repo_dir = os.path.join(self.directory, '.stestr') + shutil.rmtree(stestr_repo_dir, ignore_errors=True) + # We can use stestr run even if there's no repo directory. + self.assertRunExit('stestr run passing', 0) + + def test_empty_repo_dir(self): + stestr_repo_dir = os.path.join(self.directory, '.stestr') + shutil.rmtree(stestr_repo_dir, ignore_errors=True) + os.mkdir(stestr_repo_dir) + # We can initialize an empty repo directory. + self.assertRunExit('stestr run passing', 0) + + def test_non_empty_repo_dir(self): + stestr_repo_dir = os.path.join(self.directory, '.stestr') + shutil.rmtree(stestr_repo_dir, ignore_errors=True) + os.mkdir(stestr_repo_dir) + with open(os.path.join(stestr_repo_dir, 'foo'), 'wt') as stream: + stream.write('1\n') + # We can't initialize a non-empty repo directory. + self.assertRunExit('stestr run passing', 1) + def test_list(self): self.assertRunExit('stestr list', 0) @@ -249,6 +271,23 @@ 'stestr last --subunit')[0] self.assertRunExit('stestr load', 0, stdin=stream) + def test_load_force_init(self): + self.assertRunExit('stestr run passing', 0) + stream = self._get_cmd_stdout( + 'stestr last --subunit')[0] + # NOTE: --force-init should work here because there is an properly + # initialized repository. + self.assertRunExit('stestr load --force-init', 0, stdin=stream) + + def test_load_force_init_invalid(self): + self.assertRunExit('stestr run passing', 0) + stream = self._get_cmd_stdout( + 'stestr last --subunit')[0] + os.remove(os.path.join(self.directory, '.stestr', 'format')) + # NOTE: --force-init should fail here because there is an invalid + # repository. + self.assertRunExit('stestr load --force-init', 1, stdin=stream) + def test_load_from_stdin_quiet(self): out, err = self.assertRunExit('stestr --user-config stestr.yaml -q ' 'run passing', 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr.egg-info/PKG-INFO new/stestr-2.6.0/stestr.egg-info/PKG-INFO --- old/stestr-2.5.1/stestr.egg-info/PKG-INFO 2019-09-03 15:17:27.000000000 +0200 +++ new/stestr-2.6.0/stestr.egg-info/PKG-INFO 2019-12-13 19:59:21.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: stestr -Version: 2.5.1 +Version: 2.6.0 Summary: A parallel Python test runner built around subunit Home-page: http://stestr.readthedocs.io/en/latest/ Author: Matthew Treinish @@ -176,6 +176,7 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Software Development :: Quality Assurance Provides-Extra: sql diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr.egg-info/SOURCES.txt new/stestr-2.6.0/stestr.egg-info/SOURCES.txt --- old/stestr-2.5.1/stestr.egg-info/SOURCES.txt 2019-09-03 15:17:27.000000000 +0200 +++ new/stestr-2.6.0/stestr.egg-info/SOURCES.txt 2019-12-13 19:59:21.000000000 +0100 @@ -15,7 +15,8 @@ setup.py test-requirements.txt tox.ini -.github/issue_template.md +.github/ISSUE_TEMPLATE/bug_report.md +.github/ISSUE_TEMPLATE/feature_request.md .travis/coveralls.sh doc/source/CONTRIBUTING.rst doc/source/MANUAL.rst diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr.egg-info/pbr.json new/stestr-2.6.0/stestr.egg-info/pbr.json --- old/stestr-2.5.1/stestr.egg-info/pbr.json 2019-09-03 15:17:27.000000000 +0200 +++ new/stestr-2.6.0/stestr.egg-info/pbr.json 2019-12-13 19:59:21.000000000 +0100 @@ -1 +1 @@ -{"git_version": "2957835", "is_release": true} \ No newline at end of file +{"git_version": "ff9b688", "is_release": true} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/stestr.egg-info/requires.txt new/stestr-2.6.0/stestr.egg-info/requires.txt --- old/stestr-2.5.1/stestr.egg-info/requires.txt 2019-09-03 15:17:27.000000000 +0200 +++ new/stestr-2.6.0/stestr.egg-info/requires.txt 2019-12-13 19:59:21.000000000 +0100 @@ -12,7 +12,7 @@ subunit2sql>=1.8.0 [test] -hacking<0.12,>=0.11.0 +hacking<1.2.0,>=1.1.0 mock>=2.0 subunit2sql>=1.8.0 coverage>=4.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/test-requirements.txt new/stestr-2.6.0/test-requirements.txt --- old/stestr-2.5.1/test-requirements.txt 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/test-requirements.txt 2019-12-13 19:59:07.000000000 +0100 @@ -2,11 +2,11 @@ # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. -hacking<0.12,>=0.11.0 # Apache-2.0 +hacking<1.2.0,>=1.1.0 sphinx!=1.6.6,!=1.6.7,<2.0.0;python_version=='2.7' # BSD sphinx!=1.6.6,!=1.6.7,!=2.1.0;python_version>='3.4' # BSD mock>=2.0 # BSD subunit2sql>=1.8.0 coverage>=4.0 # Apache-2.0 ddt>=1.0.1 # MIT -doc8>=0.8.0 # Apache-2.0 \ No newline at end of file +doc8>=0.8.0 # Apache-2.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stestr-2.5.1/tox.ini new/stestr-2.6.0/tox.ini --- old/stestr-2.5.1/tox.ini 2019-09-03 15:17:17.000000000 +0200 +++ new/stestr-2.6.0/tox.ini 2019-12-13 19:59:07.000000000 +0100 @@ -1,6 +1,6 @@ [tox] minversion = 1.6 -envlist = py37,py36,py35,py34,py27,pep8 +envlist = py38,py37,py36,py35,py34,py27,pep8 skipsdist = True [testenv]
