diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b2e28e08..41c02da4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,7 @@ jobs: matrix: os: [ubuntu-18.04, windows-latest, macos-latest] python_version: ['3.7'] + timeout-minutes: 180 steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3eaed5f4..74dc215d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -21,6 +21,7 @@ jobs: - job: windows_36 pool: {vmImage: 'vs2017-win2016'} + timeoutInMinutes: 180 steps: - task: UsePythonVersion@0 inputs: @@ -33,6 +34,7 @@ jobs: - job: windows_38 pool: {vmImage: 'vs2017-win2016'} + timeoutInMinutes: 180 steps: - task: UsePythonVersion@0 inputs: diff --git a/cibuildwheel/docker_container.py b/cibuildwheel/docker_container.py index ecf9c52f..8c3a608b 100644 --- a/cibuildwheel/docker_container.py +++ b/cibuildwheel/docker_container.py @@ -27,12 +27,14 @@ class DockerContainer: bash_stdin: IO[bytes] bash_stdout: IO[bytes] - def __init__(self, docker_image: str, simulate_32_bit=False): + def __init__(self, docker_image: str, simulate_32_bit: bool = False, cwd: Optional[Union[str, PathLike]] = None): self.docker_image = docker_image self.simulate_32_bit = simulate_32_bit + self.cwd = cwd def __enter__(self) -> 'DockerContainer': self.name = f'cibuildwheel-{uuid.uuid4()}' + cwd_args = ['-w', str(self.cwd)] if self.cwd else [] shell_args = ['linux32', '/bin/bash'] if self.simulate_32_bit else ['/bin/bash'] subprocess.run( [ @@ -41,6 +43,7 @@ class DockerContainer: '--name', self.name, '-i', '-v', '/:/host', # ignored on CircleCI + *cwd_args, self.docker_image, *shell_args ], diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index e4607f0c..344b944a 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -110,8 +110,8 @@ def build(options: BuildOptions) -> None: continue try: - with DockerContainer(docker_image, simulate_32_bit=platform_tag.endswith('i686')) as docker: - docker.copy_into(Path.cwd(), Path('/project')) + with DockerContainer(docker_image, simulate_32_bit=platform_tag.endswith('i686'), cwd='/project') as docker: + docker.copy_into(Path.cwd(), PurePath('/project')) if options.before_all: env = docker.get_environment() diff --git a/test/test_before_all.py b/test/test_before_all.py index 177ec555..73d36ff6 100644 --- a/test/test_before_all.py +++ b/test/test_before_all.py @@ -1,4 +1,5 @@ -import os +import pytest +import subprocess import textwrap from . import utils @@ -21,7 +22,7 @@ def test(tmp_path): project_dir = tmp_path / 'project' project_with_before_build_asserts.generate(project_dir) - with open(os.path.join(project_dir, "text_info.txt"), mode='w') as ff: + with (project_dir / 'text_info.txt').open(mode='w') as ff: print("dummy text", file=ff) # build the wheels @@ -33,6 +34,30 @@ def test(tmp_path): }) # also check that we got the right wheels - os.remove(os.path.join(project_dir, "text_info.txt")) + (project_dir / 'text_info.txt').unlink() + expected_wheels = utils.expected_wheels('spam', '0.1.0') + assert set(actual_wheels) == set(expected_wheels) + + +def test_failing_command(tmp_path): + project_dir = tmp_path / 'project' + test_projects.new_c_project().generate(project_dir) + + with pytest.raises(subprocess.CalledProcessError): + utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_BEFORE_ALL': 'false', + 'CIBW_BEFORE_ALL_WINDOWS': 'exit /b 1', + }) + + +def test_cwd(tmp_path): + project_dir = tmp_path / 'project' + test_projects.new_c_project().generate(project_dir) + + actual_wheels = utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_BEFORE_ALL': f'''python -c "import os; assert os.getcwd() == {str(project_dir)!r}"''', + 'CIBW_BEFORE_ALL_LINUX': '''python -c "import os; assert os.getcwd() == '/project'"''', + }) + expected_wheels = utils.expected_wheels('spam', '0.1.0') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/test_before_build.py b/test/test_before_build.py index 11c752f0..cb92280b 100644 --- a/test/test_before_build.py +++ b/test/test_before_build.py @@ -1,3 +1,5 @@ +import pytest +import subprocess import textwrap from . import utils @@ -32,14 +34,41 @@ def test(tmp_path): project_dir = tmp_path / 'project' project_with_before_build_asserts.generate(project_dir) + before_build = ('''python -c "import sys; open('{output_dir}pythonversion.txt', 'w').write(sys.version)" && ''' + '''python -c "import sys; open('{output_dir}pythonexecutable.txt', 'w').write(sys.executable)"''') + # 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_BUILD': '''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_BUILD_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_BEFORE_BUILD': before_build.format(output_dir='/tmp/'), + 'CIBW_BEFORE_BUILD_WINDOWS': before_build.format(output_dir=r'c:\\'), }) # also check that we got the right wheels expected_wheels = utils.expected_wheels('spam', '0.1.0') assert set(actual_wheels) == set(expected_wheels) + + +def test_failing_command(tmp_path): + project_dir = tmp_path / 'project' + test_projects.new_c_project().generate(project_dir) + + with pytest.raises(subprocess.CalledProcessError): + utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_BEFORE_BUILD': 'false', + 'CIBW_BEFORE_BUILD_WINDOWS': 'exit /b 1', + }) + + +def test_cwd(tmp_path): + project_dir = tmp_path / 'project' + test_projects.new_c_project().generate(project_dir) + + actual_wheels = utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_BEFORE_BUILD': f'''python -c "import os; assert os.getcwd() == {str(project_dir)!r}"''', + 'CIBW_BEFORE_BUILD_LINUX': '''python -c "import os; assert os.getcwd() == '/project'"''', + }) + + expected_wheels = utils.expected_wheels('spam', '0.1.0') + assert set(actual_wheels) == set(expected_wheels) diff --git a/unit_test/docker_container_test.py b/unit_test/docker_container_test.py index a3b6f06d..22771ed2 100644 --- a/unit_test/docker_container_test.py +++ b/unit_test/docker_container_test.py @@ -41,6 +41,13 @@ def test_environment(): assert container.call(['sh', '-c', 'echo $TEST_VAR'], env={'TEST_VAR': '1'}, capture_output=True) == '1\n' +@pytest.mark.docker +def test_cwd(): + with DockerContainer(DEFAULT_IMAGE, cwd='/cibuildwheel/working_directory') as container: + assert container.call(['pwd'], capture_output=True) == '/cibuildwheel/working_directory\n' + assert container.call(['pwd'], capture_output=True, cwd='/opt') == '/opt\n' + + @pytest.mark.docker def test_container_removed(): with DockerContainer(DEFAULT_IMAGE) as container: