# License: Apache-2.0 License # Created by: Patrick Lumbantobing, VertoX-AI # Copyright (c) 2026 VertoX-AI. All rights reserved. # # This work is licensed under the Apache-2.0 License. # To view a copy of this license, visit # https://www.apache.org/licenses/LICENSE-2.0 from __future__ import annotations from pathlib import Path import pytest from speech_text_data_aligners.core.errors import ConfigurationError from speech_text_data_aligners.runtime.artifacts import ArtifactPolicy, workspace def test_workspace_never_retains_and_removes_temporary_path(tmp_path: Path) -> None: temp_root = tmp_path / "temp" with workspace(run_id="run", temporary_root=temp_root) as state: state.path.joinpath("detail.txt").write_text("detail", encoding="utf-8") active_path = state.path assert active_path.is_dir() assert not active_path.exists() assert state.retained_path is None def test_workspace_always_retains_copy(tmp_path: Path) -> None: retention = tmp_path / "keep" with workspace( run_id="run", policy=ArtifactPolicy.ALWAYS, retention_root=retention ) as state: state.path.joinpath("detail.txt").write_text("detail", encoding="utf-8") assert state.retained_path == retention / "run" assert (retention / "run" / "detail.txt").read_text(encoding="utf-8") == "detail" def test_workspace_on_failure_handles_marked_and_raised_failures( tmp_path: Path, ) -> None: retention = tmp_path / "keep" with workspace( run_id="marked", policy=ArtifactPolicy.ON_FAILURE, retention_root=retention ) as marked: marked.mark_failed() assert marked.retained_path == retention / "marked" with ( pytest.raises(ValueError, match="boom"), workspace( run_id="raised", policy=ArtifactPolicy.ON_FAILURE, retention_root=retention ) as raised, ): raised.path.joinpath("evidence").write_text("x", encoding="utf-8") raise ValueError("boom") assert (retention / "raised" / "evidence").exists() def test_workspace_on_failure_does_not_retain_success(tmp_path: Path) -> None: retention = tmp_path / "keep" with workspace( run_id="ok", policy=ArtifactPolicy.ON_FAILURE, retention_root=retention ) as state: assert state.path.exists() assert state.retained_path is None assert not retention.exists() @pytest.mark.parametrize("run_id", ["", ".", "..", "a/b"]) def test_workspace_rejects_unsafe_ids(tmp_path: Path, run_id: str) -> None: with ( pytest.raises(ConfigurationError), workspace(run_id=run_id, temporary_root=tmp_path), ): pass def test_workspace_requires_retention_root() -> None: with ( pytest.raises(ConfigurationError, match="retention_root"), workspace(run_id="run", policy=ArtifactPolicy.ALWAYS), ): pass def test_workspace_refuses_to_overwrite_retained_directory(tmp_path: Path) -> None: retention = tmp_path / "keep" (retention / "run").mkdir(parents=True) with ( pytest.raises(ConfigurationError, match="already exists"), workspace(run_id="run", policy=ArtifactPolicy.ALWAYS, retention_root=retention), ): pass