toil 7.0.0__py3-none-any.whl → 8.0.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.
Files changed (190) hide show
  1. toil/__init__.py +121 -83
  2. toil/batchSystems/__init__.py +1 -0
  3. toil/batchSystems/abstractBatchSystem.py +137 -77
  4. toil/batchSystems/abstractGridEngineBatchSystem.py +211 -101
  5. toil/batchSystems/awsBatch.py +237 -128
  6. toil/batchSystems/cleanup_support.py +22 -16
  7. toil/batchSystems/contained_executor.py +30 -26
  8. toil/batchSystems/gridengine.py +85 -49
  9. toil/batchSystems/htcondor.py +164 -87
  10. toil/batchSystems/kubernetes.py +622 -386
  11. toil/batchSystems/local_support.py +17 -12
  12. toil/batchSystems/lsf.py +132 -79
  13. toil/batchSystems/lsfHelper.py +13 -11
  14. toil/batchSystems/mesos/__init__.py +41 -29
  15. toil/batchSystems/mesos/batchSystem.py +288 -149
  16. toil/batchSystems/mesos/executor.py +77 -49
  17. toil/batchSystems/mesos/test/__init__.py +31 -23
  18. toil/batchSystems/options.py +38 -29
  19. toil/batchSystems/registry.py +53 -19
  20. toil/batchSystems/singleMachine.py +293 -123
  21. toil/batchSystems/slurm.py +489 -137
  22. toil/batchSystems/torque.py +46 -32
  23. toil/bus.py +141 -73
  24. toil/common.py +630 -359
  25. toil/cwl/__init__.py +1 -1
  26. toil/cwl/cwltoil.py +1114 -532
  27. toil/cwl/utils.py +17 -22
  28. toil/deferred.py +62 -41
  29. toil/exceptions.py +5 -3
  30. toil/fileStores/__init__.py +5 -5
  31. toil/fileStores/abstractFileStore.py +88 -57
  32. toil/fileStores/cachingFileStore.py +711 -247
  33. toil/fileStores/nonCachingFileStore.py +113 -75
  34. toil/job.py +988 -315
  35. toil/jobStores/abstractJobStore.py +387 -243
  36. toil/jobStores/aws/jobStore.py +727 -403
  37. toil/jobStores/aws/utils.py +161 -109
  38. toil/jobStores/conftest.py +1 -0
  39. toil/jobStores/fileJobStore.py +289 -151
  40. toil/jobStores/googleJobStore.py +137 -70
  41. toil/jobStores/utils.py +36 -15
  42. toil/leader.py +614 -269
  43. toil/lib/accelerators.py +115 -18
  44. toil/lib/aws/__init__.py +55 -28
  45. toil/lib/aws/ami.py +122 -87
  46. toil/lib/aws/iam.py +284 -108
  47. toil/lib/aws/s3.py +31 -0
  48. toil/lib/aws/session.py +193 -58
  49. toil/lib/aws/utils.py +238 -218
  50. toil/lib/bioio.py +13 -5
  51. toil/lib/compatibility.py +11 -6
  52. toil/lib/conversions.py +83 -49
  53. toil/lib/docker.py +131 -103
  54. toil/lib/ec2.py +322 -209
  55. toil/lib/ec2nodes.py +174 -106
  56. toil/lib/encryption/_dummy.py +5 -3
  57. toil/lib/encryption/_nacl.py +10 -6
  58. toil/lib/encryption/conftest.py +1 -0
  59. toil/lib/exceptions.py +26 -7
  60. toil/lib/expando.py +4 -2
  61. toil/lib/ftp_utils.py +217 -0
  62. toil/lib/generatedEC2Lists.py +127 -19
  63. toil/lib/humanize.py +6 -2
  64. toil/lib/integration.py +341 -0
  65. toil/lib/io.py +99 -11
  66. toil/lib/iterables.py +4 -2
  67. toil/lib/memoize.py +12 -8
  68. toil/lib/misc.py +65 -18
  69. toil/lib/objects.py +2 -2
  70. toil/lib/resources.py +19 -7
  71. toil/lib/retry.py +115 -77
  72. toil/lib/threading.py +282 -80
  73. toil/lib/throttle.py +15 -14
  74. toil/options/common.py +834 -401
  75. toil/options/cwl.py +175 -90
  76. toil/options/runner.py +50 -0
  77. toil/options/wdl.py +70 -19
  78. toil/provisioners/__init__.py +111 -46
  79. toil/provisioners/abstractProvisioner.py +322 -157
  80. toil/provisioners/aws/__init__.py +62 -30
  81. toil/provisioners/aws/awsProvisioner.py +980 -627
  82. toil/provisioners/clusterScaler.py +541 -279
  83. toil/provisioners/gceProvisioner.py +282 -179
  84. toil/provisioners/node.py +147 -79
  85. toil/realtimeLogger.py +34 -22
  86. toil/resource.py +137 -75
  87. toil/server/app.py +127 -61
  88. toil/server/celery_app.py +3 -1
  89. toil/server/cli/wes_cwl_runner.py +82 -53
  90. toil/server/utils.py +54 -28
  91. toil/server/wes/abstract_backend.py +64 -26
  92. toil/server/wes/amazon_wes_utils.py +21 -15
  93. toil/server/wes/tasks.py +121 -63
  94. toil/server/wes/toil_backend.py +142 -107
  95. toil/server/wsgi_app.py +4 -3
  96. toil/serviceManager.py +58 -22
  97. toil/statsAndLogging.py +148 -64
  98. toil/test/__init__.py +263 -179
  99. toil/test/batchSystems/batchSystemTest.py +438 -195
  100. toil/test/batchSystems/batch_system_plugin_test.py +18 -7
  101. toil/test/batchSystems/test_gridengine.py +173 -0
  102. toil/test/batchSystems/test_lsf_helper.py +67 -58
  103. toil/test/batchSystems/test_slurm.py +93 -47
  104. toil/test/cactus/test_cactus_integration.py +20 -22
  105. toil/test/cwl/cwlTest.py +271 -71
  106. toil/test/cwl/measure_default_memory.cwl +12 -0
  107. toil/test/cwl/not_run_required_input.cwl +29 -0
  108. toil/test/cwl/scatter_duplicate_outputs.cwl +40 -0
  109. toil/test/docs/scriptsTest.py +60 -34
  110. toil/test/jobStores/jobStoreTest.py +412 -235
  111. toil/test/lib/aws/test_iam.py +116 -48
  112. toil/test/lib/aws/test_s3.py +16 -9
  113. toil/test/lib/aws/test_utils.py +5 -6
  114. toil/test/lib/dockerTest.py +118 -141
  115. toil/test/lib/test_conversions.py +113 -115
  116. toil/test/lib/test_ec2.py +57 -49
  117. toil/test/lib/test_integration.py +104 -0
  118. toil/test/lib/test_misc.py +12 -5
  119. toil/test/mesos/MesosDataStructuresTest.py +23 -10
  120. toil/test/mesos/helloWorld.py +7 -6
  121. toil/test/mesos/stress.py +25 -20
  122. toil/test/options/options.py +7 -2
  123. toil/test/provisioners/aws/awsProvisionerTest.py +293 -140
  124. toil/test/provisioners/clusterScalerTest.py +440 -250
  125. toil/test/provisioners/clusterTest.py +81 -42
  126. toil/test/provisioners/gceProvisionerTest.py +174 -100
  127. toil/test/provisioners/provisionerTest.py +25 -13
  128. toil/test/provisioners/restartScript.py +5 -4
  129. toil/test/server/serverTest.py +188 -141
  130. toil/test/sort/restart_sort.py +137 -68
  131. toil/test/sort/sort.py +134 -66
  132. toil/test/sort/sortTest.py +91 -49
  133. toil/test/src/autoDeploymentTest.py +140 -100
  134. toil/test/src/busTest.py +20 -18
  135. toil/test/src/checkpointTest.py +8 -2
  136. toil/test/src/deferredFunctionTest.py +49 -35
  137. toil/test/src/dockerCheckTest.py +33 -26
  138. toil/test/src/environmentTest.py +20 -10
  139. toil/test/src/fileStoreTest.py +538 -271
  140. toil/test/src/helloWorldTest.py +7 -4
  141. toil/test/src/importExportFileTest.py +61 -31
  142. toil/test/src/jobDescriptionTest.py +32 -17
  143. toil/test/src/jobEncapsulationTest.py +2 -0
  144. toil/test/src/jobFileStoreTest.py +74 -50
  145. toil/test/src/jobServiceTest.py +187 -73
  146. toil/test/src/jobTest.py +120 -70
  147. toil/test/src/miscTests.py +19 -18
  148. toil/test/src/promisedRequirementTest.py +82 -36
  149. toil/test/src/promisesTest.py +7 -6
  150. toil/test/src/realtimeLoggerTest.py +6 -6
  151. toil/test/src/regularLogTest.py +71 -37
  152. toil/test/src/resourceTest.py +80 -49
  153. toil/test/src/restartDAGTest.py +36 -22
  154. toil/test/src/resumabilityTest.py +9 -2
  155. toil/test/src/retainTempDirTest.py +45 -14
  156. toil/test/src/systemTest.py +12 -8
  157. toil/test/src/threadingTest.py +44 -25
  158. toil/test/src/toilContextManagerTest.py +10 -7
  159. toil/test/src/userDefinedJobArgTypeTest.py +8 -5
  160. toil/test/src/workerTest.py +33 -16
  161. toil/test/utils/toilDebugTest.py +70 -58
  162. toil/test/utils/toilKillTest.py +4 -5
  163. toil/test/utils/utilsTest.py +239 -102
  164. toil/test/wdl/wdltoil_test.py +789 -148
  165. toil/test/wdl/wdltoil_test_kubernetes.py +37 -23
  166. toil/toilState.py +52 -26
  167. toil/utils/toilConfig.py +13 -4
  168. toil/utils/toilDebugFile.py +44 -27
  169. toil/utils/toilDebugJob.py +85 -25
  170. toil/utils/toilDestroyCluster.py +11 -6
  171. toil/utils/toilKill.py +8 -3
  172. toil/utils/toilLaunchCluster.py +251 -145
  173. toil/utils/toilMain.py +37 -16
  174. toil/utils/toilRsyncCluster.py +27 -14
  175. toil/utils/toilSshCluster.py +45 -22
  176. toil/utils/toilStats.py +75 -36
  177. toil/utils/toilStatus.py +226 -119
  178. toil/utils/toilUpdateEC2Instances.py +3 -1
  179. toil/version.py +11 -11
  180. toil/wdl/utils.py +5 -5
  181. toil/wdl/wdltoil.py +3513 -1052
  182. toil/worker.py +269 -128
  183. toil-8.0.0.dist-info/METADATA +173 -0
  184. toil-8.0.0.dist-info/RECORD +253 -0
  185. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/WHEEL +1 -1
  186. toil-7.0.0.dist-info/METADATA +0 -158
  187. toil-7.0.0.dist-info/RECORD +0 -244
  188. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/LICENSE +0 -0
  189. {toil-7.0.0.dist-info → toil-8.0.0.dist-info}/entry_points.txt +0 -0
  190. {toil-7.0.0.dist-info → toil-8.0.0.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('TOIL_AWS_KEYNAME').strip() or 'id_rsa'
38
- self.clusterName = f'aws-provisioner-test-{uuid4()}'
39
- self.leaderNodeType = 't2.medium'
40
- self.clusterType = 'mesos'
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 self.zone is not None, "Could not determine AWS availability zone to test in; is TOIL_AWS_ZONE set?"
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 = '/tmp/venv'
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, 'bin/python')
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, 'bin/pip')
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(['toil', 'destroy-cluster', '-p=aws', '-z', self.zone, self.clusterName])
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(['toil', 'clean', self.jobStore])
94
+ subprocess.check_call(["toil", "clean", self.jobStore])
86
95
 
