From b440bfddd79ad38ace0fd2ea376fac6867379448 Mon Sep 17 00:00:00 2001 From: w3lld1 <42353747+w3lld1@users.noreply.github.com> Date: Thu, 13 Aug 2026 11:09:36 +0200 Subject: [PATCH 1/4] Make PID status test deterministic (resolves #5232) --- src/toil/test/utils/utilsTest.py | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/toil/test/utils/utilsTest.py b/src/toil/test/utils/utilsTest.py index 3b79517278..bbcf118cdc 100644 --- a/src/toil/test/utils/utilsTest.py +++ b/src/toil/test/utils/utilsTest.py @@ -48,6 +48,12 @@ logger = logging.getLogger(__name__) +def wait_for_file(file_path: str) -> None: + """Wait until a file exists.""" + while not os.path.exists(file_path): + time.sleep(0.1) + + @pytest.fixture(scope="function") def unsortedFile(tmp_path: Path) -> Generator[Path]: try: @@ -390,19 +396,26 @@ def check_status( current_status == status ), "Waited {seconds} seconds without status reaching {status}; stuck at {current_status}" - def testGetPIDStatus(self, tmp_path: Path, unsortedFile: Path) -> None: + def testGetPIDStatus(self, tmp_path: Path) -> None: """Test that ToilStatus.getPIDStatus() behaves as expected.""" jobstore = tmp_path / "jobstore" - outputFile = tmp_path / "someSortedStuff.txt" + release_file = tmp_path / "release-workflow" + workflow = """ +from toil.job import Job +from toil.test.utils.utilsTest import wait_for_file +import sys + +options = Job.Runner.getDefaultOptions(sys.argv[1]) +options.clean = "never" +Job.Runner.startToil(Job.wrapFn(wait_for_file, sys.argv[2]), options) +""" wf = subprocess.Popen( [ python, - "-m", - "toil.test.sort.sort", - jobstore.as_uri(), - f"--fileToSort={unsortedFile}", - f"--outputFile={outputFile}", - "--clean=never", + "-c", + workflow, + str(jobstore), + str(release_file), ] ) self.check_status( @@ -412,6 +425,7 @@ def testGetPIDStatus(self, tmp_path: Path, unsortedFile: Path) -> None: process=wf, seconds=60, ) + release_file.touch() wf.wait() self.check_status( jobstore, From db4ca981334baf0e2c330f6a9eac25622c2d4ef3 Mon Sep 17 00:00:00 2001 From: Adam Novak Date: Thu, 20 Aug 2026 10:54:55 -0400 Subject: [PATCH 2/4] Move workflow code from string to function --- src/toil/test/utils/utilsTest.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/toil/test/utils/utilsTest.py b/src/toil/test/utils/utilsTest.py index bbcf118cdc..7a8f62d786 100644 --- a/src/toil/test/utils/utilsTest.py +++ b/src/toil/test/utils/utilsTest.py @@ -53,6 +53,12 @@ def wait_for_file(file_path: str) -> None: while not os.path.exists(file_path): time.sleep(0.1) +def wait_for_file_workflow() -> None: + """Toil workflow that waits for the file in argument 2 to exist.""" + options = Job.Runner.getDefaultOptions(sys.argv[1]) + options.clean = "never" + Job.Runner.startToil(Job.wrapFn(wait_for_file, sys.argv[2]), options) + @pytest.fixture(scope="function") def unsortedFile(tmp_path: Path) -> Generator[Path]: @@ -400,24 +406,18 @@ def testGetPIDStatus(self, tmp_path: Path) -> None: """Test that ToilStatus.getPIDStatus() behaves as expected.""" jobstore = tmp_path / "jobstore" release_file = tmp_path / "release-workflow" - workflow = """ -from toil.job import Job -from toil.test.utils.utilsTest import wait_for_file -import sys - -options = Job.Runner.getDefaultOptions(sys.argv[1]) -options.clean = "never" -Job.Runner.startToil(Job.wrapFn(wait_for_file, sys.argv[2]), options) -""" + # Run wait_for_file_workflow() as a child process. wf = subprocess.Popen( [ python, "-c", - workflow, + f"from {__loader__.fullname} import " + f"wait_for_file_workflow as w; w()", str(jobstore), str(release_file), ] ) + # Check the status by PID self.check_status( jobstore, "RUNNING", From 614af3c831693d6de10c4b3b3ce8696518808c31 Mon Sep 17 00:00:00 2001 From: Adam Novak Date: Thu, 20 Aug 2026 11:09:38 -0400 Subject: [PATCH 3/4] Work around mypy bug https://github.com/python/mypy/issues/4182 --- src/toil/test/utils/utilsTest.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/toil/test/utils/utilsTest.py b/src/toil/test/utils/utilsTest.py index 7a8f62d786..1927ebbb0f 100644 --- a/src/toil/test/utils/utilsTest.py +++ b/src/toil/test/utils/utilsTest.py @@ -406,12 +406,16 @@ def testGetPIDStatus(self, tmp_path: Path) -> None: """Test that ToilStatus.getPIDStatus() behaves as expected.""" jobstore = tmp_path / "jobstore" release_file = tmp_path / "release-workflow" + # Get the name of the module. + # The loader exists despite MyPy's protests; see + # + module_name = __loader__.fullname # type: ignore # Run wait_for_file_workflow() as a child process. wf = subprocess.Popen( [ python, "-c", - f"from {__loader__.fullname} import " + f"from {module_name} import " f"wait_for_file_workflow as w; w()", str(jobstore), str(release_file), From b7a9cf5ab8974fdb0c348ca8e2de8217d4f5e9a6 Mon Sep 17 00:00:00 2001 From: Adam Novak Date: Thu, 20 Aug 2026 16:39:25 -0400 Subject: [PATCH 4/4] Use __name__ instead of deprecated __loader__ to find module --- src/toil/test/utils/utilsTest.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/toil/test/utils/utilsTest.py b/src/toil/test/utils/utilsTest.py index 1927ebbb0f..e41060b046 100644 --- a/src/toil/test/utils/utilsTest.py +++ b/src/toil/test/utils/utilsTest.py @@ -406,16 +406,13 @@ def testGetPIDStatus(self, tmp_path: Path) -> None: """Test that ToilStatus.getPIDStatus() behaves as expected.""" jobstore = tmp_path / "jobstore" release_file = tmp_path / "release-workflow" - # Get the name of the module. - # The loader exists despite MyPy's protests; see - # - module_name = __loader__.fullname # type: ignore + assert __name__ != "__main__" # Run wait_for_file_workflow() as a child process. wf = subprocess.Popen( [ python, "-c", - f"from {module_name} import " + f"from {__name__} import " f"wait_for_file_workflow as w; w()", str(jobstore), str(release_file),