84 lines
4.3 KiB
Python
84 lines
4.3 KiB
Python
"""Verify current controld rejects GUI routing conflicts before invoking Cua."""
|
|
import http.client
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import time
|
|
|
|
assert os.environ.get('LAZYBOY_RUNNER_TEST_CONTAINER') == '1', 'disposable Computer only'
|
|
child = subprocess.Popen(['/usr/local/bin/lazyboy-controld'],
|
|
env={'PATH': '/usr/local/bin:/usr/bin:/bin', 'HOME': '/home/lazyboy',
|
|
'LAZYBOY_CONTROL_TOKEN': 'gui-target-fixture'}, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
try:
|
|
for _ in range(100):
|
|
assert child.poll() is None, 'fixture daemon failed to start'
|
|
try:
|
|
conn = http.client.HTTPConnection('127.0.0.1', 7070, timeout=2)
|
|
conn.request('GET', '/health')
|
|
response = conn.getresponse()
|
|
if response.status == 200:
|
|
conn.close()
|
|
break
|
|
except OSError:
|
|
time.sleep(.05)
|
|
finally:
|
|
conn.close()
|
|
else:
|
|
raise AssertionError('fixture startup deadline')
|
|
cases = 0
|
|
for route, initial in [
|
|
('act', {'actions': [], 'observe': False, 'settle_ms': 0}),
|
|
('browser', {'action': ''}),
|
|
('recording/start', {'skillId': 'fixture'}), ('recording/stop', {'skillId': 'fixture'}), ('recording/collect', {'skillId': 'fixture'}),
|
|
]:
|
|
for variant in ('display', 'profile', 'duplicate-display', 'duplicate-profile', 'slot'):
|
|
body = dict(initial)
|
|
body['display'] = ':2' if variant == 'display' else ':1'
|
|
body['profile_path' if route == 'act' else 'profilePath'] = '/profiles/b' if variant == 'profile' else '/profiles/a'
|
|
encoded = json.dumps(body).encode()
|
|
conn = http.client.HTTPConnection('127.0.0.1', 7070, timeout=5)
|
|
conn.putrequest('POST', '/' + route)
|
|
for name, value in [('Authorization', 'Bearer gui-target-fixture'), ('Content-Type', 'application/json'),
|
|
('Content-Length', str(len(encoded))), ('x-lazyboy-display', ':1'),
|
|
('x-lazyboy-profile', '/profiles/a'), ('x-lazyboy-screen-slot', '1' if variant == 'slot' else '0')]:
|
|
conn.putheader(name, value)
|
|
if variant.startswith('duplicate-'):
|
|
conn.putheader('x-lazyboy-' + variant.removeprefix('duplicate-'), ':1' if variant.endswith('display') else '/profiles/a')
|
|
conn.endheaders(encoded)
|
|
response = conn.getresponse()
|
|
raw = response.read()
|
|
conn.close()
|
|
assert response.status == 400, (route, variant, response.status, raw)
|
|
assert json.loads(raw) == {'ok': False, 'error': '400 Bad Request'}, (route, variant, raw)
|
|
cases += 1
|
|
for method, route in [('POST', '/observe'), ('GET', '/controller/health')]:
|
|
for variant in ('empty', 'invalid', 'remote', 'slot', 'duplicate-display', 'duplicate-profile', 'duplicate-slot'):
|
|
conn = http.client.HTTPConnection('127.0.0.1', 7070, timeout=5)
|
|
conn.putrequest(method, route)
|
|
conn.putheader('Authorization', 'Bearer gui-target-fixture')
|
|
conn.putheader('Content-Length', '0')
|
|
display = {'empty': '', 'invalid': ':99999', 'remote': 'remote:1'}.get(variant, ':1')
|
|
conn.putheader('x-lazyboy-display', display)
|
|
conn.putheader('x-lazyboy-profile', '/profiles/a')
|
|
conn.putheader('x-lazyboy-screen-slot', '1' if variant == 'slot' else '0')
|
|
if variant.startswith('duplicate-'):
|
|
name, value = {'duplicate-display': ('x-lazyboy-display', ':1'),
|
|
'duplicate-profile': ('x-lazyboy-profile', '/profiles/a'),
|
|
'duplicate-slot': ('x-lazyboy-screen-slot', '0')}[variant]
|
|
conn.putheader(name, value)
|
|
conn.endheaders()
|
|
response = conn.getresponse()
|
|
raw = response.read()
|
|
conn.close()
|
|
assert response.status == 400, (route, variant, response.status, raw)
|
|
assert json.loads(raw) == {'ok': False, 'error': '400 Bad Request'}, (route, variant, raw)
|
|
cases += 1
|
|
print(f'controld GUI target binding: {cases} rejected conflicts/duplicates')
|
|
finally:
|
|
child.terminate()
|
|
try:
|
|
child.wait(timeout=5)
|
|
except subprocess.TimeoutExpired:
|
|
child.kill()
|
|
child.wait()
|