Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f90fb73db | ||
|
|
c5fadcd734 | ||
|
|
16d636391b | ||
|
|
948f13730d | ||
|
|
db896a9d33 | ||
|
|
cf45eab977 | ||
|
|
00b0464d4b | ||
|
|
b3a1bf3c2e | ||
|
|
3fb369c8ac | ||
|
|
16694a978d | ||
|
|
2dcb40799f | ||
|
|
14bafa6dd5 | ||
|
|
b51286aaa2 | ||
|
|
03ddee6620 | ||
|
|
e03566b7d6 | ||
|
|
46cf204c64 |
@@ -1,21 +0,0 @@
|
|||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- TOXENV: "py35-pytestlatest"
|
|
||||||
- TOXENV: "py36-pytestlatest"
|
|
||||||
- TOXENV: "py37-pytestlatest"
|
|
||||||
- TOXENV: "py38-pytestlatest"
|
|
||||||
- TOXENV: "py38-pytestmaster"
|
|
||||||
- TOXENV: "py38-psutil"
|
|
||||||
|
|
||||||
install:
|
|
||||||
- C:\Python38\python -m pip install -U pip setuptools virtualenv
|
|
||||||
- C:\Python38\python -m pip install -U tox setuptools_scm
|
|
||||||
|
|
||||||
build: false # Not a C# project, build stuff at the test step instead.
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- C:\Python38\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
|
|
||||||
99
.github/workflows/main.yml
vendored
Normal file
99
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
name: build
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
tox_env:
|
||||||
|
- "py35-pytestlatest"
|
||||||
|
- "py36-pytestlatest"
|
||||||
|
- "py37-pytestlatest"
|
||||||
|
- "py38-pytestlatest"
|
||||||
|
- "py39-pytestlatest"
|
||||||
|
- "py38-pytestmaster"
|
||||||
|
- "py38-psutil"
|
||||||
|
- "linting"
|
||||||
|
|
||||||
|
os: [ubuntu-latest, windows-latest]
|
||||||
|
include:
|
||||||
|
- tox_env: "py35-pytestlatest"
|
||||||
|
python: "3.5"
|
||||||
|
- tox_env: "py36-pytestlatest"
|
||||||
|
python: "3.6"
|
||||||
|
- tox_env: "py37-pytestlatest"
|
||||||
|
python: "3.7"
|
||||||
|
- tox_env: "py38-pytestlatest"
|
||||||
|
python: "3.8"
|
||||||
|
- tox_env: "py39-pytestlatest"
|
||||||
|
python: "3.9"
|
||||||
|
- tox_env: "py38-pytestmaster"
|
||||||
|
python: "3.8"
|
||||||
|
- tox_env: "py38-psutil"
|
||||||
|
python: "3.8"
|
||||||
|
- tox_env: "linting"
|
||||||
|
python: "3.7"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python }}
|
||||||
|
- name: Install tox
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install tox
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
tox -e ${{ matrix.tox_env }}
|
||||||
|
|
||||||
|
linting:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: "3.7"
|
||||||
|
- name: Install tox
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install tox
|
||||||
|
- name: Linting
|
||||||
|
run: |
|
||||||
|
tox -e linting
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
|
||||||
|
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
needs: [build, linting]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: "3.7"
|
||||||
|
- name: Install wheel
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install wheel
|
||||||
|
- name: Build package
|
||||||
|
run: |
|
||||||
|
python setup.py sdist bdist_wheel
|
||||||
|
- name: Publish package to PyPI
|
||||||
|
uses: pypa/gh-action-pypi-publish@master
|
||||||
|
with:
|
||||||
|
user: __token__
|
||||||
|
password: ${{ secrets.pypi_token }}
|
||||||
64
.travis.yml
64
.travis.yml
@@ -1,64 +0,0 @@
|
|||||||
dist: xenial
|
|
||||||
language: python
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
irc:
|
|
||||||
channels:
|
|
||||||
- 'chat.freenode.net#pytest'
|
|
||||||
on_success: change
|
|
||||||
on_failure: change
|
|
||||||
skip_join: true
|
|
||||||
email:
|
|
||||||
- pytest-commit@python.org
|
|
||||||
|
|
||||||
install:
|
|
||||||
- pip install -U pip setuptools
|
|
||||||
- pip install tox setuptools_scm
|
|
||||||
script: tox
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- baseline
|
|
||||||
- test
|
|
||||||
- name: deploy
|
|
||||||
if: repo = pytest-dev/pytest-xdist AND tag IS present
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
include:
|
|
||||||
- stage: baseline
|
|
||||||
python: '3.7'
|
|
||||||
env: TOXENV=linting
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- $HOME/.cache/pre-commit
|
|
||||||
- python: '3.8'
|
|
||||||
env: TOXENV=py38-pytestlatest
|
|
||||||
|
|
||||||
- stage: test
|
|
||||||
python: "3.5"
|
|
||||||
env: TOXENV=py35-pytestlatest
|
|
||||||
- python: "3.6"
|
|
||||||
env: TOXENV=py36-pytestlatest
|
|
||||||
- python: "3.7"
|
|
||||||
env: TOXENV=py37-pytestlatest
|
|
||||||
- python: "3.9-dev"
|
|
||||||
env: TOXENV=py39-pytestlatest
|
|
||||||
- python: "3.8"
|
|
||||||
env: TOXENV=py38-pytestmaster
|
|
||||||
- python: "3.8"
|
|
||||||
env: TOXENV=py38-psutil
|
|
||||||
|
|
||||||
- stage: deploy
|
|
||||||
python: '3.8'
|
|
||||||
env:
|
|
||||||
install: pip install -U setuptools setuptools_scm
|
|
||||||
script: skip
|
|
||||||
deploy:
|
|
||||||
provider: pypi
|
|
||||||
user: ronny
|
|
||||||
distributions: sdist bdist_wheel
|
|
||||||
skip_upload_docs: true
|
|
||||||
password:
|
|
||||||
secure: cxmSDho5d+PYKEM4ZCg8ms1P4lzhYkrw6fEOm2HtTcsuCyY6aZMSgImWAnEYbJHSkdzgcxlXK9UKJ9B0YenXmBCkAr7UjdnpNXNmkySr0sYzlH/sfqt/dDATCHFaRKxnkOSOVywaDYhT9n8YudbXI77pXwD12i/CeSSJDbHhsu0JYUfAcb+D6YjRYoA2SEGCnzSzg+gDDfwXZx4ZiODCGLVwieNp1klCg88YROUE1BaYYNuUOONvfXX8+TWowbCF6ChH1WL/bZ49OStEYQNuYxZQZr4yClIqu9VJbchrU8j860K9ott2kkGTgfB/dDrQB/XncBubyIX9ikzCQAmmBXWAI3eyvWLPDk2Jz7kW2l2RT7syct80tCq3JhvQ1qdwr5ap7siocTLgnBW0tF4tkHSTFN3510fkc43npnp6FThebESQpnI24vqpwJ9hI/kW5mYi014Og2E/cpCXnz2XO8iZPDbqAMQpDsqEQoyhfGNgPTGp4K30TxRtwZBI5hHhDKnnR16fXtRgt1gYPvz/peUQvvpOm4JzIzGXPzluuutpnCBy75v5+oiwT3YRrLL/Meims9FtDDXL3qQubAE/ezIOOpm0N5XXV8DxIom8EN71yq5ab1tqhM+tBX7owRjy4FR4If2Q8feBdmTuh26DIQt/y+qSG8VkB9Sw/JCjc7c=
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
repo: pytest-dev/pytest-xdist
|
|
||||||
@@ -1,3 +1,12 @@
|
|||||||
|
pytest-xdist 2.2.0 (2020-12-14)
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- `#608 <https://github.com/pytest-dev/pytest-xdist/issues/608>`_: Internal errors in workers are now propagated to the master node.
|
||||||
|
|
||||||
|
|
||||||
pytest-xdist 2.1.0 (2020-08-25)
|
pytest-xdist 2.1.0 (2020-08-25)
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
|
|||||||
11
README.rst
11
README.rst
@@ -11,13 +11,8 @@
|
|||||||
:alt: Python versions
|
:alt: Python versions
|
||||||
:target: https://pypi.python.org/pypi/pytest-xdist
|
:target: https://pypi.python.org/pypi/pytest-xdist
|
||||||
|
|
||||||
.. image:: https://travis-ci.org/pytest-dev/pytest-xdist.svg?branch=master
|
.. image:: https://github.com/pytest-dev/pytest-xdist/workflows/build/badge.svg
|
||||||
:alt: Travis CI build status
|
:target: https://github.com/pytest-dev/pytest-xdist/actions
|
||||||
:target: https://travis-ci.org/pytest-dev/pytest-xdist
|
|
||||||
|
|
||||||
.. image:: https://ci.appveyor.com/api/projects/status/56eq1a1avd4sdd7e/branch/master?svg=true
|
|
||||||
:alt: AppVeyor build status
|
|
||||||
:target: https://ci.appveyor.com/project/pytestbot/pytest-xdist
|
|
||||||
|
|
||||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||||
:target: https://github.com/ambv/black
|
:target: https://github.com/ambv/black
|
||||||
@@ -247,7 +242,7 @@ at once. The specifications strings use the `xspec syntax`_.
|
|||||||
|
|
||||||
.. _`xspec syntax`: http://codespeak.net/execnet/basics.html#xspec
|
.. _`xspec syntax`: http://codespeak.net/execnet/basics.html#xspec
|
||||||
|
|
||||||
.. _`socketserver.py`: http://bitbucket.org/hpk42/execnet/raw/2af991418160/execnet/script/socketserver.py
|
.. _`socketserver.py`: https://raw.githubusercontent.com/pytest-dev/execnet/master/execnet/script/socketserver.py
|
||||||
|
|
||||||
.. _`execnet`: http://codespeak.net/execnet
|
.. _`execnet`: http://codespeak.net/execnet
|
||||||
|
|
||||||
|
|||||||
@@ -174,6 +174,24 @@ class DSession:
|
|||||||
assert not crashitem, (crashitem, node)
|
assert not crashitem, (crashitem, node)
|
||||||
self._active_nodes.remove(node)
|
self._active_nodes.remove(node)
|
||||||
|
|
||||||
|
def worker_internal_error(self, node, formatted_error):
|
||||||
|
"""
|
||||||
|
pytest_internalerror() was called on the worker.
|
||||||
|
|
||||||
|
pytest_internalerror() arguments are an excinfo and an excrepr, which can't
|
||||||
|
be serialized, so we go with a poor man's solution of raising an exception
|
||||||
|
here ourselves using the formatted message.
|
||||||
|
"""
|
||||||
|
self._active_nodes.remove(node)
|
||||||
|
try:
|
||||||
|
assert False, formatted_error
|
||||||
|
except AssertionError:
|
||||||
|
from _pytest._code import ExceptionInfo
|
||||||
|
|
||||||
|
excinfo = ExceptionInfo.from_current()
|
||||||
|
excrepr = excinfo.getrepr()
|
||||||
|
self.config.hook.pytest_internalerror(excrepr=excrepr, excinfo=excinfo)
|
||||||
|
|
||||||
def worker_errordown(self, node, error):
|
def worker_errordown(self, node, error):
|
||||||
"""Emitted by the WorkerController when a node dies."""
|
"""Emitted by the WorkerController when a node dies."""
|
||||||
self.config.hook.pytest_testnodedown(node=node, error=error)
|
self.config.hook.pytest_testnodedown(node=node, error=error)
|
||||||
|
|||||||
@@ -33,8 +33,10 @@ class WorkerInteractor:
|
|||||||
self.channel.send((name, kwargs))
|
self.channel.send((name, kwargs))
|
||||||
|
|
||||||
def pytest_internalerror(self, excrepr):
|
def pytest_internalerror(self, excrepr):
|
||||||
for line in str(excrepr).split("\n"):
|
formatted_error = str(excrepr)
|
||||||
|
for line in formatted_error.split("\n"):
|
||||||
self.log("IERROR>", line)
|
self.log("IERROR>", line)
|
||||||
|
interactor.sendevent("internal_error", formatted_error=formatted_error)
|
||||||
|
|
||||||
def pytest_sessionstart(self, session):
|
def pytest_sessionstart(self, session):
|
||||||
self.session = session
|
self.session = session
|
||||||
|
|||||||
@@ -324,6 +324,8 @@ class WorkerController:
|
|||||||
self.log("ignoring {}({})".format(eventname, kwargs))
|
self.log("ignoring {}({})".format(eventname, kwargs))
|
||||||
elif eventname == "workerready":
|
elif eventname == "workerready":
|
||||||
self.notify_inproc(eventname, node=self, **kwargs)
|
self.notify_inproc(eventname, node=self, **kwargs)
|
||||||
|
elif eventname == "internal_error":
|
||||||
|
self.notify_inproc(eventname, node=self, **kwargs)
|
||||||
elif eventname == "workerfinished":
|
elif eventname == "workerfinished":
|
||||||
self._down = True
|
self._down = True
|
||||||
self.workeroutput = kwargs["workeroutput"]
|
self.workeroutput = kwargs["workeroutput"]
|
||||||
|
|||||||
@@ -772,19 +772,23 @@ class TestWarnings:
|
|||||||
|
|
||||||
testdir.makeconftest(
|
testdir.makeconftest(
|
||||||
"""
|
"""
|
||||||
def pytest_warning_captured():
|
def pytest_warning_captured(warning_message):
|
||||||
assert False, "this hook should not be called in this version"
|
if warning_message == "my custom worker warning":
|
||||||
|
assert False, (
|
||||||
|
"this hook should not be called from workers "
|
||||||
|
"in this version: {}"
|
||||||
|
).format(warning_message)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
testdir.makepyfile(
|
testdir.makepyfile(
|
||||||
"""
|
"""
|
||||||
import warnings
|
import warnings
|
||||||
def test():
|
def test():
|
||||||
warnings.warn("custom warning")
|
warnings.warn("my custom worker warning")
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest("-n1")
|
result = testdir.runpytest("-n1")
|
||||||
result.stdout.fnmatch_lines(["* 1 passed in *"])
|
result.stdout.fnmatch_lines(["*1 passed*"])
|
||||||
result.stdout.no_fnmatch_line("*this hook should not be called in this version")
|
result.stdout.no_fnmatch_line("*this hook should not be called in this version")
|
||||||
|
|
||||||
@pytest.mark.parametrize("n", ["-n0", "-n1"])
|
@pytest.mark.parametrize("n", ["-n0", "-n1"])
|
||||||
@@ -1134,6 +1138,18 @@ def test_internal_error_with_maxfail(testdir):
|
|||||||
assert "INTERNALERROR" not in result.stderr.str()
|
assert "INTERNALERROR" not in result.stderr.str()
|
||||||
|
|
||||||
|
|
||||||
|
def test_internal_errors_propagate_to_master(testdir):
|
||||||
|
testdir.makeconftest(
|
||||||
|
"""
|
||||||
|
def pytest_collection_modifyitems():
|
||||||
|
raise RuntimeError("Some runtime error")
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
testdir.makepyfile("def test(): pass")
|
||||||
|
result = testdir.runpytest("-n1")
|
||||||
|
result.stdout.fnmatch_lines(["*RuntimeError: Some runtime error*"])
|
||||||
|
|
||||||
|
|
||||||
class TestLoadScope:
|
class TestLoadScope:
|
||||||
def test_by_module(self, testdir):
|
def test_by_module(self, testdir):
|
||||||
test_file = """
|
test_file = """
|
||||||
|
|||||||
1
tox.ini
1
tox.ini
@@ -24,6 +24,7 @@ commands =
|
|||||||
[testenv:linting]
|
[testenv:linting]
|
||||||
skip_install = True
|
skip_install = True
|
||||||
usedevelop = True
|
usedevelop = True
|
||||||
|
passenv = PRE_COMMIT_HOME
|
||||||
deps =
|
deps =
|
||||||
pre-commit
|
pre-commit
|
||||||
commands = pre-commit run --all-files --show-diff-on-failure
|
commands = pre-commit run --all-files --show-diff-on-failure
|
||||||
|
|||||||
Reference in New Issue
Block a user