Compare commits

...

34 Commits

Author SHA1 Message Date
Bruno Oliveira
c5f0c34d38 Prepare release 1.22.4 2018-07-27 09:17:18 -03:00
Bruno Oliveira
0b638ef02e Fix ponctuation in CHANGELOG 2018-07-27 09:16:53 -03:00
Bruno Oliveira
a9da3a5306 Update CHANGELOG template to put issue number in the start of the line
This makes using multiple paragraphs per entry possible
2018-07-27 09:15:04 -03:00
Bruno Oliveira
b814db45ce Merge pull request #317 from skirpichev/pypy3-numprocesses
Workaround cpu detection on Travis CI
2018-07-27 09:02:55 -03:00
Bruno Oliveira
ee0754bc35 Improve test for Travis fallback 2018-07-27 08:24:34 -03:00
Sergey B Kirpichev
5c59a30277 Add coverage test for Travis CI workaround 2018-07-26 12:56:10 +03:00
Sergey B Kirpichev
d3ef33ab32 Refactor automatic cpu detection code to auto_detect_cpus() 2018-07-26 12:52:18 +03:00
Sergey B Kirpichev
c950d88204 Workaround cpu detection on Travis CI
Closes #316
2018-07-25 19:05:19 +03:00
Bruno Oliveira
46119eb593 Merge pull request #315 from nicoddemus/pylib-woes
Remove last references to obsolete py.code
2018-07-25 09:07:19 -03:00
Bruno Oliveira
b5abe791ad Drop support to old pytest versions (<3.4)
Let's take the opportunity to reduce the build matrix and test with latest
pytest versions as well
2018-07-23 19:32:56 -03:00
Bruno Oliveira
fe1f239612 Remove last references to obsolete py.code
Also remove some unnecessary references to py.builtin

Fix #305
2018-07-23 17:36:03 -03:00
Bruno Oliveira
55dc257f1c Merge pull request #314 from nicoddemus/skip-tags-appveyor
Skip AppVeyor when building on tags
2018-07-23 17:14:14 -03:00
Bruno Oliveira
46dbc1223b Merge pull request #313 from nicoddemus/conda-forge-badge
Replace anaconda's badge by conda-forge's
2018-07-23 17:14:03 -03:00
Bruno Oliveira
9b46df48a6 Merge pull request #312 from nicoddemus/release-1.22.3
Release 1.22.3
2018-07-23 17:13:26 -03:00
Bruno Oliveira
c6306e4fbe Skip AppVeyor when building on tags 2018-07-23 17:03:06 -03:00
Bruno Oliveira
6ec967a3f2 Prepare release 1.22.3 2018-07-23 16:36:39 -03:00
Bruno Oliveira
0722ea12ef Use a tox environment to update the release files 2018-07-23 16:36:26 -03:00
Bruno Oliveira
a5d51f24c9 Replace anaconda's badge by conda-forge's 2018-07-23 16:33:05 -03:00
Ronny Pfannschmidt
bb91f5459d Merge pull request #309 from greut/cpu-count
plugin: get cpu_count from sched_getaffinity
2018-07-23 20:13:45 +02:00
Bruno Oliveira
00b7c4553a Merge pull request #311 from nicoddemus/skip-deploy
Skip deploy job on Travis if we are not on a tag
2018-07-21 19:20:25 -03:00
Bruno Oliveira
9ff6fc10d0 Skip deploy job on Travis if we are not on a tag 2018-07-21 18:17:21 -03:00
Bruno Oliveira
a06e75cc78 Fix flake8 issue 2018-07-21 12:09:44 -03:00
Yoan Blanc
04882074e1 plugin: get cpu_count from sched_getaffinity
Signed-off-by: Yoan Blanc <yoan.blanc@exoscale.ch>
2018-07-18 08:32:01 +02:00
Bruno Oliveira
06593498cd Merge pull request #306 from asottile/factor_out_py_std
Factor out py.std
2018-07-06 22:21:56 -03:00
Bruno Oliveira
57d09c2622 Merge pull request #308 from scop/dropthedot
Use pytest instead of py.test per upstream recommendation, #dropthedot
2018-07-06 22:20:53 -03:00
Ville Skyttä
663bbd5338 Use pytest instead of py.test per upstream recommendation, #dropthedot
http://blog.pytest.org/2016/whats-new-in-pytest-30/
https://twitter.com/hashtag/dropthedot
2018-07-07 00:01:11 +03:00
Bruno Oliveira
137b939a27 Merge pull request #307 from scop/grammar
Grammar fix
2018-07-06 12:05:26 -03:00
Ville Skyttä
17f6257a24 Grammar fix 2018-07-06 15:45:41 +03:00
Anthony Sottile
78fcf725cf Factor out py.std 2018-07-05 15:35:39 -07:00
Ronny Pfannschmidt
8d94fca964 Merge pull request #297 from nicoddemus/fix-init
Fix __init__ declaration
2018-06-11 06:01:17 +02:00
Bruno Oliveira
b06c52a5d2 Add .pytest_cache to gitignore 2018-06-03 16:10:55 -03:00
Bruno Oliveira
fd2e8a6711 Make all classes subclass from object 2018-06-03 16:10:24 -03:00
Bruno Oliveira
98ae25c12c Fix __init__ declaration 2018-06-03 16:06:52 -03:00
Bruno Oliveira
182d1f6433 Merge pull request #287 from nicoddemus/release-1.22.2
Preparing 1.22.2 release
2018-02-27 07:43:11 -03:00
27 changed files with 190 additions and 115 deletions

