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.
- toil/__init__.py +18 -13
- toil/batchSystems/abstractBatchSystem.py +21 -10
- toil/batchSystems/abstractGridEngineBatchSystem.py +2 -2
- toil/batchSystems/awsBatch.py +14 -14
- toil/batchSystems/contained_executor.py +3 -3
- toil/batchSystems/htcondor.py +0 -1
- toil/batchSystems/kubernetes.py +34 -31
- toil/batchSystems/local_support.py +3 -1
- toil/batchSystems/mesos/batchSystem.py +7 -7
- toil/batchSystems/options.py +32 -83
- toil/batchSystems/registry.py +104 -23
- toil/batchSystems/singleMachine.py +16 -13
- toil/batchSystems/slurm.py +3 -3
- toil/batchSystems/torque.py +0 -1
- toil/bus.py +6 -8
- toil/common.py +532 -743
- toil/cwl/__init__.py +28 -32
- toil/cwl/cwltoil.py +523 -520
- toil/cwl/utils.py +55 -10
- toil/fileStores/__init__.py +2 -2
- toil/fileStores/abstractFileStore.py +36 -11
- toil/fileStores/cachingFileStore.py +607 -530
- toil/fileStores/nonCachingFileStore.py +43 -10
- toil/job.py +140 -75
- toil/jobStores/abstractJobStore.py +147 -79
- toil/jobStores/aws/jobStore.py +23 -9
- toil/jobStores/aws/utils.py +1 -2
- toil/jobStores/fileJobStore.py +117 -19
- toil/jobStores/googleJobStore.py +16 -7
- toil/jobStores/utils.py +5 -6
- toil/leader.py +71 -43
- toil/lib/accelerators.py +10 -5
- toil/lib/aws/__init__.py +3 -14
- toil/lib/aws/ami.py +22 -9
- toil/lib/aws/iam.py +21 -13
- toil/lib/aws/session.py +2 -16
- toil/lib/aws/utils.py +4 -5
- toil/lib/compatibility.py +1 -1
- toil/lib/conversions.py +7 -3
- toil/lib/docker.py +22 -23
- toil/lib/ec2.py +10 -6
- toil/lib/ec2nodes.py +106 -100
- toil/lib/encryption/_nacl.py +2 -1
- toil/lib/generatedEC2Lists.py +325 -18
- toil/lib/io.py +21 -0
- toil/lib/misc.py +1 -1
- toil/lib/resources.py +1 -1
- toil/lib/threading.py +74 -26
- toil/options/common.py +738 -0
- toil/options/cwl.py +336 -0
- toil/options/wdl.py +32 -0
- toil/provisioners/abstractProvisioner.py +1 -4
- toil/provisioners/aws/__init__.py +3 -6
- toil/provisioners/aws/awsProvisioner.py +6 -0
- toil/provisioners/clusterScaler.py +3 -2
- toil/provisioners/gceProvisioner.py +2 -2
- toil/realtimeLogger.py +2 -1
- toil/resource.py +24 -18
- toil/server/app.py +2 -3
- toil/server/cli/wes_cwl_runner.py +4 -4
- toil/server/utils.py +1 -1
- toil/server/wes/abstract_backend.py +3 -2
- toil/server/wes/amazon_wes_utils.py +5 -4
- toil/server/wes/tasks.py +2 -3
- toil/server/wes/toil_backend.py +2 -10
- toil/server/wsgi_app.py +2 -0
- toil/serviceManager.py +12 -10
- toil/statsAndLogging.py +5 -1
- toil/test/__init__.py +29 -54
- toil/test/batchSystems/batchSystemTest.py +11 -111
- toil/test/batchSystems/test_slurm.py +3 -2
- toil/test/cwl/cwlTest.py +213 -90
- toil/test/cwl/glob_dir.cwl +15 -0
- toil/test/cwl/preemptible.cwl +21 -0
- toil/test/cwl/preemptible_expression.cwl +28 -0
- toil/test/cwl/revsort.cwl +1 -1
- toil/test/cwl/revsort2.cwl +1 -1
- toil/test/docs/scriptsTest.py +0 -1
- toil/test/jobStores/jobStoreTest.py +27 -16
- toil/test/lib/aws/test_iam.py +4 -14
- toil/test/lib/aws/test_utils.py +0 -3
- toil/test/lib/dockerTest.py +4 -4
- toil/test/lib/test_ec2.py +11 -16
- toil/test/mesos/helloWorld.py +4 -5
- toil/test/mesos/stress.py +1 -1
- toil/test/provisioners/aws/awsProvisionerTest.py +9 -5
- toil/test/provisioners/clusterScalerTest.py +6 -4
- toil/test/provisioners/clusterTest.py +14 -3
- toil/test/provisioners/gceProvisionerTest.py +0 -6
- toil/test/provisioners/restartScript.py +3 -2
- toil/test/server/serverTest.py +1 -1
- toil/test/sort/restart_sort.py +2 -1
- toil/test/sort/sort.py +2 -1
- toil/test/sort/sortTest.py +2 -13
- toil/test/src/autoDeploymentTest.py +45 -45
- toil/test/src/busTest.py +5 -5
- toil/test/src/checkpointTest.py +2 -2
- toil/test/src/deferredFunctionTest.py +1 -1
- toil/test/src/fileStoreTest.py +32 -16
- toil/test/src/helloWorldTest.py +1 -1
- toil/test/src/importExportFileTest.py +1 -1
- toil/test/src/jobDescriptionTest.py +2 -1
- toil/test/src/jobServiceTest.py +1 -1
- toil/test/src/jobTest.py +18 -18
- toil/test/src/miscTests.py +5 -3
- toil/test/src/promisedRequirementTest.py +3 -3
- toil/test/src/realtimeLoggerTest.py +1 -1
- toil/test/src/resourceTest.py +2 -2
- toil/test/src/restartDAGTest.py +1 -1
- toil/test/src/resumabilityTest.py +36 -2
- toil/test/src/retainTempDirTest.py +1 -1
- toil/test/src/systemTest.py +2 -2
- toil/test/src/toilContextManagerTest.py +2 -2
- toil/test/src/userDefinedJobArgTypeTest.py +1 -1
- toil/test/utils/toilDebugTest.py +98 -32
- toil/test/utils/toilKillTest.py +2 -2
- toil/test/utils/utilsTest.py +20 -0
- toil/test/wdl/wdltoil_test.py +148 -45
- toil/toilState.py +7 -6
- toil/utils/toilClean.py +1 -1
- toil/utils/toilConfig.py +36 -0
- toil/utils/toilDebugFile.py +60 -33
- toil/utils/toilDebugJob.py +39 -12
- toil/utils/toilDestroyCluster.py +1 -1
- toil/utils/toilKill.py +1 -1
- toil/utils/toilLaunchCluster.py +13 -2
- toil/utils/toilMain.py +3 -2
- toil/utils/toilRsyncCluster.py +1 -1
- toil/utils/toilSshCluster.py +1 -1
- toil/utils/toilStats.py +240 -143
- toil/utils/toilStatus.py +1 -4
- toil/version.py +11 -11
- toil/wdl/utils.py +2 -122
- toil/wdl/wdltoil.py +999 -386
- toil/worker.py +25 -31
- {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/METADATA +60 -53
- toil-6.1.0a1.dist-info/RECORD +237 -0
- {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/WHEEL +1 -1
- {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/entry_points.txt +0 -1
- toil/batchSystems/parasol.py +0 -379
- toil/batchSystems/tes.py +0 -459
- toil/test/batchSystems/parasolTestSupport.py +0 -117
- toil/test/wdl/builtinTest.py +0 -506
- toil/test/wdl/conftest.py +0 -23
- toil/test/wdl/toilwdlTest.py +0 -522
- toil/wdl/toilwdl.py +0 -141
- toil/wdl/versions/dev.py +0 -107
- toil/wdl/versions/draft2.py +0 -980
- toil/wdl/versions/v1.py +0 -794
- toil/wdl/wdl_analysis.py +0 -116
- toil/wdl/wdl_functions.py +0 -997
- toil/wdl/wdl_synthesis.py +0 -1011
- toil/wdl/wdl_types.py +0 -243
- toil-5.12.0.dist-info/RECORD +0 -244
- /toil/{wdl/versions → options}/__init__.py +0 -0
- {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/LICENSE +0 -0
- {toil-5.12.0.dist-info → toil-6.1.0a1.dist-info}/top_level.txt +0 -0
toil/test/docs/scriptsTest.py
CHANGED
|
@@ -18,7 +18,6 @@ import logging
|
|
|
18
18
|
import os
|
|
19
19
|
import shutil
|
|
20
20
|
import socketserver
|
|
21
|
-
import tempfile
|
|
22
21
|
import threading
|
|
23
22
|
import time
|
|
24
23
|
import urllib.parse as urlparse
|
|
@@ -27,6 +26,7 @@ from abc import ABCMeta, abstractmethod
|
|
|
27
26
|
from io import BytesIO
|
|
28
27
|
from itertools import chain, islice
|
|
29
28
|
from queue import Queue
|
|
29
|
+
from tempfile import mkstemp
|
|
30
30
|
from threading import Thread
|
|
31
31
|
from typing import Any, Tuple
|
|
32
32
|
from urllib.request import Request, urlopen
|
|
@@ -41,6 +41,7 @@ from toil.jobStores.abstractJobStore import (NoSuchFileException,
|
|
|
41
41
|
NoSuchJobException)
|
|
42
42
|
from toil.jobStores.fileJobStore import FileJobStore
|
|
43
43
|
from toil.lib.aws.utils import create_s3_bucket, get_object_for_url
|
|
44
|
+
from toil.lib.io import mkdtemp
|
|
44
45
|
from toil.lib.memoize import memoize
|
|
45
46
|
from toil.lib.retry import retry
|
|
46
47
|
from toil.statsAndLogging import StatsAndLogging
|
|
@@ -101,7 +102,8 @@ class AbstractJobStoreTest:
|
|
|
101
102
|
return super().__new__(cls)
|
|
102
103
|
|
|
103
104
|
def _createConfig(self):
|
|
104
|
-
|
|
105
|
+
config = Config()
|
|
106
|
+
return config
|
|
105
107
|
|
|
106
108
|
@abstractmethod
|
|
107
109
|
def _createJobStore(self):
|
|
@@ -224,11 +226,14 @@ class AbstractJobStoreTest:
|
|
|
224
226
|
|
|
225
227
|
def testPersistantFilesToDelete(self):
|
|
226
228
|
"""
|
|
227
|
-
Make sure that updating a job
|
|
228
|
-
|
|
229
|
-
The following demonstrates the job update pattern, where files to
|
|
230
|
-
|
|
231
|
-
|
|
229
|
+
Make sure that updating a job persists filesToDelete.
|
|
230
|
+
|
|
231
|
+
The following demonstrates the job update pattern, where files to
|
|
232
|
+
be deleted atomically with a job update are referenced in
|
|
233
|
+
"filesToDelete" array, which is persisted to disk first. If things
|
|
234
|
+
go wrong during the update, this list of files to delete is used to
|
|
235
|
+
ensure that the updated job and the files are never both visible at
|
|
236
|
+
the same time.
|
|
232
237
|
"""
|
|
233
238
|
|
|
234
239
|
# Create a job.
|
|
@@ -439,7 +444,7 @@ class AbstractJobStoreTest:
|
|
|
439
444
|
self.assertEqual(f.read(), one)
|
|
440
445
|
|
|
441
446
|
# ... and copy it to a temporary physical file on the jobstore1.
|
|
442
|
-
fh, path =
|
|
447
|
+
fh, path = mkstemp()
|
|
443
448
|
try:
|
|
444
449
|
os.close(fh)
|
|
445
450
|
tmpPath = path + '.read-only'
|
|
@@ -854,7 +859,7 @@ class AbstractJobStoreTest:
|
|
|
854
859
|
|
|
855
860
|
# Multi-part upload from file
|
|
856
861
|
checksum = hashlib.md5()
|
|
857
|
-
fh, path =
|
|
862
|
+
fh, path = mkstemp()
|
|
858
863
|
try:
|
|
859
864
|
with os.fdopen(fh, 'wb+') as writable:
|
|
860
865
|
with open('/dev/urandom', 'rb') as readable:
|
|
@@ -1042,7 +1047,7 @@ class AbstractJobStoreTest:
|
|
|
1042
1047
|
def testEmptyFileStoreIDIsReadable(self):
|
|
1043
1048
|
"""Simply creates an empty fileStoreID and attempts to read from it."""
|
|
1044
1049
|
id = self.jobstore_initialized.get_empty_file_store_id()
|
|
1045
|
-
fh, path =
|
|
1050
|
+
fh, path = mkstemp()
|
|
1046
1051
|
try:
|
|
1047
1052
|
self.jobstore_initialized.read_file(id, path)
|
|
1048
1053
|
self.assertTrue(os.path.isfile(path))
|
|
@@ -1071,7 +1076,7 @@ class AbstractEncryptedJobStoreTest:
|
|
|
1071
1076
|
|
|
1072
1077
|
def setUp(self):
|
|
1073
1078
|
# noinspection PyAttributeOutsideInit
|
|
1074
|
-
self.sseKeyDir =
|
|
1079
|
+
self.sseKeyDir = mkdtemp()
|
|
1075
1080
|
super().setUp()
|
|
1076
1081
|
|
|
1077
1082
|
def tearDown(self):
|
|
@@ -1139,14 +1144,14 @@ class FileJobStoreTest(AbstractJobStoreTest.Test):
|
|
|
1139
1144
|
return hashlib.md5(f.read()).hexdigest()
|
|
1140
1145
|
|
|
1141
1146
|
def _createExternalStore(self):
|
|
1142
|
-
return
|
|
1147
|
+
return mkdtemp()
|
|
1143
1148
|
|
|
1144
1149
|
def _cleanUpExternalStore(self, dirPath):
|
|
1145
|
-
shutil.rmtree(dirPath)
|
|
1150
|
+
shutil.rmtree(dirPath, ignore_errors=True)
|
|
1146
1151
|
|
|
1147
1152
|
def testPreserveFileName(self):
|
|
1148
1153
|
"""Check that the fileID ends with the given file name."""
|
|
1149
|
-
fh, path =
|
|
1154
|
+
fh, path = mkstemp()
|
|
1150
1155
|
try:
|
|
1151
1156
|
os.close(fh)
|
|
1152
1157
|
job = self.arbitraryJob()
|
|
@@ -1458,6 +1463,7 @@ class AWSJobStoreTest(AbstractJobStoreTest.Test):
|
|
|
1458
1463
|
|
|
1459
1464
|
def _hashTestFile(self, url: str) -> str:
|
|
1460
1465
|
from toil.jobStores.aws.jobStore import AWSJobStore
|
|
1466
|
+
str(AWSJobStore) # to prevent removal of that import
|
|
1461
1467
|
key = get_object_for_url(urlparse.urlparse(url), existing=True)
|
|
1462
1468
|
contents = key.get().get('Body').read()
|
|
1463
1469
|
return hashlib.md5(contents).hexdigest()
|
|
@@ -1480,8 +1486,13 @@ class AWSJobStoreTest(AbstractJobStoreTest.Test):
|
|
|
1480
1486
|
return bucket
|
|
1481
1487
|
|
|
1482
1488
|
def _cleanUpExternalStore(self, bucket):
|
|
1483
|
-
|
|
1484
|
-
|
|
1489
|
+
from toil.jobStores.aws.jobStore import establish_boto3_session
|
|
1490
|
+
from toil.lib.aws.utils import delete_s3_bucket
|
|
1491
|
+
|
|
1492
|
+
resource = establish_boto3_session().resource(
|
|
1493
|
+
"s3", region_name=self.awsRegion()
|
|
1494
|
+
)
|
|
1495
|
+
delete_s3_bucket(resource, bucket.name)
|
|
1485
1496
|
|
|
1486
1497
|
def _largeLogEntrySize(self):
|
|
1487
1498
|
from toil.jobStores.aws.jobStore import AWSJobStore
|
toil/test/lib/aws/test_iam.py
CHANGED
|
@@ -11,25 +11,15 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
import json
|
|
14
15
|
import logging
|
|
15
|
-
import os
|
|
16
|
-
import uuid
|
|
17
|
-
from typing import Optional
|
|
18
|
-
|
|
19
|
-
import pytest
|
|
20
|
-
|
|
21
|
-
from toil.jobStores.aws.jobStore import AWSJobStore
|
|
22
|
-
from toil.lib.aws import iam
|
|
23
|
-
from toil.lib.aws.utils import create_s3_bucket
|
|
24
|
-
from toil.lib.ec2 import establish_boto3_session
|
|
25
|
-
from toil.test import ToilTest, needs_aws_s3
|
|
26
16
|
|
|
27
|
-
import moto
|
|
28
17
|
import boto3
|
|
29
|
-
import json
|
|
30
|
-
|
|
31
18
|
from moto import mock_iam
|
|
32
19
|
|
|
20
|
+
from toil.lib.aws import iam
|
|
21
|
+
from toil.test import ToilTest
|
|
22
|
+
|
|
33
23
|
logger = logging.getLogger(__name__)
|
|
34
24
|
logging.basicConfig(level=logging.DEBUG)
|
|
35
25
|
|
toil/test/lib/aws/test_utils.py
CHANGED
toil/test/lib/dockerTest.py
CHANGED
|
@@ -20,8 +20,8 @@ from threading import Thread
|
|
|
20
20
|
|
|
21
21
|
from docker.errors import ContainerError
|
|
22
22
|
from toil.common import Toil
|
|
23
|
-
from toil.job import Job
|
|
24
23
|
from toil.exceptions import FailedJobsException
|
|
24
|
+
from toil.job import Job
|
|
25
25
|
from toil.lib.docker import (FORGO,
|
|
26
26
|
RM,
|
|
27
27
|
STOP,
|
|
@@ -248,12 +248,12 @@ class DockerTest(ToilTest):
|
|
|
248
248
|
deferParam=None)
|
|
249
249
|
|
|
250
250
|
def testDockerPipeChain(self, caching=False):
|
|
251
|
-
"""
|
|
251
|
+
r"""
|
|
252
252
|
Test for piping API for dockerCall(). Using this API (activated when
|
|
253
253
|
list of argument lists is given as parameters), commands a piped
|
|
254
254
|
together into a chain.
|
|
255
|
-
ex: parameters=[ ['printf', 'x\n y\n'], ['wc', '-l'] ] should execute:
|
|
256
|
-
printf 'x\n y\n' | wc -l
|
|
255
|
+
ex: ``parameters=[ ['printf', 'x\n y\n'], ['wc', '-l'] ]`` should execute:
|
|
256
|
+
``printf 'x\n y\n' | wc -l``
|
|
257
257
|
"""
|
|
258
258
|
options = Job.Runner.getDefaultOptions(os.path.join(self.tempDir, 'jobstore'))
|
|
259
259
|
options.logLevel = self.dockerTestLogLevel
|
toil/test/lib/test_ec2.py
CHANGED
|
@@ -13,26 +13,30 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
import logging
|
|
15
15
|
import os
|
|
16
|
+
|
|
16
17
|
import pytest
|
|
17
18
|
|
|
18
19
|
from toil.lib.aws.ami import (aws_marketplace_flatcar_ami_search,
|
|
19
|
-
get_flatcar_ami,
|
|
20
20
|
feed_flatcar_ami_release,
|
|
21
|
-
flatcar_release_feed_amis
|
|
21
|
+
flatcar_release_feed_amis,
|
|
22
|
+
get_flatcar_ami)
|
|
22
23
|
from toil.lib.aws.session import establish_boto3_session
|
|
23
|
-
from toil.test import ToilTest, needs_aws_ec2
|
|
24
|
+
from toil.test import ToilTest, needs_aws_ec2, needs_online
|
|
24
25
|
|
|
25
26
|
logger = logging.getLogger(__name__)
|
|
26
27
|
logging.basicConfig(level=logging.DEBUG)
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
@needs_online
|
|
29
30
|
class FlatcarFeedTest(ToilTest):
|
|
30
|
-
"""Test accessing the
|
|
31
|
-
|
|
31
|
+
"""Test accessing the Flatcar AMI release feed, independent of the AWS API"""
|
|
32
|
+
|
|
33
|
+
# Note that we need to support getting an empty list back, because
|
|
34
|
+
# sometimes the Flatcar feeds are just down, and we can't fail CI at those
|
|
35
|
+
# times.
|
|
36
|
+
|
|
32
37
|
def test_parse_archive_feed(self):
|
|
33
38
|
"""Make sure we can get a Flatcar release from the Internet Archive."""
|
|
34
39
|
amis = list(flatcar_release_feed_amis('us-west-2', 'amd64', 'archive'))
|
|
35
|
-
self.assertTrue(len(amis) > 0)
|
|
36
40
|
for ami in amis:
|
|
37
41
|
self.assertEqual(len(ami), len('ami-02b46c73fed689d1c'))
|
|
38
42
|
self.assertTrue(ami.startswith('ami-'))
|
|
@@ -40,26 +44,17 @@ class FlatcarFeedTest(ToilTest):
|
|
|
40
44
|
def test_parse_beta_feed(self):
|
|
41
45
|
"""Make sure we can get a Flatcar release from the beta channel."""
|
|
42
46
|
amis = list(flatcar_release_feed_amis('us-west-2', 'amd64', 'beta'))
|
|
43
|
-
self.assertTrue(len(amis) > 0)
|
|
44
47
|
for ami in amis:
|
|
45
48
|
self.assertEqual(len(ami), len('ami-02b46c73fed689d1c'))
|
|
46
49
|
self.assertTrue(ami.startswith('ami-'))
|
|
47
50
|
|
|
48
|
-
# TODO: This will fail until https://github.com/flatcar/Flatcar/issues/962 is fixed
|
|
49
|
-
@pytest.mark.xfail
|
|
50
51
|
def test_parse_stable_feed(self):
|
|
51
52
|
"""Make sure we can get a Flatcar release from the stable channel."""
|
|
52
53
|
amis = list(flatcar_release_feed_amis('us-west-2', 'amd64', 'stable'))
|
|
53
|
-
self.assertTrue(len(amis) > 0)
|
|
54
54
|
for ami in amis:
|
|
55
55
|
self.assertEqual(len(ami), len('ami-02b46c73fed689d1c'))
|
|
56
56
|
self.assertTrue(ami.startswith('ami-'))
|
|
57
57
|
|
|
58
|
-
def test_bypass_stable_feed(self):
|
|
59
|
-
"""Make sure we can either get or safely not get a Flatcar release from the stable channel."""
|
|
60
|
-
list(flatcar_release_feed_amis('us-west-2', 'amd64', 'stable'))
|
|
61
|
-
# Ifd we get here we safely managed to iterate everything.
|
|
62
|
-
|
|
63
58
|
@needs_aws_ec2
|
|
64
59
|
class AMITest(ToilTest):
|
|
65
60
|
@classmethod
|
toil/test/mesos/helloWorld.py
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
A simple user script for Toil
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
import
|
|
18
|
+
from configargparse import ArgumentParser
|
|
19
19
|
|
|
20
20
|
from toil.common import Toil
|
|
21
21
|
from toil.job import Job
|
|
@@ -25,14 +25,13 @@ parentMessage = "The parent job is now running!"
|
|
|
25
25
|
|
|
26
26
|
def hello_world(job):
|
|
27
27
|
|
|
28
|
-
job.fileStore.
|
|
28
|
+
job.fileStore.log_to_leader(parentMessage)
|
|
29
29
|
with open('foo_bam.txt', 'w') as handle:
|
|
30
30
|
handle.write('\nThis is a triumph...\n')
|
|
31
31
|
|
|
32
32
|
# Assign FileStoreID to a given file
|
|
33
33
|
foo_bam = job.fileStore.writeGlobalFile('foo_bam.txt')
|
|
34
34
|
|
|
35
|
-
|
|
36
35
|
# Spawn child
|
|
37
36
|
job.addChildJobFn(hello_world_child, foo_bam, memory=100, cores=0.5, disk="3G")
|
|
38
37
|
|
|
@@ -40,7 +39,7 @@ def hello_world(job):
|
|
|
40
39
|
def hello_world_child(job, hw):
|
|
41
40
|
|
|
42
41
|
path = job.fileStore.readGlobalFile(hw)
|
|
43
|
-
job.fileStore.
|
|
42
|
+
job.fileStore.log_to_leader(childMessage)
|
|
44
43
|
# NOTE: path and the udpated file are stored to /tmp
|
|
45
44
|
# If we want to SAVE our changes to this tmp file, we must write it out.
|
|
46
45
|
with open(path) as r:
|
|
@@ -56,7 +55,7 @@ def hello_world_child(job, hw):
|
|
|
56
55
|
def main():
|
|
57
56
|
# Boilerplate -- startToil requires options
|
|
58
57
|
|
|
59
|
-
parser =
|
|
58
|
+
parser = ArgumentParser()
|
|
60
59
|
Job.Runner.addToilOptions(parser)
|
|
61
60
|
options = parser.parse_args()
|
|
62
61
|
|
toil/test/mesos/stress.py
CHANGED
|
@@ -29,6 +29,7 @@ from toil.test import (ToilTest,
|
|
|
29
29
|
integrative,
|
|
30
30
|
needs_aws_ec2,
|
|
31
31
|
needs_fetchable_appliance,
|
|
32
|
+
needs_mesos,
|
|
32
33
|
slow,
|
|
33
34
|
timeLimit)
|
|
34
35
|
from toil.test.provisioners.clusterTest import AbstractClusterTest
|
|
@@ -171,9 +172,6 @@ class AbstractAWSAutoscaleTest(AbstractClusterTest):
|
|
|
171
172
|
venv_command = ['virtualenv', '--system-site-packages', '--python', exactPython, '--never-download', self.venvDir]
|
|
172
173
|
self.sshUtil(venv_command)
|
|
173
174
|
|
|
174
|
-
upgrade_command = [self.pip(), 'install', 'setuptools==28.7.1', 'pyyaml==3.12']
|
|
175
|
-
self.sshUtil(upgrade_command)
|
|
176
|
-
|
|
177
175
|
log.info('Set up script...')
|
|
178
176
|
self._getScript()
|
|
179
177
|
|
|
@@ -214,6 +212,7 @@ class AbstractAWSAutoscaleTest(AbstractClusterTest):
|
|
|
214
212
|
|
|
215
213
|
|
|
216
214
|
@integrative
|
|
215
|
+
@needs_mesos
|
|
217
216
|
@pytest.mark.timeout(1800)
|
|
218
217
|
class AWSAutoscaleTest(AbstractAWSAutoscaleTest):
|
|
219
218
|
def __init__(self, name):
|
|
@@ -282,6 +281,7 @@ class AWSAutoscaleTest(AbstractAWSAutoscaleTest):
|
|
|
282
281
|
|
|
283
282
|
|
|
284
283
|
@integrative
|
|
284
|
+
@needs_mesos
|
|
285
285
|
@pytest.mark.timeout(2400)
|
|
286
286
|
class AWSStaticAutoscaleTest(AWSAutoscaleTest):
|
|
287
287
|
"""Runs the tests on a statically provisioned cluster with autoscaling enabled."""
|
|
@@ -357,6 +357,7 @@ class AWSManagedAutoscaleTest(AWSAutoscaleTest):
|
|
|
357
357
|
|
|
358
358
|
|
|
359
359
|
@integrative
|
|
360
|
+
@needs_mesos
|
|
360
361
|
@pytest.mark.timeout(1200)
|
|
361
362
|
class AWSAutoscaleTestMultipleNodeTypes(AbstractAWSAutoscaleTest):
|
|
362
363
|
def __init__(self, name):
|
|
@@ -396,6 +397,7 @@ class AWSAutoscaleTestMultipleNodeTypes(AbstractAWSAutoscaleTest):
|
|
|
396
397
|
|
|
397
398
|
|
|
398
399
|
@integrative
|
|
400
|
+
@needs_mesos
|
|
399
401
|
@pytest.mark.timeout(1200)
|
|
400
402
|
class AWSRestartTest(AbstractAWSAutoscaleTest):
|
|
401
403
|
"""This test insures autoscaling works on a restarted Toil run."""
|
|
@@ -412,9 +414,10 @@ class AWSRestartTest(AbstractAWSAutoscaleTest):
|
|
|
412
414
|
|
|
413
415
|
def _getScript(self):
|
|
414
416
|
def restartScript():
|
|
415
|
-
import argparse
|
|
416
417
|
import os
|
|
417
418
|
|
|
419
|
+
from configargparse import ArgumentParser
|
|
420
|
+
|
|
418
421
|
from toil.job import Job
|
|
419
422
|
|
|
420
423
|
def f0(job):
|
|
@@ -422,7 +425,7 @@ class AWSRestartTest(AbstractAWSAutoscaleTest):
|
|
|
422
425
|
raise RuntimeError('failed on purpose')
|
|
423
426
|
|
|
424
427
|
if __name__ == '__main__':
|
|
425
|
-
parser =
|
|
428
|
+
parser = ArgumentParser()
|
|
426
429
|
Job.Runner.addToilOptions(parser)
|
|
427
430
|
options = parser.parse_args()
|
|
428
431
|
rootJob = Job.wrapJobFn(f0, cores=0.5, memory='50 M', disk='50 M')
|
|
@@ -458,6 +461,7 @@ class AWSRestartTest(AbstractAWSAutoscaleTest):
|
|
|
458
461
|
|
|
459
462
|
|
|
460
463
|
@integrative
|
|
464
|
+
@needs_mesos
|
|
461
465
|
@pytest.mark.timeout(1200)
|
|
462
466
|
class PreemptibleDeficitCompensationTest(AbstractAWSAutoscaleTest):
|
|
463
467
|
def __init__(self, name):
|
|
@@ -19,16 +19,16 @@ import time
|
|
|
19
19
|
import uuid
|
|
20
20
|
from argparse import Namespace
|
|
21
21
|
from collections import defaultdict
|
|
22
|
-
from contextlib import contextmanager
|
|
23
22
|
from queue import Empty, Queue
|
|
24
23
|
from threading import Event, Thread
|
|
25
|
-
from typing import
|
|
24
|
+
from typing import List, Optional, Set, Tuple
|
|
26
25
|
from unittest.mock import MagicMock
|
|
27
26
|
|
|
28
27
|
from toil.batchSystems.abstractBatchSystem import (AbstractBatchSystem,
|
|
29
28
|
AbstractScalableBatchSystem,
|
|
30
29
|
NodeInfo)
|
|
31
|
-
from toil.common import Config
|
|
30
|
+
from toil.common import Config
|
|
31
|
+
from toil.options.common import defaultTargetTime
|
|
32
32
|
from toil.job import JobDescription
|
|
33
33
|
from toil.lib.conversions import human2bytes as h2b
|
|
34
34
|
from toil.provisioners.abstractProvisioner import AbstractProvisioner, Shape
|
|
@@ -873,7 +873,9 @@ class MockBatchSystemAndProvisioner(AbstractScalableBatchSystem, AbstractProvisi
|
|
|
873
873
|
return self.jobQueue.qsize()
|
|
874
874
|
|
|
875
875
|
def getJobs(self):
|
|
876
|
-
|
|
876
|
+
# jobBatchSystemIDToIssuedJob may be modified while we are working.
|
|
877
|
+
# So copy it.
|
|
878
|
+
return dict(self.jobBatchSystemIDToIssuedJob).values()
|
|
877
879
|
|
|
878
880
|
# AbstractScalableBatchSystem functionality
|
|
879
881
|
def getNodes(self, preemptible: Optional[bool] = False, timeout: int = 600):
|
|
@@ -18,8 +18,6 @@ import subprocess
|
|
|
18
18
|
import time
|
|
19
19
|
from uuid import uuid4
|
|
20
20
|
|
|
21
|
-
import boto.ec2
|
|
22
|
-
|
|
23
21
|
from toil.lib.aws import zone_to_region
|
|
24
22
|
from toil.lib.retry import retry
|
|
25
23
|
from toil.provisioners.aws import get_best_aws_zone
|
|
@@ -38,7 +36,9 @@ class AbstractClusterTest(ToilTest):
|
|
|
38
36
|
self.clusterType = 'mesos'
|
|
39
37
|
self.zone = get_best_aws_zone()
|
|
40
38
|
assert self.zone is not None, "Could not determine AWS availability zone to test in; is TOIL_AWS_ZONE set?"
|
|
41
|
-
# We need a boto2 connection to EC2 to check on the cluster
|
|
39
|
+
# We need a boto2 connection to EC2 to check on the cluster.
|
|
40
|
+
# Since we are protected by needs_aws_ec2 we can import from boto.
|
|
41
|
+
import boto.ec2
|
|
42
42
|
self.boto2_ec2 = boto.ec2.connect_to_region(zone_to_region(self.zone))
|
|
43
43
|
# Where should we put our virtualenv?
|
|
44
44
|
self.venvDir = '/tmp/venv'
|
|
@@ -143,6 +143,17 @@ class AbstractClusterTest(ToilTest):
|
|
|
143
143
|
log.error("Failed to run %s.", str(cmd))
|
|
144
144
|
raise subprocess.CalledProcessError(p.returncode, ' '.join(cmd))
|
|
145
145
|
|
|
146
|
+
@retry(errors=[subprocess.CalledProcessError], intervals=[1, 1])
|
|
147
|
+
def rsync_util(self, from_file: str, to_file: str) -> None:
|
|
148
|
+
"""
|
|
149
|
+
Transfer a file to/from the cluster.
|
|
150
|
+
|
|
151
|
+
The cluster-side path should have a ':' in front of it.
|
|
152
|
+
"""
|
|
153
|
+
cmd = ['toil', 'rsync-cluster', '--insecure', '-p=aws', '-z', self.zone, self.clusterName, from_file, to_file]
|
|
154
|
+
log.info("Running %s.", str(cmd))
|
|
155
|
+
subprocess.check_call(cmd)
|
|
156
|
+
|
|
146
157
|
@retry(errors=[subprocess.CalledProcessError], intervals=[1, 1])
|
|
147
158
|
def createClusterUtil(self, args=None):
|
|
148
159
|
args = [] if args is None else args
|
|
@@ -136,12 +136,6 @@ class AbstractGCEAutoscaleTest(ToilTest):
|
|
|
136
136
|
'--python', exactPython, '/home/venv']
|
|
137
137
|
self.sshUtil(venv_command)
|
|
138
138
|
|
|
139
|
-
upgrade_command = ['/home/venv/bin/pip', 'install', 'setuptools==28.7.1']
|
|
140
|
-
self.sshUtil(upgrade_command)
|
|
141
|
-
|
|
142
|
-
yaml_command = ['/home/venv/bin/pip', 'install', 'pyyaml==3.12']
|
|
143
|
-
self.sshUtil(yaml_command)
|
|
144
|
-
|
|
145
139
|
self._getScript()
|
|
146
140
|
|
|
147
141
|
toilOptions = [self.jobStore,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import argparse
|
|
2
1
|
import os
|
|
3
2
|
|
|
3
|
+
from configargparse import ArgumentParser
|
|
4
|
+
|
|
4
5
|
from toil.job import Job
|
|
5
6
|
|
|
6
7
|
|
|
@@ -9,7 +10,7 @@ def f0(job):
|
|
|
9
10
|
raise RuntimeError('failed on purpose')
|
|
10
11
|
|
|
11
12
|
if __name__ == '__main__':
|
|
12
|
-
parser =
|
|
13
|
+
parser = ArgumentParser()
|
|
13
14
|
Job.Runner.addToilOptions(parser)
|
|
14
15
|
options = parser.parse_args()
|
|
15
16
|
rootJob = Job.wrapJobFn(f0, cores=0.5, memory='50 M', disk='50 M')
|
toil/test/server/serverTest.py
CHANGED
toil/test/sort/restart_sort.py
CHANGED
toil/test/sort/sort.py
CHANGED
toil/test/sort/sortTest.py
CHANGED
|
@@ -23,10 +23,10 @@ from uuid import uuid4
|
|
|
23
23
|
from toil import resolveEntryPoint
|
|
24
24
|
from toil.batchSystems.mesos.test import MesosTestSupport
|
|
25
25
|
from toil.common import Toil
|
|
26
|
+
from toil.exceptions import FailedJobsException
|
|
26
27
|
from toil.job import Job
|
|
27
28
|
from toil.jobStores.abstractJobStore import (JobStoreExistsException,
|
|
28
29
|
NoSuchJobStoreException)
|
|
29
|
-
from toil.exceptions import FailedJobsException
|
|
30
30
|
from toil.lib.bioio import root_logger
|
|
31
31
|
from toil.test import (ToilTest,
|
|
32
32
|
needs_aws_ec2,
|
|
@@ -34,10 +34,8 @@ from toil.test import (ToilTest,
|
|
|
34
34
|
needs_google_storage,
|
|
35
35
|
needs_gridengine,
|
|
36
36
|
needs_mesos,
|
|
37
|
-
needs_parasol,
|
|
38
37
|
needs_torque,
|
|
39
38
|
slow)
|
|
40
|
-
from toil.test.batchSystems.parasolTestSupport import ParasolTestSupport
|
|
41
39
|
from toil.test.sort.sort import (copySubRangeOfFile,
|
|
42
40
|
getMidPoint,
|
|
43
41
|
main,
|
|
@@ -64,7 +62,7 @@ def runMain(options):
|
|
|
64
62
|
|
|
65
63
|
|
|
66
64
|
@slow
|
|
67
|
-
class SortTest(ToilTest, MesosTestSupport
|
|
65
|
+
class SortTest(ToilTest, MesosTestSupport):
|
|
68
66
|
"""
|
|
69
67
|
Tests Toil by sorting a file in parallel on various combinations of job stores and batch
|
|
70
68
|
systems.
|
|
@@ -238,15 +236,6 @@ class SortTest(ToilTest, MesosTestSupport, ParasolTestSupport):
|
|
|
238
236
|
def testFileTorqueEngine(self):
|
|
239
237
|
self._toilSort(jobStoreLocator=self._getTestJobStorePath(), batchSystem='torque')
|
|
240
238
|
|
|
241
|
-
@needs_parasol
|
|
242
|
-
@unittest.skip("skipping until parasol support is less flaky (see github issue #449")
|
|
243
|
-
def testFileParasol(self):
|
|
244
|
-
self._startParasol()
|
|
245
|
-
try:
|
|
246
|
-
self._toilSort(jobStoreLocator=self._getTestJobStorePath(), batchSystem='parasol')
|
|
247
|
-
finally:
|
|
248
|
-
self._stopParasol()
|
|
249
|
-
|
|
250
239
|
testNo = 5
|
|
251
240
|
|
|
252
241
|
def testSort(self):
|