Exemple #1
0
        def venv_setup():
            # First just set up a blank virtualenv, this'll bypass the
            # bootstrap when we're actually testing for speed
            if not Path('venv').exists():
                requirements('')
                venv_update()
            install_coverage()

            # Now the actual requirements we'll install
            requirements('\n'.join((
                'project_with_c',
                'pure_python_package==0.2.1',
                'slow_python_package==0.1.0',
                'dependant_package',
                'many_versions_package>=2,<3',
                ''
            )))

            yield

            expected = '\n'.join((
                'dependant-package==1',
                'implicit-dependency==1',
                'many-versions-package==2.1',
                'project-with-c==0.1.0',
                'pure-python-package==0.2.1',
                'slow-python-package==0.1.0',
                'venv-update==%s' % __version__,
                ''
            ))
            assert pip_freeze() == expected
def test_conflicting_reqs(tmpdir):
    tmpdir.chdir()
    T.requirements('''
dependant_package
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)
    err = T.strip_pip_warnings(err)
    assert err == (
        "conflicting-package 1 has requirement many-versions-package<2, but you'll "
        'have many-versions-package 3 which is incompatible.\n'
        # TODO: do we still need to append our own error?
        'Error: version conflict: many-versions-package 3 (venv/{}) '
        '<-> many-versions-package<2 '
        '(from conflicting_package->-r requirements.txt (line 3))\n'.format(
            PYTHON_LIB, ))

    out = T.uncolor(out)
    assert_something_went_wrong(out)

    assert_venv_marked_invalid(tmpdir.join('venv'))
Exemple #3
0
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 <-> mccabe>=0.2.1 (from flake8==2.2.5 (from -r requirements.txt (line 3)))
Error: version conflict: pep8 1.0 <-> 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.
''' in out
Exemple #4
0
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
Exemple #5
0
def test_bad_symlink_can_be_fixed(tmpdir):
    """If the symlink at ~/.config/venv-update/$version/venv-update is wrong,
    we should be able to fix it and keep going.

    https://github.com/Yelp/pip-faster/issues/98
    """
    tmpdir.chdir()

    scratch_dir = tmpdir.join(
        'home', '.cache').ensure_dir('venv-update').ensure_dir(__version__)
    symlink = scratch_dir.join('venv-update')

    # run a trivial venv-update to populate the cache and create a proper symlink
    assert not symlink.exists()
    requirements('')
    venv_update()
    assert symlink.exists()

    # break the symlink by hand (in real life, this can happen if mounting
    # things into Docker containers, for example)
    symlink.remove()
    symlink.mksymlinkto('/nonexist')
    assert not symlink.exists()

    # a simple venv-update should install packages and fix the symlink
    enable_coverage(tmpdir)
    requirements('pure-python-package')
    venv_update()
    assert '\npure-python-package==0.2.0\n' in pip_freeze()
    assert symlink.exists()
Exemple #6
0
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
Exemple #7
0
def test_package_name_normalization(tmpdir):
    with tmpdir.as_cwd():
        enable_coverage()
        requirements('WEIRD_cAsing-packAge')

        venv_update()
        assert '\nweird-CASING-pACKage==' in pip_freeze()
Exemple #8
0
def test_override_requirements_file(tmpdir):
    tmpdir.chdir()
    enable_coverage()
    requirements('')
    Path('.').join('requirements-bootstrap.txt').write('''\
venv-update==%s
pure_python_package
''' % __version__)
    out, err = venv_update(
        'bootstrap-deps=', '-r', 'requirements-bootstrap.txt',
    )
    err = strip_pip_warnings(err)
    # pip>=10 doesn't complain about installing an empty requirements file.
    assert err == ''

    out = uncolor(out)
    # installing venv-update may downgrade / upgrade pip
    out = re.sub(' pip-[0-9.]+ ', ' ', out)
    assert '\n> pip install -r requirements-bootstrap.txt\n' in out
    assert (
        '\nSuccessfully installed pure-python-package-0.2.1 venv-update-%s' % __version__
    ) in out
    assert '\n  Successfully uninstalled pure-python-package-0.2.1\n' in out

    expected = '\n'.join((
        'venv-update==' + __version__,
        ''
    ))
    assert pip_freeze() == expected
Exemple #9
0
def test_cant_wheel_package(tmpdir):
    with tmpdir.as_cwd():
        enable_coverage()
        install_coverage()
        requirements('cant-wheel-package\npure-python-package')

        out, err = venv_update()
        err = strip_pip_warnings(err)
        assert err == ''

        out = uncolor(out)

        # for unknown reasons, py27 has an extra line with four spaces in this output, where py26 does not.
        out = out.replace('\n    \n', '\n')
        assert '''

----------------------------------------
Failed building wheel for cant-wheel-package
Running setup.py bdist_wheel for pure-python-package
Destination directory: %s/home/.cache/pip-faster/wheelhouse''' % tmpdir + '''
SLOW!! no wheel found after building (couldn't be wheeled?): cant-wheel-package==0.1.0
Installing collected packages: cant-wheel-package, pure-python-package
  Running setup.py install for cant-wheel-package
  Could not find .egg-info directory in install record for cant-wheel-package (from -r requirements.txt (line 1))
Successfully installed cant-wheel-package pure-python-package
Cleaning up...
''' in out  # noqa
        assert pip_freeze().startswith('cant-wheel-package==0.1.0\n')
Exemple #10
0
def test_symlink_is_relative(tmpdir):
    """We want to be able to mount ~/.cache/venv-update in different locations
    safely, so the symlink must be relative.

    https://github.com/Yelp/pip-faster/issues/101
    """
    tmpdir.chdir()

    scratch_dir = tmpdir.join('home', '.cache').ensure_dir('venv-update').ensure_dir(__version__)
    symlink = scratch_dir.join('venv-update')

    # run a trivial venv-update to populate the cache and create a proper symlink
    assert not symlink.exists()
    requirements('')
    venv_update()

    # it should be a valid, relative symlink
    assert symlink.exists()
    assert not symlink.readlink().startswith('/')

    # and if we move the entire scratch directory, the symlink should still be valid
    # (this is what we really care about)
    scratch_dir.move(tmpdir.join('derp'))
    symlink = tmpdir.join('derp', 'venv-update')
    assert symlink.exists()
Exemple #11
0
def test_conflicting_reqs(tmpdir):
    tmpdir.chdir()
    T.requirements('''
dependant_package
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)
    err = T.strip_pip_warnings(err)
    assert err == ''

    out = T.uncolor(out)
    assert (
        '''
Cleaning up...
Error: version conflict: many-versions-package 3 (venv/%s)'''
        ''' <-> many-versions-package<2 (from conflicting-package->-r requirements.txt (line 3))
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, tmpdir)) in out

    assert_venv_marked_invalid(tmpdir.join('venv'))
