test: add go production acceptance smoke
This commit is contained in:
136
tools/go_prod_acceptance.py
Executable file
136
tools/go_prod_acceptance.py
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run the Go native production acceptance smoke suite."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from dataclasses import asdict, dataclass
|
||||
from typing import Any
|
||||
|
||||
|
||||
DEFAULT_APP_HOST = "115.29.187.205"
|
||||
DEFAULT_KAFKA_HOST = "114.55.58.251"
|
||||
DEFAULT_USER = "root"
|
||||
DEFAULT_BASE_URL = "http://115.29.187.205:20210"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ChildCommand:
|
||||
name: str
|
||||
argv: list[str]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ChildResult:
|
||||
name: str
|
||||
status: str
|
||||
exit_code: int
|
||||
payload: dict[str, Any]
|
||||
|
||||
|
||||
def build_commands(args: argparse.Namespace) -> list[ChildCommand]:
|
||||
timeout = str(args.timeout)
|
||||
return [
|
||||
ChildCommand("systemd", [
|
||||
sys.executable,
|
||||
"tools/go_systemd_prod_smoke.py",
|
||||
"--host",
|
||||
args.app_host,
|
||||
"--user",
|
||||
args.ssh_user,
|
||||
"--timeout",
|
||||
timeout,
|
||||
]),
|
||||
ChildCommand("kafka", [
|
||||
sys.executable,
|
||||
"tools/go_kafka_prod_smoke.py",
|
||||
"--host",
|
||||
args.kafka_host,
|
||||
"--user",
|
||||
args.ssh_user,
|
||||
"--max-lag",
|
||||
str(args.max_lag),
|
||||
"--timeout",
|
||||
timeout,
|
||||
]),
|
||||
ChildCommand("http", [
|
||||
sys.executable,
|
||||
"tools/go_native_prod_smoke.py",
|
||||
"--base-url",
|
||||
args.base_url,
|
||||
"--timeout",
|
||||
timeout,
|
||||
] + (["--date", args.date] if args.date else [])),
|
||||
]
|
||||
|
||||
|
||||
def run_child(command: ChildCommand, timeout: float) -> ChildResult:
|
||||
completed = subprocess.run(
|
||||
command.argv,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
timeout=timeout,
|
||||
)
|
||||
payload = parse_json_output(completed.stdout)
|
||||
if completed.stderr.strip():
|
||||
payload.setdefault("stderr", completed.stderr.strip())
|
||||
status = payload.get("status")
|
||||
if status not in {"pass", "fail"}:
|
||||
status = "pass" if completed.returncode == 0 else "fail"
|
||||
return ChildResult(command.name, status, completed.returncode, payload)
|
||||
|
||||
|
||||
def parse_json_output(output: str) -> dict[str, Any]:
|
||||
output = output.strip()
|
||||
if not output:
|
||||
return {}
|
||||
start = output.find("{")
|
||||
end = output.rfind("}")
|
||||
if start < 0 or end < start:
|
||||
return {"rawOutput": output}
|
||||
try:
|
||||
return json.loads(output[start:end + 1])
|
||||
except json.JSONDecodeError:
|
||||
return {"rawOutput": output}
|
||||
|
||||
|
||||
def overall_status(results: list[ChildResult]) -> str:
|
||||
if not results:
|
||||
return "fail"
|
||||
return "fail" if any(result.status != "pass" or result.exit_code != 0 for result in results) else "pass"
|
||||
|
||||
|
||||
def parse_args(argv: list[str]) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--app-host", default=DEFAULT_APP_HOST)
|
||||
parser.add_argument("--kafka-host", default=DEFAULT_KAFKA_HOST)
|
||||
parser.add_argument("--ssh-user", default=DEFAULT_USER)
|
||||
parser.add_argument("--base-url", default=DEFAULT_BASE_URL)
|
||||
parser.add_argument("--date", help="Shanghai local date, YYYY-MM-DD. Defaults to today in go_native_prod_smoke.py.")
|
||||
parser.add_argument("--timeout", type=float, default=20.0)
|
||||
parser.add_argument("--max-lag", type=int, default=100)
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
args = parse_args(argv)
|
||||
results: list[ChildResult] = []
|
||||
for command in build_commands(args):
|
||||
try:
|
||||
results.append(run_child(command, args.timeout + 10))
|
||||
except Exception as exc:
|
||||
results.append(ChildResult(command.name, "fail", 1, {"status": "fail", "error": str(exc)}))
|
||||
status = overall_status(results)
|
||||
print(json.dumps({
|
||||
"status": status,
|
||||
"checks": [asdict(result) for result in results],
|
||||
}, ensure_ascii=False, indent=2))
|
||||
return 0 if status == "pass" else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main(sys.argv[1:]))
|
||||
53
tools/test_go_prod_acceptance.py
Normal file
53
tools/test_go_prod_acceptance.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import argparse
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tools import go_prod_acceptance as acceptance
|
||||
|
||||
|
||||
class GoProdAcceptanceTest(unittest.TestCase):
|
||||
def test_build_commands_runs_systemd_kafka_and_http_smokes(self):
|
||||
args = argparse.Namespace(
|
||||
app_host="115.29.187.205",
|
||||
kafka_host="114.55.58.251",
|
||||
ssh_user="root",
|
||||
base_url="http://115.29.187.205:20210",
|
||||
date="2026-07-02",
|
||||
timeout=8.0,
|
||||
max_lag=100,
|
||||
)
|
||||
|
||||
commands = acceptance.build_commands(args)
|
||||
|
||||
self.assertEqual(len(commands), 3)
|
||||
self.assertEqual(commands[0].name, "systemd")
|
||||
self.assertEqual(commands[0].argv[:2], [sys.executable, "tools/go_systemd_prod_smoke.py"])
|
||||
self.assertIn("--host", commands[0].argv)
|
||||
self.assertIn("115.29.187.205", commands[0].argv)
|
||||
self.assertEqual(commands[1].name, "kafka")
|
||||
self.assertIn("tools/go_kafka_prod_smoke.py", commands[1].argv)
|
||||
self.assertIn("--max-lag", commands[1].argv)
|
||||
self.assertEqual(commands[2].name, "http")
|
||||
self.assertIn("tools/go_native_prod_smoke.py", commands[2].argv)
|
||||
self.assertIn("--base-url", commands[2].argv)
|
||||
|
||||
def test_overall_status_fails_when_any_child_fails(self):
|
||||
results = [
|
||||
acceptance.ChildResult("systemd", "pass", 0, {"status": "pass"}),
|
||||
acceptance.ChildResult("kafka", "fail", 1, {"status": "fail"}),
|
||||
]
|
||||
|
||||
self.assertEqual(acceptance.overall_status(results), "fail")
|
||||
|
||||
def test_overall_status_passes_when_all_children_pass(self):
|
||||
results = [
|
||||
acceptance.ChildResult("systemd", "pass", 0, {"status": "pass"}),
|
||||
acceptance.ChildResult("kafka", "pass", 0, {"status": "pass"}),
|
||||
acceptance.ChildResult("http", "pass", 0, {"status": "pass"}),
|
||||
]
|
||||
|
||||
self.assertEqual(acceptance.overall_status(results), "pass")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user