toil 6.1.0a1__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 (193) hide show
  1. toil/__init__.py +122 -315
  2. toil/batchSystems/__init__.py +1 -0
  3. toil/batchSystems/abstractBatchSystem.py +173 -89
  4. toil/batchSystems/abstractGridEngineBatchSystem.py +272 -148
  5. toil/batchSystems/awsBatch.py +244 -135
  6. toil/batchSystems/cleanup_support.py +26 -16
  7. toil/batchSystems/contained_executor.py +31 -28
  8. toil/batchSystems/gridengine.py +86 -50
  9. toil/batchSystems/htcondor.py +166 -89
  10. toil/batchSystems/kubernetes.py +632 -382
  11. toil/batchSystems/local_support.py +20 -15
  12. toil/batchSystems/lsf.py +134 -81
  13. toil/batchSystems/lsfHelper.py +13 -11
  14. toil/batchSystems/mesos/__init__.py +41 -29
  15. toil/batchSystems/mesos/batchSystem.py +290 -151
  16. toil/batchSystems/mesos/executor.py +79 -50
  17. toil/batchSystems/mesos/test/__init__.py +31 -23
  18. toil/batchSystems/options.py +46 -28
  19. toil/batchSystems/registry.py +53 -19
  20. toil/batchSystems/singleMachine.py +296 -125
  21. toil/batchSystems/slurm.py +603 -138
  22. toil/batchSystems/torque.py +47 -33
  23. toil/bus.py +186 -76
  24. toil/common.py +664 -368
  25. toil/cwl/__init__.py +1 -1
  26. toil/cwl/cwltoil.py +1136 -483
  27. toil/cwl/utils.py +17 -22
  28. toil/deferred.py +63 -42
  29. toil/exceptions.py +5 -3
  30. toil/fileStores/__init__.py +5 -5
  31. toil/fileStores/abstractFileStore.py +140 -60
  32. toil/fileStores/cachingFileStore.py +717 -269
  33. toil/fileStores/nonCachingFileStore.py +116 -87
  34. toil/job.py +1225 -368
  35. toil/jobStores/abstractJobStore.py +416 -266
  36. toil/jobStores/aws/jobStore.py +863 -477
  37. toil/jobStores/aws/utils.py +201 -120
  38. toil/jobStores/conftest.py +3 -2
  39. toil/jobStores/fileJobStore.py +292 -154
  40. toil/jobStores/googleJobStore.py +140 -74
  41. toil/jobStores/utils.py +36 -15
  42. toil/leader.py +668 -272
  43. toil/lib/accelerators.py +115 -18
  44. toil/lib/aws/__init__.py +74 -31
  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 +214 -39
  49. toil/lib/aws/utils.py +287 -231
  50. toil/lib/bioio.py +13 -5
  51. toil/lib/compatibility.py +11 -6
  52. toil/lib/conversions.py +104 -47
  53. toil/lib/docker.py +131 -103
  54. toil/lib/ec2.py +361 -199
  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 +5 -3
  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 +141 -15
  66. toil/lib/iterables.py +4 -2
  67. toil/lib/memoize.py +12 -8
  68. toil/lib/misc.py +66 -21
  69. toil/lib/objects.py +2 -2
  70. toil/lib/resources.py +68 -15
  71. toil/lib/retry.py +126 -81
  72. toil/lib/threading.py +299 -82
  73. toil/lib/throttle.py +16 -15
  74. toil/options/common.py +843 -409
  75. toil/options/cwl.py +175 -90
  76. toil/options/runner.py +50 -0
  77. toil/options/wdl.py +73 -17
  78. toil/provisioners/__init__.py +117 -46
  79. toil/provisioners/abstractProvisioner.py +332 -157
  80. toil/provisioners/aws/__init__.py +70 -33
  81. toil/provisioners/aws/awsProvisioner.py +1145 -715
  82. toil/provisioners/clusterScaler.py +541 -279
  83. toil/provisioners/gceProvisioner.py +282 -179
  84. toil/provisioners/node.py +155 -79
  85. toil/realtimeLogger.py +34 -22
  86. toil/resource.py +137 -75
  87. toil/server/app.py +128 -62
  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 +224 -70
  98. toil/test/__init__.py +282 -183
  99. toil/test/batchSystems/batchSystemTest.py +460 -210
  100. toil/test/batchSystems/batch_system_plugin_test.py +90 -0
  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 +110 -49
  104. toil/test/cactus/__init__.py +0 -0
  105. toil/test/cactus/test_cactus_integration.py +56 -0
  106. toil/test/cwl/cwlTest.py +496 -287
  107. toil/test/cwl/measure_default_memory.cwl +12 -0
  108. toil/test/cwl/not_run_required_input.cwl +29 -0
  109. toil/test/cwl/scatter_duplicate_outputs.cwl +40 -0
  110. toil/test/cwl/seqtk_seq.cwl +1 -1
  111. toil/test/docs/scriptsTest.py +69 -46
  112. toil/test/jobStores/jobStoreTest.py +427 -264
  113. toil/test/lib/aws/test_iam.py +118 -50
  114. toil/test/lib/aws/test_s3.py +16 -9
  115. toil/test/lib/aws/test_utils.py +5 -6
  116. toil/test/lib/dockerTest.py +118 -141
  117. toil/test/lib/test_conversions.py +113 -115
  118. toil/test/lib/test_ec2.py +58 -50
  119. toil/test/lib/test_integration.py +104 -0
  120. toil/test/lib/test_misc.py +12 -5
  121. toil/test/mesos/MesosDataStructuresTest.py +23 -10
  122. toil/test/mesos/helloWorld.py +7 -6
  123. toil/test/mesos/stress.py +25 -20
  124. toil/test/options/__init__.py +13 -0
  125. toil/test/options/options.py +42 -0
  126. toil/test/provisioners/aws/awsProvisionerTest.py +320 -150
  127. toil/test/provisioners/clusterScalerTest.py +440 -250
  128. toil/test/provisioners/clusterTest.py +166 -44
  129. toil/test/provisioners/gceProvisionerTest.py +174 -100
  130. toil/test/provisioners/provisionerTest.py +25 -13
  131. toil/test/provisioners/restartScript.py +5 -4
  132. toil/test/server/serverTest.py +188 -141
  133. toil/test/sort/restart_sort.py +137 -68
  134. toil/test/sort/sort.py +134 -66
  135. toil/test/sort/sortTest.py +91 -49
  136. toil/test/src/autoDeploymentTest.py +141 -101
  137. toil/test/src/busTest.py +20 -18
  138. toil/test/src/checkpointTest.py +8 -2
  139. toil/test/src/deferredFunctionTest.py +49 -35
  140. toil/test/src/dockerCheckTest.py +32 -24
  141. toil/test/src/environmentTest.py +135 -0
  142. toil/test/src/fileStoreTest.py +539 -272
  143. toil/test/src/helloWorldTest.py +7 -4
  144. toil/test/src/importExportFileTest.py +61 -31
  145. toil/test/src/jobDescriptionTest.py +46 -21
  146. toil/test/src/jobEncapsulationTest.py +2 -0
  147. toil/test/src/jobFileStoreTest.py +74 -50
  148. toil/test/src/jobServiceTest.py +187 -73
  149. toil/test/src/jobTest.py +121 -71
  150. toil/test/src/miscTests.py +19 -18
  151. toil/test/src/promisedRequirementTest.py +82 -36
  152. toil/test/src/promisesTest.py +7 -6
  153. toil/test/src/realtimeLoggerTest.py +10 -6
  154. toil/test/src/regularLogTest.py +71 -37
  155. toil/test/src/resourceTest.py +80 -49
  156. toil/test/src/restartDAGTest.py +36 -22
  157. toil/test/src/resumabilityTest.py +9 -2
  158. toil/test/src/retainTempDirTest.py +45 -14
  159. toil/test/src/systemTest.py +12 -8
  160. toil/test/src/threadingTest.py +44 -25
  161. toil/test/src/toilContextManagerTest.py +10 -7
  162. toil/test/src/userDefinedJobArgTypeTest.py +8 -5
  163. toil/test/src/workerTest.py +73 -23
  164. toil/test/utils/toilDebugTest.py +103 -33
  165. toil/test/utils/toilKillTest.py +4 -5
  166. toil/test/utils/utilsTest.py +245 -106
  167. toil/test/wdl/wdltoil_test.py +818 -149
  168. toil/test/wdl/wdltoil_test_kubernetes.py +91 -0
  169. toil/toilState.py +120 -35
  170. toil/utils/toilConfig.py +13 -4
  171. toil/utils/toilDebugFile.py +44 -27
  172. toil/utils/toilDebugJob.py +214 -27
  173. toil/utils/toilDestroyCluster.py +11 -6
  174. toil/utils/toilKill.py +8 -3
  175. toil/utils/toilLaunchCluster.py +256 -140
  176. toil/utils/toilMain.py +37 -16
  177. toil/utils/toilRsyncCluster.py +32 -14
  178. toil/utils/toilSshCluster.py +49 -22
  179. toil/utils/toilStats.py +356 -273
  180. toil/utils/toilStatus.py +292 -139
  181. toil/utils/toilUpdateEC2Instances.py +3 -1
  182. toil/version.py +12 -12
  183. toil/wdl/utils.py +5 -5
  184. toil/wdl/wdltoil.py +3913 -1033
  185. toil/worker.py +367 -184
  186. {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/LICENSE +25 -0
  187. toil-8.0.0.dist-info/METADATA +173 -0
  188. toil-8.0.0.dist-info/RECORD +253 -0
  189. {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/WHEEL +1 -1
  190. toil-6.1.0a1.dist-info/METADATA +0 -125
  191. toil-6.1.0a1.dist-info/RECORD +0 -237
  192. {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/entry_points.txt +0 -0
  193. {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/top_level.txt +0 -0
@@ -11,49 +11,61 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
-
15
14
  import logging
16
15
  import os
17
16
  import subprocess
18
17
  import time
18
+ from typing import Optional
19
19
  from uuid import uuid4
20
20
 
21
21
  from toil.lib.aws import zone_to_region
22
+ from toil.lib.aws.session import AWSConnectionManager
22
23
  from toil.lib.retry import retry
24
+ from toil.provisioners import cluster_factory
23
25
  from toil.provisioners.aws import get_best_aws_zone
24
- from toil.test import ToilTest, needs_aws_ec2, needs_fetchable_appliance
26
+ from toil.test import (
27
+ ToilTest,
28
+ needs_aws_ec2,
29
+ needs_env_var,
30
+ needs_fetchable_appliance,
31
+ slow,
32
+ )
25
33
 
26
34
  log = logging.getLogger(__name__)
27
35
 
36
+
28
37
  @needs_aws_ec2
29
38
  @needs_fetchable_appliance
30
39
  class AbstractClusterTest(ToilTest):
31
- def __init__(self, methodName):
40
+ def __init__(self, methodName: str) -> None:
32
41
  super().__init__(methodName=methodName)
33
- self.keyName = os.getenv('TOIL_AWS_KEYNAME').strip() or 'id_rsa'
34
- self.clusterName = 'aws-provisioner-test-' + str(uuid4())
35
- self.leaderNodeType = 't2.medium'
36
- 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"
37
46
  self.zone = get_best_aws_zone()
38
- assert self.zone is not None, "Could not determine AWS availability zone to test in; is TOIL_AWS_ZONE set?"
39
- # We need a boto2 connection to EC2 to check on the cluster.
40
- # Since we are protected by needs_aws_ec2 we can import from boto.
41
- import boto.ec2
42
- self.boto2_ec2 = boto.ec2.connect_to_region(zone_to_region(self.zone))
47
+ assert (
48
+ self.zone is not None
49
+ ), "Could not determine AWS availability zone to test in; is TOIL_AWS_ZONE set?"
50
+ self.region = zone_to_region(self.zone)
51
+
52
+ # Get connection to AWS
53
+ self.aws = AWSConnectionManager()
54
+
43
55
  # Where should we put our virtualenv?
44
- self.venvDir = '/tmp/venv'
56
+ self.venvDir = "/tmp/venv"
45
57
 
46
- def python(self):
58
+ def python(self) -> str:
47
59
  """
48
60
  Return the full path to the venv Python on the leader.
49
61
  """
50
- return os.path.join(self.venvDir, 'bin/python')
62
+ return os.path.join(self.venvDir, "bin/python")
51
63
 
52
- def pip(self):
64
+ def pip(self) -> str:
53
65
  """
54
66
  Return the full path to the venv pip on the leader.
55
67
  """
56
- return os.path.join(self.venvDir, 'bin/pip')
68
+ return os.path.join(self.venvDir, "bin/pip")
57
69
 
58
70
  def destroyCluster(self) -> None:
59
71
  """
@@ -61,9 +73,11 @@ class AbstractClusterTest(ToilTest):
61
73
 
62
74
  Succeeds if the cluster does not currently exist.
63
75
  """
64
- 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
+ )
65
79
 
66
- def setUp(self):
80
+ def setUp(self) -> None:
67
81
  """
68
82
  Set up for the test.
69
83
  Must be overridden to call this method and set self.jobStore.
@@ -73,75 +87,87 @@ class AbstractClusterTest(ToilTest):
73
87
  # If this fails, no tests will run.
74
88
  self.destroyCluster()
75
89
 
76
- def tearDown(self):
90
+ def tearDown(self) -> None:
77
91
  # Note that teardown will run even if the test crashes.
78
92
  super().tearDown()
79
93
  self.destroyCluster()
80
- subprocess.check_call(['toil', 'clean', self.jobStore])
94
+ subprocess.check_call(["toil", "clean", self.jobStore])
81
95
 
82
- def sshUtil(self, command):
96
+ def sshUtil(self, command: list[str]) -> None:
83
97
  """
84
98
  Run the given command on the cluster.
85
99
  Raise subprocess.CalledProcessError if it fails.
86
100
  """
87
101
 
88
- 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
89
111
  log.info("Running %s.", str(cmd))
90
112
  p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
91
113
  # Put in non-blocking mode. See https://stackoverflow.com/a/59291466
92
114
  os.set_blocking(p.stdout.fileno(), False)
93
115
  os.set_blocking(p.stderr.fileno(), False)
94
116
 
95
- out_buffer = b''
96
- err_buffer = b''
117
+ out_buffer = b""
118
+ err_buffer = b""
97
119
 
98
120
  loops_since_line = 0
99
121
 
100
122
  running = True
101
123
  while running:
102
124
  # While the process is running, see if it stopped
103
- running = (p.poll() is None)
125
+ running = p.poll() is None
104
126
 
105
127
  # Also collect its output
106
128
  out_data = p.stdout.read()
107
129
  if out_data:
108
130
  out_buffer += out_data
109
131
 
110
- while out_buffer.find(b'\n') != -1:
132
+ while out_buffer.find(b"\n") != -1:
111
133
  # And log every full line
112
- cut = out_buffer.find(b'\n')
113
- 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
+ )
114
138
  loops_since_line = 0
115
- out_buffer = out_buffer[cut+1:]
139
+ out_buffer = out_buffer[cut + 1 :]
116
140
 
117
141
  # Same for the error
118
142
  err_data = p.stderr.read()
119
143
  if err_data:
120
144
  err_buffer += err_data
121
145
 
122
- while err_buffer.find(b'\n') != -1:
123
- cut = err_buffer.find(b'\n')
124
- 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
+ )
125
151
  loops_since_line = 0
126
- err_buffer = err_buffer[cut+1:]
152
+ err_buffer = err_buffer[cut + 1 :]
127
153
 
128
154
  loops_since_line += 1
129
155
  if loops_since_line > 60:
130
- log.debug('...waiting...')
156
+ log.debug("...waiting...")
131
157
  loops_since_line = 0
132
158
 
133
159
  time.sleep(1)
134
160
 
135
161
  # At the end, log the last lines
136
162
  if out_buffer:
137
- log.info('STDOUT: %s', out_buffer.decode('utf-8', errors='ignore'))
163
+ log.info("STDOUT: %s", out_buffer.decode("utf-8", errors="ignore"))
138
164
  if err_buffer:
139
- log.info('STDERR: %s', err_buffer.decode('utf-8', errors='ignore'))
165
+ log.info("STDERR: %s", err_buffer.decode("utf-8", errors="ignore"))
140
166
 
141
167
  if p.returncode != 0:
142
168
  # It failed
143
169
  log.error("Failed to run %s.", str(cmd))
144
- raise subprocess.CalledProcessError(p.returncode, ' '.join(cmd))
170
+ raise subprocess.CalledProcessError(p.returncode, " ".join(cmd))
145
171
 
146
172
  @retry(errors=[subprocess.CalledProcessError], intervals=[1, 1])
147
173
  def rsync_util(self, from_file: str, to_file: str) -> None:
@@ -150,22 +176,118 @@ class AbstractClusterTest(ToilTest):
150
176
 
151
177
  The cluster-side path should have a ':' in front of it.
152
178
  """
153
- 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
+ ]
154
190
  log.info("Running %s.", str(cmd))
155
191
  subprocess.check_call(cmd)
156
192
 
157
193
  @retry(errors=[subprocess.CalledProcessError], intervals=[1, 1])
158
- def createClusterUtil(self, args=None):
194
+ def createClusterUtil(self, args: Optional[list[str]] = None) -> None:
159
195
  args = [] if args is None else args
160
196
 
161
- command = ['toil', 'launch-cluster', '-p=aws', '-z', self.zone, f'--keyPairName={self.keyName}',
162
- f'--leaderNodeType={self.leaderNodeType}', f'--clusterType={self.clusterType}', '--logDebug', self.clusterName] + args
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
163
209
 
164
- log.debug('Launching cluster: %s', command)
210
+ log.debug("Launching cluster: %s", command)
165
211
 
166
212
  # Try creating the cluster
167
213
  subprocess.check_call(command)
168
214
  # If we fail, tearDown will destroy the cluster.
169
215
 
170
- def launchCluster(self):
216
+ def launchCluster(self) -> None:
171
217
  self.createClusterUtil()
218
+
219
+
220
+ @needs_aws_ec2
221
+ @needs_fetchable_appliance
222
+ @slow
223
+ class CWLOnARMTest(AbstractClusterTest):
224
+ """Run the CWL 1.2 conformance tests on ARM specifically."""
225
+
226
+ def __init__(self, methodName: str) -> None:
227
+ super().__init__(methodName=methodName)
228
+ self.clusterName = f"cwl-test-{uuid4()}"
229
+ self.leaderNodeType = "t4g.2xlarge"
230
+ self.clusterType = "kubernetes"
231
+ # We need to be running in a directory which Flatcar and the Toil Appliance both have
232
+ self.cwl_test_dir = "/tmp/toil/cwlTests"
233
+
234
+ def setUp(self) -> None:
235
+ super().setUp()
236
+ self.jobStore = f"aws:{self.awsRegion()}:cluster-{uuid4()}"
237
+
238
+ @needs_env_var("CI_COMMIT_SHA", "a git commit sha")
239
+ def test_cwl_on_arm(self) -> None:
240
+ # Make a cluster
241
+ self.launchCluster()
242
+ # get the leader so we know the IP address - we don't need to wait since create cluster
243
+ # already ensures the leader is running
244
+ self.cluster = cluster_factory(
245
+ provisioner="aws", zone=self.zone, clusterName=self.clusterName
246
+ )
247
+ self.leader = self.cluster.getLeader()
248
+
249
+ commit = os.environ["CI_COMMIT_SHA"]
250
+ self.sshUtil(
251
+ [
252
+ "bash",
253
+ "-c",
254
+ f"mkdir -p {self.cwl_test_dir} && cd {self.cwl_test_dir} && git clone https://github.com/DataBiosphere/toil.git",
255
+ ]
256
+ )
257
+
258
+ # We use CI_COMMIT_SHA to retrieve the Toil version needed to run the CWL tests
259
+ self.sshUtil(
260
+ ["bash", "-c", f"cd {self.cwl_test_dir}/toil && git checkout {commit}"]
261
+ )
262
+
263
+ # --never-download prevents silent upgrades to pip, wheel and setuptools
264
+ self.sshUtil(
265
+ [
266
+ "bash",
267
+ "-c",
268
+ f"virtualenv --system-site-packages --never-download {self.venvDir}",
269
+ ]
270
+ )
271
+ self.sshUtil(
272
+ [
273
+ "bash",
274
+ "-c",
275
+ f". .{self.venvDir}/bin/activate && cd {self.cwl_test_dir}/toil && make prepare && make develop extras=[all]",
276
+ ]
277
+ )
278
+
279
+ # Runs the CWLv12Test on an ARM instance
280
+ self.sshUtil(
281
+ [
282
+ "bash",
283
+ "-c",
284
+ f". .{self.venvDir}/bin/activate && cd {self.cwl_test_dir}/toil && pytest --log-cli-level DEBUG -r s src/toil/test/cwl/cwlTest.py::CWLv12Test::test_run_conformance",
285
+ ]
286
+ )
287
+
288
+ # We know if it succeeds it should save a junit XML for us to read.
289
+ # Bring it back to be an artifact.
290
+ self.rsync_util(
291
+ f":{self.cwl_test_dir}/toil/conformance-1.2.junit.xml",
292
+ os.path.join(self._projectRootPath(), "arm-conformance-1.2.junit.xml"),
293
+ )