chore: establish project baseline

This commit is contained in:
OpenCode
2026-09-21 15:51:47 -03:00
commit 9dcc263217
459 changed files with 447890 additions and 0 deletions
+272
View File
@@ -0,0 +1,272 @@
import importlib.util
import sys
from pathlib import Path
import pytest
SCRIPT = Path(__file__).parents[1] / "scripts" / "run_agent_service.py"
AUTHORIZED = r"D:\PROJETOS\GTISISTEMAS\Projeto\TESTESOFICIAIS.FDB"
def load_module():
spec = importlib.util.spec_from_file_location("run_agent_service", SCRIPT)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
return module
service = load_module()
class _FakeState:
def __init__(self):
self.logged = []
def log_ipi_write(self, *args):
self.logged.append(args)
class _FakeExecutor:
"""Mirrors the real firebird_write_executor's public surface used by execute_job."""
class WriteRefused(Exception):
pass
def __init__(self, path_guard_ok=True, updates=None, fingerprint_guard_ok=True):
self.path_guard_ok = path_guard_ok
self.updates = updates or {}
self.fingerprint_guard_ok = fingerprint_guard_ok
def assert_authorized_write_path(self, path, authorized_path=None):
if not self.path_guard_ok:
raise self.WriteRefused(f"path is not the authorized write target: {path}")
def assert_schema_fingerprint_authorized(self, observed, expected):
if not self.fingerprint_guard_ok or observed != expected:
raise self.WriteRefused(f"schema fingerprint mismatch: expected {expected!r}, observed {observed!r}")
def execute_guarded_update(self, connection, *, database_path, proposal, now, authorized_path=None):
code = proposal["product_code"]
if code in self.updates:
raise self.WriteRefused(self.updates[code])
record = type("Record", (), {
"before_value": proposal["current_value"],
"after_value": proposal["proposed_value"],
"rowcount": 1,
})()
return record
def _config(**overrides):
base = dict(
hub_url="http://localhost:8000", agent_id="a1", agent_token="tok", company_id="c1", company_uf="BA",
database_path=AUTHORIZED, firebird_writes=False, poll_interval_seconds=0.01,
agent_version="0.1.0", schema_fingerprint="fp", state_db=":memory:",
authorized_write_database_path=None, expected_schema_fingerprint="fp",
)
base.update(overrides)
return type("Config", (), base)()
def test_config_defaults_from_env():
env = {"FIREBIRD_DATABASE_PATH": AUTHORIZED}
config = service.Config(env)
assert config.firebird_writes is False
assert config.hub_url == "http://localhost:8000"
assert config.poll_interval_seconds == 5.0
def test_config_reads_gti_hub_url_and_writes_flag():
env = {"FIREBIRD_DATABASE_PATH": AUTHORIZED, "GTI_HUB_URL": "http://hub.internal", "FIREBIRD_WRITES": "1"}
config = service.Config(env)
assert config.hub_url == "http://hub.internal"
assert config.firebird_writes is True
def test_path_guard_fails_closed_before_any_write(monkeypatch):
config = _config(firebird_writes=True, database_path=r"D:\PRODUCAO\ERP.FDB")
executor = _FakeExecutor(path_guard_ok=False)
state = _FakeState()
job = {"kind": "REPROCESS_PRODUCTS", "agent_id": 1, "payload": {"codigos": ["000026"]}}
called = {"read_products": False}
def fake_read_products(env, codigos=None):
called["read_products"] = True
return []
monkeypatch.setattr(service, "read_products", fake_read_products)
result, error = service.execute_job(job, config, executor, state, {})
assert result is None
assert "not the authorized write target" in error
assert called["read_products"] is False # never even reads Firebird once the guard refuses
def test_pilot_write_blocked_when_schema_fingerprint_does_not_match(monkeypatch):
# A real client install where the live schema fingerprint drifted from what
# this Agent installation was configured/registered to expect.
config = _config(firebird_writes=True, schema_fingerprint="observed-live-fp", expected_schema_fingerprint="registered-fp")
executor = _FakeExecutor()
state = _FakeState()
job = {"kind": "REPROCESS_PRODUCTS", "agent_id": 1, "payload": {"codigos": ["000026"]}}
called = {"read_products": False}
monkeypatch.setattr(service, "read_products", lambda env, codigos=None: called.update(read_products=True) or [])
result, error = service.execute_job(job, config, executor, state, {})
assert result is None
assert "schema fingerprint mismatch" in error
assert called["read_products"] is False
def test_pilot_write_allowed_with_explicit_authorized_path_and_matching_fingerprint(monkeypatch):
client_path = r"D:\ClienteX\ERP\PRODUCAO.FDB"
config = _config(
firebird_writes=True, database_path=client_path, authorized_write_database_path=client_path,
schema_fingerprint="fp", expected_schema_fingerprint="fp",
)
products = [{"CODIGO": "000026", "PRODUTO": "x", "CLASSIFICACAO_FISCAL": "03055100", "IPI": None}]
decisions = [{
"status": "EXACT_NCM", "ipi_status": "IPI_RESOLVED",
"classification": {"ipi": {"rate_kind": "NUMERIC", "rate_numeric": 3.25}},
"dataset_versions": {"tipi_ipi": "v1"},
}]
monkeypatch.setattr(service, "read_products", lambda env, codigos=None: products)
class FakeClient:
def __init__(self, *a, **k): pass
def classify_batch(self, items): return decisions
monkeypatch.setattr(service, "HubClient", FakeClient)
fake_connection = type("Conn", (), {"close": lambda self: None})()
monkeypatch.setattr(service, "open_write_connection", lambda env, path: fake_connection)
executor = _FakeExecutor()
state = _FakeState()
job = {"kind": "REPROCESS_PRODUCTS", "agent_id": 1, "payload": {"codigos": ["000026"]}}
result, error = service.execute_job(job, config, executor, state, {})
assert error is None
assert result["writes_succeeded"] == 1
def test_execute_job_isolates_internal_errors_without_raising(monkeypatch):
config = _config()
def boom(env, codigos=None):
raise RuntimeError("firebird unavailable")
monkeypatch.setattr(service, "read_products", boom)
executor = _FakeExecutor()
state = _FakeState()
job = {"kind": "REPROCESS_ALL", "agent_id": 1, "payload": {}}
result, error = service.execute_job(job, config, executor, state, {})
assert result is None
assert "firebird unavailable" in error
def test_execute_job_success_summarizes_pipeline(monkeypatch):
config = _config()
products = [{"CODIGO": "000026", "PRODUTO": "x", "CLASSIFICACAO_FISCAL": "03055100", "IPI": None}]
decisions = [{
"status": "EXACT_NCM", "ipi_status": "IPI_RESOLVED",
"classification": {"ipi": {"rate_kind": "NUMERIC", "rate_numeric": 3.25}},
"dataset_versions": {"tipi_ipi": "v1"},
}]
monkeypatch.setattr(service, "read_products", lambda env, codigos=None: products)
class FakeClient:
def __init__(self, *a, **k): pass
def classify_batch(self, items): return decisions
monkeypatch.setattr(service, "HubClient", FakeClient)
executor = _FakeExecutor()
state = _FakeState()
job = {"kind": "REPROCESS_PRODUCTS", "agent_id": 1, "payload": {"codigos": ["000026"]}}
result, error = service.execute_job(job, config, executor, state, {})
assert error is None
assert result["products_processed"] == 1
assert result["writes_attempted"] == 0 # firebird_writes disabled by default in _config()
class _FakeHubForLoop:
"""Simulates: heartbeat flaky twice then OK, one job then nothing, and captures completions."""
def __init__(self):
self.heartbeat_calls = 0
self.jobs = [{"job_id": 1, "kind": "REPROCESS_ALL", "agent_id": 1, "payload": {}}]
self.completed = []
self.failed = []
def heartbeat(self, *a, **k):
self.heartbeat_calls += 1
if self.heartbeat_calls == 1:
raise ConnectionError("hub down")
return {}
def next_job(self):
return self.jobs.pop(0) if self.jobs else None
def complete_job(self, job_id, result_summary):
self.completed.append((job_id, result_summary))
def fail_job(self, job_id, error):
self.failed.append((job_id, error))
def classify_batch(self, items):
return []
class _ExternalStopFlag:
"""Mirrors the Windows Service wrapper's stop object: no signal registration,
just a plain flag flippable from another thread."""
def __init__(self):
self.stop = False
def test_run_honors_an_externally_supplied_stopper(monkeypatch):
# This is exactly the pattern the Windows Service wrapper uses: it never
# constructs GracefulStop() (which would crash off the main thread), it
# passes its own stop flag and flips it from the SvcStop handler.
config = _config(poll_interval_seconds=0.001)
fake_hub = _FakeHubForLoop()
fake_hub.jobs = [] # no jobs; loop would run forever without an external stop
monkeypatch.setattr(service, "HubClient", lambda *a, **k: fake_hub)
monkeypatch.setattr(service, "load_executor", lambda: _FakeExecutor())
monkeypatch.setattr(service, "AgentState", lambda path: _FakeState())
monkeypatch.setattr(service, "read_products", lambda env, codigos=None: [])
stopper = _ExternalStopFlag()
calls = {"n": 0}
real_sleep = service.time.sleep
def counting_sleep(seconds):
calls["n"] += 1
if calls["n"] >= 3:
stopper.stop = True
monkeypatch.setattr(service.time, "sleep", counting_sleep)
service.run(config, {}, stopper=stopper) # no max_iterations — only the external flag can stop it
assert stopper.stop is True
assert calls["n"] >= 3
def test_run_survives_hub_down_then_processes_one_job_and_stops(monkeypatch):
config = _config(poll_interval_seconds=0.001)
fake_hub = _FakeHubForLoop()
monkeypatch.setattr(service, "HubClient", lambda *a, **k: fake_hub)
monkeypatch.setattr(service, "load_executor", lambda: _FakeExecutor())
monkeypatch.setattr(service, "AgentState", lambda path: _FakeState())
monkeypatch.setattr(service, "read_products", lambda env, codigos=None: [])
monkeypatch.setattr(service, "build_job_coverage", lambda *a, **k: None)
monkeypatch.setattr(service.time, "sleep", lambda seconds: None)
# first heartbeat call raises -> backoff branch; second call onward succeeds.
service.run(config, {}, max_iterations=4)
assert fake_hub.heartbeat_calls >= 2
assert len(fake_hub.completed) == 1
assert fake_hub.completed[0][0] == 1
assert fake_hub.completed[0][1]["products_processed"] == 0