Exemple #12
0
def test_override_requirements_file(tmpdir):
    tmpdir.chdir()
    enable_coverage()
    requirements('')
    Path('.').ensure_dir('requirements.d').join('venv-update.txt').write('''\
venv-update==%s
pure_python_package
''' % __version__)
    out, err = venv_update()
    err = strip_pip_warnings(err)
    assert err == ''

    out = uncolor(out)
    assert (
        '\n> pip install --find-links=file://%s/home/.cache/pip-faster/wheelhouse -r requirements.d/venv-update.txt\n' % tmpdir
    ) in out
    assert (
        '\nSuccessfully installed pip-1.5.6 pure-python-package-0.2.0 venv-update-%s' % __version__
    ) in out
    assert '\n  Successfully uninstalled pure-python-package\n' in out

    expected = '\n'.join((
        'venv-update==%s' % __version__,
        'wheel==0.29.0',
        ''
    ))
    assert pip_freeze() == expected
Exemple #13
0
        def venv_setup():
            # First just set up a blank virtualenv, this'll bypass the
            # bootstrap when we're actually testing for speed
            if not Path('venv').exists():
                requirements('')
                venv_update()
            install_coverage()

            # Now the actual requirements we'll install
            requirements('\n'.join(
                ('project_with_c', 'pure_python_package==0.2.1',
                 'slow_python_package==0.1.0', 'dependant_package',
                 'many_versions_package>=2,<3', '')))

            yield

            expected = '\n'.join(
                ('appdirs==1.4.3', 'dependant-package==1',
                 'implicit-dependency==1', 'many-versions-package==2.1',
                 'packaging==16.8', 'pip==9.0.1', 'project-with-c==0.1.0',
                 'pure-python-package==0.2.1', 'pyparsing==2.2.0',
                 'setuptools==35.0.2', 'six==1.10.0',
                 'slow-python-package==0.1.0', 'venv-update==%s' % __version__,
                 'wheel==0.29.0', ''))
            assert pip_freeze() == expected
