Drei Fehler aus dem ersten Praxistest
Anmelde-Adresse wurde doppelt kodiert URLComponents.fragment kodiert beim Setzen erneut, aus %5B wurde %255B. Plex antwortete mit „Diese Anfrage konnte nicht abgeschlossen werden". Die Adresse wird jetzt von Hand zusammengesetzt. Verbindungssuche hing bis zu anderthalb Minuten probeTimeout war deklariert, aber nirgends angewendet — es galt der URLSession-Standard von 60 Sekunden. Zusammen mit der Prüfung Rang für Rang kostete eine schweigende lokale Adresse die volle Zeit, bevor der direkte Weg überhaupt begann. Jetzt laufen alle Adressen gleichzeitig, mit Zeitgrenze, und die Rangordnung entscheidet unter den erreichbaren. Kein Zurück während des Ladens Die Kopfzeile mit dem Schließen-Knopf wurde nur im Zustand .playing gezeichnet. Bei langsamer Verbindung saß man ohne Ausweg vor einem Ladekreis. Sie liegt jetzt als eigene Ebene darüber und erscheint auch beim Vorbereiten — samt Titel, damit erkennbar bleibt, worauf gewartet wird. Sechs neue Tests, darunter drei, die die Zeitgrenze der Verbindungssuche an einer schweigenden Adresse nachstellen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -165,3 +165,93 @@ struct ServerDirectoryTests {
|
||||
#expect(shared.accessToken != "konto-token")
|
||||
}
|
||||
}
|
||||
|
||||
@Suite("Verbindungsauswahl unter Zeitdruck")
|
||||
struct ConnectionSelectorTimeoutTests {
|
||||
private let serverID = "server-abc-123"
|
||||
|
||||
private func identityResponse(_ machineIdentifier: String) -> String {
|
||||
#"{"MediaContainer":{"machineIdentifier":"\#(machineIdentifier)","version":"1.42.0"}}"#
|
||||
}
|
||||
|
||||
private var resource: PlexResource {
|
||||
PlexResource(
|
||||
name: "Wohnzimmer",
|
||||
clientIdentifier: serverID,
|
||||
accessToken: "server-token",
|
||||
connections: [
|
||||
PlexConnection(uri: "http://192.168.1.10:32400", local: true),
|
||||
PlexConnection(uri: "https://1-2-3-4.abc.plex.direct:32400"),
|
||||
PlexConnection(uri: "https://relay.plex.direct:443", relay: true),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
@Test("Eine schweigende lokale Adresse blockiert die Anmeldung nicht", .timeLimit(.minutes(1)))
|
||||
func hangingLocalDoesNotBlock() async {
|
||||
// Der Fehler aus der Praxis: die Ränge wurden nacheinander geprüft,
|
||||
// also kostete eine schweigende lokale Adresse erst die volle
|
||||
// Zeitgrenze, bevor der direkte Weg überhaupt begann. Ergebnis war
|
||||
// eine Anmeldung, die anderthalb Minuten hing.
|
||||
let transport = FakeTransport.hosts(
|
||||
answering: [
|
||||
"1-2-3-4.abc.plex.direct": identityResponse(serverID),
|
||||
"relay.plex.direct": identityResponse(serverID),
|
||||
],
|
||||
hanging: ["192.168.1.10"]
|
||||
)
|
||||
let selector = PlexConnectionSelector(
|
||||
identity: .test,
|
||||
transport: transport,
|
||||
probeTimeout: .milliseconds(200)
|
||||
)
|
||||
|
||||
let started = ContinuousClock.now
|
||||
let chosen = await selector.selectConnection(for: resource)
|
||||
let elapsed = ContinuousClock.now - started
|
||||
|
||||
// Der direkte Weg gewinnt, weil lokal nicht antwortet.
|
||||
#expect(chosen?.uri == "https://1-2-3-4.abc.plex.direct:32400")
|
||||
// Und zwar in der Größenordnung der Zeitgrenze, nicht in deren
|
||||
// Vielfachem.
|
||||
#expect(elapsed < .seconds(2), "dauerte \(elapsed)")
|
||||
}
|
||||
|
||||
@Test("Die Vermittlung kommt nur zum Zug, wenn sonst nichts geht", .timeLimit(.minutes(1)))
|
||||
func relayOnlyWhenNothingElseAnswers() async {
|
||||
let transport = FakeTransport.hosts(
|
||||
answering: ["relay.plex.direct": identityResponse(serverID)],
|
||||
hanging: ["192.168.1.10"]
|
||||
)
|
||||
let selector = PlexConnectionSelector(
|
||||
identity: .test,
|
||||
transport: transport,
|
||||
probeTimeout: .milliseconds(200)
|
||||
)
|
||||
|
||||
let chosen = await selector.selectConnection(for: resource)
|
||||
#expect(chosen?.relay == true)
|
||||
}
|
||||
|
||||
@Test("Eine erreichbare lokale Adresse gewinnt sofort", .timeLimit(.minutes(1)))
|
||||
func reachableLocalWinsImmediately() async {
|
||||
// Hier hängen die beiden anderen. Würde die Auswahl auf alle Antworten
|
||||
// warten, bevor sie entscheidet, wäre auch der gute Fall langsam.
|
||||
let transport = FakeTransport.hosts(
|
||||
answering: ["192.168.1.10": identityResponse(serverID)],
|
||||
hanging: ["1-2-3-4.abc.plex.direct", "relay.plex.direct"]
|
||||
)
|
||||
let selector = PlexConnectionSelector(
|
||||
identity: .test,
|
||||
transport: transport,
|
||||
probeTimeout: .seconds(30)
|
||||
)
|
||||
|
||||
let started = ContinuousClock.now
|
||||
let chosen = await selector.selectConnection(for: resource)
|
||||
let elapsed = ContinuousClock.now - started
|
||||
|
||||
#expect(chosen?.local == true)
|
||||
#expect(elapsed < .seconds(2), "dauerte \(elapsed)")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user