wrolpi/etc
lrnselfreliance 91f92683ba
Speed Test calculator: ping, download, and upload against the API (#708)
* Speed Test calculator: ping, download, and upload against the API

Users asking whether the hotspot is fast enough, or how many people can
stream video at once, had no objective tool that works offline.  This
adds one under Calculators > Tools & Reference.

Backend (wrolpi/speedtest.py, /api/speedtest):
* ping: tiny no-store JSON the browser times for round trip latency.
* download: streams slices of a pre-built random buffer for a clamped
  number of seconds (0.1-15).  Random so no proxy or compression can
  flatter the result; slices so no bytes are generated per request.
* upload: streaming-body handler that reads and discards the body and
  reports bytes and elapsed time.  Requests over 8 MiB are refused.
* info: the client address Caddy forwarded plus how many tests are in
  flight.  Sanic now trusts one proxy hop (PROXIES_COUNT = 1) so
  request.remote_addr is the browser, not Caddy.  Nothing else read
  that field before.

There is deliberately no one-test-at-a-time lock.  Several people
testing at once is how a user learns how the link shares between
streamers, so the server only counts in-flight tests (a shared_ctx
Value created pre-fork so every worker sees the same number) and the
UI reports how many others ran alongside.

Both Caddyfiles route /api/speedtest/* unbuffered, as the SSE chat
route already is, so throughput is measured live rather than in bursts.

Frontend:
* speedtest.js holds the logic with no React in it (bucketed
  throughput, steady-state average that drops the first second, ping
  stats, stream-capacity tiers, hotspot address check) so Jest drives
  it with fake fetch and streams.
* SpeedTestCalculator runs 20 pings, a 10 s download, and a 10 s upload
  with a live figure and rolling trace, then shows Mbps and MB/s, ping
  verdict, the client address with a hotspot badge, and a table of how
  many 480p..4K streams the download speed supports.  Upload is
  sequential POSTs of one 4 MiB Blob because Safari cannot stream a
  request body.  Nothing is saved.
* Sparkline is a new inline-SVG ui component (no chart dependency),
  added to /theme-sample and checked in all four themes.  A missing
  sample is a gap, not a plunge to zero.

The page states that it measures the network path, not the drive that
actually serves video files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* speedtest: bound uploads in time, close the Start race, address review

Review on #708 found three bugs and some polish:

* Start could be clicked again while the first fetchInfo() was still
  pending, because the phase only left `idle` after that await.  A
  second click made a second AbortController and a second concurrent
  run, and Cancel only reached the later one.  start() now refuses when
  a controller already exists and enters a `starting` phase
  synchronously, so the button is Cancel before the first await.

* The upload phase could overrun the advertised 10 s by however long
  the in-flight 4 MiB POST took: on a slow hotspot, the very link this
  tool exists for, that is tens of seconds.  runUpload() now aborts the
  in-flight request at the phase deadline (counting only completed
  requests) and uses 1 MiB bodies so a few-Mbps link still completes
  several inside the phase.

* The server upload sink was capped by size only, so a slow or paused
  body could hold a worker until 8 MiB eventually arrived.  It now also
  enforces MAX_UPLOAD_SECONDS (15 s, matching download) and answers
  408 when exceeded.  Both caps together are what "cannot hold a
  worker" actually requires.

Also: a NaN `seconds` now gets a NaN message instead of "must not be
negative"; the module, Sparkline, and gallery docstrings are trimmed
to purpose; and the upload counter is covered for the mid-stream 413,
the 408, and a broken body.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 18:47:18 -06:00
..
raspberrypios Speed Test calculator: ping, download, and upload against the API (#708) 2026-09-13 18:47:18 -06:00
README.md Combining install scripts into a new repair script. Removing create_db script in favor of repair script. 2023-10-03 12:15:29 -06:00

Configuration Files

The files in etc are files necessary to build an on-the-metal WROLPi. Raspberry Pi has more config files because it is assumed to be the main OS. Debian uses the Raspberry Pi configs when possible.