add before test variable

This commit is contained in:
Grzegorz Bokota
2020-03-07 12:24:15 +01:00
committed by Grzegorz Bokota
parent ce5fc12b5f
commit 4e9316036c
9 changed files with 354 additions and 3 deletions
+2
View File
@@ -113,6 +113,7 @@ def main():
repair_command_default = ''
repair_command = get_option_from_environment('CIBW_REPAIR_WHEEL_COMMAND', platform=platform, default=repair_command_default)
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
before_test = get_option_from_environment('CIBW_BEFORE_TEST', platform=platform, default='')
if test_extras:
test_extras = '[{0}]'.format(test_extras)
@@ -154,6 +155,7 @@ def main():
build_selector=build_selector,
repair_command=repair_command,
environment=environment,
before_test=before_test
)
if platform == 'linux':
+8 -1
View File
@@ -68,7 +68,7 @@ def get_python_configurations(build_selector):
return [c for c in python_configurations if matches_platform(c.identifier) and build_selector(c.identifier)]
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, manylinux_images):
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_test, manylinux_images):
try:
subprocess.check_call(['docker', '--version'])
except Exception:
@@ -154,6 +154,10 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
echo "Running tests using `which python`"
if [ ! -z {before_test} ]; then
sh -c {before_test}
fi
# Install the wheel we just built
# Note: If auditwheel produced two wheels, it's because the earlier produced wheel
# conforms to multiple manylinux standards. These multiple versions of the wheel are
@@ -202,6 +206,9 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
environment_exports='\n'.join(environment.as_shell_commands()),
uid=os.getuid(),
gid=os.getgid(),
before_test=shlex_quote(
prepare_command(before_test, project='/project') if before_test else ''
),
)
container_name = 'cibuildwheel-{}'.format(uuid.uuid4())
+5 -1
View File
@@ -105,7 +105,7 @@ def install_pypy(version, url):
return installation_bin_path
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment):
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_test):
abs_project_dir = os.path.abspath(project_dir)
temp_dir = tempfile.mkdtemp(prefix='cibuildwheel')
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
@@ -214,6 +214,10 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
# check that we are using the Python from the virtual environment
call(['which', 'python'], env=virtualenv_env)
if before_test:
before_test_prepared = prepare_command(before_test, project=abs_project_dir)
call(before_test_prepared, env=virtualenv_env, shell=True)
# install the wheel
call(['pip', 'install', repaired_wheel + test_extras], env=virtualenv_env)
+5 -1
View File
@@ -87,7 +87,7 @@ def install_pypy(version, arch, url):
return installation_path
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment):
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, before_test):
abs_project_dir = os.path.abspath(project_dir)
temp_dir = tempfile.mkdtemp(prefix='cibuildwheel')
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
@@ -193,6 +193,10 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
# check that we are using the Python from the virtual environment
shell(['which', 'python'], env=virtualenv_env)
if before_test:
before_test_prepared = prepare_command(before_test, project=abs_project_dir)
shell([before_test_prepared], env=virtualenv_env)
# install the wheel
shell(['pip', 'install', repaired_wheel + test_extras], env=virtualenv_env)
+22
View File
@@ -0,0 +1,22 @@
import os
import utils
def test():
project_dir = os.path.dirname(__file__)
# build the wheels
actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
# write python version information to a temporary file, this is
# checked in setup.py
'CIBW_BEFORE_TEST': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)"''',
'CIBW_BEFORE_TEST_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)"''',
'CIBW_TEST_REQUIRES': 'nose',
# the 'false ||' bit is to ensure this command runs in a shell on
# mac/linux.
'CIBW_TEST_COMMAND': 'false || nosetests {project}/test',
'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test',
})
# also check that we got the right wheels
expected_wheels = utils.expected_wheels('spam', '0.1.0')
assert set(actual_wheels) == set(expected_wheels)
+19
View File
@@ -0,0 +1,19 @@
from setuptools import setup, Extension
import sys, os
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step
# is the same one as is currently running.
version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt'
if os.path.exists(version_file):
os.remove(version_file)
# check that the executable also was written
executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt'
if os.path.exists(executable_file):
os.remove(executable_file)
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
+48
View File
@@ -0,0 +1,48 @@
#include <Python.h>
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return PyLong_FromLong(sts);
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
MOD_INIT(spam)
{
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
+24
View File
@@ -0,0 +1,24 @@
import sys, os
from unittest import TestCase
class TestBeforeTest(TestCase):
def test_version(self):
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step
# is the same one as is currently running.
version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt'
with open(version_file) as f:
stored_version = f.read()
print('stored_version', stored_version)
print('sys.version', sys.version)
assert stored_version == sys.version
def test_executable(self):
# check that the executable also was written
executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt'
with open(executable_file) as f:
stored_executable = f.read()
print('stored_executable', stored_executable)
print('sys.executable', sys.executable)
# windows/mac are case insensitive
assert os.path.realpath(stored_executable).lower() == os.path.realpath(sys.executable).lower()
+221
View File
@@ -0,0 +1,221 @@
import pytest
import sys
from cibuildwheel.__main__ import main
from cibuildwheel.environment import ParsedEnvironment
from cibuildwheel.util import BuildSelector
from main_util_fixtures import mock_protection, fake_project_dir, platform, intercepted_build_args
# CIBW_PLATFORM is tested in main_platform_test.py
def test_output_dir(platform, intercepted_build_args, monkeypatch):
OUTPUT_DIR = 'some_output_dir'
monkeypatch.setenv('CIBW_OUTPUT_DIR', OUTPUT_DIR)
main()
assert intercepted_build_args.kwargs['output_dir'] == OUTPUT_DIR
def test_output_dir_default(platform, intercepted_build_args, monkeypatch):
main()
assert intercepted_build_args.kwargs['output_dir'] == 'wheelhouse'
@pytest.mark.parametrize('also_set_environment', [False, True])
def test_output_dir_argument(also_set_environment, platform, intercepted_build_args, monkeypatch):
OUTPUT_DIR = 'some_output_dir'
monkeypatch.setattr(sys, 'argv', sys.argv + ['--output-dir', OUTPUT_DIR])
if also_set_environment:
monkeypatch.setenv('CIBW_OUTPUT_DIR', 'not_this_output_dir')
main()
assert intercepted_build_args.kwargs['output_dir'] == OUTPUT_DIR
def test_build_selector(platform, intercepted_build_args, monkeypatch):
BUILD = 'some build* *-selector'
SKIP = 'some skip* *-selector'
monkeypatch.setenv('CIBW_BUILD', BUILD)
monkeypatch.setenv('CIBW_SKIP', SKIP)
main()
intercepted_build_selector = intercepted_build_args.kwargs['build_selector']
assert isinstance(intercepted_build_selector, BuildSelector)
assert intercepted_build_selector('build-this')
assert not intercepted_build_selector('skip-that')
# This unit test is just testing the options of 'main'
# Unit tests for BuildSelector are in build_selector_test.py
@pytest.mark.parametrize('architecture, image, full_image', [
('x86_64', None, 'quay.io/pypa/manylinux2010_x86_64'),
('x86_64', 'manylinux1', 'quay.io/pypa/manylinux1_x86_64'),
('x86_64', 'manylinux2010', 'quay.io/pypa/manylinux2010_x86_64'),
('x86_64', 'manylinux2014', 'quay.io/pypa/manylinux2014_x86_64'),
('x86_64', 'custom_image', 'custom_image'),
('i686', None, 'quay.io/pypa/manylinux2010_i686'),
('i686', 'manylinux1', 'quay.io/pypa/manylinux1_i686'),
('i686', 'manylinux2010', 'quay.io/pypa/manylinux2010_i686'),
('i686', 'manylinux2014', 'quay.io/pypa/manylinux2014_i686'),
('i686', 'custom_image', 'custom_image'),
])
def test_manylinux_images(architecture, image, full_image, platform, intercepted_build_args, monkeypatch):
if image is not None:
monkeypatch.setenv('CIBW_MANYLINUX_' + architecture.upper() + '_IMAGE', image)
main()
if platform == 'linux':
assert intercepted_build_args.kwargs['manylinux_images'][architecture] == full_image
else:
assert 'manylinux_images' not in intercepted_build_args.kwargs
def get_default_repair_command(platform):
if platform == 'linux':
return 'auditwheel repair -w {dest_dir} {wheel}'
elif platform == 'macos':
return 'delocate-listdeps {wheel} && delocate-wheel -w {dest_dir} {wheel}'
elif platform == 'windows':
return ''
else:
raise ValueError('Unknown platform', platform)
@pytest.mark.parametrize('repair_command', [None, 'repair', 'repair -w {dest_dir} {wheel}'])
@pytest.mark.parametrize('platform_specific', [False, True])
def test_repair_command(repair_command, platform_specific, platform, intercepted_build_args, monkeypatch):
if repair_command is not None:
if platform_specific:
monkeypatch.setenv('CIBW_REPAIR_WHEEL_COMMAND_' + platform.upper(), repair_command)
monkeypatch.setenv('CIBW_REPAIR_WHEEL_COMMAND', 'overwritten')
else:
monkeypatch.setenv('CIBW_REPAIR_WHEEL_COMMAND', repair_command)
main()
expected_repair = repair_command or get_default_repair_command(platform)
assert intercepted_build_args.kwargs['repair_command'] == expected_repair
@pytest.mark.parametrize('environment', [
{},
{'something': 'value'},
{'something': 'value', 'something_else': 'other_value'}
])
@pytest.mark.parametrize('platform_specific', [False, True])
def test_environment(environment, platform_specific, platform, intercepted_build_args, monkeypatch):
env_string = ' '.join(['{}={}'.format(k, v) for k, v in environment.items()])
if platform_specific:
monkeypatch.setenv('CIBW_ENVIRONMENT_' + platform.upper(), env_string)
monkeypatch.setenv('CIBW_ENVIRONMENT', 'overwritten')
else:
monkeypatch.setenv('CIBW_ENVIRONMENT', env_string)
main()
intercepted_environment = intercepted_build_args.kwargs['environment']
assert isinstance(intercepted_environment, ParsedEnvironment)
assert intercepted_environment.as_dictionary(prev_environment={}) == environment
@pytest.mark.parametrize('test_requires', [None, 'requirement other_requirement'])
@pytest.mark.parametrize('platform_specific', [False, True])
def test_test_requires(test_requires, platform_specific, platform, intercepted_build_args, monkeypatch):
if test_requires is not None:
if platform_specific:
monkeypatch.setenv('CIBW_TEST_REQUIRES_' + platform.upper(), test_requires)
monkeypatch.setenv('CIBW_TEST_REQUIRES', 'overwritten')
else:
monkeypatch.setenv('CIBW_TEST_REQUIRES', test_requires)
main()
assert intercepted_build_args.kwargs['test_requires'] == (test_requires or '').split()
@pytest.mark.parametrize('test_extras', [None, 'extras'])
@pytest.mark.parametrize('platform_specific', [False, True])
def test_test_extras(test_extras, platform_specific, platform, intercepted_build_args, monkeypatch):
if test_extras is not None:
if platform_specific:
monkeypatch.setenv('CIBW_TEST_EXTRAS_' + platform.upper(), test_extras)
monkeypatch.setenv('CIBW_TEST_EXTRAS', 'overwritten')
else:
monkeypatch.setenv('CIBW_TEST_EXTRAS', test_extras)
main()
assert intercepted_build_args.kwargs['test_extras'] == ('[' + test_extras + ']' if test_extras else '')
@pytest.mark.parametrize('test_command', [None, 'test --command'])
@pytest.mark.parametrize('platform_specific', [False, True])
def test_test_command(test_command, platform_specific, platform, intercepted_build_args, monkeypatch):
if test_command is not None:
if platform_specific:
monkeypatch.setenv('CIBW_TEST_COMMAND_' + platform.upper(), test_command)
monkeypatch.setenv('CIBW_TEST_COMMAND', 'overwritten')
else:
monkeypatch.setenv('CIBW_TEST_COMMAND', test_command)
main()
assert intercepted_build_args.kwargs['test_command'] == test_command
@pytest.mark.parametrize('before_build', [None, 'before --build'])
@pytest.mark.parametrize('platform_specific', [False, True])
def test_before_build(before_build, platform_specific, platform, intercepted_build_args, monkeypatch):
if before_build is not None:
if platform_specific:
monkeypatch.setenv('CIBW_BEFORE_BUILD_' + platform.upper(), before_build)
monkeypatch.setenv('CIBW_BEFORE_BUILD', 'overwritten')
else:
monkeypatch.setenv('CIBW_BEFORE_BUILD', before_build)
main()
assert intercepted_build_args.kwargs['before_build'] == before_build
@pytest.mark.parametrize('build_verbosity', [None, 0, 2, -2, 4, -4])
@pytest.mark.parametrize('platform_specific', [False, True])
def test_build_verbosity(build_verbosity, platform_specific, platform, intercepted_build_args, monkeypatch):
if build_verbosity is not None:
if platform_specific:
monkeypatch.setenv('CIBW_BUILD_VERBOSITY_' + platform.upper(), str(build_verbosity))
monkeypatch.setenv('CIBW_BUILD_VERBOSITY', 'overwritten')
else:
monkeypatch.setenv('CIBW_BUILD_VERBOSITY', str(build_verbosity))
main()
expected_verbosity = max(-3, min(3, int(build_verbosity or 0)))
assert intercepted_build_args.kwargs['build_verbosity'] == expected_verbosity
@pytest.mark.parametrize('before_test', ["", 'before --test'])
@pytest.mark.parametrize('platform_specific', [False, True])
def test_before_test(before_test, platform_specific, platform, intercepted_build_args, monkeypatch):
if before_test is not None:
if platform_specific:
monkeypatch.setenv('CIBW_BEFORE_TEST_' + platform.upper(), before_test)
monkeypatch.setenv('CIBW_BEFORE_TEST', 'overwritten')
else:
monkeypatch.setenv('CIBW_BEFORE_TEST', before_test)
main()
assert intercepted_build_args.kwargs['before_test'] == before_test