aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-03 12:53:35 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-03 14:24:54 +0200
commitcf8345386996c561f176049b2f83fbd07956995e (patch)
treeda50f4f3329d519f06b8bf06483b15fa2ae9ca64 /packages/meshbay-android/app/src/test/kotlin/org/meshbay/client
parente7d663b76e58354d6a1b58f40624427d5ae660c8 (diff)
downloadmeshbay-cf8345386996c561f176049b2f83fbd07956995e.tar.gz
fix(android): the cast relay spools a receiver's lead to disk
Fragments are 5-10 MB at a film's bitrate; dropped past 8 MB in memory, the TV froze for their length. Each receiver now reads from its own spool file, deleted with it; nothing is dropped short of a disk bound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-android/app/src/test/kotlin/org/meshbay/client')
-rw-r--r--packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt31
1 files changed, 29 insertions, 2 deletions
diff --git a/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt b/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt
index e11c8c0..1c604d0 100644
--- a/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt
+++ b/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt
@@ -17,9 +17,10 @@ import java.net.Socket
/** The real relay on loopback, read with a raw socket: what a receiver sees. */
class CastRelayTest {
- private val relay = CastRelay { InetAddress.getByName("127.0.0.1") }
+ private val spool = java.nio.file.Files.createTempDirectory("relay-spool").toFile()
+ private val relay = CastRelay({ InetAddress.getByName("127.0.0.1") }, spool)
- @After fun stop() = relay.stop()
+ @After fun stop() { relay.stop(); spool.deleteRecursively() }
private class Reply(val status: Int, val headers: Map<String, String>, val body: ByteArray)
@@ -166,6 +167,32 @@ class CastRelayTest {
}
}
+ @Test fun `a receiver far behind loses nothing, and its spool goes with it`() {
+ // Fragments of 4 MB, ten of them pushed while the receiver has read
+ // none: far past the 8 MB the desktop drops at, which froze the TV.
+ val url = relay.start(null, null).getString("url")
+ val u = java.net.URI(url)
+ Socket(u.host, u.port).use { s ->
+ s.getOutputStream().write("GET ${u.rawPath}?${u.rawQuery} HTTP/1.1\r\nHost: x\r\n\r\n".toByteArray())
+ Thread.sleep(300)
+ val big = (0 until 10).map { box("moof", 16 + it) + box("mdat", 4 * 1024 * 1024 + it) }
+ big.forEach { relay.push(it) }
+ assertEquals("one spool file for the one receiver", 1, spool.listFiles()!!.size)
+ val input = DataInputStream(s.getInputStream())
+ while (true) { val l = StringBuilder(); while (true) { val c = input.read(); if (c == '\n'.code) break; l.append(c.toChar()) }; if (l.toString().trim().isEmpty()) break }
+ val body = ByteArrayOutputStream()
+ val want = big.sumOf { it.size }
+ while (body.size() < want) {
+ val size = StringBuilder().also { sb -> while (true) { val c = input.read(); if (c == '\n'.code) break; sb.append(c.toChar()) } }.toString().trim().toInt(16)
+ val buf = ByteArray(size); input.readFully(buf); body.write(buf); input.read(); input.read()
+ }
+ assertArrayEquals("every fragment, in order, none dropped", big.reduce { a, b -> a + b }, body.toByteArray())
+ }
+ Thread.sleep(300)
+ relay.stop()
+ assertEquals("the spool is deleted with the receiver", 0, spool.listFiles()!!.size)
+ }
+
@Test fun `stopping closes the port`() {
val url = relay.start(null, null).getString("url")
relay.stop()