Skip to content

Commit b9b4554

Browse files
Merge pull request #115 from wfcommons/ci_testing
Ci testing improvements
2 parents bcee5d4 + 3fcaf98 commit b9b4554

3 files changed

Lines changed: 34 additions & 39 deletions

File tree

tests/test_helpers.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def _install_WfCommons_on_container(container):
5151
exit_code, output = container.exec_run("sudo python3 -m pip install . --break-system-packages",
5252
workdir="/tmp/WfCommons", stdout=True, stderr=True)
5353
if exit_code != 0:
54-
raise RuntimeError("Failed to install WfCommons on the container");
54+
raise RuntimeError("Failed to install WfCommons on the container")
5555

5656
def _start_docker_container(backend, mounted_dir, working_dir, bin_dir, command=None):
5757
if command is None:
@@ -62,13 +62,13 @@ def _start_docker_container(backend, mounted_dir, working_dir, bin_dir, command=
6262

6363
try:
6464
image = client.images.get(image_name)
65-
sys.stderr.write(f"Image '{image_name}' is available locally\n")
65+
sys.stderr.write(f"[{backend}] Image '{image_name}' is available locally\n")
6666
except ImageNotFound:
67-
sys.stderr.write(f"Pulling image '{image_name}'...\n")
67+
sys.stderr.write(f"[{backend}] Pulling image '{image_name}'...\n")
6868
client.images.pull(image_name)
6969

7070
# Launch the docker container to actually run the translated workflow
71-
sys.stderr.write("Starting Docker container...\n")
71+
sys.stderr.write(f"[{backend}] Starting Docker container...\n")
7272
container = client.containers.run(
7373
image=image_name,
7474
command=command,
@@ -83,7 +83,7 @@ def _start_docker_container(backend, mounted_dir, working_dir, bin_dir, command=
8383

8484
# Copy over the wfbench and cpu-benchmark executables to where they should go on the container
8585
if bin_dir:
86-
sys.stderr.write("Copying wfbench and cpu-benchmark...\n")
86+
sys.stderr.write(f"[{backend}] Copying wfbench and cpu-benchmark...\n")
8787
exit_code, output = container.exec_run(["sh", "-c", "sudo cp -f `which wfbench` " + bin_dir],
8888
stdout=True, stderr=True)
8989
if exit_code != 0:
@@ -93,13 +93,27 @@ def _start_docker_container(backend, mounted_dir, working_dir, bin_dir, command=
9393
if exit_code != 0:
9494
raise RuntimeError("Failed to copy cpu-benchmark executable to the bin directory")
9595
else:
96-
sys.stderr.write("Not Copying wfbench and cpu-benchmark...\n")
96+
sys.stderr.write(f"[{backend}] Not Copying wfbench and cpu-benchmark...\n")
9797

98+
container.backend = backend
9899
return container
99100

100-
def _shutdown_docker_container(container):
101-
container.stop()
102-
container.remove()
101+
def _shutdown_docker_container_and_remove_image(container):
102+
image = container.image
103+
sys.stderr.write(f"[{container.backend}] Terminating container if need be...\n")
104+
try:
105+
container.stop()
106+
container.remove()
107+
except Exception as e:
108+
pass
109+
110+
# Remove the images as we go, if running on GitHub
111+
if os.getenv('CI') or os.getenv('GITHUB_ACTIONS'):
112+
sys.stderr.write(f"[{container.backend}] Removing Docker image...\n")
113+
try:
114+
image.remove(force=True)
115+
except Exception as e:
116+
sys.stderr.write(f"[{container.backend}] Warning: Error while removing image: {e}\n")
103117

104118
def _get_total_size_of_directory(directory_path: str):
105119
total_size = 0

tests/translators_loggers/test_translators_loggers.py

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from tests.test_helpers import _create_fresh_local_dir
2020
from tests.test_helpers import _remove_local_dir_if_it_exists
2121
from tests.test_helpers import _start_docker_container
22-
from tests.test_helpers import _shutdown_docker_container
22+
from tests.test_helpers import _shutdown_docker_container_and_remove_image
2323
from tests.test_helpers import _compare_workflows
2424

2525
from wfcommons import BlastRecipe
@@ -116,8 +116,6 @@ def _additional_setup_swiftt(container):
116116

117117
def run_workflow_dask(container, num_tasks, str_dirpath):
118118
exit_code, output = container.exec_run("python ./dask_workflow.py", stdout=True, stderr=True)
119-
# Kill the container
120-
container.remove(force=True)
121119
# Check sanity
122120
assert (exit_code == 0)
123121
assert (output.decode().count("completed!") == num_tasks)
@@ -126,8 +124,6 @@ def run_workflow_dask(container, num_tasks, str_dirpath):
126124
def run_workflow_parsl(container, num_tasks, str_dirpath):
127125
exit_code, output = container.exec_run("python ./parsl_workflow.py", stdout=True, stderr=True)
128126
ignored, output = container.exec_run(f"cat {str_dirpath}/runinfo/000/parsl.log", stdout=True, stderr=True)
129-
# Kill the container
130-
container.remove(force=True)
131127
# Check sanity
132128
assert (exit_code == 0)
133129
assert ("completed" in output.decode())
@@ -137,8 +133,6 @@ def run_workflow_nextflow(container, num_tasks, str_dirpath):
137133
# Run the workflow!
138134
exit_code, output = container.exec_run(f"nextflow run ./workflow.nf --pwd .", stdout=True, stderr=True)
139135
ignored, task_exit_codes = container.exec_run("find . -name .exitcode -exec cat {} \;", stdout=True, stderr=True)
140-
# Kill the container
141-
container.remove(force=True)
142136
# Check sanity
143137
assert (exit_code == 0)
144138
assert (task_exit_codes.decode() == num_tasks * "0")
@@ -149,37 +143,28 @@ def run_workflow_airflow(container, num_tasks, str_dirpath):
149143
exit_code, output = container.exec_run(cmd=["sh", "-c", "cd /home/wfcommons/ && sudo /bin/bash /run_a_workflow.sh Blast-Benchmark"],
150144
stdout=True,
151145
stderr=True)
152-
# Kill the container
153-
container.remove(force=True)
154-
155146
# Check sanity
156147
assert (exit_code == 0)
157148
assert (output.decode().count("completed") == num_tasks * 2)
158149

159150
def run_workflow_bash(container, num_tasks, str_dirpath):
160151
# Run the workflow!
161152
exit_code, output = container.exec_run(cmd="/bin/bash ./run_workflow.sh", stdout=True, stderr=True)
162-
# Kill the container
163-
container.remove(force=True)
164153
# Check sanity
165154
assert (exit_code == 0)
166155
assert (output.decode().count("completed") == num_tasks)
167156

168157
def run_workflow_taskvine(container, num_tasks, str_dirpath):
169158
# Run the workflow!
170159
exit_code, output = container.exec_run(cmd=["bash", "-c", "source ~/conda/etc/profile.d/conda.sh && conda activate && python3 ./taskvine_workflow.py"], stdout=True, stderr=True)
171-
# Kill the container
172-
container.remove(force=True)
173-
# # Check sanity
160+
# Check sanity
174161
assert (exit_code == 0)
175162
assert (output.decode().count("completed") == num_tasks)
176163

177164
def run_workflow_cwl(container, num_tasks, str_dirpath):
178165
# Run the workflow!
179166
# Note that the input file is hardcoded and Blast-specific
180167
exit_code, output = container.exec_run(cmd="cwltool ./main.cwl --split_fasta_00000001_input ./data/workflow_infile_0001 ", stdout=True, stderr=True)
181-
# Kill the container
182-
container.remove(force=True)
183168
# Check sanity
184169
assert (exit_code == 0)
185170
# this below is ugly (the 3 is for "workflow", "compile_output_files" and "compile_log_files",
@@ -189,17 +174,13 @@ def run_workflow_cwl(container, num_tasks, str_dirpath):
189174
def run_workflow_pegasus(container, num_tasks, str_dirpath):
190175
# Run the workflow!
191176
exit_code, output = container.exec_run(cmd="bash /home/wfcommons/run_workflow.sh", stdout=True, stderr=True)
192-
# Kill the container
193-
container.remove(force=True)
194177
# Check sanity
195178
assert(exit_code == 0)
196179
assert("success" in output.decode())
197180

198181
def run_workflow_swiftt(container, num_tasks, str_dirpath):
199182
# Run the workflow!
200183
exit_code, output = container.exec_run(cmd="swift-t workflow.swift", stdout=True, stderr=True)
201-
# Kill the container
202-
container.remove(force=True)
203184
# sys.stderr.write(output.decode())
204185
# Check sanity
205186
assert(exit_code == 0)
@@ -236,7 +217,7 @@ class TestTranslators:
236217
@pytest.mark.parametrize(
237218
"backend",
238219
[
239-
# "swiftt",
220+
"swiftt",
240221
"dask",
241222
"parsl",
242223
"nextflow",
@@ -259,22 +240,21 @@ def test_translator(self, backend) -> None:
259240
_remove_local_dir_if_it_exists(str_dirpath)
260241

261242
# Perform the translation
262-
sys.stderr.write("\nTranslating workflow...\n")
243+
sys.stderr.write(f"\n[{backend}] Translating workflow...\n")
263244
translator = translator_classes[backend](benchmark.workflow)
264245
translator.translate(output_folder=dirpath)
265246

266247
# Start the Docker container
267-
sys.stderr.write("Starting Docker container...\n")
268248
container = _start_docker_container(backend, str_dirpath, str_dirpath, str_dirpath + "bin/")
269249

270250
# Do whatever necessary setup
271251
additional_setup_methods[backend](container)
272252

273253
# Run the workflow
274-
sys.stderr.write("Running workflow...\n")
254+
sys.stderr.write(f"[{backend}] Running workflow...\n")
275255
start_time = time.time()
276256
run_workflow_methods[backend](container, num_tasks, str_dirpath)
277-
sys.stderr.write("Workflow ran in %.2f seconds\n" % (time.time() - start_time))
257+
sys.stderr.write(f"[{backend}] Workflow ran in %.2f seconds\n" % (time.time() - start_time))
278258

279259
# Run the log parser if any
280260
if backend == "pegasus":
@@ -285,14 +265,14 @@ def test_translator(self, backend) -> None:
285265
parser = None
286266

287267
if parser:
288-
sys.stderr.write("\nParsing the logs...\n")
268+
sys.stderr.write(f"\n[{backend}] Parsing the logs...\n")
289269
reconstructed_workflow : Workflow = parser.build_workflow("reconstructed_workflow")
290270
reconstructed_workflow.write_json(pathlib.Path("/tmp/reconstructed_workflow.json"))
291271

292272
original_workflow : Workflow = benchmark.workflow
293273

294274
_compare_workflows(original_workflow, reconstructed_workflow)
295275

296-
# Shutdown the container
297-
# _shutdown_docker_container(container)
276+
# Shutdown the container (weirdly, container is already shutdown by now... not sure how)
277+
_shutdown_docker_container_and_remove_image(container)
298278

tests/wfbench/test_wfbench.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
from tests.test_helpers import _create_fresh_local_dir
1919
from tests.test_helpers import _start_docker_container
20+
from tests.test_helpers import _shutdown_docker_container_and_remove_image
2021
from tests.test_helpers import _remove_local_dir_if_it_exists
2122
from tests.test_helpers import _get_total_size_of_directory
2223
from tests.test_helpers import _compare_workflows
@@ -166,7 +167,7 @@ def test_create_from_recipe(self) -> None:
166167
exit_code, output = container.exec_run(cmd="/bin/bash ./run_workflow.sh", stdout=True, stderr=True)
167168

168169
# Kill the container
169-
container.remove(force=True)
170+
_shutdown_docker_container_and_remove_image(container)
170171

171172
# Inspect the data after execution
172173
_actual_data_files_as_expected(dirpath, benchmark.workflow, data_spec)

0 commit comments

Comments
 (0)