Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
b0b1752
New aws jobstore.
DailyDreaming Oct 14, 2024
7dc1a7c
Update.
DailyDreaming Jan 24, 2025
06b7a40
Updates.
DailyDreaming Feb 3, 2025
4c12449
Linting.
DailyDreaming Mar 3, 2025
2900c99
Update.
DailyDreaming Mar 25, 2025
3a345dd
Update from master.
DailyDreaming Mar 25, 2025
9322285
Update.
DailyDreaming Mar 25, 2025
031bab4
Update and rebase.
DailyDreaming Mar 25, 2025
c58e025
Update and rebase.
DailyDreaming Mar 25, 2025
698b450
Assuage make docs's anger.
DailyDreaming Mar 25, 2025
b9f3cc8
Rebase.
DailyDreaming Mar 25, 2025
321a2c6
Some compat, some review comments.
DailyDreaming Mar 26, 2025
faf0581
Move boto imports.
DailyDreaming Mar 26, 2025
a9a8880
Update.
DailyDreaming Mar 27, 2025
082311d
Update comments, move imports, and update docstrings.
DailyDreaming Mar 31, 2025
0608622
Update imports.
DailyDreaming Apr 1, 2025
687b9b7
Merge branch 'master' into issues/964-aws-remove-sdb
DailyDreaming Apr 1, 2025
133fc26
Merge remote-tracking branch 'upstream/master' into issues/964-aws-re…
adamnovak Jul 24, 2025
0b2316b
Fix typing
adamnovak Jul 24, 2025
d778e1e
Enable type checking and fix utils typing
adamnovak Jul 24, 2025
aaf6085
Address code review comments, drop comments in docstrings, drop dupli…
adamnovak Jul 24, 2025
b99e462
Reformat and revise docs so docs build works
adamnovak Jul 24, 2025
56faabd
Merge remote-tracking branch 'upstream/master' into issues/964-aws-re…
adamnovak Jul 24, 2025
859dd2d
Quote possibly-unavailable types
adamnovak Jul 24, 2025
4631950
Make missing AWS modules produce ImportError and not NotImplementedError
adamnovak Jul 25, 2025
1f75eac
Stop trying to import the boto 2 error types
adamnovak Jul 25, 2025
3a643b7
Use the key function everywhere and deal with not having a log place …
adamnovak Jul 25, 2025
9e912b2
Add missing pre_update_hook call
adamnovak Jul 25, 2025
654d8e7
Stop logging every write
adamnovak Jul 25, 2025
cc0f8c4
Only write the marker when it moves
adamnovak Jul 25, 2025
7f3c3d2
Use the content key prefix when uploading files
adamnovak Jul 25, 2025
adef28a
Get executable bit from the end of the key fields
adamnovak Jul 25, 2025
1122742
Add --toil suffix to test bucket cleanup script
adamnovak Jul 25, 2025
14d1338
Make FileJobStore _write_to_url a classmethod again
adamnovak Jul 25, 2025
2126540
Stop tracking executability in key because it is tracked in the typed…
adamnovak Jul 25, 2025
3503b01
Merge remote-tracking branch 'upstream/master' into issues/964-aws-re…
adamnovak Jul 25, 2025
5fc4c39
Fix self reference in classmethod
adamnovak Jul 25, 2025
4a1de2e
Add pytest-randomly to report and set seeds only
adamnovak Jul 28, 2025
05c04fc
Fix removed method and enable AWS util test type checking
adamnovak Aug 5, 2025
7a3df6d
Move single-test teardown into test and fix argument type
adamnovak Aug 5, 2025
80aabc9
Fix typing by moving import
adamnovak Aug 5, 2025
47d2518
Merge remote-tracking branch 'upstream/master' into issues/964-aws-re…
adamnovak Aug 6, 2025
7822305
Satisfy MyPy on the pipes
adamnovak Aug 6, 2025
2d6d7ad
Respect turning off encryption for stream uploads so config.pickle ca…
adamnovak Aug 6, 2025
c369df4
Get the config from self
adamnovak Aug 6, 2025
bfc6616
Make AWS encryption settings update live from the config to satisfy test
adamnovak Aug 6, 2025
df02144
Handle error from trying to read without encryption, and default encr…
adamnovak Aug 6, 2025
86a8fe6
Make Bucket from the resource and not free-floating
adamnovak Aug 6, 2025
59b2eec
Satisfy MyPy
adamnovak Aug 6, 2025
278fb2f
Avoid depending on strongly-consistent clean in subTest tests
adamnovak Aug 7, 2025
4f55510
Raise correct nonexistent job store exception
adamnovak Aug 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,6 @@ py313_main:
TOIL_SKIP_DOCKER=true make test threads="${TEST_THREADS}" tests="src/toil/test/lib"
echo -e "\e[0Ksection_end:`date +%s`:test\r\e[0K"


