toil 8.1.0b1__py3-none-any.whl → 8.2.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 (254) hide show
  1. toil/__init__.py +0 -35
  2. toil/batchSystems/abstractBatchSystem.py +1 -1
  3. toil/batchSystems/abstractGridEngineBatchSystem.py +1 -1
  4. toil/batchSystems/awsBatch.py +1 -1
  5. toil/batchSystems/cleanup_support.py +1 -1
  6. toil/batchSystems/kubernetes.py +53 -7
  7. toil/batchSystems/local_support.py +1 -1
  8. toil/batchSystems/mesos/batchSystem.py +13 -8
  9. toil/batchSystems/mesos/test/__init__.py +3 -2
  10. toil/batchSystems/singleMachine.py +1 -1
  11. toil/batchSystems/slurm.py +27 -26
  12. toil/bus.py +5 -3
  13. toil/common.py +39 -11
  14. toil/cwl/cwltoil.py +1 -1
  15. toil/job.py +64 -49
  16. toil/jobStores/abstractJobStore.py +24 -3
  17. toil/jobStores/fileJobStore.py +25 -1
  18. toil/jobStores/googleJobStore.py +104 -30
  19. toil/leader.py +9 -0
  20. toil/lib/accelerators.py +3 -1
  21. toil/lib/aws/utils.py.orig +504 -0
  22. toil/lib/bioio.py +1 -1
  23. toil/lib/docker.py +252 -91
  24. toil/lib/dockstore.py +11 -3
  25. toil/lib/exceptions.py +5 -3
  26. toil/lib/history.py +87 -13
  27. toil/lib/history_submission.py +23 -9
  28. toil/lib/io.py +34 -22
  29. toil/lib/misc.py +7 -1
  30. toil/lib/resources.py +2 -1
  31. toil/lib/threading.py +11 -10
  32. toil/options/common.py +8 -0
  33. toil/options/wdl.py +11 -0
  34. toil/server/api_spec/LICENSE +201 -0
  35. toil/server/api_spec/README.rst +5 -0
  36. toil/server/cli/wes_cwl_runner.py +2 -1
  37. toil/test/__init__.py +275 -115
  38. toil/test/batchSystems/batchSystemTest.py +227 -205
  39. toil/test/batchSystems/test_slurm.py +27 -0
  40. toil/test/cactus/pestis.tar.gz +0 -0
  41. toil/test/conftest.py +7 -0
  42. toil/test/cwl/2.fasta +11 -0
  43. toil/test/cwl/2.fastq +12 -0
  44. toil/test/cwl/conftest.py +1 -1
  45. toil/test/cwl/cwlTest.py +999 -867
  46. toil/test/cwl/directory/directory/file.txt +15 -0
  47. toil/test/cwl/download_directory_file.json +4 -0
  48. toil/test/cwl/download_directory_s3.json +4 -0
  49. toil/test/cwl/download_file.json +6 -0
  50. toil/test/cwl/download_http.json +6 -0
  51. toil/test/cwl/download_https.json +6 -0
  52. toil/test/cwl/download_s3.json +6 -0
  53. toil/test/cwl/download_subdirectory_file.json +5 -0
  54. toil/test/cwl/download_subdirectory_s3.json +5 -0
  55. toil/test/cwl/empty.json +1 -0
  56. toil/test/cwl/mock_mpi/fake_mpi.yml +8 -0
  57. toil/test/cwl/mock_mpi/fake_mpi_run.py +42 -0
  58. toil/test/cwl/optional-file-exists.json +6 -0
  59. toil/test/cwl/optional-file-missing.json +6 -0
  60. toil/test/cwl/preemptible_expression.json +1 -0
  61. toil/test/cwl/revsort-job-missing.json +6 -0
  62. toil/test/cwl/revsort-job.json +6 -0
  63. toil/test/cwl/s3_secondary_file.json +16 -0
  64. toil/test/cwl/seqtk_seq_job.json +6 -0
  65. toil/test/cwl/stream.json +6 -0
  66. toil/test/cwl/test_filename_conflict_resolution.ms/table.dat +0 -0
  67. toil/test/cwl/test_filename_conflict_resolution.ms/table.f0 +0 -0
  68. toil/test/cwl/test_filename_conflict_resolution.ms/table.f1 +0 -0
  69. toil/test/cwl/test_filename_conflict_resolution.ms/table.f1i +0 -0
  70. toil/test/cwl/test_filename_conflict_resolution.ms/table.f2 +0 -0
  71. toil/test/cwl/test_filename_conflict_resolution.ms/table.f2_TSM0 +0 -0
  72. toil/test/cwl/test_filename_conflict_resolution.ms/table.f3 +0 -0
  73. toil/test/cwl/test_filename_conflict_resolution.ms/table.f3_TSM0 +0 -0
  74. toil/test/cwl/test_filename_conflict_resolution.ms/table.f4 +0 -0
  75. toil/test/cwl/test_filename_conflict_resolution.ms/table.f4_TSM0 +0 -0
  76. toil/test/cwl/test_filename_conflict_resolution.ms/table.f5 +0 -0
  77. toil/test/cwl/test_filename_conflict_resolution.ms/table.info +0 -0
  78. toil/test/cwl/test_filename_conflict_resolution.ms/table.lock +0 -0
  79. toil/test/cwl/whale.txt +16 -0
  80. toil/test/docs/scripts/example_alwaysfail.py +38 -0
  81. toil/test/docs/scripts/example_alwaysfail_with_files.wdl +33 -0
  82. toil/test/docs/scripts/example_cachingbenchmark.py +117 -0
  83. toil/test/docs/scripts/stagingExampleFiles/in.txt +1 -0
  84. toil/test/docs/scripts/stagingExampleFiles/out.txt +2 -0
  85. toil/test/docs/scripts/tutorial_arguments.py +23 -0
  86. toil/test/docs/scripts/tutorial_debugging.patch +12 -0
  87. toil/test/docs/scripts/tutorial_debugging_hangs.wdl +126 -0
  88. toil/test/docs/scripts/tutorial_debugging_works.wdl +129 -0
  89. toil/test/docs/scripts/tutorial_docker.py +20 -0
  90. toil/test/docs/scripts/tutorial_dynamic.py +24 -0
  91. toil/test/docs/scripts/tutorial_encapsulation.py +28 -0
  92. toil/test/docs/scripts/tutorial_encapsulation2.py +29 -0
  93. toil/test/docs/scripts/tutorial_helloworld.py +15 -0
  94. toil/test/docs/scripts/tutorial_invokeworkflow.py +27 -0
  95. toil/test/docs/scripts/tutorial_invokeworkflow2.py +30 -0
  96. toil/test/docs/scripts/tutorial_jobfunctions.py +22 -0
  97. toil/test/docs/scripts/tutorial_managing.py +29 -0
  98. toil/test/docs/scripts/tutorial_managing2.py +56 -0
  99. toil/test/docs/scripts/tutorial_multiplejobs.py +25 -0
  100. toil/test/docs/scripts/tutorial_multiplejobs2.py +21 -0
  101. toil/test/docs/scripts/tutorial_multiplejobs3.py +22 -0
  102. toil/test/docs/scripts/tutorial_promises.py +25 -0
  103. toil/test/docs/scripts/tutorial_promises2.py +30 -0
  104. toil/test/docs/scripts/tutorial_quickstart.py +22 -0
  105. toil/test/docs/scripts/tutorial_requirements.py +44 -0
  106. toil/test/docs/scripts/tutorial_services.py +45 -0
  107. toil/test/docs/scripts/tutorial_staging.py +45 -0
  108. toil/test/docs/scripts/tutorial_stats.py +64 -0
  109. toil/test/lib/aws/test_iam.py +3 -1
  110. toil/test/lib/dockerTest.py +205 -122
  111. toil/test/lib/test_history.py +101 -77
  112. toil/test/provisioners/aws/awsProvisionerTest.py +12 -9
  113. toil/test/provisioners/clusterTest.py +4 -4
  114. toil/test/provisioners/gceProvisionerTest.py +16 -14
  115. toil/test/sort/sort.py +4 -1
  116. toil/test/src/busTest.py +17 -17
  117. toil/test/src/deferredFunctionTest.py +145 -132
  118. toil/test/src/importExportFileTest.py +71 -63
  119. toil/test/src/jobEncapsulationTest.py +27 -28
  120. toil/test/src/jobServiceTest.py +149 -133
  121. toil/test/src/jobTest.py +219 -211
  122. toil/test/src/miscTests.py +66 -60
  123. toil/test/src/promisedRequirementTest.py +163 -169
  124. toil/test/src/regularLogTest.py +24 -24
  125. toil/test/src/resourceTest.py +82 -76
  126. toil/test/src/restartDAGTest.py +51 -47
  127. toil/test/src/resumabilityTest.py +24 -19
  128. toil/test/src/retainTempDirTest.py +60 -57
  129. toil/test/src/systemTest.py +17 -13
  130. toil/test/src/threadingTest.py +29 -32
  131. toil/test/utils/ABCWorkflowDebug/B_file.txt +1 -0
  132. toil/test/utils/ABCWorkflowDebug/debugWorkflow.py +204 -0
  133. toil/test/utils/ABCWorkflowDebug/mkFile.py +16 -0
  134. toil/test/utils/ABCWorkflowDebug/sleep.cwl +12 -0
  135. toil/test/utils/ABCWorkflowDebug/sleep.yaml +1 -0
  136. toil/test/utils/toilDebugTest.py +117 -102
  137. toil/test/utils/toilKillTest.py +54 -53
  138. toil/test/utils/utilsTest.py +303 -229
  139. toil/test/wdl/lint_error.wdl +9 -0
  140. toil/test/wdl/md5sum/empty_file.json +1 -0
  141. toil/test/wdl/md5sum/md5sum-gs.json +1 -0
  142. toil/test/wdl/md5sum/md5sum.1.0.wdl +32 -0
  143. toil/test/wdl/md5sum/md5sum.input +1 -0
  144. toil/test/wdl/md5sum/md5sum.json +1 -0
  145. toil/test/wdl/md5sum/md5sum.wdl +25 -0
  146. toil/test/wdl/miniwdl_self_test/inputs-namespaced.json +1 -0
  147. toil/test/wdl/miniwdl_self_test/inputs.json +1 -0
  148. toil/test/wdl/miniwdl_self_test/self_test.wdl +40 -0
  149. toil/test/wdl/standard_library/as_map.json +16 -0
  150. toil/test/wdl/standard_library/as_map_as_input.wdl +23 -0
  151. toil/test/wdl/standard_library/as_pairs.json +7 -0
  152. toil/test/wdl/standard_library/as_pairs_as_input.wdl +23 -0
  153. toil/test/wdl/standard_library/ceil.json +3 -0
  154. toil/test/wdl/standard_library/ceil_as_command.wdl +16 -0
  155. toil/test/wdl/standard_library/ceil_as_input.wdl +16 -0
  156. toil/test/wdl/standard_library/collect_by_key.json +1 -0
  157. toil/test/wdl/standard_library/collect_by_key_as_input.wdl +23 -0
  158. toil/test/wdl/standard_library/cross.json +11 -0
  159. toil/test/wdl/standard_library/cross_as_input.wdl +19 -0
  160. toil/test/wdl/standard_library/flatten.json +7 -0
  161. toil/test/wdl/standard_library/flatten_as_input.wdl +18 -0
  162. toil/test/wdl/standard_library/floor.json +3 -0
  163. toil/test/wdl/standard_library/floor_as_command.wdl +16 -0
  164. toil/test/wdl/standard_library/floor_as_input.wdl +16 -0
  165. toil/test/wdl/standard_library/keys.json +8 -0
  166. toil/test/wdl/standard_library/keys_as_input.wdl +24 -0
  167. toil/test/wdl/standard_library/length.json +7 -0
  168. toil/test/wdl/standard_library/length_as_input.wdl +16 -0
  169. toil/test/wdl/standard_library/length_as_input_with_map.json +7 -0
  170. toil/test/wdl/standard_library/length_as_input_with_map.wdl +17 -0
  171. toil/test/wdl/standard_library/length_invalid.json +3 -0
  172. toil/test/wdl/standard_library/range.json +3 -0
  173. toil/test/wdl/standard_library/range_0.json +3 -0
  174. toil/test/wdl/standard_library/range_as_input.wdl +17 -0
  175. toil/test/wdl/standard_library/range_invalid.json +3 -0
  176. toil/test/wdl/standard_library/read_boolean.json +3 -0
  177. toil/test/wdl/standard_library/read_boolean_as_command.wdl +17 -0
  178. toil/test/wdl/standard_library/read_float.json +3 -0
  179. toil/test/wdl/standard_library/read_float_as_command.wdl +17 -0
  180. toil/test/wdl/standard_library/read_int.json +3 -0
  181. toil/test/wdl/standard_library/read_int_as_command.wdl +17 -0
  182. toil/test/wdl/standard_library/read_json.json +3 -0
  183. toil/test/wdl/standard_library/read_json_as_output.wdl +31 -0
  184. toil/test/wdl/standard_library/read_lines.json +3 -0
  185. toil/test/wdl/standard_library/read_lines_as_output.wdl +31 -0
  186. toil/test/wdl/standard_library/read_map.json +3 -0
  187. toil/test/wdl/standard_library/read_map_as_output.wdl +31 -0
  188. toil/test/wdl/standard_library/read_string.json +3 -0
  189. toil/test/wdl/standard_library/read_string_as_command.wdl +17 -0
  190. toil/test/wdl/standard_library/read_tsv.json +3 -0
  191. toil/test/wdl/standard_library/read_tsv_as_output.wdl +31 -0
  192. toil/test/wdl/standard_library/round.json +3 -0
  193. toil/test/wdl/standard_library/round_as_command.wdl +16 -0
  194. toil/test/wdl/standard_library/round_as_input.wdl +16 -0
  195. toil/test/wdl/standard_library/size.json +3 -0
  196. toil/test/wdl/standard_library/size_as_command.wdl +17 -0
  197. toil/test/wdl/standard_library/size_as_output.wdl +36 -0
  198. toil/test/wdl/standard_library/stderr.json +3 -0
  199. toil/test/wdl/standard_library/stderr_as_output.wdl +30 -0
  200. toil/test/wdl/standard_library/stdout.json +3 -0
  201. toil/test/wdl/standard_library/stdout_as_output.wdl +30 -0
  202. toil/test/wdl/standard_library/sub.json +3 -0
  203. toil/test/wdl/standard_library/sub_as_input.wdl +17 -0
  204. toil/test/wdl/standard_library/sub_as_input_with_file.wdl +17 -0
  205. toil/test/wdl/standard_library/transpose.json +6 -0
  206. toil/test/wdl/standard_library/transpose_as_input.wdl +18 -0
  207. toil/test/wdl/standard_library/write_json.json +6 -0
  208. toil/test/wdl/standard_library/write_json_as_command.wdl +17 -0
  209. toil/test/wdl/standard_library/write_lines.json +7 -0
  210. toil/test/wdl/standard_library/write_lines_as_command.wdl +17 -0
  211. toil/test/wdl/standard_library/write_map.json +6 -0
  212. toil/test/wdl/standard_library/write_map_as_command.wdl +17 -0
  213. toil/test/wdl/standard_library/write_tsv.json +6 -0
  214. toil/test/wdl/standard_library/write_tsv_as_command.wdl +17 -0
  215. toil/test/wdl/standard_library/zip.json +12 -0
  216. toil/test/wdl/standard_library/zip_as_input.wdl +19 -0
  217. toil/test/wdl/test.csv +3 -0
  218. toil/test/wdl/test.tsv +3 -0
  219. toil/test/wdl/testfiles/croo.wdl +38 -0
  220. toil/test/wdl/testfiles/drop_files.wdl +62 -0
  221. toil/test/wdl/testfiles/drop_files_subworkflow.wdl +13 -0
  222. toil/test/wdl/testfiles/empty.txt +0 -0
  223. toil/test/wdl/testfiles/not_enough_outputs.wdl +33 -0
  224. toil/test/wdl/testfiles/random.wdl +66 -0
  225. toil/test/wdl/testfiles/string_file_coercion.json +1 -0
  226. toil/test/wdl/testfiles/string_file_coercion.wdl +35 -0
  227. toil/test/wdl/testfiles/test.json +4 -0
  228. toil/test/wdl/testfiles/test_boolean.txt +1 -0
  229. toil/test/wdl/testfiles/test_float.txt +1 -0
  230. toil/test/wdl/testfiles/test_int.txt +1 -0
  231. toil/test/wdl/testfiles/test_lines.txt +5 -0
  232. toil/test/wdl/testfiles/test_map.txt +2 -0
  233. toil/test/wdl/testfiles/test_string.txt +1 -0
  234. toil/test/wdl/testfiles/url_to_file.wdl +13 -0
  235. toil/test/wdl/testfiles/url_to_optional_file.wdl +13 -0
  236. toil/test/wdl/testfiles/vocab.json +1 -0
  237. toil/test/wdl/testfiles/vocab.wdl +66 -0
  238. toil/test/wdl/testfiles/wait.wdl +34 -0
  239. toil/test/wdl/wdl_specification/type_pair.json +23 -0
  240. toil/test/wdl/wdl_specification/type_pair_basic.wdl +36 -0
  241. toil/test/wdl/wdl_specification/type_pair_with_files.wdl +36 -0
  242. toil/test/wdl/wdl_specification/v1_spec.json +1 -0
  243. toil/test/wdl/wdl_specification/v1_spec_declaration.wdl +39 -0
  244. toil/test/wdl/wdltoil_test.py +680 -407
  245. toil/test/wdl/wdltoil_test_kubernetes.py +2 -2
  246. toil/version.py +9 -9
  247. toil/wdl/wdltoil.py +336 -123
  248. {toil-8.1.0b1.dist-info → toil-8.2.0.dist-info}/METADATA +5 -4
  249. toil-8.2.0.dist-info/RECORD +439 -0
  250. {toil-8.1.0b1.dist-info → toil-8.2.0.dist-info}/WHEEL +1 -1
  251. toil-8.1.0b1.dist-info/RECORD +0 -259
  252. {toil-8.1.0b1.dist-info → toil-8.2.0.dist-info}/entry_points.txt +0 -0
  253. {toil-8.1.0b1.dist-info → toil-8.2.0.dist-info/licenses}/LICENSE +0 -0
  254. {toil-8.1.0b1.dist-info → toil-8.2.0.dist-info}/top_level.txt +0 -0
