Add webhook endpoint test programs
This commit is contained in:
116
TestPrograms/test-pr-event-creation.py
Normal file
116
TestPrograms/test-pr-event-creation.py
Normal file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env python3
|
||||
# Simple webhook test sender for webhook_endpoint.py
|
||||
# Edit the CONFIG section and Run in Thonny. No CLI args needed.
|
||||
|
||||
import json
|
||||
import hmac
|
||||
import hashlib
|
||||
import httpx
|
||||
import sqlite3
|
||||
import os
|
||||
import time
|
||||
|
||||
# -------------- CONFIG (edit these) --------------
|
||||
|
||||
# Your running server (uvicorn webhook_endpoint:app ...)
|
||||
SERVER_BASE = "http://127.0.0.1:8081"
|
||||
|
||||
# Must match WEBHOOK_SECRET used by the server
|
||||
WEBHOOK_SECRET = "123456gfdsaqwertyuio"
|
||||
|
||||
# Path to the server's STATE_PATH (so we can seed the PR mapping to skip Bugzilla)
|
||||
STATE_PATH = "/tmp/webhook_state.sqlite"
|
||||
|
||||
# The real GitHub repo and PR you want to mirror (PR must exist on GitHub)
|
||||
REPO_FULL = "Koozali-SME-Server/smeserver-manager" # owner/repo
|
||||
PR_NUMBER = 9 # existing PR number on GitHub
|
||||
|
||||
# Cosmetic fields (not used for mirroring logic; placeholders are fine)
|
||||
PR_TITLE = "Test PR from harness"
|
||||
PR_BODY = "Harness test body."
|
||||
BASE_BRANCH = "master"
|
||||
BASE_SHA = "9f8e7d6cafebabe0000deadbeef0000000000000"
|
||||
HEAD_BRANCH = "feature/test"
|
||||
HEAD_SHA = "a1b2c3ddeeddbb0000deadbeef0000000000000"
|
||||
PR_AUTHOR = "octocat" # GitHub login of PR author (cosmetic)
|
||||
|
||||
# Seed the state DB so the server skips Bugzilla and treats event as "synchronize"
|
||||
SEED_STATE = True
|
||||
|
||||
# -------------------------------------------------
|
||||
|
||||
def sign(secret: str, body: bytes) -> str:
|
||||
return "sha256=" + hmac.new(secret.encode("utf-8"), body, hashlib.sha256).hexdigest()
|
||||
|
||||
def seed_state_db(state_path: str, pr_key: str, bug_id: int = 1):
|
||||
os.makedirs(os.path.dirname(state_path) or ".", exist_ok=True)
|
||||
conn = sqlite3.connect(state_path)
|
||||
cur = conn.cursor()
|
||||
cur.execute("""
|
||||
CREATE TABLE IF NOT EXISTS pr_map (
|
||||
pr_key TEXT PRIMARY KEY,
|
||||
bug_id INTEGER NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
)
|
||||
""")
|
||||
now = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
|
||||
cur.execute("""
|
||||
INSERT INTO pr_map (pr_key, bug_id, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(pr_key) DO UPDATE SET bug_id=excluded.bug_id, updated_at=excluded.updated_at
|
||||
""", (pr_key, bug_id, now, now))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def build_payload():
|
||||
owner, repo = REPO_FULL.split("/", 1)
|
||||
return {
|
||||
"action": "synchronize", # use synchronize to trigger mirroring without Bugzilla create
|
||||
"repository": {
|
||||
"full_name": REPO_FULL,
|
||||
"owner": {"login": owner},
|
||||
"name": repo,
|
||||
},
|
||||
"pull_request": {
|
||||
"number": PR_NUMBER,
|
||||
"html_url": f"https://github.com/{REPO_FULL}/pull/{PR_NUMBER}",
|
||||
"title": PR_TITLE,
|
||||
"body": PR_BODY,
|
||||
"user": {"login": PR_AUTHOR, "html_url": f"https://github.com/{PR_AUTHOR}"},
|
||||
"base": {"ref": BASE_BRANCH, "sha": BASE_SHA},
|
||||
"head": {"ref": HEAD_BRANCH, "sha": HEAD_SHA, "repo": {"owner": {"login": PR_AUTHOR}}},
|
||||
"created_at": "2025-09-20T12:34:56Z",
|
||||
"labels": [],
|
||||
},
|
||||
}
|
||||
|
||||
def main():
|
||||
pr_key = f"{REPO_FULL}#{PR_NUMBER}"
|
||||
|
||||
if SEED_STATE:
|
||||
print(f"Seeding state: {STATE_PATH} -> {pr_key} = bug_id 1 (skips Bugzilla)")
|
||||
seed_state_db(STATE_PATH, pr_key, bug_id=1)
|
||||
|
||||
# Optional health check (won't fail the run)
|
||||
try:
|
||||
r = httpx.get(f"{SERVER_BASE.rstrip('/')}/healthz", timeout=3)
|
||||
print("Healthz:", r.status_code, r.text)
|
||||
except Exception as e:
|
||||
print("Healthz check failed (continuing):", e)
|
||||
|
||||
payload = build_payload()
|
||||
body = json.dumps(payload).encode("utf-8")
|
||||
headers = {
|
||||
"X-GitHub-Event": "pull_request",
|
||||
"X-Hub-Signature-256": sign(WEBHOOK_SECRET, body),
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
url = f"{SERVER_BASE.rstrip('/')}/webhook/github"
|
||||
print(f"POST {url} for {REPO_FULL} PR #{PR_NUMBER}")
|
||||
resp = httpx.post(url, data=body, headers=headers, timeout=30)
|
||||
print("Response:", resp.status_code, resp.text)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user