Skip to content

Commit fe3d37b

Browse files
committed
Merge pull request #1159 from dstufft/isolate-tests-and-run-concurrently
Isolate tests and run concurrently
2 parents d3b6381 + b9706a7 commit fe3d37b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+808
-872
lines changed

.travis.yml

+7-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ before_install:
1010
- echo -e "[web]\ncacerts = /etc/ssl/certs/ca-certificates.crt" >> ~/.hgrc
1111
- git config --global user.email "[email protected]"
1212
- git config --global user.name "Pip"
13-
install: pip install pytest git+https://github.com/pypa/virtualenv@develop#egg=virtualenv scripttest>=1.3 mock
14-
script: py.test
13+
install:
14+
- pip install --upgrade setuptools
15+
- pip install pytest pytest-xdist git+https://github.com/pypa/virtualenv@develop#egg=virtualenv scripttest>=1.3 mock
16+
script:
17+
- "if [[ $TRAVIS_PYTHON_VERSION == '3.2' ]]; then py.test -v; fi"
18+
- "if [[ $TRAVIS_PYTHON_VERSION != '3.2' ]]; then py.test -v -n 8; fi"
1519
notifications:
1620
irc: "irc.freenode.org#pip"
1721
branches:
@@ -20,4 +24,4 @@ branches:
2024
- 1.3.X
2125
- 1.4.X
2226
env:
23-
- PIP_USE_MIRRORS=true
27+
- PYTHONHASHSEED=0

tests/conftest.py

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import shutil
2+
3+
import py
4+
import pytest
5+
6+
from tests.lib import SRC_DIR, TestData
7+
from tests.lib.path import Path
8+
from tests.lib.scripttest import PipTestEnvironment
9+
from tests.lib.venv import VirtualEnvironment
10+
11+
12+
@pytest.fixture
13+
def tmpdir(request):
14+
"""
15+
Return a temporary directory path object which is unique to each test
16+
function invocation, created as a sub directory of the base temporary
17+
directory. The returned object is a ``tests.lib.path.Path`` object.
18+
19+
This is taken from pytest itself but modified to return our typical
20+
path object instead of py.path.local.
21+
"""
22+
name = request.node.name
23+
name = py.std.re.sub("[\W]", "_", name)
24+
tmp = request.config._tmpdirhandler.mktemp(name, numbered=True)
25+
return Path(tmp)
26+
27+
28+
@pytest.fixture
29+
def virtualenv(tmpdir, monkeypatch):
30+
"""
31+
Return a virtual environment which is unique to each test function
32+
invocation created inside of a sub directory of the test function's
33+
temporary directory. The returned object is a
34+
``tests.lib.venv.VirtualEnvironment`` object.
35+
"""
36+
# Force shutil to use the older method of rmtree that didn't use the fd
37+
# functions. These seem to fail on Travis (and only on Travis).
38+
monkeypatch.setattr(shutil, "_use_fd_functions", False, raising=False)
39+
40+
# Copy over our source tree so that each virtual environment is self
41+
# contained
42+
pip_src = tmpdir.join("pip_src").abspath
43+
shutil.copytree(SRC_DIR, pip_src,
44+
ignore=shutil.ignore_patterns(
45+
"*.pyc", "docs/", "tests/", "pip.egg-info",
46+
),
47+
)
48+
49+
# Create the virtual environment
50+
venv = VirtualEnvironment.create(
51+
tmpdir.join("workspace", "venv"),
52+
pip_source_dir=pip_src,
53+
)
54+
55+
# Undo our monkeypatching of shutil
56+
monkeypatch.undo()
57+
58+
return venv
59+
60+
61+
@pytest.fixture
62+
def script(tmpdir, virtualenv):
63+
"""
64+
Return a PipTestEnvironment which is unique to each test function and
65+
will execute all commands inside of the unique virtual environment for this
66+
test function. The returned object is a
67+
``tests.lib.scripttest.PipTestEnvironment``.
68+
"""
69+
return PipTestEnvironment(
70+
# The base location for our test environment
71+
tmpdir.join("workspace"),
72+
73+
# Tell the Test Environment where our virtualenv is located
74+
virtualenv=virtualenv.location,
75+
76+
# Do not ignore hidden files, they need to be checked as well
77+
ignore_hidden=False,
78+
79+
# We are starting with an already empty directory
80+
start_clear=False,
81+
82+
# We want to ensure no temporary files are left behind, so the
83+
# PipTestEnvironment needs to capture and assert against temp
84+
capture_temp=True,
85+
assert_no_temp=True,
86+
)
87+
88+
89+
@pytest.fixture
90+
def data(tmpdir):
91+
return TestData.copy(tmpdir.join("data"))
92+
93+
# This is here to work around a bug with pytest, pytest-xdist, and Python 3.2
94+

