Verify server receipt delivery through configurable UI tunnel
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user