Files
StarPilot/openpilot/starpilot/galaxy/tests/test_monitor_feed.mjs
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

98 lines
3.7 KiB
JavaScript

import assert from "node:assert/strict"
import { readFile } from "node:fs/promises"
import { MonitorFeed } from "../web/js/monitor-feed.js"
const sample = JSON.parse(await readFile(new URL("../web/data/system-monitor.sample.json", import.meta.url)))
const local = { ...sample, mode: "local-runtime" }
const flush = async () => { for (let n = 0; n < 10; n++) await Promise.resolve() }
function fixture(mode = "local", ignoresAbort = false) {
let now = 0, id = 0
const timers = new Map(), requests = [], states = []
const feed = new MonitorFeed({ mode, publish: (state) => states.push(state), clock: () => now,
schedule: (fn, delay) => { const key = ++id; timers.set(key, { fn, time: now + delay }); return key },
cancel: (key) => timers.delete(key),
fetcher: (url, options) => new Promise((resolve, reject) => {
requests.push({ url, resolve, reject, signal: options.signal })
if (!ignoresAbort) options.signal.addEventListener("abort", () => reject(new Error("Aborted")))
}),
})
return { feed, requests, states, timers,
reply: async (raw = local, ok = true) => { requests.at(-1).resolve({ ok, json: async () => raw }); await flush() },
advance: async (ms) => {
now += ms
for (const [key, timer] of [...timers]) if (timer.time <= now && timers.delete(key)) timer.fn()
await flush()
},
}
}
// Real transport selection, first response, ordinary polling, no overlapping
// request and replacement of the old sample's deadline by the new one.
const live = fixture()
live.feed.start()
assert.equal(live.requests[0].url, "./api/system/monitor")
await live.reply()
assert.equal(live.states.at(-1).status, "current")
await live.advance(2000)
assert.equal(live.requests.length, 2)
live.feed.refresh()
assert.equal(live.requests.length, 2)
await live.reply()
await live.advance(2000)
assert.equal(live.states.at(-1).status, "current")
// Third request is outstanding; the previous sample expires at its original
// request-based deadline, rather than staying current until another reply.
await live.advance(2000)
assert.equal(live.states.at(-1).snapshot, null)
await live.advance(2000)
assert.equal(live.requests.at(-1).signal.aborted, true)
assert.equal(live.states.at(-1).status, "unavailable")
live.feed.stop()
assert.equal(live.timers.size, 0)
// A local source must never turn a synthetic sample into live state.
const wrong = fixture()
wrong.feed.start()
await wrong.reply(sample)
assert.equal(wrong.states.at(-1).snapshot, null)
wrong.feed.stop()
// Failed refresh drops previous values immediately, and unmount cancels work.
const failed = fixture()
failed.feed.start()
await failed.reply()
await failed.advance(2000)
await failed.reply({}, false)
assert.equal(failed.states.at(-1).snapshot, null)
await failed.advance(2000)
failed.feed.stop()
const before = failed.states.length
await failed.reply()
assert.equal(failed.states.length, before)
assert.equal(failed.timers.size, 0)
const preview = fixture("sample")
preview.feed.start()
assert.equal(preview.requests[0].url, "./data/system-monitor.sample.json")
await preview.reply(sample)
await preview.advance(20000)
assert.equal(preview.states.at(-1).status, "sample")
assert.equal(preview.requests.length, 1)
preview.feed.stop()
const stalled = fixture("local", true)
stalled.feed.start()
const abandoned = stalled.requests[0]
await stalled.advance(4000)
await stalled.advance(2000)
assert.equal(stalled.requests.length, 2)
await stalled.reply()
const count = stalled.states.length
abandoned.resolve({ ok: true, json: async () => local })
await flush()
assert.equal(stalled.states.length, count)
assert.equal(stalled.states.at(-1).status, "current")
stalled.feed.stop()
console.log("Monitor transport, source isolation, expiry, cancellation and failure checks passed")