1
.gitignore vendored
View File

@@ -30,5 +30,6 @@ issue/
pytestdebug.log
.tox/
.cache/
.pytest_cache/
.eggs/
.idea/

View File

@@ -17,14 +17,18 @@ python:
- '3.5'
- '3.6'
env:
- TOXENV=py-pytest30
- TOXENV=py-pytest31
- TOXENV=py-pytest32
- TOXENV=py-pytest33
- TOXENV=py-pytest34
- TOXENV=py-pytest35
- TOXENV=py-pytest36
install: pip install tox setuptools_scm
script: tox
stages:
- test
- name: deploy
if: repo = pytest-dev/pytest-xdist AND tag IS present
jobs:
include:
- stage: test

View File

@@ -1,3 +1,31 @@
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)
================================
Bug Fixes
---------
- Fix issue of virtualized or containerized environments not reporting the number of CPUs correctly. (`#9 <https://github.com/pytest-dev/pytest-xdist/issues/9>`_)
Trivial Changes
---------------
- Make all classes subclass from ``object`` and fix ``super()`` call in ``LoadFileScheduling``; (`#297 <https://github.com/pytest-dev/pytest-xdist/issues/297>`_)
pytest-xdist 1.22.2 (2018-02-26)
================================

View File

@@ -24,13 +24,13 @@ To publish a new release ``X.Y.Z``, the steps are as follows:
#. Create a new branch named ``release-X.Y.Z`` from the latest ``master``.
#. Install ``pytest-xdist`` and dev requirements in a virtualenv::
#. Install ``tox`` in a virtualenv::
$ pip install -e . -U -r dev-requirements.txt
$ pip install tox
#. Update ``CHANGELOG.rst`` file by running::
#. Update the necessary files with::
$ towncrier --version X.Y.Z --yes
$ tox -e release -- X.Y.Z
#. Commit and push the branch for review.

View File

@@ -19,7 +19,7 @@ tag: feature
allow to run xdist own tests using its own mechanism.
currently this doesn't work because the remote side
has no py.test plugin. How to configure/do
has no pytest plugin. How to configure/do
register "xdist.plugin" on the remote side?
see to avoid any "from _pytest" internal imports

View File

