2424from tests .test_helpers import _shutdown_docker_container_and_remove_image
2525from tests .test_helpers import _compare_workflows
2626
27- from wfcommons import BlastRecipe
27+ from wfcommons import BlastRecipe , EpigenomicsRecipe , BwaRecipe , CyclesRecipe , GenomeRecipe , MontageRecipe , \
28+ RnaseqRecipe , SeismologyRecipe , SoykbRecipe , SrasearchRecipe
2829from wfcommons .common import Workflow , Task
2930from wfcommons .wfbench import WorkflowBenchmark
3031from wfcommons .wfbench import DaskTranslator
3435from wfcommons .wfbench import BashTranslator
3536from wfcommons .wfbench import TaskVineTranslator
3637from wfcommons .wfbench import MakeflowTranslator
38+ from wfcommons .wfbench import SnakemakeTranslator
3739from wfcommons .wfbench import CWLTranslator
3840from wfcommons .wfbench import StreamflowTranslator
3941from wfcommons .wfbench import PegasusTranslator
4345from wfcommons .wfinstances .logs import TaskVineLogsParser
4446from wfcommons .wfinstances .logs import MakeflowLogsParser
4547from wfcommons .wfinstances .logs import ROCrateLogsParser
48+ from wfcommons .wfinstances .logs import SnakemakeLogsParser
4649
4750
4851def _create_workflow_benchmark () -> (WorkflowBenchmark , int ):
4952 # Create a workflow benchmark object to generate specifications based on a recipe (in /tmp/, whatever)
5053 desired_num_tasks = 45
51- benchmark_full_path = "/tmp/blast-benchmark-{desired_num_tasks}.json"
54+ benchmark_full_path = f"/tmp/blast-benchmark-{ desired_num_tasks } .json"
55+ # benchmark_full_path = f"/tmp/epigenomics-benchmark-{desired_num_tasks}.json"
56+ # benchmark_full_path = f"/tmp/bwa-benchmark-{desired_num_tasks}.json"
57+ # benchmark_full_path = f"/tmp/cycles-benchmark-{desired_num_tasks}.json"
58+ # benchmark_full_path = f"/tmp/genome-benchmark-{desired_num_tasks}.json"
59+ # benchmark_full_path = f"/tmp/montage-benchmark-{desired_num_tasks}.json"
60+ # benchmark_full_path = f"/tmp/rnaseq-benchmark-{desired_num_tasks}.json"
61+ # benchmark_full_path = f"/tmp/seismology-benchmark-{desired_num_tasks}.json"
62+ # benchmark_full_path = f"/tmp/soykb-benchmark-{desired_num_tasks}.json"
63+ # benchmark_full_path = f"/tmp/srasearch-benchmark-{desired_num_tasks}.json"
5264 shutil .rmtree (benchmark_full_path , ignore_errors = True )
5365 benchmark = WorkflowBenchmark (recipe = BlastRecipe , num_tasks = desired_num_tasks )
66+ # benchmark = WorkflowBenchmark(recipe=EpigenomicsRecipe, num_tasks=desired_num_tasks)
67+ # benchmark = WorkflowBenchmark(recipe=BwaRecipe, num_tasks=desired_num_tasks)
68+ # benchmark = WorkflowBenchmark(recipe=CyclesRecipe, num_tasks=desired_num_tasks)
69+ # benchmark = WorkflowBenchmark(recipe=GenomeRecipe, num_tasks=desired_num_tasks)
70+ # benchmark = WorkflowBenchmark(recipe=MontageRecipe, num_tasks=desired_num_tasks)
71+ # benchmark = WorkflowBenchmark(recipe=RnaseqRecipe, num_tasks=desired_num_tasks)
72+ # benchmark = WorkflowBenchmark(recipe=SeismologyRecipe, num_tasks=desired_num_tasks)
73+ # benchmark = WorkflowBenchmark(recipe=SoykbRecipe, num_tasks=desired_num_tasks)
74+ # benchmark = WorkflowBenchmark(recipe=SrasearchRecipe, num_tasks=desired_num_tasks)
5475 benchmark .create_benchmark (pathlib .Path ("/tmp/" ), cpu_work = 10 , data = 10 , percent_cpu = 0.6 )
55- with open (f"/tmp/blast-benchmark- { desired_num_tasks } .json" , "r" ) as f :
76+ with open (benchmark_full_path , "r" ) as f :
5677 generated_json = json .load (f )
5778 num_tasks = len (generated_json ["workflow" ]["specification" ]["tasks" ])
5879 return benchmark , num_tasks
@@ -119,6 +140,7 @@ def _additional_setup_swiftt(container):
119140 "bash" : noop ,
120141 "taskvine" : _additional_setup_taskvine ,
121142 "makeflow" : noop ,
143+ "snakemake" : noop ,
122144 "cwl" : noop ,
123145 "streamflow" : noop ,
124146 "pegasus" : _additional_setup_pegasus ,
@@ -199,6 +221,15 @@ def run_workflow_makeflow(container, num_tasks, str_dirpath):
199221 num_completed_jobs = len (re .findall (r'job \d+ completed' , output .decode ()))
200222 assert (num_completed_jobs == num_tasks )
201223
224+ def run_workflow_snakemake (container , num_tasks , str_dirpath ):
225+ # Run the workflow (with full logging)
226+ exit_code , output = container .exec_run (cmd = ["bash" , "-c" , "snakemake -s ./workflow.smk --cores 1 --logger snkmt --logger-snkmt-db ./snkmt.sqlite" ],
227+ user = "wfcommons" , stdout = True , stderr = True )
228+ # Check sanity
229+ assert (exit_code == 0 )
230+ num_completed_jobs = len (re .findall (r'Finished jobid: \d+' , output .decode ()))
231+ assert (num_completed_jobs - 1 == num_tasks ) # Discounting the "all_tasks" rule
232+
202233def run_workflow_cwl (container , num_tasks , str_dirpath ):
203234 # Run the workflow!
204235 # Note that the input file is hardcoded and Blast-specific
@@ -214,7 +245,6 @@ def run_workflow_cwl(container, num_tasks, str_dirpath):
214245
215246def run_workflow_streamflow (container , num_tasks , str_dirpath ):
216247 # Run the workflow!
217- # Note that the input file is hardcoded and Blast-specific
218248 exit_code , output = container .exec_run (cmd = "streamflow run ./streamflow.yml" ,
219249 user = "wfcommons" , stdout = True , stderr = True )
220250 # Check sanity
@@ -264,6 +294,7 @@ def run_workflow_swiftt(container, num_tasks, str_dirpath):
264294 "bash" : run_workflow_bash ,
265295 "taskvine" : run_workflow_taskvine ,
266296 "makeflow" : run_workflow_makeflow ,
297+ "snakemake" : run_workflow_snakemake ,
267298 "cwl" : run_workflow_cwl ,
268299 "streamflow" : run_workflow_streamflow ,
269300 "pegasus" : run_workflow_pegasus ,
@@ -279,6 +310,7 @@ def run_workflow_swiftt(container, num_tasks, str_dirpath):
279310 "bash" : BashTranslator ,
280311 "taskvine" : TaskVineTranslator ,
281312 "makeflow" : MakeflowTranslator ,
313+ "snakemake" : SnakemakeTranslator ,
282314 "cwl" : CWLTranslator ,
283315 "streamflow" : StreamflowTranslator ,
284316 "pegasus" : PegasusTranslator ,
@@ -291,18 +323,19 @@ class TestTranslators:
291323 @pytest .mark .parametrize (
292324 "backend" ,
293325 [
294- "swiftt" ,
295- "dask" ,
296- "parsl" ,
297- "nextflow" ,
298- "nextflow_subworkflow" ,
299- "airflow" ,
300- "bash" ,
301- "taskvine" ,
302- "makeflow" ,
303- "cwl" ,
304- "streamflow" ,
305- "pegasus" ,
326+ "swiftt" ,
327+ "dask" ,
328+ "parsl" ,
329+ "nextflow" ,
330+ "nextflow_subworkflow" ,
331+ "airflow" ,
332+ "bash" ,
333+ "taskvine" ,
334+ "makeflow" ,
335+ "snakemake" ,
336+ "cwl" ,
337+ "streamflow" ,
338+ "pegasus" ,
306339 ])
307340 @pytest .mark .unit
308341 # @pytest.mark.skip(reason="tmp")
@@ -359,12 +392,13 @@ def test_translator(self, backend) -> None:
359392 steps_to_ignore = ["main.cwl#compile_output_files" , "main.cwl#compile_log_files" ],
360393 file_extensions_to_ignore = [".out" , ".err" ],
361394 instruments_to_ignore = ["shell.cwl" ])
395+ elif backend == "snakemake" :
396+ parser = SnakemakeLogsParser (dirpath , snkmt_db = dirpath / "snkmt.sqlite" , rules_to_ignore = ["all_wfbench_tasks" ])
362397
363398 if parser is not None :
364399 sys .stderr .write (f"[{ backend } ] Parsing the logs...\n " )
365400 reconstructed_workflow : Workflow = parser .build_workflow (f"reconstructed_workflow_{ backend } " )
366401 reconstructed_workflow .write_json (pathlib .Path ("/tmp/reconstructed_workflow.json" ))
367-
368402 original_workflow : Workflow = benchmark .workflow
369403
370404 _compare_workflows (original_workflow , reconstructed_workflow )
0 commit comments