144 lines
4.2 KiB
Python
Executable File
144 lines
4.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Send qvac.setEnabled over native messaging and fail on INVALID_VERSION."""
|
|
import json
|
|
import os
|
|
import struct
|
|
import subprocess
|
|
import sys
|
|
import threading
|
|
import time
|
|
|
|
|
|
def main():
|
|
binpath = sys.argv[1]
|
|
env = os.environ.copy()
|
|
env.setdefault('BRIDGE_SWARM_STORAGE', '/tmp/bs-qvac-packed-selftest')
|
|
proc = subprocess.Popen(
|
|
[binpath],
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
env=env,
|
|
)
|
|
err_chunks = []
|
|
|
|
def pump_err():
|
|
while True:
|
|
line = proc.stderr.readline()
|
|
if not line:
|
|
break
|
|
err_chunks.append(line)
|
|
sys.stderr.buffer.write(line)
|
|
sys.stderr.flush()
|
|
|
|
threading.Thread(target=pump_err, daemon=True).start()
|
|
time.sleep(1.5)
|
|
msg = json.dumps(
|
|
{
|
|
'id': 1,
|
|
'type': 'capability',
|
|
'payload': {
|
|
'pack': 'qvac',
|
|
'cmd': 'setEnabled',
|
|
'payload': {'enabled': True},
|
|
},
|
|
}
|
|
).encode()
|
|
proc.stdin.write(struct.pack('<I', len(msg)) + msg)
|
|
proc.stdin.flush()
|
|
hdr = proc.stdout.read(4)
|
|
if len(hdr) < 4:
|
|
print('FAIL: no native-messaging reply', file=sys.stderr)
|
|
stop_proc(proc)
|
|
return 1
|
|
n = struct.unpack('<I', hdr)[0]
|
|
body = proc.stdout.read(n).decode('utf-8', 'replace')
|
|
print('REPLY', body[:4000])
|
|
time.sleep(0.5)
|
|
stop_proc(proc)
|
|
blob = body + b''.join(err_chunks).decode('utf-8', 'replace')
|
|
if 'INVALID_VERSION' in blob:
|
|
print('FAIL: packed host still throws INVALID_VERSION', file=sys.stderr)
|
|
return 1
|
|
try:
|
|
reply = json.loads(body)
|
|
except json.JSONDecodeError:
|
|
print('FAIL: setEnabled reply is not JSON', file=sys.stderr)
|
|
return 1
|
|
payload = reply.get('payload') or reply
|
|
plugins = payload_plugins(payload)
|
|
audiogen = payload.get('audiogen') is True or 'audiogen' in plugins
|
|
if not audiogen:
|
|
print(
|
|
'FAIL: packed host did not bind AudioGen (plugins=%s audiogen=%s)%s'
|
|
% (plugins, payload.get('audiogen'), missing_native_hint(blob)),
|
|
file=sys.stderr,
|
|
)
|
|
return 1
|
|
diffusion = payload.get('diffusion') is True or 'diffusion' in plugins
|
|
if not diffusion:
|
|
print(
|
|
'FAIL: packed host did not bind diffusion (plugins=%s diffusion=%s)%s'
|
|
% (plugins, payload.get('diffusion'), missing_native_hint(blob)),
|
|
file=sys.stderr,
|
|
)
|
|
return 1
|
|
required = ('asr', 'tts', 'ocr', 'nmt', 'classification', 'bci', 'vla')
|
|
missing = [name for name in required if payload.get(name) is not True and name not in plugins]
|
|
if missing:
|
|
print(
|
|
'FAIL: packed host did not bind %s (plugins=%s)%s'
|
|
% (','.join(missing), plugins, missing_native_hint(blob)),
|
|
file=sys.stderr,
|
|
)
|
|
return 1
|
|
print('PASS: no INVALID_VERSION; QVAC plugins packed')
|
|
return 0
|
|
|
|
|
|
def stop_proc(proc):
|
|
try:
|
|
proc.kill()
|
|
except OSError:
|
|
pass
|
|
try:
|
|
proc.wait(timeout=2)
|
|
except (OSError, subprocess.TimeoutExpired):
|
|
pass
|
|
|
|
|
|
def vulkan_loader_ok():
|
|
if sys.platform != 'linux':
|
|
return True
|
|
candidates = (
|
|
'/usr/lib/x86_64-linux-gnu/libvulkan.so.1',
|
|
'/usr/lib/aarch64-linux-gnu/libvulkan.so.1',
|
|
'/usr/lib64/libvulkan.so.1',
|
|
'/usr/lib/libvulkan.so.1',
|
|
'/lib/x86_64-linux-gnu/libvulkan.so.1',
|
|
)
|
|
return any(os.path.exists(p) for p in candidates)
|
|
|
|
|
|
def missing_native_hint(body):
|
|
blob = body.lower()
|
|
if 'libvulkan.so.1' in blob or 'cannot open shared object file' in blob:
|
|
if not vulkan_loader_ok():
|
|
return (
|
|
' (libvulkan.so.1 is missing on this runner; '
|
|
'install libvulkan1 / vulkan-loader before the smoke test)'
|
|
)
|
|
return ' (native .bare failed to dlopen; see host stderr)'
|
|
return ''
|
|
|
|
|
|
def payload_plugins(payload):
|
|
raw = payload.get('plugins') if isinstance(payload, dict) else None
|
|
if isinstance(raw, list):
|
|
return [str(x) for x in raw]
|
|
return []
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|