def test_push_dir(tmpdir): assert os.path.split(os.getcwd())[-1] == 'tests' from skbuild.utils import push_dir # No directory with push_dir(): os.chdir(os.path.join(os.getcwd(), '..')) assert os.path.split(os.getcwd())[-1] == 'scikit-build' assert os.path.split(os.getcwd())[-1] == 'tests' # With existing directory with push_dir(directory=os.path.join(os.getcwd(), '..')): assert os.path.split(os.getcwd())[-1] == 'scikit-build' assert os.path.split(os.getcwd())[-1] == 'tests' foo_directory = os.path.join(str(tmpdir), 'foo') # With non existing directory failed = False try: with push_dir(directory=foo_directory): pass except OSError: failed = True assert failed assert not os.path.isdir(foo_directory) # With make_directory option with push_dir(directory=foo_directory, make_directory=True): assert os.getcwd() == foo_directory assert os.path.split(os.getcwd())[-1] == 'tests' assert os.path.isdir(foo_directory)
def test_outside_project_root_fails(option): with push_dir(): expected_failure = False cmd = ["install"] if option is not None: expected_failure = True cmd.extend(["--", option]) @project_setup_py_test(("samples", "fail-outside-project-root"), cmd, clear_cache=True) def should_fail(): pass failed = False msg = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) msg = str(e) except SKBuildError as e: failed = True msg = str(e) assert expected_failure == failed if expected_failure: assert "CMake-installed files must be within the project root." in msg
def wrapped(*iargs, **ikwargs): # Clear distutils.dir_util.mkpath() cache # See issue scikit-build#120 distutils.dir_util._path_created = {} dir = list(wrapped.project) dir.insert(0, os.path.dirname(os.path.abspath(__file__))) dir = os.path.join(*dir) with push_dir(dir), push_argv(["setup.py"] + wrapped.setup_args): if wrapped.clear_cache: # XXX We assume dist_dir is not customized dest_dir = 'dist' for dir_to_remove in [SKBUILD_DIR, dest_dir]: if os.path.exists(dir_to_remove): shutil.rmtree(dir_to_remove) setup_code = None with open("setup.py", "r") as fp: setup_code = compile(fp.read(), "setup.py", mode="exec") if setup_code is not None: six.exec_(setup_code) result2 = fun(*iargs, **ikwargs) return result2
def test_invalid_cmake(exception, mocker): exceptions = { OSError: OSError('Unknown error'), CalledProcessError: CalledProcessError(['cmake', '--version'], 1) } mocker.patch('subprocess.check_call', side_effect=exceptions[exception]) with push_dir(): @project_setup_py_test(("samples", "hello"), ["build"], clear_cache=True) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) assert failed assert "Problem with the CMake installation, aborting build." in message
def test_hello_builds_with_generator(generator_args): with push_dir(): build_args = ["build"] build_args.extend(generator_args) @project_setup_py_test(("samples", "hello"), build_args, clear_cache=True) def run(): pass failed = False message = "" try: run() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) if 'invalid' in generator_args: assert failed assert "Could not get working generator for your system." \ " Aborting build." in message else: assert not failed
def initialize_git_repo_and_commit(project_dir, verbose=True): """Convenience function creating a git repository in ``project_dir``. If ``project_dir`` does NOT contain a ``.git`` directory, a new git repository with one commit containing all the directories and files is created. """ if isinstance(project_dir, six.string_types): project_dir = py.path.local(project_dir) if project_dir.join('.git').exists(): return # If any, exclude virtualenv files project_dir.join(".gitignore").write(".env") with push_dir(str(project_dir)): for cmd in [ ['git', 'init'], ['git', 'config', 'user.name', 'scikit-build'], ['git', 'config', 'user.email', 'test@test'], ['git', 'add', '-A'], ['git', 'reset', '.gitignore'], ['git', 'commit', '-m', 'Initial commit'] ]: do_call = (subprocess.check_call if verbose else subprocess.check_output) do_call(cmd)
def test_invalid_generator(mocker, capfd): platform = get_platform() mocker.patch.object(type(platform), 'default_generators', new_callable=mocker.PropertyMock, return_value=[CMakeGenerator('Invalid')]) mocker.patch('skbuild.cmaker.get_platform', return_value=platform) with push_dir(), push_env(CMAKE_GENERATOR=None): @project_setup_py_test("hello", ["build"]) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) _, err = capfd.readouterr() assert "CMake Error: Could not create named generator Invalid" in err assert failed assert "scikit-build could not get a working generator for your system." \ " Aborting build." in message
def test_invalid_cmake(exception, mocker): exceptions = { OSError: OSError('Unknown error'), CalledProcessError: CalledProcessError(['cmake', '--version'], 1) } check_call_original = check_call def check_call_mock(*args, **kwargs): if args[0] == ['cmake', '--version']: raise exceptions[exception] check_call_original(*args, **kwargs) mocker.patch('skbuild.cmaker.subprocess.check_call', new=check_call_mock) with push_dir(): @project_setup_py_test("hello", ["build"]) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) assert failed assert "Problem with the CMake installation, aborting build." in message
def test_invalid_cmake(exception, mocker): exceptions = { OSError: OSError('Unknown error'), CalledProcessError: CalledProcessError(['cmake', '--version'], 1) } check_output_original = check_output def check_output_mock(*args, **kwargs): if args[0] == ['cmake', '--version']: raise exceptions[exception] check_output_original(*args, **kwargs) mocker.patch('skbuild.cmaker.subprocess.check_output', new=check_output_mock) with push_dir(): @project_setup_py_test("hello-no-language", ["build"], disable_languages_test=True) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) assert failed assert "Problem with the CMake installation, aborting build." in message
def test_hello_cleans(capfd): with push_dir(): tmp_dir = _tmpdir("test_hello_cleans") _copy_dir(tmp_dir, os.path.join(SAMPLES_DIR, "hello-cpp")) @project_setup_py_test("hello-cpp", ["build"], tmp_dir=tmp_dir) def run_build(): pass @project_setup_py_test("hello-cpp", ["clean"], tmp_dir=tmp_dir) def run_clean(): pass # Check that a project can be cleaned twice in a row run_build() print("<<-->>") run_clean() print("<<-->>") run_clean() _, clean1_out, clean2_out = \ capfd.readouterr()[0].split('<<-->>') clean1_out = clean1_out.strip() clean2_out = clean2_out.strip() assert "running clean" == clean1_out.splitlines()[0] assert "removing '{}'".format(CMAKE_INSTALL_DIR) == clean1_out.splitlines()[1] assert "removing '{}'".format(CMAKE_BUILD_DIR) == clean1_out.splitlines()[2] assert "removing '{}'".format(SKBUILD_DIR) == clean1_out.splitlines()[3] assert "running clean" == clean2_out
def test_invalid_generator(mocker, capfd): platform = get_platform() mocker.patch.object(type(platform), 'default_generators', new_callable=mocker.PropertyMock, return_value=[CMakeGenerator('Invalid')]) mocker.patch('skbuild.cmaker.get_platform', return_value=platform) with push_dir(), push_env(CMAKE_GENERATOR=None): @project_setup_py_test("hello-no-language", ["build"]) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) _, err = capfd.readouterr() assert "CMake Error: Could not create named generator Invalid" in err assert failed assert "scikit-build could not get a working generator for your system." \ " Aborting build." in message
def test_hello_clean(capfd): with push_dir(): skbuild_dir = os.path.join( "tests", "samples", "hello-pure", SKBUILD_DIR) @project_setup_py_test(("samples", "hello-pure"), ["build"], clear_cache=True) def run_build(): pass run_build() assert os.path.exists(skbuild_dir) @project_setup_py_test(("samples", "hello-pure"), ["clean"]) def run_clean(): pass run_clean() assert not os.path.exists(skbuild_dir) out = capfd.readouterr()[0] assert 'Build files have been written to' not in out
def test_outside_project_root_fails(option): with push_dir(): expected_failure = False cmd = ["install"] if option is not None: expected_failure = True cmd.extend(["--", option]) @project_setup_py_test("fail-outside-project-root", cmd) def should_fail(): pass failed = False msg = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) msg = str(e) except SKBuildError as e: failed = True msg = str(e) assert expected_failure == failed if expected_failure: assert "CMake-installed files must be within the project root." in msg
def initialize_git_repo_and_commit(project_dir, verbose=True): """Convenience function creating a git repository in ``project_dir``. If ``project_dir`` does NOT contain a ``.git`` directory, a new git repository with one commit containing all the directories and files is created. """ if isinstance(project_dir, six.string_types): project_dir = py.path.local(project_dir) if project_dir.join('.git').exists(): return # If any, exclude virtualenv files project_dir.join(".gitignore").write(".env") with push_dir(str(project_dir)): for cmd in [['git', 'init'], ['git', 'config', 'user.name', 'scikit-build'], ['git', 'config', 'user.email', 'test@test'], ['git', 'add', '-A'], ['git', 'reset', '.gitignore'], ['git', 'commit', '-m', 'Initial commit']]: do_call = (subprocess.check_call if verbose else subprocess.check_output) do_call(cmd)
def test_hello_cleans(capfd): with push_dir(): @project_setup_py_test(("samples", "hello"), ["build"], clear_cache=True) def run_build(): pass @project_setup_py_test(("samples", "hello"), ["clean"]) def run_clean(): pass # Check that a project can be cleaned twice in a row run_build() print("<<-->>") run_clean() print("<<-->>") run_clean() _, clean1_out, clean2_out = \ capfd.readouterr()[0].split('<<-->>') clean1_out = clean1_out.strip() clean2_out = clean2_out.strip() assert "running clean" == clean1_out.splitlines()[0] assert "removing '_skbuild{}cmake-install'".format(os.path.sep) \ == clean1_out.splitlines()[1] assert "removing '_skbuild{}cmake-build'".format(os.path.sep) \ == clean1_out.splitlines()[2] assert "removing '_skbuild'" == clean1_out.splitlines()[3] assert "running clean" == clean2_out
def test_hello_cleans(capfd): with push_dir(): tmp_dir = _tmpdir("test_hello_cleans") _copy_dir(tmp_dir, os.path.join(SAMPLES_DIR, "hello-cpp")) @project_setup_py_test("hello-cpp", ["build"], tmp_dir=tmp_dir) def run_build(): pass @project_setup_py_test("hello-cpp", ["clean"], tmp_dir=tmp_dir) def run_clean(): pass # Check that a project can be cleaned twice in a row run_build() print("<<-->>") run_clean() print("<<-->>") run_clean() _, clean1_out, clean2_out = \ capfd.readouterr()[0].split('<<-->>') clean1_out = clean1_out.strip() clean2_out = clean2_out.strip() assert "running clean" == clean1_out.splitlines()[0] assert "removing '{}'".format(CMAKE_INSTALL_DIR()) == clean1_out.splitlines()[1] assert "removing '{}'".format(CMAKE_BUILD_DIR()) == clean1_out.splitlines()[2] assert "removing '{}'".format(SKBUILD_DIR()) == clean1_out.splitlines()[3] assert "running clean" == clean2_out
def test_make_without_configure_fails(capfd): src_dir = _tmpdir('test_make_without_configure_fails') src_dir.ensure(CMAKE_BUILD_DIR, dir=1) with push_dir(str(src_dir)), pytest.raises(SKBuildError) as excinfo: CMaker().make() _, err = capfd.readouterr() assert "An error occurred while building with CMake." in str(excinfo.value) assert "Error: could not load cache" in err
def test_make(configure_with_cmake_source_dir, capfd): tmp_dir = _tmpdir('test_make') with push_dir(str(tmp_dir)): src_dir = tmp_dir.ensure('SRC', dir=1) src_dir.join('CMakeLists.txt').write(textwrap.dedent( """ cmake_minimum_required(VERSION 3.5.0) project(foobar NONE) file(WRITE "${CMAKE_BINARY_DIR}/foo.txt" "# foo") install(FILES "${CMAKE_BINARY_DIR}/foo.txt" DESTINATION ".") install(CODE "message(STATUS \\"Project has been installed\\")") message(STATUS "CMAKE_SOURCE_DIR:${CMAKE_SOURCE_DIR}") message(STATUS "CMAKE_BINARY_DIR:${CMAKE_BINARY_DIR}") """ )) src_dir.ensure(CMAKE_BUILD_DIR, dir=1) with push_dir(str(src_dir) if not configure_with_cmake_source_dir else str(tmp_dir.ensure('BUILD', dir=1))): cmkr = CMaker() config_kwargs = {} if configure_with_cmake_source_dir: config_kwargs['cmake_source_dir'] = str(src_dir) env = cmkr.configure(**config_kwargs) cmkr.make(env=env) messages = ["Project has been installed"] if configure_with_cmake_source_dir: messages += [ "/SRC", "/BUILD/{}".format(to_unix_path(CMAKE_BUILD_DIR)), "/BUILD/{}/./foo.txt".format(to_unix_path(CMAKE_INSTALL_DIR)) ] else: messages += [ "/SRC", "/SRC/{}".format(to_unix_path(CMAKE_BUILD_DIR)), "/SRC/{}/./foo.txt".format(to_unix_path(CMAKE_INSTALL_DIR)), ] out, _ = capfd.readouterr() for message in messages: assert message in out
def test_check_for_bad_installs(tmpdir): with push_dir(str(tmpdir)): tmpdir.ensure(CMAKE_BUILD_DIR(), "cmake_install.cmake").write(textwrap.dedent( """ file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/../hello" TYPE FILE FILES "/path/to/hello/world.py") """ )) with pytest.raises(SKBuildError) as excinfo: CMaker.check_for_bad_installs() assert "CMake-installed files must be within the project root" in str(excinfo.value)
def test_distribution_is_pure(distribution_type, tmpdir): skbuild_setup_kwargs = {} if distribution_type == 'unknown': is_pure = False elif distribution_type == 'py_modules': is_pure = True hello_py = tmpdir.join("hello.py") hello_py.write("") skbuild_setup_kwargs["py_modules"] = ["hello"] elif distribution_type == 'packages': is_pure = True init_py = tmpdir.mkdir("hello").join("__init__.py") init_py.write("") skbuild_setup_kwargs["packages"] = ["hello"] elif distribution_type == 'skbuild': is_pure = False cmakelists_txt = tmpdir.join("CMakeLists.txt") cmakelists_txt.write( """ cmake_minimum_required(VERSION 3.5.0) project(test NONE) install(CODE "execute_process( COMMAND \${CMAKE_COMMAND} -E sleep 0)") """ ) else: raise Exception( "Unknown distribution_type: {}".format(distribution_type)) platform = get_platform() original_write_test_cmakelist = platform.write_test_cmakelist def write_test_cmakelist_no_languages(_self, _languages): original_write_test_cmakelist([]) with patch.object(type(platform), 'write_test_cmakelist', new=write_test_cmakelist_no_languages): with push_dir(str(tmpdir)), push_argv(["setup.py", "build"]): distribution = skbuild_setup( name="test", version="0.0.1", description="test object returned by setup function", author="The scikit-build team", license="MIT", **skbuild_setup_kwargs ) assert issubclass(distribution.__class__, (distutils_Distribution, setuptool_Distribution)) assert is_pure == distribution.is_pure()
def test_hello_builds(): with push_dir(): @project_setup_py_test(("samples", "hello"), ["build"], clear_cache=True) def run(): pass # Check that a project can be build twice in a row # See issue scikit-build#120 run() run()
def test_configure_with_cmake_args(capfd): tmp_dir = _tmpdir('test_configure_with_cmake_args') with push_dir(str(tmp_dir)): tmp_dir.join('CMakeLists.txt').write(textwrap.dedent( """ cmake_minimum_required(VERSION 3.5.0) project(foobar NONE) # Do not complain about missing arguments passed to the main # project foreach(unused_var IN ITEMS ${CMAKE_EXPECTED_BAR} ${CMAKE_EXPECTED_FOO} ${PYTHON_EXECUTABLE} ${PYTHON_INCLUDE_DIR} ${PYTHON_LIBRARY} ${PYTHON_VERSION_STRING} ${SKBUILD} ) endforeach() """ )) with push_dir(str(tmp_dir)): cmkr = CMaker() cmkr.configure(clargs=[ '-DCMAKE_EXPECTED_FOO:STRING=foo', '-DCMAKE_EXPECTED_BAR:STRING=bar' ], cleanup=False) cmakecache = tmp_dir.join( "_cmake_test_compile", "build", "CMakeCache.txt") assert cmakecache.exists() variables = get_cmakecache_variables(str(cmakecache)) assert variables.get('CMAKE_EXPECTED_FOO', (None, None))[1] == "foo" assert variables.get('CMAKE_EXPECTED_BAR', (None, None))[1] == "bar" unexpected = "Manually-specified variables were not used by the project" _, err = capfd.readouterr() assert unexpected not in err
def test_push_dir(tmpdir): old_cwd = os.getcwd() try: level1 = tmpdir.mkdir("level1") level2 = level1.mkdir("level2") os.chdir(str(level2)) assert os.path.split(os.getcwd())[-1] == 'level2' # No directory with push_dir(): os.chdir(os.path.join(os.getcwd(), '..')) assert os.path.split(os.getcwd())[-1] == 'level1' assert os.path.split(os.getcwd())[-1] == 'level2' # With existing directory with push_dir(directory=os.path.join(os.getcwd(), '..')): assert os.path.split(os.getcwd())[-1] == 'level1' assert os.path.split(os.getcwd())[-1] == 'level2' foo_directory = os.path.join(str(tmpdir), 'foo') # With non existing directory failed = False try: with push_dir(directory=foo_directory): pass except OSError: failed = True assert failed assert not os.path.isdir(foo_directory) # With make_directory option with push_dir(directory=foo_directory, make_directory=True): assert os.getcwd() == foo_directory assert os.path.split(os.getcwd())[-1] == 'level2' assert os.path.isdir(foo_directory) finally: os.chdir(old_cwd)
def test_too_many_separators(): with push_dir(): @project_setup_py_test("hello-no-language", ["--"] * 3, disable_languages_test=True) def run(): pass failed = False try: run() except SystemExit as e: failed = e.args[0].startswith('ERROR: Too many') assert failed
def test_too_many_separators(): with push_dir(): @project_setup_py_test("hello", ["--"] * 3) def run(): pass failed = False try: run() except SystemExit as e: failed = e.args[0].startswith('ERROR: Too many') assert failed
def test_too_many_separators(): with push_dir(): @project_setup_py_test(("samples", "hello"), ["--"] * 3) def run(): pass failed = False try: run() except SystemExit as e: failed = e.args[0].startswith('ERROR: Too many') assert failed
def test_no_command(): with push_dir(): @project_setup_py_test("hello", []) def run(): pass failed = False try: run() except SystemExit as e: failed = 'error: no commands supplied' in e.args[0] assert failed assert not os.path.exists('_skbuild')
def test_no_command(): with push_dir(): @project_setup_py_test("hello-no-language", [], disable_languages_test=True) def run(): pass failed = False try: run() except SystemExit as e: failed = 'error: no commands supplied' in e.args[0] assert failed assert not os.path.exists('_skbuild')
def test_invalid_command(): with push_dir(): @project_setup_py_test("hello", ["unknown"]) def run(): pass failed = False try: run() except SystemExit as e: failed = 'error: invalid command' in e.args[0] assert failed assert not os.path.exists('_skbuild')
def test_no_command(): with push_dir(): @project_setup_py_test(("samples", "hello"), [], clear_cache=True) def run(): pass failed = False try: run() except SystemExit as e: failed = 'error: no commands supplied' in e.args[0] assert failed assert not os.path.exists('_skbuild')
def test_hello_builds(): with push_dir(): @project_setup_py_test("hello-cpp", ["build"]) def run(): pass # Check that a project can be build twice in a row # See issue scikit-build#120 tmp_dir = run()[0] @project_setup_py_test("hello-cpp", ["build"], tmp_dir=tmp_dir) def another_run(): pass another_run()
def test_hello_builds(): with push_dir(): @project_setup_py_test("hello", ["build"]) def run(): pass # Check that a project can be build twice in a row # See issue scikit-build#120 tmp_dir = run()[0] @project_setup_py_test("hello", ["build"], tmp_dir=tmp_dir) def another_run(): pass another_run()
def execute_setup_py(project_dir, setup_args, disable_languages_test=False): """Context manager executing ``setup.py`` with the given arguments. It yields after changing the current working directory to ``project_dir``. """ # See https://stackoverflow.com/questions/9160227/dir-util-copy-tree-fails-after-shutil-rmtree distutils.dir_util._path_created = {} # Clear _PYTHON_HOST_PLATFORM to ensure value sets in skbuild.setuptools_wrap.setup() does not # influence other tests. if '_PYTHON_HOST_PLATFORM' in os.environ: del os.environ['_PYTHON_HOST_PLATFORM'] with push_dir(str(project_dir)), push_argv(["setup.py"] + setup_args), prepend_sys_path( [str(project_dir)]): # Restore master working set that is reset following call to "python setup.py test" # See function "project_on_sys_path()" in setuptools.command.test pkg_resources._initialize_master_working_set() with open("setup.py", "r") as fp: setup_code = compile(fp.read(), "setup.py", mode="exec") if setup_code is not None: if disable_languages_test: platform = get_platform() original_write_test_cmakelist = platform.write_test_cmakelist def write_test_cmakelist_no_languages(_self, _languages): original_write_test_cmakelist([]) with patch.object(type(platform), 'write_test_cmakelist', new=write_test_cmakelist_no_languages): six.exec_(setup_code) else: six.exec_(setup_code) yield
def execute_setup_py(project_dir, setup_args): """Context manager executing ``setup.py`` with the given arguments. It yields after changing the current working directory to ``project_dir``. """ with push_dir(str(project_dir)), \ push_argv(["setup.py"] + setup_args): setup_code = None with open("setup.py", "r") as fp: setup_code = compile(fp.read(), "setup.py", mode="exec") if setup_code is not None: six.exec_(setup_code) yield
def test_first_invalid_generator(mocker, capfd): platform = get_platform() default_generators = [CMakeGenerator('Invalid')] default_generators.extend(platform.default_generators) mocker.patch.object(type(platform), 'default_generators', new_callable=mocker.PropertyMock, return_value=default_generators) mocker.patch('skbuild.cmaker.get_platform', return_value=platform) with push_dir(), push_env(CMAKE_GENERATOR=None): @project_setup_py_test("hello-no-language", ["build"]) def run_build(): pass run_build() _, err = capfd.readouterr() assert "CMake Error: Could not create named generator Invalid" in err
def execute_setup_py(project_dir, setup_args, disable_languages_test=False): """Context manager executing ``setup.py`` with the given arguments. It yields after changing the current working directory to ``project_dir``. """ # See https://stackoverflow.com/questions/9160227/dir-util-copy-tree-fails-after-shutil-rmtree distutils.dir_util._path_created = {} # Clear _PYTHON_HOST_PLATFORM to ensure value sets in skbuild.setuptools_wrap.setup() does not # influence other tests. if '_PYTHON_HOST_PLATFORM' in os.environ: del os.environ['_PYTHON_HOST_PLATFORM'] with push_dir(str(project_dir)), push_argv(["setup.py"] + setup_args), prepend_sys_path([str(project_dir)]): # Restore master working set that is reset following call to "python setup.py test" # See function "project_on_sys_path()" in setuptools.command.test pkg_resources._initialize_master_working_set() with open("setup.py", "r") as fp: setup_code = compile(fp.read(), "setup.py", mode="exec") if setup_code is not None: if disable_languages_test: platform = get_platform() original_write_test_cmakelist = platform.write_test_cmakelist def write_test_cmakelist_no_languages(_self, _languages): original_write_test_cmakelist([]) with patch.object(type(platform), 'write_test_cmakelist', new=write_test_cmakelist_no_languages): six.exec_(setup_code) else: six.exec_(setup_code) yield
def test_cmakelists_with_fatalerror_fails(capfd): with push_dir(): @project_setup_py_test("fail-with-fatal-error-cmakelists", ["build"], disable_languages_test=True) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) assert failed _, err = capfd.readouterr() assert "Invalid CMakeLists.txt" in err assert "An error occurred while configuring with CMake." in message
def test_hello_clean(capfd): with push_dir(): @project_setup_py_test("hello-pure", ["build"]) def run_build(): pass tmp_dir = run_build()[0] assert tmp_dir.join(SKBUILD_DIR).exists() @project_setup_py_test("hello-pure", ["clean"], tmp_dir=tmp_dir) def run_clean(): pass run_clean() assert not tmp_dir.join(SKBUILD_DIR).exists() out = capfd.readouterr()[0] assert 'Build files have been written to' not in out
def test_cmakelists_with_syntaxerror_fails(capfd): with push_dir(): @project_setup_py_test("fail-with-syntax-error-cmakelists", ["build"], disable_languages_test=True) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) assert failed _, err = capfd.readouterr() assert "Parse error. Function missing ending \")\"" in err assert "An error occurred while configuring with CMake." in message
def test_hello_with_compileerror_fails(capfd): with push_dir(): @project_setup_py_test("fail-hello-with-compile-error", ["build"]) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) assert failed out, err = capfd.readouterr() assert "_hello.cxx" in out or "_hello.cxx" in err assert "An error occurred while building with CMake." in message
def test_hello_clean(capfd): with push_dir(): @project_setup_py_test("hello-pure", ["build"], disable_languages_test=True) def run_build(): pass tmp_dir = run_build()[0] assert tmp_dir.join(SKBUILD_DIR()).exists() @project_setup_py_test("hello-pure", ["clean"], tmp_dir=tmp_dir, disable_languages_test=True) def run_clean(): pass run_clean() assert not tmp_dir.join(SKBUILD_DIR()).exists() out = capfd.readouterr()[0] assert 'Build files have been written to' not in out
def test_cmakelists_with_fatalerror_fails(capfd): with push_dir(): @project_setup_py_test("fail-with-fatal-error-cmakelists", ["build"]) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) assert failed _, err = capfd.readouterr() assert "Invalid CMakeLists.txt" in err assert "An error occurred while configuring with CMake." in message
def test_cmakelists_with_syntaxerror_fails(capfd): with push_dir(): @project_setup_py_test("fail-with-syntax-error-cmakelists", ["build"]) def should_fail(): pass failed = False message = "" try: should_fail() except SystemExit as e: failed = isinstance(e.code, SKBuildError) message = str(e) assert failed _, err = capfd.readouterr() assert "Parse error. Function missing ending \")\"" in err assert "An error occurred while configuring with CMake." in message
def test_hello_clean(dry_run, capfd): with push_dir(): dry_run = dry_run == 'with-dry-run' skbuild_dir = os.path.join("tests", "samples", "hello", SKBUILD_DIR) @project_setup_py_test(("samples", "hello"), ["build"], clear_cache=True) def run_build(): pass run_build() assert os.path.exists(skbuild_dir) # XXX Since using capfd.disabled() context manager prevents # the output from being captured atfer it exits, we display # a separator allowing to differentiate the build and clean output. print("<<-->>") clean_args = ["clean"] if dry_run: clean_args.append("--dry-run") @project_setup_py_test(("samples", "hello"), clean_args) def run_clean(): pass run_clean() if not dry_run: assert not os.path.exists(skbuild_dir) else: assert os.path.exists(skbuild_dir) build_out, clean_out = capfd.readouterr()[0].split('<<-->>') assert 'Build files have been written to' in build_out assert 'Build files have been written to' not in clean_out
def test_hello_clean(dry_run, capfd): with push_dir(): dry_run = dry_run == 'with-dry-run' @project_setup_py_test("hello", ["build"]) def run_build(): pass tmp_dir = run_build()[0] assert tmp_dir.join(SKBUILD_DIR).exists() # XXX Since using capfd.disabled() context manager prevents # the output from being captured atfer it exits, we display # a separator allowing to differentiate the build and clean output. print("<<-->>") clean_args = ["clean"] if dry_run: clean_args.append("--dry-run") @project_setup_py_test("hello", clean_args, tmp_dir=tmp_dir) def run_clean(): pass run_clean() if not dry_run: assert not tmp_dir.join(SKBUILD_DIR).exists() else: assert tmp_dir.join(SKBUILD_DIR).exists() build_out, clean_out = capfd.readouterr()[0].split('<<-->>') assert 'Build files have been written to' in build_out assert 'Build files have been written to' not in clean_out
def test_hello_cleans(capfd): with push_dir(): tmp_dir = _tmpdir("test_hello_cleans") _copy_dir(tmp_dir, os.path.join(SAMPLES_DIR, "hello")) @project_setup_py_test("hello", ["build"], tmp_dir=tmp_dir) def run_build(): pass @project_setup_py_test("hello", ["clean"], tmp_dir=tmp_dir) def run_clean(): pass # Check that a project can be cleaned twice in a row run_build() print("<<-->>") run_clean() print("<<-->>") run_clean() _, clean1_out, clean2_out = \ capfd.readouterr()[0].split('<<-->>') clean1_out = clean1_out.strip() clean2_out = clean2_out.strip() assert "running clean" == clean1_out.splitlines()[0] assert "removing '_skbuild{}cmake-install'".format(os.path.sep) \ == clean1_out.splitlines()[1] assert "removing '_skbuild{}cmake-build'".format(os.path.sep) \ == clean1_out.splitlines()[2] assert "removing '_skbuild'" == clean1_out.splitlines()[3] assert "running clean" == clean2_out
def test_hello_clean(dry_run, capfd): with push_dir(): dry_run = dry_run == 'with-dry-run' @project_setup_py_test("hello-cpp", ["build"]) def run_build(): pass tmp_dir = run_build()[0] assert tmp_dir.join(SKBUILD_DIR()).exists() # XXX Since using capfd.disabled() context manager prevents # the output from being captured atfer it exits, we display # a separator allowing to differentiate the build and clean output. print("<<-->>") clean_args = ["clean"] if dry_run: clean_args.append("--dry-run") @project_setup_py_test("hello-cpp", clean_args, tmp_dir=tmp_dir) def run_clean(): pass run_clean() if not dry_run: assert not tmp_dir.join(SKBUILD_DIR()).exists() else: assert tmp_dir.join(SKBUILD_DIR()).exists() build_out, clean_out = capfd.readouterr()[0].split('<<-->>') assert 'Build files have been written to' in build_out assert 'Build files have been written to' not in clean_out
def execute_setup_py(project_dir, setup_args, disable_languages_test=False): """Context manager executing ``setup.py`` with the given arguments. It yields after changing the current working directory to ``project_dir``. """ # See https://stackoverflow.com/questions/9160227/dir-util-copy-tree-fails-after-shutil-rmtree distutils.dir_util._path_created = {} with push_dir(str(project_dir)), push_argv(["setup.py"] + setup_args), prepend_sys_path( [str(project_dir)]): with open("setup.py", "r") as fp: setup_code = compile(fp.read(), "setup.py", mode="exec") if setup_code is not None: if disable_languages_test: platform = get_platform() original_write_test_cmakelist = platform.write_test_cmakelist def write_test_cmakelist_no_languages(_self, _languages): original_write_test_cmakelist([]) with patch.object(type(platform), 'write_test_cmakelist', new=write_test_cmakelist_no_languages): six.exec_(setup_code) else: six.exec_(setup_code) yield
def test_make_without_build_dir_fails(): src_dir = _tmpdir('test_make_without_build_dir_fails') with push_dir(str(src_dir)), pytest.raises(SKBuildError) as excinfo: CMaker().make() assert "Did you forget to run configure before make" in str(excinfo.value)