80 lines
4.2 KiB
Python
80 lines
4.2 KiB
Python
"""在同一个 sw9 快照上核对优化前后接口,涵盖分页/排序及统计偏好。"""
|
|
|
|
import argparse
|
|
import json
|
|
import urllib.parse
|
|
import urllib.request
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
from sw_database_rehearsal import connect, query
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--runtime", type=Path, required=True)
|
|
parser.add_argument("--before-url", default="http://127.0.0.1:19002")
|
|
parser.add_argument("--after-url", default="http://127.0.0.1:19004")
|
|
parser.add_argument("--output", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
if args.runtime.resolve().is_relative_to(Path(__file__).resolve().parents[1]):
|
|
raise ValueError("原始响应必须保存在仓库外")
|
|
config = yaml.safe_load((args.runtime / "config.yaml").read_text(encoding="utf-8"))["data"]["database"]
|
|
if config["name"] != "sw9":
|
|
raise ValueError("统计偏好测试仅允许 sw9")
|
|
folder = args.runtime / "parity"
|
|
folder.mkdir(exist_ok=True)
|
|
reports = []
|
|
|
|
def api(base, token, path, params=None, payload=None):
|
|
url = base + path + ("?" + urllib.parse.urlencode(params, doseq=True) if params else "")
|
|
request = urllib.request.Request(url, headers={"x-token": token, "Content-Type": "application/json"}, data=json.dumps(payload).encode() if payload is not None else None, method="PUT" if payload is not None else "GET")
|
|
with urllib.request.urlopen(request, timeout=300) as response:
|
|
data = json.load(response)
|
|
if data.get("code") != 0:
|
|
raise RuntimeError("接口请求失败:" + path)
|
|
return data["data"]
|
|
|
|
def compare(case, token, group):
|
|
values = [api(base, token, case["path"], case["params"]) for base in (args.before_url, args.after_url)]
|
|
name = group + "-" + case["name"]
|
|
(folder / (name + ".json")).write_text(json.dumps({"case": case, "before": values[0], "after": values[1]}, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
row = {"case": name, "passed": values[0] == values[1]}
|
|
reports.append(row)
|
|
args.output.write_text(json.dumps({"checks": reports, "passed": all(row["passed"] for row in reports)}, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
print(json.dumps(row), flush=True)
|
|
if not row["passed"]:
|
|
raise AssertionError("接口数据不一致:" + name)
|
|
|
|
admin = (args.runtime / "new-admin.token").read_text(encoding="utf-8").strip()
|
|
for case in json.loads((args.runtime / "parity-cases.json").read_text(encoding="utf-8")):
|
|
compare(case, admin, "admin")
|
|
|
|
token = (args.runtime / "new-level3.token").read_text(encoding="utf-8").strip()
|
|
user = api(args.before_url, token, "/user/getUserInfo")["userInfo"]["ID"]
|
|
original_preference = api(args.before_url, token, "/sw/user/preference")
|
|
cases = json.loads((args.runtime / "cases.json").read_text(encoding="utf-8"))
|
|
with connect(config) as db:
|
|
original = query(db, "SELECT * FROM sw9.sys_user_preference WHERE user_id=%s", (user,))
|
|
try:
|
|
for include, dedup in ((True, True), (True, False), (False, True), (False, False)):
|
|
api(args.before_url, token, "/sw/user/preference", payload={"includeSubPromote": include, "idcardDedup": dedup})
|
|
for case in cases:
|
|
compare(case, token, f"level3-sub{int(include)}-dedup{int(dedup)}")
|
|
finally:
|
|
try:
|
|
api(args.before_url, token, "/sw/user/preference", payload=original_preference)
|
|
finally:
|
|
# Restore the row even if the service stopped during verification.
|
|
if original:
|
|
row = original[0]
|
|
query(db, "UPDATE sw9.sys_user_preference SET include_sub_promote=%s,idcard_dedup=%s,update_time=%s WHERE user_id=%s", (row["include_sub_promote"], row["idcard_dedup"], row["update_time"], user))
|
|
else:
|
|
query(db, "DELETE FROM sw9.sys_user_preference WHERE user_id=%s", (user,))
|
|
assert query(db, "SELECT * FROM sw9.sys_user_preference WHERE user_id=%s", (user,)) == original
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|