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
@@ -32,46 +32,77 @@ class hidden:
32
32
  http://stackoverflow.com/questions/1323455/python-unit-test-with-base-and-sub-class#answer-25695512
33
33
  """
34
34
 
35
- class AbstractPromisedRequirementsTest(batchSystemTest.hidden.AbstractBatchSystemJobTest):
35
+ class AbstractPromisedRequirementsTest(
36
+ batchSystemTest.hidden.AbstractBatchSystemJobTest
37
+ ):
36
38
  """An abstract base class for testing Toil workflows with promised requirements."""
39
+
37
40
  @slow
38
41
  def testConcurrencyDynamic(self):
39
42
  """
40
43
  Asserts that promised core resources are allocated properly using a dynamic Toil workflow
41
44
  """
42
45
  for coresPerJob in self.allocatedCores:
43
- log.debug('Testing %d cores per job with CPU count %d', coresPerJob, self.cpuCount)
44
- tempDir = self._createTempDir('testFiles')
46
+ log.debug(
47
+ "Testing %d cores per job with CPU count %d",
48
+ coresPerJob,
49
+ self.cpuCount,
50
+ )
51
+ tempDir = self._createTempDir("testFiles")
45
52
  counterPath = self.getCounterPath(tempDir)
46
53
 
47
- root = Job.wrapJobFn(maxConcurrency, self.cpuCount, counterPath, coresPerJob,
48
- cores=1, memory='1M', disk='1M')
54
+ root = Job.wrapJobFn(
55
+ maxConcurrency,
56
+ self.cpuCount,
57
+ counterPath,
58
+ coresPerJob,
59
+ cores=1,
60
+ memory="1M",
61
+ disk="1M",
62
+ )
49
63
  values = Job.Runner.startToil(root, self.getOptions(tempDir))
50
64
  maxValue = max(values)
51
65
  self.assertLessEqual(maxValue, self.cpuCount // coresPerJob)
52
66
 
53
67
  @slow
54
- @retry_flaky_test(prepare=[batchSystemTest.hidden.AbstractBatchSystemJobTest.tearDown,
55
- batchSystemTest.hidden.AbstractBatchSystemJobTest.setUp])
68
+ @retry_flaky_test(
69
+ prepare=[
70
+ batchSystemTest.hidden.AbstractBatchSystemJobTest.tearDown,
71
+ batchSystemTest.hidden.AbstractBatchSystemJobTest.setUp,
72
+ ]
73
+ )
56
74
  def testConcurrencyStatic(self):
57
75
  """
58
76
  Asserts that promised core resources are allocated properly using a static DAG
59
77
  """
60
78
  for coresPerJob in self.allocatedCores:
61
- log.debug('Testing %d cores per job with CPU count %d', coresPerJob, self.cpuCount)
62
- tempDir = self._createTempDir('testFiles')
79
+ log.debug(
80
+ "Testing %d cores per job with CPU count %d",
81
+ coresPerJob,
82
+ self.cpuCount,
83
+ )
84
+ tempDir = self._createTempDir("testFiles")
63
85
  counterPath = self.getCounterPath(tempDir)
64
86
 
65
87
  root = Job()
66
- one = Job.wrapFn(getOne, cores=0.1, memory='32M', disk='1M')
67
- thirtyTwoMb = Job.wrapFn(getThirtyTwoMb, cores=0.1, memory='32M', disk='1M')
88
+ one = Job.wrapFn(getOne, cores=0.1, memory="32M", disk="1M")
89
+ thirtyTwoMb = Job.wrapFn(
90
+ getThirtyTwoMb, cores=0.1, memory="32M", disk="1M"
91
+ )
68
92
  root.addChild(one)
69
93
  root.addChild(thirtyTwoMb)
70
94
  for _ in range(self.cpuCount):
71
- root.addFollowOn(Job.wrapFn(batchSystemTest.measureConcurrency, counterPath,
72
- cores=PromisedRequirement(lambda x: x * coresPerJob, one.rv()),
73
- memory=PromisedRequirement(thirtyTwoMb.rv()),
74
- disk='1M'))
95
+ root.addFollowOn(
96
+ Job.wrapFn(
97
+ batchSystemTest.measureConcurrency,
98
+ counterPath,
99
+ cores=PromisedRequirement(
100
+ lambda x: x * coresPerJob, one.rv()
101
+ ),
102
+ memory=PromisedRequirement(thirtyTwoMb.rv()),
103
+ disk="1M",
104
+ )
105
+ )
75
106
  Job.Runner.startToil(root, self.getOptions(tempDir))
76
107
  _, maxValue = batchSystemTest.getCounters(counterPath)
77
108
  self.assertLessEqual(maxValue, self.cpuCount // coresPerJob)
@@ -90,7 +121,7 @@ class hidden:
90
121
  :param str tempDir: path to test directory
91
122
  :return: path to counter file
92
123
  """
