The engine can hold a conversation but had no way to reach a relay. This is that: the §8 routes, both authentication modes, and the transparency log. 13 tests against a real HTTP server rather than a hand-written fake. That distinction is the point -- a fake written alongside the client agrees with it about everything including the field name it got wrong, which is exactly how this protocol's one shipped bug survived until a live round trip. Two more tests run against the deployed relay, opt-in via FN_LIVE_RELAY and silent when unset. A test that reaches the network cannot sit in a hermetic suite; it fails on an aeroplane and a suite that is red for unrelated reasons stops being read. What they check is the thing MockWebServer structurally cannot: that the URL this client builds is one relay.flamenet.io actually serves. It does, on both mounts, and the Kotlin engine verified an inclusion proof from the production log against a head fetched separately -- not against the root the proof response carried, because a server that supplies both halves of a comparison has proven nothing. Details that are load-bearing: The per-request signature covers the LOGICAL section-8 path, not the URL's. The relay mounts these routes twice and signs against the former, so signing the REST-prefixed path yields a valid signature over the wrong string and a refusal with no hint as to why. Tested by asserting the other one does NOT verify. The nonce is not decoration. Two inbox polls in the same second with the same empty body would otherwise produce identical signatures, and the relay's replay cache cannot tell an honest repeat from a captured one -- so it refuses the honest client and the app quietly stops receiving mail. Token minting is lazy, and a deployment with no token route is asked exactly once. Laziness cost an hour here: the tests hung, because takeRequest() blocks forever and I was waiting for a mint that had not happened yet. They now use a bounded read, so that mistake fails instead of looking like a hung build. Application passwords are stripped of spaces. The account service prints them in readable groups and users paste what they were shown; sending the spaces is a 401 nobody can diagnose, because the password on screen looks right. Kotlin nests block comments, so `/e2e/` followed by a star inside a doc comment opens one that never closes and the compiler blames the last line of the file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
41 lines
1.1 KiB
Kotlin
41 lines
1.1 KiB
Kotlin
// The relay transport.
|
|
//
|
|
// Plain Kotlin/JVM like `:engine`, and for the same reason: HTTP against a
|
|
// relay has nothing to do with Android, and keeping it off the platform means
|
|
// its tests run against a real local server on any machine, with no emulator.
|
|
// OkHttp works identically on both.
|
|
plugins {
|
|
kotlin("jvm")
|
|
}
|
|
|
|
repositories { mavenCentral() }
|
|
|
|
dependencies {
|
|
api(project(":engine"))
|
|
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
|
compileOnly("org.json:json:20240303")
|
|
|
|
testImplementation(kotlin("test"))
|
|
testImplementation("org.json:json:20240303")
|
|
// A real HTTP server, so the tests exercise headers, status codes and
|
|
// bodies rather than a hand-written fake that agrees with the client about
|
|
// everything including its mistakes.
|
|
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
|
|
}
|
|
|
|
kotlin {
|
|
compilerOptions {
|
|
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
|
|
}
|
|
}
|
|
|
|
java {
|
|
sourceCompatibility = JavaVersion.VERSION_17
|
|
targetCompatibility = JavaVersion.VERSION_17
|
|
}
|
|
|
|
tasks.test {
|
|
useJUnitPlatform()
|
|
testLogging { events("passed", "failed", "skipped") }
|
|
}
|