Exemple #14
0
def test_cant_wheel_package(tmpdir):
    with tmpdir.as_cwd():
        enable_coverage(tmpdir)
        requirements('cant-wheel-package\npure-python-package')

        out, err = venv_update()
        assert err == ''

        out = uncolor(out)

        # for unknown reasons, py27 has an extra line with four spaces in this output, where py26 does not.
        out = out.replace('\n    \n', '\n')
        assert '''

----------------------------------------
Failed building wheel for cant-wheel-package
Running setup.py bdist_wheel for pure-python-package
Destination directory: %s/home/.cache/pip-faster/wheelhouse''' % tmpdir + '''
SLOW!! no wheel found after building (couldn't be wheeled?): cant-wheel-package (from -r requirements.txt (line 1))
Installing collected packages: cant-wheel-package, pure-python-package
  Running setup.py install for cant-wheel-package
  Could not find .egg-info directory in install record for cant-wheel-package (from -r requirements.txt (line 1))
Successfully installed cant-wheel-package pure-python-package
Cleaning up...
> pip uninstall --yes coverage coverage-enable-subprocess
''' in out  # noqa
        assert pip_freeze().startswith('cant-wheel-package==0.1.0\n')
Exemple #15
0
def flake8_newer():
    requirements('''\
flake8==2.2.5
# we expect 0.8.1
pyflakes<=0.8.1

# simply to prevent these from drifting:
mccabe<=0.3
pep8<=1.5.7

-r %s/requirements.d/coverage.txt
''' % TOP)
    venv_update()
    assert pip_freeze() == '\n'.join((
        'appdirs==1.4.3',
        'coverage==4.4.1',
        'coverage-enable-subprocess==1.0',
        'flake8==2.2.5',
        'mccabe==0.3',
        'packaging==16.8',
        'pep8==1.5.7',
        'pip==9.0.1',
        'pyflakes==0.8.1',
        'pyparsing==2.2.0',
        'setuptools==35.0.2',
        'six==1.10.0',
        'venv-update==' + __version__,
        'wheel==0.29.0',
        ''
    ))
Exemple #16
0
def test_package_name_normalization(tmpdir):
    with tmpdir.as_cwd():
        enable_coverage(tmpdir)
        requirements('WEIRD_cAsing-packAge')

        venv_update()
        assert '\nweird-CASING-pACKage==' in pip_freeze()