tests/functional/test_bundle.py

+7-11
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,22 @@
22
import textwrap
33
from os.path import abspath, exists, join
44
from pip.download import path_to_url2
5-
from tests.lib import tests_data, reset_env
6-
from tests.lib.path import Path
75
from tests.lib.local_repos import local_checkout
86

97

10-
def test_create_bundle():
8+
def test_create_bundle(script, tmpdir, data):
119
"""
1210
Test making a bundle. We'll grab one package from the filesystem
1311
(the FSPkg dummy package), one from vcs (initools) and one from an
1412
index (pip itself).
1513
1614
"""
17-
script = reset_env()
18-
fspkg = path_to_url2(Path(tests_data)/'packages'/'FSPkg')
15+
fspkg = path_to_url2(data.packages/'FSPkg')
1916
script.pip('install', '-e', fspkg)
2017
pkg_lines = textwrap.dedent('''\
2118
-e %s
2219
-e %s#egg=initools-dev
23-
pip''' % (fspkg, local_checkout('svn+http://svn.colorstudy.com/INITools/trunk')))
20+
pip''' % (fspkg, local_checkout('svn+http://svn.colorstudy.com/INITools/trunk', tmpdir.join("cache"))))
2421
script.scratch_path.join("bundle-req.txt").write(pkg_lines)
2522
# Create a bundle in env.scratch_path/ test.pybundle
2623
result = script.pip('bundle', '-r', script.scratch_path/ 'bundle-req.txt', script.scratch_path/ 'test.pybundle')
@@ -33,29 +30,28 @@ def test_create_bundle():
3330
assert 'build/pip/' in files
3431

3532

36-
def test_cleanup_after_create_bundle():
33+
def test_cleanup_after_create_bundle(script, tmpdir, data):
3734
"""
3835
Test clean up after making a bundle. Make sure (build|src)-bundle/ dirs are removed but not src/.
3936
4037
"""
41-
script = reset_env()
4238
# Install an editable to create a src/ dir.
4339
args = ['install']
4440
args.extend(['-e',
4541
'%s#egg=pip-test-package' %
46-
local_checkout('git+http://github.com/pypa/pip-test-package.git')])
42+
local_checkout('git+http://github.com/pypa/pip-test-package.git', tmpdir.join("cache"))])
4743
script.pip(*args)
4844
build = script.venv_path/"build"
4945
src = script.venv_path/"src"
5046
assert not exists(build), "build/ dir still exists: %s" % build
5147
assert exists(src), "expected src/ dir doesn't exist: %s" % src
5248

5349
# Make the bundle.
54-
fspkg = 'file://%s/FSPkg' %join(tests_data, 'packages')
50+
fspkg = path_to_url2(data.packages/'FSPkg')
5551
pkg_lines = textwrap.dedent('''\
5652
-e %s
5753
-e %s#egg=initools-dev
58-
pip''' % (fspkg, local_checkout('svn+http://svn.colorstudy.com/INITools/trunk')))
54+
pip''' % (fspkg, local_checkout('svn+http://svn.colorstudy.com/INITools/trunk', tmpdir.join("cache"))))
5955
script.scratch_path.join("bundle-req.txt").write(pkg_lines)
6056
script.pip('bundle', '-r', 'bundle-req.txt', 'test.pybundle')
6157
build_bundle = script.scratch_path/"build-bundle"

