fix: prevent tdengine raw frame overwrite
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
lingniu
2026-06-29 18:41:58 +08:00
parent 5c1c61f29b
commit 8804c01d99
9 changed files with 422 additions and 6 deletions

View File

@@ -6,6 +6,7 @@ from __future__ import annotations
import argparse
import datetime as dt
import json
import os
import pathlib
import socket
import time
@@ -14,6 +15,11 @@ import urllib.request
from dataclasses import dataclass
from typing import Any
try:
from tools import tdengine_smoke
except ModuleNotFoundError:
import tdengine_smoke
SHANGHAI = dt.timezone(dt.timedelta(hours=8))
DEFAULT_SAMPLE = (
@@ -144,6 +150,25 @@ def wait_for_fields(
return last_items
def wait_for_tdengine_raw_frames(
rest_url: str,
username: str,
password: str,
sql: str,
minimum: int,
timeout_seconds: float,
request_timeout: float,
) -> int:
deadline = time.monotonic() + timeout_seconds
last_count = 0
while time.monotonic() < deadline:
last_count = tdengine_smoke.query_count(rest_url, username, password, sql, request_timeout)
if last_count >= minimum:
return last_count
time.sleep(1)
return last_count
def parse_field_keys(value: str) -> list[str]:
return [item.strip() for item in value.split(",") if item.strip()]
@@ -172,6 +197,50 @@ def check_archive(root: pathlib.Path, records: list[dict[str, Any]], limit: int)
return checked
def raw_frame_count_sql(info: FrameInfo, records: list[dict[str, Any]]) -> str:
sqls = raw_frame_count_sqls(info, records)
if not sqls:
raise ValueError("no raw archive uri found in gb32960 records")
return sqls[0]
def raw_frame_count_sqls(info: FrameInfo, records: list[dict[str, Any]]) -> list[str]:
seen: set[str] = set()
sqls: list[str] = []
for record in records:
uri = record.get("rawArchiveUri") or ""
if not uri or uri in seen:
continue
seen.add(uri)
sqls.append(tdengine_smoke.raw_frame_count_sql(
protocol="GB32960",
vehicle_key=info.vin,
vin=info.vin,
raw_uri=uri,
))
return sqls
def verify_tdengine_raw_frames(
rest_url: str,
username: str,
password: str,
sqls: list[str],
timeout_seconds: float,
request_timeout: float,
) -> int:
if not sqls:
raise RuntimeError("no raw archive uri available for tdengine raw_frames verification")
verified = 0
for sql in sqls:
count = wait_for_tdengine_raw_frames(
rest_url, username, password, sql, 1, timeout_seconds, request_timeout)
if count < 1:
raise RuntimeError(f"tdengine raw_frames row not visible for query: {sql}")
verified += 1
return verified
def run(args: argparse.Namespace) -> dict[str, Any]:
frame = read_hex_frame(pathlib.Path(args.frame_hex_file))
info = parse_frame_info(frame)
@@ -212,6 +281,17 @@ def run(args: argparse.Namespace) -> dict[str, Any]:
if args.archive_root:
archive_checked = check_archive(pathlib.Path(args.archive_root), records, args.archive_check_limit)
tdengine_raw_frames = None
if args.tdengine_rest_url:
tdengine_raw_frames = verify_tdengine_raw_frames(
args.tdengine_rest_url,
args.tdengine_username,
args.tdengine_password,
raw_frame_count_sqls(info, records),
args.history_timeout,
args.http_timeout,
)
return {
"tcpHost": args.tcp_host,
"tcpPort": args.tcp_port,
@@ -221,6 +301,7 @@ def run(args: argparse.Namespace) -> dict[str, Any]:
"ackBytesHex": ack.hex(),
"records": len(records),
"fieldCounts": field_counts,
"tdengineRawFrames": tdengine_raw_frames,
"archiveChecked": archive_checked,
"firstRawUri": first_raw_uri(records),
}
@@ -245,6 +326,9 @@ def parser() -> argparse.ArgumentParser:
p.add_argument("--expect-record-count", type=int, default=1)
p.add_argument("--archive-root", default="")
p.add_argument("--archive-check-limit", type=int, default=1)
p.add_argument("--tdengine-rest-url", default=os.environ.get("TDENGINE_REST_URL", ""))
p.add_argument("--tdengine-username", default=os.environ.get("TDENGINE_USERNAME", "root"))
p.add_argument("--tdengine-password", default=os.environ.get("TDENGINE_PASSWORD", "taosdata"))
p.add_argument("--require-ack", action="store_true", default=True)
p.add_argument("--tcp-timeout", type=float, default=5)
p.add_argument("--http-timeout", type=float, default=5)