93
- counterPath = os.path.join(tempDir, 'counter')
124
+ counterPath = os.path.join(tempDir, "counter")
94
125
  batchSystemTest.resetCounters(counterPath)
95
126
  minValue, maxValue = batchSystemTest.getCounters(counterPath)
96
127
  assert (minValue, maxValue) == (0, 0)
@@ -108,13 +139,19 @@ class hidden:
108
139
  file2 = 512
109
140
  F1 = Job.wrapJobFn(_writer, file1)
110
141
  F2 = Job.wrapJobFn(_writer, file2)
111
- G = Job.wrapJobFn(_follower, file1 + file2,
112
- disk=PromisedRequirement(lambda x, y: x.size + y.size,
113
- F1.rv(), F2.rv()))
142
+ G = Job.wrapJobFn(
143
+ _follower,
144
+ file1 + file2,
145
+ disk=PromisedRequirement(
146
+ lambda x, y: x.size + y.size, F1.rv(), F2.rv()
147
+ ),
148
+ )
114
149
  F1.addChild(F2)
115
150
  F2.addChild(G)
116
151
 
117
- Job.Runner.startToil(F1, self.getOptions(self._createTempDir('testFiles'), caching=caching))
152
+ Job.Runner.startToil(
153
+ F1, self.getOptions(self._createTempDir("testFiles"), caching=caching)
154
+ )
118
155
 
119
156
  def testPromisesWithNonCachingFileStore(self):
120
157
  self.testPromisesWithJobStoreFileObjects(caching=False)
@@ -124,14 +161,18 @@ class hidden:
124
161
  """
125
162
  Checks for a race condition when using promised requirements and child job functions.
126
163
  """
127
- A = Job.wrapJobFn(logDiskUsage, 'A', sleep=5, disk=PromisedRequirement(1024))
128
- B = Job.wrapJobFn(logDiskUsage, 'B', disk=PromisedRequirement(lambda x: x + 1024, A.rv()))
164
+ A = Job.wrapJobFn(
165
+ logDiskUsage, "A", sleep=5, disk=PromisedRequirement(1024)
166
+ )
167
+ B = Job.wrapJobFn(
168
+ logDiskUsage, "B", disk=PromisedRequirement(lambda x: x + 1024, A.rv())
169
+ )
129
170
  A.addChild(B)
130
- Job.Runner.startToil(A, self.getOptions(self._createTempDir('testFiles')))
171
+ Job.Runner.startToil(A, self.getOptions(self._createTempDir("testFiles")))
131
172
 
132
173
 
133
174
  def _writer(job, fileSize):
134
- '''
175
+ """
135
176
  Write a local file and return the FileID obtained from running writeGlobalFile on
136
177
  it.
137
178
 
@@ -139,8 +180,8 @@ def _writer(job, fileSize):
139
180
  :param int fileSize: Size of the file in bytes
140
181
  :returns: the result of writeGlobalFile on a locally created file
141
182
  :rtype: job.FileID
142
- '''
143
- with open(job.fileStore.getLocalTempFileName(), 'wb') as fH:
183
+ """
184
+ with open(job.fileStore.getLocalTempFileName(), "wb") as fH:
144
185
  fH.write(os.urandom(fileSize))
145
186
  return job.fileStore.writeGlobalFile(fH.name)
146
187
 
@@ -166,15 +207,18 @@ def maxConcurrency(job, cpuCount, filename, coresPerJob):
166
207
  :param int coresPerJob: number of cores assigned to each job
167
208
  :return int max concurrency value:
168
209
  """
