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.
- toil/__init__.py +122 -315
- toil/batchSystems/__init__.py +1 -0
- toil/batchSystems/abstractBatchSystem.py +173 -89
- toil/batchSystems/abstractGridEngineBatchSystem.py +272 -148
- toil/batchSystems/awsBatch.py +244 -135
- toil/batchSystems/cleanup_support.py +26 -16
- toil/batchSystems/contained_executor.py +31 -28
- toil/batchSystems/gridengine.py +86 -50
- toil/batchSystems/htcondor.py +166 -89
- toil/batchSystems/kubernetes.py +632 -382
- toil/batchSystems/local_support.py +20 -15
- toil/batchSystems/lsf.py +134 -81
- toil/batchSystems/lsfHelper.py +13 -11
- toil/batchSystems/mesos/__init__.py +41 -29
- toil/batchSystems/mesos/batchSystem.py +290 -151
- toil/batchSystems/mesos/executor.py +79 -50
- toil/batchSystems/mesos/test/__init__.py +31 -23
- toil/batchSystems/options.py +46 -28
- toil/batchSystems/registry.py +53 -19
- toil/batchSystems/singleMachine.py +296 -125
- toil/batchSystems/slurm.py +603 -138
- toil/batchSystems/torque.py +47 -33
- toil/bus.py +186 -76
- toil/common.py +664 -368
- toil/cwl/__init__.py +1 -1
- toil/cwl/cwltoil.py +1136 -483
- toil/cwl/utils.py +17 -22
- toil/deferred.py +63 -42
- toil/exceptions.py +5 -3
- toil/fileStores/__init__.py +5 -5
- toil/fileStores/abstractFileStore.py +140 -60
- toil/fileStores/cachingFileStore.py +717 -269
- toil/fileStores/nonCachingFileStore.py +116 -87
- toil/job.py +1225 -368
- toil/jobStores/abstractJobStore.py +416 -266
- toil/jobStores/aws/jobStore.py +863 -477
- toil/jobStores/aws/utils.py +201 -120
- toil/jobStores/conftest.py +3 -2
- toil/jobStores/fileJobStore.py +292 -154
- toil/jobStores/googleJobStore.py +140 -74
- toil/jobStores/utils.py +36 -15
- toil/leader.py +668 -272
- toil/lib/accelerators.py +115 -18
- toil/lib/aws/__init__.py +74 -31
- toil/lib/aws/ami.py +122 -87
- toil/lib/aws/iam.py +284 -108
- toil/lib/aws/s3.py +31 -0
- toil/lib/aws/session.py +214 -39
- toil/lib/aws/utils.py +287 -231
- toil/lib/bioio.py +13 -5
- toil/lib/compatibility.py +11 -6
- toil/lib/conversions.py +104 -47
- toil/lib/docker.py +131 -103
- toil/lib/ec2.py +361 -199
- toil/lib/ec2nodes.py +174 -106
- toil/lib/encryption/_dummy.py +5 -3
- toil/lib/encryption/_nacl.py +10 -6
- toil/lib/encryption/conftest.py +1 -0
- toil/lib/exceptions.py +26 -7
- toil/lib/expando.py +5 -3
- toil/lib/ftp_utils.py +217 -0
- toil/lib/generatedEC2Lists.py +127 -19
- toil/lib/humanize.py +6 -2
- toil/lib/integration.py +341 -0
- toil/lib/io.py +141 -15
- toil/lib/iterables.py +4 -2
- toil/lib/memoize.py +12 -8
- toil/lib/misc.py +66 -21
- toil/lib/objects.py +2 -2
- toil/lib/resources.py +68 -15
- toil/lib/retry.py +126 -81
- toil/lib/threading.py +299 -82
- toil/lib/throttle.py +16 -15
- toil/options/common.py +843 -409
- toil/options/cwl.py +175 -90
- toil/options/runner.py +50 -0
- toil/options/wdl.py +73 -17
- toil/provisioners/__init__.py +117 -46
- toil/provisioners/abstractProvisioner.py +332 -157
- toil/provisioners/aws/__init__.py +70 -33
- toil/provisioners/aws/awsProvisioner.py +1145 -715
- toil/provisioners/clusterScaler.py +541 -279
- toil/provisioners/gceProvisioner.py +282 -179
- toil/provisioners/node.py +155 -79
- toil/realtimeLogger.py +34 -22
- toil/resource.py +137 -75
- toil/server/app.py +128 -62
- toil/server/celery_app.py +3 -1
- toil/server/cli/wes_cwl_runner.py +82 -53
- toil/server/utils.py +54 -28
- toil/server/wes/abstract_backend.py +64 -26
- toil/server/wes/amazon_wes_utils.py +21 -15
- toil/server/wes/tasks.py +121 -63
- toil/server/wes/toil_backend.py +142 -107
- toil/server/wsgi_app.py +4 -3
- toil/serviceManager.py +58 -22
- toil/statsAndLogging.py +224 -70
- toil/test/__init__.py +282 -183
- toil/test/batchSystems/batchSystemTest.py +460 -210
- toil/test/batchSystems/batch_system_plugin_test.py +90 -0
- toil/test/batchSystems/test_gridengine.py +173 -0
- toil/test/batchSystems/test_lsf_helper.py +67 -58
- toil/test/batchSystems/test_slurm.py +110 -49
- toil/test/cactus/__init__.py +0 -0
- toil/test/cactus/test_cactus_integration.py +56 -0
- toil/test/cwl/cwlTest.py +496 -287
- toil/test/cwl/measure_default_memory.cwl +12 -0
- toil/test/cwl/not_run_required_input.cwl +29 -0
- toil/test/cwl/scatter_duplicate_outputs.cwl +40 -0
- toil/test/cwl/seqtk_seq.cwl +1 -1
- toil/test/docs/scriptsTest.py +69 -46
- toil/test/jobStores/jobStoreTest.py +427 -264
- toil/test/lib/aws/test_iam.py +118 -50
- toil/test/lib/aws/test_s3.py +16 -9
- toil/test/lib/aws/test_utils.py +5 -6
- toil/test/lib/dockerTest.py +118 -141
- toil/test/lib/test_conversions.py +113 -115
- toil/test/lib/test_ec2.py +58 -50
- toil/test/lib/test_integration.py +104 -0
- toil/test/lib/test_misc.py +12 -5
- toil/test/mesos/MesosDataStructuresTest.py +23 -10
- toil/test/mesos/helloWorld.py +7 -6
- toil/test/mesos/stress.py +25 -20
- toil/test/options/__init__.py +13 -0
- toil/test/options/options.py +42 -0
- toil/test/provisioners/aws/awsProvisionerTest.py +320 -150
- toil/test/provisioners/clusterScalerTest.py +440 -250
- toil/test/provisioners/clusterTest.py +166 -44
- toil/test/provisioners/gceProvisionerTest.py +174 -100
- toil/test/provisioners/provisionerTest.py +25 -13
- toil/test/provisioners/restartScript.py +5 -4
- toil/test/server/serverTest.py +188 -141
- toil/test/sort/restart_sort.py +137 -68
- toil/test/sort/sort.py +134 -66
- toil/test/sort/sortTest.py +91 -49
- toil/test/src/autoDeploymentTest.py +141 -101
- toil/test/src/busTest.py +20 -18
- toil/test/src/checkpointTest.py +8 -2
- toil/test/src/deferredFunctionTest.py +49 -35
- toil/test/src/dockerCheckTest.py +32 -24
- toil/test/src/environmentTest.py +135 -0
- toil/test/src/fileStoreTest.py +539 -272
- toil/test/src/helloWorldTest.py +7 -4
- toil/test/src/importExportFileTest.py +61 -31
- toil/test/src/jobDescriptionTest.py +46 -21
- toil/test/src/jobEncapsulationTest.py +2 -0
- toil/test/src/jobFileStoreTest.py +74 -50
- toil/test/src/jobServiceTest.py +187 -73
- toil/test/src/jobTest.py +121 -71
- toil/test/src/miscTests.py +19 -18
- toil/test/src/promisedRequirementTest.py +82 -36
- toil/test/src/promisesTest.py +7 -6
- toil/test/src/realtimeLoggerTest.py +10 -6
- toil/test/src/regularLogTest.py +71 -37
- toil/test/src/resourceTest.py +80 -49
- toil/test/src/restartDAGTest.py +36 -22
- toil/test/src/resumabilityTest.py +9 -2
- toil/test/src/retainTempDirTest.py +45 -14
- toil/test/src/systemTest.py +12 -8
- toil/test/src/threadingTest.py +44 -25
- toil/test/src/toilContextManagerTest.py +10 -7
- toil/test/src/userDefinedJobArgTypeTest.py +8 -5
- toil/test/src/workerTest.py +73 -23
- toil/test/utils/toilDebugTest.py +103 -33
- toil/test/utils/toilKillTest.py +4 -5
- toil/test/utils/utilsTest.py +245 -106
- toil/test/wdl/wdltoil_test.py +818 -149
- toil/test/wdl/wdltoil_test_kubernetes.py +91 -0
- toil/toilState.py +120 -35
- toil/utils/toilConfig.py +13 -4
- toil/utils/toilDebugFile.py +44 -27
- toil/utils/toilDebugJob.py +214 -27
- toil/utils/toilDestroyCluster.py +11 -6
- toil/utils/toilKill.py +8 -3
- toil/utils/toilLaunchCluster.py +256 -140
- toil/utils/toilMain.py +37 -16
- toil/utils/toilRsyncCluster.py +32 -14
- toil/utils/toilSshCluster.py +49 -22
- toil/utils/toilStats.py +356 -273
- toil/utils/toilStatus.py +292 -139
- toil/utils/toilUpdateEC2Instances.py +3 -1
- toil/version.py +12 -12
- toil/wdl/utils.py +5 -5
- toil/wdl/wdltoil.py +3913 -1033
- toil/worker.py +367 -184
- {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/LICENSE +25 -0
- toil-8.0.0.dist-info/METADATA +173 -0
- toil-8.0.0.dist-info/RECORD +253 -0
- {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/WHEEL +1 -1
- toil-6.1.0a1.dist-info/METADATA +0 -125
- toil-6.1.0a1.dist-info/RECORD +0 -237
- {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/entry_points.txt +0 -0
- {toil-6.1.0a1.dist-info → toil-8.0.0.dist-info}/top_level.txt +0 -0
toil/test/lib/dockerTest.py
CHANGED
|
@@ -22,12 +22,14 @@ from docker.errors import ContainerError
|
|
|
22
22
|
from toil.common import Toil
|
|
23
23
|
from toil.exceptions import FailedJobsException
|
|
24
24
|
from toil.job import Job
|
|
25
|
-
from toil.lib.docker import (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
from toil.lib.docker import (
|
|
26
|
+
FORGO,
|
|
27
|
+
RM,
|
|
28
|
+
STOP,
|
|
29
|
+
apiDockerCall,
|
|
30
|
+
containerIsRunning,
|
|
31
|
+
dockerKill,
|
|
32
|
+
)
|
|
31
33
|
from toil.test import ToilTest, needs_docker, slow
|
|
32
34
|
|
|
33
35
|
logger = logging.getLogger(__name__)
|
|
@@ -47,15 +49,12 @@ class DockerTest(ToilTest):
|
|
|
47
49
|
removed during tear down.
|
|
48
50
|
Otherwise, left-over files will not be removed.
|
|
49
51
|
"""
|
|
52
|
+
|
|
50
53
|
def setUp(self):
|
|
51
|
-
self.tempDir = self._createTempDir(purpose=
|
|
52
|
-
self.dockerTestLogLevel =
|
|
53
|
-
|
|
54
|
-
def testDockerClean(self,
|
|
55
|
-
caching=False,
|
|
56
|
-
detached=True,
|
|
57
|
-
rm=True,
|
|
58
|
-
deferParam=None):
|
|
54
|
+
self.tempDir = self._createTempDir(purpose="tempDir")
|
|
55
|
+
self.dockerTestLogLevel = "INFO"
|
|
56
|
+
|
|
57
|
+
def testDockerClean(self, caching=False, detached=True, rm=True, deferParam=None):
|
|
59
58
|
"""
|
|
60
59
|
Run the test container that creates a file in the work dir, and sleeps
|
|
61
60
|
for 5 minutes.
|
|
@@ -73,29 +72,25 @@ class DockerTest(ToilTest):
|
|
|
73
72
|
# detached X R E X
|
|
74
73
|
# Neither X R E X
|
|
75
74
|
|
|
76
|
-
data_dir = os.path.join(self.tempDir,
|
|
77
|
-
working_dir = os.path.join(self.tempDir,
|
|
78
|
-
test_file = os.path.join(working_dir,
|
|
75
|
+
data_dir = os.path.join(self.tempDir, "data")
|
|
76
|
+
working_dir = os.path.join(self.tempDir, "working")
|
|
77
|
+
test_file = os.path.join(working_dir, "test.txt")
|
|
79
78
|
|
|
80
79
|
os.makedirs(data_dir, exist_ok=True)
|
|
81
80
|
os.makedirs(working_dir, exist_ok=True)
|
|
82
81
|
|
|
83
|
-
options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir,
|
|
84
|
-
'jobstore'))
|
|
82
|
+
options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir, "jobstore"))
|
|
85
83
|
options.logLevel = self.dockerTestLogLevel
|
|
86
84
|
options.workDir = working_dir
|
|
87
|
-
options.clean =
|
|
85
|
+
options.clean = "always"
|
|
88
86
|
options.retryCount = 0 # we're expecting the job to fail so don't retry!
|
|
89
87
|
options.caching = caching
|
|
90
88
|
|
|
91
89
|
# No base64 logic since it might create a name starting with a `-`.
|
|
92
90
|
container_name = uuid.uuid4().hex
|
|
93
|
-
A = Job.wrapJobFn(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
rm,
|
|
97
|
-
deferParam,
|
|
98
|
-
container_name)
|
|
91
|
+
A = Job.wrapJobFn(
|
|
92
|
+
_testDockerCleanFn, working_dir, detached, rm, deferParam, container_name
|
|
93
|
+
)
|
|
99
94
|
try:
|
|
100
95
|
with Toil(options) as toil:
|
|
101
96
|
toil.start(A)
|
|
@@ -110,18 +105,21 @@ class DockerTest(ToilTest):
|
|
|
110
105
|
|
|
111
106
|
if (rm and (deferParam != FORGO)) or deferParam == RM or deferParam is None:
|
|
112
107
|
# These containers should not exist
|
|
113
|
-
assert
|
|
114
|
-
|
|
108
|
+
assert (
|
|
109
|
+
containerIsRunning(container_name) is None
|
|
110
|
+
), "Container was not removed."
|
|
115
111
|
|
|
116
112
|
elif deferParam == STOP:
|
|
117
113
|
# These containers should exist but be non-running
|
|
118
|
-
assert
|
|
119
|
-
|
|
114
|
+
assert (
|
|
115
|
+
containerIsRunning(container_name) == False
|
|
116
|
+
), "Container was not stopped."
|
|
120
117
|
|
|
121
118
|
else:
|
|
122
119
|
# These containers will be running
|
|
123
|
-
assert
|
|
124
|
-
|
|
120
|
+
assert (
|
|
121
|
+
containerIsRunning(container_name) == True
|
|
122
|
+
), "Container was not running."
|
|
125
123
|
finally:
|
|
126
124
|
# Clean up
|
|
127
125
|
try:
|
|
@@ -131,121 +129,97 @@ class DockerTest(ToilTest):
|
|
|
131
129
|
pass
|
|
132
130
|
|
|
133
131
|
def testDockerClean_CRx_FORGO(self):
|
|
134
|
-
self.testDockerClean(caching=False, detached=False, rm=True,
|
|
135
|
-
deferParam=FORGO)
|
|
132
|
+
self.testDockerClean(caching=False, detached=False, rm=True, deferParam=FORGO)
|
|
136
133
|
|
|
137
134
|
def testDockerClean_CRx_STOP(self):
|
|
138
|
-
self.testDockerClean(caching=False, detached=False, rm=True,
|
|
139
|
-
deferParam=STOP)
|
|
135
|
+
self.testDockerClean(caching=False, detached=False, rm=True, deferParam=STOP)
|
|
140
136
|
|
|
141
137
|
def testDockerClean_CRx_RM(self):
|
|
142
|
-
self.testDockerClean(caching=False, detached=False, rm=True,
|
|
143
|
-
deferParam=RM)
|
|
138
|
+
self.testDockerClean(caching=False, detached=False, rm=True, deferParam=RM)
|
|
144
139
|
|
|
145
140
|
@slow
|
|
146
141
|
def testDockerClean_CRx_None(self):
|
|
147
|
-
self.testDockerClean(caching=False, detached=False, rm=True,
|
|
148
|
-
deferParam=None)
|
|
142
|
+
self.testDockerClean(caching=False, detached=False, rm=True, deferParam=None)
|
|
149
143
|
|
|
150
144
|
@slow
|
|
151
145
|
def testDockerClean_CxD_FORGO(self):
|
|
152
|
-
self.testDockerClean(caching=False, detached=True, rm=False,
|
|
153
|
-
deferParam=FORGO)
|
|
146
|
+
self.testDockerClean(caching=False, detached=True, rm=False, deferParam=FORGO)
|
|
154
147
|
|
|
155
148
|
@slow
|
|
156
149
|
def testDockerClean_CxD_STOP(self):
|
|
157
|
-
self.testDockerClean(caching=False, detached=True, rm=False,
|
|
158
|
-
deferParam=STOP)
|
|
150
|
+
self.testDockerClean(caching=False, detached=True, rm=False, deferParam=STOP)
|
|
159
151
|
|
|
160
152
|
@slow
|
|
161
153
|
def testDockerClean_CxD_RM(self):
|
|
162
|
-
self.testDockerClean(caching=False, detached=True, rm=False,
|
|
163
|
-
deferParam=RM)
|
|
154
|
+
self.testDockerClean(caching=False, detached=True, rm=False, deferParam=RM)
|
|
164
155
|
|
|
165
156
|
@slow
|
|
166
157
|
def testDockerClean_CxD_None(self):
|
|
167
|
-
self.testDockerClean(caching=False, detached=True, rm=False,
|
|
168
|
-
deferParam=None)
|
|
158
|
+
self.testDockerClean(caching=False, detached=True, rm=False, deferParam=None)
|
|
169
159
|
|
|
170
160
|
@slow
|
|
171
161
|
def testDockerClean_Cxx_FORGO(self):
|
|
172
|
-
self.testDockerClean(caching=False, detached=False, rm=False,
|
|
173
|
-
deferParam=FORGO)
|
|
162
|
+
self.testDockerClean(caching=False, detached=False, rm=False, deferParam=FORGO)
|
|
174
163
|
|
|
175
164
|
@slow
|
|
176
165
|
def testDockerClean_Cxx_STOP(self):
|
|
177
|
-
self.testDockerClean(caching=False, detached=False, rm=False,
|
|
178
|
-
deferParam=STOP)
|
|
166
|
+
self.testDockerClean(caching=False, detached=False, rm=False, deferParam=STOP)
|
|
179
167
|
|
|
180
168
|
@slow
|
|
181
169
|
def testDockerClean_Cxx_RM(self):
|
|
182
|
-
self.testDockerClean(caching=False, detached=False, rm=False,
|
|
183
|
-
deferParam=RM)
|
|
170
|
+
self.testDockerClean(caching=False, detached=False, rm=False, deferParam=RM)
|
|
184
171
|
|
|
185
172
|
@slow
|
|
186
173
|
def testDockerClean_Cxx_None(self):
|
|
187
|
-
self.testDockerClean(caching=False, detached=False, rm=False,
|
|
188
|
-
deferParam=None)
|
|
174
|
+
self.testDockerClean(caching=False, detached=False, rm=False, deferParam=None)
|
|
189
175
|
|
|
190
176
|
@slow
|
|
191
177
|
def testDockerClean_xRx_FORGO(self):
|
|
192
|
-
self.testDockerClean(caching=True, detached=False, rm=True,
|
|
193
|
-
deferParam=FORGO)
|
|
178
|
+
self.testDockerClean(caching=True, detached=False, rm=True, deferParam=FORGO)
|
|
194
179
|
|
|
195
180
|
@slow
|
|
196
181
|
def testDockerClean_xRx_STOP(self):
|
|
197
|
-
self.testDockerClean(caching=True, detached=False, rm=True,
|
|
198
|
-
deferParam=STOP)
|
|
182
|
+
self.testDockerClean(caching=True, detached=False, rm=True, deferParam=STOP)
|
|
199
183
|
|
|
200
184
|
@slow
|
|
201
185
|
def testDockerClean_xRx_RM(self):
|
|
202
|
-
self.testDockerClean(caching=True, detached=False, rm=True,
|
|
203
|
-
deferParam=RM)
|
|
186
|
+
self.testDockerClean(caching=True, detached=False, rm=True, deferParam=RM)
|
|
204
187
|
|
|
205
188
|
@slow
|
|
206
189
|
def testDockerClean_xRx_None(self):
|
|
207
|
-
self.testDockerClean(caching=True, detached=False, rm=True,
|
|
208
|
-
deferParam=None)
|
|
190
|
+
self.testDockerClean(caching=True, detached=False, rm=True, deferParam=None)
|
|
209
191
|
|
|
210
192
|
@slow
|
|
211
193
|
def testDockerClean_xxD_FORGO(self):
|
|
212
|
-
self.testDockerClean(caching=True, detached=True, rm=False,
|
|
213
|
-
deferParam=FORGO)
|
|
194
|
+
self.testDockerClean(caching=True, detached=True, rm=False, deferParam=FORGO)
|
|
214
195
|
|
|
215
196
|
@slow
|
|
216
197
|
def testDockerClean_xxD_STOP(self):
|
|
217
|
-
self.testDockerClean(caching=True, detached=True, rm=False,
|
|
218
|
-
deferParam=STOP)
|
|
198
|
+
self.testDockerClean(caching=True, detached=True, rm=False, deferParam=STOP)
|
|
219
199
|
|
|
220
200
|
@slow
|
|
221
201
|
def testDockerClean_xxD_RM(self):
|
|
222
|
-
self.testDockerClean(caching=True, detached=True, rm=False,
|
|
223
|
-
deferParam=RM)
|
|
202
|
+
self.testDockerClean(caching=True, detached=True, rm=False, deferParam=RM)
|
|
224
203
|
|
|
225
204
|
@slow
|
|
226
205
|
def testDockerClean_xxD_None(self):
|
|
227
|
-
self.testDockerClean(caching=True, detached=True, rm=False,
|
|
228
|
-
deferParam=None)
|
|
206
|
+
self.testDockerClean(caching=True, detached=True, rm=False, deferParam=None)
|
|
229
207
|
|
|
230
208
|
@slow
|
|
231
209
|
def testDockerClean_xxx_FORGO(self):
|
|
232
|
-
self.testDockerClean(caching=True, detached=False, rm=False,
|
|
233
|
-
deferParam=FORGO)
|
|
210
|
+
self.testDockerClean(caching=True, detached=False, rm=False, deferParam=FORGO)
|
|
234
211
|
|
|
235
212
|
@slow
|
|
236
213
|
def testDockerClean_xxx_STOP(self):
|
|
237
|
-
self.testDockerClean(caching=True, detached=False, rm=False,
|
|
238
|
-
deferParam=STOP)
|
|
214
|
+
self.testDockerClean(caching=True, detached=False, rm=False, deferParam=STOP)
|
|
239
215
|
|
|
240
216
|
@slow
|
|
241
217
|
def testDockerClean_xxx_RM(self):
|
|
242
|
-
self.testDockerClean(caching=True, detached=False, rm=False,
|
|
243
|
-
deferParam=RM)
|
|
218
|
+
self.testDockerClean(caching=True, detached=False, rm=False, deferParam=RM)
|
|
244
219
|
|
|
245
220
|
@slow
|
|
246
221
|
def testDockerClean_xxx_None(self):
|
|
247
|
-
self.testDockerClean(caching=True, detached=False, rm=False,
|
|
248
|
-
deferParam=None)
|
|
222
|
+
self.testDockerClean(caching=True, detached=False, rm=False, deferParam=None)
|
|
249
223
|
|
|
250
224
|
def testDockerPipeChain(self, caching=False):
|
|
251
225
|
r"""
|
|
@@ -255,16 +229,16 @@ class DockerTest(ToilTest):
|
|
|
255
229
|
ex: ``parameters=[ ['printf', 'x\n y\n'], ['wc', '-l'] ]`` should execute:
|
|
256
230
|
``printf 'x\n y\n' | wc -l``
|
|
257
231
|
"""
|
|
258
|
-
options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir,
|
|
232
|
+
options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir, "jobstore"))
|
|
259
233
|
options.logLevel = self.dockerTestLogLevel
|
|
260
234
|
options.workDir = self.tempDir
|
|
261
|
-
options.clean =
|
|
235
|
+
options.clean = "always"
|
|
262
236
|
options.caching = caching
|
|
263
237
|
A = Job.wrapJobFn(_testDockerPipeChainFn)
|
|
264
238
|
rv = Job.Runner.startToil(A, options)
|
|
265
|
-
logger.info(
|
|
266
|
-
rv = rv.decode(
|
|
267
|
-
assert rv.strip() ==
|
|
239
|
+
logger.info("Container pipeline result: %s", repr(rv))
|
|
240
|
+
rv = rv.decode("utf-8")
|
|
241
|
+
assert rv.strip() == "2"
|
|
268
242
|
|
|
269
243
|
def testDockerPipeChainErrorDetection(self, caching=False):
|
|
270
244
|
"""
|
|
@@ -273,10 +247,10 @@ class DockerTest(ToilTest):
|
|
|
273
247
|
silently missed. This tests to make sure that the piping API for
|
|
274
248
|
dockerCall() throws an exception if non-last commands in the chain fail.
|
|
275
249
|
"""
|
|
276
|
-
options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir,
|
|
250
|
+
options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir, "jobstore"))
|
|
277
251
|
options.logLevel = self.dockerTestLogLevel
|
|
278
252
|
options.workDir = self.tempDir
|
|
279
|
-
options.clean =
|
|
253
|
+
options.clean = "always"
|
|
280
254
|
options.caching = caching
|
|
281
255
|
A = Job.wrapJobFn(_testDockerPipeChainErrorFn)
|
|
282
256
|
rv = Job.Runner.startToil(A, options)
|
|
@@ -291,19 +265,21 @@ class DockerTest(ToilTest):
|
|
|
291
265
|
def testDockerLogs(self, stream=False, demux=False):
|
|
292
266
|
"""Test for the different log outputs when deatch=False."""
|
|
293
267
|
|
|
294
|
-
working_dir = os.path.join(self.tempDir,
|
|
295
|
-
script_file = os.path.join(working_dir,
|
|
268
|
+
working_dir = os.path.join(self.tempDir, "working")
|
|
269
|
+
script_file = os.path.join(working_dir, "script.sh")
|
|
296
270
|
os.makedirs(working_dir, exist_ok=True)
|
|
297
271
|
|
|
298
|
-
options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir,
|
|
272
|
+
options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir, "jobstore"))
|
|
299
273
|
options.logLevel = self.dockerTestLogLevel
|
|
300
274
|
options.workDir = working_dir
|
|
301
|
-
options.clean =
|
|
302
|
-
A = Job.wrapJobFn(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
275
|
+
options.clean = "always"
|
|
276
|
+
A = Job.wrapJobFn(
|
|
277
|
+
_testDockerLogsFn,
|
|
278
|
+
working_dir=working_dir,
|
|
279
|
+
script_file=script_file,
|
|
280
|
+
stream=stream,
|
|
281
|
+
demux=demux,
|
|
282
|
+
)
|
|
307
283
|
|
|
308
284
|
try:
|
|
309
285
|
rv = Job.Runner.startToil(A, options)
|
|
@@ -324,12 +300,9 @@ class DockerTest(ToilTest):
|
|
|
324
300
|
self.testDockerLogs(stream=True, demux=True)
|
|
325
301
|
|
|
326
302
|
|
|
327
|
-
def _testDockerCleanFn(
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
rm=None,
|
|
331
|
-
deferParam=None,
|
|
332
|
-
containerName=None):
|
|
303
|
+
def _testDockerCleanFn(
|
|
304
|
+
job, working_dir, detached=None, rm=None, deferParam=None, containerName=None
|
|
305
|
+
):
|
|
333
306
|
"""
|
|
334
307
|
Test function for test docker_clean. Runs a container with given flags and
|
|
335
308
|
then dies leaving behind a zombie container.
|
|
@@ -340,11 +313,12 @@ def _testDockerCleanFn(job,
|
|
|
340
313
|
:param int deferParam: See `deferParam=` in :func:`dockerCall`
|
|
341
314
|
:param str containerName: See `container_name=` in :func:`dockerCall`
|
|
342
315
|
"""
|
|
316
|
+
|
|
343
317
|
def killSelf():
|
|
344
|
-
test_file = os.path.join(working_dir,
|
|
318
|
+
test_file = os.path.join(working_dir, "test.txt")
|
|
345
319
|
# Kill the worker once we are sure the docker container is started
|
|
346
320
|
while not os.path.exists(test_file):
|
|
347
|
-
logger.debug(
|
|
321
|
+
logger.debug("Waiting on the file created by spooky_container.")
|
|
348
322
|
time.sleep(1)
|
|
349
323
|
# By the time we reach here, we are sure the container is running.
|
|
350
324
|
time.sleep(1)
|
|
@@ -354,48 +328,48 @@ def _testDockerCleanFn(job,
|
|
|
354
328
|
# Make it a daemon thread so that thread failure doesn't hang tests.
|
|
355
329
|
t.daemon = True
|
|
356
330
|
t.start()
|
|
357
|
-
apiDockerCall(
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
331
|
+
apiDockerCall(
|
|
332
|
+
job,
|
|
333
|
+
image="quay.io/ucsc_cgl/spooky_test",
|
|
334
|
+
working_dir=working_dir,
|
|
335
|
+
deferParam=deferParam,
|
|
336
|
+
containerName=containerName,
|
|
337
|
+
detach=detached,
|
|
338
|
+
remove=rm,
|
|
339
|
+
privileged=True,
|
|
340
|
+
)
|
|
365
341
|
|
|
366
342
|
|
|
367
343
|
def _testDockerPipeChainFn(job):
|
|
368
344
|
"""Return the result of a simple pipe chain. Should be 2."""
|
|
369
|
-
parameters = [[
|
|
370
|
-
return apiDockerCall(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
345
|
+
parameters = [["printf", "x\n y\n"], ["wc", "-l"]]
|
|
346
|
+
return apiDockerCall(
|
|
347
|
+
job,
|
|
348
|
+
image="quay.io/ucsc_cgl/ubuntu:20.04",
|
|
349
|
+
parameters=parameters,
|
|
350
|
+
privileged=True,
|
|
351
|
+
)
|
|
374
352
|
|
|
375
353
|
|
|
376
354
|
def _testDockerPipeChainErrorFn(job):
|
|
377
355
|
"""Return True if the command exit 1 | wc -l raises a ContainerError."""
|
|
378
|
-
parameters = [[
|
|
356
|
+
parameters = [["exit", "1"], ["wc", "-l"]]
|
|
379
357
|
try:
|
|
380
|
-
apiDockerCall(job,
|
|
381
|
-
image='quay.io/ucsc_cgl/spooky_test',
|
|
382
|
-
parameters=parameters)
|
|
358
|
+
apiDockerCall(job, image="quay.io/ucsc_cgl/spooky_test", parameters=parameters)
|
|
383
359
|
except ContainerError:
|
|
384
360
|
return True
|
|
385
361
|
return False
|
|
386
362
|
|
|
387
363
|
|
|
388
|
-
def _testDockerLogsFn(job,
|
|
389
|
-
working_dir,
|
|
390
|
-
script_file,
|
|
391
|
-
stream=False,
|
|
392
|
-
demux=False):
|
|
364
|
+
def _testDockerLogsFn(job, working_dir, script_file, stream=False, demux=False):
|
|
393
365
|
"""Return True if the test succeeds. Otherwise Exception is raised."""
|
|
394
366
|
|
|
395
367
|
# we write a script file because the redirection operator, '>&2', is wrapped
|
|
396
368
|
# in quotes when passed as parameters.
|
|
397
369
|
import textwrap
|
|
398
|
-
|
|
370
|
+
|
|
371
|
+
bash_script = textwrap.dedent(
|
|
372
|
+
"""
|
|
399
373
|
#!/bin/bash
|
|
400
374
|
echo hello stdout ;
|
|
401
375
|
echo hello stderr >&2 ;
|
|
@@ -403,27 +377,30 @@ def _testDockerLogsFn(job,
|
|
|
403
377
|
echo hello stderr >&2 ;
|
|
404
378
|
echo hello stdout ;
|
|
405
379
|
echo hello stdout ;
|
|
406
|
-
|
|
380
|
+
"""
|
|
381
|
+
)
|
|
407
382
|
|
|
408
|
-
with open(script_file,
|
|
383
|
+
with open(script_file, "w") as file:
|
|
409
384
|
file.write(bash_script)
|
|
410
385
|
|
|
411
|
-
out = apiDockerCall(
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
386
|
+
out = apiDockerCall(
|
|
387
|
+
job,
|
|
388
|
+
image="quay.io/ucsc_cgl/ubuntu:20.04",
|
|
389
|
+
working_dir=working_dir,
|
|
390
|
+
parameters=[script_file],
|
|
391
|
+
volumes={working_dir: {"bind": working_dir, "mode": "rw"}},
|
|
392
|
+
entrypoint="/bin/bash",
|
|
393
|
+
stdout=True,
|
|
394
|
+
stderr=True,
|
|
395
|
+
stream=stream,
|
|
396
|
+
demux=demux,
|
|
397
|
+
)
|
|
421
398
|
|
|
422
399
|
# we check the output length because order is not guaranteed.
|
|
423
400
|
if stream:
|
|
424
401
|
if demux:
|
|
425
402
|
# a generator with tuples of (stdout, stderr)
|
|
426
|
-
assert hasattr(out,
|
|
403
|
+
assert hasattr(out, "__iter__")
|
|
427
404
|
for _ in range(6):
|
|
428
405
|
stdout, stderr = next(out)
|
|
429
406
|
if stdout:
|
|
@@ -435,7 +412,7 @@ def _testDockerLogsFn(job,
|
|
|
435
412
|
assert False
|
|
436
413
|
else:
|
|
437
414
|
# a generator with bytes
|
|
438
|
-
assert hasattr(out,
|
|
415
|
+
assert hasattr(out, "__iter__")
|
|
439
416
|
for _ in range(6):
|
|
440
417
|
assert len(next(out)) == 13
|
|
441
418
|
else:
|