test: code-to10 v2 coverage additions (14 files, production code unchanged)
(cherry picked from commit 473338c35d59bfd50929542e7f08c0a4a22c5987)
This commit is contained in:
1 parent
2032043b60
commit
3a72ed3847
14 files changed
+8249
No files matched your search
@@ -0,0 +1,204 @@
|
||||
"""Coverage batch v2 (D8): GitHub webhook /fix-review branches --
|
||||
project with no owner, task-INSERT IntegrityError duplicate read,
|
||||
and IntegrityError re-raise.
|
||||
|
||||
The webhook handler runs end to end with a real HMAC signature
|
||||
(env secret), a real delivery claim and a real fix-review claim;
|
||||
only the task-table INSERT is faulted, via a counting _db proxy,
|
||||
to drive the handler's own IntegrityError mapping.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import hmac
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import sqlite3
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from unittest import mock
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0, str(REPO_ROOT))
|
||||
|
||||
from cloud.server import (
|
||||
CloudControlPlaneHandler,
|
||||
init_db,
|
||||
)
|
||||
|
||||
SECRET = "test-secret"
|
||||
|
||||
|
||||
def _handler(db_path):
|
||||
h = CloudControlPlaneHandler.__new__(CloudControlPlaneHandler)
|
||||
h.server = SimpleNamespace(db_path=db_path, upload_dir=None,
|
||||
tenants_root=None)
|
||||
sent = []
|
||||
h._send_json = lambda status, obj, extra_headers=None: sent.append(
|
||||
(status, obj))
|
||||
h.sent = sent
|
||||
return h
|
||||
|
||||
|
||||
def _conn(db_path):
|
||||
c = sqlite3.connect(db_path)
|
||||
c.row_factory = sqlite3.Row
|
||||
return c
|
||||
|
||||
|
||||
class _RowCursor:
|
||||
def __init__(self, row):
|
||||
self._row = row
|
||||
|
||||
def fetchone(self):
|
||||
return self._row
|
||||
|
||||
def fetchall(self):
|
||||
return [self._row] if self._row else []
|
||||
|
||||
|
||||
class _WebhookConn:
|
||||
"""Delegates everything except the task INSERT (raises
|
||||
IntegrityError) and the idempotency re-read (faked row)."""
|
||||
|
||||
def __init__(self, real, existing_row):
|
||||
self._real = real
|
||||
self._existing_row = existing_row
|
||||
|
||||
def execute(self, sql, params=()):
|
||||
text = sql.strip()
|
||||
if text.startswith("INSERT INTO tasks"):
|
||||
raise sqlite3.IntegrityError("duplicate delivery")
|
||||
if "SELECT id FROM tasks WHERE project_id" in text:
|
||||
return _RowCursor(self._existing_row)
|
||||
return self._real.execute(sql, params)
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self._real, name)
|
||||
|
||||
|
||||
class WebhookFixReviewTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp = tempfile.TemporaryDirectory()
|
||||
self.db_path = os.path.join(self.tmp.name, "test.db")
|
||||
init_db(self.db_path)
|
||||
from cloud.cost import CostStore
|
||||
CostStore(self.db_path)
|
||||
|
||||
def tearDown(self):
|
||||
self.tmp.cleanup()
|
||||
|
||||
def _project_row(self, owner):
|
||||
c = _conn(self.db_path)
|
||||
c.execute(
|
||||
"INSERT INTO projects(id, name, owner_id, created_at,"
|
||||
" repo_url, auto_pr) VALUES(?, ?, ?, ?, ?, 0)",
|
||||
("p1", "o/r", owner, time.time(), None))
|
||||
c.commit()
|
||||
c.close()
|
||||
|
||||
def _payload(self):
|
||||
return {
|
||||
"action": "created",
|
||||
"comment": {
|
||||
"id": 99,
|
||||
"body": "/fix-review please fix this",
|
||||
"user": {"login": "alice",
|
||||
"author_association": "MEMBER"},
|
||||
},
|
||||
"issue": {"number": 7, "user": {"login": "bob"}},
|
||||
"repository": {"full_name": "o/r"},
|
||||
}
|
||||
|
||||
def _h(self, raw, delivery="d1"):
|
||||
h = _handler(self.db_path)
|
||||
sig = "sha256=" + hmac.new(
|
||||
SECRET.encode(), raw, hashlib.sha256).hexdigest()
|
||||
h.rfile = io.BytesIO(raw)
|
||||
h.headers = {
|
||||
"Content-Length": str(len(raw)),
|
||||
"X-Hub-Signature-256": sig,
|
||||
"X-GitHub-Event": "issue_comment",
|
||||
"X-GitHub-Delivery": delivery,
|
||||
}
|
||||
return h
|
||||
|
||||
def test_project_no_owner(self):
|
||||
self._project_row(None)
|
||||
raw = json.dumps(self._payload()).encode()
|
||||
h = self._h(raw)
|
||||
with mock.patch.dict(os.environ,
|
||||
{"GITHUB_WEBHOOK_SECRET": SECRET}):
|
||||
h._handle_github_webhook()
|
||||
code, payload = h.sent[-1]
|
||||
self.assertEqual(code, 200)
|
||||
self.assertIn("no owner for quota attribution",
|
||||
payload["error"])
|
||||
|
||||
def _proxy_db(self, existing_row):
|
||||
calls = {"n": 0}
|
||||
|
||||
def _db():
|
||||
calls["n"] += 1
|
||||
if calls["n"] == 2:
|
||||
return _WebhookConn(_conn(self.db_path), existing_row)
|
||||
return _conn(self.db_path)
|
||||
return _db
|
||||
|
||||
def test_insert_conflict_reads_duplicate(self):
|
||||
self._project_row("u1")
|
||||
raw = json.dumps(self._payload()).encode()
|
||||
h = self._h(raw)
|
||||
h._db = self._proxy_db(("existing-task",))
|
||||
with mock.patch.dict(os.environ,
|
||||
{"GITHUB_WEBHOOK_SECRET": SECRET}):
|
||||
h._handle_github_webhook()
|
||||
code, payload = h.sent[-1]
|
||||
self.assertEqual(code, 200)
|
||||
self.assertTrue(payload["duplicate"])
|
||||
self.assertEqual(payload["task_id"], "existing-task")
|
||||
|
||||
def test_insert_conflict_reraises(self):
|
||||
self._project_row("u1")
|
||||
raw = json.dumps(self._payload()).encode()
|
||||
h = self._h(raw)
|
||||
h._db = self._proxy_db(None)
|
||||
with mock.patch.dict(os.environ,
|
||||
{"GITHUB_WEBHOOK_SECRET": SECRET}):
|
||||
with self.assertRaises(sqlite3.IntegrityError):
|
||||
h._handle_github_webhook()
|
||||
|
||||
|
||||
class MainHarnessTestCase(unittest.TestCase):
|
||||
def _fake_server(self):
|
||||
server = SimpleNamespace(
|
||||
rate_limiter=object(), server_address=("127.0.0.1", 18765))
|
||||
|
||||
def _serve_forever():
|
||||
raise KeyboardInterrupt
|
||||
|
||||
server.serve_forever = _serve_forever
|
||||
return server
|
||||
|
||||
def test_main_shared_home_synced(self):
|
||||
from cloud.server import main
|
||||
with mock.patch("cloud.server.create_server",
|
||||
return_value=self._fake_server()), \
|
||||
mock.patch("cloud.server._resolve_shared_home_mcp",
|
||||
return_value="/tmp/x"), \
|
||||
mock.patch("cloud.server._sync_shared_home_mcp",
|
||||
return_value={"copied": ["f"],
|
||||
"refreshed": []}):
|
||||
main(["--port", "18765"])
|
||||
|
||||
def test_main_shared_home_failure_swallowed(self):
|
||||
from cloud.server import main
|
||||
with mock.patch("cloud.server.create_server",
|
||||
return_value=self._fake_server()), \
|
||||
mock.patch("cloud.server._resolve_shared_home_mcp",
|
||||
side_effect=RuntimeError("resolve down")):
|
||||
main(["--port", "18765"])
|
||||
Reference in new issue
Block a user