f607ee7502
AvevaGatewayHistoryLiveGateTests boots the server in-process, wires the production Gateway backend (HistorianBackendRegistry -> GatewayHistorianDataSource) to a real HistorianGateway and drives HistoryRead over a real SDK session: raw (all, paged, reverse, bounds), modified, the ten served aggregates and seven refused ones, AtTime, events (all, 1-event pages, reverse), a missing tag, HistoryServerCapabilities and node metadata, and a HistoryUpdate that must be refused (sandbox-bound node only). Every wire answer is compared with the backend's direct answer; the run is dumped as JSON for cross-SDK and SQL comparison. Skips unless HISTGW_GATEWAY_ENDPOINT and HISTGW_GATEWAY_APIKEY are set; read-only by construction. scripts/validation/aveva-history-801: run/compare instructions, the SDK 1.5.378 baseline port patch (API spelling only), and the diff / SQL / aggregate / histgw-cli comparison scripts. Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
20 lines
1.5 KiB
Python
20 lines
1.5 KiB
Python
# Compares the gate's raw.all wire rows with HistorianGateway's own smoke CLI (`histgw-cli read-raw`, JSON lines),
|
|
# an independent gRPC client. Usage: hgcli_raw_check.py <aveva-gate-*.json> <dir with hgcli-*.jsonl>
|
|
import json, sys, glob, os
|
|
from datetime import datetime
|
|
rep = json.load(open(sys.argv[1]))
|
|
def ts(s): return datetime.fromisoformat(s.replace('Z', '+00:00').replace('0000000+', '+'))
|
|
for f in sorted(glob.glob(os.path.join(sys.argv[2], 'hgcli-*.jsonl'))):
|
|
rows = [json.loads(l) for l in open(f)]
|
|
tag, start = rows[0]['tag'], rows[0]['timestamp'][:19]
|
|
c = next(c for c in rep['Cases'] if c['Name'] == 'raw.all' and c['Path'] == 'wire' and c['Tag'] == tag and c['Window'].startswith(start))
|
|
w0, w1 = (ts(x) for x in c['Window'].split('/'))
|
|
# AVEVA's synthetic Quality-133 row at the query start is not a stored sample (#687); the gateway's end is inclusive,
|
|
# OtOpcUa's exclusive.
|
|
stored = [r for r in rows if not (r['quality'] == 133 and ts(r['timestamp']) == w0) and ts(r['timestamp']) < w1]
|
|
n = min(len(stored), len(c['Rows']))
|
|
ok = all(abs((ts(a['timestamp']) - ts(b['Src'])).total_seconds()) < 5e-4 and float(a['value']) == float(b['V'])
|
|
for a, b in zip(stored[:n], c['Rows'][:n]))
|
|
short = ' (histgw-cli stopped at the stored NULL: its JSON writer cannot emit NaN)' if len(stored) < len(c['Rows']) else ''
|
|
print(f"{tag:<16} {start} histgw-cli={len(stored)} wire={len(c['Rows'])} compared={n} {'MATCH' if ok else 'MISMATCH'}{short}")
|