Exemple #17
0
def test_override_requirements_file(tmpdir):
    tmpdir.chdir()
    requirements('')
    Path('.').ensure_dir('requirements.d').join('venv-update.txt').write('''\
pip-faster==%s
pure_python_package
''' % __version__)
    out, err = venv_update()
    err = strip_pip_warnings(err)
    assert err == ''

    out = uncolor(out)
    assert ' '.join((
        '\n> venv/bin/python -m pip.__main__ install',
        '-r requirements.d/venv-update.txt\n',
    )) in out
    expected = ('\nSuccessfully installed pip-1.5.6 pip-faster-%s pure-python-package-0.2.0 virtualenv-1.11.6' % __version__)
    assert expected in out
    assert '\n  Successfully uninstalled pure-python-package\n' in out

    expected = '\n'.join((
        'pip-faster==%s' % __version__,
        'virtualenv==1.11.6',
        'wheel==0.29.0',
        ''
    ))
    assert pip_freeze() == expected
Exemple #18
0
def flake8_older():
    requirements('''\
flake8==2.0
# last pyflakes release before 0.8 was 0.7.3
pyflakes<0.8

# simply to prevent these from drifting:
mccabe<=0.3
pep8<=1.5.7

-r %s/requirements.d/coverage.txt
''' % TOP)
    venv_update()
    assert pip_freeze() == '\n'.join((
        'coverage==4.0.3',
        'coverage-enable-subprocess==0',
        'flake8==2.0',
        'mccabe==0.3',
        'pep8==1.5.7',
        'pip-faster==' + __version__,
        'pyflakes==0.7.3',
        'virtualenv==1.11.6',
        'wheel==0.29.0',
        ''
    ))
Exemple #19
0
def flake8_newer():
    requirements('''\
flake8==2.2.5
# we expect 0.8.1
pyflakes<=0.8.1

# simply to prevent these from drifting:
mccabe<=0.3
pep8<=1.5.7

-r %s/requirements.d/coverage.txt
''' % TOP)
    venv_update()
    assert pip_freeze() == '\n'.join((
        'coverage==4.0.3',
        'coverage-enable-subprocess==0',
        'flake8==2.2.5',
        'mccabe==0.3',
        'pep8==1.5.7',
        'pip-faster==' + __version__,
        'pyflakes==0.8.1',
        'virtualenv==1.11.6',
        'wheel==0.29.0',
        ''
    ))
Exemple #20
0
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
Exemple #21
0
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
Exemple #22
0
def test_conflicting_reqs(tmpdir):
    tmpdir.chdir()
    T.requirements('''
dependant_package
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)
    err = T.strip_pip_warnings(err)
    assert err == (
        "conflicting-package 1 has requirement many-versions-package<2, but you'll "
        'have many-versions-package 3 which is incompatible.\n'
        # TODO: do we still need to append our own error?
        'Error: version conflict: many-versions-package 3 (venv/{}) '
        '<-> many-versions-package<2 '
        '(from conflicting_package->-r requirements.txt (line 3))\n'.format(
            PYTHON_LIB,
        )
    )

    out = T.uncolor(out)
    assert_something_went_wrong(out)

    assert_venv_marked_invalid(tmpdir.join('venv'))
Exemple #23
0
def test_conflicting_reqs(tmpdir):
    tmpdir.chdir()
    T.requirements('''
dependant_package
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)
    err = T.strip_pip_warnings(err)
    assert err == ''

    out = T.uncolor(out)
    assert (
        '''
Cleaning up...
Error: version conflict: many-versions-package 3 (venv/%s)'''
        ''' <-> many-versions-package<2 (from conflicting-package->-r requirements.txt (line 3))
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, tmpdir)
    ) in out

    assert_venv_marked_invalid(tmpdir.join('venv'))
Exemple #24
0
def test_symlink_is_relative(tmpdir):
    """We want to be able to mount ~/.cache/venv-update in different locations
    safely, so the symlink must be relative.

    https://github.com/Yelp/pip-faster/issues/101
    """
    tmpdir.chdir()

    scratch_dir = tmpdir.join(
        'home', '.cache').ensure_dir('venv-update').ensure_dir(__version__)
    symlink = scratch_dir.join('venv-update')

    # run a trivial venv-update to populate the cache and create a proper symlink
    assert not symlink.exists()
    requirements('')
    venv_update()

    # it should be a valid, relative symlink
    assert symlink.exists()
    assert not symlink.readlink().startswith('/')

    # and if we move the entire scratch directory, the symlink should still be valid
    # (this is what we really care about)
    scratch_dir.move(tmpdir.join('derp'))
    symlink = tmpdir.join('derp', 'venv-update')
    assert symlink.exists()
Exemple #25
0
def test_conflicting_reqs(tmpdir):
    tmpdir.chdir()
    T.requirements('''
# flake8 2.2.5 requires mccabe>=0.2.1, so this isn't satisfiable
flake8==2.2.5
mccabe==0.2
''')

    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)))

Something went wrong! Sending 'virtualenv_run' back in time, so make knows it's invalid.
''' % PYTHON_LIB
    ) in out
