def it_gives_the_same_python_version_as_we_started_with(tmpdir): other_python = OtherPython() with tmpdir.as_cwd(): requirements('') # first simulate some unrelated use of venv-update # this guards against statefulness in the venv-update scratch dir venv_update('venv=', 'unrelated_venv', 'pip-command=', 'true') run('virtualenv', '--python', other_python.interpreter, 'venv') initial_version = assert_python_version(other_python.version_prefix) venv_update_symlink_pwd() out, err = run('./venv/bin/python', 'venv_update.py') err = strip_pip_warnings(err) assert err == '' out = uncolor(out) assert out.startswith('''\ > virtualenv venv Keeping valid virtualenv from previous run. > rm -rf venv/local > pip install venv-update=={} '''.format(__version__)) final_version = assert_python_version(other_python.version_prefix) assert final_version == initial_version
def it_doesnt_wheel_local_dirs(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) run( venv.join('bin/pip-faster').strpath, 'install', TOP.join('tests/testing/packages/dependant_package').strpath, ) frozen_requirements = pip_freeze(str(venv)).split('\n') assert set(frozen_requirements) == { 'coverage==ANY', 'coverage-enable-subprocess==1.0', 'dependant-package==1', 'implicit-dependency==1', 'many-versions-package==3', 'pure-python-package==0.2.1', 'venv-update==' + __version__, '', } assert {wheel.name for wheel in cached_wheels(tmpdir)} == { 'implicit-dependency', 'many-versions-package', 'pure-python-package', }
def it_installs_stuff_with_dash_e_without_wheeling(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) # Install a package from git with no extra dependencies in editable mode. # # We need to install a package from VCS instead of the filesystem because # otherwise we aren't testing that editable requirements aren't wheeled # (and instead might just be testing that local paths aren't wheeled). requirements('-e git+git://github.com/Yelp/dumb-init.git@87545be699a13d0fd31f67199b7782ebd446437e#egg=dumb-init') # noqa run(str(venv.join('bin/pip-faster')), 'install', '-r', 'requirements.txt') frozen_requirements = pip_freeze(str(venv)).split('\n') assert set(frozen_requirements) == { '-e git://github.com/Yelp/dumb-init.git@87545be699a13d0fd31f67199b7782ebd446437e#egg=dumb_init', # noqa 'coverage-enable-subprocess==1.0', 'coverage==ANY', 'venv-update==' + __version__, '', } # we shouldn't wheel things installed editable assert not tuple(cached_wheels(tmpdir))
def test_circular_dependencies(tmpdir): """pip-faster should be able to install packages with circular dependencies.""" tmpdir.chdir() venv = enable_coverage(tmpdir, 'venv') pip = venv.join('bin/pip').strpath run(pip, 'install', 'pip-faster==' + __version__) out, err = run( venv.join('bin/pip-faster').strpath, 'install', '-vv', # show debug logging 'circular-dep-a', ) assert err == '' out = uncolor(out) assert out.endswith(''' tracing: circular-dep-a adding sub-requirement circular-dep-b==1.0 (from circular-dep-a) tracing: circular-dep-b==1.0 (from circular-dep-a) adding sub-requirement circular-dep-a==1.0 (from circular-dep-b==1.0->circular-dep-a) already analyzed: circular-dep-b==1.0 (from circular-dep-a) tracing: circular-dep-a==1.0 (from circular-dep-b==1.0->circular-dep-a) Circular dependency! circular-dep-a==1.0 (from circular-dep-b==1.0->circular-dep-a) ''') frozen_requirements = pip_freeze(str(venv)).split('\n') assert 'circular-dep-a==1.0' in frozen_requirements assert 'circular-dep-b==1.0' in frozen_requirements
def it_can_handle_a_bad_findlink(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) out, err = run( str(venv.join('bin/pip-faster')), 'install', '-vvv', '--find-links', 'git+wat://not/a/thing', 'pure-python-package', ) out = uncolor(out) err = strip_pip_warnings(err) expected = '''\ Successfully built pure-python-package Installing collected packages: pure-python-package ''' assert expected in out # Between this there's: # 'changing mode of .../venv/bin/pure-python-script to 775' # but that depends on umask _, rest = out.split(expected) expected2 = '''\ Successfully installed pure-python-package-0.2.1 Cleaning up... ''' assert expected2 in rest assert err == ( " Url 'git+wat://not/a/thing' is ignored. " 'It is either a non-existing path or lacks a specific scheme.\n' ) assert 'pure-python-package==0.2.1' in pip_freeze(str(venv)).split('\n')
def test_multiple_issues(tmpdir): # Make it a bit worse. The output should show all three issues. tmpdir.chdir() T.requirements('flake8==2.2.5') T.venv_update() T.run('./virtualenv_run/bin/pip', 'uninstall', '--yes', 'pyflakes') T.requirements(''' # flake8 2.2.5 requires mccabe>=0.2.1 and pep8>=1.5.7, so this isn't satisfiable flake8==2.2.5 mccabe==0.2 pep8==1.0 ''') with pytest.raises(CalledProcessError) as excinfo: T.venv_update() assert excinfo.value.returncode == 1 out, err = excinfo.value.result err = T.strip_coverage_warnings(err) assert err == '' out = T.uncolor(out) assert ( ''' Cleaning up... Error: version conflict: mccabe 0.2 (virtualenv_run/%s)''' ''' <-> mccabe>=0.2.1 (from flake8==2.2.5 (from -r requirements.txt (line 3))) Error: version conflict: pep8 1.0 (virtualenv_run/%s) ''' '''<-> pep8>=1.5.7 (from flake8==2.2.5 (from -r requirements.txt (line 3))) Error: unmet dependency: pyflakes>=0.8.1 (from flake8==2.2.5 (from -r requirements.txt (line 3))) Something went wrong! Sending 'virtualenv_run' back in time, so make knows it's invalid. ''' % (PYTHON_LIB, PYTHON_LIB) ) in out
def it_gives_the_same_python_version_as_we_started_with(tmpdir): other_python = OtherPython() with tmpdir.as_cwd(): requirements('') # first simulate some unrelated use of venv-update # this guards against statefulness in the venv-update scratch dir venv_update('unrelated_venv', '--', '--version') run('virtualenv', '--python', other_python.interpreter, 'venv') initial_version = assert_python_version(other_python.version_prefix) venv_update_symlink_pwd() out, err = run('./venv/bin/python', 'venv_update.py') assert err == '' out = uncolor(out) assert out.startswith('''\ > virtualenv Keeping valid virtualenv from previous run. > venv/bin/python -m pip.__main__ install pip-faster==%s ''' % __version__) final_version = assert_python_version(other_python.version_prefix) assert final_version == initial_version
def assert_c_extension_runs(): out, err = run('venv/bin/c-extension-script') assert err == '' assert out == 'hello world\n' out, err = run('sh', '-c', '. venv/bin/activate && c-extension-script') assert err == '' assert out == 'hello world\n'
def stage2(executable, tmpdir): run( executable, venv_update.__file__, '--stage2', 'myvenv', HOME=tmpdir.strpath, )
def make_venv(): enable_coverage() venv = Path('venv') run('virtualenv', venv.strpath) install_coverage(venv.strpath) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) return venv
def test_is_relocatable(tmpdir): tmpdir.chdir() get_scenario('trivial') venv_update() Path('virtualenv_run').rename('relocated') pip = 'relocated/bin/pip' assert Path(pip).exists() run(pip, '--version')
def test_is_relocatable_different_python_version(tmpdir): tmpdir.chdir() with io.open('requirements.txt', 'w') as reqs: reqs.write('doge==3.5.0') python_arg = '--python=python' + ('2.7' if not PY27 else '2.6') venv_update(python_arg) run('sh', '-c', '. virtualenv_run/bin/activate && doge --help')
def test_relocatable(tmpdir): tmpdir.chdir() requirements('') venv_update('--python=python') # this makes pypy work right. derp. Path('virtualenv_run').rename('relocated') python = 'relocated/bin/python' assert Path(python).exists() run(python, '-m', 'pip.__main__', '--version')
def enable_coverage(tmpdir): venv = tmpdir.join('virtualenv_run') if not venv.isdir(): run('virtualenv', venv.strpath) run( venv.join('bin/python').strpath, '-m', 'pip.__main__', 'install', '-r', TOP.join('requirements.d/coverage.txt').strpath, )
def test_relocatable(tmpdir): tmpdir.chdir() requirements('') venv_update() Path('venv').rename('relocated') python = 'relocated/bin/python' assert Path(python).exists() run(python, '-m', 'pip.__main__', '--version')
def test_editable_egg_conflict(tmpdir): conflicting_package = tmpdir / 'tmp/conflicting_package' many_versions_package_2 = tmpdir / 'tmp/many_versions_package_2' from shutil import copytree copytree( str(T.TOP / 'tests/testing/packages/conflicting_package'), str(conflicting_package), ) copytree( str(T.TOP / 'tests/testing/packages/many_versions_package_2'), str(many_versions_package_2), ) with many_versions_package_2.as_cwd(): from sys import executable as python T.run(python, 'setup.py', 'bdist_egg', '--dist-dir', str(conflicting_package)) with tmpdir.as_cwd(): T.requirements('-r %s/requirements.d/coverage.txt' % T.TOP) T.venv_update() T.requirements('-e %s' % conflicting_package) with pytest.raises(CalledProcessError) as excinfo: T.venv_update() assert excinfo.value.returncode == 1 out, err = excinfo.value.result err = T.strip_coverage_warnings(err) assert err == '' out = T.uncolor(out) expected = '\nSuccessfully installed many-versions-package conflicting-package\n' assert expected in out rest = out.rsplit(expected, 1)[-1] if True: # :pragma:nocover:pylint:disable=using-constant-test # Debian de-vendorizes the version of pip it ships try: from sysconfig import get_python_version except ImportError: # <= python2.6 from distutils.sysconfig import get_python_version assert ( '''\ Cleaning up... Error: version conflict: many-versions-package 2 (tmp/conflicting_package/many_versions_package-2-py{0}.egg)''' ''' <-> many-versions-package<2 (from conflicting-package==1->-r requirements.txt (line 1)) Storing debug log for failure in {1}/home/.pip/pip.log Something went wrong! Sending 'venv' back in time, so make knows it's invalid. '''.format(get_python_version(), tmpdir) ) == rest assert_venv_marked_invalid(tmpdir.join('venv'))
def it_gives_proper_error_without_requirements(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) with pytest.raises(CalledProcessError) as exc_info: run(str(venv.join('bin/pip-faster')), 'install') _, err = exc_info.value.result assert err.startswith('ERROR: You must give at least one requirement to install')
def pypi_packages(tmpdir_factory): package_temp = tmpdir_factory.ensuretemp("venv-update-packages") with TOP.as_cwd(): run( sys.executable, "tests/testing/make_sdists.py", "tests/testing/packages", ".", # we need pip-faster to be installable too str(package_temp), ) yield package_temp
def pypi_packages(): package_temp = TOP.join('build/test-packages') with TOP.as_cwd(): run( sys.executable, 'tests/testing/make_sdists.py', 'tests/testing/packages', '.', # we need venv-update to be installable too str(package_temp), ) yield package_temp
def test_update_while_active(tmpdir, capfd): tmpdir.chdir() get_scenario('trivial') venv_update() assert 'mccabe' not in pip_freeze(capfd) with open('requirements.txt', 'w') as requirements: # An arbitrary small package: mccabe requirements.write('mccabe') venv_update_symlink_pwd() run('sh', '-c', '. virtualenv_run/bin/activate && python venv_update.py') assert 'mccabe' in pip_freeze(capfd)
def test_trivial(tmpdir): tmpdir.chdir() # An arbitrary small package: mccabe requirements('mccabe\npep8==1.0') run('virtualenv', 'myvenv') # need this to get coverage. surely there's a better way... run( 'myvenv/bin/pip', 'install', '-r', (TOP / 'requirements.d/coverage.txt').strpath ) stage2('myvenv/bin/python', tmpdir)
def it_caches_downloaded_wheels_from_pypi(tmpdir): venv = tmpdir.join('venv') install_coverage() pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) run( venv.join('bin/pip-faster').strpath, 'install', # One of the few wheeled things on our pypi 'wheeled-package', ) expected = {'wheeled-package'} assert {wheel.name for wheel in cached_wheels(tmpdir)} == expected
def test_scripts_left_behind(tmpdir): tmpdir.chdir() requirements('') venv_update() # an arbitrary small package with a script: pep8 script_path = Path('virtualenv_run/bin/pep8') assert not script_path.exists() run('virtualenv_run/bin/pip', 'install', 'pep8') assert script_path.exists() venv_update() assert not script_path.exists()
def test_circular_dependencies(): """pip-faster should be able to install packages with circular dependencies.""" venv = make_venv() out, err = run( venv.join('bin/pip-faster').strpath, 'install', '-vv', # show debug logging 'circular-dep-a', ) err = strip_pip_warnings(err) assert err == ( 'Circular dependency! circular-dep-a==1.0 ' '(from circular-dep-b==1.0->circular-dep-a)\n' ) out = uncolor(out) assert out.endswith(''' tracing: circular-dep-a already queued: circular-dep-b==1.0 (from circular-dep-a) tracing: circular-dep-b==1.0 (from circular-dep-a) ''') frozen_requirements = pip_freeze(str(venv)).split('\n') assert 'circular-dep-a==1.0' in frozen_requirements assert 'circular-dep-b==1.0' in frozen_requirements
def it_installs_stuff_from_requirements_file(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) # An arbitrary small package: pure_python_package requirements('pure_python_package\nproject_with_c') run(str(venv.join('bin/pip-faster')), 'install', '-r', 'requirements.txt') frozen_requirements = pip_freeze(str(venv)).split('\n') assert 'pure-python-package==0.2.1' in frozen_requirements assert 'project-with-c==0.1.0' in frozen_requirements
def assert_python_version(version): outputs = run('sh', '-c', '. venv/bin/activate && python -c "import sys; print(sys.version)"') # older versions of python output on stderr, newer on stdout, but we dont care too much which assert '' in outputs actual_version = ''.join(outputs) assert actual_version.startswith(version) return actual_version
def it_shows_help_for_prune(): out, err = run('pip-faster', 'install', '--help') assert ''' --prune Uninstall any non-required packages. --no-prune Do not uninstall any non-required packages. Package Index Options''' in out assert err == ''
def test_multiple_issues(tmpdir): # Make it a bit worse. The output should show all three issues. tmpdir.chdir() T.enable_coverage() T.requirements('dependant_package\n-r %s/requirements.d/coverage.txt' % T.TOP) T.venv_update() T.run('./venv/bin/pip', 'uninstall', '--yes', 'implicit_dependency') T.requirements(''' dependant_package conflicting_package pure_python_package==0.1.0 ''') with pytest.raises(CalledProcessError) as excinfo: T.venv_update() assert excinfo.value.returncode == 1 out, err = excinfo.value.result err = T.strip_coverage_warnings(err) err = T.strip_pip_warnings(err) err = err.splitlines() # pip outputs conflict lines in a non-consistent order assert set(err[:3]) == { "conflicting-package 1 has requirement many-versions-package<2, but you'll have many-versions-package 3 which is incompatible.", # noqa "dependant-package 1 has requirement pure-python-package>=0.2.1, but you'll have pure-python-package 0.1.0 which is incompatible.", # noqa 'Error: version conflict: pure-python-package 0.1.0 (venv/{lib}) <-> pure-python-package>=0.2.1 (from dependant_package->-r requirements.txt (line 2))'.format( # noqa lib=PYTHON_LIB, ), } # TODO: do we still need to append our own error? assert '\n'.join(err[3:]) == ( 'Error: version conflict: many-versions-package 3 ' '(venv/{lib}) <-> many-versions-package<2 ' '(from conflicting_package->-r requirements.txt (line 3))'.format( lib=PYTHON_LIB, ) ) out = T.uncolor(out) assert_something_went_wrong(out) assert_venv_marked_invalid(tmpdir.join('venv'))
def it_caches_downloaded_wheels_extra_index_url(tmpdir): venv = tmpdir.join('venv') install_coverage() pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) index = os.environ.pop('PIP_INDEX_URL') run( venv.join('bin/pip-faster').strpath, 'install', # bogus index url just to test `--extra-index-url` '--index-url', 'file://{}'.format(tmpdir), '--extra-index-url', index, 'wheeled-package', ) expected = {'wheeled-package'} assert {wheel.name for wheel in cached_wheels(tmpdir)} == expected
def test_arguments_system_packages(tmpdir, capfd): """Show that we can pass arguments through to virtualenv""" tmpdir.chdir() get_scenario('trivial') venv_update('--system-site-packages', 'virtualenv_run', 'requirements.txt') out, err = capfd.readouterr() # flush buffers run('virtualenv_run/bin/python', '-c', '''\ import sys for p in sys.path: if p.startswith(sys.real_prefix) and p.endswith("-packages"): print(p) break ''') out, err = capfd.readouterr() assert strip_coverage_warnings(err) == '' out = out.rstrip('\n') assert out and Path(out).isdir()
def it_installs_stuff(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) assert pip_freeze(str(venv)) == '''\ coverage==4.5.1 coverage-enable-subprocess==1.0 ''' pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) assert [req.split('==')[0] for req in pip_freeze(str(venv)).split()] == [ 'coverage', 'coverage-enable-subprocess', 'venv-update', ] run(str(venv.join('bin/pip-faster')), 'install', 'pure_python_package') assert 'pure-python-package==0.2.1' in pip_freeze(str(venv)).split('\n')
def pip_freeze(): out, err = run('./virtualenv_run/bin/pip', 'freeze', '--local') # Most python distributions which have argparse in the stdlib fail to # expose it to setuptools as an installed package (it seems all but ubuntu # do this). This results in argparse sometimes being installed locally, # sometimes not, even for a specific version of python. # We normalize by never looking at argparse =/ out = out.replace('argparse==1.2.1\n', '', 1) assert err == '' return out
def test_no_conflicts_when_no_deps_specified(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) pkgdir = tmpdir.join('pkgdir').ensure_dir() setup_py = pkgdir.join('setup.py') def _setup_py(many_versions_package_version): setup_py.write('from setuptools import setup\n' 'setup(\n' ' name="pkg",\n' ' install_requires=["many-versions-package=={}"],\n' ')\n'.format(many_versions_package_version)) cmd = ( venv.join('bin/pip-faster').strpath, 'install', '--upgrade', pkgdir.strpath, ) _setup_py('1') run(*cmd) _setup_py('2') # Should not complain about conflicts since we specified `--no-deps` run(*cmd + ('--no-deps', ))
def test_old_pip_and_setuptools(tmpdir, reqs): """We should be able to use pip-faster's wheel building even if we have ancient pip and setuptools. https://github.com/Yelp/venv-update/issues/33 """ tmpdir.chdir() # 1. Create an empty virtualenv. # 2. Install old pip/setuptools that don't support wheel building. # 3. Install pip-faster. # 4. Install pure-python-package and assert it was wheeled during install. tmpdir.join('venv') venv = Path('venv') run('virtualenv', venv.strpath) # We need to add public PyPI as an extra URL since we're installing # packages (setuptools and pip) which aren't available from our PyPI fixture. from os import environ environ['PIP_EXTRA_INDEX_URL'] = 'https://pypi.python.org/simple/' try: pip = venv.join('bin/pip').strpath for req in reqs: run(pip, 'install', '--', req) # wheel needs argparse but it won't get installed if sys.version_info < (2, 7): run(pip, 'install', 'argparse') run(pip, 'install', 'venv-update==' + __version__) finally: del environ['PIP_EXTRA_INDEX_URL'] run(str(venv.join('bin/pip-faster')), 'install', 'pure_python_package') # it was installed assert 'pure-python-package==0.2.1' in pip_freeze(str(venv)).split('\n') # it was wheeled wheel_names = [wheel.name for wheel in cached_wheels(tmpdir)] assert 'pure-python-package' in wheel_names
def test_multiple_issues(tmpdir): # Make it a bit worse. The output should show all three issues. tmpdir.chdir() T.enable_coverage() T.requirements('dependant_package\n-r %s/requirements.d/coverage.txt' % T.TOP) T.venv_update() T.run('./venv/bin/pip', 'uninstall', '--yes', 'implicit_dependency') T.requirements(''' dependant_package conflicting_package pure_python_package==0.1.0 ''') with pytest.raises(CalledProcessError) as excinfo: T.venv_update() assert excinfo.value.returncode == 1 out, err = excinfo.value.result err = T.strip_coverage_warnings(err) assert err == '' out = T.uncolor(out) assert ( ''' Cleaning up... Error: unmet dependency: implicit-dependency (from dependant-package->-r requirements.txt (line 2)) Error: version conflict: many-versions-package 1 (venv/%s)''' ''' <-> many-versions-package>=2,<4 (from dependant-package->-r requirements.txt (line 2)) Error: version conflict: pure-python-package 0.1.0 (venv/%s)''' ''' <-> pure-python-package>=0.2.0 (from dependant-package->-r requirements.txt (line 2)) Storing debug log for failure in %s/home/.pip/pip.log Something went wrong! Sending 'venv' back in time, so make knows it's invalid. ''' % (PYTHON_LIB, PYTHON_LIB, tmpdir)) in out assert_venv_marked_invalid(tmpdir.join('venv'))
def it_doesnt_wheel_local_dirs(tmpdir): from pip.wheel import Wheel tmpdir.chdir() venv = enable_coverage(tmpdir, 'venv') pip = venv.join('bin/pip').strpath run(pip, 'install', 'pip-faster==' + __version__) run( venv.join('bin/pip-faster').strpath, 'install', TOP.join('tests/testing/packages/dependant_package').strpath, ) frozen_requirements = pip_freeze(str(venv)).split('\n') assert set(frozen_requirements) == set([ 'coverage==4.0.3', 'coverage-enable-subprocess==0', 'dependant-package==1', 'implicit-dependency==1', 'many-versions-package==3', 'pip-faster==' + __version__, 'pure-python-package==0.2.0', 'virtualenv==1.11.6', 'wheel==0.29.0', '', ]) wheelhouse = tmpdir.join('home', '.cache', 'pip-faster', 'wheelhouse') assert set(Wheel(f.basename).name for f in wheelhouse.listdir()) == set([ 'coverage', 'coverage-enable-subprocess', 'implicit-dependency', 'many-versions-package', 'pure-python-package', ])
def it_installs_stuff_with_dash_e_without_wheeling(tmpdir): from pip.wheel import Wheel tmpdir.chdir() venv = enable_coverage(tmpdir, 'venv') pip = venv.join('bin/pip').strpath run(pip, 'install', 'pip-faster==' + __version__) # Install a package from git with no extra dependencies in editable mode. # # We need to install a package from VCS instead of the filesystem because # otherwise we aren't testing that editable requirements aren't wheeled # (and instead might just be testing that local paths aren't wheeled). requirements( '-e git+git://github.com/Yelp/dumb-init.git@87545be699a13d0fd31f67199b7782ebd446437e#egg=dumb-init' ) # noqa run(str(venv.join('bin/pip-faster')), 'install', '-r', 'requirements.txt') frozen_requirements = pip_freeze(str(venv)).split('\n') assert set(frozen_requirements) == set([ '-e git://github.com/Yelp/dumb-init.git@87545be699a13d0fd31f67199b7782ebd446437e#egg=dumb_init-dev', # noqa 'coverage-enable-subprocess==0', 'coverage==4.0.3', 'pip-faster==' + __version__, 'virtualenv==1.11.6', 'wheel==0.29.0', '', ]) # we shouldn't wheel things installed editable wheelhouse = tmpdir.join('home', '.cache', 'pip-faster', 'wheelhouse') assert set(Wheel(f.basename).name for f in wheelhouse.listdir()) == set([ 'coverage', 'coverage-enable-subprocess', ])
def it_doesnt_wheel_git_repos(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) run( venv.join('bin/pip-faster').strpath, 'install', 'git+git://github.com/Yelp/dumb-init.git@87545be699a13d0fd31f67199b7782ebd446437e#egg=dumb-init', # noqa ) frozen_requirements = pip_freeze(str(venv)).split('\n') assert set(frozen_requirements) == { 'coverage-enable-subprocess==1.0', 'coverage==ANY', 'dumb-init==0.5.0', 'venv-update==' + __version__, '', } assert not tuple(cached_wheels(tmpdir))
def test_install_whl_over_http(pypi_server): whl_url = pypi_server + '/packages/wheeled_package-0.2.0-py2.py3-none-any.whl' venv = make_venv() out, err = run(str(venv.join('bin/pip-faster')), 'install', whl_url) err = strip_pip_warnings(err) assert err == '' out = uncolor(out) assert out == '''\ Collecting wheeled-package==0.2.0 from {server}/packages/wheeled_package-0.2.0-py2.py3-none-any.whl Downloading {server}/packages/wheeled_package-0.2.0-py2.py3-none-any.whl Installing collected packages: wheeled-package Successfully installed wheeled-package-0.2.0 '''.format(server=pypi_server)
def it_doesnt_wheel_local_dirs(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) run( venv.join('bin/pip-faster').strpath, 'install', TOP.join('tests/testing/packages/dependant_package').strpath, ) frozen_requirements = pip_freeze(str(venv)).split('\n') assert set(frozen_requirements) == set([ 'appdirs==1.4.0', 'coverage==4.3.4', 'coverage-enable-subprocess==1.0', 'dependant-package==1', 'implicit-dependency==1', 'many-versions-package==3', 'packaging==16.8', 'pip==9.0.1', 'pure-python-package==0.2.1', 'pyparsing==2.1.10', 'setuptools==34.1.1', 'six==1.10.0', 'venv-update==' + __version__, 'wheel==0.29.0', '', ]) assert set(wheel.name for wheel in cached_wheels(tmpdir)) == set(( 'implicit-dependency', 'many-versions-package', 'pure-python-package', ))
def it_installs_stuff_with_dash_e_without_wheeling(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) # Install a package from git with no extra dependencies in editable mode. # # We need to install a package from VCS instead of the filesystem because # otherwise we aren't testing that editable requirements aren't wheeled # (and instead might just be testing that local paths aren't wheeled). requirements( '-e git+git://github.com/Yelp/dumb-init.git@87545be699a13d0fd31f67199b7782ebd446437e#egg=dumb-init' ) # noqa run(str(venv.join('bin/pip-faster')), 'install', '-r', 'requirements.txt') frozen_requirements = pip_freeze(str(venv)).split('\n') assert set(frozen_requirements) == set([ '-e git://github.com/Yelp/dumb-init.git@87545be699a13d0fd31f67199b7782ebd446437e#egg=dumb_init', # noqa 'appdirs==1.4.0', 'coverage-enable-subprocess==1.0', 'coverage==4.3.4', 'packaging==16.8', 'pip==9.0.1', 'pyparsing==2.1.10', 'setuptools==34.1.1', 'six==1.10.0', 'venv-update==' + __version__, 'wheel==0.29.0', '', ]) # we shouldn't wheel things installed editable assert not tuple(cached_wheels(tmpdir))
def it_can_handle_a_bad_findlink(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) out, err = run( str(venv.join('bin/pip-faster')), 'install', '-vvv', '--find-links', 'git+wat://not/a/thing', 'pure-python-package', ) out = uncolor(out) err = strip_pip_warnings(err) expected = '''\ Successfully built pure-python-package Installing collected packages: pure-python-package ''' assert expected in out # Between this there's: # 'changing mode of .../venv/bin/pure-python-script to 775' # but that depends on umask _, rest = out.split(expected) expected2 = '''\ Successfully installed pure-python-package-0.2.1 Cleaning up... ''' assert expected2 in rest assert err == ( " Url 'git+wat://not/a/thing' is ignored. " 'It is either a non-existing path or lacks a specific scheme.\n') assert 'pure-python-package==0.2.1' in pip_freeze(str(venv)).split('\n')
def test_multiple_issues(tmpdir): # Make it a bit worse. The output should show all three issues. tmpdir.chdir() T.enable_coverage() T.requirements('dependant_package\n-r %s/requirements.d/coverage.txt' % T.TOP) T.venv_update() T.run('./venv/bin/pip', 'uninstall', '--yes', 'implicit_dependency') T.requirements(''' dependant_package conflicting_package pure_python_package==0.1.0 ''') with pytest.raises(CalledProcessError) as excinfo: T.venv_update() assert excinfo.value.returncode == 1 out, err = excinfo.value.result err = T.strip_coverage_warnings(err) err = T.strip_pip_warnings(err) assert err == ( 'Error: version conflict: pure-python-package 0.1.0 ' '(venv/{lib}) <-> pure-python-package>=0.2.1 ' '(from dependant_package->-r requirements.txt (line 2))\n' 'Error: version conflict: many-versions-package 3 ' '(venv/{lib}) <-> many-versions-package<2 ' '(from conflicting_package->-r requirements.txt (line 3))\n'.format( lib=PYTHON_LIB, )) out = T.uncolor(out) assert_something_went_wrong(out) assert_venv_marked_invalid(tmpdir.join('venv'))
def it_can_handle_a_bad_findlink(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) out, err = run( str(venv.join('bin/pip-faster')), 'install', '-vvv', '--find-links', 'git+wat://not/a/thing', 'pure-python-package', ) out = uncolor(out) assert ''' Candidate wheel: pure_python_package-0.2.0-py2.py3-none-any.whl Installing collected packages: pure-python-package Successfully installed pure-python-package ''' in out assert err == '' assert 'pure-python-package==0.2.0' in pip_freeze(str(venv)).split('\n')
def test_python_versions(tmpdir): tmpdir.chdir() requirements('doge==3.5.0') venv_update('--python=python2.6') run('sh', '-c', '. virtualenv_run/bin/activate && doge --help') out, err = run('sh', '-c', '. virtualenv_run/bin/activate && python --version') assert out == '' assert err.startswith('Python 2.6') venv_update('--python=python2.7') run('sh', '-c', '. virtualenv_run/bin/activate && doge --help') out, err = run('sh', '-c', '. virtualenv_run/bin/activate && python --version') assert out == '' assert err.startswith('Python 2.7') venv_update('--python=python2.6') run('sh', '-c', '. virtualenv_run/bin/activate && doge --help') out, err = run('sh', '-c', '. virtualenv_run/bin/activate && python --version') assert out == '' assert err.startswith('Python 2.6')
def test_recreate_active_virtualenv(tmpdir): with tmpdir.as_cwd(): run('virtualenv', 'venv') run('venv/bin/pip', 'install', '-r', str(TOP / 'requirements.d/coverage.txt')) requirements('project_with_c') venv_update_symlink_pwd() run('venv/bin/python', 'venv_update.py') assert_c_extension_runs()
def test_update_while_active(tmpdir): tmpdir.chdir() requirements('virtualenv<2') venv_update() assert 'mccabe' not in pip_freeze() # An arbitrary small package: mccabe requirements('virtualenv<2\nmccabe') venv_update_symlink_pwd() out, err = run('sh', '-c', '. virtualenv_run/bin/activate && python venv_update.py') assert err == '' assert out.startswith('Keeping virtualenv from previous run.\n') assert 'mccabe' in pip_freeze()
def test_arguments_system_packages(tmpdir): """Show that we can pass arguments through to virtualenv""" tmpdir.chdir() requirements('') venv_update('venv=', '--system-site-packages', 'venv') out, err = run('venv/bin/python', '-c', '''\ import sys for p in sys.path: if p.startswith(sys.real_prefix) and p.endswith("-packages"): print(p) break ''') assert err == '' out = out.rstrip('\n') assert out and Path(out).isdir()
def test_update_while_active(tmpdir): tmpdir.chdir() requirements('virtualenv<2') venv_update() assert 'project-with-c' not in pip_freeze() # An arbitrary small package: project_with_c requirements('project_with_c') venv_update_symlink_pwd() out, err = run('sh', '-c', '. venv/bin/activate && python venv_update.py') out = uncolor(out) assert err == '' assert out.startswith( '> virtualenv\nKeeping valid virtualenv from previous run.\n') assert 'project-with-c' in pip_freeze()
def test_update_invalidated_while_active(tmpdir): tmpdir.chdir() requirements('virtualenv<2') venv_update() assert 'mccabe' not in pip_freeze() # An arbitrary small package: mccabe requirements('virtualenv<2\nmccabe') venv_update_symlink_pwd() out, err = run( 'sh', '-c', '. virtualenv_run/bin/activate && python venv_update.py --system-site-packages' ) assert err == '' assert out.startswith('Removing invalidated virtualenv.\n') assert 'mccabe' in pip_freeze()
def it_can_handle_requirements_already_met(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) requirements('many-versions-package==1') run(str(venv.join('bin/pip-faster')), 'install', '-r', 'requirements.txt') assert 'many-versions-package==1\n' in pip_freeze(str(venv)) run(str(venv.join('bin/pip-faster')), 'install', '-r', 'requirements.txt') assert 'many-versions-package==1\n' in pip_freeze(str(venv))
def get_installed(): out, err = run( 'myvenv/bin/python', '-c', '''\ import pip_faster as p for p in sorted(p.reqnames(p.pip_get_installed())): print(p)''') assert err == '' out = set(out.split()) # Most python distributions which have argparse in the stdlib fail to # expose it to setuptools as an installed package (it seems all but ubuntu # do this). This results in argparse sometimes being installed locally, # sometimes not, even for a specific version of python. # We normalize by never looking at argparse =/ out -= {'argparse'} # these will always be present assert ALWAYS.issubset(out) return sorted(out - ALWAYS)
def it_considers_equals_star_not_pinned(tmpdir): venv = tmpdir.join('venv') install_coverage(venv) pip = venv.join('bin/pip').strpath run(pip, 'install', 'venv-update==' + __version__) run( str(venv.join('bin/pip-faster')), 'install', 'many-versions-package==2', ) run( str(venv.join('bin/pip-faster')), 'install', '--upgrade', 'many-versions-package==2.*', ) assert 'many-versions-package==2.1' in pip_freeze(str(venv)).split('\n')
def it_installs_stuff(tmpdir): venv = tmpdir.join('venv') run('virtualenv', str(venv)) assert pip_freeze(str(venv)) == '''\ ''' pip = venv.join('bin/pip').strpath run(pip, 'install', 'pip-faster==' + __version__) assert [req.split('==')[0] for req in pip_freeze(str(venv)).split() ] == ['pip-faster', 'virtualenv', 'wheel'] run(str(venv.join('bin/pip-faster')), 'install', 'pure_python_package') assert 'pure-python-package==0.2.0' in pip_freeze(str(venv)).split('\n')
def test_update_while_active(tmpdir): tmpdir.chdir() enable_coverage() requirements('') venv_update() assert 'project-with-c' not in pip_freeze() # An arbitrary small package: project_with_c requirements('project_with_c') venv_update_symlink_pwd() out, err = run('sh', '-c', '. venv/bin/activate && python venv_update.py venv= venv --python=venv/bin/python') out = uncolor(out) err = strip_pip_warnings(err) assert err == '' assert out.startswith('''\ > virtualenv venv --python=venv/bin/python Keeping valid virtualenv from previous run. ''') assert 'project-with-c' in pip_freeze()
def test_update_invalidated_while_active(tmpdir): tmpdir.chdir() enable_coverage() requirements('') venv_update() assert 'project-with-c' not in pip_freeze() # An arbitrary small package: project_with_c requirements('project-with-c') venv_update_symlink_pwd() out, err = run('sh', '-c', '. venv/bin/activate && python venv_update.py venv= --system-site-packages venv') err = strip_pip_warnings(err) assert err == '' out = uncolor(out) assert out.startswith('''\ > virtualenv --system-site-packages venv Removing invalidated virtualenv. (system-site-packages changed, to True) ''') assert 'project-with-c' in pip_freeze()
def it_installs_stuff_from_requirements_file(tmpdir): tmpdir.chdir() venv = tmpdir.join('venv') run('virtualenv', str(venv)) pip = venv.join('bin/pip').strpath run(pip, 'install', 'pip-faster==' + __version__) # An arbitrary small package: pure_python_package requirements('pure_python_package\nproject_with_c') run(str(venv.join('bin/pip-faster')), 'install', '-r', 'requirements.txt') frozen_requirements = pip_freeze(str(venv)).split('\n') assert 'pure-python-package==0.2.0' in frozen_requirements assert 'project-with-c==0.1.0' in frozen_requirements
def test_circular_dependencies(): """pip-faster should be able to install packages with circular dependencies.""" venv = make_venv() out, err = run( venv.join('bin/pip-faster').strpath, 'install', '-vv', # show debug logging 'circular-dep-a', ) err = strip_pip_warnings(err) assert err == ('Circular dependency! circular-dep-a==1.0 ' '(from circular-dep-b==1.0->circular-dep-a)\n') out = uncolor(out) assert out.endswith(''' tracing: circular-dep-a already queued: circular-dep-b==1.0 (from circular-dep-a) tracing: circular-dep-b==1.0 (from circular-dep-a) ''') frozen_requirements = pip_freeze(str(venv)).split('\n') assert 'circular-dep-a==1.0' in frozen_requirements assert 'circular-dep-b==1.0' in frozen_requirements
no_watcher_call_args = mailq.call_args_list[0][0] T.assert_equal(['testuser'], no_watcher_call_args[0]) T.assert_in('for testuser', no_watcher_call_args[1]) T.assert_in('testuser - title', no_watcher_call_args[1]) T.assert_in('[push] testuser - title', no_watcher_call_args[2]) watched_call_args = mailq.call_args_list[1][0] T.assert_equal(['testuser', 'testuser1', 'testuser2'], watched_call_args[0]) T.assert_in('for testuser (testuser1,testuser2)', watched_call_args[1]) T.assert_in('testuser (testuser1,testuser2) - title', watched_call_args[1]) T.assert_in('[push] testuser (testuser1,testuser2) - title', watched_call_args[2]) @mock.patch('core.db.execute_transaction_cb') @mock.patch('core.mail.MailQueue.enqueue_user_email') @mock.patch('core.xmppclient.XMPPQueue.enqueue_user_xmpp') def test_xmppqueue_on_db_complete(self, xmppq, *_): self.call_on_db_complete() no_watcher_call_args = xmppq.call_args_list[0][0] T.assert_equal(['testuser'], no_watcher_call_args[0]) T.assert_in('for testuser', no_watcher_call_args[1]) watched_call_args = xmppq.call_args_list[1][0] T.assert_equal(['testuser', 'testuser1', 'testuser2'], watched_call_args[0]) T.assert_in('for testuser (testuser1,testuser2)', watched_call_args[1]) if __name__ == '__main__': T.run()