toil 5.12.0__py3-none-any.whl → 6.1.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 +18 -13
- toil/batchSystems/abstractBatchSystem.py +39 -13
- toil/batchSystems/abstractGridEngineBatchSystem.py +24 -24
- toil/batchSystems/awsBatch.py +14 -14
- toil/batchSystems/cleanup_support.py +7 -3
- toil/batchSystems/contained_executor.py +3 -3
- toil/batchSystems/htcondor.py +0 -1
- toil/batchSystems/kubernetes.py +34 -31
- toil/batchSystems/local_support.py +3 -1
- toil/batchSystems/lsf.py +7 -7
- toil/batchSystems/mesos/batchSystem.py +7 -7
- toil/batchSystems/options.py +32 -83
- toil/batchSystems/registry.py +104 -23
- toil/batchSystems/singleMachine.py +16 -13
- toil/batchSystems/slurm.py +87 -16
- toil/batchSystems/torque.py +0 -1
- toil/bus.py +44 -8
- toil/common.py +544 -753
- toil/cwl/__init__.py +28 -32
- toil/cwl/cwltoil.py +595 -574
- toil/cwl/utils.py +55 -10
- toil/exceptions.py +1 -1
- toil/fileStores/__init__.py +2 -2
- toil/fileStores/abstractFileStore.py +88 -14
- toil/fileStores/cachingFileStore.py +610 -549
- toil/fileStores/nonCachingFileStore.py +46 -22
- toil/job.py +182 -101
- toil/jobStores/abstractJobStore.py +161 -95
- toil/jobStores/aws/jobStore.py +23 -9
- toil/jobStores/aws/utils.py +6 -6
- toil/jobStores/fileJobStore.py +116 -18
- toil/jobStores/googleJobStore.py +16 -7
- toil/jobStores/utils.py +5 -6
- toil/leader.py +87 -56
- toil/lib/accelerators.py +10 -5
- toil/lib/aws/__init__.py +3 -14
- toil/lib/aws/ami.py +22 -9
- toil/lib/aws/iam.py +21 -13
- toil/lib/aws/session.py +2 -16
- toil/lib/aws/utils.py +4 -5
- toil/lib/compatibility.py +1 -1
- toil/lib/conversions.py +26 -3
- toil/lib/docker.py +22 -23
- toil/lib/ec2.py +10 -6
- toil/lib/ec2nodes.py +106 -100
- toil/lib/encryption/_nacl.py +2 -1
- toil/lib/generatedEC2Lists.py +325 -18
- toil/lib/io.py +49 -2
- toil/lib/misc.py +1 -1
- toil/lib/resources.py +9 -2
- toil/lib/threading.py +101 -38
- toil/options/common.py +736 -0
- toil/options/cwl.py +336 -0
- toil/options/wdl.py +37 -0
- toil/provisioners/abstractProvisioner.py +9 -4
- toil/provisioners/aws/__init__.py +3 -6
- toil/provisioners/aws/awsProvisioner.py +6 -0
- toil/provisioners/clusterScaler.py +3 -2
- toil/provisioners/gceProvisioner.py +2 -2
- toil/realtimeLogger.py +2 -1
- toil/resource.py +24 -18
- toil/server/app.py +2 -3
- toil/server/cli/wes_cwl_runner.py +4 -4
- toil/server/utils.py +1 -1
- toil/server/wes/abstract_backend.py +3 -2
- toil/server/wes/amazon_wes_utils.py +5 -4
- toil/server/wes/tasks.py +2 -3
- toil/server/wes/toil_backend.py +2 -10
- toil/server/wsgi_app.py +2 -0
- toil/serviceManager.py +12 -10
- toil/statsAndLogging.py +41 -9
- toil/test/__init__.py +29 -54
- toil/test/batchSystems/batchSystemTest.py +11 -111
- toil/test/batchSystems/test_slurm.py +24 -8
- toil/test/cactus/__init__.py +0 -0
- toil/test/cactus/test_cactus_integration.py +58 -0
- toil/test/cwl/cwlTest.py +438 -223
- toil/test/cwl/glob_dir.cwl +15 -0
- toil/test/cwl/preemptible.cwl +21 -0
- toil/test/cwl/preemptible_expression.cwl +28 -0
- toil/test/cwl/revsort.cwl +1 -1
- toil/test/cwl/revsort2.cwl +1 -1
- toil/test/docs/scriptsTest.py +2 -3
- toil/test/jobStores/jobStoreTest.py +34 -21
- toil/test/lib/aws/test_iam.py +4 -14
- toil/test/lib/aws/test_utils.py +0 -3
- toil/test/lib/dockerTest.py +4 -4
- toil/test/lib/test_ec2.py +12 -17
- toil/test/mesos/helloWorld.py +4 -5
- toil/test/mesos/stress.py +1 -1
- toil/test/{wdl/conftest.py → options/__init__.py} +0 -10
- toil/test/options/options.py +37 -0
- toil/test/provisioners/aws/awsProvisionerTest.py +9 -5
- toil/test/provisioners/clusterScalerTest.py +6 -4
- toil/test/provisioners/clusterTest.py +23 -11
- toil/test/provisioners/gceProvisionerTest.py +0 -6
- toil/test/provisioners/restartScript.py +3 -2
- toil/test/server/serverTest.py +1 -1
- toil/test/sort/restart_sort.py +2 -1
- toil/test/sort/sort.py +2 -1
- toil/test/sort/sortTest.py +2 -13
- toil/test/src/autoDeploymentTest.py +45 -45
- toil/test/src/busTest.py +5 -5
- toil/test/src/checkpointTest.py +2 -2
- toil/test/src/deferredFunctionTest.py +1 -1
- toil/test/src/fileStoreTest.py +32 -16
- toil/test/src/helloWorldTest.py +1 -1
- toil/test/src/importExportFileTest.py +1 -1
- toil/test/src/jobDescriptionTest.py +2 -1
- toil/test/src/jobServiceTest.py +1 -1
- toil/test/src/jobTest.py +18 -18
- toil/test/src/miscTests.py +5 -3
- toil/test/src/promisedRequirementTest.py +3 -3
- toil/test/src/realtimeLoggerTest.py +1 -1
- toil/test/src/resourceTest.py +2 -2
- toil/test/src/restartDAGTest.py +1 -1
- toil/test/src/resumabilityTest.py +36 -2
- toil/test/src/retainTempDirTest.py +1 -1
- toil/test/src/systemTest.py +2 -2
- toil/test/src/toilContextManagerTest.py +2 -2
- toil/test/src/userDefinedJobArgTypeTest.py +1 -1
- toil/test/utils/toilDebugTest.py +98 -32
- toil/test/utils/toilKillTest.py +2 -2
- toil/test/utils/utilsTest.py +23 -3
- toil/test/wdl/wdltoil_test.py +223 -45
- toil/toilState.py +7 -6
- toil/utils/toilClean.py +1 -1
- toil/utils/toilConfig.py +36 -0
- toil/utils/toilDebugFile.py +60 -33
- toil/utils/toilDebugJob.py +39 -12
- toil/utils/toilDestroyCluster.py +1 -1
- toil/utils/toilKill.py +1 -1
- toil/utils/toilLaunchCluster.py +13 -2
- toil/utils/toilMain.py +3 -2
- toil/utils/toilRsyncCluster.py +1 -1
- toil/utils/toilSshCluster.py +1 -1
- toil/utils/toilStats.py +445 -305
- toil/utils/toilStatus.py +2 -5
- toil/version.py +10 -10
- toil/wdl/utils.py +2 -122
- toil/wdl/wdltoil.py +1257 -492
- toil/worker.py +55 -46
- toil-6.1.0.dist-info/METADATA +124 -0
- toil-6.1.0.dist-info/RECORD +241 -0
- {toil-5.12.0.dist-info → toil-6.1.0.dist-info}/WHEEL +1 -1
- {toil-5.12.0.dist-info → toil-6.1.0.dist-info}/entry_points.txt +0 -1
- toil/batchSystems/parasol.py +0 -379
- toil/batchSystems/tes.py +0 -459
- toil/test/batchSystems/parasolTestSupport.py +0 -117
- toil/test/wdl/builtinTest.py +0 -506
- toil/test/wdl/toilwdlTest.py +0 -522
- toil/wdl/toilwdl.py +0 -141
- toil/wdl/versions/dev.py +0 -107
- toil/wdl/versions/draft2.py +0 -980
- toil/wdl/versions/v1.py +0 -794
- toil/wdl/wdl_analysis.py +0 -116
- toil/wdl/wdl_functions.py +0 -997
- toil/wdl/wdl_synthesis.py +0 -1011
- toil/wdl/wdl_types.py +0 -243
- toil-5.12.0.dist-info/METADATA +0 -118
- toil-5.12.0.dist-info/RECORD +0 -244
- /toil/{wdl/versions → options}/__init__.py +0 -0
- {toil-5.12.0.dist-info → toil-6.1.0.dist-info}/LICENSE +0 -0
- {toil-5.12.0.dist-info → toil-6.1.0.dist-info}/top_level.txt +0 -0
|
@@ -31,10 +31,9 @@ from toil.batchSystems.abstractBatchSystem import (AbstractBatchSystem,
|
|
|
31
31
|
# in order to import properly. Import them later, in tests
|
|
32
32
|
# protected by annotations.
|
|
33
33
|
from toil.batchSystems.mesos.test import MesosTestSupport
|
|
34
|
-
from toil.batchSystems.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
addBatchSystemFactory,
|
|
34
|
+
from toil.batchSystems.registry import (add_batch_system_factory,
|
|
35
|
+
get_batch_system,
|
|
36
|
+
get_batch_systems,
|
|
38
37
|
restore_batch_system_plugin_state,
|
|
39
38
|
save_batch_system_plugin_state)
|
|
40
39
|
from toil.batchSystems.singleMachine import SingleMachineBatchSystem
|
|
@@ -52,12 +51,9 @@ from toil.test import (ToilTest,
|
|
|
52
51
|
needs_kubernetes_installed,
|
|
53
52
|
needs_lsf,
|
|
54
53
|
needs_mesos,
|
|
55
|
-
needs_parasol,
|
|
56
54
|
needs_slurm,
|
|
57
|
-
needs_tes,
|
|
58
55
|
needs_torque,
|
|
59
56
|
slow)
|
|
60
|
-
from toil.test.batchSystems.parasolTestSupport import ParasolTestSupport
|
|
61
57
|
|
|
62
58
|
logger = logging.getLogger(__name__)
|
|
63
59
|
|
|
@@ -88,16 +84,16 @@ class BatchSystemPluginTest(ToilTest):
|
|
|
88
84
|
restore_batch_system_plugin_state(self.__state)
|
|
89
85
|
super().tearDown()
|
|
90
86
|
|
|
91
|
-
def
|
|
87
|
+
def test_add_batch_system_factory(self):
|
|
92
88
|
def test_batch_system_factory():
|
|
93
89
|
# TODO: Adding the same batch system under multiple names means we
|
|
94
90
|
# can't actually create Toil options, because each version tries to
|
|
95
91
|
# add its arguments.
|
|
96
92
|
return SingleMachineBatchSystem
|
|
97
93
|
|
|
98
|
-
|
|
99
|
-
assert
|
|
100
|
-
assert 'testBatchSystem'
|
|
94
|
+
add_batch_system_factory('testBatchSystem', test_batch_system_factory)
|
|
95
|
+
assert 'testBatchSystem' in get_batch_systems()
|
|
96
|
+
assert get_batch_system('testBatchSystem') == SingleMachineBatchSystem
|
|
101
97
|
|
|
102
98
|
class hidden:
|
|
103
99
|
"""
|
|
@@ -248,10 +244,6 @@ class hidden:
|
|
|
248
244
|
self.batchSystem.killBatchJobs([10])
|
|
249
245
|
|
|
250
246
|
def test_set_env(self):
|
|
251
|
-
# Parasol disobeys shell rules and splits the command at the space
|
|
252
|
-
# character into arguments before exec'ing it, whether the space is
|
|
253
|
-
# quoted, escaped or not.
|
|
254
|
-
|
|
255
247
|
# Start with a relatively safe script
|
|
256
248
|
script_shell = 'if [ "x${FOO}" == "xbar" ] ; then exit 23 ; else exit 42 ; fi'
|
|
257
249
|
|
|
@@ -575,23 +567,6 @@ class KubernetesBatchSystemBenchTest(ToilTest):
|
|
|
575
567
|
self.assertEqual(str(spec.tolerations), "None")
|
|
576
568
|
|
|
577
569
|
|
|
578
|
-
@needs_tes
|
|
579
|
-
@needs_fetchable_appliance
|
|
580
|
-
class TESBatchSystemTest(hidden.AbstractBatchSystemTest):
|
|
581
|
-
"""
|
|
582
|
-
Tests against the TES batch system
|
|
583
|
-
"""
|
|
584
|
-
|
|
585
|
-
def supportsWallTime(self):
|
|
586
|
-
return True
|
|
587
|
-
|
|
588
|
-
def createBatchSystem(self):
|
|
589
|
-
# Import the batch system when we know we have it.
|
|
590
|
-
# Doesn't really matter for TES right now, but someday it might.
|
|
591
|
-
from toil.batchSystems.tes import TESBatchSystem
|
|
592
|
-
return TESBatchSystem(config=self.config,
|
|
593
|
-
maxCores=numCores, maxMemory=1e9, maxDisk=2001)
|
|
594
|
-
|
|
595
570
|
@needs_aws_batch
|
|
596
571
|
@needs_fetchable_appliance
|
|
597
572
|
class AWSBatchBatchSystemTest(hidden.AbstractBatchSystemTest):
|
|
@@ -849,7 +824,7 @@ class MaxCoresSingleMachineBatchSystemTest(ToilTest):
|
|
|
849
824
|
if len(sys.argv) < 3:
|
|
850
825
|
count(1)
|
|
851
826
|
try:
|
|
852
|
-
time.sleep(
|
|
827
|
+
time.sleep(0.5)
|
|
853
828
|
finally:
|
|
854
829
|
count(-1)
|
|
855
830
|
else:
|
|
@@ -910,9 +885,10 @@ class MaxCoresSingleMachineBatchSystemTest(ToilTest):
|
|
|
910
885
|
logger.info(f'maxCores: {maxCores}, '
|
|
911
886
|
f'coresPerJob: {coresPerJob}, '
|
|
912
887
|
f'load: {load}')
|
|
913
|
-
# This is the key assertion:
|
|
888
|
+
# This is the key assertion: we shouldn't run too many jobs.
|
|
889
|
+
# Because of nondeterminism we can't guarantee hitting the limit.
|
|
914
890
|
expectedMaxConcurrentTasks = min(maxCores // coresPerJob, jobs)
|
|
915
|
-
self.
|
|
891
|
+
self.assertLessEqual(maxConcurrentTasks, expectedMaxConcurrentTasks)
|
|
916
892
|
resetCounters(self.counterPath)
|
|
917
893
|
|
|
918
894
|
@skipIf(SingleMachineBatchSystem.numCores < 3, 'Need at least three cores to run this test')
|
|
@@ -965,82 +941,6 @@ class Service(Job.Service):
|
|
|
965
941
|
subprocess.check_call(self.cmd + ' -1', shell=True)
|
|
966
942
|
|
|
967
943
|
|
|
968
|
-
@slow
|
|
969
|
-
@needs_parasol
|
|
970
|
-
class ParasolBatchSystemTest(hidden.AbstractBatchSystemTest, ParasolTestSupport):
|
|
971
|
-
"""
|
|
972
|
-
Tests the Parasol batch system
|
|
973
|
-
"""
|
|
974
|
-
|
|
975
|
-
def supportsWallTime(self):
|
|
976
|
-
return True
|
|
977
|
-
|
|
978
|
-
def _createConfig(self):
|
|
979
|
-
config = super()._createConfig()
|
|
980
|
-
# can't use _getTestJobStorePath since that method removes the directory
|
|
981
|
-
config.jobStore = self._createTempDir('jobStore')
|
|
982
|
-
return config
|
|
983
|
-
|
|
984
|
-
def createBatchSystem(self) -> AbstractBatchSystem:
|
|
985
|
-
memory = int(3e9)
|
|
986
|
-
self._startParasol(numCores=numCores, memory=memory)
|
|
987
|
-
|
|
988
|
-
return ParasolBatchSystem(config=self.config,
|
|
989
|
-
maxCores=numCores,
|
|
990
|
-
maxMemory=memory,
|
|
991
|
-
maxDisk=1001)
|
|
992
|
-
|
|
993
|
-
def tearDown(self):
|
|
994
|
-
super().tearDown()
|
|
995
|
-
self._stopParasol()
|
|
996
|
-
|
|
997
|
-
def testBatchResourceLimits(self):
|
|
998
|
-
jobDesc1 = JobDescription(command="sleep 1000",
|
|
999
|
-
requirements=dict(memory=1 << 30, cores=1,
|
|
1000
|
-
disk=1000, accelerators=[],
|
|
1001
|
-
preemptible=preemptible),
|
|
1002
|
-
jobName='testResourceLimits')
|
|
1003
|
-
job1 = self.batchSystem.issueBatchJob(jobDesc1)
|
|
1004
|
-
self.assertIsNotNone(job1)
|
|
1005
|
-
jobDesc2 = JobDescription(command="sleep 1000",
|
|
1006
|
-
requirements=dict(memory=2 << 30, cores=1,
|
|
1007
|
-
disk=1000, accelerators=[],
|
|
1008
|
-
preemptible=preemptible),
|
|
1009
|
-
jobName='testResourceLimits')
|
|
1010
|
-
job2 = self.batchSystem.issueBatchJob(jobDesc2)
|
|
1011
|
-
self.assertIsNotNone(job2)
|
|
1012
|
-
batches = self._getBatchList()
|
|
1013
|
-
self.assertEqual(len(batches), 2)
|
|
1014
|
-
# It would be better to directly check that the batches have the correct memory and cpu
|
|
1015
|
-
# values, but Parasol seems to slightly change the values sometimes.
|
|
1016
|
-
self.assertNotEqual(batches[0]['ram'], batches[1]['ram'])
|
|
1017
|
-
# Need to kill one of the jobs because there are only two cores available
|
|
1018
|
-
self.batchSystem.killBatchJobs([job2])
|
|
1019
|
-
job3 = self.batchSystem.issueBatchJob(jobDesc1)
|
|
1020
|
-
self.assertIsNotNone(job3)
|
|
1021
|
-
batches = self._getBatchList()
|
|
1022
|
-
self.assertEqual(len(batches), 1)
|
|
1023
|
-
|
|
1024
|
-
def _parseBatchString(self, batchString):
|
|
1025
|
-
import re
|
|
1026
|
-
batchInfo = dict()
|
|
1027
|
-
memPattern = re.compile(r"(\d+\.\d+)([kgmbt])")
|
|
1028
|
-
items = batchString.split()
|
|
1029
|
-
batchInfo["cores"] = int(items[7])
|
|
1030
|
-
memMatch = memPattern.match(items[8])
|
|
1031
|
-
ramValue = float(memMatch.group(1))
|
|
1032
|
-
ramUnits = memMatch.group(2)
|
|
1033
|
-
ramConversion = {'b': 1e0, 'k': 1e3, 'm': 1e6, 'g': 1e9, 't': 1e12}
|
|
1034
|
-
batchInfo["ram"] = ramValue * ramConversion[ramUnits]
|
|
1035
|
-
return batchInfo
|
|
1036
|
-
|
|
1037
|
-
def _getBatchList(self):
|
|
1038
|
-
# noinspection PyUnresolvedReferences
|
|
1039
|
-
exitStatus, batchLines = self.batchSystem._runParasol(['list', 'batches'])
|
|
1040
|
-
self.assertEqual(exitStatus, 0)
|
|
1041
|
-
return [self._parseBatchString(line) for line in batchLines[1:] if line]
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
944
|
@slow
|
|
1045
945
|
@needs_gridengine
|
|
1046
946
|
class GridEngineBatchSystemTest(hidden.AbstractGridEngineBatchSystemTest):
|
|
@@ -4,6 +4,7 @@ from queue import Queue
|
|
|
4
4
|
import pytest
|
|
5
5
|
|
|
6
6
|
import toil.batchSystems.slurm
|
|
7
|
+
from toil.batchSystems.abstractBatchSystem import BatchJobExitReason, EXIT_STATUS_UNAVAILABLE_VALUE
|
|
7
8
|
from toil.common import Config
|
|
8
9
|
from toil.lib.misc import CalledProcessErrorStderr
|
|
9
10
|
from toil.test import ToilTest
|
|
@@ -16,7 +17,8 @@ def call_sacct(args, **_) -> str:
|
|
|
16
17
|
The arguments passed to `call_command` when executing `sacct` are:
|
|
17
18
|
['sacct', '-n', '-j', '<comma-separated list of job-ids>', '--format',
|
|
18
19
|
'JobIDRaw,State,ExitCode', '-P', '-S', '1970-01-01']
|
|
19
|
-
The multi-line output is something like
|
|
20
|
+
The multi-line output is something like::
|
|
21
|
+
|
|
20
22
|
1234|COMPLETED|0:0
|
|
21
23
|
1234.batch|COMPLETED|0:0
|
|
22
24
|
1235|PENDING|0:0
|
|
@@ -46,7 +48,7 @@ def call_sacct(args, **_) -> str:
|
|
|
46
48
|
def call_scontrol(args, **_) -> str:
|
|
47
49
|
"""
|
|
48
50
|
The arguments passed to `call_command` when executing `scontrol` are:
|
|
49
|
-
['scontrol', 'show', 'job'] or ['scontrol', 'show', 'job', '<job-id>']
|
|
51
|
+
``['scontrol', 'show', 'job']`` or ``['scontrol', 'show', 'job', '<job-id>']``
|
|
50
52
|
"""
|
|
51
53
|
job_id = int(args[3]) if len(args) > 3 else None
|
|
52
54
|
# Fake output per fake job-id.
|
|
@@ -283,7 +285,7 @@ class SlurmTest(ToilTest):
|
|
|
283
285
|
def test_getJobExitCode_job_exists(self):
|
|
284
286
|
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_sacct)
|
|
285
287
|
job_id = '785023' # FAILED
|
|
286
|
-
expected_result = 127
|
|
288
|
+
expected_result = (127, BatchJobExitReason.FAILED)
|
|
287
289
|
result = self.worker.getJobExitCode(job_id)
|
|
288
290
|
assert result == expected_result, f"{result} != {expected_result}"
|
|
289
291
|
|
|
@@ -302,7 +304,7 @@ class SlurmTest(ToilTest):
|
|
|
302
304
|
self.monkeypatch.setattr(self.worker, "_getJobDetailsFromSacct", call_sacct_raises)
|
|
303
305
|
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_scontrol)
|
|
304
306
|
job_id = '787204' # COMPLETED
|
|
305
|
-
expected_result = 0
|
|
307
|
+
expected_result = (0, BatchJobExitReason.FINISHED)
|
|
306
308
|
result = self.worker.getJobExitCode(job_id)
|
|
307
309
|
assert result == expected_result, f"{result} != {expected_result}"
|
|
308
310
|
|
|
@@ -328,7 +330,7 @@ class SlurmTest(ToilTest):
|
|
|
328
330
|
def test_coalesce_job_exit_codes_one_exists(self):
|
|
329
331
|
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_sacct)
|
|
330
332
|
job_ids = ['785023'] # FAILED
|
|
331
|
-
expected_result = [127]
|
|
333
|
+
expected_result = [(127, BatchJobExitReason.FAILED)]
|
|
332
334
|
result = self.worker.coalesce_job_exit_codes(job_ids)
|
|
333
335
|
assert result == expected_result, f"{result} != {expected_result}"
|
|
334
336
|
|
|
@@ -346,7 +348,14 @@ class SlurmTest(ToilTest):
|
|
|
346
348
|
'789724', # RUNNING,
|
|
347
349
|
'789868', # PENDING,
|
|
348
350
|
'789869'] # COMPLETED
|
|
349
|
-
|
|
351
|
+
# RUNNING and PENDING jobs should return None
|
|
352
|
+
expected_result = [
|
|
353
|
+
(EXIT_STATUS_UNAVAILABLE_VALUE, BatchJobExitReason.KILLED),
|
|
354
|
+
(1, BatchJobExitReason.FAILED),
|
|
355
|
+
None,
|
|
356
|
+
None,
|
|
357
|
+
(0, BatchJobExitReason.FINISHED)
|
|
358
|
+
]
|
|
350
359
|
result = self.worker.coalesce_job_exit_codes(job_ids)
|
|
351
360
|
assert result == expected_result, f"{result} != {expected_result}"
|
|
352
361
|
|
|
@@ -357,7 +366,14 @@ class SlurmTest(ToilTest):
|
|
|
357
366
|
'789724', # RUNNING,
|
|
358
367
|
'999999', # Non-existent,
|
|
359
368
|
'789869'] # COMPLETED
|
|
360
|
-
|
|
369
|
+
# RUNNING job should return None
|
|
370
|
+
expected_result = [
|
|
371
|
+
(130, BatchJobExitReason.FAILED),
|
|
372
|
+
(2, BatchJobExitReason.FAILED),
|
|
373
|
+
None,
|
|
374
|
+
None,
|
|
375
|
+
(0, BatchJobExitReason.FINISHED)
|
|
376
|
+
]
|
|
361
377
|
result = self.worker.coalesce_job_exit_codes(job_ids)
|
|
362
378
|
assert result == expected_result, f"{result} != {expected_result}"
|
|
363
379
|
|
|
@@ -369,7 +385,7 @@ class SlurmTest(ToilTest):
|
|
|
369
385
|
self.monkeypatch.setattr(self.worker, "_getJobDetailsFromSacct", call_sacct_raises)
|
|
370
386
|
self.monkeypatch.setattr(toil.batchSystems.slurm, "call_command", call_scontrol)
|
|
371
387
|
job_ids = ['787204'] # COMPLETED
|
|
372
|
-
expected_result = [0]
|
|
388
|
+
expected_result = [(0, BatchJobExitReason.FINISHED)]
|
|
373
389
|
result = self.worker.coalesce_job_exit_codes(job_ids)
|
|
374
390
|
assert result == expected_result, f"{result} != {expected_result}"
|
|
375
391
|
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import uuid
|
|
3
|
+
|
|
4
|
+
from toil.provisioners import cluster_factory
|
|
5
|
+
from toil.test.provisioners.clusterTest import AbstractClusterTest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CactusIntegrationTest(AbstractClusterTest):
|
|
9
|
+
"""
|
|
10
|
+
Run the Cactus Integration test on a Kubernetes AWS cluster
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, methodName):
|
|
14
|
+
super().__init__(methodName=methodName)
|
|
15
|
+
self.clusterName = "cactus-test-" + str(uuid.uuid4())
|
|
16
|
+
self.leaderNodeType = "t2.medium"
|
|
17
|
+
self.clusterType = "kubernetes"
|
|
18
|
+
|
|
19
|
+
def setUp(self):
|
|
20
|
+
super().setUp()
|
|
21
|
+
self.jobStore = f"aws:{self.awsRegion()}:cluster-{uuid.uuid4()}"
|
|
22
|
+
|
|
23
|
+
def test_cactus_integration(self):
|
|
24
|
+
# Make a cluster with worker nodes
|
|
25
|
+
self.createClusterUtil(args=["--nodeTypes=t2.xlarge", "-w=1-3"])
|
|
26
|
+
# get the leader so we know the IP address - we don't need to wait since create cluster
|
|
27
|
+
# already ensures the leader is running
|
|
28
|
+
self.cluster = cluster_factory(
|
|
29
|
+
provisioner="aws", zone=self.zone, clusterName=self.clusterName
|
|
30
|
+
)
|
|
31
|
+
self.leader = self.cluster.getLeader()
|
|
32
|
+
|
|
33
|
+
CACTUS_COMMIT_SHA = os.environ["CACTUS_COMMIT_SHA"] or "f5adf4013326322ae58ef1eccb8409b71d761583" # default cactus commit
|
|
34
|
+
|
|
35
|
+
# command to install and run cactus on the cluster
|
|
36
|
+
cactus_command = ("python -m virtualenv --system-site-packages venv && "
|
|
37
|
+
". venv/bin/activate && "
|
|
38
|
+
"git clone https://github.com/ComparativeGenomicsToolkit/cactus.git --recursive && "
|
|
39
|
+
"cd cactus && "
|
|
40
|
+
"git fetch origin && "
|
|
41
|
+
f"git checkout {CACTUS_COMMIT_SHA} && "
|
|
42
|
+
"git submodule update --init --recursive && "
|
|
43
|
+
"pip install --upgrade 'setuptools<66' pip && "
|
|
44
|
+
"pip install --upgrade . && "
|
|
45
|
+
"pip install --upgrade numpy psutil && "
|
|
46
|
+
"time cactus --batchSystem kubernetes --retryCount=3 "
|
|
47
|
+
f"--consCores 2 --binariesMode singularity --clean always {self.jobStore} "
|
|
48
|
+
"examples/evolverMammals.txt examples/evolverMammals.hal --root mr --defaultDisk 8G --logDebug")
|
|
49
|
+
|
|
50
|
+
# run cactus
|
|
51
|
+
self.sshUtil(
|
|
52
|
+
[
|
|
53
|
+
"bash",
|
|
54
|
+
"-c",
|
|
55
|
+
cactus_command
|
|
56
|
+
]
|
|
57
|
+
)
|
|
58
|
+
|