Files
StarPilot/openpilot/starpilot/galaxy/test_starport_remote.py
T

90 lines
4.5 KiB
Python

from unittest.mock import Mock
import base64
import hashlib
import http.client
import json
import threading
from openpilot.starpilot.galaxy.access import GalaxyAccessOwner
from openpilot.starpilot.galaxy.starport_setup import StarPortSetup
from openpilot.starpilot.galaxy.remote import RemotePairing, gateway_cookie_valid
from openpilot.starpilot.galaxy.server import make_remote_server, make_server
from openpilot.starpilot.galaxy.test_starport_http import FakeImport
from openpilot.starpilot.system.starport.source_verifier import StarPortSourceVerifier
def test_remote_binary_upload_and_pairing_use_existing_gateway_session(tmp_path):
access = GalaxyAccessOwner(tmp_path / 'access')
pairing = RemotePairing(tmp_path / 'pairing')
assert access.configure('password123', lambda: True)
slug = pairing.pair(hashlib.sha256(b'password123').hexdigest())
assert slug is not None
record = pairing.read()
assert record is not None
cookie = 'galaxy_session=' + base64.urlsafe_b64encode(json.dumps({slug: record['session']}).encode()).decode().rstrip('=')
state = {'parked': True}
job = FakeImport(tmp_path / 'imports')
def session_valid(identity: tuple) -> bool:
current = pairing.read()
return bool(identity) and current is not None and gateway_cookie_valid(identity[0], current)
setup = StarPortSetup(parked=lambda: state['parked'], enabled=lambda: True,
session_valid=session_valid, import_job=Mock(wraps=job, work_dir=job.work_dir), identity_status=lambda: {'installed': True},
bluetooth_enabled=lambda: True, install_ready=lambda: True, service_ready=lambda: True)
class Client:
source = None
def call(self, command, **kwargs):
if command != 'status':
self.source = kwargs['source']
assert verifier.valid(self.source)
return {'status': {'receiver_address': '', 'running': False}} if command == 'status' else {}
client = Client()
local = make_server(port=0, owner=access, remote_pairing=pairing, parked=lambda: state['parked'],
starport_setup=setup, starport_client=client)
remote = make_remote_server(local, port=0)
verifier = StarPortSourceVerifier(port=local.server_port)
threads = []
for server in (local, remote):
worker = threading.Thread(target=server.serve_forever, kwargs={'poll_interval': .01}, daemon=True)
worker.start()
threads.append(worker)
def request(path, body=None, *, auth=cookie, origin='https://galaxy.firestar.link', content_type='application/octet-stream'):
conn = http.client.HTTPConnection('127.0.0.1', remote.server_port, timeout=10)
headers = {'Host': f'{slug}.devices.local', 'Cookie': auth, 'Origin': origin, 'Content-Type': content_type}
try:
conn.request('POST' if body is not None else 'GET', '/' + slug + path, body, headers)
response = conn.getresponse()
return response.status, json.loads(response.read())
finally:
conn.close()
try:
assert request('/api/starport/setup', auth='')[0] == 401
assert request('/api/starport/setup')[0] == 200
assert request('/api/starport/upload', b'abc', origin='https://example.com')[0] == 403
assert request('/api/starport/upload', b'abc', content_type='application/json')[0] == 415
body = b'APK\x00\xff' * (20 * 1024 * 1024 // 5)
assert request('/api/starport/upload', body)[0] == 202
assert len(job.calls) == 1 and job.calls[0][0] == body
job.running = False
assert request('/api/starport/pairing', b'{}', content_type='application/json')[0] == 200
assert client.source and verifier.valid(client.source)
# Pairing material is daemon-only even through the authenticated remote listener.
assert request('/api/starport/source/' + client.source)[0] == 403
state['parked'] = False
# Package admission is session-only in either road state; pairing remains parked-only.
assert job.calls[0][1]() is True
assert request('/api/starport/pairing', b'{}', content_type='application/json')[0] == 403
assert request('/api/starport/upload', b'retry')[0] == 202
assert len(job.calls) == 2 and job.calls[1][0] == b'retry'
assert job.calls[1][1]() is True
state['parked'] = True
pairing.unpair()
assert not verifier.valid(client.source)
assert request('/api/starport/upload', b'retry')[0] in (401, 403)
assert len(job.calls) == 2
assert all(admission() is False for _, admission in job.calls)
finally:
for server, worker in zip((remote, local), reversed(threads), strict=True):
server.shutdown()
worker.join(timeout=2)
server.server_close()