Exemple #26
0
def test_bad_symlink_can_be_fixed(tmpdir):
    """If the symlink at ~/.config/venv-update/$version/venv-update is wrong,
    we should be able to fix it and keep going.

    https://github.com/Yelp/pip-faster/issues/98
    """
    tmpdir.chdir()

    scratch_dir = tmpdir.join('home', '.cache').ensure_dir('venv-update').ensure_dir(__version__)
    symlink = scratch_dir.join('venv-update')

    # run a trivial venv-update to populate the cache and create a proper symlink
    assert not symlink.exists()
    requirements('')
    venv_update()
    assert symlink.exists()

    # break the symlink by hand (in real life, this can happen if mounting
    # things into Docker containers, for example)
    symlink.remove()
    symlink.mksymlinkto('/nonexist')
    assert not symlink.exists()

    # a simple venv-update should install packages and fix the symlink
    enable_coverage(tmpdir)
    requirements('pure-python-package')
    venv_update()
    assert '\npure-python-package==0.2.0\n' in pip_freeze()
    assert symlink.exists()
Exemple #27
0
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()
Exemple #28
0
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))
Exemple #29
0
def test_override_requirements_file(tmpdir):
    tmpdir.chdir()
    enable_coverage()
    requirements('')
    Path('.').join('requirements-bootstrap.txt').write('''\
venv-update==%s
pure_python_package
''' % __version__)
    out, err = venv_update(
        'bootstrap-deps=', '-r', 'requirements-bootstrap.txt',
    )
    err = strip_pip_warnings(err)
    # pip>=10 doesn't complain about installing an empty requirements file.
    assert err == ''

    out = uncolor(out)
    assert '\n> pip install -r requirements-bootstrap.txt\n' in out
    assert (
        '\nSuccessfully installed pure-python-package-0.2.1 venv-update-%s' % __version__
    ) in out
    assert '\n  Successfully uninstalled pure-python-package-0.2.1\n' in out

    expected = '\n'.join((
        'venv-update==' + __version__,
        ''
    ))
    assert pip_freeze() == expected
Exemple #30
0
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()
Exemple #31
0
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_args_backward(tmpdir):
    tmpdir.chdir()
    enable_coverage()
    requirements('')

    with pytest.raises(CalledProcessError) as excinfo:
        venv_update('venv=', 'requirements.txt')

    # py26 doesn't have a consistent exit code:
    #   http://bugs.python.org/issue15033
    assert excinfo.value.returncode != 0
    out, err = excinfo.value.result
    err = strip_coverage_warnings(err)
    err = strip_pip_warnings(err)
    assert err == ''
    out = uncolor(out)
    assert out.rsplit('\n', 4)[-4:] == [
        '> virtualenv requirements.txt',
        'ERROR: File already exists and is not a directory.',
        'Please provide a different path or delete the file.',
        '',
    ]

    assert Path('requirements.txt').isfile()
    assert Path('requirements.txt').read() == ''
    assert not Path('myvenv').exists()
