feat: consolidate legacy workflows into gyxx-flow
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from gyxx_flow.adapters import (
|
||||
BrowserProfileManager,
|
||||
FeishuOutboxAdapter,
|
||||
HermesCommandAdapter,
|
||||
PostgresOutboxAdapter,
|
||||
)
|
||||
from gyxx_flow.core.context import RunContext
|
||||
from gyxx_flow.core.locks import ResourceBusyError
|
||||
from gyxx_flow.ops import Outbox
|
||||
|
||||
|
||||
def test_feishu_and_postgres_writes_share_idempotent_outbox_boundary(tmp_path: Path) -> None:
|
||||
outbox = Outbox(tmp_path)
|
||||
feishu = FeishuOutboxAdapter(outbox)
|
||||
postgres = PostgresOutboxAdapter(outbox)
|
||||
|
||||
first = feishu.upsert(
|
||||
run_id="run-001",
|
||||
operation_key="weekly-report",
|
||||
artifact_id="artifact-report-001",
|
||||
)
|
||||
duplicate = feishu.upsert(
|
||||
run_id="run-001",
|
||||
operation_key="weekly-report",
|
||||
artifact_id="artifact-report-001",
|
||||
)
|
||||
db_message = postgres.upsert(
|
||||
run_id="run-001",
|
||||
operation_key="shop-metrics",
|
||||
artifact_id="artifact-metrics-001",
|
||||
)
|
||||
|
||||
assert duplicate == first
|
||||
assert first.topic == "feishu.upsert"
|
||||
assert db_message.topic == "postgres.upsert"
|
||||
assert first.payload == {"artifact_id": "artifact-report-001"}
|
||||
assert db_message.payload == {"artifact_id": "artifact-metrics-001"}
|
||||
assert first.idempotency_key != db_message.idempotency_key
|
||||
|
||||
|
||||
def test_hermes_adapter_builds_explicit_command_and_dry_run_starts_no_process(
|
||||
monkeypatch, tmp_path: Path
|
||||
) -> None:
|
||||
prompt = tmp_path / "prompt.md"
|
||||
prompt.write_text("analyze artifact-001", encoding="utf-8")
|
||||
adapter = HermesCommandAdapter(executable="hermes", base_env={"PROFILE": "analysis"})
|
||||
command = adapter.build(prompt_file=prompt, cwd=tmp_path)
|
||||
|
||||
assert command.argv == ("hermes", "-z", "analyze artifact-001")
|
||||
assert command.cwd == tmp_path.resolve()
|
||||
assert command.env == {"PROFILE": "analysis"}
|
||||
|
||||
monkeypatch.setattr(
|
||||
subprocess,
|
||||
"run",
|
||||
lambda *args, **kwargs: pytest.fail("dry-run must not start Hermes"),
|
||||
)
|
||||
context = RunContext.create("product.style", "2026-07-27")
|
||||
outcome = command.execute(context=context, timeout_seconds=60, dry_run=True)
|
||||
assert outcome.skipped is True
|
||||
|
||||
|
||||
def test_browser_profiles_are_portable_and_exclusively_locked(tmp_path: Path) -> None:
|
||||
manager = BrowserProfileManager(tmp_path)
|
||||
|
||||
with manager.acquire("shop-compass", owner="run-001") as first:
|
||||
assert first.profile_path == (
|
||||
tmp_path / "state" / "browser_profiles" / "shop-compass"
|
||||
).resolve()
|
||||
assert first.profile_path.is_dir()
|
||||
with pytest.raises(ResourceBusyError):
|
||||
with manager.acquire(
|
||||
"shop-compass", owner="run-002", timeout_seconds=0
|
||||
):
|
||||
pass
|
||||
|
||||
with manager.acquire("shop-compass", owner="run-002", timeout_seconds=0) as second:
|
||||
assert second.profile_path == first.profile_path
|
||||
|
||||
|
||||
@pytest.mark.parametrize("unsafe", ["../escape", "a/b", "a\\b", "", ".."])
|
||||
def test_browser_profile_id_rejects_path_escape(tmp_path: Path, unsafe: str) -> None:
|
||||
with pytest.raises(ValueError, match="profile"):
|
||||
with BrowserProfileManager(tmp_path).acquire(unsafe, owner="run-001"):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user