Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
87 changes: 53 additions & 34 deletions autofit/aggregator/aggregator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from shutil import rmtree
from typing import List, Union, Iterator, Optional

from autonerves.test_mode import is_test_mode

from .predicate import AttributePredicate
from .search_output import SearchOutput, GridSearchOutput, GridSearch

Expand Down Expand Up @@ -168,42 +170,59 @@ def from_directory(
"""
print("Aggregator loading search_outputs... could take some time.")

search_outputs = []
grid_search_outputs = []

for root, dirs, filenames in os.walk(directory, topdown=True):
for filename in filenames:
if filename.endswith(".zip"):
extracted = Path(root) / filename[:-4]
if extracted.exists():
continue
try:
with zipfile.ZipFile(Path(root) / filename, "r") as f:
f.extractall(extracted)
except zipfile.BadZipFile:
raise zipfile.BadZipFile(
f"File is not a zip file: \n " f"{root} \n" f"{filename}"
def scan(scan_directory):
search_outputs = []
grid_search_outputs = []

for root, dirs, filenames in os.walk(scan_directory, topdown=True):
for filename in filenames:
if filename.endswith(".zip"):
extracted = Path(root) / filename[:-4]
if extracted.exists():
continue
try:
with zipfile.ZipFile(Path(root) / filename, "r") as f:
f.extractall(extracted)
except zipfile.BadZipFile:
raise zipfile.BadZipFile(
f"File is not a zip file: \n " f"{root} \n" f"{filename}"
)
dirs.append(filename[:-4])

def should_add():
return not completed_only or ".completed" in filenames

if "metadata" in filenames:
if should_add():
search_outputs.append(
SearchOutput(
Path(root),
reference=reference,
)
)
dirs.append(filename[:-4])

def should_add():
return not completed_only or ".completed" in filenames

if "metadata" in filenames:
if should_add():
search_outputs.append(
SearchOutput(
Path(root),
reference=reference,
if ".is_grid_search" in filenames:
if should_add():
grid_search_outputs.append(
GridSearchOutput(
Path(root),
)
)
)
if ".is_grid_search" in filenames:
if should_add():
grid_search_outputs.append(
GridSearchOutput(
Path(root),
)
)

return search_outputs, grid_search_outputs

search_outputs, grid_search_outputs = scan(directory)

# Under test mode the searches wrote their results beneath an inserted
# ``test_mode`` segment (``output/test_mode/<prefix>``) rather than the
# real-run location the caller points at (``output/<prefix>``); see
# ``_test_mode_segment`` in ``non_linear/paths/abstract.py``. If nothing
# was found there, retry once against that sibling so aggregator-based
# tutorials (e.g. features/interpolate) run cleanly under test mode.
if len(search_outputs) == 0 and is_test_mode():
directory = Path(directory)
test_mode_directory = directory.parent / "test_mode" / directory.name
if test_mode_directory.exists():
search_outputs, grid_search_outputs = scan(test_mode_directory)

if len(search_outputs) == 0:
print(f"\nNo search_outputs found in {directory}\n")
Expand Down
31 changes: 31 additions & 0 deletions test_autofit/aggregator/test_from_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,34 @@ def test_samples_summary_cached():
search_output = SearchOutput(directory)

assert search_output.samples_summary is search_output.samples_summary


@pytest.fixture(name="test_mode_directory")
def make_test_mode_directory(tmp_path):
"""
Mirrors the on-disk layout a search produces under test mode: the results
live beneath an inserted ``test_mode`` segment (``output/test_mode/prefix``)
while the caller points ``from_directory`` at the real-run location
(``output/prefix``), which holds no metadata.
"""
source = Path(__file__).parent / "search_output"
real_directory = tmp_path / "output" / "prefix"
real_directory.mkdir(parents=True)
shutil.copytree(source, real_directory.parent / "test_mode" / "prefix" / "search_output")
return real_directory


def test_from_directory_test_mode_fallback(test_mode_directory, monkeypatch):
monkeypatch.setattr(
"autofit.aggregator.aggregator.is_test_mode", lambda: True
)
aggregator = Aggregator.from_directory(test_mode_directory)
assert len(aggregator) == 1


def test_from_directory_no_fallback_when_not_test_mode(test_mode_directory, monkeypatch):
monkeypatch.setattr(
"autofit.aggregator.aggregator.is_test_mode", lambda: False
)
aggregator = Aggregator.from_directory(test_mode_directory)
assert len(aggregator) == 0
Loading