def test_override_requirements_file(tmpdir):
    tmpdir.chdir()
    enable_coverage()
    requirements('')
    Path('.').join('requirements-bootstrap.txt').write('''\
venv-update==%s
pure_python_package
''' % __version__)
    out, err = venv_update(
        'bootstrap-deps=',
        '-r',
        'requirements-bootstrap.txt',
    )
    err = strip_pip_warnings(err)
    assert err == ('You must give at least one requirement to install '
                   '(see "pip help install")\n')

    out = uncolor(out)
    assert '\n> pip install -r requirements-bootstrap.txt\n' in out
    assert (
        '\nSuccessfully installed pure-python-package-0.2.1 venv-update-%s' %
        __version__) in out
    assert '\n  Successfully uninstalled pure-python-package-0.2.1\n' in out

    expected = '\n'.join(
        ('appdirs==1.4.0', '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', ''))
    assert pip_freeze() == expected
Exemple #34
0
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
Exemple #35
0
def test_package_name_normalization_with_dots(tmpdir, install_req):
    """Packages with dots should be installable with either dots or dashes."""
    with tmpdir.as_cwd():
        enable_coverage()
        requirements(install_req)

        venv_update()
        assert pip_freeze().startswith('dotted.package-name==')
Exemple #36
0
def test_package_name_normalization_with_dots(tmpdir, install_req):
    """Packages with dots should be installable with either dots or dashes."""
    with tmpdir.as_cwd():
        enable_coverage()
        requirements(install_req)

        venv_update()
        assert pip_freeze().startswith('dotted.package-name==')
Exemple #37
0
def install_twice(tmpdir, between):
    """install twice, and the second one should be faster, due to whl caching"""
    tmpdir.chdir()

    # Arbitrary packages that takes a bit of time to install:
    # Should I make a fixture c-extension to remove these dependencies?
    # NOTE: Avoid projects that use 2to3 (urwid). It makes the runtime vary too widely.
    requirements('''\
simplejson==3.6.5
pyyaml==3.11
pylint==1.4.0
astroid<1.3.3
pytest==2.6.4
unittest2==0.8.0
six<=1.8.0
chroniker
''')

    from time import time
    enable_coverage(tmpdir)
    assert pip_freeze() == '\n'.join(
        ('cov-core==1.15.0', 'coverage==4.0a1', ''))

    start = time()
    venv_update()
    time1 = time() - start
    assert pip_freeze() == '\n'.join(
        ('PyYAML==3.11', 'astroid==1.3.2', 'chroniker==0.0.0',
         'logilab-common==0.63.2', 'py==1.4.26', 'pylint==1.4.0',
         'pytest==2.6.4', 'simplejson==3.6.5', 'six==1.8.0',
         'unittest2==0.8.0', 'wheel==0.24.0', ''))

    between()

    enable_coverage(tmpdir)
    # there may be more or less packages depending on what exactly happened between
    assert 'cov-core==1.15.0\ncoverage==4.0a1\n' in pip_freeze()

    start = time()
    # second install should also need no network access
    # these are localhost addresses with arbitrary invalid ports
    venv_update(
        http_proxy='http://127.0.0.1:111111',
        https_proxy='https://127.0.0.1:222222',
        ftp_proxy='ftp://127.0.0.1:333333',
    )
    time2 = time() - start
    assert pip_freeze() == '\n'.join(
        ('PyYAML==3.11', 'astroid==1.3.2', 'chroniker==0.0.0',
         'logilab-common==0.63.2', 'py==1.4.26', 'pylint==1.4.0',
         'pytest==2.6.4', 'simplejson==3.6.5', 'six==1.8.0',
         'unittest2==0.8.0', 'wheel==0.24.0', ''))

    # second install should be at least twice as fast
    ratio = time1 / time2
    print('%.2fx speedup' % ratio)
    return ratio