@@ -12,44 +12,42 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import os
15
+ from collections.abc import Generator
16
+ from pathlib import Path
16
17
  import logging
17
- import pytest
18
18
  import time
19
- from toil.test import ToilTest
20
19
 
21
20
  from toil.lib.history import HistoryManager
22
21
 
22
+ import pytest
23
+
23
24
  logger = logging.getLogger(__name__)
24
25
  logging.basicConfig(level=logging.DEBUG)
25
26
 
26
- class HistoryTest(ToilTest):
27
+
28
+ class TestHistory:
27
29
  """
28
30
  Tests for Toil history tracking.
29
31
 
30
32
  Each test gets its own history database.
31
33
  """
32
34
 
33
- def setUp(self) -> None:
34
- super().setUp()
35
-
36
- # Apply a temp dir override to history tracking
37
- temp_dir = self._createTempDir()
38
- HistoryManager.database_path_override = os.path.join(temp_dir, "test-db.sqlite")
39
-
40
- # Flag on job history tracking
41
- self.original_flag = HistoryManager.JOB_HISTORY_ENABLED
42
- HistoryManager.JOB_HISTORY_ENABLED = True
43
-
44
-
45
- def tearDown(self) -> None:
46
- # Remove the temp dir override from history tracking
47
- HistoryManager.database_path_override = None
48
-
49
- # Restore job history tracking flag
50
- HistoryManager.JOB_HISTORY_ENABLED = self.original_flag
51
-
52
- super().tearDown()
35
+ @pytest.fixture(autouse=True, scope="function")
36
+ def private_history_manager(
37
+ self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
38
+ ) -> Generator[None]:
39
+ try:
40
+ with monkeypatch.context() as m:
41
+ m.setattr(
42
+ HistoryManager,
43
+ "database_path_override",
44
+ str(tmp_path / "test-db.sqlite"),
45
+ )
46
+ m.setattr(HistoryManager, "enabled", lambda: True)
47
+ m.setattr(HistoryManager, "enabled_job", lambda: True)
48
+ yield
49
+ finally:
50
+ pass # no cleanup needed
53
51
 
