Files
FESADev/tests/test_execute.py
T
2026-08-12 18:36:37 +09:00

157 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import subprocess
import pytest
from scripts import execute
def test_invoke_codex_uses_utf8_for_unicode_prompt(tmp_path, monkeypatch):
phase_dir = tmp_path / "phases" / "unicode-phase"
phase_dir.mkdir(parents=True)
(phase_dir / "index.json").write_text(
json.dumps(
{
"project": "FESA Structural Solver",
"phase": "unicode-phase",
"steps": [{"step": 0, "name": "unicode", "status": "pending"}],
}
),
encoding="utf-8",
)
(phase_dir / "step0.md").write_text("EulerBernoulli 보", encoding="utf-8")
invocation = {}
def capture_run(command, **kwargs):
invocation["command"] = command
invocation["kwargs"] = kwargs
return subprocess.CompletedProcess(command, 0, stdout="", stderr="")
monkeypatch.setattr(execute, "ROOT", tmp_path)
monkeypatch.setattr(execute.subprocess, "run", capture_run)
executor = execute.StepExecutor("unicode-phase")
executor._invoke_codex({"step": 0, "name": "unicode"}, "승인된 설계 ")
assert "EulerBernoulli 보" in invocation["kwargs"]["input"]
assert invocation["kwargs"]["encoding"] == "utf-8"
sandbox_index = invocation["command"].index("--sandbox")
assert invocation["command"][sandbox_index + 1] == "workspace-write"
def test_invoke_codex_accepts_explicit_danger_full_access_override(
tmp_path, monkeypatch
):
phase_dir = tmp_path / "phases" / "sandbox-phase"
phase_dir.mkdir(parents=True)
(phase_dir / "index.json").write_text(
json.dumps(
{
"project": "FESA Structural Solver",
"phase": "sandbox-phase",
"steps": [{"step": 0, "name": "sandbox", "status": "pending"}],
}
),
encoding="utf-8",
)
(phase_dir / "step0.md").write_text("sandbox override", encoding="utf-8")
invocation = {}
def capture_run(command, **kwargs):
invocation["command"] = command
return subprocess.CompletedProcess(command, 0, stdout="", stderr="")
monkeypatch.setattr(execute, "ROOT", tmp_path)
monkeypatch.setattr(execute.subprocess, "run", capture_run)
monkeypatch.setenv("FESA_HARNESS_CODEX_SANDBOX", "danger-full-access")
executor = execute.StepExecutor("sandbox-phase")
executor._invoke_codex({"step": 0, "name": "sandbox"}, "")
sandbox_index = invocation["command"].index("--sandbox")
assert invocation["command"][sandbox_index + 1] == "danger-full-access"
def test_invoke_codex_rejects_unknown_sandbox_override(tmp_path, monkeypatch):
phase_dir = tmp_path / "phases" / "sandbox-phase"
phase_dir.mkdir(parents=True)
(phase_dir / "index.json").write_text(
json.dumps(
{
"project": "FESA Structural Solver",
"phase": "sandbox-phase",
"steps": [{"step": 0, "name": "sandbox", "status": "pending"}],
}
),
encoding="utf-8",
)
(phase_dir / "step0.md").write_text("sandbox override", encoding="utf-8")
monkeypatch.setattr(execute, "ROOT", tmp_path)
monkeypatch.setenv("FESA_HARNESS_CODEX_SANDBOX", "read-only")
executor = execute.StepExecutor("sandbox-phase")
with pytest.raises(execute.CodexEnvironmentError, match="FESA_HARNESS_CODEX_SANDBOX"):
executor._invoke_codex({"step": 0, "name": "sandbox"}, "")
def test_codex_environment_failure_detects_missing_sandbox_helper_on_zero_exit():
output = {
"exitCode": 0,
"stdout": "",
"stderr": (
"windows sandbox: orchestrator_helper_launch_failed: "
"helper=codex-windows-sandbox-setup.exe, error=program not found"
),
}
assert execute.StepExecutor._codex_environment_failure(output) == (
"Codex Windows sandbox helper를 실행할 수 없습니다."
)
def test_run_git_decodes_output_as_utf8(tmp_path, monkeypatch):
invocation = {}
def capture_run(command, **kwargs):
invocation["command"] = command
invocation["kwargs"] = kwargs
return subprocess.CompletedProcess(command, 0, stdout="", stderr="")
monkeypatch.setattr(execute.subprocess, "run", capture_run)
executor = object.__new__(execute.StepExecutor)
executor._root = str(tmp_path)
executor._run_git("status", "--short")
assert invocation["kwargs"]["encoding"] == "utf-8"
def test_feature_commit_message_is_windows_console_safe():
message = execute.StepExecutor.FEAT_MSG.format(
phase="linear-static-3d-euler-beam", num=0, name="requirements-baseline"
)
message.encode("cp949")
def test_configure_utf8_stdio_reconfigures_both_streams(monkeypatch):
class ReconfigurableStream:
def __init__(self):
self.encodings = []
def reconfigure(self, *, encoding):
self.encodings.append(encoding)
stdout = ReconfigurableStream()
stderr = ReconfigurableStream()
monkeypatch.setattr(execute.sys, "stdout", stdout)
monkeypatch.setattr(execute.sys, "stderr", stderr)
execute._configure_utf8_stdio()
assert stdout.encodings == ["utf-8"]
assert stderr.encodings == ["utf-8"]