Exemple #38
0
def test_not_installable_thing(tmpdir):
    tmpdir.chdir()
    enable_coverage()

    install_coverage()

    requirements('not-a-real-package-plz')
    with pytest.raises(CalledProcessError):
        venv_update()
Exemple #39
0
def test_not_installable_thing(tmpdir):
    tmpdir.chdir()
    enable_coverage()

    install_coverage()

    requirements('not-a-real-package-plz')
    with pytest.raises(CalledProcessError):
        venv_update()
Exemple #40
0
def test_trivial(tmpdir):
    tmpdir.chdir()
    requirements('')
    enable_coverage()
    venv_update()
    # Originally suggested by none other than @bukzor in:
    # https://github.com/pypa/virtualenv/issues/118
    # This directory now just causes problems (especially with relocating)
    # since the debian issue has been fixed.
    assert not tmpdir.join('venv', 'local').exists()
Exemple #41
0
def test_eggless_url(tmpdir):
    tmpdir.chdir()

    enable_coverage()

    # An arbitrary url requirement.
    requirements('-e file://' + str(TOP / 'tests/testing/packages/pure_python_package'))

    venv_update()
    assert '#egg=pure_python_package' in pip_freeze()
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')
Exemple #43
0
def test_trivial(tmpdir):
    tmpdir.chdir()
    requirements('')
    enable_coverage()
    venv_update()
    # Originally suggested by none other than @bukzor in:
    # https://github.com/pypa/virtualenv/issues/118
    # This directory now just causes problems (especially with relocating)
    # since the debian issue has been fixed.
    assert not tmpdir.join('venv', 'local').exists()
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')
Exemple #45
0
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()
Exemple #46
0
def test_eggless_url(tmpdir):
    tmpdir.chdir()

    enable_coverage()

    # An arbitrary url requirement.
    requirements('-e file://' + str(TOP / 'tests/testing/packages/pure_python_package'))

    venv_update()
    assert '#egg=pure_python_package' in pip_freeze()
Exemple #47
0
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')
Exemple #48
0
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'))
Exemple #49
0
def time_savings(tmpdir, between):
    """install twice, and the second one should be faster, due to whl caching"""
    with tmpdir.as_cwd():
        enable_coverage()
        install_coverage()

        requirements('\n'.join(
            ('project_with_c', 'pure_python_package==0.2.0',
             'slow_python_package==0.1.0', 'dependant_package',
             'many_versions_package>=2,<3', '')))

        from time import time

        start = time()
        venv_update(
            PIP_VERBOSE='1',
            PIP_RETRIES='0',
            PIP_TIMEOUT='0',
        )
        time1 = time() - start
        expected = '\n'.join(
            ('dependant-package==1', 'implicit-dependency==1',
             'many-versions-package==2.1', 'project-with-c==0.1.0',
             'pure-python-package==0.2.0', 'slow-python-package==0.1.0',
             'venv-update==%s' % __version__, 'wheel==0.29.0', ''))
        assert pip_freeze() == expected

        between()
        install_coverage()

        start = time()
        # second install should also need no network access
        # these are localhost addresses with arbitrary invalid ports
        venv_update(
            PIP_VERBOSE='1',
            PIP_RETRIES='0',
            PIP_TIMEOUT='0',
            http_proxy='http://127.0.0.1:111111',
            https_proxy='https://127.0.0.1:222222',
            ftp_proxy='ftp://127.0.0.1:333333',
        )
        time2 = time() - start
        assert pip_freeze() == expected

        print()
        print('%.3fs originally' % time1)
        print('%.3fs subsequently' % time2)

        difference = time1 - time2
        print('%.2fs speedup' % difference)

        ratio = time1 / time2
        percent = (ratio - 1) * 100
        print('%.2f%% speedup' % percent)
        return difference
