feat(client): Mac aider-watch client (B1-B4: scaffolding + api_client + buffer + aiderw)
This commit is contained in:
1
scripts/aider_watch_client/tests/__init__.py
Normal file
1
scripts/aider_watch_client/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# 2026-04-20 @ Asia/Taipei
|
||||
23
scripts/aider_watch_client/tests/test_api_client.py
Normal file
23
scripts/aider_watch_client/tests/test_api_client.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# 2026-04-20 @ Asia/Taipei
|
||||
import hmac, hashlib
|
||||
from aider_watch_client.api_client import sign_body
|
||||
|
||||
|
||||
def test_sign_body_format():
|
||||
body = b'{"events":[]}'
|
||||
sig = sign_body(body, "secret")
|
||||
assert sig.startswith("sha256=")
|
||||
expected = "sha256=" + hmac.new(b"secret", body, hashlib.sha256).hexdigest()
|
||||
assert sig == expected
|
||||
|
||||
|
||||
def test_sign_body_deterministic():
|
||||
assert sign_body(b"same", "secret") == sign_body(b"same", "secret")
|
||||
|
||||
|
||||
def test_sign_body_different_secrets():
|
||||
assert sign_body(b"body", "sec1") != sign_body(b"body", "sec2")
|
||||
|
||||
|
||||
def test_sign_body_different_bodies():
|
||||
assert sign_body(b"a", "s") != sign_body(b"b", "s")
|
||||
53
scripts/aider_watch_client/tests/test_buffer.py
Normal file
53
scripts/aider_watch_client/tests/test_buffer.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# 2026-04-20 @ Asia/Taipei
|
||||
import json
|
||||
from aider_watch_client import buffer
|
||||
|
||||
|
||||
def test_write_reads_back(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(buffer, "BUFFER_DIR", tmp_path)
|
||||
ev = {"type":"session_start","session_id":"s1",
|
||||
"ts":"2026-04-20T10:00:00+08:00","host":"ogt-mac","payload":{}}
|
||||
buffer.write([ev])
|
||||
files = list(tmp_path.glob("pending_*.jsonl"))
|
||||
assert len(files) == 1
|
||||
lines = [json.loads(l) for l in files[0].read_text().splitlines() if l.strip()]
|
||||
assert lines[0]["session_id"] == "s1"
|
||||
|
||||
|
||||
def test_flush_all_drained(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(buffer, "BUFFER_DIR", tmp_path)
|
||||
ev = {"type":"session_start","session_id":"s1",
|
||||
"ts":"2026-04-20T10:00:00+08:00","host":"ogt-mac","payload":{}}
|
||||
buffer.write([ev])
|
||||
sent = []
|
||||
def fake_post(evs): sent.extend(evs); return True
|
||||
n = buffer.flush(post_fn=fake_post)
|
||||
assert n == 1
|
||||
assert len(sent) == 1
|
||||
assert list(tmp_path.glob("pending_*.jsonl")) == []
|
||||
|
||||
|
||||
def test_flush_keeps_on_fail(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(buffer, "BUFFER_DIR", tmp_path)
|
||||
ev = {"type":"session_start","session_id":"s1",
|
||||
"ts":"2026-04-20T10:00:00+08:00","host":"ogt-mac","payload":{}}
|
||||
buffer.write([ev])
|
||||
n = buffer.flush(post_fn=lambda evs: False)
|
||||
assert n == 0
|
||||
assert len(list(tmp_path.glob("pending_*.jsonl"))) == 1
|
||||
|
||||
|
||||
def test_flush_chunks_oversize(tmp_path, monkeypatch):
|
||||
""">50 events → chunked."""
|
||||
monkeypatch.setattr(buffer, "BUFFER_DIR", tmp_path)
|
||||
events = [{"type":"raw","session_id":f"s{i}",
|
||||
"ts":"2026-04-20T10:00:00+08:00","host":"m","payload":{}}
|
||||
for i in range(120)]
|
||||
buffer.write(events)
|
||||
posted_sizes = []
|
||||
def fake_post(evs):
|
||||
posted_sizes.append(len(evs))
|
||||
return True
|
||||
n = buffer.flush(post_fn=fake_post)
|
||||
assert n == 120
|
||||
assert posted_sizes == [50, 50, 20] # 切成 3 批
|
||||
Reference in New Issue
Block a user