|
1 | 1 | import os
|
2 | 2 | import shutil
|
3 | 3 | import attr
|
| 4 | +import typing as ty |
4 | 5 | import numpy as np
|
| 6 | +import time |
5 | 7 | from unittest import mock
|
| 8 | +from pathlib import Path |
6 | 9 | import pytest
|
7 | 10 | import time
|
| 11 | +from fileformats.generic import File |
| 12 | +import pydra.mark |
8 | 13 |
|
9 | 14 | from .utils import (
|
10 | 15 | fun_addtwo,
|
@@ -1599,3 +1604,62 @@ def test_task_files_cachelocations(plugin_dask_opt, tmp_path):
|
1599 | 1604 | # checking if the second task didn't run the interface again
|
1600 | 1605 | assert nn.output_dir.exists()
|
1601 | 1606 | assert not nn2.output_dir.exists()
|
| 1607 | + |
| 1608 | + |
| 1609 | +class OverriddenContentsFile(File): |
| 1610 | + """A class for testing purposes, to that enables you to override the contents |
| 1611 | + of the file to allow you to check whether the persistent cache is used.""" |
| 1612 | + |
| 1613 | + def __init__( |
| 1614 | + self, |
| 1615 | + fspaths: ty.Iterator[Path], |
| 1616 | + contents: ty.Optional[bytes] = None, |
| 1617 | + metadata: ty.Dict[str, ty.Any] = None, |
| 1618 | + ): |
| 1619 | + super().__init__(fspaths, metadata=metadata) |
| 1620 | + self._contents = contents |
| 1621 | + |
| 1622 | + def byte_chunks(self, **kwargs) -> ty.Generator[ty.Tuple[str, bytes], None, None]: |
| 1623 | + if self._contents is not None: |
| 1624 | + yield (str(self.fspath), iter([self._contents])) |
| 1625 | + else: |
| 1626 | + yield from super().byte_chunks(**kwargs) |
| 1627 | + |
| 1628 | + @property |
| 1629 | + def contents(self): |
| 1630 | + if self._contents is not None: |
| 1631 | + return self._contents |
| 1632 | + return super().contents |
| 1633 | + |
| 1634 | + |
| 1635 | +def test_task_files_persistentcache(tmp_path): |
| 1636 | + """ |
| 1637 | + Two identical tasks with provided cache_dir that use file as an input; |
| 1638 | + the second task has cache_locations and should not recompute the results |
| 1639 | + """ |
| 1640 | + test_file_path = tmp_path / "test_file.txt" |
| 1641 | + test_file_path.write_bytes(b"foo") |
| 1642 | + cache_dir = tmp_path / "cache-dir" |
| 1643 | + cache_dir.mkdir() |
| 1644 | + test_file = OverriddenContentsFile(test_file_path) |
| 1645 | + |
| 1646 | + @pydra.mark.task |
| 1647 | + def read_contents(x: OverriddenContentsFile) -> bytes: |
| 1648 | + return x.contents |
| 1649 | + |
| 1650 | + assert ( |
| 1651 | + read_contents(x=test_file, cache_dir=cache_dir)(plugin="serial").output.out |
| 1652 | + == b"foo" |
| 1653 | + ) |
| 1654 | + test_file._contents = b"bar" |
| 1655 | + # should return result from the first run using the persistent cache |
| 1656 | + assert ( |
| 1657 | + read_contents(x=test_file, cache_dir=cache_dir)(plugin="serial").output.out |
| 1658 | + == b"foo" |
| 1659 | + ) |
| 1660 | + time.sleep(2) # Windows has a 2-second resolution for mtime |
| 1661 | + test_file_path.touch() # update the mtime to invalidate the persistent cache value |
| 1662 | + assert ( |
| 1663 | + read_contents(x=test_file, cache_dir=cache_dir)(plugin="serial").output.out |
| 1664 | + == b"bar" |
| 1665 | + ) # returns the overridden value |
0 commit comments