69 lines
3.6 KiB
Python
69 lines
3.6 KiB
Python
"""只读验证运行实例的商务画像、缺数据处理与参数校验。"""
|
|
|
|
import argparse
|
|
import json
|
|
import urllib.parse
|
|
import urllib.request
|
|
from pathlib import Path
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--base-url", default="http://127.0.0.1:18000")
|
|
parser.add_argument("--token-file", required=True, type=Path)
|
|
parser.add_argument("--output", required=True, type=Path)
|
|
args = parser.parse_args()
|
|
token = args.token_file.read_text(encoding="utf-8").strip()
|
|
checks = []
|
|
|
|
def get(path, expected=0):
|
|
request = urllib.request.Request(args.base_url + path, headers={"x-token": token})
|
|
with urllib.request.urlopen(request, timeout=30) as response:
|
|
payload = json.load(response)
|
|
check = {"path": path, "http": response.status, "code": payload.get("code"),
|
|
"msg": payload.get("msg"), "passed": response.status == 200 and payload.get("code") == expected}
|
|
data = payload.get("data", {})
|
|
if isinstance(data, dict) and "basic" in data:
|
|
check.update(available=data.get("available"), promote_count=data["basic"].get("promoteCount"),
|
|
register_points=len(data.get("registerTrend", [])), pay_points=len(data.get("payTrend", [])))
|
|
checks.append(check)
|
|
return data
|
|
|
|
accounts = get("/sw/business/list?pageNum=1&pageSize=500")["rows"]
|
|
|
|
def bound_subtree(account):
|
|
prefix = f"{account.get('idPath') or '0'},{account['userId']}"
|
|
ids = [account]
|
|
if int(account.get("level") or 0) < 3:
|
|
ids += [row for row in accounts if row["userId"] != account["userId"] and
|
|
(row.get("parentId") == account["userId"] or row.get("idPath") == prefix or
|
|
str(row.get("idPath") or "").startswith(prefix + ","))]
|
|
return sum(row.get("bindCount") or 0 for row in ids)
|
|
|
|
empty = next((row for row in accounts if bound_subtree(row) == 0), None)
|
|
bound = next((row for row in accounts if bound_subtree(row) > 0), None)
|
|
if empty:
|
|
data = get(f"/sw/business/{empty['userId']}/portrait?sourceDbList=lx,hw,yq&period=today")
|
|
checks[-1]["passed"] &= data.get("available") is True and data.get("metrics", {}).get("register", {}).get("value") == "0" and len(data.get("registerTrend", [])) == 24
|
|
data = get(f"/sw/business/{empty['userId']}/portrait?sourceDbList=lx&period=thisMonth")
|
|
checks[-1]["passed"] &= data.get("period") == "thismonth" and 1 <= len(data.get("registerTrend", [])) <= 31
|
|
if bound:
|
|
data = get(f"/sw/business/{bound['userId']}/portrait?sourceDbList=lx,hw,yq&period=last7")
|
|
if data.get("available") is False:
|
|
checks[-1]["passed"] &= data.get("metrics") is None and bool(data.get("unavailableReason"))
|
|
else:
|
|
checks[-1]["passed"] &= len(data.get("registerTrend", [])) == 7
|
|
if accounts:
|
|
get(f"/sw/business/{accounts[0]['userId']}/portrait", expected=7)
|
|
get("/sw/business/bindPlatform/portrait?sourceDb=lx&platformBusierId=0", expected=7)
|
|
report = {"scope": "真实 sw7 登录会话,只读请求;有绑定但业务表未接入时不伪造零,无绑定时验证真实空画像。完整指标和 SDK 基本信息通过隔离双库 TCP HTTP 测试。",
|
|
"checks": checks, "passed": all(check["passed"] for check in checks)}
|
|
args.output.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
print(json.dumps(report, ensure_ascii=False))
|
|
if not report["passed"]:
|
|
raise SystemExit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|