def test_pyinstall_opportunistically_upgrades_dependent_packages( pytestconfig, simple_http_test_server, use_egg_cache): # @UnusedVariable # NOQA with PkgTemplate(name='acme.a-1.0', install_requires='acme.c') as pkg: pkg.dead = True # delete on exit pkg_t(pkg, "acme.c-1.0") _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.a" % simple_http_test_server.uri) assert pkg.installed_packages()["acme.c"].version == "1.0" pkg_t(pkg, "acme.c-1.1") pkg_t(pkg, "acme.b-1.0", install_requires='acme.c') _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.b" % simple_http_test_server.uri) assert 'acme.b' in pkg.installed_packages() assert pkg.installed_packages()["acme.c"].version == "1.1"
def test_pyinstall_installs_required_dependencies_when_backtracking( pytestconfig, simple_http_test_server, use_egg_cache): # @UnusedVariable # NOQA with PkgTemplate(name='acme.a-1.0', install_requires='acme.c\nacme.b') as pkg: pkg.dead = True # delete on exit pkg_t(pkg, "acme.b-1.0", install_requires='acme.d') pkg_t(pkg, "acme.b-1.1", install_requires='acme.d') pkg_t(pkg, "acme.c-1.0", install_requires='acme.b==1.0') pkg_t(pkg, "acme.d-1.0") _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.a" % simple_http_test_server.uri) assert 'acme.a' in pkg.installed_packages() assert pkg.installed_packages()["acme.b"].version == "1.0" assert pkg.installed_packages()["acme.c"].version == "1.0" assert pkg.installed_packages()["acme.d"].version == "1.0"
def test_pyinstall_force_ignores_incompatible_pinned_dependencies( pytestconfig, simple_http_test_server, use_egg_cache): # @UnusedVariable # NOQA with PkgTemplate(name='acme.a-1.0', install_requires='acme.c==1.0') as pkg: pkg.dead = True # delete on exit pkg_t(pkg, "acme.b-1.0", install_requires='acme.c==1.1') pkg_t(pkg, "acme.c-1.0") pkg_t(pkg, "acme.c-1.1") _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.a" % simple_http_test_server.uri) assert pkg.installed_packages()["acme.c"].version == "1.0" _exec_pyinstall(pkg, "-i %s --force acme.b" % simple_http_test_server.uri) assert 'acme.b' in pkg.installed_packages() assert pkg.installed_packages()["acme.c"].version == "1.1" assert 'acme.a' in pkg.installed_packages() # but acme.a is now broken
def test_ext_gcov_test_cython(pytestconfig): """Create a package with a Cython extension we can run ext_gcov_test on """ test_dir = os.path.join(os.path.dirname(__file__), 'gcov_ext_cython') with PkgTemplate(name='acme.foo') as pkg: pkg.install_package('pytest-cov') copy_tree(test_dir, pkg.trunk_dir) pkg.run_with_coverage( [os.path.join(pkg.trunk_dir, 'setup.py'), 'ext_gcov_test'], pytestconfig, cd=pkg.trunk_dir) root = etree.parse(os.path.join(pkg.trunk_dir, 'gcov', 'coverage.xml')) (class_, ) = root.findall('./packages/package/classes/class') assert class_.attrib['filename'] == 'src/ext.pyx' lines = dict((int(e.attrib['number']), int(e.attrib['hits'])) for e in class_.findall('./lines/line')) assert lines[5] >= 1 # fn_1 covered assert lines[12] == 0 # fn_2 not covered
def test_delete_other_dev_eggs(pytestconfig, pypi_chishop): with PkgTemplate(name='acme.tpi.test.dev-1.0.0.dev1') as pkg: dist_dir = os.path.join(pypi_chishop.workspace, 'chishop/media/dists/a/acme.tpi.test.dev') pkg.create_pypirc(pypi_chishop.get_rc()) pkg.install_package('pytest-cov') new_env = copy.copy(pkg.env) new_env['HOME'] = pkg.workspace setup_cmd = ['%s/setup.py' % pkg.trunk_dir] setup_cmd += ['sdist', 'register', 'upload', '--show-response'] pkg.run_with_coverage(setup_cmd, pytestconfig, env=new_env, cd=HERE, capture_stdout=False) assert os.path.isfile(os.path.join(dist_dir, 'acme.tpi.test.dev-1.0.0.dev1.tar.gz')) update_setup_cfg('%s/setup.cfg' % pkg.trunk_dir, vcs_uri=pkg.vcs_uri, metadata={'version': '1.1.0'}, dev=True) pkg.run_with_coverage(setup_cmd, pytestconfig, env=new_env, cd=HERE, capture_stdout=False) assert os.path.isfile(os.path.join(dist_dir, 'acme.tpi.test.dev-1.1.0.dev1.tar.gz')) assert not os.path.isfile(os.path.join(dist_dir, 'acme.tpi.test.dev-1.0.0.dev1.tar.gz'))
def test_develop_pulls_in_deps_of_other_deps_in_development_1( pytestconfig, simple_http_test_server, use_egg_cache): # @UnusedVariable # NOQA """ 1) given the following package hierarchy: A / B (fetched without dependencies) | C | D 2) and provided that package B has been set-up using: $ python setup.py develop --no-deps --no-build 3) executing the following command for pacakge D: $ python setup.py develop 4) should pull in package A """ with PkgTemplate(name='acme.a-1.0') as pkg: _, acmeb_trunk = pkg_t(pkg, "acme.b-1.0", install_requires='acme.a==1.0') pkg_t(pkg, "acme.c-1.0", install_requires='acme.b==1.0') _, acmed_trunk = pkg_t(pkg, "acme.d-1.0", install_requires='acme.c==1.0', metadata=dict(tests_require='')) _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) pkg.run("%s setup.py develop --no-deps --no-build -i %s" % (pkg.python, simple_http_test_server.uri), cd=acmeb_trunk) assert "acme.a" not in pkg.installed_packages() pkg.run("%s setup.py develop -i %s" % (pkg.python, simple_http_test_server.uri), cd=acmed_trunk) assert pkg.installed_packages()["acme.a"].version == "1.0"
def test_non_inhouse_namespace(pytestconfig): """ As above, using a non-inhouse namespace """ metadata = dict(install_requires='acme.bar', ) with PkgTemplate(name='mesa.foobar', metadata=metadata) as pkg: pkg.install_package('pytest-cov') print pkg.run_with_coverage( ['%s/setup.py' % pkg.trunk_dir, 'develop', '-q'], pytestconfig, cd=HERE) [ pkg.run(cmd, capture=False, cd=HERE) for cmd in [ '%s -c "import mesa.foobar"' % pkg.python, '%s/bin/foobar -h' % pkg.virtualenv, ] ] installed = pkg.installed_packages() assert installed['mesa.foobar'].issrc assert installed['acme.bar'].isdev
def test_multi_level_namespace(pytestconfig): """ As above, using a multi-level namespace """ with PkgTemplate(name='acme.foo.bar') as pkg: pkg.install_package('pytest-cov') print pkg.run_with_coverage( ['%s/setup.py' % pkg.trunk_dir, 'develop', '-q'], pytestconfig, cd=HERE) [ pkg.run(cmd, capture=False, cd=HERE) for cmd in [ '%s -c "import acme.foo.bar"' % pkg.python, '%s/bin/acme.foo.bar -h' % pkg.virtualenv, ] ] installed = pkg.installed_packages() assert installed['acme.foo.bar'].issrc assert (path.path(pkg.trunk_dir) / 'acme' / 'foo' / 'bar' / '__init__.py').isfile()
def test_egg_revisions(pypi_chishop, svn_repo, workspace, pytestconfig): # @UnusedVariable # NOQA # pypi_chishop.restore() package1_metadata = dict(version='1.2.3', ) package2_metadata = dict(version='4.5.6', install_requires='acme.er.package1==1.2.3') package3_metadata = dict(version='7.8.9', install_requires='acme.er.package2==4.5.6') with ExitStack() as stack: pkg1 = stack.enter_context( create_pkg(pypi_chishop, svn_repo, 'acme.er.package1', metadata=package1_metadata, dev=False)) pkg2 = stack.enter_context( create_pkg(pypi_chishop, svn_repo, 'acme.er.package2', metadata=package2_metadata, dev=False)) pkg3 = stack.enter_context( PkgTemplate(name='acme.package3', repo_base=svn_repo.uri, metadata=package3_metadata)) pkg3.run('%s %s/bin/easy_install -i %s/simple acme.er.package2' % (pkg3.python, pkg3.virtualenv, pypi_chishop.uri)) py_env = PythonInstallation(pkg3.python) egg = os.path.join( pkg3.virtualenv, 'lib', 'python' + py_env.short_version(2), 'site-packages', 'acme.er.package2-4.5.6-%s.egg' % py_env.py_version()) name_to_revno = dict( (name, str(revision)) for name, _, _, revision in read_allrevisions(egg)) assert len(name_to_revno) == 2 assert (name_to_revno['acme.er.package1'] == _svn_info_revision( pkg3, pkg1.workspace, 'acme.er.package1')) assert (name_to_revno['acme.er.package2'] == _svn_info_revision( pkg3, pkg2.workspace, 'acme.er.package2'))
def test_core_package(pytestconfig): """ Creates template, runs setup.py develop then does some checks that the package was setup properly. """ metadata = dict(install_requires='acme.bar', ) with PkgTemplate(name='acme.foo', metadata=metadata) as pkg: pkg.install_package('pytest-cov') print pkg.run_with_coverage(['%s/setup.py' % pkg.trunk_dir, 'develop'], pytestconfig, cd=HERE) [ pkg.run(cmd, capture=False, cd=HERE) for cmd in [ '%s -c "import acme.foo"' % pkg.python, '%s/bin/foo -h' % pkg.virtualenv, ] ] installed = pkg.installed_packages() assert installed['acme.foo'].issrc assert installed['acme.bar'].isdev
def test_pyinstall_downgrades_as_required_by_pins( pytestconfig, simple_http_test_server, use_egg_cache): # @UnusedVariable # NOQA with PkgTemplate(name='acme.a-1.0', install_requires='acme.c') as pkg: pkg.dead = True # delete on exit pkg_t(pkg, "acme.c-1.0") pkg_t(pkg, "acme.c-1.1") pkg_t(pkg, "acme.b-1.0", install_requires='acme.c==1.0') _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.a" % simple_http_test_server.uri) assert pkg.installed_packages()["acme.c"].version == "1.1" out = _exec_pyinstall(pkg, "-i %s acme.b" % simple_http_test_server.uri, capture=True) assert 'Downgrading acme.c from 1.1 to 1.0' in out assert 'acme.b' in pkg.installed_packages() assert pkg.installed_packages()["acme.c"].version == "1.0"
def test_pyinstall_links_to_package_from_cache_in_preference_to_fetching_from_pypi( pytestconfig, pypi_chishop_with_egg_cache, run_from): """ Creates template, runs pyinstall from the setuptools command Find and install latest non-dev version of a given package, and then try and import it, check that it is an egglink into the egg cache. """ cache = pypi_chishop_with_egg_cache.egg_cache pypi_url = "http://%s:%s/simple" % (pypi_chishop_with_egg_cache.hostname, pypi_chishop_with_egg_cache.port) with PkgTemplate(name="acme.pypipkg", dev=False, metadata=dict(name="acme.pypipkg", version="1.2.3")) as pkg: pkg.install_package('pytest-cov') pkg.create_pypirc(pypi_chishop_with_egg_cache.get_rc()) new_env = copy.copy(pkg.env) new_env['HOME'] = pkg.workspace setup_cmd = [os.path.join(pkg.trunk_dir, "setup.py")] setup_cmd += ['bdist_egg', 'register', 'upload', '--show-response'] pkg.run_with_coverage(setup_cmd, pytestconfig, env=new_env, cd=HERE, capture_stdout=False) path_of_egg_in_cache = os.path.join(cache, 'ap', ('acme.pypipkg-1.2.3-py%d.%d.egg' % sys.version_info[:2])) assert os.path.exists(path_of_egg_in_cache) pyinstall_cmd = pyinstall_cmd_func(pkg, 'pyinstall', run_from) pyinstall_cmd = pyinstall_cmd + ['-i', pypi_url, 'acme.pypipkg'] pkg.run_with_coverage(pyinstall_cmd, pytestconfig, cd=HERE, env={'VIRTUALENV_SEARCH_PATH': cache}, capture_stdout=False) [pkg.run(cmd, capture=False, cd=HERE) for cmd in [ '%s -c "import acme.pypipkg"' % (pkg.python), ]] installed = pkg.installed_packages() assert installed['acme.pypipkg'].version == '1.2.3' assert installed['acme.pypipkg'].isrel assert installed['acme.pypipkg'].source_path == path_of_egg_in_cache
def test_upload_different_platforms(pytestconfig, pypi_chishop): with PkgTemplate(name='acme.tpi.test.platforms') as pkg: pkg.create_pypirc(pypi_chishop.get_rc()) pkg.install_package('pytest-cov') setup_py = '%s/setup.py' % pkg.trunk_dir _add_ext_module(pkg) setup_cmd = [setup_py, 'bdist_egg', '-p', 'platform1', 'register', 'upload'] pkg.run_with_coverage(setup_cmd, pytestconfig, env=dict(pkg.env, HOME=pkg.workspace), cd=HERE, capture_stdout=False) setup_cmd = [setup_py, 'bdist_egg', '-p', 'platform2', 'register', 'upload'] pkg.run_with_coverage(setup_cmd, pytestconfig, env=dict(pkg.env, HOME=pkg.workspace), cd=HERE, capture_stdout=False) response = urlopen('http://%s:%s/simple/acme.tpi.test.platforms' % (pypi_chishop.hostname, pypi_chishop.port)) buf = response.read() pyversion = sys.version[:3] # sysconfig.get_python_version() assert ('acme.tpi.test.platforms-1.0.0.dev1-py%s-platform1.egg' % pyversion) in buf assert ('acme.tpi.test.platforms-1.0.0.dev1-py%s-platform2.egg' % pyversion) in buf
def test_pyinstall_update_dev_skips_pinned_packages( pytestconfig, simple_http_test_server, use_egg_cache): # @UnusedVariable # NOQA with PkgTemplate(name='acme.a-1.0', install_requires='acme.b==1.1') as pkg: pkg_t(pkg, "acme.b-1.1") _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.a" % simple_http_test_server.uri) pkg_t(pkg, "acme.b-1.2.dev1") _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) with pytest.raises(CalledProcessError) as exc: _exec_pyinstall(pkg, "-i %s -U --dev acme.b" % simple_http_test_server.uri, capture=True) assert ( 'Unable to update package acme.b, it is pinned (See list above)' in exc.value.output) assert pkg.installed_packages()["acme.b"].version == "1.1"
def test_pyinstall_fails_on_incompatible_pinned_dependencies( pytestconfig, simple_http_test_server, use_egg_cache): # @UnusedVariable # NOQA with PkgTemplate(name='acme.a-1.0', install_requires='acme.c==1.0') as pkg: pkg.dead = True # delete on exit pkg_t(pkg, "acme.b-1.0", install_requires='acme.c==1.1') pkg_t(pkg, "acme.c-1.0") pkg_t(pkg, "acme.c-1.1") _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.a" % simple_http_test_server.uri) assert pkg.installed_packages()["acme.c"].version == "1.0" with pytest.raises(Exception): _exec_pyinstall(pkg, "-i %s acme.b" % simple_http_test_server.uri) assert 'acme.b' not in pkg.installed_packages() # nothing happened assert pkg.installed_packages()["acme.c"].version == "1.0"
def test_jenkins_create(pytestconfig, jenkins_server): """ Creates template, creates the jenkins job """ name = 'acme.projecttemplate.test' try: with PkgTemplate(name=name) as pkg: pkg.install_package('pytest-cov') print( pkg.run_with_coverage([ '%s/setup.py' % pkg.trunk_dir, 'jenkins', '--vcs-url=foo', '--no-prompt', '--server', jenkins_server.uri, '--user', 'foo', '--password', 'bar' ], pytestconfig, cd=HERE)) info = jenkins_server.api.get_job_info(name) assert info['name'] == name finally: try: jenkins_server.api.delete_job(name) except: pass
def test_cython_build_ext(pytestconfig): """ Creates template, runs setup.py develop which will invoke build_ext which for this project template contains cython template files """ test_dir = os.path.join(os.path.dirname(__file__), 'cython') with PkgTemplate(name='acme.foo') as pkg: pkg.install_package('pytest-cov') copy_tree(test_dir, pkg.trunk_dir) print( pkg.run_with_coverage(['%s/setup.py' % pkg.trunk_dir, 'develop'], pytestconfig, cd=HERE)) [ pkg.run(cmd, capture=False, cd=HERE) for cmd in [ '%s -c "import acme.foo"' % pkg.python, ] ] exec_code = ("from acme.foo import _mycython; " "print(_mycython.test_cython([1,2,3]))") output = pkg.run('%s -c "%s"' % (pkg.python, exec_code), capture=True) assert output.strip() == "[2, 4, 6]"
def test_full_dependency_walkback_in_version_conflict_exception( pytestconfig, simple_http_test_server, use_egg_cache): # @UnusedVariable # NOQA with PkgTemplate(name='acme.a-1.0', install_requires='acme.c==1.0') as pkg: pkg_t(pkg, "acme.b-1.0", install_requires='acme.c==1.1') pkg_t(pkg, "acme.c-1.0") pkg_t(pkg, "acme.c-1.1") _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.a" % simple_http_test_server.uri) with pytest.raises(Exception) as exc: _exec_pyinstall(pkg, "-i %s acme.b" % simple_http_test_server.uri, capture=True) assert """There is a version conflict. We already have: acme.c 1.0 required by acme.c==1.0 (acme.c 1.0) required by acme.a (acme.a 1.0) which is incompatible with acme.c==1.1 required by acme.b (acme.b 1.0) """ in exc.value.output
def test_prevent_upload_after_adding_platform(pytestconfig, pypi_chishop): """If the maintainer makes the package platform-aware (e.g. by Cythonising), we should refuse upload without a version bump.""" expected_msg = ('Upload failed (400): BAD REQUEST: cannot upload a platform-specific ' 'distribution when a platform-independent distribution already exists ' '(delete the existing distribution, or bump the version)') with PkgTemplate(name='acme.tpi.test.cythonise') as pkg: pkg.create_pypirc(pypi_chishop.get_rc()) pkg.install_package('pytest-cov') setup_py = '%s/setup.py' % pkg.trunk_dir setup_cmd = [setup_py, 'bdist_egg', 'register', 'upload'] pkg.run_with_coverage(setup_cmd, pytestconfig, env=dict(pkg.env, HOME=pkg.workspace), cd=HERE, capture_stdout=False) _add_ext_module(pkg) setup_cmd = [setup_py, 'bdist_egg', '-p', 'platform1', 'register', 'upload'] with pytest.raises(CalledProcessError) as exc: print(pkg.run_with_coverage(setup_cmd, pytestconfig, env=dict(pkg.env, HOME=pkg.workspace), cd=HERE, capture_stderr=True)) assert expected_msg in exc.value.output
def test_upgrade_handles_multi_level_dependencies( pytestconfig, simple_http_test_server, use_egg_cache): # @UnusedVariable # NOQA with PkgTemplate(name='acme.a-1.0', install_requires='acme.b==1.0') as pkg: pkg_t(pkg, 'acme.b-1.0', install_requires='acme.c==1.0') pkg_t(pkg, 'acme.c-1.0') _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.a" % simple_http_test_server.uri) assert pkg.installed_packages()['acme.a'].version == '1.0' assert pkg.installed_packages()['acme.b'].version == '1.0' assert pkg.installed_packages()['acme.c'].version == '1.0' pkg_t(pkg, "acme.a-1.1", install_requires='acme.b==1.1') pkg_t(pkg, 'acme.b-1.1', install_requires='acme.c==1.1') pkg_t(pkg, 'acme.c-1.1') _dist_inhouse_eggs(pkg, simple_http_test_server, use_egg_cache) _exec_pyinstall(pkg, "-i %s acme.a" % simple_http_test_server.uri) assert pkg.installed_packages()['acme.a'].version == '1.1' assert pkg.installed_packages()['acme.b'].version == '1.1' assert pkg.installed_packages()['acme.c'].version == '1.1'
def test_rpm(svn_repo, workspace, pytestconfig): """ Creates template, runs setup.py egg_info which should then call rpm """ cfg = dict( rpm=dict(services='svc1', include_files='file1.txt\nfile2.txt', install_requires='foo == 1\nbar <= 2'), svc1=dict(script='bin/svc1.sh', env="FOO=1,BAR=2", runas="myuser", numprocs="2"), ) with PkgTemplate(name='acme.foo', repo_base=svn_repo.uri, **cfg) as pkg: pkg.install_package('pytest-cov') [ pkg.run(cmd, capture=False, cd=HERE) for cmd in [ ("svn import %s/%s %s -m 'initial import'" % (pkg.workspace, 'acme.foo', pkg.vcs_uri)), 'svn co %s/trunk %s/acme.foo' % (pkg.vcs_uri, workspace.workspace), 'mkdir %s/acme.foo/bin' % workspace.workspace, 'echo "echo foo" > %s/acme.foo/bin/svc1.sh' % workspace.workspace, 'echo "test123" > %s/acme.foo/file1.txt' % workspace.workspace, 'echo "test345" > %s/acme.foo/file2.txt' % workspace.workspace, ] ] # Egg-info will trigger RPM print( pkg.run_with_coverage( ['%s/acme.foo/setup.py' % workspace.workspace, 'egg_info'], pytestconfig, cd=HERE)) egginfo_dir = workspace.workspace / 'acme.foo' / 'acme.foo.egg-info' ctl_dir = egginfo_dir / 'ctl' assert ctl_dir.isdir() file1 = ctl_dir / 'file1.txt' assert file1.isfile() assert file1.lines(retain=False) == ['test123'] file2 = ctl_dir / 'file2.txt' assert file2.isfile() assert file2.lines(retain=False) == ['test345'] script = ctl_dir / 'svc1.sh' assert script.isfile() assert script.lines(retain=False) == ['echo foo'] ctl_file = ctl_dir / 'svc1.ctl' lines = ctl_file.lines(retain=False) assert 'PYRPM_SVC_ENVIRONMENT="FOO=1,BAR=2"' in lines assert 'PYRPM_SVC_NUMPROCS=2' in lines assert 'PYRPM_SVC_RUNAS="myuser"' in lines assert 'exec ${PYRPM_PKG_DIR}/ctl/svc1.sh ' in lines requires = egginfo_dir / 'rpm_requires.spec' assert requires.isfile() assert requires.lines(retain=False) == ['Requires: foo == 1, bar <= 2']