@@ -4,14 +4,13 @@
:alt: PyPI version
: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
:alt: Python versions
: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
:alt: Travis CI build status
:target: https://travis-ci.org/pytest-dev/pytest-xdist
@@ -23,7 +22,7 @@
xdist: pytest distributed testing plugin
========================================
The `pytest-xdist`_ plugin extends py.test with some unique
The `pytest-xdist`_ plugin extends pytest with some unique
test execution modes:
* test run parallelization_: if you have multiple CPUs or hosts you can use
@@ -32,14 +31,14 @@ test execution modes:
* ``--looponfail``: run your tests repeatedly in a subprocess. After each run
py.test waits until a file in your project changes and then re-runs
pytest waits until a file in your project changes and then re-runs
the previously failing tests. This is repeated until all tests pass
after which again a full run is performed.
* `Multi-Platform`_ coverage: you can specify different Python interpreters
or different platforms and run tests in parallel on all of them.
Before running tests remotely, ``py.test`` efficiently "rsyncs" your
Before running tests remotely, ``pytest`` efficiently "rsyncs" your
program source code to the remote place. All test results
are reported back and displayed to your local terminal.
You may specify different Python versions and interpreters.
@@ -67,7 +66,7 @@ Speed up test runs by sending tests to multiple CPUs
To send tests to multiple CPUs, type::
py.test -n NUM
pytest -n NUM
Especially for longer running tests or tests requiring
a lot of I/O this can lead to considerable speed ups. This option can
@@ -98,7 +97,7 @@ Running tests in a Python subprocess
To instantiate a python3.5 subprocess and send tests to it, you may type::
py.test -d --tx popen//python=python3.5
pytest -d --tx popen//python=python3.5
This will start a subprocess which is run with the ``python3.5``
Python interpreter, found in your system binary lookup path.
@@ -129,10 +128,10 @@ tests that you can successfully run locally. And you
have a ssh-reachable machine ``myhost``. Then
you can ad-hoc distribute your tests by typing::
py.test -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg
pytest -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg
This will synchronize your :code:`mypkg` package directory
to an remote ssh account and then locally collect tests
to a remote ssh account and then locally collect tests
and send them to remote places for execution.
You can specify multiple :code:`--rsyncdir` directories
@@ -140,11 +139,11 @@ to be sent to the remote side.
.. note::
For py.test to collect and send tests correctly
For pytest to collect and send tests correctly
you not only need to make sure all code and tests
directories are rsynced, but that any test (sub) directory
also has an :code:`__init__.py` file because internally
py.test references tests as a fully qualified python
pytest references tests as a fully qualified python
module path. **You will otherwise get strange errors**
during setup of the remote side.
@@ -168,7 +167,7 @@ It will tell you that it starts listening on the default
port. You can now on your home machine specify this
new socket host with something like this::
py.test -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg
pytest -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg
.. _`atonce`:
@@ -180,7 +179,7 @@ Running tests on many platforms at once
The basic command to run tests on multiple platforms is::
py.test --dist=each --tx=spec1 --tx=spec2
pytest --dist=each --tx=spec1 --tx=spec2
If you specify a windows host, an OSX host and a Linux
environment this command will send each tests to all
@@ -242,7 +241,7 @@ You can also add default environments like this:
and then just type::
py.test --dist=each
pytest --dist=each
to run tests in each of the environments.

View File

@@ -1,19 +1,22 @@
environment:
matrix:
# note: please use "tox --listenvs" to populate the build matrix
- TOXENV: "py27-pytest33"
- TOXENV: "py34-pytest33"
- TOXENV: "py35-pytest33"
- TOXENV: "py36-pytest33"
- TOXENV: "py27-pytest33-pexpect"
- TOXENV: "py36-pytest33-pexpect"
- TOXENV: "py27-pytest36"
- TOXENV: "py34-pytest36"
- TOXENV: "py35-pytest36"
- TOXENV: "py36-pytest36"
- TOXENV: "py27-pytest36-pexpect"
- TOXENV: "py36-pytest36-pexpect"
- TOXENV: "flakes"
- TOXENV: "readme"
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.
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

View File

@@ -13,8 +13,7 @@
{% if definitions[category]['showcontent'] %}
{% 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 %}
{% else %}

View File

@@ -1 +0,0 @@
towncrier

View File

@@ -25,7 +25,7 @@ to run each test in a controlled subprocess. Here is a basic example::
If you run this with::
$ py.test -n1
$ pytest -n1
=========================== test session starts ============================
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev8
plugins: xdist, bugzilla, cache, oejskit, cli, pep8, cov
@@ -46,7 +46,7 @@ You'll see that a couple of tests are reported as crashing, indicated
by lower-case ``f`` and the respective failure summary. You can also use
the xdist-provided parallelization feature to speed up your testing::
$ py.test -n3
$ pytest -n3
=========================== test session starts ============================
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev8
plugins: xdist, bugzilla, cache, oejskit, cli, pep8, cov