Exemple #50
0
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'))
Exemple #51
0
def test_wrong_wheel(tmpdir):
    tmpdir.chdir()

    requirements('')
    venv_update('venv1', 'requirements.txt', '-ppython2.7')
    # A different python
    # Before fixing, this would install argparse using the `py2-none-any`
    # wheel, even on py3
    ret2out, _ = venv_update('venv2', 'requirements.txt', '-ppython3.3')

    assert 'py2-none-any' not in ret2out
Exemple #52
0
def test_remove_stale_cache_values(tmpdir):
    """Tests that we remove stale (older than a week) cached packages
    and wheels, while still keeping everything created within the past week.
    """
    import os
    import time

    tmpdir.chdir()
    home_path = str(Path('.').realpath())

    pip_path = home_path + '/.pip'
    cache_path = pip_path + '/cache'
    wheelhouse_path = pip_path + '/wheelhouse'

    stale_cached_package = cache_path + '/stale_package'
    fresh_cached_package = cache_path + '/new_package'

    stale_cached_wheel = wheelhouse_path + '/stale_wheel'
    fresh_cached_wheel = wheelhouse_path + '/new_wheel'

    # Creates a cached package and wheel in their respective
    # .pip/cache/ and .pip/wheelhouse directories.
    os.makedirs(stale_cached_package)
    os.makedirs(fresh_cached_package)
    os.makedirs(stale_cached_wheel)
    os.makedirs(fresh_cached_wheel)

    # Create some rough times for testing. These represent, in
    # seconds since epoch, a time from today, this week, and last month
    seconds_in_day = 86400
    today_time = int(time.time())
    this_week_time = int(time.time()) - seconds_in_day * 3
    last_month_time = int(time.time()) - seconds_in_day * 40

    # Set access times of stale package/wheel to be older than a week.
    os.utime(stale_cached_package, (0, 0))  # Jan 1, 1970
    os.utime(stale_cached_wheel, (last_month_time, last_month_time))

    # Set access times of fresh package/wheel to be within the past week.
    os.utime(fresh_cached_package, (today_time, today_time))
    os.utime(fresh_cached_wheel, (this_week_time, this_week_time))

    requirements('')
    venv_update()

    # Assert that we can no longer access the stale package/wheel
    # that have been removed.
    assert not os.access(stale_cached_package, os.F_OK)
    assert not os.access(stale_cached_wheel, os.F_OK)

    # Assert that we can still access the fresh package/wheel,
    # they should not have been removed.
    assert os.access(fresh_cached_package, os.F_OK)
    assert os.access(fresh_cached_wheel, os.F_OK)
Exemple #53
0
def test_extra_index_url_doesnt_cache(tmpdir):
    tmpdir.chdir()
    enable_coverage()
    install_coverage()

    requirements('pure-python-package==0.2.1')
    venv_update(
        'pip-command=', 'pip-faster', 'install',
        '--extra-index-url=https://pypi.python.org/simple',
    )

    assert not tuple(cached_wheels(tmpdir))
Exemple #54
0
def test_eggless_url(tmpdir):
    tmpdir.chdir()
    requirements('')

    venv_update()
    assert 'venv-update' not in pip_freeze()

    # An arbitrary git-url requirement.
    requirements('git+git://github.com/Yelp/venv-update.git')

    venv_update()
    assert 'venv-update' in pip_freeze()
Exemple #55
0
def test_wrong_wheel(tmpdir):
    tmpdir.chdir()

    requirements('pure_python_package==0.1.0')
    venv_update('venv1')
    # A different python
    # Before fixing, this would install argparse using the `py2-none-any`
    # wheel, even on py3
    other_python = OtherPython()
    ret2out, _ = venv_update('venv2', '-p' + other_python.interpreter, '--', '-vv', '-r', 'requirements.txt')

    assert '''
  No wheel found locally for pinned requirement pure-python-package==0.1.0 (from -r requirements.txt (line 1))
''' in uncolor(ret2out)
Exemple #56
0
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))