Files
StarPilot/openpilot/starpilot/galaxy/tests/test_segment_summary_http.py
T
firestar5683 80fbb4f6db Feature registration
Register vehicle controls, planner modes, UI actions and Galaxy services after their providers exist. Wire the shared runtime entrypoints and cover their combined behavior.

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
Co-authored-by: Daniel Koepping <elkoled@gmail.com>
Co-authored-by: Danny <dannyirwin31@yahoo.com>
Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com>
Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com>
Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com>
Co-authored-by: Kacper Rączy <gfw.kra@gmail.com>
Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu>
Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com>
Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com>
Co-authored-by: stef <19478336+stefpi@users.noreply.github.com>
Co-authored-by: whoisdomi <dcantu83@gmail.com>

Co-authored-by: Intelli <contact@intelli.software>
Co-authored-by: haraschax <6804392+haraschax@users.noreply.github.com>
Co-authored-by: prabhaavp <prabhaav@msu.edu>
2026-10-14 20:02:39 -05:00

117 lines
5.2 KiB
Python

"""Authenticated local summary HTTP, including revocation during decode."""
import http.client
import json
from pathlib import Path
import tempfile
import threading
import unittest
from openpilot.starpilot.galaxy.access import GalaxyAccessOwner
from openpilot.starpilot.galaxy.drive_history import DriveHistory
from openpilot.starpilot.galaxy.segment_summary import SegmentSummary
from openpilot.starpilot.galaxy.server import make_server
from openpilot.starpilot.galaxy.tests.test_segment_summary import NAME, car, control, write
class SegmentSummaryHttpTest(unittest.TestCase):
def test_authenticated_real_serialized_summary_and_bad_selection(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
recordings = root / 'recordings'
recordings.mkdir()
write(recordings, [car(1_000_000_000, 10), control(1_000_000_000, True, False),
car(2_000_000_000, 10), control(2_000_000_000, False, True)])
access = GalaxyAccessOwner(root / 'access')
access.configure('password123', lambda: True)
server = make_server(port=0, owner=access, recordings=DriveHistory(recordings))
worker = threading.Thread(target=server.serve_forever, kwargs={'poll_interval': .01}, daemon=True)
worker.start()
def request(method, path, cookie=''):
conn = http.client.HTTPConnection('127.0.0.1', server.server_port, timeout=5)
headers = {'Cookie': cookie} if cookie else {}
if method == 'POST':
headers.update({'Content-Type': 'application/json', 'Origin': f'http://127.0.0.1:{server.server_port}'})
try:
payload = {'password': 'password123'} if path.endswith('/login') else {}
conn.request(method, path, json.dumps(payload) if method == 'POST' else None, headers)
response = conn.getresponse()
return response.status, response.read(), dict(response.getheaders())
finally:
conn.close()
path = f'/api/recordings/segment-summary?segmentName={NAME}'
try:
self.assertEqual(request('GET', path)[0], 401)
_, _, headers = request('POST', '/api/auth/login')
cookie = headers['Set-Cookie'].split(';', 1)[0]
status, body, _ = request('GET', path, cookie)
self.assertEqual(status, 200)
result = json.loads(body)
self.assertEqual(result['estimatedDistanceMeters'], 10)
self.assertEqual(result['observedLatActiveSeconds'], 1)
self.assertEqual(result['observedLongActiveSeconds'], 0)
self.assertEqual(request('GET', path + '&other=x', cookie)[0], 400)
self.assertEqual(request('GET', '/api/recordings/segment-summary?segmentName=../x', cookie)[0], 400)
logout = request('POST', '/api/auth/logout', cookie)
self.assertEqual(logout[0], 200, logout[1])
self.assertEqual(request('GET', path, cookie)[0], 401)
finally:
server.shutdown()
worker.join(2)
server.server_close()
def test_revoked_session_during_summary_sends_no_metrics(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
recordings = root / 'recordings'
recordings.mkdir()
write(recordings, [car(1_000_000_000, 10), car(2_000_000_000, 10)])
access = GalaxyAccessOwner(root / 'access')
access.configure('password123', lambda: True)
entered, release = threading.Event(), threading.Event()
class PausedSummary(SegmentSummary):
def snapshot(self, segment_name, *, permitted):
result = super().snapshot(segment_name, permitted=permitted)
entered.set()
release.wait(2)
return result
server = make_server(port=0, owner=access, recordings=DriveHistory(recordings),
segment_summary=PausedSummary(recordings))
worker = threading.Thread(target=server.serve_forever, kwargs={'poll_interval': .01}, daemon=True)
worker.start()
def request(path, cookie='', body=None):
conn = http.client.HTTPConnection('127.0.0.1', server.server_port, timeout=5)
method = 'POST' if body is not None else 'GET'
headers = {'Cookie': cookie} if cookie else {}
if body is not None:
headers.update({'Content-Type': 'application/json', 'Origin': f'http://127.0.0.1:{server.server_port}'})
try:
conn.request(method, path, json.dumps(body) if body is not None else None, headers)
response = conn.getresponse()
return response.status, response.read(), dict(response.getheaders())
finally:
conn.close()
try:
_, _, headers = request('/api/auth/login', body={'password': 'password123'})
cookie = headers['Set-Cookie'].split(';', 1)[0]
outcome = []
blocked = threading.Thread(target=lambda: outcome.append(request(f'/api/recordings/segment-summary?segmentName={NAME}', cookie)))
blocked.start()
self.assertTrue(entered.wait(2))
self.assertEqual(request('/api/auth/logout', cookie, {})[0], 200)
release.set()
blocked.join(3)
self.assertEqual(outcome[0][0], 401)
self.assertNotIn(b'estimatedDistanceMeters', outcome[0][1])
finally:
release.set()
server.shutdown()
worker.join(2)
server.server_close()