toil 5.12.0__py3-none-any.whl → 6.1.0a1__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 (157) hide show
  1. toil/__init__.py +18 -13
  2. toil/batchSystems/abstractBatchSystem.py +21 -10
  3. toil/batchSystems/abstractGridEngineBatchSystem.py +2 -2
  4. toil/batchSystems/awsBatch.py +14 -14
  5. toil/batchSystems/contained_executor.py +3 -3
  6. toil/batchSystems/htcondor.py +0 -1
  7. toil/batchSystems/kubernetes.py +34 -31
  8. toil/batchSystems/local_support.py +3 -1
  9. toil/batchSystems/mesos/batchSystem.py +7 -7
  10. toil/batchSystems/options.py +32 -83
  11. toil/batchSystems/registry.py +104 -23
  12. toil/batchSystems/singleMachine.py +16 -13
  13. toil/batchSystems/slurm.py +3 -3
  14. toil/batchSystems/torque.py +0 -1
  15. toil/bus.py +6 -8
  16. toil/common.py +532 -743
  17. toil/cwl/__init__.py +28 -32
  18. toil/cwl/cwltoil.py +523 -520
  19. toil/cwl/utils.py +55 -10
  20. toil/fileStores/__init__.py +2 -2
  21. toil/fileStores/abstractFileStore.py +36 -11
  22. toil/fileStores/cachingFileStore.py +607 -530
  23. toil/fileStores/nonCachingFileStore.py +43 -10
  24. toil/job.py +140 -75
  25. toil/jobStores/abstractJobStore.py +147 -79
  26. toil/jobStores/aws/jobStore.py +23 -9
  27. toil/jobStores/aws/utils.py +1 -2
  28. toil/jobStores/fileJobStore.py +117 -19
  29. toil/jobStores/googleJobStore.py +16 -7
  30. toil/jobStores/utils.py +5 -6
  31. toil/leader.py +71 -43
  32. toil/lib/accelerators.py +10 -5
  33. toil/lib/aws/__init__.py +3 -14
  34. toil/lib/aws/ami.py +22 -9
  35. toil/lib/aws/iam.py +21 -13
  36. toil/lib/aws/session.py +2 -16
  37. toil/lib/aws/utils.py +4 -5
  38. toil/lib/compatibility.py +1 -1
  39. toil/lib/conversions.py +7 -3
  40. toil/lib/docker.py +22 -23
  41. toil/lib/ec2.py +10 -6
  42. toil/lib/ec2nodes.py +106 -100
  43. toil/lib/encryption/_nacl.py +2 -1
  44. toil/lib/generatedEC2Lists.py +325 -18
  45. toil/lib/io.py +21 -0
  46. toil/lib/misc.py +1 -1
  47. toil/lib/resources.py +1 -1
  48. toil/lib/threading.py +74 -26
  49. toil/options/common.py +738 -0
  50. toil/options/cwl.py +336 -0
  51. toil/options/wdl.py +32 -0
  52. toil/provisioners/abstractProvisioner.py +1 -4
  53. toil/provisioners/aws/__init__.py +3 -6
  54. toil/provisioners/aws/awsProvisioner.py +6 -0
  55. toil/provisioners/clusterScaler.py +3 -2
  56. toil/provisioners/gceProvisioner.py +2 -2
  57. toil/realtimeLogger.py +2 -1
  58. toil/resource.py +24 -18
  59. toil/server/app.py +2 -3
  60. toil/server/cli/wes_cwl_runner.py +4 -4
  61. toil/server/utils.py +1 -1
  62. toil/server/wes/abstract_backend.py +3 -2
  63. toil/server/wes/amazon_wes_utils.py +5 -4
  64. toil/server/wes/tasks.py +2 -3
  65. toil/server/wes/toil_backend.py +2 -10
  66. toil/server/wsgi_app.py +2 -0
  67. toil/serviceManager.py +12 -10
  68. toil/statsAndLogging.py +5 -1
  69. toil/test/__init__.py +29 -54
  70. toil/test/batchSystems/batchSystemTest.py +11 -111
  71. toil/test/batchSystems/test_slurm.py +3 -2
  72. toil/test/cwl/cwlTest.py +213 -90
  73. toil/test/cwl/glob_dir.cwl +15 -0
  74. toil/test/cwl/preemptible.cwl +21 -0
  75. toil/test/cwl/preemptible_expression.cwl +28 -0
  76. toil/test/cwl/revsort.cwl +1 -1
  77. toil/test/cwl/revsort2.cwl +1 -1
  78. toil/test/docs/scriptsTest.py +0 -1
  79. toil/test/jobStores/jobStoreTest.py +27 -16
  80. toil/test/lib/aws/test_iam.py +4 -14
  81. toil/test/lib/aws/test_utils.py +0 -3
  82. toil/test/lib/dockerTest.py +4 -4
  83. toil/test/lib/test_ec2.py +11 -16
  84. toil/test/mesos/helloWorld.py +4 -5
  85. toil/test/mesos/stress.py +1 -1
  86. toil/test/provisioners/aws/awsProvisionerTest.py +9 -5
  87. toil/test/provisioners/clusterScalerTest.py +6 -4
  88. toil/test/provisioners/clusterTest.py +14 -3
  89. toil/test/provisioners/gceProvisionerTest.py +0 -6
  90. toil/test/provisioners/restartScript.py +3 -2
  91. toil/test/server/serverTest.py +1 -1
  92. toil/test/sort/restart_sort.py +2 -1
  93. toil/test/sort/sort.py +2 -1
  94. toil/test/sort/sortTest.py +2 -13
  95. toil/test/src/autoDeploymentTest.py +45 -45
  96. toil/test/src/busTest.py +5 -5
  97. toil/test/src/checkpointTest.py +2 -2
  98. toil/test/src/deferredFunctionTest.py +1 -1
  99. toil/test/src/fileStoreTest.py +32 -16
  100. toil/test/src/helloWorldTest.py +1 -1
  101. toil/test/src/importExportFileTest.py +1 -1
  102. toil/test/src/jobDescriptionTest.py +2 -1
  103. toil/test/src/jobServiceTest.py +1 -1
  104. toil/test/src/jobTest.py +18 -18
  105. toil/test/src/miscTests.py +5 -3
  106. toil/test/src/promisedRequirementTest.py +3 -3
  107. toil/test/src/realtimeLoggerTest.py +1 -1
  108. toil/test/src/resourceTest.py +2 -2
  109. toil/test/src/restartDAGTest.py +1 -1
  110. toil/test/src/resumabilityTest.py +36 -2
  111. toil/test/src/retainTempDirTest.py +1 -1
  112. toil/test/src/systemTest.py +2 -2
  113. toil/test/src/toilContextManagerTest.py +2 -2
  114. toil/test/src/userDefinedJobArgTypeTest.py +1 -1
  115. toil/test/utils/toilDebugTest.py +98 -32
  116. toil/test/utils/toilKillTest.py +2 -2
  117. toil/test/utils/utilsTest.py +20 -0
  118. toil/test/wdl/wdltoil_test.py +148 -45
  119. toil/toilState.py +7 -6
  120. toil/utils/toilClean.py +1 -1
  121. toil/utils/toilConfig.py +36 -0
  122. toil/utils/toilDebugFile.py +60 -33
  123. toil/utils/toilDebugJob.py +39 -12
  124. toil/utils/toilDestroyCluster.py +1 -1
  125. toil/utils/toilKill.py +1 -1
  126. toil/utils/toilLaunchCluster.py +13 -2
  127. toil/utils/toilMain.py +3 -2
  128. toil/utils/toilRsyncCluster.py +1 -1
  129. toil/utils/toilSshCluster.py +1 -1
  130. toil/utils/toilStats.py +240 -143
  131. toil/utils/toilStatus.py +1 -4
  132. toil/version.py +11 -11
  133. toil/wdl/utils.py +2 -122
  134. toil/wdl/wdltoil.py +999 -386
  135. toil/worker.py +25 -31
  136. {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/METADATA +60 -53
  137. toil-6.1.0a1.dist-info/RECORD +237 -0
  138. {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/WHEEL +1 -1
  139. {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/entry_points.txt +0 -1
  140. toil/batchSystems/parasol.py +0 -379
  141. toil/batchSystems/tes.py +0 -459
  142. toil/test/batchSystems/parasolTestSupport.py +0 -117
  143. toil/test/wdl/builtinTest.py +0 -506
  144. toil/test/wdl/conftest.py +0 -23
  145. toil/test/wdl/toilwdlTest.py +0 -522
  146. toil/wdl/toilwdl.py +0 -141
  147. toil/wdl/versions/dev.py +0 -107
  148. toil/wdl/versions/draft2.py +0 -980
  149. toil/wdl/versions/v1.py +0 -794
  150. toil/wdl/wdl_analysis.py +0 -116
  151. toil/wdl/wdl_functions.py +0 -997
  152. toil/wdl/wdl_synthesis.py +0 -1011
  153. toil/wdl/wdl_types.py +0 -243
  154. toil-5.12.0.dist-info/RECORD +0 -244
  155. /toil/{wdl/versions → options}/__init__.py +0 -0
  156. {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/LICENSE +0 -0
  157. {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/top_level.txt +0 -0
@@ -1,506 +0,0 @@
1
- import json
2
- import os
3
- import shutil
4
- import subprocess
5
- import unittest
6
- import uuid
7
- from typing import List, Optional
8
-
9
- from toil.test import ToilTest
10
- from toil.version import exactPython
11
- from toil.wdl.wdl_functions import (WDLPair,
12
- WDLRuntimeError,
13
- ceil,
14
- cross,
15
- floor,
16
- length,
17
- read_boolean,
18
- read_float,
19
- read_int,
20
- read_json,
21
- read_lines,
22
- read_map,
23
- read_string,
24
- read_tsv,
25
- sub,
26
- transpose,
27
- wdl_zip,
28
- write_json,
29
- write_lines,
30
- write_map,
31
- write_tsv)
32
-
33
-
34
- class WdlStandardLibraryFunctionsTest(ToilTest):
35
- """ A set of test cases for toil's wdl functions."""
36
-
37
- def setUp(self):
38
- """Runs anew before each test to create farm fresh temp dirs."""
39
- self.output_dir = os.path.join('/tmp/', 'toil-wdl-test-' + str(uuid.uuid4()))
40
- os.makedirs(self.output_dir)
41
- os.makedirs(os.path.join(self.output_dir, 'execution'))
42
-
43
- @classmethod
44
- def setUpClass(cls):
45
- pass
46
-
47
- def tearDown(self):
48
- """Clean up outputs."""
49
- if os.path.exists(self.output_dir):
50
- shutil.rmtree(self.output_dir)
51
-
52
- def _check_output(self, path, expected_result, strip=True):
53
- """ Compare expected_result to content from file."""
54
- with open(path) as f:
55
- result = f.read()
56
- if strip:
57
- result = result.strip()
58
- self.assertEqual(expected_result, result)
59
-
60
- def _write_temp_file(self, function_name, content):
61
- """ Write content to a temp file."""
62
- path = os.path.join(self.output_dir, f'{function_name}_{uuid.uuid4()}.tmp')
63
- with open(path, 'w') as f:
64
- f.write(content + '\n')
65
- return path
66
-
67
- def testFn_Sub(self):
68
- """Test the wdl built-in functional equivalent of 'sub()'."""
69
- # example from the WDL spec.
70
- chocolike = "I like chocolate when it's late"
71
- self.assertEqual("I love chocolate when it's late", sub(chocolike, 'like', 'love'))
72
- self.assertEqual("I like chocoearly when it's early", sub(chocolike, 'late', 'early'))
73
- self.assertEqual("I like chocolate when it's early", sub(chocolike, 'late$', 'early'))
74
-
75
- def testFn_Ceil(self):
76
- """Test the wdl built-in functional equivalent of 'ceil()', which converts
77
- a Float value into an Int by rounding up to the next higher integer"""
78
- assert ceil(1.999) == 2
79
- assert ceil(-1.5) == -1
80
-
81
- def testFn_Floor(self):
82
- """Test the wdl built-in functional equivalent of 'floor()', which converts
83
- a Float value into an Int by rounding down to the next lower integer"""
84
- assert floor(1.999) == 1
85
- assert floor(-1.5) == -2
86
-
87
- def testFn_ReadLines(self):
88
- """Test the wdl built-in functional equivalent of 'read_lines()'."""
89
- # trailing newlines are stripped; spaces are kept
90
- lines = 'line 1\nline 2\t\t\n \n\n'
91
- path = self._write_temp_file('read_lines', lines)
92
- self.assertEqual(['line 1', 'line 2\t\t', ' '], read_lines(path))
93
-
94
- # preceding newlines are kept
95
- lines = '\n\n\nline 1\nline 2\t\t\n '
96
- path = self._write_temp_file('read_lines', lines)
97
- self.assertEqual(['', '', '', 'line 1', 'line 2\t\t', ' '], read_lines(path))
98
-
99
- def testFn_ReadTsv(self):
100
- """Test the wdl built-in functional equivalent of 'read_tsv()'."""
101
- tsv = [['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']]
102
- tsv_str = '1\t2\t3\n4\t5\t6\n7\t8\t9'
103
-
104
- path = self._write_temp_file('read_tsv', tsv_str)
105
- self.assertEqual(tsv, read_tsv(path))
106
-
107
- def testFn_ReadJson(self):
108
- """Test the wdl built-in functional equivalent of 'read_json()'."""
109
- json_obj = {'str': 'some string', 'num': 3.14, 'bool': True, 'null': None, 'arr': ['test']}
110
- json_arr = ['1', '2']
111
- json_num = 3.14
112
-
113
- path = self._write_temp_file('read_json', json.dumps(json_obj))
114
- self.assertEqual(json_obj, read_json(path))
115
-
116
- path = self._write_temp_file('read_json', json.dumps(json_arr))
117
- self.assertEqual(json_arr, read_json(path))
118
-
119
- path = self._write_temp_file('read_json', json.dumps(json_num))
120
- self.assertEqual(json_num, read_json(path))
121
-
122
- def testFn_ReadMap(self):
123
- """Test the wdl built-in functional equivalent of 'read_map()'."""
124
- map_str = 'key1\tvalue1\nkey2\tvalue2'
125
- path = self._write_temp_file('read_map', map_str)
126
- self.assertEqual({'key1': 'value1', 'key2': 'value2'}, read_map(path))
127
-
128
- # extra lines and spaces are stripped, except spaces in keys are kept.
129
- map_str = '\n\n\nkey1 \tvalue1\nkey2\tvalue2 \n \n \t \n'
130
- path = self._write_temp_file('read_map', map_str)
131
- self.assertEqual({'key1 ': 'value1', 'key2': 'value2'}, read_map(path))
132
-
133
- def testFn_ReadInt(self):
134
- """Test the wdl built-in functional equivalent of 'read_int()'."""
135
- num = 10
136
- path = self._write_temp_file('read_int', content=str(num))
137
- self.assertEqual(num, read_int(path))
138
-
139
- num = 10.0
140
- path = self._write_temp_file('read_int', content=str(num))
141
- self.assertRaises(ValueError, read_int, path)
142
-
143
- num = 10.5
144
- path = self._write_temp_file('read_int', content=str(num))
145
- self.assertRaises(ValueError, read_int, path)
146
-
147
- def testFn_ReadString(self):
148
- """Test the wdl built-in functional equivalent of 'read_string()'."""
149
- some_str = 'some string'
150
- path = self._write_temp_file('read_string', content=some_str)
151
- self.assertEqual(some_str, read_string(path))
152
-
153
- # with preceding newlines. Cromwell strips from the front and the end.
154
- path = self._write_temp_file('read_string', content='\n\n\n' + some_str)
155
- self.assertEqual(some_str, read_string(path))
156
-
157
- # with trailing newlines
158
- path = self._write_temp_file('read_string', content=some_str + '\n\n')
159
- self.assertEqual(some_str, read_string(path))
160
-
161
- def testFn_ReadFloat(self):
162
- """Test the wdl built-in functional equivalent of 'read_float()'."""
163
- num = 2.718281828459045
164
- path = self._write_temp_file('read_float', content=str(num))
165
- self.assertEqual(num, read_float(path))
166
-
167
- def testFn_ReadBoolean(self):
168
- """Test the wdl built-in functional equivalent of 'read_boolean()'."""
169
- for val in (True, False):
170
- path = self._write_temp_file('read_boolean', content=str(val))
171
- self.assertEqual(val, read_boolean(path))
172
-
173
- # upper
174
- path = self._write_temp_file('read_boolean', content=str(val).upper())
175
- self.assertEqual(val, read_boolean(path))
176
-
177
- # lower
178
- path = self._write_temp_file('read_boolean', content=str(val).lower())
179
- self.assertEqual(val, read_boolean(path))
180
-
181
- def testFn_WriteLines(self):
182
- """Test the wdl built-in functional equivalent of 'write_lines()'."""
183
- # 'line 1' \n
184
- # 'line 2\t\t' \n
185
- # ' ' \n
186
- # '\n' \n
187
- path = write_lines(['line 1', 'line 2\t\t', ' ', '\n'], temp_dir=self.output_dir)
188
- self._check_output(path, 'line 1\nline 2\t\t\n \n\n\n', strip=False)
189
-
190
- def testFn_WriteTsv(self):
191
- """Test the wdl built-in functional equivalent of 'write_tsv()'."""
192
- path = write_tsv([['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']], temp_dir=self.output_dir)
193
- self._check_output(path, '1\t2\t3\n4\t5\t6\n7\t8\t9')
194
-
195
- def testFn_WriteJson(self):
196
- """Test the wdl built-in functional equivalent of 'write_json()'."""
197
- json_obj = {'str': 'some string', 'num': 3.14, 'bool': True, 'null': None, 'arr': ['test']}
198
- json_arr = ['1', '2']
199
- json_num = 3.14
200
- json_str = 'test string'
201
- json_bool = False
202
- json_null = None
203
-
204
- # Pair[Int, Pair[Int, Pair[Int, Pair[Int, Int]]]]
205
- json_pairs = WDLPair(1, WDLPair(2, WDLPair(3, WDLPair(4, 5))))
206
-
207
- path = write_json(json_obj, temp_dir=self.output_dir)
208
- self._check_output(path, '{"str":"some string","num":3.14,"bool":true,"null":null,"arr":["test"]}')
209
-
210
- path = write_json(json_arr, temp_dir=self.output_dir)
211
- self._check_output(path, '["1","2"]')
212
-
213
- path = write_json(json_num, temp_dir=self.output_dir)
214
- self._check_output(path, '3.14')
215
-
216
- path = write_json(json_str, temp_dir=self.output_dir)
217
- self._check_output(path, '"test string"')
218
-
219
- path = write_json(json_bool, temp_dir=self.output_dir)
220
- self._check_output(path, 'false')
221
-
222
- path = write_json(json_null, temp_dir=self.output_dir)
223
- self._check_output(path, 'null')
224
-
225
- path = write_json(json_pairs, temp_dir=self.output_dir)
226
- self._check_output(path, '{"left":1,"right":{"left":2,"right":{"left":3,"right":{"left":4,"right":5}}}}')
227
-
228
- def testFn_WriteMap(self):
229
- """Test the wdl built-in functional equivalent of 'write_map()'."""
230
- path = write_map({'key1': 'value1', 'key2': 'value2'}, temp_dir=self.output_dir)
231
- self._check_output(path, 'key1\tvalue1\nkey2\tvalue2')
232
-
233
- def testFn_Transpose(self):
234
- """Test the wdl built-in functional equivalent of 'transpose()'."""
235
- self.assertEqual([[0, 3], [1, 4], [2, 5]], transpose([[0, 1, 2], [3, 4, 5]]))
236
- self.assertEqual([[0, 1, 2], [3, 4, 5]], transpose([[0, 3], [1, 4], [2, 5]]))
237
-
238
- self.assertEqual([], transpose([]))
239
- self.assertEqual([], transpose([[]])) # same as Cromwell
240
- self.assertEqual([[0]], transpose([[0]]))
241
- self.assertRaises(AssertionError, transpose, [[0, 1, 2], [3, 4, 5, 6]])
242
-
243
- def testFn_Length(self):
244
- """Test the WDL 'length()' built-in."""
245
- self.assertEqual(3, length([1, 2, 3]))
246
- self.assertEqual(3, length(['a', 'b', 'c']))
247
- self.assertEqual(0, length([]))
248
-
249
- def testFn_Zip(self):
250
- """Test the wdl built-in functional equivalent of 'zip()'."""
251
- left_array = [1, 2, 3]
252
- right_array = ['a', 'b', 'c']
253
- zipped = wdl_zip(left_array, right_array)
254
- expected_results = [WDLPair(1, 'a'), WDLPair(2, 'b'), WDLPair(3, 'c')]
255
-
256
- self.assertEqual(zipped, expected_results)
257
-
258
- # input with different size should fail.
259
- self.assertRaises(WDLRuntimeError, wdl_zip, [1, 2, 3], ['a', 'b'])
260
-
261
- def testFn_Cross(self):
262
- """Test the wdl built-in functional equivalent of 'cross()'."""
263
- left_array = [1, 2, 3]
264
- right_array = ['a', 'b']
265
- crossed = cross(left_array, right_array)
266
- expected_results = [WDLPair(1, 'a'), WDLPair(1, 'b'),
267
- WDLPair(2, 'a'), WDLPair(2, 'b'),
268
- WDLPair(3, 'a'), WDLPair(3, 'b')]
269
-
270
- self.assertEqual(crossed, expected_results)
271
-
272
-
273
- class WdlWorkflowsTest(ToilTest):
274
- """
275
- A set of test cases for toil's conformance with WDL.
276
-
277
- All tests should include a simple wdl and json file for toil to run that checks the output.
278
- """
279
-
280
- @classmethod
281
- def setUpClass(cls):
282
- super().setUpClass()
283
- cls.program = os.path.abspath("src/toil/wdl/toilwdl.py")
284
- cls.test_path = os.path.abspath("src/toil/test/wdl")
285
-
286
- def check_function(self,
287
- function_name: str,
288
- cases: List[str],
289
- json_file_name: Optional[str] = None,
290
- expected_result: Optional[str] = None,
291
- expected_exception: Optional[str] = None):
292
- """
293
- Run the given WDL workflow and check its output. The WDL workflow
294
- should store its output inside a 'output.txt' file that can be
295
- compared to `expected_result`.
296
-
297
- If `expected_exception` is set, this test passes only when both the
298
- workflow fails and that the given `expected_exception` string is
299
- present in standard error.
300
- """
301
- wdl_files = [os.path.abspath(f'{self.test_path}/{function_name}_{case}.wdl')
302
- for case in cases]
303
- json_file = os.path.abspath(f'{self.test_path}/{json_file_name or function_name}.json')
304
- for wdl_file in wdl_files:
305
- with self.subTest(f'Testing: {wdl_file} {json_file}'):
306
- output_dir = f'/tmp/toil-wdl-test-{uuid.uuid4()}'
307
- os.makedirs(output_dir)
308
-
309
- if expected_exception is not None:
310
- with self.assertRaises(subprocess.CalledProcessError) as context:
311
- # use check_output() here so that the output is read before return.
312
- subprocess.check_output([exactPython, self.program, wdl_file, json_file, '-o', output_dir],
313
- stderr=subprocess.PIPE)
314
-
315
- stderr = context.exception.stderr
316
- self.assertIsInstance(stderr, bytes)
317
- self.assertIn(expected_exception, stderr.decode('utf-8'))
318
-
319
- elif expected_result is not None:
320
- subprocess.check_call([exactPython, self.program, wdl_file, json_file, '-o', output_dir])
321
- output = os.path.join(output_dir, 'output.txt')
322
- with open(output) as f:
323
- result = f.read().strip()
324
- self.assertEqual(result, expected_result)
325
-
326
- else:
327
- self.fail("Invalid test. Either `expected_result` or `expected_exception` must be set.")
328
-
329
- shutil.rmtree(output_dir)
330
-
331
-
332
- class WdlLanguageSpecWorkflowsTest(WdlWorkflowsTest):
333
- """
334
- A set of test cases for toil's conformance with the WDL language specification:
335
-
336
- https://github.com/openwdl/wdl/blob/main/versions/development/SPEC.md#language-specification
337
- """
338
-
339
- @classmethod
340
- def setUpClass(cls):
341
- super().setUpClass()
342
- cls.test_path = os.path.abspath("src/toil/test/wdl/wdl_specification")
343
-
344
- def test_type_pair(self):
345
- # NOTE: these tests depend on read_lines(), write_json(), and select_first().
346
-
347
- expected_result = '[23,"twenty-three","a.bai",{"left":23,"right":"twenty-three"}]'
348
- self.check_function('type_pair', cases=['basic'], expected_result=expected_result)
349
-
350
- # tests if files from the pair type are correctly imported.
351
- # the array of three arrays consists content from:
352
- # 1. src/toil/test/wdl/testfiles/test_string.txt -> 'A Whale of a Tale.'
353
- # 2. src/toil/test/wdl/testfiles/test_boolean.txt -> 'true'
354
- # 3. src/toil/test/wdl/testfiles/test_int.txt -> '11'
355
- expected_result = '[["A Whale of a Tale."],["true"],["11"]]'
356
- self.check_function('type_pair', cases=['with_files'], expected_result=expected_result)
357
-
358
- def test_v1_declaration(self):
359
- """
360
- Basic declaration example modified from the WDL 1.0 spec:
361
-
362
- https://github.com/openwdl/wdl/blob/main/versions/1.0/SPEC.md#declarations
363
- """
364
- expected_result = 'Hello, x!; Hello, y!'
365
- self.check_function('v1_spec', cases=['declaration'], expected_result=expected_result)
366
-
367
-
368
- class WdlStandardLibraryWorkflowsTest(WdlWorkflowsTest):
369
- """
370
- A set of test cases for toil's conformance with the WDL built-in standard library:
371
-
372
- https://github.com/openwdl/wdl/blob/main/versions/development/SPEC.md#standard-library
373
- """
374
-
375
- @classmethod
376
- def setUpClass(cls):
377
- super().setUpClass()
378
- cls.test_path = os.path.abspath("src/toil/test/wdl/standard_library")
379
-
380
- def test_sub(self):
381
- # this workflow swaps the extension of a TSV file to CSV, with String and File inputs.
382
- self.check_function('sub', cases=['as_input'], expected_result='src/toil/test/wdl/test.csv')
383
-
384
- # NOTE: the result differs from Cromwell since we copy the file to the file store without
385
- # preserving the path. Cromwell would return 'src/toil/test/wdl/test.csv' instead.
386
- self.check_function('sub', cases=['as_input_with_file'], expected_result='test.csv')
387
-
388
- def test_size(self):
389
- self.check_function('size', cases=['as_command'], expected_result='19.0')
390
-
391
- # this workflow outputs the size of a 22-byte file in 'B', 'K', and 'Ki' separated with spaces.
392
-
393
- # NOTE: Cromwell treats the decimal and binary units (e.g.: 'K' and 'Ki') the same, which differs from
394
- # the spec (https://github.com/openwdl/wdl/blob/main/versions/development/SPEC.md#float-sizefile-string).
395
- # The correct output should be '22.0 0.022 0.021484375' not '22.0 0.021484375 0.021484375'
396
- self.check_function('size', cases=['as_output'], expected_result='22.0 0.022 0.021484375')
397
-
398
- def test_ceil(self):
399
- self.check_function('ceil', cases=['as_input', 'as_command'], expected_result='12')
400
-
401
- def test_floor(self):
402
- self.check_function('floor', cases=['as_input', 'as_command'], expected_result='11')
403
-
404
- def test_round(self):
405
- self.check_function('round', cases=['as_input', 'as_command'], expected_result='11')
406
-
407
- def test_stdout(self):
408
- self.check_function('stdout', cases=['as_output'], expected_result='A Whale of a Tale.')
409
- self.check_function('stderr', cases=['as_output'], expected_result='a journey straight to stderr')
410
-
411
- def test_read(self):
412
- """ Test the set of WDL read functions."""
413
- # NOTE: these tests depend on stdout() and the write_*() functions.
414
-
415
- self.check_function('read_lines', cases=['as_output'],
416
- expected_result='line 1\n\t\tline 2 with tabs\n line 3\n\nline 5')
417
-
418
- self.check_function('read_tsv', cases=['as_output'],
419
- expected_result='1\t2\t3\n4\t5\t6\n7\t8\t9')
420
-
421
- self.check_function('read_json', cases=['as_output'],
422
- expected_result='{"key1":"value1","key2":"value2"}')
423
-
424
- self.check_function('read_map', cases=['as_output'],
425
- expected_result='key1\tvalue1\nkey2\tvalue2')
426
-
427
- # primitives
428
- self.check_function('read_int', cases=['as_command'], expected_result='11')
429
- self.check_function('read_string', cases=['as_command'], expected_result='A Whale of a Tale.')
430
- self.check_function('read_float', cases=['as_command'], expected_result='11.2345')
431
- self.check_function('read_boolean', cases=['as_command'], expected_result='True')
432
-
433
- def test_write(self):
434
- """ Test the set of WDL write functions."""
435
- self.check_function('write_lines', cases=['as_command'],
436
- expected_result='first\nsecond\nthird')
437
-
438
- self.check_function('write_tsv', cases=['as_command'],
439
- expected_result='one\ttwo\tthree\nun\tdeux\ttrois')
440
-
441
- self.check_function('write_json', cases=['as_command'],
442
- expected_result='{"key1":"value1","key2":"value2"}')
443
-
444
- self.check_function('write_map', cases=['as_command'],
445
- expected_result='key1\tvalue1\nkey2\tvalue2')
446
-
447
- def test_range(self):
448
- # NOTE: this test depends on write_lines().
449
- self.check_function('range', cases=['as_input'],
450
- expected_result='0\n1\n2\n3\n4\n5\n6\n7')
451
-
452
- self.check_function('range', cases=['as_input'],
453
- json_file_name='range_0',
454
- expected_result='')
455
-
456
- self.check_function('range', cases=['as_input'],
457
- json_file_name='range_invalid',
458
- expected_exception='WDLRuntimeError')
459
-
460
- def test_transpose(self):
461
- # NOTE: this test depends on write_tsv().
462
-
463
- # this workflow writes a transposed 2-dimensional array as a TSV file.
464
- self.check_function('transpose', cases=['as_input'], expected_result='0\t3\n1\t4\n2\t5')
465
-
466
- def test_length(self):
467
- self.check_function('length', cases=['as_input'], expected_result='3')
468
-
469
- self.check_function('length', cases=['as_input'],
470
- json_file_name='length_invalid',
471
- expected_exception='WDLRuntimeError')
472
-
473
- # length() should not work with Map[X, Y].
474
- self.check_function('length', cases=['as_input_with_map'],
475
- expected_exception='WDLRuntimeError')
476
-
477
- def test_zip(self):
478
- self.check_function('zip', cases=['as_input'],
479
- expected_result='[{"left":1,"right":"a"},{"left":2,"right":"b"},{"left":3,"right":"c"}]')
480
-
481
- def test_cross(self):
482
- self.check_function('cross', cases=['as_input'],
483
- expected_result='[{"left":1,"right":"a"},{"left":1,"right":"b"},'
484
- '{"left":2,"right":"a"},{"left":2,"right":"b"},'
485
- '{"left":3,"right":"a"},{"left":3,"right":"b"}]')
486
-
487
- def test_as_pairs(self):
488
- self.check_function('as_pairs', cases=['as_input'],
489
- expected_result='[{"left":"a","right":1},{"left":"b","right":2},{"left":"c","right":3}]')
490
-
491
- def test_as_map(self):
492
- self.check_function('as_map', cases=['as_input'], expected_result='{"a":1,"b":2,"c":3}')
493
-
494
- def test_keys(self):
495
- self.check_function('keys', cases=['as_input'], expected_result='["a","b","c"]')
496
-
497
- def test_collect_by_key(self):
498
- # NOTE: this result is expected according to the spec but differs from Cromwell.
499
- self.check_function('collect_by_key', cases=['as_input'], expected_result='{"a":[1,3],"b":[2]}')
500
-
501
- def test_flatten(self):
502
- self.check_function('flatten', cases=['as_input'], expected_result='[1,2,3,1,21,22]')
503
-
504
-
505
- if __name__ == "__main__":
506
- unittest.main()
toil/test/wdl/conftest.py DELETED
@@ -1,23 +0,0 @@
1
- # Copyright (C) 2015-2021 Regents of the University of California
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- # https://pytest.org/latest/example/pythoncollection.html
16
-
17
- collect_ignore = []
18
-
19
- try:
20
- import wdlparse
21
- print(wdlparse.__file__) # keep this import from being removed
22
- except ImportError:
23
- collect_ignore.append("toilwdl.py")