tests/functional/test_completion.py

+15-21
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import os
2-
from tests.lib import reset_env
32

43

5-
def test_completion_for_bash():
4+
def test_completion_for_bash(script):
65
"""
76
Test getting completion for bash shell
87
"""
9-
script = reset_env()
108
bash_completion = """\
119
_pip_completion()
1210
{
@@ -20,11 +18,10 @@ def test_completion_for_bash():
2018
assert bash_completion in result.stdout, 'bash completion is wrong'
2119

2220

23-
def test_completion_for_zsh():
21+
def test_completion_for_zsh(script):
2422
"""
2523
Test getting completion for zsh shell
2624
"""
27-
script = reset_env()
2825
zsh_completion = """\
2926
function _pip_completion {
3027
local words cword
@@ -40,32 +37,29 @@ def test_completion_for_zsh():
4037
assert zsh_completion in result.stdout, 'zsh completion is wrong'
4138

4239

43-
def test_completion_for_unknown_shell():
40+
def test_completion_for_unknown_shell(script):
4441
"""
4542
Test getting completion for an unknown shell
4643
"""
47-
script = reset_env()
4844
error_msg = 'no such option: --myfooshell'
4945
result = script.pip('completion', '--myfooshell', expect_error=True)
5046
assert error_msg in result.stderr, 'tests for an unknown shell failed'
5147

5248

53-
def test_completion_alone():
49+
def test_completion_alone(script):
5450
"""
5551
Test getting completion for none shell, just pip completion
5652
"""
57-
script = reset_env()
5853
result = script.pip('completion', expect_error=True)
5954
assert 'ERROR: You must pass --bash or --zsh' in result.stderr, \
6055
'completion alone failed -- ' + result.stderr
6156

6257

63-
def setup_completion(words, cword):
64-
environ = os.environ.copy()
65-
script = reset_env(environ)
66-
environ['PIP_AUTO_COMPLETE'] = '1'
67-
environ['COMP_WORDS'] = words
68-
environ['COMP_CWORD'] = cword
58+
def setup_completion(script, words, cword):
59+
script.environ = os.environ.copy()
60+
script.environ['PIP_AUTO_COMPLETE'] = '1'
61+
script.environ['COMP_WORDS'] = words
62+
script.environ['COMP_CWORD'] = cword
6963

7064
# expect_error is True because autocomplete exists with 1 status code
7165
result = script.run('python', '-c', 'import pip;pip.autocomplete()',
@@ -74,31 +68,31 @@ def setup_completion(words, cword):
7468
return result, script
7569

7670

77-
def test_completion_for_un_snippet():
71+
def test_completion_for_un_snippet(script):
7872
"""
7973
Test getting completion for ``un`` should return
8074
uninstall and unzip
8175
"""
8276

83-
res, env = setup_completion('pip un', '1')
77+
res, env = setup_completion(script, 'pip un', '1')
8478
assert res.stdout.strip().split() == ['uninstall', 'unzip'], res.stdout
8579

8680

87-
def test_completion_for_default_parameters():
81+
def test_completion_for_default_parameters(script):
8882
"""
8983
Test getting completion for ``--`` should contain --help
9084
"""
9185

92-
res, env = setup_completion('pip --', '1')
86+
res, env = setup_completion(script, 'pip --', '1')
9387
assert '--help' in res.stdout,\
9488
"autocomplete function could not complete ``--``"
9589

9690

97-
def test_completion_option_for_command():
91+
def test_completion_option_for_command(script):
9892
"""
9993
Test getting completion for ``--`` in command (eg. pip search --)
10094
"""
10195

102-
res, env = setup_completion('pip search --', '2')
96+
res, env = setup_completion(script, 'pip search --', '2')
10397
assert '--help' in res.stdout,\
10498
"autocomplete function could not complete ``--``"

0 commit comments

Comments
 (0)