View File

@@ -8,7 +8,7 @@ passenv = http_proxy https_proxy
deps = -rrequirements.txt
changedir = {envtmpdir}
commands =
py.test -s -v \
pytest -s -v \
--doctest-modules \
--junitxml=tests.xml \
--dist=loadscope \

View File

@@ -1,12 +1,12 @@
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(
name="pytest-xdist",
use_scm_version={'write_to': 'xdist/_version.py'},
description='py.test xdist plugin for distributed testing'
description='pytest xdist plugin for distributed testing'
' and loop-on-failing modes',
long_description=open('README.rst').read(),
license='MIT',

View File

@@ -1,4 +1,6 @@
import os
import re
import textwrap
import py
import pytest
@@ -54,8 +56,8 @@ class TestDistribution:
def test_n1_skip(self, testdir):
p1 = testdir.makepyfile("""
def test_skip():
import py
py.test.skip("myreason")
import pytest
pytest.skip("myreason")
""")
result = testdir.runpytest(p1, "-n1")
assert result.ret == 0
@@ -78,7 +80,7 @@ class TestDistribution:
def test_manytests_to_one_popen(self, testdir):
p1 = testdir.makepyfile(
"""
import py
import pytest
def test_fail0():
assert 0
def test_fail1():
@@ -86,7 +88,7 @@ class TestDistribution:
def test_ok():
pass
def test_skip():
py.test.skip("hello")
pytest.skip("hello")
""", )
result = testdir.runpytest(p1, "-v", '-d', '--tx=popen', '--tx=popen')
result.stdout.fnmatch_lines([
@@ -124,7 +126,7 @@ class TestDistribution:
def test_dist_ini_specified(self, testdir):
p1 = testdir.makepyfile(
"""
import py
import pytest
def test_fail0():
assert 0
def test_fail1():
@@ -132,7 +134,7 @@ class TestDistribution:
def test_ok():
pass
def test_skip():
py.test.skip("hello")
pytest.skip("hello")
""", )
testdir.makeini("""
[pytest]
@@ -145,13 +147,13 @@ class TestDistribution:
])
assert result.ret == 1
@py.test.mark.xfail("sys.platform.startswith('java')", run=False)
@pytest.mark.xfail("sys.platform.startswith('java')", run=False)
def test_dist_tests_with_crash(self, testdir):
if not hasattr(py.std.os, 'kill'):
py.test.skip("no os.kill")
if not hasattr(os, 'kill'):
pytest.skip("no os.kill")
p1 = testdir.makepyfile("""
import py
import pytest
def test_fail0():
assert 0
def test_fail1():
@@ -159,7 +161,7 @@ class TestDistribution:
def test_ok():
pass
def test_skip():
py.test.skip("hello")
pytest.skip("hello")
def test_crash():
import time
import os
@@ -299,7 +301,7 @@ class TestDistEach:
assert not result.ret
result.stdout.fnmatch_lines(["*2 pass*"])
@py.test.mark.xfail(
@pytest.mark.xfail(
run=False,
reason="other python versions might not have py.test installed")
def test_simple_diffoutput(self, testdir):
@@ -307,7 +309,7 @@ class TestDistEach:
for name in ("python2.5", "python2.6"):
interp = py.path.local.sysfind(name)
if interp is None:
py.test.skip("%s not found" % name)
pytest.skip("%s not found" % name)
interpreters.append(interp)
testdir.makepyfile(
@@ -330,11 +332,11 @@ class TestDistEach:
class TestTerminalReporting:
def test_pass_skip_fail(self, testdir):
testdir.makepyfile("""
import py
import pytest
def test_ok():
pass
def test_skip():
py.test.skip("xx")
pytest.skip("xx")
def test_func():
assert 0
""")
@@ -421,7 +423,7 @@ def test_teardownfails_one_function(testdir):
["*def teardown_function(function):*", "*1 passed*1 error*"])
@py.test.mark.xfail
@pytest.mark.xfail
def test_terminate_on_hangingnode(testdir):
p = testdir.makeconftest("""
def pytest_sessionfinish(session):
@@ -585,7 +587,7 @@ def test_skipping(testdir):
def test_issue34_pluginloading_in_subprocess(testdir):
testdir.tmpdir.join("plugin123.py").write(
py.code.Source("""
textwrap.dedent("""
def pytest_namespace():
return {'sample_variable': 'testing'}
"""))

View File

@@ -31,7 +31,9 @@ def test_dist_options(testdir):
def test_auto_detect_cpus(testdir, monkeypatch):
import os
if hasattr(os, 'cpu_count'):
if hasattr(os, 'sched_getaffinity'):
monkeypatch.setattr(os, 'sched_getaffinity', lambda _pid: set(range(99)))
elif hasattr(os, 'cpu_count'):
monkeypatch.setattr(os, 'cpu_count', lambda: 99)
else:
import multiprocessing
@@ -43,6 +45,11 @@ def test_auto_detect_cpus(testdir, monkeypatch):
config = testdir.parseconfigure("-nauto")
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):
from xdist.plugin import pytest_cmdline_main as check_options

View File

@@ -1,11 +1,12 @@
import py
import pprint
import pytest
from xdist.workermanage import WorkerController, unserialize_report
from xdist.remote import serialize_report
import execnet
import marshal
queue = py.builtin._tryimport("queue", "Queue")
from six.moves.queue import Queue
WAIT_TIMEOUT = 10.0
@@ -14,7 +15,7 @@ def check_marshallable(d):
try:
marshal.dumps(d)
except ValueError:
py.std.pprint.pprint(d)
pprint.pprint(d)
raise ValueError("not marshallable")
@@ -32,7 +33,7 @@ class WorkerSetup:
def __init__(self, request, testdir):
self.request = request
self.testdir = testdir
self.events = queue.Queue()
self.events = Queue()
def setup(self, ):
self.testdir.chdir()
@@ -344,7 +345,7 @@ class TestWorkerInteractor:
for data in worker.slp.channel:
worker.slp.process_from_remote(data)
worker.slp.process_from_remote(worker.slp.ENDMARK)
py.std.pprint.pprint(hookrec.hookrecorder.calls)
pprint.pprint(hookrec.hookrecorder.calls)
hookrec.hookrecorder.contains([
("pytest_collectstart", "collector.fspath == aaa"),
("pytest_pycollect_makeitem", "name == 'test_func'"),

View File

@@ -1,5 +1,7 @@
from __future__ import print_function
import py
import pytest
import textwrap
import execnet
from _pytest.pytester import HookRecorder
from xdist import workermanage, newhooks
@@ -169,7 +171,7 @@ class TestNodeManager:
p, = nodemanager.gwmanager.multi_exec(
"import os ; channel.send(os.getcwd())").receive_each()
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.join("dir1").check()
assert p.join("dir1", "file1").check()
@@ -198,7 +200,7 @@ class TestNodeManager:
source.ensure("dir1", "somefile", dir=1)
dir2.ensure("hello")
source.ensure("bogusdir", "file")
source.join("tox.ini").write(py.std.textwrap.dedent("""
source.join("tox.ini").write(textwrap.dedent("""
[pytest]
rsyncdirs=dir1/dir2
"""))
@@ -217,7 +219,7 @@ class TestNodeManager:
dir2.ensure("hello")
source.ensure("foo", "bar")
source.ensure("bar", "foo")
source.join("tox.ini").write(py.std.textwrap.dedent("""
source.join("tox.ini").write(textwrap.dedent("""
[pytest]
rsyncdirs = dir1 dir5
rsyncignore = dir1/dir2 dir5/dir6 foo*

26
tox.ini
View File

@@ -1,8 +1,8 @@
[tox]
# if you change the envlist, please update .travis.yml file as well
envlist=
py{27,34,35,36}-pytest{30,31,32,33}
py{27,36}-pytest{30,31,32,33}-pexpect
py{27,34,35,36}-pytest{34,35,36}
py{27,36}-pytest36-pexpect
py{27,36}-pytest{master,features}
flakes
readme
@@ -15,10 +15,9 @@ deps =
pycmd
# to avoid .eggs
setuptools_scm
pytest30: pytest~=3.0.5
pytest31: pytest~=3.1.0
pytest32: pytest~=3.2.0
pytest33: pytest~=3.3.0
pytest34: pytest~=3.4.0
pytest35: pytest~=3.5.0
pytest36: pytest~=3.6.0
pytestmaster: git+https://github.com/pytest-dev/pytest.git@master
pytestfeatures: git+https://github.com/pytest-dev/pytest.git@features
pexpect: pexpect
@@ -27,7 +26,7 @@ platform=
commands=
# always clean to avoid code unmarshal mismatch on old python/pytest
py.cleanup -aq
py.test {posargs}
pytest {posargs}
[testenv:flakes]
changedir=
@@ -40,7 +39,18 @@ deps = readme
skip_install = true
commands = python setup.py check -r -s
[testenv:release]
changedir=
decription = do a release, required posarg of the version number
basepython = python3.6
skipsdist = True
usedevelop = True
passenv = *
deps =
towncrier
commands =
towncrier --version {posargs} --yes
[pytest]
addopts = -rsfxX
;; hello

View File

@@ -10,15 +10,15 @@ from xdist.scheduler import (
)
queue = py.builtin._tryimport('queue', 'Queue')
from six.moves.queue import Empty, Queue
class Interrupted(KeyboardInterrupt):
""" signals an immediate interruption. """
class DSession:
"""A py.test plugin which runs a distributed test session
class DSession(object):
"""A pytest plugin which runs a distributed test session
At the beginning of the test session this creates a NodeManager
instance which creates and starts all nodes. Nodes then emit
@@ -26,7 +26,7 @@ class DSession:
methods.
Once a node is started it will automatically start running the
py.test mainloop with some custom hooks. This means a node
pytest mainloop with some custom hooks. This means a node
automatically starts collecting tests. Once tests are collected
it will wait for instructions.
"""
@@ -41,7 +41,7 @@ class DSession:
self.shuttingdown = False
self.countfailures = 0
self.maxfail = config.getvalue("maxfail")
self.queue = queue.Queue()
self.queue = Queue()
self._session = None
self._failed_collection_errors = {}
self._active_nodes = set()
@@ -129,7 +129,7 @@ class DSession:
try:
eventcall = self.queue.get(timeout=2.0)
break
except queue.Empty:
except Empty:
continue
callname, kwargs = eventcall
assert callname, kwargs
@@ -316,7 +316,7 @@ class DSession:
self.config.hook.pytest_runtest_logreport(report=rep)
class TerminalDistReporter:
class TerminalDistReporter(object):
def __init__(self, config):
self.config = config
self.tr = config.pluginmanager.getplugin("terminalreporter")

View File

@@ -1,15 +1,16 @@
"""
Implement -f aka looponfailing for py.test.
Implement -f aka looponfailing for pytest.
NOTE that we try to avoid loading and depending on application modules
within the controlling process (the one that starts repeatedly test
processes) otherwise changes to source code can crash
the controlling process which should best never happen.
"""
from __future__ import print_function
import py
import pytest
import sys
import time
import execnet
@@ -59,7 +60,7 @@ class RemoteControl(object):
def trace(self, *args):
if self.config.option.debug:
msg = " ".join([str(x) for x in args])
py.builtin.print_("RemoteControl:", msg)
print("RemoteControl:", msg)
def initgateway(self):
return execnet.makegateway("popen")
@@ -157,7 +158,7 @@ def init_worker_session(channel, args, option_dict):
WorkerFailSession(config, channel).main()
class WorkerFailSession:
class WorkerFailSession(object):
def __init__(self, config, channel):
self.config = config
self.channel = channel
@@ -211,7 +212,7 @@ class WorkerFailSession:
self.channel.send((trails, failreports, self.collection_failed))
class StatRecorder:
class StatRecorder(object):
def __init__(self, rootdirlist):
self.rootdirlist = rootdirlist
self.statcache = {}
@@ -228,7 +229,7 @@ class StatRecorder:
changed = self.check()
if changed:
return
py.std.time.sleep(checkinterval)
time.sleep(checkinterval)
def check(self, removepycfiles=True): # noqa, too complex
changed = False
@@ -247,7 +248,7 @@ class StatRecorder:
if oldstat.mtime != curstat.mtime or \
oldstat.size != curstat.size:
changed = True
py.builtin.print_("# MODIFIED", path)
print("# MODIFIED", path)
if removepycfiles and path.ext == ".py":
pycfile = path + "c"
if pycfile.check():

View File

@@ -1,18 +1,34 @@
import os
import py
import pytest
def parse_numprocesses(s):
if s == 'auto':
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):
if s == 'auto':
return auto_detect_cpus()
else:
return int(s)

View File

@@ -14,7 +14,7 @@ import _pytest.hookspec
import pytest
class WorkerInteractor:
class WorkerInteractor(object):
def __init__(self, config, channel):
self.config = config
self.workerid = config.workerinput.get('workerid', "?")

View File

@@ -1,4 +1,4 @@
import py
from __future__ import print_function
from difflib import unified_diff
@@ -17,10 +17,10 @@ def report_collection_diff(from_collection, to_collection, from_id, to_id):
fromfile=from_id,
tofile=to_id,
)
error_message = py.builtin._totext(
'Different tests were collected between {from_id} and {to_id}. '
'The difference is:\n'
'{diff}'
error_message = (
u'Different tests were collected between {from_id} and {to_id}. '
u'The difference is:\n'
u'{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")])
return msg

View File

@@ -4,7 +4,7 @@ from xdist.workermanage import parse_spec_config
from xdist.report import report_collection_diff
class EachScheduling:
class EachScheduling(object):
"""Implement scheduling of test items on all nodes
If a node gets added after the test run is started then it is

View File

@@ -20,7 +20,7 @@ class LoadFileScheduling(LoadScopeScheduling):
This class behaves very much like LoadScopeScheduling, but with a file-level scope.
"""
def __init(self, config, log=None):
def __init__(self, config, log=None):
super(LoadFileScheduling, self).__init__(config, log)
if log is None:
self.log = Producer('loadfilesched')

View File

@@ -7,7 +7,7 @@ from xdist.workermanage import parse_spec_config
from xdist.report import report_collection_diff
class LoadScheduling:
class LoadScheduling(object):
"""Implement load scheduling across nodes.
This distributes the tests collected across all nodes so each test

View File

@@ -6,7 +6,7 @@ from xdist.report import report_collection_diff
from xdist.workermanage import parse_spec_config
class LoadScopeScheduling:
class LoadScopeScheduling(object):
"""Implement load scheduling across nodes, but grouping test by scope.
This distributes the tests collected across all nodes so each test is run

View File

@@ -1,10 +1,13 @@
from __future__ import print_function
import fnmatch
import os
import re
import threading
import py
import pytest
import execnet
import xdist.remote
from _pytest import runner # XXX load dynamically
@@ -32,7 +35,7 @@ class NodeManager(object):
def __init__(self, config, specs=None, defaultchdir="pyexecnetcache"):
self.config = config
self._nodesready = py.std.threading.Event()
self._nodesready = threading.Event()
self.trace = self.config.trace.get("nodemanager")
self.group = execnet.Group()
if specs is None:
@@ -47,7 +50,7 @@ class NodeManager(object):
self.specs.append(spec)
self.roots = self._getrsyncdirs()
self.rsyncoptions = self._getrsyncoptions()
self._rsynced_specs = py.builtin.set()
self._rsynced_specs = set()
def rsync_roots(self, gateway):
"""Rsync the set of roots to the node's gateway cwd."""
@@ -179,12 +182,11 @@ class HostRSync(execnet.RSync):
if self._verbose:
path = os.path.basename(self._sourcedir) + "/" + modified_rel_path
remotepath = gateway.spec.chdir
py.builtin.print_('%s:%s <= %s' %
(gateway.spec, remotepath, path))
print('%s:%s <= %s' % (gateway.spec, remotepath, path))
def make_reltoroot(roots, args):
# XXX introduce/use public API for splitting py.test args
# XXX introduce/use public API for splitting pytest args
splitcode = "::"
result = []
for arg in args:
@@ -332,8 +334,9 @@ class WorkerController(object):
# should not land in receiver-thread
raise
except: # noqa
excinfo = py.code.ExceptionInfo()
py.builtin.print_("!" * 20, excinfo)
from _pytest._code import ExceptionInfo
excinfo = ExceptionInfo()
print("!" * 20, excinfo)
self.config.notify_exception(excinfo)
self.shutdown()
self.notify_inproc("errordown", node=self, error=excinfo)