def test_unwriteable_contents(): my_app_setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=['my_app'], include_package_data=True, package_data={'my_app': ['unwriteable.so']}, ) """) UNWRITEABLE_PERMS = 0o400 with temporary_content( { 'setup.py': my_app_setup_py, 'my_app/__init__.py': '', 'my_app/unwriteable.so': '' }, perms=UNWRITEABLE_PERMS) as my_app_project_dir: with pushd(my_app_project_dir): subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel']) uses_my_app_setup_py = dedent(""" from setuptools import setup setup( name='uses_my_app', version='0.0.0', zip_safe=True, install_requires=['my_app'], ) """) with temporary_content({'setup.py': uses_my_app_setup_py }) as uses_my_app_project_dir: with pushd(uses_my_app_project_dir): subprocess.check_call([ sys.executable, 'setup.py', 'bdist_pex', '--pex-args=--disable-cache --no-pypi -f {}'.format( os.path.join(my_app_project_dir, 'dist')) ]) with open_zip('dist/uses_my_app-0.0.0.pex') as zf: unwriteable_sos = [ path for path in zf.namelist() if path.endswith('my_app/unwriteable.so') ] assert 1 == len(unwriteable_sos) unwriteable_so = unwriteable_sos.pop() zf.extract(unwriteable_so) assert UNWRITEABLE_PERMS == stat.S_IMODE( os.stat(unwriteable_so).st_mode)
def test_unwriteable_contents(): my_app_setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=['my_app'], include_package_data=True, package_data={'my_app': ['unwriteable.so']}, ) """) UNWRITEABLE_PERMS = 0o400 with temporary_content( { 'setup.py': my_app_setup_py, 'my_app/__init__.py': '', 'my_app/unwriteable.so': '' }, perms=UNWRITEABLE_PERMS) as my_app_project_dir: my_app_whl = WheelInstaller(my_app_project_dir).bdist() uses_my_app_setup_py = bdist_pex_setup_py(name='uses_my_app', version='0.0.0', zip_safe=True, install_requires=['my_app']) with temporary_content({'setup.py': uses_my_app_setup_py }) as uses_my_app_project_dir: pex_args = '--pex-args=--disable-cache --no-pypi -f {}'.format( os.path.dirname(my_app_whl)) uses_my_app_pex = bdist_pex_installer(uses_my_app_project_dir, bdist_args=[pex_args ]).bdist() with open_zip(uses_my_app_pex) as zf: unwriteable_sos = [ path for path in zf.namelist() if path.endswith('my_app/unwriteable.so') ] assert 1 == len(unwriteable_sos) unwriteable_so = unwriteable_sos.pop() zf.extract(unwriteable_so, path=uses_my_app_project_dir) extract_dest = os.path.join(uses_my_app_project_dir, unwriteable_so) assert UNWRITEABLE_PERMS == stat.S_IMODE( os.stat(extract_dest).st_mode)
def test_entry_point_exit_code(): setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=[''], entry_points={'console_scripts': ['my_app = my_app:do_something']}, ) """) error_msg = 'setuptools expects this to exit non-zero' my_app = dedent(""" def do_something(): return '%s' """ % error_msg) with temporary_content({'setup.py': setup_py, 'my_app.py': my_app}) as project_dir: installer = EggInstaller(project_dir) dist = DistributionHelper.distribution_from_path(installer.bdist()) so, rc = run_simple_pex_test('', env={'PEX_SCRIPT': 'my_app'}, dists=[dist]) assert so.decode('utf-8').strip() == error_msg assert rc == 1
def assert_entry_points(entry_points): setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=[''], entry_points=%(entry_points)r, ) """ % dict(entry_points=entry_points)) my_app = dedent(""" def do_something(): print("hello world!") """) with temporary_content({'setup.py': setup_py, 'my_app.py': my_app}) as project_dir: with pushd(project_dir): subprocess.check_call([sys.executable, 'setup.py', 'bdist_pex']) process = subprocess.Popen([os.path.join(project_dir, 'dist', 'my_app-0.0.0.pex')], stdout=subprocess.PIPE) stdout, _ = process.communicate() assert 0 == process.returncode assert stdout == b'hello world!\n'
def assert_entry_points(entry_points): setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=[''], entry_points=%(entry_points)r, ) """ % dict(entry_points=entry_points)) my_app = dedent(""" def do_something(): print("hello world!") """) with temporary_content({ 'setup.py': setup_py, 'my_app.py': my_app }) as project_dir: with pushd(project_dir): subprocess.check_call([sys.executable, 'setup.py', 'bdist_pex']) process = subprocess.Popen( [os.path.join(project_dir, 'dist', 'my_app-0.0.0.pex')], stdout=subprocess.PIPE) stdout, _ = process.communicate() assert '{pex_root}' not in os.listdir(project_dir) assert 0 == process.returncode assert stdout == b'hello world!\n'
def test_entry_point_exit_code(): setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=[''], entry_points={'console_scripts': ['my_app = my_app:do_something']}, ) """) error_msg = 'setuptools expects this to exit non-zero' my_app = dedent(""" def do_something(): return '%s' """ % error_msg) with temporary_content({ 'setup.py': setup_py, 'my_app.py': my_app }) as project_dir: installer = EggInstaller(project_dir) dist = DistributionHelper.distribution_from_path(installer.bdist()) so, rc = run_simple_pex_test('', env=make_env(PEX_SCRIPT='my_app'), dists=[dist]) assert so.decode('utf-8').strip() == error_msg assert rc == 1
def pex_with_entrypoints(entry_point): setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=[''], install_requires=['setuptools==36.2.7'], entry_points={'console_scripts': ['my_app_function = my_app:do_something', 'my_app_module = my_app']}, ) """) my_app = dedent(""" from setuptools.sandbox import run_setup def do_something(): return run_setup if __name__ == '__main__': do_something() """) with temporary_content({'setup.py': setup_py, 'my_app.py': my_app}) as project_dir: with temporary_dir() as out: pex = os.path.join(out, 'pex.pex') pex_command = ['--validate-entry-point', '-c', entry_point, project_dir, '-o', pex] results = run_pex_command(pex_command) results.assert_success() yield pex
def test_hash_consistency(): for reverse in (False, True): with temporary_content(CONTENT) as td: dir_hash = CacheHelper.dir_hash(td) with named_temporary_file() as tf: write_zipfile(td, tf.name, reverse=reverse) with contextlib.closing(zipfile.ZipFile(tf.name, 'r')) as zf: zip_hash = CacheHelper.zip_hash(zf) assert zip_hash == dir_hash assert zip_hash != sha1().hexdigest() # make sure it's not an empty hash
def test_hash_consistency(): for reverse in (False, True): with temporary_content(CONTENT) as td: dir_hash = CacheHelper.dir_hash(td) with named_temporary_file() as tf: write_zipfile(td, tf.name, reverse=reverse) with open_zip(tf.name, 'r') as zf: zip_hash = CacheHelper.zip_hash(zf) assert zip_hash == dir_hash assert zip_hash != sha1().hexdigest() # make sure it's not an empty hash
def test_pex_executable(): # type: () -> None # Tests that pex keeps executable permissions with temporary_dir() as temp_dir: pex_dir = os.path.join(temp_dir, "pex_dir") safe_mkdir(pex_dir) with open(os.path.join(pex_dir, "exe.py"), "w") as fp: fp.write( textwrap.dedent( """ import subprocess import os import sys import my_package path = os.path.join(os.path.dirname(my_package.__file__), 'bin/start.sh') sys.stdout.write(subprocess.check_output([path]).decode('utf-8')) """ ) ) project_content = { "setup.py": textwrap.dedent( """ from setuptools import setup setup( name='my_project', version='0.0.0.0', zip_safe=True, packages=['my_package'], package_data={'my_package': ['bin/*']}, install_requires=[], ) """ ), "my_package/__init__.py": 0, "my_package/bin/start.sh": ( "#!/usr/bin/env bash\n" "echo 'hello world from start.sh!'" ), "my_package/my_module.py": 'def do_something():\n print("hello world!")\n', } # type: Dict[str, Union[str, int]] pex_builder = PEXBuilder(path=pex_dir) with temporary_content(project_content, perms=0o755) as project_dir: installer = WheelBuilder(project_dir) bdist = installer.bdist() pex_builder.add_dist_location(bdist) pex_builder.set_executable(os.path.join(pex_dir, "exe.py")) pex_builder.freeze() app_pex = os.path.join(os.path.join(temp_dir, "out_pex_dir"), "app.pex") pex_builder.build(app_pex) std_out, rc = run_simple_pex(app_pex, env={"PEX_ROOT": os.path.join(temp_dir, ".pex")}) assert rc == 0 assert std_out.decode("utf-8") == "hello world from start.sh!\n"
def test_pex_executable(): # Tests that pex keeps executable permissions with temporary_dir() as temp_dir: pex_dir = os.path.join(temp_dir, 'pex_dir') safe_mkdir(pex_dir) with open(os.path.join(pex_dir, 'exe.py'), 'w') as fp: fp.write( textwrap.dedent(''' import subprocess import os import sys import my_package path = os.path.join(os.path.dirname(my_package.__file__), 'bin/start.sh') sys.stdout.write(subprocess.check_output([path]).decode('utf-8')) ''')) project_content = { 'setup.py': textwrap.dedent(''' from setuptools import setup setup( name='my_project', version='0.0.0.0', zip_safe=True, packages=['my_package'], package_data={'my_package': ['bin/*']}, install_requires=[], ) '''), 'my_package/__init__.py': 0, 'my_package/bin/start.sh': ("#!/usr/bin/env bash\n" "echo 'hello world from start.sh!'"), 'my_package/my_module.py': 'def do_something():\n print("hello world!")\n', } pex_builder = PEXBuilder(path=pex_dir) with temporary_content(project_content, perms=0o755) as project_dir: installer = WheelInstaller(project_dir) bdist = DistributionHelper.distribution_from_path( installer.bdist()) pex_builder.add_dist_location(bdist.location) pex_builder.set_executable(os.path.join(pex_dir, 'exe.py')) pex_builder.freeze() app_pex = os.path.join(os.path.join(temp_dir, 'out_pex_dir'), 'app.pex') pex_builder.build(app_pex) std_out, rc = run_simple_pex( app_pex, env={'PEX_ROOT': os.path.join(temp_dir, '.pex')}) assert rc == 0 assert std_out.decode('utf-8') == 'hello world from start.sh!\n'
def assert_pex_args_shebang(shebang): setup_py = bdist_pex_setup_py(name='my_app', version='0.0.0', zip_safe=True, packages=['']) with temporary_content({'setup.py': setup_py}) as project_dir: pex_args = '--pex-args=--python-shebang="{}"'.format(shebang) with bdist_pex(project_dir, bdist_args=[pex_args]) as my_app_pex: with open(my_app_pex, 'rb') as fp: assert fp.readline().decode().rstrip() == shebang
def pythonpath_isolation_test(): # type: () -> Iterator[PythonpathIsolationTest] with temporary_dir() as temp_dir: pythonpath = os.path.join(temp_dir, "one") with safe_open(os.path.join(pythonpath, "foo.py"), "w") as fp: fp.write("BAR = 42") with safe_open(os.path.join(pythonpath, "bar.py"), "w") as fp: fp.write("FOO = 137") dist_content = { "setup.py": textwrap.dedent( """ from setuptools import setup setup( name='foo', version='0.0.0', zip_safe=True, packages=['foo'], install_requires=[], ) """ ), "foo/__init__.py": "BAR = 137", } with temporary_content(dist_content) as project_dir: installer = WheelBuilder(project_dir) foo_bdist = installer.bdist() exe_contents = textwrap.dedent( """ import sys try: import bar except ImportError: import collections bar = collections.namedtuple('bar', ['FOO'])(None) import foo sys.stdout.write("foo.BAR={} bar.FOO={}".format(foo.BAR, bar.FOO)) """ ) yield PythonpathIsolationTest( pythonpath=pythonpath, dists=[foo_bdist], exe=exe_contents )
def test_pex_exit_code_propagation(): """Tests exit code propagation.""" test_stub = dedent(""" def test_fail(): assert False """) with temporary_content({'tester.py': test_stub}) as output_dir: pex_path = os.path.join(output_dir, 'test.pex') tester_path = os.path.join(output_dir, 'tester.py') results = run_pex_command( ['pytest==3.9.1', '-e', 'pytest:main', '-o', pex_path]) results.assert_success() assert subprocess.call([pex_path, os.path.realpath(tester_path)]) == 1
def test_unwriteable_contents(): my_app_setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=['my_app'], include_package_data=True, package_data={'my_app': ['unwriteable.so']}, ) """) UNWRITEABLE_PERMS = 0o400 with temporary_content({'setup.py': my_app_setup_py, 'my_app/__init__.py': '', 'my_app/unwriteable.so': ''}, perms=UNWRITEABLE_PERMS) as my_app_project_dir: my_app_whl = WheelInstaller(my_app_project_dir).bdist() uses_my_app_setup_py = bdist_pex_setup_py(name='uses_my_app', version='0.0.0', zip_safe=True, install_requires=['my_app']) with temporary_content({'setup.py': uses_my_app_setup_py}) as uses_my_app_project_dir: pex_args = '--pex-args=--disable-cache --no-pypi -f {}'.format(os.path.dirname(my_app_whl)) with bdist_pex(uses_my_app_project_dir, bdist_args=[pex_args]) as uses_my_app_pex: with open_zip(uses_my_app_pex) as zf: unwriteable_sos = [path for path in zf.namelist() if path.endswith('my_app/unwriteable.so')] assert 1 == len(unwriteable_sos) unwriteable_so = unwriteable_sos.pop() zf.extract(unwriteable_so, path=uses_my_app_project_dir) extract_dest = os.path.join(uses_my_app_project_dir, unwriteable_so) assert UNWRITEABLE_PERMS == stat.S_IMODE(os.stat(extract_dest).st_mode)
def pythonpath_isolation_test(): with temporary_dir() as temp_dir: pythonpath = os.path.join(temp_dir, 'one') with safe_open(os.path.join(pythonpath, 'foo.py'), 'w') as fp: fp.write('BAR = 42') with safe_open(os.path.join(pythonpath, 'bar.py'), 'w') as fp: fp.write('FOO = 137') dist_content = { 'setup.py': textwrap.dedent(""" from setuptools import setup setup( name='foo', version='0.0.0', zip_safe=True, packages=['foo'], install_requires=[], ) """), 'foo/__init__.py': 'BAR = 137', } with temporary_content(dist_content) as project_dir: installer = WheelInstaller(project_dir) foo_bdist = DistributionHelper.distribution_from_path( installer.bdist()) exe_contents = textwrap.dedent(""" import sys try: import bar except ImportError: import collections bar = collections.namedtuple('bar', ['FOO'])(None) import foo sys.stdout.write("foo.BAR={} bar.FOO={}".format(foo.BAR, bar.FOO)) """) yield PythonpathIsolationTest(pythonpath=pythonpath, dists=[foo_bdist], exe=exe_contents)
def assert_entry_points(entry_points): setup_py = bdist_pex_setup_py(name='my_app', version='0.0.0', zip_safe=True, packages=[''], entry_points=entry_points) my_app = dedent(""" def do_something(): print("hello world!") """) with temporary_content({'setup.py': setup_py, 'my_app.py': my_app}) as project_dir: with bdist_pex(project_dir) as my_app_pex: process = subprocess.Popen([my_app_pex], stdout=subprocess.PIPE) stdout, _ = process.communicate() assert '{pex_root}' not in os.listdir(project_dir) assert 0 == process.returncode assert stdout == b'hello world!\n'
def test_pex_manylinux_runtime(): """Tests resolver manylinux support and runtime resolution (and --platform=current).""" test_stub = dedent(""" import msgpack print(msgpack.unpackb(msgpack.packb([1, 2, 3]))) """) with temporary_content({'tester.py': test_stub}) as output_dir: pex_path = os.path.join(output_dir, 'test.pex') tester_path = os.path.join(output_dir, 'tester.py') results = run_pex_command([ '--disable-cache', '--no-build', 'msgpack-python==0.4.7', '--platform=current'.format(platform), '-o', pex_path ]) results.assert_success() out = subprocess.check_output([pex_path, tester_path]) assert out.strip() == '[1, 2, 3]'
def test_unwriteable_contents(): # type: () -> None my_app_setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=['my_app'], include_package_data=True, package_data={'my_app': ['unwriteable.so']}, ) """) UNWRITEABLE_PERMS = 0o400 with temporary_content( { "setup.py": my_app_setup_py, "my_app/__init__.py": "", "my_app/unwriteable.so": "so contents", }, perms=UNWRITEABLE_PERMS, ) as my_app_project_dir: my_app_whl = WheelBuilder(my_app_project_dir).bdist() with make_project(name="uses_my_app", install_reqs=["my_app"]) as uses_my_app_project_dir: pex_args = "--pex-args=--disable-cache --no-pypi -f {}".format( os.path.dirname(my_app_whl)) with bdist_pex(uses_my_app_project_dir, bdist_args=[pex_args]) as uses_my_app_pex: with open_zip(uses_my_app_pex) as zf: unwriteable_sos = [ path for path in zf.namelist() if path.endswith("my_app/unwriteable.so") ] assert 1 == len(unwriteable_sos) unwriteable_so = unwriteable_sos.pop() zf.extract(unwriteable_so, path=uses_my_app_project_dir) extract_dest = os.path.join(uses_my_app_project_dir, unwriteable_so) with open(extract_dest) as fp: assert "so contents" == fp.read()
def assert_entry_points(entry_points): setup_py = bdist_pex_setup_py(name='my_app', version='0.0.0', zip_safe=True, packages=[''], entry_points=entry_points) my_app = dedent(""" def do_something(): print("hello world!") """) with temporary_content({ 'setup.py': setup_py, 'my_app.py': my_app }) as project_dir: with bdist_pex(project_dir) as my_app_pex: process = subprocess.Popen([my_app_pex], stdout=subprocess.PIPE) stdout, _ = process.communicate() assert '{pex_root}' not in os.listdir(project_dir) assert 0 == process.returncode assert stdout == b'hello world!\n'
def assert_pex_args_shebang(shebang): setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=[''], ) """) with temporary_content({'setup.py': setup_py}) as project_dir: with pushd(project_dir): assert subprocess.check_call( [sys.executable, 'setup.py', 'bdist_pex', '--pex-args=--python-shebang="%(shebang)s"' % dict(shebang=shebang)]) == 0 with open(os.path.join(project_dir, 'dist', 'my_app-0.0.0.pex'), 'rb') as fp: assert fp.readline().decode().rstrip() == shebang
def assert_pex_args_shebang(shebang): setup_py = dedent(""" from setuptools import setup setup( name='my_app', version='0.0.0', zip_safe=True, packages=[''], ) """) with temporary_content({'setup.py': setup_py}) as project_dir: with pushd(project_dir): assert subprocess.check_call([ sys.executable, 'setup.py', 'bdist_pex', '--pex-args=--python-shebang="%(shebang)s"' % dict(shebang=shebang) ]) == 0 with open(os.path.join(project_dir, 'dist', 'my_app-0.0.0.pex'), 'rb') as fp: assert fp.readline().decode().rstrip() == shebang
def add_wheel(builder, content): # type: (PEXBuilder, Dict[str, str]) -> None with temporary_content(content) as project: dist = WheelBuilder(project, interpreter=builder.interpreter).bdist() builder.add_dist_location(dist)
def add_wheel(builder, content): with temporary_content(content) as project: dist = WheelInstaller(project, interpreter=builder.interpreter).bdist() builder.add_dist_location(dist)
def add_sources(builder, content): with temporary_content(content) as project: for path in content.keys(): builder.add_source(os.path.join(project, path), path)
def add_sources(builder, content): # type: (PEXBuilder, Dict[str, str]) -> None with temporary_content(content) as project: for path in content.keys(): builder.add_source(os.path.join(project, path), path)