summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/git_submodule_helpers.py13
-rwxr-xr-xtests/packages/HackedEggInfo/setup.py17
-rw-r--r--tests/packages/README.txt3
-rw-r--r--tests/packages/child-0.1.tar.gzbin0 -> 498 bytes
-rw-r--r--tests/packages/parent-0.1.tar.gzbin0 -> 483 bytes
-rw-r--r--tests/test_basic.py10
-rw-r--r--tests/test_cleanup.py23
-rw-r--r--tests/test_hashes.py194
-rw-r--r--tests/test_index.py29
-rw-r--r--tests/test_pip.py26
-rw-r--r--tests/test_requirements.py17
-rw-r--r--tests/test_test.py21
-rw-r--r--tests/test_unicode.py4
-rw-r--r--tests/test_uninstall.py57
-rw-r--r--tests/test_upgrade.py4
-rw-r--r--tests/test_user_site.py95
-rw-r--r--tests/test_util.py140
-rw-r--r--tests/test_vcs_git.py5
18 files changed, 619 insertions, 39 deletions
diff --git a/tests/git_submodule_helpers.py b/tests/git_submodule_helpers.py
index ef08b2636..ecb789b10 100644
--- a/tests/git_submodule_helpers.py
+++ b/tests/git_submodule_helpers.py
@@ -44,19 +44,22 @@ def _create_test_package_with_submodule(env):
packages=find_packages(),
)
'''), version_pkg_path)
- env.run('git', 'init', cwd=version_pkg_path)
- env.run('git', 'add', '.', cwd=version_pkg_path)
+ env.run('git', 'init', cwd=version_pkg_path, expect_error=True)
+ env.run('git', 'add', '.', cwd=version_pkg_path, expect_error=True)
env.run('git', 'commit', '-q',
'--author', 'Pip <python-virtualenv@googlegroups.com>',
- '-am', 'initial version', cwd=version_pkg_path)
+ '-am', 'initial version', cwd=version_pkg_path,
+ expect_error=True)
submodule_path = _create_test_package_submodule(env)
- env.run('git', 'submodule', 'add', submodule_path, 'testpkg/static', cwd=version_pkg_path)
+ env.run('git', 'submodule', 'add', submodule_path, 'testpkg/static', cwd=version_pkg_path,
+ expect_error=True)
env.run('git', 'commit', '-q',
'--author', 'Pip <python-virtualenv@googlegroups.com>',
- '-am', 'initial version w submodule', cwd=version_pkg_path)
+ '-am', 'initial version w submodule', cwd=version_pkg_path,
+ expect_error=True)
return version_pkg_path, submodule_path
diff --git a/tests/packages/HackedEggInfo/setup.py b/tests/packages/HackedEggInfo/setup.py
new file mode 100755
index 000000000..c34b57c4b
--- /dev/null
+++ b/tests/packages/HackedEggInfo/setup.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+
+from setuptools import setup
+from setuptools.command import egg_info as orig_egg_info
+
+class egg_info (orig_egg_info.egg_info):
+ def run(self):
+ orig_egg_info.egg_info.run(self)
+
+
+setup(
+ name = "hackedegginfo",
+ version = '0.0.0',
+ cmdclass = {'egg_info':egg_info },
+ zip_safe = False,
+)
+
diff --git a/tests/packages/README.txt b/tests/packages/README.txt
index b6ecde635..069b32c14 100644
--- a/tests/packages/README.txt
+++ b/tests/packages/README.txt
@@ -4,3 +4,6 @@ Version 0.2broken has a setup.py crafted to fail on install (and only on
install). If any earlier step would fail (i.e. egg-info-generation), the
already-installed version would never be uninstalled, so uninstall-rollback
would not come into play.
+
+The parent-0.1.tar.gz and child-0.1.tar.gz packages are used by
+test_uninstall:test_uninstall_overlapping_package.
diff --git a/tests/packages/child-0.1.tar.gz b/tests/packages/child-0.1.tar.gz
new file mode 100644
index 000000000..2fb34ca5d
--- /dev/null
+++ b/tests/packages/child-0.1.tar.gz
Binary files differ
diff --git a/tests/packages/parent-0.1.tar.gz b/tests/packages/parent-0.1.tar.gz
new file mode 100644
index 000000000..130e756f4
--- /dev/null
+++ b/tests/packages/parent-0.1.tar.gz
Binary files differ
diff --git a/tests/test_basic.py b/tests/test_basic.py
index c27e28fd1..a49824abf 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -376,6 +376,16 @@ def test_install_with_pax_header():
run_pip('install', 'paxpkg.tar.bz2', cwd=run_from)
+def test_install_with_hacked_egg_info():
+ """
+ test installing a package which defines its own egg_info class
+ """
+ reset_env()
+ run_from = abspath(join(here, 'packages', 'HackedEggInfo'))
+ result = run_pip('install', '.', cwd=run_from)
+ assert 'Successfully installed hackedegginfo\n' in result.stdout
+
+
def test_install_using_install_option_and_editable():
"""
Test installing a tool using -e and --install-option
diff --git a/tests/test_cleanup.py b/tests/test_cleanup.py
index 15a050833..c57db91ee 100644
--- a/tests/test_cleanup.py
+++ b/tests/test_cleanup.py
@@ -17,6 +17,7 @@ def test_cleanup_after_install_from_pypi():
src = env.scratch_path/"src"
assert not exists(build), "build/ dir still exists: %s" % build
assert not exists(src), "unexpected src/ dir exists: %s" % src
+ env.assert_no_temp()
def test_cleanup_after_install_editable_from_hg():
@@ -34,6 +35,7 @@ def test_cleanup_after_install_editable_from_hg():
src = env.venv_path/'src'
assert not exists(build), "build/ dir still exists: %s" % build
assert exists(src), "expected src/ dir doesn't exist: %s" % src
+ env.assert_no_temp()
def test_cleanup_after_install_from_local_directory():
@@ -48,6 +50,7 @@ def test_cleanup_after_install_from_local_directory():
src = env.venv_path/'src'
assert not exists(build), "unexpected build/ dir exists: %s" % build
assert not exists(src), "unexpected src/ dir exist: %s" % src
+ env.assert_no_temp()
def test_cleanup_after_create_bundle():
@@ -79,6 +82,7 @@ def test_cleanup_after_create_bundle():
src_bundle = env.scratch_path/"src-bundle"
assert not exists(build_bundle), "build-bundle/ dir still exists: %s" % build_bundle
assert not exists(src_bundle), "src-bundle/ dir still exists: %s" % src_bundle
+ env.assert_no_temp()
# Make sure previously created src/ from editable still exists
assert exists(src), "expected src dir doesn't exist: %s" % src
@@ -96,6 +100,25 @@ def test_no_install_and_download_should_not_leave_build_dir():
assert not os.path.exists(env.venv_path/'/build'), "build/ dir should be deleted"
+def test_cleanup_req_satisifed_no_name():
+ """
+ Test cleanup when req is already satisfied, and req has no 'name'
+ """
+ #this test confirms Issue #420 is fixed
+ #reqs with no 'name' that were already satisfied were leaving behind tmp build dirs
+ #2 examples of reqs that would do this
+ # 1) https://bitbucket.org/ianb/initools/get/tip.zip
+ # 2) parent-0.1.tar.gz
+
+ dist = abspath(join(here, 'packages', 'parent-0.1.tar.gz'))
+ env = reset_env()
+ result = run_pip('install', dist)
+ result = run_pip('install', dist)
+ build = env.venv_path/'build'
+ assert not exists(build), "unexpected build/ dir exists: %s" % build
+ env.assert_no_temp()
+
+
def test_download_should_not_delete_existing_build_dir():
"""
It should not delete build/ if existing before run the command
diff --git a/tests/test_hashes.py b/tests/test_hashes.py
new file mode 100644
index 000000000..79c4f1649
--- /dev/null
+++ b/tests/test_hashes.py
@@ -0,0 +1,194 @@
+import os
+
+from nose.tools import assert_raises
+
+from pip.download import _get_hash_from_file, _check_hash
+from pip.exceptions import InstallationError
+from pip.index import Link
+
+
+def test_get_hash_from_file_md5():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#md5=d41d8cd98f00b204e9800998ecf8427e")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert download_hash.digest_size == 16
+ assert download_hash.hexdigest() == "d41d8cd98f00b204e9800998ecf8427e"
+
+
+def test_get_hash_from_file_sha1():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha1=da39a3ee5e6b4b0d3255bfef95601890afd80709")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert download_hash.digest_size == 20
+ assert download_hash.hexdigest() == "da39a3ee5e6b4b0d3255bfef95601890afd80709"
+
+
+def test_get_hash_from_file_sha224():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha224=d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert download_hash.digest_size == 28
+ assert download_hash.hexdigest() == "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"
+
+
+def test_get_hash_from_file_sha384():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha384=38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert download_hash.digest_size == 48
+ assert download_hash.hexdigest() == "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"
+
+
+def test_get_hash_from_file_sha256():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert download_hash.digest_size == 32
+ assert download_hash.hexdigest() == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+
+
+def test_get_hash_from_file_sha512():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha512=cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert download_hash.digest_size == 64
+ assert download_hash.hexdigest() == "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
+
+
+def test_get_hash_from_file_unknown():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#unknown_hash=d41d8cd98f00b204e9800998ecf8427e")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert download_hash is None
+
+
+def test_check_hash_md5_valid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#md5=d41d8cd98f00b204e9800998ecf8427e")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ _check_hash(download_hash, file_link)
+
+
+def test_check_hash_md5_invalid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#md5=deadbeef")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert_raises(InstallationError, _check_hash, download_hash, file_link)
+
+
+def test_check_hash_sha1_valid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha1=da39a3ee5e6b4b0d3255bfef95601890afd80709")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ _check_hash(download_hash, file_link)
+
+
+def test_check_hash_sha1_invalid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha1=deadbeef")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert_raises(InstallationError, _check_hash, download_hash, file_link)
+
+
+def test_check_hash_sha224_valid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha224=d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f'")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ _check_hash(download_hash, file_link)
+
+
+def test_check_hash_sha224_invalid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha224=deadbeef")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert_raises(InstallationError, _check_hash, download_hash, file_link)
+
+
+def test_check_hash_sha384_valid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha384=38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ _check_hash(download_hash, file_link)
+
+
+def test_check_hash_sha384_invalid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha384=deadbeef")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert_raises(InstallationError, _check_hash, download_hash, file_link)
+
+
+def test_check_hash_sha256_valid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ _check_hash(download_hash, file_link)
+
+
+def test_check_hash_sha256_invalid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha256=deadbeef")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert_raises(InstallationError, _check_hash, download_hash, file_link)
+
+
+def test_check_hash_sha512_valid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha512=cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ _check_hash(download_hash, file_link)
+
+
+def test_check_hash_sha512_invalid():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#sha512=deadbeef")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert_raises(InstallationError, _check_hash, download_hash, file_link)
+
+
+def test_check_hasher_mismsatch():
+ file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "packages", "gmpy-1.15.tar.gz")
+ file_link = Link("http://testserver/gmpy-1.15.tar.gz#md5=d41d8cd98f00b204e9800998ecf8427e")
+ other_link = Link("http://testserver/gmpy-1.15.tar.gz#sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+
+ download_hash = _get_hash_from_file(file_path, file_link)
+
+ assert_raises(InstallationError, _check_hash, download_hash, other_link)
diff --git a/tests/test_index.py b/tests/test_index.py
index 6f9d216dc..c537172aa 100644
--- a/tests/test_index.py
+++ b/tests/test_index.py
@@ -1,4 +1,6 @@
-from pip.index import package_to_requirement, HTMLPage
+from pip.index import package_to_requirement, HTMLPage, get_mirrors, DEFAULT_MIRROR_HOSTNAME
+from string import ascii_lowercase
+from mock import patch
def test_package_name_should_be_converted_to_requirement():
@@ -26,3 +28,28 @@ def test_html_page_should_be_able_to_scrap_rel_links():
assert len(links) == 1
assert links[0].url == 'http://supervisord.org/'
+@patch('socket.gethostbyname_ex')
+def test_get_mirrors(mock_gethostbyname_ex):
+ # Test when the expected result comes back
+ # from socket.gethostbyname_ex
+ mock_gethostbyname_ex.return_value = ('g.pypi.python.org', [DEFAULT_MIRROR_HOSTNAME], ['129.21.171.98'])
+ mirrors = get_mirrors()
+ # Expect [a-g].pypi.python.org, since last mirror
+ # is returned as g.pypi.python.org
+ assert len(mirrors) == 7
+ for c in "abcdefg":
+ assert c + ".pypi.python.org" in mirrors
+
+@patch('socket.gethostbyname_ex')
+def test_get_mirrors_no_cname(mock_gethostbyname_ex):
+ # Test when the UNexpected result comes back
+ # from socket.gethostbyname_ex
+ # (seeing this in Japan and was resulting in 216k
+ # invalid mirrors and a hot CPU)
+ mock_gethostbyname_ex.return_value = (DEFAULT_MIRROR_HOSTNAME, [DEFAULT_MIRROR_HOSTNAME], ['129.21.171.98'])
+ mirrors = get_mirrors()
+ # Falls back to [a-z].pypi.python.org
+ assert len(mirrors) == 26
+ for c in ascii_lowercase:
+ assert c + ".pypi.python.org" in mirrors
+
diff --git a/tests/test_pip.py b/tests/test_pip.py
index 10f075b98..8612232cf 100644
--- a/tests/test_pip.py
+++ b/tests/test_pip.py
@@ -314,12 +314,18 @@ class TestPipEnvironment(TestFileEnvironment):
assert self.venv_path == virtualenv_paths[0] # sanity check
for id, path in zip(('venv', 'lib', 'include', 'bin'), virtualenv_paths):
+ #fix for virtualenv issue #306
+ if hasattr(sys, "pypy_version_info") and id == 'lib':
+ path = os.path.join(self.venv_path, 'lib-python', pyversion)
setattr(self, id+'_path', Path(path))
setattr(self, id, relpath(self.root_path, path))
assert self.venv == TestPipEnvironment.venv # sanity check
- self.site_packages = self.lib/'site-packages'
+ if hasattr(sys, "pypy_version_info"):
+ self.site_packages = self.venv/'site-packages'
+ else:
+ self.site_packages = self.lib/'site-packages'
self.user_base_path = self.venv_path/'user'
self.user_site_path = self.venv_path/'user'/site_packages_suffix
@@ -362,6 +368,10 @@ class TestPipEnvironment(TestFileEnvironment):
if sitecustomize:
self._add_to_sitecustomize(sitecustomize)
+ # Ensure that $TMPDIR exists (because we use start_clear=False, it's not created for us)
+ if self.temp_path and not os.path.exists(self.temp_path):
+ os.makedirs(self.temp_path)
+
def _ignore_file(self, fn):
if fn.endswith('__pycache__') or fn.endswith(".pyc"):
result = True
@@ -444,12 +454,18 @@ class FastTestPipEnvironment(TestPipEnvironment):
virtualenv_paths = virtualenv.path_locations(self.venv_path)
for id, path in zip(('venv', 'lib', 'include', 'bin'), virtualenv_paths):
+ #fix for virtualenv issue #306
+ if hasattr(sys, "pypy_version_info") and id == 'lib':
+ path = os.path.join(self.venv_path, 'lib-python', pyversion)
setattr(self, id+'_path', Path(path))
setattr(self, id, relpath(self.root_path, path))
assert self.venv == TestPipEnvironment.venv # sanity check
- self.site_packages = self.lib/'site-packages'
+ if hasattr(sys, "pypy_version_info"):
+ self.site_packages = self.venv/'site-packages'
+ else:
+ self.site_packages = self.lib/'site-packages'
self.user_base_path = self.venv_path/'user'
self.user_site_path = self.venv_path/'user'/'lib'/self.lib.name/'site-packages'
@@ -510,6 +526,10 @@ class FastTestPipEnvironment(TestPipEnvironment):
assert self.root_path.exists
+ # Ensure that $TMPDIR exists (because we use start_clear=False, it's not created for us)
+ if self.temp_path and not os.path.exists(self.temp_path):
+ os.makedirs(self.temp_path)
+
def __del__(self):
pass # shutil.rmtree(str(self.root_path), ignore_errors=True)
@@ -663,5 +683,5 @@ def _change_test_package_version(env, version_pkg_path):
if __name__ == '__main__':
- sys.stderr.write("Run pip's tests using nosetests. Requires virtualenv, ScriptTest, and nose.\n")
+ sys.stderr.write("Run pip's tests using nosetests. Requires virtualenv, ScriptTest, mock, and nose.\n")
sys.exit(1)
diff --git a/tests/test_requirements.py b/tests/test_requirements.py
index 6fd8c67a5..64a88e378 100644
--- a/tests/test_requirements.py
+++ b/tests/test_requirements.py
@@ -121,19 +121,22 @@ def test_requirements_data_structure_implements__contains__():
assert 'pip' in requirements
assert 'nose' not in requirements
+@patch('os.path.normcase')
@patch('pip.req.os.getcwd')
@patch('pip.req.os.path.exists')
@patch('pip.req.os.path.isdir')
-def test_parse_editable_local(isdir_mock, exists_mock, getcwd_mock):
+def test_parse_editable_local(isdir_mock, exists_mock, getcwd_mock, normcase_mock):
exists_mock.return_value = isdir_mock.return_value = True
- getcwd_mock.return_value = "/some/path"
+ # mocks needed to support path operations on windows tests
+ normcase_mock.return_value = getcwd_mock.return_value = "/some/path"
assert_equal(
parse_editable('.', 'git'),
(None, 'file:///some/path', None)
)
+ normcase_mock.return_value = "/some/path/foo"
assert_equal(
parse_editable('foo', 'git'),
- (None, 'file://' + os.path.join("/some/path", 'foo'), None)
+ (None, 'file:///some/path/foo', None)
)
def test_parse_editable_default_vcs():
@@ -154,19 +157,21 @@ def test_parse_editable_vcs_extras():
('foo[extras]', 'svn+https://foo#egg=foo[extras]', None)
)
+@patch('os.path.normcase')
@patch('pip.req.os.getcwd')
@patch('pip.req.os.path.exists')
@patch('pip.req.os.path.isdir')
-def test_parse_editable_local_extras(isdir_mock, exists_mock, getcwd_mock):
+def test_parse_editable_local_extras(isdir_mock, exists_mock, getcwd_mock, normcase_mock):
exists_mock.return_value = isdir_mock.return_value = True
- getcwd_mock.return_value = "/some/path"
+ normcase_mock.return_value = getcwd_mock.return_value = "/some/path"
assert_equal(
parse_editable('.[extras]', 'git'),
(None, 'file://' + "/some/path", ('extras',))
)
+ normcase_mock.return_value = "/some/path/foo"
assert_equal(
parse_editable('foo[bar,baz]', 'git'),
- (None, 'file://' + os.path.join("/some/path", 'foo'), ('bar', 'baz'))
+ (None, 'file:///some/path/foo', ('bar', 'baz'))
)
def test_install_local_editable_with_extras():
diff --git a/tests/test_test.py b/tests/test_test.py
index a52939575..498652d95 100644
--- a/tests/test_test.py
+++ b/tests/test_test.py
@@ -66,3 +66,24 @@ def test_sitecustomize_not_growing_in_fast_environment():
size2 = os.stat(sc2).st_size
assert size1==size2, "size before, %d != size after, %d" %(size1, size2)
+
+def test_tmp_dir_exists_in_env():
+ """
+ Test that $TMPDIR == env.temp_path and path exists, and env.assert_no_temp() passes
+ """
+ #need these tests to ensure the assert_no_temp feature of scripttest is working
+ env = reset_env(use_distribute=True)
+ env.assert_no_temp() #this fails if env.tmp_path doesn't exist
+ assert env.environ['TMPDIR'] == env.temp_path
+ assert isdir(env.temp_path)
+
+
+def test_tmp_dir_exists_in_fast_env():
+ """
+ Test that $TMPDIR == env.temp_path and path exists and env.assert_no_temp() passes (in fast env)
+ """
+ #need these tests to ensure the assert_no_temp feature of scripttest is working
+ env = reset_env()
+ env.assert_no_temp() #this fails if env.tmp_path doesn't exist
+ assert env.environ['TMPDIR'] == env.temp_path
+ assert isdir(env.temp_path)
diff --git a/tests/test_unicode.py b/tests/test_unicode.py
index d9196e750..eb926494e 100644
--- a/tests/test_unicode.py
+++ b/tests/test_unicode.py
@@ -20,6 +20,6 @@ def test_install_package_that_emits_unicode():
env = reset_env()
to_install = os.path.abspath(os.path.join(here, 'packages', 'BrokenEmitsUTF8'))
- result = run_pip('install', to_install, expect_error=True)
- assert '__main__.FakeError: this package designed to fail on install' in result.stdout
+ result = run_pip('install', to_install, expect_error=True, expect_temp=True, quiet=True)
+ assert 'FakeError: this package designed to fail on install' in result.stdout
assert 'UnicodeDecodeError' not in result.stdout
diff --git a/tests/test_uninstall.py b/tests/test_uninstall.py
index 21b111710..28339a615 100644
--- a/tests/test_uninstall.py
+++ b/tests/test_uninstall.py
@@ -1,7 +1,9 @@
import textwrap
import sys
-from os.path import join, abspath
+from os.path import join, abspath, normpath
from tempfile import mkdtemp
+from mock import Mock
+from nose.tools import assert_raises
from tests.test_pip import here, reset_env, run_pip, assert_all_changes, write_file, pyversion
from tests.local_repos import local_repo, local_checkout
@@ -16,6 +18,8 @@ def test_simple_uninstall():
env = reset_env()
result = run_pip('install', 'INITools==0.2')
assert join(env.site_packages, 'initools') in result.files_created, sorted(result.files_created.keys())
+ #the import forces the generation of __pycache__ if the version of python supports it
+ env.run('python', '-c', "import initools")
result2 = run_pip('uninstall', 'INITools', '-y')
assert_all_changes(result, result2, [env.venv/'build', 'cache'])
@@ -34,6 +38,19 @@ def test_uninstall_with_scripts():
assert_all_changes(result, result2, [env.venv/'build', 'cache'])
+def test_uninstall_easy_install_after_import():
+ """
+ Uninstall an easy_installed package after it's been imported
+
+ """
+ env = reset_env()
+ result = env.run('easy_install', 'INITools==0.2', expect_stderr=True)
+ #the import forces the generation of __pycache__ if the version of python supports it
+ env.run('python', '-c', "import initools")
+ result2 = run_pip('uninstall', 'INITools', '-y')
+ assert_all_changes(result, result2, [env.venv/'build', 'cache'])
+
+
def test_uninstall_namespace_package():
"""
Uninstall a distribution with a namespace package without clobbering
@@ -48,6 +65,33 @@ def test_uninstall_namespace_package():
assert join(env.site_packages, 'pd', 'find') in result2.files_deleted, sorted(result2.files_deleted.keys())
+def test_uninstall_overlapping_package():
+ """
+ Uninstalling a distribution that adds modules to a pre-existing package
+ should only remove those added modules, not the rest of the existing
+ package.
+
+ See: GitHub issue #355 (pip uninstall removes things it didn't install)
+ """
+ parent_pkg = abspath(join(here, 'packages', 'parent-0.1.tar.gz'))
+ child_pkg = abspath(join(here, 'packages', 'child-0.1.tar.gz'))
+ env = reset_env()
+ result1 = run_pip('install', parent_pkg, expect_error=False)
+ assert join(env.site_packages, 'parent') in result1.files_created, sorted(result1.files_created.keys())
+ result2 = run_pip('install', child_pkg, expect_error=False)
+ assert join(env.site_packages, 'child') in result2.files_created, sorted(result2.files_created.keys())
+ assert normpath(join(env.site_packages, 'parent/plugins/child_plugin.py')) in result2.files_created, sorted(result2.files_created.keys())
+ #the import forces the generation of __pycache__ if the version of python supports it
+ env.run('python', '-c', "import parent.plugins.child_plugin, child")
+ result3 = run_pip('uninstall', '-y', 'child', expect_error=False)
+ assert join(env.site_packages, 'child') in result3.files_deleted, sorted(result3.files_created.keys())
+ assert normpath(join(env.site_packages, 'parent/plugins/child_plugin.py')) in result3.files_deleted, sorted(result3.files_deleted.keys())
+ assert join(env.site_packages, 'parent') not in result3.files_deleted, sorted(result3.files_deleted.keys())
+ # Additional check: uninstalling 'child' should return things to the
+ # previous state, without unintended side effects.
+ assert_all_changes(result2, result3, [])
+
+
def test_uninstall_console_scripts():
"""
Test uninstalling a package with more files (console_script entry points, extra directories).
@@ -155,3 +199,14 @@ def test_uninstall_as_egg():
result2 = run_pip('uninstall', 'FSPkg', '-y', expect_error=True)
assert_all_changes(result, result2, [env.venv/'build', 'cache'])
+
+def test_uninstallpathset_no_paths():
+ """
+ Test UninstallPathSet raises installation error when there are no paths (uses mocking)
+
+ """
+ from pip.req import UninstallPathSet
+ from pip.exceptions import InstallationError
+ mock_dist = Mock(project_name='pkg')
+ uninstall_set = UninstallPathSet(mock_dist)
+ assert_raises(InstallationError, uninstall_set.remove)
diff --git a/tests/test_upgrade.py b/tests/test_upgrade.py
index 795e68f85..24449aec0 100644
--- a/tests/test_upgrade.py
+++ b/tests/test_upgrade.py
@@ -207,8 +207,8 @@ def test_upgrade_vcs_req_with_no_dists_found():
def test_upgrade_vcs_req_with_dist_found():
"""It can upgrade a VCS requirement that has distributions on the index."""
reset_env()
- req = "%s#egg=virtualenv" % local_checkout(
- "git+git://github.com/pypa/virtualenv@c21fef2c2d53cf19f49bcc37f9c058a33fb50499")
+ # TODO(pnasrat) Using local_checkout fails on windows - oddness with the test path urls/git.
+ req = "%s#egg=virtualenv" % "git+git://github.com/pypa/virtualenv@c21fef2c2d53cf19f49bcc37f9c058a33fb50499"
run_pip("install", req)
result = run_pip("install", "-U", req)
assert not "pypi.python.org" in result.stdout, result.stdout
diff --git a/tests/test_user_site.py b/tests/test_user_site.py
index 4e997692e..2d1eec924 100644
--- a/tests/test_user_site.py
+++ b/tests/test_user_site.py
@@ -6,7 +6,15 @@ import sys
from os.path import abspath, join, curdir, isdir, isfile
from nose import SkipTest
from tests.local_repos import local_checkout
-from tests.test_pip import here, reset_env, run_pip, pyversion
+from tests.test_pip import here, reset_env, run_pip, pyversion, assert_all_changes
+
+
+patch_dist_in_site_packages = """
+ def dist_in_site_packages(dist):
+ return False
+ import pip
+ pip.util.dist_in_site_packages=dist_in_site_packages
+"""
def test_install_curdir_usersite_fails_in_old_python():
@@ -27,6 +35,10 @@ class Tests_UserSite:
# --user only works on 2.6 or higher
if sys.version_info < (2, 6):
raise SkipTest()
+ # --user option is broken in pypy
+ if hasattr(sys, "pypy_version_info"):
+ raise SkipTest()
+
def test_reset_env_system_site_packages_usersite(self):
"""
@@ -58,9 +70,6 @@ class Tests_UserSite:
"""
Test installing current directory ('.') into usersite after installing distribute
"""
- # FIXME distutils --user option seems to be broken in pypy
- if hasattr(sys, "pypy_version_info"):
- raise SkipTest()
env = reset_env(use_distribute=True, system_site_packages=True)
result = run_pip('install', '--user', '-e',
'%s#egg=initools-dev' %
@@ -72,9 +81,6 @@ class Tests_UserSite:
"""
Test installing current directory ('.') into usersite
"""
- # FIXME distutils --user option seems to be broken in pypy
- if hasattr(sys, "pypy_version_info"):
- raise SkipTest()
env = reset_env(use_distribute=True, system_site_packages=True)
run_from = abspath(join(here, 'packages', 'FSPkg'))
result = run_pip('install', '--user', curdir, cwd=run_from, expect_error=False)
@@ -111,15 +117,21 @@ class Tests_UserSite:
assert not isfile(initools_v3_file), initools_v3_file
- def test_install_user_conflict_in_site(self):
+ def test_install_user_conflict_in_globalsite(self):
"""
- Test user install with conflict in site ignores site and installs to usersite
+ Test user install with conflict in global site ignores site and installs to usersite
"""
- #the test framework only supports testing using virtualenvs
- #this test will use a --system_site_packages virtualenv to achieve the conflict scenario.
+ # the test framework only supports testing using virtualenvs
+ # the sys.path ordering for virtualenvs with --system-site-packages is this: virtualenv-site, user-site, global-site
+ # this test will use 2 modifications to simulate the user-site/global-site relationship
+ # 1) a monkey patch which will make it appear INITools==0.2 is not in in the virtualenv site
+ # if we don't patch this, pip will return an installation error: "Will not install to the usersite because it will lack sys.path precedence..."
+ # 2) adding usersite to PYTHONPATH, so usersite as sys.path precedence over the virtualenv site
+
+ env = reset_env(system_site_packages=True, sitecustomize=patch_dist_in_site_packages)
+ env.environ["PYTHONPATH"] = env.root_path / env.user_site
- env = reset_env(system_site_packages=True)
result1 = run_pip('install', 'INITools==0.2')
result2 = run_pip('install', '--user', 'INITools==0.1')
@@ -141,14 +153,14 @@ class Tests_UserSite:
Test user install with conflict in globalsite and usersite ignores global site and updates usersite.
"""
- #the test framework only supports testing using virtualenvs
- #this test will use a --system_site_packages virtualenv to achieve the conflict scenario.
-
- env = reset_env(system_site_packages=True)
+ # the test framework only supports testing using virtualenvs.
+ # the sys.path ordering for virtualenvs with --system-site-packages is this: virtualenv-site, user-site, global-site.
+ # this test will use 2 modifications to simulate the user-site/global-site relationship
+ # 1) a monkey patch which will make it appear INITools==0.2 is not in in the virtualenv site
+ # if we don't patch this, pip will return an installation error: "Will not install to the usersite because it will lack sys.path precedence..."
+ # 2) adding usersite to PYTHONPATH, so usersite as sys.path precedence over the virtualenv site
- # the sys.path ordering for virtualenvs with --system-site-packages is this: virtualenv site, usersite, global site
- # given this ordering you *can't* use it to simulate the scenario for this test.
- # this test will add the usersite to PYTHONPATH to simulate the desired ordering
+ env = reset_env(system_site_packages=True, sitecustomize=patch_dist_in_site_packages)
env.environ["PYTHONPATH"] = env.root_path / env.user_site
result1 = run_pip('install', 'INITools==0.2')
@@ -166,3 +178,48 @@ class Tests_UserSite:
initools_folder = env.root_path / env.site_packages / 'initools'
assert isdir(egg_info_folder)
assert isdir(initools_folder)
+
+
+ def test_install_user_in_global_virtualenv_with_conflict_fails(self):
+ """
+ Test user install in --system-site-packages virtualenv with conflict in site fails.
+ """
+ env = reset_env(system_site_packages=True)
+ result1 = run_pip('install', 'INITools==0.2')
+ result2 = run_pip('install', '--user', 'INITools==0.1', expect_error=True)
+ resultp = env.run('python', '-c', "import pkg_resources; print(pkg_resources.get_distribution('initools').location)")
+ dist_location = resultp.stdout.strip()
+ assert result2.stdout.startswith("Will not install to the user site because it will lack sys.path precedence to %s in %s"
+ %('INITools', dist_location)), result2.stdout
+
+
+ def test_uninstall_from_usersite(self):
+ """
+ Test uninstall from usersite
+ """
+ env = reset_env(system_site_packages=True)
+ result1 = run_pip('install', '--user', 'INITools==0.3')
+ result2 = run_pip('uninstall', '-y', 'INITools')
+ assert_all_changes(result1, result2, [env.venv/'build', 'cache'])
+
+
+ def test_uninstall_editable_from_usersite(self):
+ """
+ Test uninstall editable local user install
+ """
+ env = reset_env(use_distribute=True, system_site_packages=True)
+
+ #install
+ to_install = abspath(join(here, 'packages', 'FSPkg'))
+ result1 = run_pip('install', '--user', '-e', to_install, expect_error=False)
+ egg_link = env.user_site/'FSPkg.egg-link'
+ assert egg_link in result1.files_created, str(result1.stdout)
+
+ #uninstall
+ result2 = run_pip('uninstall', '-y', 'FSPkg')
+ assert not isfile(env.root_path / egg_link)
+
+ assert_all_changes(result1, result2,
+ [env.venv/'build', 'cache', env.user_site/'easy-install.pth'])
+
+
diff --git a/tests/test_util.py b/tests/test_util.py
new file mode 100644
index 000000000..2907cc067
--- /dev/null
+++ b/tests/test_util.py
@@ -0,0 +1,140 @@
+"""
+util tests
+
+"""
+import os
+import pkg_resources
+from mock import Mock
+from nose.tools import eq_
+from tests.path import Path
+from pip.util import egg_link_path
+
+
+class Tests_EgglinkPath:
+ "util.egg_link_path() tests"
+
+ def setup(self):
+
+ project = 'foo'
+
+ self.mock_dist = Mock(project_name=project)
+ self.site_packages = 'SITE_PACKAGES'
+ self.user_site = 'USER_SITE'
+ self.user_site_egglink = os.path.join(self.user_site,'%s.egg-link' % project)
+ self.site_packages_egglink = os.path.join(self.site_packages,'%s.egg-link' % project)
+
+ #patches
+ from pip import util
+ self.old_site_packages = util.site_packages
+ self.mock_site_packages = util.site_packages = 'SITE_PACKAGES'
+ self.old_running_under_virtualenv = util.running_under_virtualenv
+ self.mock_running_under_virtualenv = util.running_under_virtualenv = Mock()
+ self.old_virtualenv_no_global = util.virtualenv_no_global
+ self.mock_virtualenv_no_global = util.virtualenv_no_global = Mock()
+ self.old_user_site = util.user_site
+ self.mock_user_site = util.user_site = self.user_site
+ from os import path
+ self.old_isfile = path.isfile
+ self.mock_isfile = path.isfile = Mock()
+
+
+ def teardown(self):
+ from pip import util
+ util.site_packages = self.old_site_packages
+ util.running_under_virtualenv = self.old_running_under_virtualenv
+ util.virtualenv_no_global = self.old_virtualenv_no_global
+ util.user_site = self.old_user_site
+ from os import path
+ path.isfile = self.old_isfile
+
+
+ def eggLinkInUserSite(self,egglink):
+ return egglink==self.user_site_egglink
+
+ def eggLinkInSitePackages(self,egglink):
+ return egglink==self.site_packages_egglink
+
+ #########################
+ ## egglink in usersite ##
+ #########################
+ def test_egglink_in_usersite_notvenv(self):
+ self.mock_virtualenv_no_global.return_value = False
+ self.mock_running_under_virtualenv.return_value = False
+ self.mock_isfile.side_effect = self.eggLinkInUserSite
+ eq_(egg_link_path(self.mock_dist), self.user_site_egglink)
+
+ def test_egglink_in_usersite_venv_noglobal(self):
+ self.mock_virtualenv_no_global.return_value = True
+ self.mock_running_under_virtualenv.return_value = True
+ self.mock_isfile.side_effect = self.eggLinkInUserSite
+ eq_(egg_link_path(self.mock_dist), None)
+
+ def test_egglink_in_usersite_venv_global(self):
+ self.mock_virtualenv_no_global.return_value = False
+ self.mock_running_under_virtualenv.return_value = True
+ self.mock_isfile.side_effect = self.eggLinkInUserSite
+ eq_(egg_link_path(self.mock_dist), self.user_site_egglink)
+
+ #########################
+ ## egglink in sitepkgs ##
+ #########################
+ def test_egglink_in_sitepkgs_notvenv(self):
+ self.mock_virtualenv_no_global.return_value = False
+ self.mock_running_under_virtualenv.return_value = False
+ self.mock_isfile.side_effect = self.eggLinkInSitePackages
+ eq_(egg_link_path(self.mock_dist), self.site_packages_egglink)
+
+ def test_egglink_in_sitepkgs_venv_noglobal(self):
+ self.mock_virtualenv_no_global.return_value = True
+ self.mock_running_under_virtualenv.return_value = True
+ self.mock_isfile.side_effect = self.eggLinkInSitePackages
+ eq_(egg_link_path(self.mock_dist), self.site_packages_egglink)
+
+ def test_egglink_in_sitepkgs_venv_global(self):
+ self.mock_virtualenv_no_global.return_value = False
+ self.mock_running_under_virtualenv.return_value = True
+ self.mock_isfile.side_effect = self.eggLinkInSitePackages
+ eq_(egg_link_path(self.mock_dist), self.site_packages_egglink)
+
+ ####################################
+ ## egglink in usersite & sitepkgs ##
+ ####################################
+ def test_egglink_in_both_notvenv(self):
+ self.mock_virtualenv_no_global.return_value = False
+ self.mock_running_under_virtualenv.return_value = False
+ self.mock_isfile.return_value = True
+ eq_(egg_link_path(self.mock_dist), self.user_site_egglink)
+
+ def test_egglink_in_both_venv_noglobal(self):
+ self.mock_virtualenv_no_global.return_value = True
+ self.mock_running_under_virtualenv.return_value = True
+ self.mock_isfile.return_value = True
+ eq_(egg_link_path(self.mock_dist), self.site_packages_egglink)
+
+ def test_egglink_in_both_venv_global(self):
+ self.mock_virtualenv_no_global.return_value = False
+ self.mock_running_under_virtualenv.return_value = True
+ self.mock_isfile.return_value = True
+ eq_(egg_link_path(self.mock_dist), self.site_packages_egglink)
+
+ ################
+ ## no egglink ##
+ ################
+ def test_noegglink_in_sitepkgs_notvenv(self):
+ self.mock_virtualenv_no_global.return_value = False
+ self.mock_running_under_virtualenv.return_value = False
+ self.mock_isfile.return_value = False
+ eq_(egg_link_path(self.mock_dist), None)
+
+ def test_noegglink_in_sitepkgs_venv_noglobal(self):
+ self.mock_virtualenv_no_global.return_value = True
+ self.mock_running_under_virtualenv.return_value = True
+ self.mock_isfile.return_value = False
+ eq_(egg_link_path(self.mock_dist), None)
+
+ def test_noegglink_in_sitepkgs_venv_global(self):
+ self.mock_virtualenv_no_global.return_value = False
+ self.mock_running_under_virtualenv.return_value = True
+ self.mock_isfile.return_value = False
+ eq_(egg_link_path(self.mock_dist), None)
+
diff --git a/tests/test_vcs_git.py b/tests/test_vcs_git.py
index 206e80512..b27c12d8b 100644
--- a/tests/test_vcs_git.py
+++ b/tests/test_vcs_git.py
@@ -1,4 +1,6 @@
+import sys
from mock import patch
+from nose import SkipTest
from pip.vcs.git import Git
from tests.test_pip import (reset_env, run_pip,
_create_test_package,)
@@ -87,6 +89,9 @@ def test_check_submodule_addition():
Submodules are pulled in on install and updated on upgrade.
"""
+ # TODO(pnasrat) fix all helpers to do right things with paths on windows.
+ if sys.platform == 'win32':
+ raise SkipTest()
env = reset_env()
module_path, submodule_path = _create_test_package_with_submodule(env)