toil 7.0.0__py3-none-any.whl → 8.1.0b1__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 +124 -86
- toil/batchSystems/__init__.py +1 -0
- toil/batchSystems/abstractBatchSystem.py +137 -77
- toil/batchSystems/abstractGridEngineBatchSystem.py +211 -101
- toil/batchSystems/awsBatch.py +237 -128
- toil/batchSystems/cleanup_support.py +22 -16
- toil/batchSystems/contained_executor.py +30 -26
- toil/batchSystems/gridengine.py +85 -49
- toil/batchSystems/htcondor.py +164 -87
- toil/batchSystems/kubernetes.py +622 -386
- toil/batchSystems/local_support.py +17 -12
- toil/batchSystems/lsf.py +132 -79
- toil/batchSystems/lsfHelper.py +13 -11
- toil/batchSystems/mesos/__init__.py +41 -29
- toil/batchSystems/mesos/batchSystem.py +288 -149
- toil/batchSystems/mesos/executor.py +77 -49
- toil/batchSystems/mesos/test/__init__.py +31 -23
- toil/batchSystems/options.py +39 -29
- toil/batchSystems/registry.py +53 -19
- toil/batchSystems/singleMachine.py +293 -123
- toil/batchSystems/slurm.py +651 -155
- toil/batchSystems/torque.py +46 -32
- toil/bus.py +141 -73
- toil/common.py +784 -397
- toil/cwl/__init__.py +1 -1
- toil/cwl/cwltoil.py +1137 -534
- toil/cwl/utils.py +17 -22
- toil/deferred.py +62 -41
- toil/exceptions.py +5 -3
- toil/fileStores/__init__.py +5 -5
- toil/fileStores/abstractFileStore.py +88 -57
- toil/fileStores/cachingFileStore.py +711 -247
- toil/fileStores/nonCachingFileStore.py +113 -75
- toil/job.py +1031 -349
- toil/jobStores/abstractJobStore.py +387 -243
- toil/jobStores/aws/jobStore.py +772 -412
- toil/jobStores/aws/utils.py +161 -109
- toil/jobStores/conftest.py +1 -0
- toil/jobStores/fileJobStore.py +289 -151
- toil/jobStores/googleJobStore.py +137 -70
- toil/jobStores/utils.py +36 -15
- toil/leader.py +614 -269
- toil/lib/accelerators.py +115 -18
- toil/lib/aws/__init__.py +55 -28
- toil/lib/aws/ami.py +122 -87
- toil/lib/aws/iam.py +284 -108
- toil/lib/aws/s3.py +31 -0
- toil/lib/aws/session.py +204 -58
- toil/lib/aws/utils.py +290 -213
- toil/lib/bioio.py +13 -5
- toil/lib/compatibility.py +11 -6
- toil/lib/conversions.py +83 -49
- toil/lib/docker.py +131 -103
- toil/lib/dockstore.py +379 -0
- toil/lib/ec2.py +322 -209
- toil/lib/ec2nodes.py +174 -105
- toil/lib/encryption/_dummy.py +5 -3
- toil/lib/encryption/_nacl.py +10 -6
- toil/lib/encryption/conftest.py +1 -0
- toil/lib/exceptions.py +26 -7
- toil/lib/expando.py +4 -2
- toil/lib/ftp_utils.py +217 -0
- toil/lib/generatedEC2Lists.py +127 -19
- toil/lib/history.py +1271 -0
- toil/lib/history_submission.py +681 -0
- toil/lib/humanize.py +6 -2
- toil/lib/io.py +121 -12
- toil/lib/iterables.py +4 -2
- toil/lib/memoize.py +12 -8
- toil/lib/misc.py +83 -18
- toil/lib/objects.py +2 -2
- toil/lib/resources.py +19 -7
- toil/lib/retry.py +125 -87
- toil/lib/threading.py +282 -80
- toil/lib/throttle.py +15 -14
- toil/lib/trs.py +390 -0
- toil/lib/web.py +38 -0
- toil/options/common.py +850 -402
- toil/options/cwl.py +185 -90
- toil/options/runner.py +50 -0
- toil/options/wdl.py +70 -19
- toil/provisioners/__init__.py +111 -46
- toil/provisioners/abstractProvisioner.py +322 -157
- toil/provisioners/aws/__init__.py +62 -30
- toil/provisioners/aws/awsProvisioner.py +980 -627
- toil/provisioners/clusterScaler.py +541 -279
- toil/provisioners/gceProvisioner.py +283 -180
- toil/provisioners/node.py +147 -79
- toil/realtimeLogger.py +34 -22
- toil/resource.py +137 -75
- toil/server/app.py +127 -61
- toil/server/celery_app.py +3 -1
- toil/server/cli/wes_cwl_runner.py +84 -55
- toil/server/utils.py +56 -31
- toil/server/wes/abstract_backend.py +64 -26
- toil/server/wes/amazon_wes_utils.py +21 -15
- toil/server/wes/tasks.py +121 -63
- toil/server/wes/toil_backend.py +142 -107
- toil/server/wsgi_app.py +4 -3
- toil/serviceManager.py +58 -22
- toil/statsAndLogging.py +183 -65
- toil/test/__init__.py +263 -179
- toil/test/batchSystems/batchSystemTest.py +438 -195
- toil/test/batchSystems/batch_system_plugin_test.py +18 -7
- toil/test/batchSystems/test_gridengine.py +173 -0
- toil/test/batchSystems/test_lsf_helper.py +67 -58
- toil/test/batchSystems/test_slurm.py +265 -49
- toil/test/cactus/test_cactus_integration.py +20 -22
- toil/test/cwl/conftest.py +39 -0
- toil/test/cwl/cwlTest.py +375 -72
- toil/test/cwl/measure_default_memory.cwl +12 -0
- toil/test/cwl/not_run_required_input.cwl +29 -0
- toil/test/cwl/optional-file.cwl +18 -0
- toil/test/cwl/scatter_duplicate_outputs.cwl +40 -0
- toil/test/docs/scriptsTest.py +60 -34
- toil/test/jobStores/jobStoreTest.py +412 -235
- toil/test/lib/aws/test_iam.py +116 -48
- toil/test/lib/aws/test_s3.py +16 -9
- toil/test/lib/aws/test_utils.py +5 -6
- toil/test/lib/dockerTest.py +118 -141
- toil/test/lib/test_conversions.py +113 -115
- toil/test/lib/test_ec2.py +57 -49
- toil/test/lib/test_history.py +212 -0
- toil/test/lib/test_misc.py +12 -5
- toil/test/lib/test_trs.py +161 -0
- toil/test/mesos/MesosDataStructuresTest.py +23 -10
- toil/test/mesos/helloWorld.py +7 -6
- toil/test/mesos/stress.py +25 -20
- toil/test/options/options.py +7 -2
- toil/test/provisioners/aws/awsProvisionerTest.py +293 -140
- toil/test/provisioners/clusterScalerTest.py +440 -250
- toil/test/provisioners/clusterTest.py +81 -42
- toil/test/provisioners/gceProvisionerTest.py +174 -100
- toil/test/provisioners/provisionerTest.py +25 -13
- toil/test/provisioners/restartScript.py +5 -4
- toil/test/server/serverTest.py +188 -141
- toil/test/sort/restart_sort.py +137 -68
- toil/test/sort/sort.py +134 -66
- toil/test/sort/sortTest.py +91 -49
- toil/test/src/autoDeploymentTest.py +140 -100
- toil/test/src/busTest.py +20 -18
- toil/test/src/checkpointTest.py +8 -2
- toil/test/src/deferredFunctionTest.py +49 -35
- toil/test/src/dockerCheckTest.py +33 -26
- toil/test/src/environmentTest.py +20 -10
- toil/test/src/fileStoreTest.py +538 -271
- toil/test/src/helloWorldTest.py +7 -4
- toil/test/src/importExportFileTest.py +61 -31
- toil/test/src/jobDescriptionTest.py +32 -17
- toil/test/src/jobEncapsulationTest.py +2 -0
- toil/test/src/jobFileStoreTest.py +74 -50
- toil/test/src/jobServiceTest.py +187 -73
- toil/test/src/jobTest.py +120 -70
- toil/test/src/miscTests.py +19 -18
- toil/test/src/promisedRequirementTest.py +82 -36
- toil/test/src/promisesTest.py +7 -6
- toil/test/src/realtimeLoggerTest.py +6 -6
- toil/test/src/regularLogTest.py +71 -37
- toil/test/src/resourceTest.py +80 -49
- toil/test/src/restartDAGTest.py +36 -22
- toil/test/src/resumabilityTest.py +9 -2
- toil/test/src/retainTempDirTest.py +45 -14
- toil/test/src/systemTest.py +12 -8
- toil/test/src/threadingTest.py +44 -25
- toil/test/src/toilContextManagerTest.py +10 -7
- toil/test/src/userDefinedJobArgTypeTest.py +8 -5
- toil/test/src/workerTest.py +33 -16
- toil/test/utils/toilDebugTest.py +70 -58
- toil/test/utils/toilKillTest.py +4 -5
- toil/test/utils/utilsTest.py +239 -102
- toil/test/wdl/wdltoil_test.py +789 -148
- toil/test/wdl/wdltoil_test_kubernetes.py +37 -23
- toil/toilState.py +52 -26
- toil/utils/toilConfig.py +13 -4
- toil/utils/toilDebugFile.py +44 -27
- toil/utils/toilDebugJob.py +85 -25
- toil/utils/toilDestroyCluster.py +11 -6
- toil/utils/toilKill.py +8 -3
- toil/utils/toilLaunchCluster.py +251 -145
- toil/utils/toilMain.py +37 -16
- toil/utils/toilRsyncCluster.py +27 -14
- toil/utils/toilSshCluster.py +45 -22
- toil/utils/toilStats.py +75 -36
- toil/utils/toilStatus.py +226 -119
- toil/utils/toilUpdateEC2Instances.py +3 -1
- toil/version.py +6 -6
- toil/wdl/utils.py +5 -5
- toil/wdl/wdltoil.py +3528 -1053
- toil/worker.py +370 -149
- toil-8.1.0b1.dist-info/METADATA +178 -0
- toil-8.1.0b1.dist-info/RECORD +259 -0
- {toil-7.0.0.dist-info → toil-8.1.0b1.dist-info}/WHEEL +1 -1
- toil-7.0.0.dist-info/METADATA +0 -158
- toil-7.0.0.dist-info/RECORD +0 -244
- {toil-7.0.0.dist-info → toil-8.1.0b1.dist-info}/LICENSE +0 -0
- {toil-7.0.0.dist-info → toil-8.1.0b1.dist-info}/entry_points.txt +0 -0
- {toil-7.0.0.dist-info → toil-8.1.0b1.dist-info}/top_level.txt +0 -0
|
@@ -15,16 +15,21 @@ import logging
|
|
|
15
15
|
import os
|
|
16
16
|
import subprocess
|
|
17
17
|
import time
|
|
18
|
-
|
|
18
|
+
from typing import Optional
|
|
19
19
|
from uuid import uuid4
|
|
20
|
-
from typing import Optional, List
|
|
21
20
|
|
|
22
|
-
from toil.lib.retry import retry
|
|
23
|
-
from toil.test import ToilTest, needs_aws_ec2, needs_fetchable_appliance, slow, needs_env_var
|
|
24
21
|
from toil.lib.aws import zone_to_region
|
|
25
22
|
from toil.lib.aws.session import AWSConnectionManager
|
|
23
|
+
from toil.lib.retry import retry
|
|
26
24
|
from toil.provisioners import cluster_factory
|
|
27
25
|
from toil.provisioners.aws import get_best_aws_zone
|
|
26
|
+
from toil.test import (
|
|
27
|
+
ToilTest,
|
|
28
|
+
needs_aws_ec2,
|
|
29
|
+
needs_env_var,
|
|
30
|
+
needs_fetchable_appliance,
|
|
31
|
+
slow,
|
|
32
|
+
)
|
|
28
33
|
|
|
29
34
|
log = logging.getLogger(__name__)
|
|
30
35
|
|
|
@@ -34,31 +39,33 @@ log = logging.getLogger(__name__)
|
|
|
34
39
|
class AbstractClusterTest(ToilTest):
|
|
35
40
|
def __init__(self, methodName: str) -> None:
|
|
36
41
|
super().__init__(methodName=methodName)
|
|
37
|
-
self.keyName = os.getenv(
|
|
38
|
-
self.clusterName = f
|
|
39
|
-
self.leaderNodeType =
|
|
40
|
-
self.clusterType =
|
|
42
|
+
self.keyName = os.getenv("TOIL_AWS_KEYNAME").strip() or "id_rsa"
|
|
43
|
+
self.clusterName = f"aws-provisioner-test-{uuid4()}"
|
|
44
|
+
self.leaderNodeType = "t2.medium"
|
|
45
|
+
self.clusterType = "mesos"
|
|
41
46
|
self.zone = get_best_aws_zone()
|
|
42
|
-
assert
|
|
47
|
+
assert (
|
|
48
|
+
self.zone is not None
|
|
49
|
+
), "Could not determine AWS availability zone to test in; is TOIL_AWS_ZONE set?"
|
|
43
50
|
self.region = zone_to_region(self.zone)
|
|
44
51
|
|
|
45
52
|
# Get connection to AWS
|
|
46
53
|
self.aws = AWSConnectionManager()
|
|
47
54
|
|
|
48
55
|
# Where should we put our virtualenv?
|
|
49
|
-
self.venvDir =
|
|
56
|
+
self.venvDir = "/tmp/venv"
|
|
50
57
|
|
|
51
58
|
def python(self) -> str:
|
|
52
59
|
"""
|
|
53
60
|
Return the full path to the venv Python on the leader.
|
|
54
61
|
"""
|
|
55
|
-
return os.path.join(self.venvDir,
|
|
62
|
+
return os.path.join(self.venvDir, "bin/python")
|
|
56
63
|
|
|
57
64
|
def pip(self) -> str:
|
|
58
65
|
"""
|
|
59
66
|
Return the full path to the venv pip on the leader.
|
|
60
67
|
"""
|
|
61
|
-
return os.path.join(self.venvDir,
|
|
68
|
+
return os.path.join(self.venvDir, "bin/pip")
|
|
62
69
|
|
|
63
70
|
def destroyCluster(self) -> None:
|
|
64
71
|
"""
|
|
@@ -66,7 +73,9 @@ class AbstractClusterTest(ToilTest):
|
|
|
66
73
|
|
|
67
74
|
Succeeds if the cluster does not currently exist.
|
|
68
75
|
"""
|
|
69
|
-
subprocess.check_call(
|
|
76
|
+
subprocess.check_call(
|
|
77
|
+
["toil", "destroy-cluster", "-p=aws", "-z", self.zone, self.clusterName]
|
|
78
|
+
)
|
|
70
79
|
|
|
71
80
|
def setUp(self) -> None:
|
|
72
81
|
"""
|
|
@@ -82,71 +91,83 @@ class AbstractClusterTest(ToilTest):
|
|
|
82
91
|
# Note that teardown will run even if the test crashes.
|
|
83
92
|
super().tearDown()
|
|
84
93
|
self.destroyCluster()
|
|
85
|
-
subprocess.check_call([
|
|
94
|
+
subprocess.check_call(["toil", "clean", self.jobStore])
|
|
86
95
|
|
|
87
|
-
def sshUtil(self, command:
|
|
96
|
+
def sshUtil(self, command: list[str]) -> None:
|
|
88
97
|
"""
|
|
89
98
|
Run the given command on the cluster.
|
|
90
99
|
Raise subprocess.CalledProcessError if it fails.
|
|
91
100
|
"""
|
|
92
101
|
|
|
93
|
-
cmd = [
|
|
102
|
+
cmd = [
|
|
103
|
+
"toil",
|
|
104
|
+
"ssh-cluster",
|
|
105
|
+
"--insecure",
|
|
106
|
+
"-p=aws",
|
|
107
|
+
"-z",
|
|
108
|
+
self.zone,
|
|
109
|
+
self.clusterName,
|
|
110
|
+
] + command
|
|
94
111
|
log.info("Running %s.", str(cmd))
|
|
95
112
|
p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
96
113
|
# Put in non-blocking mode. See https://stackoverflow.com/a/59291466
|
|
97
114
|
os.set_blocking(p.stdout.fileno(), False)
|
|
98
115
|
os.set_blocking(p.stderr.fileno(), False)
|
|
99
116
|
|
|
100
|
-
out_buffer = b
|
|
101
|
-
err_buffer = b
|
|
117
|
+
out_buffer = b""
|
|
118
|
+
err_buffer = b""
|
|
102
119
|
|
|
103
120
|
loops_since_line = 0
|
|
104
121
|
|
|
105
122
|
running = True
|
|
106
123
|
while running:
|
|
107
124
|
# While the process is running, see if it stopped
|
|
108
|
-
running =
|
|
125
|
+
running = p.poll() is None
|
|
109
126
|
|
|
110
127
|
# Also collect its output
|
|
111
128
|
out_data = p.stdout.read()
|
|
112
129
|
if out_data:
|
|
113
130
|
out_buffer += out_data
|
|
114
131
|
|
|
115
|
-
while out_buffer.find(b
|
|
132
|
+
while out_buffer.find(b"\n") != -1:
|
|
116
133
|
# And log every full line
|
|
117
|
-
cut = out_buffer.find(b
|
|
118
|
-
log.info(
|
|
134
|
+
cut = out_buffer.find(b"\n")
|
|
135
|
+
log.info(
|
|
136
|
+
"STDOUT: %s", out_buffer[0:cut].decode("utf-8", errors="ignore")
|
|
137
|
+
)
|
|
119
138
|
loops_since_line = 0
|
|
120
|
-
out_buffer = out_buffer[cut+1:]
|
|
139
|
+
out_buffer = out_buffer[cut + 1 :]
|
|
121
140
|
|
|
122
141
|
# Same for the error
|
|
123
142
|
err_data = p.stderr.read()
|
|
124
143
|
if err_data:
|
|
125
144
|
err_buffer += err_data
|
|
126
145
|
|
|
127
|
-
while err_buffer.find(b
|
|
128
|
-
cut = err_buffer.find(b
|
|
129
|
-
log.info(
|
|
146
|
+
while err_buffer.find(b"\n") != -1:
|
|
147
|
+
cut = err_buffer.find(b"\n")
|
|
148
|
+
log.info(
|
|
149
|
+
"STDERR: %s", err_buffer[0:cut].decode("utf-8", errors="ignore")
|
|
150
|
+
)
|
|
130
151
|
loops_since_line = 0
|
|
131
|
-
err_buffer = err_buffer[cut+1:]
|
|
152
|
+
err_buffer = err_buffer[cut + 1 :]
|
|
132
153
|
|
|
133
154
|
loops_since_line += 1
|
|
134
155
|
if loops_since_line > 60:
|
|
135
|
-
log.debug(
|
|
156
|
+
log.debug("...waiting...")
|
|
136
157
|
loops_since_line = 0
|
|
137
158
|
|
|
138
159
|
time.sleep(1)
|
|
139
160
|
|
|
140
161
|
# At the end, log the last lines
|
|
141
162
|
if out_buffer:
|
|
142
|
-
log.info(
|
|
163
|
+
log.info("STDOUT: %s", out_buffer.decode("utf-8", errors="ignore"))
|
|
143
164
|
if err_buffer:
|
|
144
|
-
log.info(
|
|
165
|
+
log.info("STDERR: %s", err_buffer.decode("utf-8", errors="ignore"))
|
|
145
166
|
|
|
146
167
|
if p.returncode != 0:
|
|
147
168
|
# It failed
|
|
148
169
|
log.error("Failed to run %s.", str(cmd))
|
|
149
|
-
raise subprocess.CalledProcessError(p.returncode,
|
|
170
|
+
raise subprocess.CalledProcessError(p.returncode, " ".join(cmd))
|
|
150
171
|
|
|
151
172
|
@retry(errors=[subprocess.CalledProcessError], intervals=[1, 1])
|
|
152
173
|
def rsync_util(self, from_file: str, to_file: str) -> None:
|
|
@@ -155,18 +176,38 @@ class AbstractClusterTest(ToilTest):
|
|
|
155
176
|
|
|
156
177
|
The cluster-side path should have a ':' in front of it.
|
|
157
178
|
"""
|
|
158
|
-
cmd = [
|
|
179
|
+
cmd = [
|
|
180
|
+
"toil",
|
|
181
|
+
"rsync-cluster",
|
|
182
|
+
"--insecure",
|
|
183
|
+
"-p=aws",
|
|
184
|
+
"-z",
|
|
185
|
+
self.zone,
|
|
186
|
+
self.clusterName,
|
|
187
|
+
from_file,
|
|
188
|
+
to_file,
|
|
189
|
+
]
|
|
159
190
|
log.info("Running %s.", str(cmd))
|
|
160
191
|
subprocess.check_call(cmd)
|
|
161
192
|
|
|
162
193
|
@retry(errors=[subprocess.CalledProcessError], intervals=[1, 1])
|
|
163
|
-
def createClusterUtil(self, args: Optional[
|
|
194
|
+
def createClusterUtil(self, args: Optional[list[str]] = None) -> None:
|
|
164
195
|
args = [] if args is None else args
|
|
165
196
|
|
|
166
|
-
command = [
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
197
|
+
command = [
|
|
198
|
+
"toil",
|
|
199
|
+
"launch-cluster",
|
|
200
|
+
"-p=aws",
|
|
201
|
+
"-z",
|
|
202
|
+
self.zone,
|
|
203
|
+
f"--keyPairName={self.keyName}",
|
|
204
|
+
f"--leaderNodeType={self.leaderNodeType}",
|
|
205
|
+
f"--clusterType={self.clusterType}",
|
|
206
|
+
"--logDebug",
|
|
207
|
+
self.clusterName,
|
|
208
|
+
] + args
|
|
209
|
+
|
|
210
|
+
log.debug("Launching cluster: %s", command)
|
|
170
211
|
|
|
171
212
|
# Try creating the cluster
|
|
172
213
|
subprocess.check_call(command)
|
|
@@ -181,9 +222,10 @@ class AbstractClusterTest(ToilTest):
|
|
|
181
222
|
@slow
|
|
182
223
|
class CWLOnARMTest(AbstractClusterTest):
|
|
183
224
|
"""Run the CWL 1.2 conformance tests on ARM specifically."""
|
|
225
|
+
|
|
184
226
|
def __init__(self, methodName: str) -> None:
|
|
185
227
|
super().__init__(methodName=methodName)
|
|
186
|
-
self.clusterName = f
|
|
228
|
+
self.clusterName = f"cwl-test-{uuid4()}"
|
|
187
229
|
self.leaderNodeType = "t4g.2xlarge"
|
|
188
230
|
self.clusterType = "kubernetes"
|
|
189
231
|
# We need to be running in a directory which Flatcar and the Toil Appliance both have
|
|
@@ -247,8 +289,5 @@ class CWLOnARMTest(AbstractClusterTest):
|
|
|
247
289
|
# Bring it back to be an artifact.
|
|
248
290
|
self.rsync_util(
|
|
249
291
|
f":{self.cwl_test_dir}/toil/conformance-1.2.junit.xml",
|
|
250
|
-
os.path.join(
|
|
251
|
-
self._projectRootPath(),
|
|
252
|
-
"arm-conformance-1.2.junit.xml"
|
|
253
|
-
)
|
|
292
|
+
os.path.join(self._projectRootPath(), "arm-conformance-1.2.junit.xml"),
|
|
254
293
|
)
|