169
- one = job.addChildFn(getOne, cores=0.1, memory='32M', disk='1M')
170
- thirtyTwoMb = job.addChildFn(getThirtyTwoMb, cores=0.1, memory='32M', disk='1M')
210
+ one = job.addChildFn(getOne, cores=0.1, memory="32M", disk="1M")
211
+ thirtyTwoMb = job.addChildFn(getThirtyTwoMb, cores=0.1, memory="32M", disk="1M")
171
212
 
172
213
  values = []
173
214
  for _ in range(cpuCount):
174
- value = job.addFollowOnFn(batchSystemTest.measureConcurrency, filename,
175
- cores=PromisedRequirement(lambda x: x * coresPerJob, one.rv()),
176
- memory=PromisedRequirement(thirtyTwoMb.rv()),
177
- disk='1M').rv()
215
+ value = job.addFollowOnFn(
216
+ batchSystemTest.measureConcurrency,
217
+ filename,
218
+ cores=PromisedRequirement(lambda x: x * coresPerJob, one.rv()),
219
+ memory=PromisedRequirement(thirtyTwoMb.rv()),
220
+ disk="1M",
221
+ ).rv()
178
222
  values.append(value)
179
223
  return values
180
224
 
@@ -184,7 +228,7 @@ def getOne():
184
228
 
185
229
 
186
230
  def getThirtyTwoMb():
187
- return '32M'
231
+ return "32M"
188
232
 
189
233
 
190
234
  def logDiskUsage(job, funcName, sleep=0):
@@ -194,7 +238,7 @@ def logDiskUsage(job, funcName, sleep=0):
194
238
  :return: job function's disk usage
195
239
  """
196
240
  diskUsage = job.disk
197
- job.fileStore.log_to_leader(f'{funcName}: {diskUsage}')
241
+ job.fileStore.log_to_leader(f"{funcName}: {diskUsage}")
198
242
  time.sleep(sleep)
199
243
  return diskUsage
200
244
 
@@ -212,14 +256,16 @@ class SingleMachinePromisedRequirementsTest(hidden.AbstractPromisedRequirementsT
212
256
 
213
257
 
214
258
  @needs_mesos
215
- class MesosPromisedRequirementsTest(hidden.AbstractPromisedRequirementsTest, MesosTestSupport):
259
+ class MesosPromisedRequirementsTest(
260
+ hidden.AbstractPromisedRequirementsTest, MesosTestSupport
261
+ ):
216
262
  """
217
263
  Tests against the Mesos batch system
218
264
  """
219
265
 
220
266
  def getOptions(self, tempDir, caching=True):
221
267
  options = super().getOptions(tempDir, caching=caching)
222
- options.mesos_endpoint = 'localhost:5050'
268
+ options.mesos_endpoint = "localhost:5050"
223
269
  return options
224
270
 
225
271
  def getBatchSystemName(self):
@@ -23,7 +23,7 @@ class CachedUnpicklingJobStoreTest(ToilTest):
23
23
  """
24
24
  for _ in range(2):
25
25
  options = Job.Runner.getDefaultOptions(self._getTestJobStorePath())
26
- options.logLevel = 'INFO'
26
+ options.logLevel = "INFO"
27
27
  root = Job.wrapJobFn(parent)
28
28
  Job.Runner.startToil(root, options)
29
29
 
@@ -40,7 +40,7 @@ class ChainedIndexedPromisesTest(ToilTest):
40
40
  # https://github.com/BD2KGenomics/toil/issues/1021
41
41
  def test(self):
42
42
  options = Job.Runner.getDefaultOptions(self._getTestJobStorePath())
43
- options.logLevel = 'INFO'
43
+ options.logLevel = "INFO"
44
44
  root = Job.wrapJobFn(a)
45
45
  self.assertEqual(Job.Runner.startToil(root, options), 42)
46
46
 
@@ -62,17 +62,18 @@ class PathIndexingPromiseTest(ToilTest):
62
62
  Test support for indexing promises of arbitrarily nested data structures of lists, dicts and
63
63
  tuples, or any other object supporting the __getitem__() protocol.