87
- def sshUtil(self, command: List[str]) -> None:
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 = ['toil', 'ssh-cluster', '--insecure', '-p=aws', '-z', self.zone, self.clusterName] + command
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 = (p.poll() is None)
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'\n') != -1:
132
+ while out_buffer.find(b"\n") != -1:
116
133
  # And log every full line
117
- cut = out_buffer.find(b'\n')
118
- log.info('STDOUT: %s', out_buffer[0:cut].decode('utf-8', errors='ignore'))
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'\n') != -1:
128
- cut = err_buffer.find(b'\n')
129
- log.info('STDERR: %s', err_buffer[0:cut].decode('utf-8', errors='ignore'))
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('...waiting...')
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('STDOUT: %s', out_buffer.decode('utf-8', errors='ignore'))
163
+ log.info("STDOUT: %s", out_buffer.decode("utf-8", errors="ignore"))
143
164
  if err_buffer:
144
- log.info('STDERR: %s', err_buffer.decode('utf-8', errors='ignore'))
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, ' '.join(cmd))
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 = ['toil', 'rsync-cluster', '--insecure', '-p=aws', '-z', self.zone, self.clusterName, from_file, to_file]
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[List[str]]=None) -> None:
194
+ def createClusterUtil(self, args: Optional[list[str]] = None) -> None:
164
195
  args = [] if args is None else args
165
196
 
166
- command = ['toil', 'launch-cluster', '-p=aws', '-z', self.zone, f'--keyPairName={self.keyName}',
167
- f'--leaderNodeType={self.leaderNodeType}', f'--clusterType={self.clusterType}', '--logDebug', self.clusterName] + args
168
-
169
- log.debug('Launching cluster: %s', command)
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'cwl-test-{uuid4()}'
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
  )