Verify server receipt delivery through configurable UI tunnel
Test and deploy MQTT backend / test (push) Successful in 1m46s
Test and deploy MQTT backend / deploy (push) Successful in 13s

This commit is contained in:
2026-10-10 08:41:31 +03:30
parent 9a32f634d4
commit 55f11c9956
3 changed files with 145 additions and 5 deletions
+21 -5
View File
@@ -4,6 +4,7 @@ import ssl
import struct
import time
import urllib.request
import urllib.error
import uuid
from pathlib import Path
@@ -12,9 +13,13 @@ parser = argparse.ArgumentParser(description='Independent test-device/backend re
parser.add_argument('--credentials', required=True, help='Private JSON handoff or ESP32 connection.txt file')
parser.add_argument('--ca', required=True, help='Test broker public CA file')
parser.add_argument('--host', default='109.122.252.129')
parser.add_argument('--viewer-url', default='http://127.0.0.1:8080', help='Viewer base URL, including a private SSH tunnel port')
parser.add_argument('--viewer-wait', type=float, default=15, help='Bounded seconds to wait for exact UI event evidence')
parser.add_argument('--plaintext-port', type=int, default=1884)
parser.add_argument('--tls-port', type=int, default=8884)
args = parser.parse_args()
if args.viewer_wait <= 0 or args.viewer_wait > 60:
parser.error('--viewer-wait must be in (0, 60]')
HOST = args.host
private = Path(args.credentials).read_text()
if args.credentials.endswith('.json'):
@@ -116,14 +121,25 @@ def received(sock, version):
return body[position:].decode()
def viewer_has(topic, payload, kind):
until = time.monotonic() + 5
until = time.monotonic() + args.viewer_wait
unavailable = 0
while time.monotonic() < until:
with urllib.request.urlopen('http://127.0.0.1:8080/api/snapshot', timeout=3) as response:
snapshot = json.load(response)
remaining = until - time.monotonic()
if remaining <= 0:
break
try:
with urllib.request.urlopen(args.viewer_url.rstrip('/') + '/api/snapshot', timeout=min(5, remaining)) as response:
snapshot = json.load(response)
except (TimeoutError, urllib.error.URLError):
unavailable += 1
time.sleep(min(.1, max(0, until-time.monotonic())))
continue
if any(event.get('topic') == topic and event.get('kind') == kind and event.get('payload', {}).get('text', '') == payload for event in snapshot['events']):
if unavailable:
print('UI evidence confirmed after ' + str(unavailable) + ' transient HTTP failures')
return
time.sleep(0.1)
raise RuntimeError('broker delivered but viewer did not show ' + kind)
time.sleep(min(.1, max(0, until-time.monotonic())))
raise RuntimeError('exact UI evidence missing: ' + kind + '; HTTP failures=' + str(unavailable))
import hashlib