slurm_test:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
Expand Down Expand Up @@ -464,7 +463,7 @@ cwl_badge:
rm -rf badges1.2
echo -e "\e[0Ksection_end:`date +%s`:download_tests\r\e[0K"
echo -e "\e[0Ksection_start:`date +%s`:test\r\e[0KRun the CWL v1.2 conformance tests."
make test tests="src/toil/test/cwl/spec_v12/conformance_tests.cwltest.yaml" threads="${TEST_THREADS}" pytest_args="--cwl-runner-verbose --cwl-badgedir=badges1.2 --junit-xml=in-place-update-conformance-1.2.junit.xml --cwl-args='--relax-path-checks --clean=always --logDebug --statusWait=10 --retryCount=2 --eval-timeout=600 --bypass-file-store'"
make test tests="src/toil/test/cwl/spec_v12/conformance_tests.cwltest.yaml" threads="${TEST_THREADS}" pytest_args="--randomly-dont-reorganize --cwl-runner-verbose --cwl-badgedir=badges1.2 --junit-xml=in-place-update-conformance-1.2.junit.xml --cwl-args='--relax-path-checks --clean=always --logDebug --statusWait=10 --retryCount=2 --eval-timeout=600 --bypass-file-store'"
echo -e "\e[0Ksection_end:`date +%s`:test\r\e[0K"
allow_failure: true
artifacts:
Expand Down Expand Up @@ -497,7 +496,7 @@ cwl_badge_release:
rm -rf badges1.2
echo -e "\e[0Ksection_end:`date +%s`:download_tests\r\e[0K"
echo -e "\e[0Ksection_start:`date +%s`:test\r\e[0KRun the CWL v1.2 conformance tests."
make test tests="src/toil/test/cwl/spec_v12/conformance_tests.cwltest.yaml" threads="${TEST_THREADS}" pytest_args="--cwl-runner-verbose --cwl-badgedir=badges1.2 --junit-xml=in-place-update-conformance-1.2.junit.xml --cwl-args='--relax-path-checks --clean=always --logDebug --statusWait=10 --retryCount=2 --eval-timeout=600 --bypass-file-store'"
make test tests="src/toil/test/cwl/spec_v12/conformance_tests.cwltest.yaml" threads="${TEST_THREADS}" pytest_args="--randomly-dont-reorganize --cwl-runner-verbose --cwl-badgedir=badges1.2 --junit-xml=in-place-update-conformance-1.2.junit.xml --cwl-args='--relax-path-checks --clean=always --logDebug --statusWait=10 --retryCount=2 --eval-timeout=600 --bypass-file-store'"
echo -e "\e[0Ksection_end:`date +%s`:test\r\e[0K"
allow_failure: true
artifacts:
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ marker=""
threads:="auto"

dist:="worksteal"
pytest_args:=""
pytest_args:="--randomly-dont-reorganize"

# Only pass the threading options if running parallel tests. Otherwise we lose
# live logging. See <https://stackoverflow.com/q/62533239>
Expand Down Expand Up @@ -199,7 +199,7 @@ test_offline: check_venv check_build_reqs
test_1min: check_venv check_build_reqs
TOIL_SKIP_DOCKER=False \
TOIL_HISTORY=0 \
python -m pytest $(verbose) $(durations) $(threadopts) -m "$(marker)" $(logging) --timeout=30 --maxfail=1 $(pytest_args) src/toil/test/batchSystems/batchSystemTest.py::SingleMachineBatchSystemTest::test_run_jobs src/toil/test/batchSystems/batchSystemTest.py::KubernetesBatchSystemBenchTest src/toil/test/server/serverTest.py::ToilWESServerBenchTest::test_get_service_info src/toil/test/cwl/cwlTest.py::TestCWLWorkflow::test_run_colon_output src/toil/test/jobStores/jobStoreTest.py::FileJobStoreTest::testUpdateBehavior
python -m pytest $(verbose) $(durations) $(threadopts) -m "$(marker)" $(logging) --timeout=30 --maxfail=1 $(pytest_args) src/toil/test/batchSystems/batchSystemTest.py::SingleMachineBatchSystemTest::test_run_jobs src/toil/test/batchSystems/batchSystemTest.py::KubernetesBatchSystemBenchTest src/toil/test/server/serverTest.py::ToilWESServerBenchTest::test_get_service_info src/toil/test/cwl/cwlTest.py::TestCWLWorkflow::test_run_colon_output src/toil/test/jobStores/jobStoreTest.py::FileJobStoreTest::testUpdateBehavior

