From 49dddeb6c21d18c2216316194dd4d81b2bf46838 Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:21:57 +0200 Subject: [PATCH 01/11] check that build action can use TMPDIR Fixes #52 --- tests/test_container_template.py | 34 +++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/tests/test_container_template.py b/tests/test_container_template.py index aab0bb7..22b2a34 100644 --- a/tests/test_container_template.py +++ b/tests/test_container_template.py @@ -11,6 +11,7 @@ import os import socket import subprocess +import tempfile # port used by tests @@ -18,17 +19,27 @@ sock.bind(('', 0)) port = sock.getsockname()[1] -# Check that (1) singularity exist, and (2) if not, check for docker. +# Check that (1) singularity or apptainer executables exist, +# and (2) if not, check for docker. # If neither are found, tests will fall back to plain python. +# This may be useful for testing on a local machine, but should +# be revised for the particular usecase. try: pth = os.path.join('containers', 'container_template.sif') - out = subprocess.run('singularity') + try: + out = subprocess.run('singularity', check=False) + except FileNotFoundError: + try: + out = subprocess.run('apptainer', check=False) + except FileNotFoundError as exc: + raise FileNotFoundError from exc cwd = os.getcwd() PREFIX = f'singularity run {pth} python' PREFIX_MOUNT = f'singularity run --home={cwd}:/home/ {pth} python' + PREFIX_CUSTOM_MOUNT = f'singularity run --home={cwd}:/home/ ' + '{custom_mount}' + f'{pth} python' except FileNotFoundError: try: - out = subprocess.run('docker') + out = subprocess.run('docker', check=False) pwd = os.getcwd() PREFIX = (f'docker run -p {port}:{port} ' + 'ghcr.io/precimed/container_template python') @@ -36,6 +47,11 @@ f'docker run -p {port}:{port} ' + f'--mount type=bind,source={pwd},target={pwd} ' + 'ghcr.io/precimed/container_template python') + PREFIX_CUSTOM_MOUNT = ( + f'docker run -p {port}:{port} ' + + f'--mount type=bind,source={pwd},target={pwd} ' + + '{custom_mount} ' + + 'ghcr.io/precimed/container_template python') except FileNotFoundError: # neither singularity nor docker found, fall back to plain python PREFIX = 'python' @@ -62,6 +78,17 @@ def test_container_template_python_script(): assert out.returncode == 0 +def test_container_template_python_script_from_tempdir(): + '''test that the tempdir is working''' + with tempfile.TemporaryDirectory() as d: + os.system(f'cp {pwd}/tests/extras/hello.py {d}/') + custom_mount = f'--mount type=bind,source={d},target=/temp/' + call = f'{PREFIX_CUSTOM_MOUNT.format(custom_mount=custom_mount)} ' + \ + '/temp/hello.py' + out = subprocess.run(call.split(' '), check=False) + assert out.returncode == 0 + + def test_container_template_python_packages(): '''test that the Python packages are installed''' packages = [ @@ -78,3 +105,4 @@ def test_container_template_python_packages(): call = f"{PREFIX} -c '{importstr}'" out = subprocess.run(call, shell=True) assert out.returncode == 0 + From 6d5306ec6f20dc70921817815198d4b454ba3bc7 Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:24:56 +0200 Subject: [PATCH 02/11] flake8 must be happy --- tests/test_container_template.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_container_template.py b/tests/test_container_template.py index 22b2a34..4244390 100644 --- a/tests/test_container_template.py +++ b/tests/test_container_template.py @@ -19,10 +19,10 @@ sock.bind(('', 0)) port = sock.getsockname()[1] -# Check that (1) singularity or apptainer executables exist, +# Check that (1) singularity or apptainer executables exist, # and (2) if not, check for docker. # If neither are found, tests will fall back to plain python. -# This may be useful for testing on a local machine, but should +# This may be useful for testing on a local machine, but should # be revised for the particular usecase. try: pth = os.path.join('containers', 'container_template.sif') @@ -36,7 +36,8 @@ cwd = os.getcwd() PREFIX = f'singularity run {pth} python' PREFIX_MOUNT = f'singularity run --home={cwd}:/home/ {pth} python' - PREFIX_CUSTOM_MOUNT = f'singularity run --home={cwd}:/home/ ' + '{custom_mount}' + f'{pth} python' + PREFIX_CUSTOM_MOUNT = f'singularity run --home={cwd}:/home/ ' + \ + '{custom_mount}' + f'{pth} python' except FileNotFoundError: try: out = subprocess.run('docker', check=False) @@ -105,4 +106,3 @@ def test_container_template_python_packages(): call = f"{PREFIX} -c '{importstr}'" out = subprocess.run(call, shell=True) assert out.returncode == 0 - From 7bf75e5190dc1cb9143a9584cd19c9909e574c9c Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:26:10 +0200 Subject: [PATCH 03/11] PREFIX_CUSTOM_MOUNT defined --- tests/test_container_template.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_container_template.py b/tests/test_container_template.py index 4244390..3766f53 100644 --- a/tests/test_container_template.py +++ b/tests/test_container_template.py @@ -57,6 +57,7 @@ # neither singularity nor docker found, fall back to plain python PREFIX = 'python' PREFIX_MOUNT = 'python' + PREFIX_CUSTOM_MOUNT = 'python' def test_assert(): From ce496b9cdcc45eaef9819931c7b84ce5912daf60 Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:27:47 +0200 Subject: [PATCH 04/11] pwd to cwd --- tests/test_container_template.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_container_template.py b/tests/test_container_template.py index 3766f53..5574ab6 100644 --- a/tests/test_container_template.py +++ b/tests/test_container_template.py @@ -41,16 +41,16 @@ except FileNotFoundError: try: out = subprocess.run('docker', check=False) - pwd = os.getcwd() + cwd = os.getcwd() PREFIX = (f'docker run -p {port}:{port} ' + 'ghcr.io/precimed/container_template python') PREFIX_MOUNT = ( f'docker run -p {port}:{port} ' + - f'--mount type=bind,source={pwd},target={pwd} ' + + f'--mount type=bind,source={cwd},target={cwd} ' + 'ghcr.io/precimed/container_template python') PREFIX_CUSTOM_MOUNT = ( f'docker run -p {port}:{port} ' + - f'--mount type=bind,source={pwd},target={pwd} ' + + f'--mount type=bind,source={cwd},target={cwd} ' + '{custom_mount} ' + 'ghcr.io/precimed/container_template python') except FileNotFoundError: @@ -74,8 +74,8 @@ def test_container_template_python(): def test_container_template_python_script(): '''test that Python can run a script''' - pwd = os.getcwd() if PREFIX.rfind('docker') >= 0 else '.' - call = f'''{PREFIX_MOUNT} {pwd}/tests/extras/hello.py''' + cwd = os.getcwd() if PREFIX.rfind('docker') >= 0 else '.' + call = f'''{PREFIX_MOUNT} {cwd}/tests/extras/hello.py''' out = subprocess.run(call.split(' '), capture_output=True) assert out.returncode == 0 @@ -83,7 +83,7 @@ def test_container_template_python_script(): def test_container_template_python_script_from_tempdir(): '''test that the tempdir is working''' with tempfile.TemporaryDirectory() as d: - os.system(f'cp {pwd}/tests/extras/hello.py {d}/') + os.system(f'cp {cwd}/tests/extras/hello.py {d}/') custom_mount = f'--mount type=bind,source={d},target=/temp/' call = f'{PREFIX_CUSTOM_MOUNT.format(custom_mount=custom_mount)} ' + \ '/temp/hello.py' From ede9c732c5949330d06ed3e39c444c209117bc65 Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:24:33 +0200 Subject: [PATCH 05/11] cwd --- tests/test_container_template.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_container_template.py b/tests/test_container_template.py index 5574ab6..2fc3326 100644 --- a/tests/test_container_template.py +++ b/tests/test_container_template.py @@ -24,6 +24,7 @@ # If neither are found, tests will fall back to plain python. # This may be useful for testing on a local machine, but should # be revised for the particular usecase. +cwd = os.getcwd() try: pth = os.path.join('containers', 'container_template.sif') try: @@ -33,7 +34,6 @@ out = subprocess.run('apptainer', check=False) except FileNotFoundError as exc: raise FileNotFoundError from exc - cwd = os.getcwd() PREFIX = f'singularity run {pth} python' PREFIX_MOUNT = f'singularity run --home={cwd}:/home/ {pth} python' PREFIX_CUSTOM_MOUNT = f'singularity run --home={cwd}:/home/ ' + \ @@ -41,7 +41,6 @@ except FileNotFoundError: try: out = subprocess.run('docker', check=False) - cwd = os.getcwd() PREFIX = (f'docker run -p {port}:{port} ' + 'ghcr.io/precimed/container_template python') PREFIX_MOUNT = ( From f607580ec5190f7aead8c20653f0c578f4c08258 Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:41:50 +0200 Subject: [PATCH 06/11] should work --- tests/test_container_template.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_container_template.py b/tests/test_container_template.py index 2fc3326..d68c15a 100644 --- a/tests/test_container_template.py +++ b/tests/test_container_template.py @@ -83,10 +83,10 @@ def test_container_template_python_script_from_tempdir(): '''test that the tempdir is working''' with tempfile.TemporaryDirectory() as d: os.system(f'cp {cwd}/tests/extras/hello.py {d}/') - custom_mount = f'--mount type=bind,source={d},target=/temp/' + custom_mount = f'--mount type=bind,source={d},target={d}' call = f'{PREFIX_CUSTOM_MOUNT.format(custom_mount=custom_mount)} ' + \ - '/temp/hello.py' - out = subprocess.run(call.split(' '), check=False) + f'{d}/hello.py' + out = subprocess.run(call, shell=True, check=False) assert out.returncode == 0 From 1df34337c51955b0375c6dbcfd939e86bc418a68 Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:06:14 +0000 Subject: [PATCH 07/11] revise tests for apptainer runtime --- tests/test_container_template.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/tests/test_container_template.py b/tests/test_container_template.py index d68c15a..425d0a5 100644 --- a/tests/test_container_template.py +++ b/tests/test_container_template.py @@ -28,32 +28,36 @@ try: pth = os.path.join('containers', 'container_template.sif') try: - out = subprocess.run('singularity', check=False) + runtime = 'apptainer' + out = subprocess.run(runtime, check=False) except FileNotFoundError: try: - out = subprocess.run('apptainer', check=False) + runtime = 'singularity' + out = subprocess.run(runtime, check=False) except FileNotFoundError as exc: raise FileNotFoundError from exc - PREFIX = f'singularity run {pth} python' - PREFIX_MOUNT = f'singularity run --home={cwd}:/home/ {pth} python' - PREFIX_CUSTOM_MOUNT = f'singularity run --home={cwd}:/home/ ' + \ + PREFIX = f'{runtime} run {pth} python' + PREFIX_MOUNT = f'{runtime} run --home={cwd}:/home/ {pth} python' + PREFIX_CUSTOM_MOUNT = f'{runtime} run --home={cwd}:/home/ ' + \ '{custom_mount}' + f'{pth} python' except FileNotFoundError: try: - out = subprocess.run('docker', check=False) - PREFIX = (f'docker run -p {port}:{port} ' + + runtime = 'docker' + out = subprocess.run(runtime, check=False) + PREFIX = (f'{runtime} run -p {port}:{port} ' + 'ghcr.io/precimed/container_template python') PREFIX_MOUNT = ( - f'docker run -p {port}:{port} ' + + f'{runtime} run -p {port}:{port} ' + f'--mount type=bind,source={cwd},target={cwd} ' + 'ghcr.io/precimed/container_template python') PREFIX_CUSTOM_MOUNT = ( - f'docker run -p {port}:{port} ' + + f'{runtime} run -p {port}:{port} ' + f'--mount type=bind,source={cwd},target={cwd} ' + '{custom_mount} ' + 'ghcr.io/precimed/container_template python') except FileNotFoundError: # neither singularity nor docker found, fall back to plain python + runtime = None PREFIX = 'python' PREFIX_MOUNT = 'python' PREFIX_CUSTOM_MOUNT = 'python' @@ -73,7 +77,7 @@ def test_container_template_python(): def test_container_template_python_script(): '''test that Python can run a script''' - cwd = os.getcwd() if PREFIX.rfind('docker') >= 0 else '.' + cwd = os.getcwd() if runtime == 'docker' >= 0 else '.' call = f'''{PREFIX_MOUNT} {cwd}/tests/extras/hello.py''' out = subprocess.run(call.split(' '), capture_output=True) assert out.returncode == 0 @@ -83,7 +87,12 @@ def test_container_template_python_script_from_tempdir(): '''test that the tempdir is working''' with tempfile.TemporaryDirectory() as d: os.system(f'cp {cwd}/tests/extras/hello.py {d}/') - custom_mount = f'--mount type=bind,source={d},target={d}' + if runtime == 'docker': + custom_mount = f'--mount type=bind,source={d},target={d}' + elif runtime in ['apptainer', 'singularity']: + custom_mount = f'--bind {d}:{d} ' + else: + custom_mount = '' call = f'{PREFIX_CUSTOM_MOUNT.format(custom_mount=custom_mount)} ' + \ f'{d}/hello.py' out = subprocess.run(call, shell=True, check=False) From 63d7d1b7e7e45eaaa85cd88107347df305aef09a Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:07:32 +0200 Subject: [PATCH 08/11] bah --- tests/test_container_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_container_template.py b/tests/test_container_template.py index 425d0a5..3f37b31 100644 --- a/tests/test_container_template.py +++ b/tests/test_container_template.py @@ -77,7 +77,7 @@ def test_container_template_python(): def test_container_template_python_script(): '''test that Python can run a script''' - cwd = os.getcwd() if runtime == 'docker' >= 0 else '.' + cwd = os.getcwd() if runtime == 'docker' else '.' call = f'''{PREFIX_MOUNT} {cwd}/tests/extras/hello.py''' out = subprocess.run(call.split(' '), capture_output=True) assert out.returncode == 0 From 43a262c17a92756c7fb33656500d151232e0f200 Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:10:42 +0200 Subject: [PATCH 09/11] test using py.test inner and outer scope --- .github/workflows/container_build.yml | 13 +++++++++---- test-requirements.txt | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 test-requirements.txt diff --git a/.github/workflows/container_build.yml b/.github/workflows/container_build.yml index 5c141da..db56b62 100644 --- a/.github/workflows/container_build.yml +++ b/.github/workflows/container_build.yml @@ -10,7 +10,7 @@ on: tags: - "v*.*.*" env: - TEST_TAG: ghcr.io/precimed/container_template:test + LATEST_TAG: ghcr.io/precimed/container_template:latest jobs: docker: @@ -51,13 +51,18 @@ jobs: with: context: "{{defaultContext}}:docker" load: true - tags: ${{ env.TEST_TAG }} + tags: ${{ env.LATEST_TAG }} file: ./dockerfiles/container_template/Dockerfile - - name: Run unit tests + - name: Run unit tests I run: | - docker run --rm -v ${{ github.workspace }}:/home ${{ env.TEST_TAG }} py.test -v tests + docker run --rm -v ${{ github.workspace }}:/home ${{ env.LATEST_TAG }} py.test -v tests + + - name: Run unit tests II + run: | + pip install -r test-requirements.txt + py.test -v tests - name: Build uses: docker/build-push-action@v6 diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..e079f8a --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +pytest From dfbbcd290c7821390ba6cb7777aadf5cbf1358bd Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 21:24:51 +0200 Subject: [PATCH 10/11] don't assing docker port --- tests/test_container_template.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/test_container_template.py b/tests/test_container_template.py index 3f37b31..1e50208 100644 --- a/tests/test_container_template.py +++ b/tests/test_container_template.py @@ -9,16 +9,10 @@ """ import os -import socket import subprocess import tempfile -# port used by tests -sock = socket.socket() -sock.bind(('', 0)) -port = sock.getsockname()[1] - # Check that (1) singularity or apptainer executables exist, # and (2) if not, check for docker. # If neither are found, tests will fall back to plain python. @@ -44,14 +38,14 @@ try: runtime = 'docker' out = subprocess.run(runtime, check=False) - PREFIX = (f'{runtime} run -p {port}:{port} ' + + PREFIX = (f'{runtime} run ' + 'ghcr.io/precimed/container_template python') PREFIX_MOUNT = ( - f'{runtime} run -p {port}:{port} ' + + f'{runtime} run ' + f'--mount type=bind,source={cwd},target={cwd} ' + 'ghcr.io/precimed/container_template python') PREFIX_CUSTOM_MOUNT = ( - f'{runtime} run -p {port}:{port} ' + + f'{runtime} run ' + f'--mount type=bind,source={cwd},target={cwd} ' + '{custom_mount} ' + 'ghcr.io/precimed/container_template python') From dc89260c832c1a4511911fcd2715fbe70536ff4d Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Wed, 2 Oct 2024 21:34:11 +0200 Subject: [PATCH 11/11] squash some pytest warnings --- tests/pytest.ini | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/pytest.ini diff --git a/tests/pytest.ini b/tests/pytest.ini new file mode 100644 index 0000000..8f2ad61 --- /dev/null +++ b/tests/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +cache_dir = /tmp/pytest-cache/ \ No newline at end of file