toil 8.0.0__py3-none-any.whl → 8.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- toil/__init__.py +4 -39
- toil/batchSystems/abstractBatchSystem.py +1 -1
- toil/batchSystems/abstractGridEngineBatchSystem.py +1 -1
- toil/batchSystems/awsBatch.py +1 -1
- toil/batchSystems/cleanup_support.py +1 -1
- toil/batchSystems/kubernetes.py +53 -7
- toil/batchSystems/local_support.py +1 -1
- toil/batchSystems/mesos/batchSystem.py +13 -8
- toil/batchSystems/mesos/test/__init__.py +3 -2
- toil/batchSystems/options.py +1 -0
- toil/batchSystems/singleMachine.py +1 -1
- toil/batchSystems/slurm.py +229 -84
- toil/bus.py +5 -3
- toil/common.py +198 -54
- toil/cwl/cwltoil.py +32 -11
- toil/job.py +110 -86
- toil/jobStores/abstractJobStore.py +24 -3
- toil/jobStores/aws/jobStore.py +46 -10
- toil/jobStores/fileJobStore.py +25 -1
- toil/jobStores/googleJobStore.py +104 -30
- toil/leader.py +9 -0
- toil/lib/accelerators.py +3 -1
- toil/lib/aws/session.py +14 -3
- toil/lib/aws/utils.py +92 -35
- toil/lib/aws/utils.py.orig +504 -0
- toil/lib/bioio.py +1 -1
- toil/lib/docker.py +252 -91
- toil/lib/dockstore.py +387 -0
- toil/lib/ec2nodes.py +3 -2
- toil/lib/exceptions.py +5 -3
- toil/lib/history.py +1345 -0
- toil/lib/history_submission.py +695 -0
- toil/lib/io.py +56 -23
- toil/lib/misc.py +25 -1
- toil/lib/resources.py +2 -1
- toil/lib/retry.py +10 -10
- toil/lib/threading.py +11 -10
- toil/lib/{integration.py → trs.py} +95 -46
- toil/lib/web.py +38 -0
- toil/options/common.py +25 -2
- toil/options/cwl.py +10 -0
- toil/options/wdl.py +11 -0
- toil/provisioners/gceProvisioner.py +4 -4
- toil/server/api_spec/LICENSE +201 -0
- toil/server/api_spec/README.rst +5 -0
- toil/server/cli/wes_cwl_runner.py +5 -4
- toil/server/utils.py +2 -3
- toil/statsAndLogging.py +35 -1
- toil/test/__init__.py +275 -115
- toil/test/batchSystems/batchSystemTest.py +227 -205
- toil/test/batchSystems/test_slurm.py +199 -2
- toil/test/cactus/pestis.tar.gz +0 -0
- toil/test/conftest.py +7 -0
- toil/test/cwl/2.fasta +11 -0
- toil/test/cwl/2.fastq +12 -0
- toil/test/cwl/conftest.py +39 -0
- toil/test/cwl/cwlTest.py +1015 -780
- toil/test/cwl/directory/directory/file.txt +15 -0
- toil/test/cwl/download_directory_file.json +4 -0
- toil/test/cwl/download_directory_s3.json +4 -0
- toil/test/cwl/download_file.json +6 -0
- toil/test/cwl/download_http.json +6 -0
- toil/test/cwl/download_https.json +6 -0
- toil/test/cwl/download_s3.json +6 -0
- toil/test/cwl/download_subdirectory_file.json +5 -0
- toil/test/cwl/download_subdirectory_s3.json +5 -0
- toil/test/cwl/empty.json +1 -0
- toil/test/cwl/mock_mpi/fake_mpi.yml +8 -0
- toil/test/cwl/mock_mpi/fake_mpi_run.py +42 -0
- toil/test/cwl/optional-file-exists.json +6 -0
- toil/test/cwl/optional-file-missing.json +6 -0
- toil/test/cwl/optional-file.cwl +18 -0
- toil/test/cwl/preemptible_expression.json +1 -0
- toil/test/cwl/revsort-job-missing.json +6 -0
- toil/test/cwl/revsort-job.json +6 -0
- toil/test/cwl/s3_secondary_file.json +16 -0
- toil/test/cwl/seqtk_seq_job.json +6 -0
- toil/test/cwl/stream.json +6 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.dat +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f0 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f1 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f1i +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f2 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f2_TSM0 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f3 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f3_TSM0 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f4 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f4_TSM0 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.f5 +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.info +0 -0
- toil/test/cwl/test_filename_conflict_resolution.ms/table.lock +0 -0
- toil/test/cwl/whale.txt +16 -0
- toil/test/docs/scripts/example_alwaysfail.py +38 -0
- toil/test/docs/scripts/example_alwaysfail_with_files.wdl +33 -0
- toil/test/docs/scripts/example_cachingbenchmark.py +117 -0
- toil/test/docs/scripts/stagingExampleFiles/in.txt +1 -0
- toil/test/docs/scripts/stagingExampleFiles/out.txt +2 -0
- toil/test/docs/scripts/tutorial_arguments.py +23 -0
- toil/test/docs/scripts/tutorial_debugging.patch +12 -0
- toil/test/docs/scripts/tutorial_debugging_hangs.wdl +126 -0
- toil/test/docs/scripts/tutorial_debugging_works.wdl +129 -0
- toil/test/docs/scripts/tutorial_docker.py +20 -0
- toil/test/docs/scripts/tutorial_dynamic.py +24 -0
- toil/test/docs/scripts/tutorial_encapsulation.py +28 -0
- toil/test/docs/scripts/tutorial_encapsulation2.py +29 -0
- toil/test/docs/scripts/tutorial_helloworld.py +15 -0
- toil/test/docs/scripts/tutorial_invokeworkflow.py +27 -0
- toil/test/docs/scripts/tutorial_invokeworkflow2.py +30 -0
- toil/test/docs/scripts/tutorial_jobfunctions.py +22 -0
- toil/test/docs/scripts/tutorial_managing.py +29 -0
- toil/test/docs/scripts/tutorial_managing2.py +56 -0
- toil/test/docs/scripts/tutorial_multiplejobs.py +25 -0
- toil/test/docs/scripts/tutorial_multiplejobs2.py +21 -0
- toil/test/docs/scripts/tutorial_multiplejobs3.py +22 -0
- toil/test/docs/scripts/tutorial_promises.py +25 -0
- toil/test/docs/scripts/tutorial_promises2.py +30 -0
- toil/test/docs/scripts/tutorial_quickstart.py +22 -0
- toil/test/docs/scripts/tutorial_requirements.py +44 -0
- toil/test/docs/scripts/tutorial_services.py +45 -0
- toil/test/docs/scripts/tutorial_staging.py +45 -0
- toil/test/docs/scripts/tutorial_stats.py +64 -0
- toil/test/lib/aws/test_iam.py +3 -1
- toil/test/lib/dockerTest.py +205 -122
- toil/test/lib/test_history.py +236 -0
- toil/test/lib/test_trs.py +161 -0
- toil/test/provisioners/aws/awsProvisionerTest.py +12 -9
- toil/test/provisioners/clusterTest.py +4 -4
- toil/test/provisioners/gceProvisionerTest.py +16 -14
- toil/test/sort/sort.py +4 -1
- toil/test/src/busTest.py +17 -17
- toil/test/src/deferredFunctionTest.py +145 -132
- toil/test/src/importExportFileTest.py +71 -63
- toil/test/src/jobEncapsulationTest.py +27 -28
- toil/test/src/jobServiceTest.py +149 -133
- toil/test/src/jobTest.py +219 -211
- toil/test/src/miscTests.py +66 -60
- toil/test/src/promisedRequirementTest.py +163 -169
- toil/test/src/regularLogTest.py +24 -24
- toil/test/src/resourceTest.py +82 -76
- toil/test/src/restartDAGTest.py +51 -47
- toil/test/src/resumabilityTest.py +24 -19
- toil/test/src/retainTempDirTest.py +60 -57
- toil/test/src/systemTest.py +17 -13
- toil/test/src/threadingTest.py +29 -32
- toil/test/utils/ABCWorkflowDebug/B_file.txt +1 -0
- toil/test/utils/ABCWorkflowDebug/debugWorkflow.py +204 -0
- toil/test/utils/ABCWorkflowDebug/mkFile.py +16 -0
- toil/test/utils/ABCWorkflowDebug/sleep.cwl +12 -0
- toil/test/utils/ABCWorkflowDebug/sleep.yaml +1 -0
- toil/test/utils/toilDebugTest.py +117 -102
- toil/test/utils/toilKillTest.py +54 -53
- toil/test/utils/utilsTest.py +303 -229
- toil/test/wdl/lint_error.wdl +9 -0
- toil/test/wdl/md5sum/empty_file.json +1 -0
- toil/test/wdl/md5sum/md5sum-gs.json +1 -0
- toil/test/wdl/md5sum/md5sum.1.0.wdl +32 -0
- toil/test/wdl/md5sum/md5sum.input +1 -0
- toil/test/wdl/md5sum/md5sum.json +1 -0
- toil/test/wdl/md5sum/md5sum.wdl +25 -0
- toil/test/wdl/miniwdl_self_test/inputs-namespaced.json +1 -0
- toil/test/wdl/miniwdl_self_test/inputs.json +1 -0
- toil/test/wdl/miniwdl_self_test/self_test.wdl +40 -0
- toil/test/wdl/standard_library/as_map.json +16 -0
- toil/test/wdl/standard_library/as_map_as_input.wdl +23 -0
- toil/test/wdl/standard_library/as_pairs.json +7 -0
- toil/test/wdl/standard_library/as_pairs_as_input.wdl +23 -0
- toil/test/wdl/standard_library/ceil.json +3 -0
- toil/test/wdl/standard_library/ceil_as_command.wdl +16 -0
- toil/test/wdl/standard_library/ceil_as_input.wdl +16 -0
- toil/test/wdl/standard_library/collect_by_key.json +1 -0
- toil/test/wdl/standard_library/collect_by_key_as_input.wdl +23 -0
- toil/test/wdl/standard_library/cross.json +11 -0
- toil/test/wdl/standard_library/cross_as_input.wdl +19 -0
- toil/test/wdl/standard_library/flatten.json +7 -0
- toil/test/wdl/standard_library/flatten_as_input.wdl +18 -0
- toil/test/wdl/standard_library/floor.json +3 -0
- toil/test/wdl/standard_library/floor_as_command.wdl +16 -0
- toil/test/wdl/standard_library/floor_as_input.wdl +16 -0
- toil/test/wdl/standard_library/keys.json +8 -0
- toil/test/wdl/standard_library/keys_as_input.wdl +24 -0
- toil/test/wdl/standard_library/length.json +7 -0
- toil/test/wdl/standard_library/length_as_input.wdl +16 -0
- toil/test/wdl/standard_library/length_as_input_with_map.json +7 -0
- toil/test/wdl/standard_library/length_as_input_with_map.wdl +17 -0
- toil/test/wdl/standard_library/length_invalid.json +3 -0
- toil/test/wdl/standard_library/range.json +3 -0
- toil/test/wdl/standard_library/range_0.json +3 -0
- toil/test/wdl/standard_library/range_as_input.wdl +17 -0
- toil/test/wdl/standard_library/range_invalid.json +3 -0
- toil/test/wdl/standard_library/read_boolean.json +3 -0
- toil/test/wdl/standard_library/read_boolean_as_command.wdl +17 -0
- toil/test/wdl/standard_library/read_float.json +3 -0
- toil/test/wdl/standard_library/read_float_as_command.wdl +17 -0
- toil/test/wdl/standard_library/read_int.json +3 -0
- toil/test/wdl/standard_library/read_int_as_command.wdl +17 -0
- toil/test/wdl/standard_library/read_json.json +3 -0
- toil/test/wdl/standard_library/read_json_as_output.wdl +31 -0
- toil/test/wdl/standard_library/read_lines.json +3 -0
- toil/test/wdl/standard_library/read_lines_as_output.wdl +31 -0
- toil/test/wdl/standard_library/read_map.json +3 -0
- toil/test/wdl/standard_library/read_map_as_output.wdl +31 -0
- toil/test/wdl/standard_library/read_string.json +3 -0
- toil/test/wdl/standard_library/read_string_as_command.wdl +17 -0
- toil/test/wdl/standard_library/read_tsv.json +3 -0
- toil/test/wdl/standard_library/read_tsv_as_output.wdl +31 -0
- toil/test/wdl/standard_library/round.json +3 -0
- toil/test/wdl/standard_library/round_as_command.wdl +16 -0
- toil/test/wdl/standard_library/round_as_input.wdl +16 -0
- toil/test/wdl/standard_library/size.json +3 -0
- toil/test/wdl/standard_library/size_as_command.wdl +17 -0
- toil/test/wdl/standard_library/size_as_output.wdl +36 -0
- toil/test/wdl/standard_library/stderr.json +3 -0
- toil/test/wdl/standard_library/stderr_as_output.wdl +30 -0
- toil/test/wdl/standard_library/stdout.json +3 -0
- toil/test/wdl/standard_library/stdout_as_output.wdl +30 -0
- toil/test/wdl/standard_library/sub.json +3 -0
- toil/test/wdl/standard_library/sub_as_input.wdl +17 -0
- toil/test/wdl/standard_library/sub_as_input_with_file.wdl +17 -0
- toil/test/wdl/standard_library/transpose.json +6 -0
- toil/test/wdl/standard_library/transpose_as_input.wdl +18 -0
- toil/test/wdl/standard_library/write_json.json +6 -0
- toil/test/wdl/standard_library/write_json_as_command.wdl +17 -0
- toil/test/wdl/standard_library/write_lines.json +7 -0
- toil/test/wdl/standard_library/write_lines_as_command.wdl +17 -0
- toil/test/wdl/standard_library/write_map.json +6 -0
- toil/test/wdl/standard_library/write_map_as_command.wdl +17 -0
- toil/test/wdl/standard_library/write_tsv.json +6 -0
- toil/test/wdl/standard_library/write_tsv_as_command.wdl +17 -0
- toil/test/wdl/standard_library/zip.json +12 -0
- toil/test/wdl/standard_library/zip_as_input.wdl +19 -0
- toil/test/wdl/test.csv +3 -0
- toil/test/wdl/test.tsv +3 -0
- toil/test/wdl/testfiles/croo.wdl +38 -0
- toil/test/wdl/testfiles/drop_files.wdl +62 -0
- toil/test/wdl/testfiles/drop_files_subworkflow.wdl +13 -0
- toil/test/wdl/testfiles/empty.txt +0 -0
- toil/test/wdl/testfiles/not_enough_outputs.wdl +33 -0
- toil/test/wdl/testfiles/random.wdl +66 -0
- toil/test/wdl/testfiles/string_file_coercion.json +1 -0
- toil/test/wdl/testfiles/string_file_coercion.wdl +35 -0
- toil/test/wdl/testfiles/test.json +4 -0
- toil/test/wdl/testfiles/test_boolean.txt +1 -0
- toil/test/wdl/testfiles/test_float.txt +1 -0
- toil/test/wdl/testfiles/test_int.txt +1 -0
- toil/test/wdl/testfiles/test_lines.txt +5 -0
- toil/test/wdl/testfiles/test_map.txt +2 -0
- toil/test/wdl/testfiles/test_string.txt +1 -0
- toil/test/wdl/testfiles/url_to_file.wdl +13 -0
- toil/test/wdl/testfiles/url_to_optional_file.wdl +13 -0
- toil/test/wdl/testfiles/vocab.json +1 -0
- toil/test/wdl/testfiles/vocab.wdl +66 -0
- toil/test/wdl/testfiles/wait.wdl +34 -0
- toil/test/wdl/wdl_specification/type_pair.json +23 -0
- toil/test/wdl/wdl_specification/type_pair_basic.wdl +36 -0
- toil/test/wdl/wdl_specification/type_pair_with_files.wdl +36 -0
- toil/test/wdl/wdl_specification/v1_spec.json +1 -0
- toil/test/wdl/wdl_specification/v1_spec_declaration.wdl +39 -0
- toil/test/wdl/wdltoil_test.py +681 -408
- toil/test/wdl/wdltoil_test_kubernetes.py +2 -2
- toil/version.py +10 -10
- toil/wdl/wdltoil.py +350 -123
- toil/worker.py +113 -33
- {toil-8.0.0.dist-info → toil-8.2.0.dist-info}/METADATA +13 -7
- toil-8.2.0.dist-info/RECORD +439 -0
- {toil-8.0.0.dist-info → toil-8.2.0.dist-info}/WHEEL +1 -1
- toil/test/lib/test_integration.py +0 -104
- toil-8.0.0.dist-info/RECORD +0 -253
- {toil-8.0.0.dist-info → toil-8.2.0.dist-info}/entry_points.txt +0 -0
- {toil-8.0.0.dist-info → toil-8.2.0.dist-info/licenses}/LICENSE +0 -0
- {toil-8.0.0.dist-info → toil-8.2.0.dist-info}/top_level.txt +0 -0
|
@@ -1,17 +1,24 @@
|
|
|
1
|
+
import errno
|
|
1
2
|
import textwrap
|
|
2
3
|
from queue import Queue
|
|
3
4
|
|
|
5
|
+
import logging
|
|
4
6
|
import pytest
|
|
7
|
+
import sys
|
|
5
8
|
|
|
6
9
|
import toil.batchSystems.slurm
|
|
7
10
|
from toil.batchSystems.abstractBatchSystem import (
|
|
8
11
|
EXIT_STATUS_UNAVAILABLE_VALUE,
|
|
9
12
|
BatchJobExitReason,
|
|
13
|
+
BatchSystemSupport,
|
|
10
14
|
)
|
|
11
15
|
from toil.common import Config
|
|
12
16
|
from toil.lib.misc import CalledProcessErrorStderr
|
|
13
17
|
from toil.test import ToilTest
|
|
14
18
|
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
15
22
|
# TODO: Come up with a better way to mock the commands then monkey-patching the
|
|
16
23
|
# command-calling functions.
|
|
17
24
|
|
|
@@ -29,6 +36,9 @@ def call_sacct(args, **_) -> str:
|
|
|
29
36
|
1236|FAILED|0:2
|
|
30
37
|
1236.extern|COMPLETED|0:0
|
|
31
38
|
"""
|
|
39
|
+
if sum(len(a) for a in args) > 1000:
|
|
40
|
+
# Simulate if the argument list is too long
|
|
41
|
+
raise OSError(errno.E2BIG, "Argument list is too long")
|
|
32
42
|
# Fake output per fake job-id.
|
|
33
43
|
sacct_info = {
|
|
34
44
|
609663: "609663|FAILED|0:2\n609663.extern|COMPLETED|0:0\n",
|
|
@@ -173,14 +183,34 @@ def call_sacct_raises(*_):
|
|
|
173
183
|
1, "sacct: error: Problem talking to the database: " "Connection timed out"
|
|
174
184
|
)
|
|
175
185
|
|
|
186
|
+
def call_sinfo(*_) -> str:
|
|
187
|
+
"""
|
|
188
|
+
Simulate asking for partition info from Slurm
|
|
189
|
+
"""
|
|
190
|
+
stdout = textwrap.dedent(
|
|
191
|
+
"""\
|
|
192
|
+
PARTITION GRES TIMELIMIT PRIO_TIER CPUS MEMORY
|
|
193
|
+
short* (null) 1:00:00 500 256+ 1996800+
|
|
194
|
+
medium (null) 12:00:00 500 256+ 1996800+
|
|
195
|
+
long (null) 14-00:00:00 500 256+ 1996800+
|
|
196
|
+
gpu gpu:A100:8 7-00:00:00 5000 256 996800
|
|
197
|
+
gpu gpu:A5500:8 7-00:00:00 5000 256 1996800
|
|
198
|
+
high_priority gpu:A5500:8 7-00:00:00 65000 256 1996800
|
|
199
|
+
high_priority (null) 7-00:00:00 65000 256+ 1996800+
|
|
200
|
+
simple_nodelist gpu:A100:8 1:00 65000 256 996800
|
|
201
|
+
simple_nodelist gpu:A5500:8 1:00 65000 256 1996800
|
|
202
|
+
simple_nodelist (null) 1:00 65000 256+ 1996800+
|
|
203
|
+
"""
|
|
204
|
+
)
|
|
205
|
+
return stdout
|
|
176
206
|
|
|
177
|
-
class FakeBatchSystem:
|
|
207
|
+
class FakeBatchSystem(BatchSystemSupport):
|
|
178
208
|
"""
|
|
179
209
|
Class that implements a minimal Batch System, needed to create a Worker (see below).
|
|
180
210
|
"""
|
|
181
211
|
|
|
182
212
|
def __init__(self):
|
|
183
|
-
|
|
213
|
+
super().__init__(self.__fake_config(), float("inf"), sys.maxsize, sys.maxsize)
|
|
184
214
|
|
|
185
215
|
def getWaitDuration(self):
|
|
186
216
|
return 10
|
|
@@ -198,8 +228,12 @@ class FakeBatchSystem:
|
|
|
198
228
|
|
|
199
229
|
config.workflowID = str(uuid4())
|
|
200
230
|
config.cleanWorkDir = "always"
|
|
231
|
+
toil.batchSystems.slurm.SlurmBatchSystem.setOptions(lambda o: setattr(config, o, None))
|
|
201
232
|
return config
|
|
202
233
|
|
|
234
|
+
# Make the mock class not have abstract methods anymore, even though we don't
|
|
235
|
+
# implement them. See <https://stackoverflow.com/a/17345619>.
|
|
236
|
+
FakeBatchSystem.__abstractmethods__ = set()
|
|
203
237
|
|
|
204
238
|
class SlurmTest(ToilTest):
|
|
205
239
|
"""
|
|
@@ -262,6 +296,13 @@ class SlurmTest(ToilTest):
|
|
|
262
296
|
result = self.worker._getJobDetailsFromSacct(list(expected_result))
|
|
263
297
|
assert result == expected_result, f"{result} != {expected_result}"
|
|
264
298
|
|
|
299
|
+
def test_getJobDetailsFromSacct_argument_list_too_big(self):
|
|
300
|
+
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_sacct)
|
|
301
|
+
expected_result = {i: (None, None) for i in range(2000)}
|
|
302
|
+
result = self.worker._getJobDetailsFromSacct(list(expected_result))
|
|
303
|
+
assert result == expected_result, f"{result} != {expected_result}"
|
|
304
|
+
|
|
305
|
+
|
|
265
306
|
####
|
|
266
307
|
#### tests for _getJobDetailsFromScontrol()
|
|
267
308
|
####
|
|
@@ -449,3 +490,159 @@ class SlurmTest(ToilTest):
|
|
|
449
490
|
pass
|
|
450
491
|
else:
|
|
451
492
|
assert False, "Exception CalledProcessErrorStderr not raised"
|
|
493
|
+
|
|
494
|
+
###
|
|
495
|
+
### Tests for partition selection
|
|
496
|
+
##
|
|
497
|
+
|
|
498
|
+
def test_PartitionSet_get_partition(self):
|
|
499
|
+
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_sinfo)
|
|
500
|
+
ps = toil.batchSystems.slurm.SlurmBatchSystem.PartitionSet()
|
|
501
|
+
|
|
502
|
+
# At zero. short will win because simple_nodelist has higher priority.
|
|
503
|
+
self.assertEqual(ps.get_partition(0), "short")
|
|
504
|
+
# Easily within the partition
|
|
505
|
+
self.assertEqual(ps.get_partition(10 * 60), "short")
|
|
506
|
+
# Exactly on the boundary
|
|
507
|
+
self.assertEqual(ps.get_partition(60 * 60), "short")
|
|
508
|
+
# Well within the next partition
|
|
509
|
+
self.assertEqual(ps.get_partition(2 * 60 * 60), "medium")
|
|
510
|
+
# Can only fit in long
|
|
511
|
+
self.assertEqual(ps.get_partition(8 * 24 * 60 * 60), "long")
|
|
512
|
+
# Could fit in gpu or long
|
|
513
|
+
self.assertEqual(ps.get_partition(6 * 24 * 60 * 60), "long")
|
|
514
|
+
# Can't fit in anything
|
|
515
|
+
with self.assertRaises(Exception):
|
|
516
|
+
ps.get_partition(365 * 24 * 60 * 60)
|
|
517
|
+
|
|
518
|
+
def test_PartitionSet_default_gpu_partition(self):
|
|
519
|
+
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_sinfo)
|
|
520
|
+
ps = toil.batchSystems.slurm.SlurmBatchSystem.PartitionSet()
|
|
521
|
+
|
|
522
|
+
# Make sure we picked the useful-length GPU partition and not the super
|
|
523
|
+
# short one.
|
|
524
|
+
self.assertEqual(ps.default_gpu_partition.partition_name, "gpu")
|
|
525
|
+
|
|
526
|
+
def test_prepareSbatch_partition(self):
|
|
527
|
+
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_sinfo)
|
|
528
|
+
ps = toil.batchSystems.slurm.SlurmBatchSystem.PartitionSet()
|
|
529
|
+
self.worker.boss.partitions = ps
|
|
530
|
+
# This is in seconds
|
|
531
|
+
self.worker.boss.config.slurm_time = 30
|
|
532
|
+
|
|
533
|
+
# Without a partition override in the environment, we should get the
|
|
534
|
+
# "short" partition for this job
|
|
535
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
536
|
+
assert "--partition=short" in command
|
|
537
|
+
|
|
538
|
+
# With a partition override, we should not. But the override will be rewritten.
|
|
539
|
+
self.worker.boss.config.slurm_args = "--something --partition foo --somethingElse"
|
|
540
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
541
|
+
assert "--partition=short" not in command
|
|
542
|
+
assert "--partition=foo" in command
|
|
543
|
+
|
|
544
|
+
# All ways of setting partition should work, including =
|
|
545
|
+
self.worker.boss.config.slurm_args = "--something --partition=foo --somethingElse"
|
|
546
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
547
|
+
assert "--partition=short" not in command
|
|
548
|
+
assert "--partition=foo" in command
|
|
549
|
+
|
|
550
|
+
# And short options
|
|
551
|
+
self.worker.boss.config.slurm_args = "--something -p foo --somethingElse"
|
|
552
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
553
|
+
assert "--partition=short" not in command
|
|
554
|
+
assert "--partition=foo" in command
|
|
555
|
+
|
|
556
|
+
# Partition settings from the config should override automatic selection
|
|
557
|
+
self.worker.boss.config.slurm_partition = "foobar"
|
|
558
|
+
self.worker.boss.config.slurm_args = "--something --somethingElse"
|
|
559
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
560
|
+
assert "--partition=foobar" in command
|
|
561
|
+
|
|
562
|
+
# But they should be overridden by the argument overrides
|
|
563
|
+
self.worker.boss.config.slurm_args = "--something --partition=baz --somethingElse"
|
|
564
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
565
|
+
assert "--partition=baz" in command
|
|
566
|
+
|
|
567
|
+
def test_prepareSbatch_time(self):
|
|
568
|
+
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_sinfo)
|
|
569
|
+
ps = toil.batchSystems.slurm.SlurmBatchSystem.PartitionSet()
|
|
570
|
+
self.worker.boss.partitions = ps
|
|
571
|
+
# This is in seconds
|
|
572
|
+
self.worker.boss.config.slurm_time = 30
|
|
573
|
+
|
|
574
|
+
# Without a time override in the environment, we should use the normal
|
|
575
|
+
# time and the "short" partition
|
|
576
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
577
|
+
logger.debug("Command: %s", command)
|
|
578
|
+
assert "--time=0:30" in command
|
|
579
|
+
assert "--partition=short" in command
|
|
580
|
+
|
|
581
|
+
# With a time override, we should use it, slightly translated, and it
|
|
582
|
+
# should change the selected partition.
|
|
583
|
+
self.worker.boss.config.slurm_args = "--something --time 10:00:00 --somethingElse"
|
|
584
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
585
|
+
logger.debug("Command: %s", command)
|
|
586
|
+
assert "--partition=medium" in command
|
|
587
|
+
assert "--time=0:36000" in command
|
|
588
|
+
|
|
589
|
+
# All ways of setting time should work, including =
|
|
590
|
+
self.worker.boss.config.slurm_args = "--something --time=10:00:00 --somethingElse"
|
|
591
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
592
|
+
logger.debug("Command: %s", command)
|
|
593
|
+
assert "--partition=medium" in command
|
|
594
|
+
assert "--time=0:36000" in command
|
|
595
|
+
|
|
596
|
+
# And short options
|
|
597
|
+
self.worker.boss.config.slurm_args = "--something -t 10:00:00 --somethingElse"
|
|
598
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
599
|
+
logger.debug("Command: %s", command)
|
|
600
|
+
assert "--partition=medium" in command
|
|
601
|
+
assert "--time=0:36000" in command
|
|
602
|
+
|
|
603
|
+
def test_prepareSbatch_export(self):
|
|
604
|
+
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_sinfo)
|
|
605
|
+
ps = toil.batchSystems.slurm.SlurmBatchSystem.PartitionSet()
|
|
606
|
+
self.worker.boss.partitions = ps
|
|
607
|
+
|
|
608
|
+
# Without any overrides, we need --export=ALL
|
|
609
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
610
|
+
assert "--export=ALL" in command
|
|
611
|
+
|
|
612
|
+
# With overrides, we don't get --export=ALL
|
|
613
|
+
self.worker.boss.config.slurm_args = "--export=foo"
|
|
614
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
615
|
+
assert "--export=ALL" not in command
|
|
616
|
+
|
|
617
|
+
# With --export-file, we don't get --export=ALL as documented.
|
|
618
|
+
self.worker.boss.config.slurm_args = "--export-file=./thefile.txt"
|
|
619
|
+
command = self.worker.prepareSbatch(1, 100, 5, "job5", None, None)
|
|
620
|
+
assert "--export=ALL" not in command
|
|
621
|
+
|
|
622
|
+
def test_option_detector(self):
|
|
623
|
+
detector = toil.batchSystems.slurm.option_detector("foobar", "f")
|
|
624
|
+
|
|
625
|
+
self.assertTrue(detector("--foobar"))
|
|
626
|
+
self.assertTrue(detector("--foobar=1"))
|
|
627
|
+
self.assertTrue(detector("-f"))
|
|
628
|
+
self.assertFalse(detector("-F"))
|
|
629
|
+
self.assertFalse(detector("--foo-bar"))
|
|
630
|
+
self.assertFalse(detector("foobar"))
|
|
631
|
+
self.assertFalse(detector("-foobar"))
|
|
632
|
+
self.assertFalse(detector("f"))
|
|
633
|
+
|
|
634
|
+
def test_any_option_detector(self):
|
|
635
|
+
detector = toil.batchSystems.slurm.any_option_detector([])
|
|
636
|
+
self.assertFalse(detector("--anything"))
|
|
637
|
+
|
|
638
|
+
detector = toil.batchSystems.slurm.any_option_detector([("foobar", "f"), "many-bothans", ("bazz-only", "B")])
|
|
639
|
+
|
|
640
|
+
self.assertTrue(detector("--foobar"))
|
|
641
|
+
self.assertTrue(detector("-f"))
|
|
642
|
+
self.assertTrue(detector("--many-bothans=False"))
|
|
643
|
+
self.assertTrue(detector("--bazz-only"))
|
|
644
|
+
self.assertTrue(detector("-B"))
|
|
645
|
+
self.assertFalse(detector("--no-bazz"))
|
|
646
|
+
self.assertFalse(detector("--foo-bar=--bazz-only"))
|
|
647
|
+
|
|
648
|
+
|
|
Binary file
|
toil/test/conftest.py
ADDED
toil/test/cwl/2.fasta
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
>Sequence 561 BP; 135 A; 106 C; 98 G; 222 T; 0 other;
|
|
2
|
+
gttcgatgcc taaaatacct tcttttgtcc ctacacagac cacagttttc ctaatggctt
|
|
3
|
+
tacaccgact agaaattctt gtgcaagcac taattgaaag cggttggcct agagtgttac
|
|
4
|
+
cggtttgtat agctgagcgc gtctcttgcc ctgatcaaag gttcattttc tctactttgg
|
|
5
|
+
aagacgttgt ggaagaatac aacaagtacg agtctctccc ccctggtttg ctgattactg
|
|
6
|
+
gatacagttg taataccctt cgcaacaccg cgtaactatc tatatgaatt attttccctt
|
|
7
|
+
tattatatgt agtaggttcg tctttaatct tcctttagca agtcttttac tgttttcgac
|
|
8
|
+
ctcaatgttc atgttcttag gttgttttgg ataatatgcg gtcagtttaa tcttcgttgt
|
|
9
|
+
ttcttcttaa aatatttatt catggtttaa tttttggttt gtacttgttc aggggccagt
|
|
10
|
+
tcattattta ctctgtttgt atacagcagt tcttttattt ttagtatgat tttaatttaa
|
|
11
|
+
aacaattcta atggtcaaaa a
|
toil/test/cwl/2.fastq
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
@EAS54_6_R1_2_1_413_324
|
|
2
|
+
CCCTTCTTGTCTTCAGCGTTTCTCC
|
|
3
|
+
+
|
|
4
|
+
;;3;;;;;;;;;;;;7;;;;;;;88
|
|
5
|
+
@EAS54_6_R1_2_1_540_792
|
|
6
|
+
TTGGCAGGCCAAGGCCGATGGATCA
|
|
7
|
+
+
|
|
8
|
+
;;;;;;;;;;;7;;;;;-;;;3;83
|
|
9
|
+
@EAS54_6_R1_2_1_443_348
|
|
10
|
+
GTTGCTTCTGGCGTGGGTGGGGGGG
|
|
11
|
+
+EAS54_6_R1_2_1_443_348
|
|
12
|
+
;;;;;;;;;;;9;7;;.7;393333
|
toil/test/cwl/conftest.py
CHANGED
|
@@ -14,4 +14,43 @@
|
|
|
14
14
|
|
|
15
15
|
# https://pytest.org/latest/example/pythoncollection.html
|
|
16
16
|
|
|
17
|
+
import json
|
|
18
|
+
import logging
|
|
19
|
+
from io import StringIO
|
|
20
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
21
|
+
|
|
22
|
+
from cwltest import utils
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
17
25
|
collect_ignore = ["spec"]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# Hook into Pytest for testing CWL conformance with Toil
|
|
29
|
+
# https://pytest.org/en/6.2.x/writing_plugins.html?highlight=conftest#conftest-py-local-per-directory-plugins
|
|
30
|
+
# See cwltool's reference implementation:
|
|
31
|
+
# https://github.com/common-workflow-language/cwltool/blob/05af6c1357c327b3146e9f5da40e7c0aa3e6d976/tests/cwl-conformance/cwltool-conftest.py
|
|
32
|
+
def pytest_cwl_execute_test(
|
|
33
|
+
config: utils.CWLTestConfig,
|
|
34
|
+
processfile: str,
|
|
35
|
+
jobfile: Optional[str]
|
|
36
|
+
) -> Tuple[int, Optional[Dict[str, Any]]]:
|
|
37
|
+
"""Use Toil to execute CWL tests (equivalent to running toil-cwl-runner)."""
|
|
38
|
+
from toil.cwl.cwltoil import main
|
|
39
|
+
|
|
40
|
+
stdout = StringIO()
|
|
41
|
+
argsl: List[str] = [f"--outdir={config.outdir}"]
|
|
42
|
+
if config.runner_quiet:
|
|
43
|
+
argsl.append("--quiet")
|
|
44
|
+
elif config.verbose:
|
|
45
|
+
argsl.append("--debug")
|
|
46
|
+
argsl.extend(config.args)
|
|
47
|
+
argsl.append(processfile)
|
|
48
|
+
if jobfile:
|
|
49
|
+
argsl.append(jobfile)
|
|
50
|
+
try:
|
|
51
|
+
result = main(args=argsl, stdout=stdout)
|
|
52
|
+
except Exception as e:
|
|
53
|
+
logger.error(e)
|
|
54
|
+
return 1, {}
|
|
55
|
+
out = stdout.getvalue()
|
|
56
|
+
return result, json.loads(out) if out else {}
|