64
64
  """
65
+
65
66
  def test(self):
66
67
  options = Job.Runner.getDefaultOptions(self._getTestJobStorePath())
67
- options.logLevel = 'INFO'
68
+ options.logLevel = "INFO"
68
69
  root = Job.wrapJobFn(d)
69
- self.assertEqual(Job.Runner.startToil(root, options), ('b', 43, 3))
70
+ self.assertEqual(Job.Runner.startToil(root, options), ("b", 43, 3))
70
71
 
71
72
 
72
73
  def d(job):
73
74
  child = job.addChild(job.wrapFn(e))
74
- return child.rv('a'), child.rv(42), child.rv('c', 2)
75
+ return child.rv("a"), child.rv(42), child.rv("c", 2)
75
76
 
76
77
 
77
78
  def e():
78
- return {'a': 'b', 42: 43, 'c': [1, 2, 3]}
79
+ return {"a": "b", 42: 43, "c": [1, 2, 3]}
@@ -23,13 +23,16 @@ class RealtimeLoggerTest(ToilTest):
23
23
  def testRealtimeLogger(self):
24
24
  options = Job.Runner.getDefaultOptions(self._getTestJobStorePath())
25
25
  options.realTimeLogging = True
26
- options.logLevel = 'INFO'
26
+ options.logLevel = "INFO"
27
27
 
28
28
  detector = MessageDetector()
29
29
 
30
30
  # Set up a log message detector to the root logger
31
31
  logging.getLogger().addHandler(detector)
32
32
 
33
+ # I believe coloredlogs replaces handlers with its own when doing handler formatting, preserving only filters
34
+ # https://github.com/xolox/python-coloredlogs/blob/65bdfe976ac0bf81e8c0bd9a98242b9d666b2859/coloredlogs/__init__.py#L453-L459
35
+ options.colored_logs = False
33
36
  Job.Runner.startToil(LogTest(), options)
34
37
 
35
38
  # We need the message we're supposed to see
@@ -46,19 +49,20 @@ class MessageDetector(logging.StreamHandler):
46
49
  def __init__(self):
47
50
  self.detected = False # Have we seen the message we want?
48
51
  self.overLogged = False # Have we seen the message we don't want?
52
+
49
53
  super().__init__()
50
54
 
51
55
  def emit(self, record):
52
- if record.msg == 'This should be logged at info level':
56
+ if record.msg == "This should be logged at info level":
53
57
  self.detected = True
54
- if record.msg == 'This should be logged at debug level':
58
+ if record.msg == "This should be logged at debug level":
55
59
  self.overLogged = True
56
60
 
57
61
 
58
62
  class LogTest(Job):
59
63
  def __init__(self):
60
- Job.__init__(self, memory=100000, cores=1, disk='3G')
64
+ Job.__init__(self, memory=100000, cores=1, disk="3G")
61
65
 
62
66
  def run(self, fileStore):
63
- RealtimeLogger.info('This should be logged at info level')
64
- RealtimeLogger.debug('This should be logged at debug level')
67
+ RealtimeLogger.info("This should be logged at info level")
68
+ RealtimeLogger.debug("This should be logged at debug level")
@@ -28,10 +28,14 @@ class RegularLogTest(ToilTest):
28
28
 
29
29
  def setUp(self) -> None:
30
30
  super().setUp()
31
- self.tempDir = self._createTempDir(purpose='tempDir')
31
+ self.tempDir = self._createTempDir(purpose="tempDir")
32
32
 
33
33
  def _getFiles(self, dir):
34
- return [os.path.join(dir, f) for f in os.listdir(dir) if os.path.isfile(os.path.join(dir, f))]
34
+ return [
35
+ os.path.join(dir, f)
36
+ for f in os.listdir(dir)
37
+ if os.path.isfile(os.path.join(dir, f))
38
+ ]
35
39
 
36
40
  def _assertFileTypeExists(self, dir, extension, encoding=None):
37
41
  # an encoding of None implies no compression
@@ -45,56 +49,86 @@ class RegularLogTest(ToilTest):
45
49
  if encoding is not None:
46
50
  for log in onlyLogs:
47
51
  with open(log, "rb") as f:
48
- logger.info("Checking for encoding %s on file %s", str(encoding), log)
52
+ logger.info(
53
+ "Checking for encoding %s on file %s", str(encoding), log
54
+ )
49
55
  if encoding == "gzip":
50
56
  # Check for gzip magic header '\x1f\x8b'
51
- assert f.read().startswith(b'\x1f\x8b')
57
+ assert f.read().startswith(b"\x1f\x8b")
52
58
  else:
53
59
  mime = mimetypes.guess_type(log)
54
60
  self.assertEqual(mime[1], encoding)
55
61
 
56
62
  @slow
57
63
  def testLogToMaster(self):
58
- toilOutput = subprocess.check_output([sys.executable,
59
- '-m', helloWorld.__name__,
60
- './toilTest',
61
- '--clean=always',
62
- '--logLevel=info'], stderr=subprocess.STDOUT)
63
- assert helloWorld.childMessage in toilOutput.decode('utf-8')
64
+ toilOutput = subprocess.check_output(
65
+ [
66
+ sys.executable,
67
+ "-m",
68
+ helloWorld.__name__,
69
+ "./toilTest",
70
+ "--clean=always",
71
+ "--logLevel=info",
72
+ ],
73
+ stderr=subprocess.STDOUT,
74
+ )
75
+ assert helloWorld.childMessage in toilOutput.decode("utf-8")
64
76
 
65
77
  def testWriteLogs(self):
66
- subprocess.check_call([sys.executable,
67
- '-m', helloWorld.__name__,
68
- './toilTest',
69
- '--clean=always',
70
- '--logLevel=debug',
71
- '--writeLogs=%s' % self.tempDir])
72
- self._assertFileTypeExists(self.tempDir, '.log')
78
+ subprocess.check_call(
79
+ [
80
+ sys.executable,
81
+ "-m",
82
+ helloWorld.__name__,
83
+ "./toilTest",
84
+ "--clean=always",
85
+ "--logLevel=debug",
86
+ "--writeLogs=%s" % self.tempDir,
87
+ ]
88
+ )
89
+ self._assertFileTypeExists(self.tempDir, ".log")
73
90
 
74
91
  @slow
75
92
  def testWriteGzipLogs(self):
76
- subprocess.check_call([sys.executable,
77
- '-m', helloWorld.__name__,
78
- './toilTest',
79
- '--clean=always',
80
- '--logLevel=debug',
81
- '--writeLogsGzip=%s' % self.tempDir])
82
- self._assertFileTypeExists(self.tempDir, '.log.gz', 'gzip')
93
+ subprocess.check_call(
94
+ [
95
+ sys.executable,
96
+ "-m",
97
+ helloWorld.__name__,
98
+ "./toilTest",
99
+ "--clean=always",
100
+ "--logLevel=debug",
101
+ "--writeLogsGzip=%s" % self.tempDir,
102
+ ]
103
+ )
104
+ self._assertFileTypeExists(self.tempDir, ".log.gz", "gzip")
83
105
 
84
106
  @slow
85
107
  def testMultipleLogToMaster(self):
86
- toilOutput = subprocess.check_output([sys.executable,
87
- '-m', helloWorld.__name__,
88
- './toilTest',
89
- '--clean=always',
90
- '--logLevel=info'], stderr=subprocess.STDOUT)
91
- assert helloWorld.parentMessage in toilOutput.decode('utf-8')
108
+ toilOutput = subprocess.check_output(
109
+ [
110
+ sys.executable,
111
+ "-m",
112
+ helloWorld.__name__,
113
+ "./toilTest",
114
+ "--clean=always",
115
+ "--logLevel=info",
116
+ ],
117
+ stderr=subprocess.STDOUT,
118
+ )
119
+ assert helloWorld.parentMessage in toilOutput.decode("utf-8")
92
120
 
93
121
  def testRegularLog(self):
94
- toilOutput = subprocess.check_output([sys.executable,
95
- '-m', helloWorld.__name__,
96
- './toilTest',
97
- '--clean=always',
98
- '--batchSystem=single_machine',
99
- '--logLevel=debug'], stderr=subprocess.STDOUT)
100
- assert "single machine batch system" in toilOutput.decode('utf-8')
122
+ toilOutput = subprocess.check_output(
123
+ [
124
+ sys.executable,
125
+ "-m",
126
+ helloWorld.__name__,
127
+ "./toilTest",
128
+ "--clean=always",
129
+ "--batchSystem=single_machine",
130
+ "--logLevel=debug",
131
+ ],
132
+ stderr=subprocess.STDOUT,
133
+ )
134
+ assert "single machine batch system" in toilOutput.decode("utf-8")