54
52
  def make_fake_workflow(self, workflow_id: str) -> None:
55
53
  # Make a fake workflow
@@ -57,15 +55,17 @@ class HistoryTest(ToilTest):
57
55
  HistoryManager.record_workflow_creation(workflow_id, workflow_jobstore_spec)
58
56
  workflow_name = "SuperCoolWF"
59
57
  workflow_trs_spec = "#wf:v1"
60
- HistoryManager.record_workflow_metadata(workflow_id, workflow_name, workflow_trs_spec)
61
-
58
+ HistoryManager.record_workflow_metadata(
59
+ workflow_id, workflow_name, workflow_trs_spec
60
+ )
61
+
62
62
  # Give it a job
63
63
  workflow_attempt_number = 1
64
64
  job_name = "DoThing"
65
65
  succeeded = True
66
66
  start_time = time.time()
67
67
  runtime = 0.1
68
- HistoryManager.record_job_attempt(
68
+ HistoryManager.record_job_attempt(
69
69
  workflow_id,
70
70
  workflow_attempt_number,
71
71
  job_name,
@@ -93,92 +93,126 @@ class HistoryTest(ToilTest):
93
93
  workflow_attempt_number = 1
94
94
 
95
95
  # Make sure we have data
96
- self.assertEqual(HistoryManager.count_workflows(), 1)
97
- self.assertEqual(HistoryManager.count_workflow_attempts(), 1)
98
- self.assertEqual(HistoryManager.count_job_attempts(), 1)
96
+ assert HistoryManager.count_workflows() == 1
97
+ assert HistoryManager.count_workflow_attempts() == 1
98
+ assert HistoryManager.count_job_attempts() == 1
99
99
 
100
100
  # Make sure we see it as submittable
101
- submittable_workflow_attempts = HistoryManager.get_submittable_workflow_attempts()
102
- self.assertEqual(len(submittable_workflow_attempts), 1)
101
+ submittable_workflow_attempts = (
102
+ HistoryManager.get_submittable_workflow_attempts()
103
+ )
104
+ assert len(submittable_workflow_attempts) == 1
103
105
 
104
106
  # Make sure we see its jobs as submittable
105
- with_submittable_job_attempts = HistoryManager.get_workflow_attempts_with_submittable_job_attempts()
106
- self.assertEqual(len(with_submittable_job_attempts), 1)
107
+ with_submittable_job_attempts = (
108
+ HistoryManager.get_workflow_attempts_with_submittable_job_attempts()
109
+ )
110
+ assert len(with_submittable_job_attempts) == 1
107
111
 
108
112
  # Make sure we actually see the job
109
- submittable_job_attempts = HistoryManager.get_unsubmitted_job_attempts(workflow_id, workflow_attempt_number)
110
- self.assertEqual(len(submittable_job_attempts), 1)
113
+ submittable_job_attempts = HistoryManager.get_unsubmitted_job_attempts(
114
+ workflow_id, workflow_attempt_number
115
+ )
116
+ assert len(submittable_job_attempts) == 1
111
117
 
112
118
  # Pretend we submitted them.
113
- HistoryManager.mark_job_attempts_submitted([j.id for j in submittable_job_attempts])
114
- HistoryManager.mark_workflow_attempt_submitted(workflow_id, workflow_attempt_number)
119
+ HistoryManager.mark_job_attempts_submitted(
120
+ [j.id for j in submittable_job_attempts]
121
+ )
122
+ HistoryManager.mark_workflow_attempt_submitted(
123
+ workflow_id, workflow_attempt_number
124
+ )
115
125
 
116
126
  # Make sure they are no longer matching
117
- self.assertEqual(len(HistoryManager.get_submittable_workflow_attempts()), 0)
118
- self.assertEqual(len(HistoryManager.get_workflow_attempts_with_submittable_job_attempts()), 0)
119
- self.assertEqual(len(HistoryManager.get_unsubmitted_job_attempts(workflow_id, workflow_attempt_number)), 0)
127
+ assert len(HistoryManager.get_submittable_workflow_attempts()) == 0
128
+ assert (
129
+ len(HistoryManager.get_workflow_attempts_with_submittable_job_attempts())
130
+ == 0
131
+ )
132
+ assert (
133
+ len(
134
+ HistoryManager.get_unsubmitted_job_attempts(
135
+ workflow_id, workflow_attempt_number
136
+ )
137
+ )
138
+ == 0
139
+ )
120
140
 
121
141
  # Make sure we still have data
122
- self.assertEqual(HistoryManager.count_workflows(), 1)
123
- self.assertEqual(HistoryManager.count_workflow_attempts(), 1)
124
- self.assertEqual(HistoryManager.count_job_attempts(), 1)
142
+ assert HistoryManager.count_workflows() == 1
143
+ assert HistoryManager.count_workflow_attempts() == 1
144
+ assert HistoryManager.count_job_attempts() == 1
125
145
 
126
146
  def test_history_deletion(self) -> None:
127
147
  workflow_id = "123"
128
148
  self.make_fake_workflow(workflow_id)
129
149
  workflow_attempt_number = 1
130
-
150
+
131
151
  # Make sure we can see the workflow for deletion by age but not by done-ness
132
- self.assertEqual(len(HistoryManager.get_oldest_workflow_ids()), 1)
133
- self.assertEqual(len(HistoryManager.get_fully_submitted_workflow_ids()), 0)
152
+ assert len(HistoryManager.get_oldest_workflow_ids()) == 1
153
+ assert len(HistoryManager.get_fully_submitted_workflow_ids()) == 0
134
154
 
135
155
  # Pretend we submitted the workflow.
136
- HistoryManager.mark_job_attempts_submitted([j.id for j in HistoryManager.get_unsubmitted_job_attempts(workflow_id, workflow_attempt_number)])
137
- HistoryManager.mark_workflow_attempt_submitted(workflow_id, workflow_attempt_number)
156
+ HistoryManager.mark_job_attempts_submitted(
157
+ [
158
+ j.id
159
+ for j in HistoryManager.get_unsubmitted_job_attempts(
160
+ workflow_id, workflow_attempt_number
161
+ )
162
+ ]
163
+ )
164
+ HistoryManager.mark_workflow_attempt_submitted(
165
+ workflow_id, workflow_attempt_number
166
+ )
138
167
 
139
168
  # Make sure we can see the workflow for deletion by done-ness
140
- self.assertEqual(len(HistoryManager.get_fully_submitted_workflow_ids()), 1)
169
+ assert len(HistoryManager.get_fully_submitted_workflow_ids()) == 1
141
170
 
142
171
  # Add a new workflow
143
172
  other_workflow_id = "456"
144
173
  self.make_fake_workflow(other_workflow_id)
145
174
 
146
175
  # Make sure we can see the both for deletion by age but only one by done-ness
147
- self.assertEqual(len(HistoryManager.get_oldest_workflow_ids()), 2)
148
- self.assertEqual(len(HistoryManager.get_fully_submitted_workflow_ids()), 1)
176
+ assert len(HistoryManager.get_oldest_workflow_ids()) == 2
177
+ assert len(HistoryManager.get_fully_submitted_workflow_ids()) == 1
149
178
 
150
179
  # Make sure the older workflow is first.
151
- self.assertEqual(HistoryManager.get_oldest_workflow_ids(), [workflow_id, other_workflow_id])
180
+ assert HistoryManager.get_oldest_workflow_ids() == [
181
+ workflow_id,
182
+ other_workflow_id,
183
+ ]
152
184
 
153
185
  # Delete the new workflow
154
186
  HistoryManager.delete_workflow(other_workflow_id)
155
187
 
156
188
  # Make sure we can see the old one
157
- self.assertEqual(HistoryManager.get_oldest_workflow_ids(), [workflow_id])
158
- self.assertEqual(HistoryManager.get_fully_submitted_workflow_ids(), [workflow_id])
189
+ assert HistoryManager.get_oldest_workflow_ids() == [workflow_id]
190
+ assert HistoryManager.get_fully_submitted_workflow_ids() == [workflow_id]
159
191
 
160
192
  # Delete the old workflow
161
193
  HistoryManager.delete_workflow(workflow_id)
162
194
 
163
195
  # Make sure we have no data
164
- self.assertEqual(HistoryManager.count_workflows(), 0)
165
- self.assertEqual(HistoryManager.count_workflow_attempts(), 0)
166
- self.assertEqual(HistoryManager.count_job_attempts(), 0)
167
-
196
+ assert HistoryManager.count_workflows() == 0
197
+ assert HistoryManager.count_workflow_attempts() == 0
198
+ assert HistoryManager.count_job_attempts() == 0
168
199
 
169
200
  def test_history_size_limit(self) -> None:
170
201
  """
171
202
  Make sure the database size can be controlled.
172
203
  """
173
204
 
174
- for workflow_id in ("WorkflowThatTakesUpSomeSpace,ActuallyMoreThanTheLaterOnesTake" + str(i) for i in range(10)):
205
+ for workflow_id in (
206
+ "WorkflowThatTakesUpSomeSpace,ActuallyMoreThanTheLaterOnesTake" + str(i)
207
+ for i in range(10)
208
+ ):
175
209
  self.make_fake_workflow(workflow_id)
176
210
 
177
211
  # We should see the workflows.
178
- self.assertEqual(HistoryManager.count_workflows(), 10)
212
+ assert HistoryManager.count_workflows() == 10
179
213
  # And they take up space.
180
214
  small_size = HistoryManager.get_database_byte_size()
181
- self.assertGreater(small_size, 0)
215
+ assert small_size > 0
182
216
 
183
217
  # Add a bunch more
184
218
  for workflow_id in ("WorkflowThatTakesUpSpace" + str(i) for i in range(50)):
@@ -187,26 +221,16 @@ class HistoryTest(ToilTest):
187
221
  # We should see that this is now a much larger database
188
222
  large_size = HistoryManager.get_database_byte_size()
189
223
  logger.info("Increased database size from %s to %s", small_size, large_size)
190
- self.assertGreater(large_size, small_size)
191
-
224
+ large_size > small_size
225
+
192
226
  # We should be able to shrink it back down
193
227
  HistoryManager.enforce_byte_size_limit(small_size)
194
-
228
+
195
229
  reduced_size = HistoryManager.get_database_byte_size()
196
230
  logger.info("Decreased database size from %s to %s", large_size, reduced_size)
197
231
  # The database should be small enough
198
- self.assertLessEqual(reduced_size, small_size)
232
+ reduced_size <= small_size
199
233
  # There should still be some workflow attempts left in the smaller database (though probably not the first ones)
200
234
  remaining_workflows = HistoryManager.count_workflows()
201
235
  logger.info("Still have %s workflows", remaining_workflows)
202
- self.assertGreater(remaining_workflows, 0)
203
-
204
-
205
-
206
-
207
-
208
-
209
-
210
-
211
-
212
-
236
+ assert remaining_workflows > 0
@@ -28,6 +28,7 @@ from toil.provisioners import cluster_factory
28
28
  from toil.provisioners.aws.awsProvisioner import AWSProvisioner
29
29
  from toil.test import (
30
30
  ToilTest,
31
+ get_data,
31
32
  integrative,
32
33
  needs_aws_ec2,
33
34
  needs_fetchable_appliance,
@@ -135,7 +136,7 @@ class AbstractAWSAutoscaleTest(AbstractClusterTest):
135
136
  """
136
137
  return os.path.join(self.dataDir, filename)
137
138
 
138
- def rsyncUtil(self, src, dest):
139
+ def rsyncUtil(self, src: str, dest: str) -> None:
139
140
  subprocess.check_call(
140
141
  [
141
142
  "toil",
@@ -285,10 +286,11 @@ class AWSAutoscaleTest(AbstractAWSAutoscaleTest):
285
286
  with open(fileToSort, "w") as f:
286
287
  # Fixme: making this file larger causes the test to hang
287
288
  f.write("01234567890123456789012345678901")
288
- self.rsyncUtil(
289
- os.path.join(self._projectRootPath(), "src/toil/test/sort/sort.py"),
290
- ":" + self.script(),
291
- )
289
+ with get_data("test/sort/sort.py") as sort_py:
290
+ self.rsyncUtil(
291
+ sort_py,
292
+ ":" + self.script(),
293
+ )
292
294
  self.rsyncUtil(fileToSort, ":" + self.data("sortFile"))
293
295
  os.unlink(fileToSort)
294
296
 
@@ -501,10 +503,11 @@ class AWSAutoscaleTestMultipleNodeTypes(AbstractAWSAutoscaleTest):
501
503
  sseKeyFile = os.path.join(os.getcwd(), "keyFile")
502
504
  with open(sseKeyFile, "w") as f:
503
505
  f.write("01234567890123456789012345678901")
504
- self.rsyncUtil(
505
- os.path.join(self._projectRootPath(), "src/toil/test/sort/sort.py"),
506
- ":" + self.script(),
507
- )
506
+ with get_data("test/sort/sort.py") as sort_py:
507
+ self.rsyncUtil(
508
+ sort_py,
509
+ ":" + self.script(),
510
+ )
508
511
  self.rsyncUtil(sseKeyFile, ":" + self.data("keyFile"))
509
512
  os.unlink(sseKeyFile)
510
513
 
@@ -39,7 +39,7 @@ log = logging.getLogger(__name__)
39
39
  class AbstractClusterTest(ToilTest):
40
40
  def __init__(self, methodName: str) -> None:
41
41
  super().__init__(methodName=methodName)
42
- self.keyName = os.getenv("TOIL_AWS_KEYNAME").strip() or "id_rsa"
42
+ self.keyName = os.getenv("TOIL_AWS_KEYNAME", "id_rsa").strip()
43
43
  self.clusterName = f"aws-provisioner-test-{uuid4()}"
44
44
  self.leaderNodeType = "t2.medium"
45
45
  self.clusterType = "mesos"
@@ -276,12 +276,12 @@ class CWLOnARMTest(AbstractClusterTest):
276
276
  ]
277
277
  )
278
278
 
279
- # Runs the CWLv12Test on an ARM instance
279
+ # Runs the TestCWLv12 on an ARM instance
280
280
  self.sshUtil(
281
281
  [
282
282
  "bash",
283
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",
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::TestCWLv12::test_run_conformance",
285
285
  ]
286
286
  )
287
287
 
@@ -289,5 +289,5 @@ class CWLOnARMTest(AbstractClusterTest):
289
289
  # Bring it back to be an artifact.
290
290
  self.rsync_util(
291
291
  f":{self.cwl_test_dir}/toil/conformance-1.2.junit.xml",
292
- os.path.join(self._projectRootPath(), "arm-conformance-1.2.junit.xml"),
292
+ str(self._rootpath / "arm-conformance-1.2.junit.xml"),
293
293
  )
@@ -21,6 +21,7 @@ import pytest
21
21
 
22
22
  from toil.test import (
23
23
  ToilTest,
24
+ get_data,
24
25
  integrative,
25
26
  needs_fetchable_appliance,
26
27
  needs_google_project,
@@ -214,10 +215,11 @@ class GCEAutoscaleTest(AbstractGCEAutoscaleTest):
214
215
  with open(fileToSort, "w") as f:
215
216
  # Fixme: making this file larger causes the test to hang
216
217
  f.write("01234567890123456789012345678901")
217
- self.rsyncUtil(
218
- os.path.join(self._projectRootPath(), "src/toil/test/sort/sort.py"),
219
- ":/home/sort.py",
220
- )
218
+ with get_data("test/sort/sort.py") as sort_py:
219
+ self.rsyncUtil(
220
+ sort_py,
221
+ ":/home/sort.py",
222
+ )
221
223
  self.rsyncUtil(fileToSort, ":/home/sortFile")
222
224
  os.unlink(fileToSort)
223
225
 
@@ -324,10 +326,11 @@ class GCEAutoscaleTestMultipleNodeTypes(AbstractGCEAutoscaleTest):
324
326
  sseKeyFile = os.path.join(os.getcwd(), "keyFile")
325
327
  with open(sseKeyFile, "w") as f:
326
328
  f.write("01234567890123456789012345678901")
327
- self.rsyncUtil(
328
- os.path.join(self._projectRootPath(), "src/toil/test/sort/sort.py"),
329
- ":/home/sort.py",
330
- )
329
+ with get_data("test/sort/sort.py") as sort_py:
330
+ self.rsyncUtil(
331
+ sort_py,
332
+ ":/home/sort.py",
333
+ )
331
334
  self.rsyncUtil(sseKeyFile, ":/home/keyFile")
332
335
  os.unlink(sseKeyFile)
333
336
 
@@ -376,12 +379,11 @@ class GCERestartTest(AbstractGCEAutoscaleTest):
376
379
  self.jobStore = f"google:{self.projectID}:restart-{uuid4()}"
377
380
 
378
381
  def _getScript(self):
379
- self.rsyncUtil(
380
- os.path.join(
381
- self._projectRootPath(), "src/toil/test/provisioners/restartScript.py"
382
- ),
383
- ":" + self.scriptName,
384
- )
382
+ with get_data("test/provisioners/restartScript.py") as restartScript:
383
+ self.rsyncUtil(
384
+ restartScript,
385
+ ":" + self.scriptName,
386
+ )
385
387
 
386
388
  def _runScript(self, toilOptions):
387
389
  # clean = onSuccess
toil/test/sort/sort.py CHANGED
@@ -23,6 +23,7 @@ from configargparse import ArgumentParser
23
23
 
24
24
  from toil.common import Toil
25
25
  from toil.job import Job
26
+ from toil.lib.misc import StrPath
26
27
  from toil.realtimeLogger import RealtimeLogger
27
28
 
28
29
  defaultLines = 1000
@@ -207,7 +208,9 @@ def getMidPoint(file, fileStart, fileEnd):
207
208
  return len(line) + fileStart - 1
208
209
 
209
210
 
210
- def makeFileToSort(fileName, lines=defaultLines, lineLen=defaultLineLen):
211
+ def makeFileToSort(
212
+ fileName: StrPath, lines: int = defaultLines, lineLen: int = defaultLineLen
213
+ ) -> None:
211
214
  with open(fileName, "w") as f:
212
215
  for _ in range(lines):
213
216
  line = (
toil/test/src/busTest.py CHANGED
@@ -14,7 +14,9 @@
14
14
 
15
15
  import logging
16
16
  import os
17
+ from pathlib import Path
17
18
  from threading import Thread, current_thread
19
+ from typing import NoReturn
18
20
 
19
21
  from toil.batchSystems.abstractBatchSystem import BatchJobExitReason
20
22
  from toil.bus import (
@@ -26,18 +28,17 @@ from toil.bus import (
26
28
  from toil.common import Toil
27
29
  from toil.exceptions import FailedJobsException
28
30
  from toil.job import Job
29
- from toil.test import ToilTest, get_temp_file
30
31
 
31
32
  logger = logging.getLogger(__name__)
32
33
 
33
34
 
34
- class MessageBusTest(ToilTest):
35
+ class TestMessageBus:
35
36
 
36
- def test_enum_ints_in_file(self) -> None:
37
+ def test_enum_ints_in_file(self, tmp_path: Path) -> None:
37
38
  """
38
39
  Make sure writing bus messages to files works with enums.
39
40
  """
40
- bus_file = get_temp_file()
41
+ bus_file = tmp_path / "bus"
41
42
 
42
43
  bus = MessageBus()
43
44
  # Connect the handler and hold the result to protect it from GC
@@ -73,7 +74,7 @@ class MessageBusTest(ToilTest):
73
74
  # Message should always arrive in the main thread.
74
75
  nonlocal message_count
75
76
  logger.debug("Got message: %s", received)
76
- self.assertEqual(current_thread(), main_thread)
77
+ assert current_thread() == main_thread
77
78
  message_count += 1
78
79
 
79
80
  bus.subscribe(JobIssuedMessage, handler)
@@ -101,28 +102,27 @@ class MessageBusTest(ToilTest):
101
102
  t.join()
102
103
 
103
104
  # We should ge tone message per thread, plus our own
104
- self.assertEqual(box.count(JobIssuedMessage), 11)
105
+ assert box.count(JobIssuedMessage) == 11
105
106
  # And having polled for those, our handler should have run
106
- self.assertEqual(message_count, 11)
107
+ assert message_count == 11
107
108
 
108
- def test_restart_without_bus_path(self) -> None:
109
+ def test_restart_without_bus_path(self, tmp_path: Path) -> None:
109
110
  """
110
111
  Test the ability to restart a workflow when the message bus path used
111
112
  by the previous attempt is gone.
112
113
  """
113
- temp_dir = self._createTempDir(purpose="tempDir")
114
- job_store = self._getTestJobStorePath()
114
+ temp_dir = tmp_path / "tempDir"
115
+ temp_dir.mkdir()
116
+ job_store = tmp_path / "jobstore"
115
117
 
116
- bus_holder_dir = os.path.join(temp_dir, "bus_holder")
117
- os.mkdir(bus_holder_dir)
118
+ bus_holder_dir = temp_dir / "bus_holder"
119
+ bus_holder_dir.mkdir()
118
120
 
119
121
  start_options = Job.Runner.getDefaultOptions(job_store)
120
122
  start_options.logLevel = "DEBUG"
121
123
  start_options.retryCount = 0
122
124
  start_options.clean = "never"
123
- start_options.write_messages = os.path.abspath(
124
- os.path.join(bus_holder_dir, "messagebus.txt")
125
- )
125
+ start_options.write_messages = str(bus_holder_dir / "messagebus.txt")
126
126
 
127
127
  root = Job.wrapJobFn(failing_job_fn)
128
128
 
@@ -137,7 +137,7 @@ class MessageBusTest(ToilTest):
137
137
 
138
138
  # Get rid of the bus
139
139
  os.unlink(start_options.write_messages)
140
- os.rmdir(bus_holder_dir)
140
+ bus_holder_dir.rmdir()
141
141
 
142
142
  logger.info("Making second attempt")
143
143
 
@@ -158,7 +158,7 @@ class MessageBusTest(ToilTest):
158
158
  logger.info("Second attempt successfully failed")
159
159
 
160
160
 
161
- def failing_job_fn(job: Job) -> None:
161
+ def failing_job_fn(job: Job) -> NoReturn:
162
162
  """
163
163
  This function is guaranteed to fail.
164
164
  """