Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5f0c34d38 | ||
|
|
0b638ef02e | ||
|
|
a9da3a5306 | ||
|
|
b814db45ce | ||
|
|
ee0754bc35 | ||
|
|
5c59a30277 | ||
|
|
d3ef33ab32 | ||
|
|
c950d88204 | ||
|
|
46119eb593 | ||
|
|
b5abe791ad | ||
|
|
fe1f239612 | ||
|
|
55dc257f1c | ||
|
|
46dbc1223b | ||
|
|
9b46df48a6 | ||
|
|
c6306e4fbe | ||
|
|
a5d51f24c9 |
@@ -17,10 +17,9 @@ python:
|
|||||||
- '3.5'
|
- '3.5'
|
||||||
- '3.6'
|
- '3.6'
|
||||||
env:
|
env:
|
||||||
- TOXENV=py-pytest30
|
- TOXENV=py-pytest34
|
||||||
- TOXENV=py-pytest31
|
- TOXENV=py-pytest35
|
||||||
- TOXENV=py-pytest32
|
- TOXENV=py-pytest36
|
||||||
- TOXENV=py-pytest33
|
|
||||||
|
|
||||||
install: pip install tox setuptools_scm
|
install: pip install tox setuptools_scm
|
||||||
script: tox
|
script: tox
|
||||||
|
|||||||
@@ -1,3 +1,16 @@
|
|||||||
|
pytest-xdist 1.22.4 (2018-07-27)
|
||||||
|
================================
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
- `#305 <https://github.com/pytest-dev/pytest-xdist/issues/305>`_: Remove last references to obsolete ``py.code``.
|
||||||
|
|
||||||
|
Remove some unnecessary references to ``py.builtin``.
|
||||||
|
|
||||||
|
- `#316 <https://github.com/pytest-dev/pytest-xdist/issues/316>`_: Workaround cpu detection on Travis CI.
|
||||||
|
|
||||||
|
|
||||||
pytest-xdist 1.22.3 (2018-07-23)
|
pytest-xdist 1.22.3 (2018-07-23)
|
||||||
================================
|
================================
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,13 @@
|
|||||||
:alt: PyPI version
|
:alt: PyPI version
|
||||||
:target: https://pypi.python.org/pypi/pytest-xdist
|
:target: https://pypi.python.org/pypi/pytest-xdist
|
||||||
|
|
||||||
|
.. image:: https://img.shields.io/conda/vn/conda-forge/pytest-xdist.svg
|
||||||
|
:target: https://anaconda.org/conda-forge/pytest-xdist
|
||||||
|
|
||||||
.. image:: https://img.shields.io/pypi/pyversions/pytest-xdist.svg
|
.. image:: https://img.shields.io/pypi/pyversions/pytest-xdist.svg
|
||||||
:alt: Python versions
|
:alt: Python versions
|
||||||
:target: https://pypi.python.org/pypi/pytest-xdist
|
:target: https://pypi.python.org/pypi/pytest-xdist
|
||||||
|
|
||||||
.. image:: https://anaconda.org/conda-forge/pytest-xdist/badges/version.svg
|
|
||||||
:alt: Anaconda version
|
|
||||||
:target: https://anaconda.org/conda-forge/pytest-xdist
|
|
||||||
|
|
||||||
.. image:: https://travis-ci.org/pytest-dev/pytest-xdist.svg?branch=master
|
.. image:: https://travis-ci.org/pytest-dev/pytest-xdist.svg?branch=master
|
||||||
:alt: Travis CI build status
|
:alt: Travis CI build status
|
||||||
:target: https://travis-ci.org/pytest-dev/pytest-xdist
|
:target: https://travis-ci.org/pytest-dev/pytest-xdist
|
||||||
@@ -44,7 +43,7 @@ program source code to the remote place. All test results
|
|||||||
are reported back and displayed to your local terminal.
|
are reported back and displayed to your local terminal.
|
||||||
You may specify different Python versions and interpreters.
|
You may specify different Python versions and interpreters.
|
||||||
|
|
||||||
If you would like to know how pytest-xdist works under the covers, checkout
|
If you would like to know how pytest-xdist works under the covers, checkout
|
||||||
`OVERVIEW <https://github.com/pytest-dev/pytest-xdist/blob/master/OVERVIEW.md>`_.
|
`OVERVIEW <https://github.com/pytest-dev/pytest-xdist/blob/master/OVERVIEW.md>`_.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
21
appveyor.yml
21
appveyor.yml
@@ -1,19 +1,22 @@
|
|||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
# note: please use "tox --listenvs" to populate the build matrix
|
- TOXENV: "py27-pytest36"
|
||||||
- TOXENV: "py27-pytest33"
|
- TOXENV: "py34-pytest36"
|
||||||
- TOXENV: "py34-pytest33"
|
- TOXENV: "py35-pytest36"
|
||||||
- TOXENV: "py35-pytest33"
|
- TOXENV: "py36-pytest36"
|
||||||
- TOXENV: "py36-pytest33"
|
- TOXENV: "py27-pytest36-pexpect"
|
||||||
- TOXENV: "py27-pytest33-pexpect"
|
- TOXENV: "py36-pytest36-pexpect"
|
||||||
- TOXENV: "py36-pytest33-pexpect"
|
|
||||||
- TOXENV: "flakes"
|
- TOXENV: "flakes"
|
||||||
- TOXENV: "readme"
|
- TOXENV: "readme"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- C:\Python35\python -m pip install -U tox setuptools_scm pip
|
- C:\Python36\python -m pip install -U tox setuptools_scm pip
|
||||||
|
|
||||||
build: false # Not a C# project, build stuff at the test step instead.
|
build: false # Not a C# project, build stuff at the test step instead.
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- C:\Python35\python -m tox
|
- C:\Python36\python -m tox
|
||||||
|
|
||||||
|
# We don't deploy anything on tags with AppVeyor, we use Travis instead, so we
|
||||||
|
# might as well save resources
|
||||||
|
skip_tags: true
|
||||||
|
|||||||
@@ -13,8 +13,7 @@
|
|||||||
|
|
||||||
{% if definitions[category]['showcontent'] %}
|
{% if definitions[category]['showcontent'] %}
|
||||||
{% for text, values in sections[section][category]|dictsort(by='value') %}
|
{% for text, values in sections[section][category]|dictsort(by='value') %}
|
||||||
- {{ text }}{% if category != 'vendor' %} (`{{ values[0] }} <https://github.com/pytest-dev/pytest-xdist/issues/{{ values[0][1:] }}>`_){% endif %}
|
- `{{ values[0] }} <https://github.com/pytest-dev/pytest-xdist/issues/{{ values[0][1:] }}>`_: {{ text }}
|
||||||
|
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -1,6 +1,6 @@
|
|||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
install_requires = ['execnet>=1.1', 'pytest>=3.0.0', 'pytest-forked']
|
install_requires = ['execnet>=1.1', 'pytest>=3.4', 'pytest-forked']
|
||||||
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ def test_auto_detect_cpus(testdir, monkeypatch):
|
|||||||
config = testdir.parseconfigure("-nauto")
|
config = testdir.parseconfigure("-nauto")
|
||||||
assert config.getoption('numprocesses') == 99
|
assert config.getoption('numprocesses') == 99
|
||||||
|
|
||||||
|
monkeypatch.delattr(os, 'sched_getaffinity', raising=False)
|
||||||
|
monkeypatch.setenv('TRAVIS', 'true')
|
||||||
|
config = testdir.parseconfigure("-nauto")
|
||||||
|
assert config.getoption('numprocesses') == 2
|
||||||
|
|
||||||
|
|
||||||
def test_boxed_with_collect_only(testdir):
|
def test_boxed_with_collect_only(testdir):
|
||||||
from xdist.plugin import pytest_cmdline_main as check_options
|
from xdist.plugin import pytest_cmdline_main as check_options
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from xdist.remote import serialize_report
|
|||||||
import execnet
|
import execnet
|
||||||
import marshal
|
import marshal
|
||||||
|
|
||||||
queue = py.builtin._tryimport("queue", "Queue")
|
from six.moves.queue import Queue
|
||||||
|
|
||||||
WAIT_TIMEOUT = 10.0
|
WAIT_TIMEOUT = 10.0
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ class WorkerSetup:
|
|||||||
def __init__(self, request, testdir):
|
def __init__(self, request, testdir):
|
||||||
self.request = request
|
self.request = request
|
||||||
self.testdir = testdir
|
self.testdir = testdir
|
||||||
self.events = queue.Queue()
|
self.events = Queue()
|
||||||
|
|
||||||
def setup(self, ):
|
def setup(self, ):
|
||||||
self.testdir.chdir()
|
self.testdir.chdir()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from __future__ import print_function
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
import textwrap
|
import textwrap
|
||||||
@@ -170,7 +171,7 @@ class TestNodeManager:
|
|||||||
p, = nodemanager.gwmanager.multi_exec(
|
p, = nodemanager.gwmanager.multi_exec(
|
||||||
"import os ; channel.send(os.getcwd())").receive_each()
|
"import os ; channel.send(os.getcwd())").receive_each()
|
||||||
p = py.path.local(p)
|
p = py.path.local(p)
|
||||||
py.builtin.print_("remote curdir", p)
|
print("remote curdir", p)
|
||||||
assert p == mysetup.dest.join(config.topdir.basename)
|
assert p == mysetup.dest.join(config.topdir.basename)
|
||||||
assert p.join("dir1").check()
|
assert p.join("dir1").check()
|
||||||
assert p.join("dir1", "file1").check()
|
assert p.join("dir1", "file1").check()
|
||||||
|
|||||||
11
tox.ini
11
tox.ini
@@ -1,8 +1,8 @@
|
|||||||
[tox]
|
[tox]
|
||||||
# if you change the envlist, please update .travis.yml file as well
|
# if you change the envlist, please update .travis.yml file as well
|
||||||
envlist=
|
envlist=
|
||||||
py{27,34,35,36}-pytest{30,31,32,33}
|
py{27,34,35,36}-pytest{34,35,36}
|
||||||
py{27,36}-pytest{30,31,32,33}-pexpect
|
py{27,36}-pytest36-pexpect
|
||||||
py{27,36}-pytest{master,features}
|
py{27,36}-pytest{master,features}
|
||||||
flakes
|
flakes
|
||||||
readme
|
readme
|
||||||
@@ -15,10 +15,9 @@ deps =
|
|||||||
pycmd
|
pycmd
|
||||||
# to avoid .eggs
|
# to avoid .eggs
|
||||||
setuptools_scm
|
setuptools_scm
|
||||||
pytest30: pytest~=3.0.5
|
pytest34: pytest~=3.4.0
|
||||||
pytest31: pytest~=3.1.0
|
pytest35: pytest~=3.5.0
|
||||||
pytest32: pytest~=3.2.0
|
pytest36: pytest~=3.6.0
|
||||||
pytest33: pytest~=3.3.0
|
|
||||||
pytestmaster: git+https://github.com/pytest-dev/pytest.git@master
|
pytestmaster: git+https://github.com/pytest-dev/pytest.git@master
|
||||||
pytestfeatures: git+https://github.com/pytest-dev/pytest.git@features
|
pytestfeatures: git+https://github.com/pytest-dev/pytest.git@features
|
||||||
pexpect: pexpect
|
pexpect: pexpect
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from xdist.scheduler import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
queue = py.builtin._tryimport('queue', 'Queue')
|
from six.moves.queue import Empty, Queue
|
||||||
|
|
||||||
|
|
||||||
class Interrupted(KeyboardInterrupt):
|
class Interrupted(KeyboardInterrupt):
|
||||||
@@ -41,7 +41,7 @@ class DSession(object):
|
|||||||
self.shuttingdown = False
|
self.shuttingdown = False
|
||||||
self.countfailures = 0
|
self.countfailures = 0
|
||||||
self.maxfail = config.getvalue("maxfail")
|
self.maxfail = config.getvalue("maxfail")
|
||||||
self.queue = queue.Queue()
|
self.queue = Queue()
|
||||||
self._session = None
|
self._session = None
|
||||||
self._failed_collection_errors = {}
|
self._failed_collection_errors = {}
|
||||||
self._active_nodes = set()
|
self._active_nodes = set()
|
||||||
@@ -129,7 +129,7 @@ class DSession(object):
|
|||||||
try:
|
try:
|
||||||
eventcall = self.queue.get(timeout=2.0)
|
eventcall = self.queue.get(timeout=2.0)
|
||||||
break
|
break
|
||||||
except queue.Empty:
|
except Empty:
|
||||||
continue
|
continue
|
||||||
callname, kwargs = eventcall
|
callname, kwargs = eventcall
|
||||||
assert callname, kwargs
|
assert callname, kwargs
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
processes) otherwise changes to source code can crash
|
processes) otherwise changes to source code can crash
|
||||||
the controlling process which should best never happen.
|
the controlling process which should best never happen.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
import sys
|
import sys
|
||||||
@@ -60,7 +60,7 @@ class RemoteControl(object):
|
|||||||
def trace(self, *args):
|
def trace(self, *args):
|
||||||
if self.config.option.debug:
|
if self.config.option.debug:
|
||||||
msg = " ".join([str(x) for x in args])
|
msg = " ".join([str(x) for x in args])
|
||||||
py.builtin.print_("RemoteControl:", msg)
|
print("RemoteControl:", msg)
|
||||||
|
|
||||||
def initgateway(self):
|
def initgateway(self):
|
||||||
return execnet.makegateway("popen")
|
return execnet.makegateway("popen")
|
||||||
@@ -248,7 +248,7 @@ class StatRecorder(object):
|
|||||||
if oldstat.mtime != curstat.mtime or \
|
if oldstat.mtime != curstat.mtime or \
|
||||||
oldstat.size != curstat.size:
|
oldstat.size != curstat.size:
|
||||||
changed = True
|
changed = True
|
||||||
py.builtin.print_("# MODIFIED", path)
|
print("# MODIFIED", path)
|
||||||
if removepycfiles and path.ext == ".py":
|
if removepycfiles and path.ext == ".py":
|
||||||
pycfile = path + "c"
|
pycfile = path + "c"
|
||||||
if pycfile.check():
|
if pycfile.check():
|
||||||
|
|||||||
@@ -1,25 +1,34 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def auto_detect_cpus():
|
||||||
|
try:
|
||||||
|
from os import sched_getaffinity
|
||||||
|
except ImportError:
|
||||||
|
if os.environ.get('TRAVIS') == 'true':
|
||||||
|
# workaround https://bitbucket.org/pypy/pypy/issues/2375
|
||||||
|
return 2
|
||||||
|
try:
|
||||||
|
from os import cpu_count
|
||||||
|
except ImportError:
|
||||||
|
from multiprocessing import cpu_count
|
||||||
|
else:
|
||||||
|
def cpu_count():
|
||||||
|
return len(sched_getaffinity(0))
|
||||||
|
|
||||||
|
try:
|
||||||
|
n = cpu_count()
|
||||||
|
except NotImplementedError:
|
||||||
|
return 1
|
||||||
|
return n if n else 1
|
||||||
|
|
||||||
|
|
||||||
def parse_numprocesses(s):
|
def parse_numprocesses(s):
|
||||||
if s == 'auto':
|
if s == 'auto':
|
||||||
try:
|
return auto_detect_cpus()
|
||||||
from os import sched_getaffinity
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
from os import cpu_count
|
|
||||||
except ImportError:
|
|
||||||
from multiprocessing import cpu_count
|
|
||||||
else:
|
|
||||||
def cpu_count():
|
|
||||||
return len(sched_getaffinity(0))
|
|
||||||
|
|
||||||
try:
|
|
||||||
n = cpu_count()
|
|
||||||
except NotImplementedError:
|
|
||||||
return 1
|
|
||||||
return n if n else 1
|
|
||||||
else:
|
else:
|
||||||
return int(s)
|
return int(s)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import py
|
from __future__ import print_function
|
||||||
from difflib import unified_diff
|
from difflib import unified_diff
|
||||||
|
|
||||||
|
|
||||||
@@ -17,10 +17,10 @@ def report_collection_diff(from_collection, to_collection, from_id, to_id):
|
|||||||
fromfile=from_id,
|
fromfile=from_id,
|
||||||
tofile=to_id,
|
tofile=to_id,
|
||||||
)
|
)
|
||||||
error_message = py.builtin._totext(
|
error_message = (
|
||||||
'Different tests were collected between {from_id} and {to_id}. '
|
u'Different tests were collected between {from_id} and {to_id}. '
|
||||||
'The difference is:\n'
|
u'The difference is:\n'
|
||||||
'{diff}'
|
u'{diff}'
|
||||||
).format(from_id=from_id, to_id=to_id, diff='\n'.join(diff))
|
).format(from_id=from_id, to_id=to_id, diff='\n'.join(diff))
|
||||||
msg = "\n".join([x.rstrip() for x in error_message.split("\n")])
|
msg = "\n".join([x.rstrip() for x in error_message.split("\n")])
|
||||||
return msg
|
return msg
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from __future__ import print_function
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@@ -6,6 +7,7 @@ import threading
|
|||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
import execnet
|
import execnet
|
||||||
|
|
||||||
import xdist.remote
|
import xdist.remote
|
||||||
|
|
||||||
from _pytest import runner # XXX load dynamically
|
from _pytest import runner # XXX load dynamically
|
||||||
@@ -48,7 +50,7 @@ class NodeManager(object):
|
|||||||
self.specs.append(spec)
|
self.specs.append(spec)
|
||||||
self.roots = self._getrsyncdirs()
|
self.roots = self._getrsyncdirs()
|
||||||
self.rsyncoptions = self._getrsyncoptions()
|
self.rsyncoptions = self._getrsyncoptions()
|
||||||
self._rsynced_specs = py.builtin.set()
|
self._rsynced_specs = set()
|
||||||
|
|
||||||
def rsync_roots(self, gateway):
|
def rsync_roots(self, gateway):
|
||||||
"""Rsync the set of roots to the node's gateway cwd."""
|
"""Rsync the set of roots to the node's gateway cwd."""
|
||||||
@@ -180,8 +182,7 @@ class HostRSync(execnet.RSync):
|
|||||||
if self._verbose:
|
if self._verbose:
|
||||||
path = os.path.basename(self._sourcedir) + "/" + modified_rel_path
|
path = os.path.basename(self._sourcedir) + "/" + modified_rel_path
|
||||||
remotepath = gateway.spec.chdir
|
remotepath = gateway.spec.chdir
|
||||||
py.builtin.print_('%s:%s <= %s' %
|
print('%s:%s <= %s' % (gateway.spec, remotepath, path))
|
||||||
(gateway.spec, remotepath, path))
|
|
||||||
|
|
||||||
|
|
||||||
def make_reltoroot(roots, args):
|
def make_reltoroot(roots, args):
|
||||||
@@ -333,8 +334,9 @@ class WorkerController(object):
|
|||||||
# should not land in receiver-thread
|
# should not land in receiver-thread
|
||||||
raise
|
raise
|
||||||
except: # noqa
|
except: # noqa
|
||||||
excinfo = py.code.ExceptionInfo()
|
from _pytest._code import ExceptionInfo
|
||||||
py.builtin.print_("!" * 20, excinfo)
|
excinfo = ExceptionInfo()
|
||||||
|
print("!" * 20, excinfo)
|
||||||
self.config.notify_exception(excinfo)
|
self.config.notify_exception(excinfo)
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
self.notify_inproc("errordown", node=self, error=excinfo)
|
self.notify_inproc("errordown", node=self, error=excinfo)
|
||||||
|
|||||||
Reference in New Issue
Block a user