ifdef TOIL_DOCKER_REGISTRY

Expand Down
7 changes: 5 additions & 2 deletions contrib/admin/cleanup_aws_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,11 @@ def contains_toil_test_patterns(string):


def matches(resource_name):
if (resource_name.endswith('--files') or resource_name.endswith('--jobs') or resource_name.endswith('_toil')
or resource_name.endswith('--internal') or resource_name.startswith('toil-s3test-')):
if (
resource_name.endswith('--files') or resource_name.endswith('--jobs')
or resource_name.endswith('--toil') or resource_name.endswith('_toil')
or resource_name.endswith('--internal') or resource_name.startswith('toil-s3test-')
):
if contains_toil_test_patterns(resource_name):
return resource_name

Expand Down
8 changes: 2 additions & 6 deletions contrib/admin/mypy-with-ignore.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def main():

# TODO: Remove these paths as typing is added and mypy conflicts are addressed.
# These are handled as path prefixes.
ignore_paths = [os.path.abspath(f) for f in [

ignore_paths = [os.path.join(pkg_root, f) for f in [
'docs/_build',
'docker/Dockerfile.py',
'docs/conf.py',
Expand Down Expand Up @@ -61,12 +62,8 @@ def main():
'src/toil/jobStores/fileJobStore.py',
'src/toil/jobStores/__init__.py',
'src/toil/jobStores/googleJobStore.py',
'src/toil/jobStores/aws/utils.py',
'src/toil/jobStores/aws/jobStore.py',
'src/toil/jobStores/aws/__init__.py',
'src/toil/utils/__init__.py',
'src/toil/lib/throttle.py',
'src/toil/lib/iterables.py',
'src/toil/lib/bioio.py',
'src/toil/lib/ec2.py',
'src/toil/lib/expando.py',
Expand All @@ -87,7 +84,6 @@ def main():
'src/toil/test/cactus',
'src/toil/test/docs',
'src/toil/test/jobStores',
'src/toil/test/lib/aws',
'src/toil/test/lib/test_conversions.py',
'src/toil/test/lib/test_ec2.py',
'src/toil/test/lib/test_misc.py',
Expand Down
1 change: 0 additions & 1 deletion docs/appendices/aws_min_permissions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ with the ``--awsEc2ProfileArn`` parameter.
"Action": [
"ec2:*",
"s3:*",
"sdb:*",
"iam:PassRole"
],
"Resource": "*"
Expand Down
3 changes: 2 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ pytest>=6.2.1,<9
pytest-cov>=2.12.1,<7
pytest-timeout>=1.4.2,<3
pytest_httpserver>=1.1.3,<2
pytest-subtests
pytest-subtests>=0.14.2,<0.15
pytest-randomly>=3.16.0,<4
stubserver>=1.1,<2
setuptools>=65.5.1,<81
sphinx>=7,<9
Expand Down
2 changes: 1 addition & 1 deletion src/toil/fileStores/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class FileID(str):
the job store if unavailable in the ID.
"""

def __new__(cls, fileStoreID: str, *args: Any) -> "FileID":
def __new__(cls, fileStoreID: str, *args: Any, **kwargs: dict[str, Any]) -> "FileID":
return super().__new__(cls, fileStoreID)

def __init__(self, fileStoreID: str, size: int, executable: bool = False) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/toil/fileStores/cachingFileStore.py
Original file line number Diff line number Diff line change
Expand Up @@ -1207,7 +1207,7 @@ def open(self, job: Job) -> Generator[None, None, None]:
# its temp dir and database entry.
self._deallocateSpaceForJob()

def writeGlobalFile(self, localFileName, cleanup=False, executable=False):
def writeGlobalFile(self, localFileName, cleanup=False):
"""
Creates a file in the jobstore and returns a FileID reference.
"""
Expand Down
1 change: 0 additions & 1 deletion src/toil/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,6 @@ class JobDescription(Requirer):
Subclassed into variants for checkpoint jobs and service jobs that have
their specific parameters.
"""

def __init__(
self,
requirements: Mapping[str, Union[int, str, float, bool, list]],
Expand Down
43 changes: 24 additions & 19 deletions src/toil/jobStores/abstractJobStore.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def __init__(self, url: ParseResult) -> None:
class NoSuchJobException(Exception):
"""Indicates that the specified job does not exist."""

def __init__(self, jobStoreID: FileID):
def __init__(self, jobStoreID: Union[FileID, str]):
"""
:param str jobStoreID: the jobStoreID that was mistakenly assumed to exist
"""
Expand All @@ -100,7 +100,7 @@ def __init__(self, jobStoreID: FileID):
class ConcurrentFileModificationException(Exception):
"""Indicates that the file was attempted to be modified by multiple processes at once."""

def __init__(self, jobStoreFileID: FileID):
def __init__(self, jobStoreFileID: Union[FileID, str]):
"""
:param jobStoreFileID: the ID of the file that was modified by multiple workers
or processes concurrently
Expand All @@ -112,7 +112,7 @@ class NoSuchFileException(Exception):
"""Indicates that the specified file does not exist."""

def __init__(
self, jobStoreFileID: FileID, customName: Optional[str] = None, *extra: Any
self, jobStoreFileID: Union[FileID, str], customName: Optional[str] = None, *extra: Any
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a good reason to say this can be a string now? Is it too hard to drag the typed file ID object through in the new implementation for some good reason?

When this is a string, is this meant to be the string-packed version of the file ID? Or just the ID part without e.g. the size packed in?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess some of the user-facing file ID API still accepts file IDs typed as strings, so maybe we do still need to be able to take them here.

):
"""
:param jobStoreFileID: the ID of the file that was mistakenly assumed to exist
Expand Down Expand Up @@ -140,11 +140,12 @@ class NoSuchJobStoreException(LocatorException):
def __init__(self, locator: str, prefix: str):
"""
:param str locator: The location of the job store
:param str prefix: The type of job store
"""
super().__init__(
"The job store '%s' does not exist, so there is nothing to restart.",
locator,
prefix,
prefix
)


Expand All @@ -159,7 +160,7 @@ def __init__(self, locator: str, prefix: str):
"The job store '%s' already exists. Use --restart to resume the workflow, or remove "
"the job store with 'toil clean' to start the workflow from scratch.",
locator,
prefix,
prefix
)


Expand Down Expand Up @@ -240,7 +241,12 @@ def resume(self) -> None:

@property
def config(self) -> Config:
"""Return the Toil configuration associated with this job store."""
"""
Return the Toil configuration associated with this job store.

:raises AttributeError: if the config has not yet been assigned (i.e.
during :meth:`resume`).
"""
return self.__config

@property
Expand Down Expand Up @@ -561,7 +567,6 @@ def _default_export_file(
executable = jobStoreFileID.executable
otherCls._write_to_url(readable, url, executable)


@abstractmethod
def destroy(self) -> None:
"""
Expand Down Expand Up @@ -930,15 +935,6 @@ def assign_job_id(self, job_description: JobDescription) -> None:
"""
raise NotImplementedError()

@contextmanager
def batch(self) -> Iterator[None]:
"""
If supported by the batch system, calls to create() with this context
manager active will be performed in a batch after the context manager
is released.
"""
yield

@deprecated(new_function_name="create_job")
def create(self, jobDescription: JobDescription) -> JobDescription:
return self.create_job(jobDescription)
Expand Down Expand Up @@ -1036,6 +1032,15 @@ def load_job(self, job_id: str) -> JobDescription:
def update(self, jobDescription: JobDescription) -> None:
return self.update_job(jobDescription)

@contextmanager
def batch(self) -> Iterator[None]:
"""
If supported by the batch system, calls to create() with this context
manager active will be performed in a batch after the context manager
is released.
"""
yield

@abstractmethod
def update_job(self, job_description: JobDescription) -> None:
"""
Expand Down Expand Up @@ -1206,14 +1211,14 @@ def get_empty_file_store_id(
Creates an empty file in the job store and returns its ID.
Call to fileExists(getEmptyFileStoreID(jobStoreID)) will return True.

:param str job_id: the id of a job, or None. If specified, the may be associated
:param job_id: the id of a job, or None. If specified, the may be associated
with that job in a job-store-specific way. This may influence the returned ID.

:param bool cleanup: Whether to attempt to delete the file when the job
:param cleanup: Whether to attempt to delete the file when the job
whose jobStoreID was given as jobStoreID is deleted with
jobStore.delete(job). If jobStoreID was not given, does nothing.

:param str basename: If supported by the implementation, use the given
:param basename: If supported by the implementation, use the given
file basename so that when searching the job store with a query
matching that basename, the file will be detected.

Expand Down
Loading
Loading