Beim Remote-Debugging eines iOS-Clients ist meist nicht der vollständige Verbindungsabbruch am schwersten zu reproduzieren, sondern eine Verbindung, die zwar noch funktioniert, aber nur sehr langsam reagiert: Der Verbindungsaufbau verzögert sich, die Upload-Geschwindigkeit sinkt und einzelne Anfragen gehen verloren. Dadurch kann es zu doppelten Übermittlungen, endlosen Wiederholungsversuchen oder dauerhaft wartenden Oberflächen kommen. Bei solchen Tests auf einem HexVM Cloud-Mac gilt daher als oberster Grundsatz: Nicht zuerst den Durchsatz begrenzen, sondern den Testverkehr der App vom Verwaltungsverkehr über SSH, VNC und ähnliche Dienste trennen. Andernfalls kann bereits eine zu weit gefasste Regel den eigenen Verwaltungszugang sperren.
Abnahmekriterien für schlechte Netzwerkbedingungen definieren
„Schlechtes Netzwerk“ ist keine geeignete Testbedingung. Sie lässt sich weder reproduzieren noch zur Beurteilung einer Fehlerbehebung heranziehen. Legen Sie stattdessen jedes Szenario anhand fester Parameter fest und definieren Sie vorab das erwartete Clientverhalten.
| Szenario | Download- und Upload-Limit | Zusätzliche Latenz | Paketverlust | Wichtigste Abnahmekriterien |
|---|---|---|---|---|
| Ausgangswert | Unbegrenzt | 0 ms | 0 | Normale Anfragedauer und Erfolgsquote |
| Hohe Latenz | 8 Mbit/s | 120 ms | 0 | Ladezustände, Abbruch und Zeitüberschreitungen |
| Geringe Bandbreite | 1 Mbit/s | 80 ms | 0 | Upload-Fortschritt und Wechsel in den Hintergrund |
| Instabile Verbindung | 4 Mbit/s | 100 ms | 2% | Obergrenze für Wiederholungen und idempotente Verarbeitung |
Diese Parameter sind Testeingaben und keine Beschreibung der Netzwerkqualität des Knotens. Das Team sollte die Werte an die Zeitüberschreitungen der Schnittstellen, die Dateigrößen und die von den Benutzern verwendeten Netze anpassen. Innerhalb eines Regressionslaufs müssen die Parameter jedoch unverändert bleiben.
Das Ziel eines Tests unter schlechten Netzwerkbedingungen besteht nicht darin, zu beweisen, dass eine Anfrage irgendwann doch noch erfolgreich ist. Entscheidend ist vielmehr, dass der Client bei einem Fehler das Warten rechtzeitig beendet, einen verständlichen Status anzeigt und keine doppelten Daten erzeugt.
Ausgangswerte ohne Drosselung erfassen
Erfassen Sie zunächst DNS-, Routing- und Antwortdaten der Schnittstelle, ohne Regeln zur Netzwerkdrosselung zu laden. Das Team sollte die Testschnittstelle selbst kontrollieren und einen Prüfpfad bereitstellen, der keine Produktionsdaten verändern kann.
export TEST_URL="https://test-endpoint.invalid/health"
scutil --dns | grep 'nameserver\[[0-9]*\]'
route -n get default
networkQuality
curl -sS -o /dev/null \
-w 'code=%{http_code} connect=%{time_connect} tls=%{time_appconnect} total=%{time_total}
' \
"$TEST_URL"
Ersetzen Sie die Beispieldomain durch eine echte, kontrollierte Testadresse. Erfassen Sie den Median aus mindestens drei Anfragen, statt nur das beste Ergebnis zu speichern. Treten bereits bei dieser Ausgangsmessung DNS-Fehler, Zertifikatsprobleme oder Routing-Störungen auf, müssen zunächst diese grundlegenden Ursachen behoben werden. Zusätzliche Wiederholungsversuche dürfen solche Probleme nicht verdecken.
Prüfen Sie außerdem, ob das Ziel über mehrere IP-Adressen bereitgestellt wird. Wird nur eine davon gedrosselt, kann die Namensauflösung eine Anfrage an eine andere Adresse weiterleiten. Dadurch liefert derselbe Test wechselnde Ergebnisse. Zuverlässiger ist ein fester Einstiegspunkt für die Abnahme unter schlechten Netzwerkbedingungen, dessen aufgelöste Adresse vor dem Testlauf gespeichert wird.
Nur den Verkehr der Zielschnittstelle drosseln
Unter macOS erstellt dnctl Pipes für Bandbreitenbegrenzung und Latenz, während pf den passenden Verkehr in diese Pipes leitet. Jede Regel muss gleichzeitig die Ziel-IP-Adresse, das Protokoll und den Port einschränken. Verwenden Sie keine Platzhalterbedingung, die sämtliche ausgehenden Verbindungen erfasst.
Das folgende Skript erstellt eine Test-Pipe mit 8 Mbit/s Bandbreite, 120 ms Latenz und 2% Paketverlust. Tragen Sie in TARGET_IP die feste Adresse der kontrollierten Schnittstelle ein.
set -euo pipefail
TARGET_IP="${TARGET_IP:?set TARGET_IP first}"
PIPE_ID=310
ANCHOR="com.apple/hexvm-nettest"
cleanup() {
sudo pfctl -a "$ANCHOR" -F all >/dev/null 2>&1 || true
sudo dnctl delete "$PIPE_ID" >/dev/null 2>&1 || true
}
trap cleanup EXIT INT TERM
sudo dnctl pipe "$PIPE_ID" config bw 8Mbit/s delay 120 plr 0.02
printf 'dummynet out quick proto tcp from any to %s port 443 pipe %s
' \
"$TARGET_IP" "$PIPE_ID" |
sudo pfctl -a "$ANCHOR" -f -
sudo pfctl -E >/dev/null
sudo pfctl -a "$ANCHOR" -sr -v
curl -sS -o /dev/null \
-w 'code=%{http_code} connect=%{time_connect} total=%{time_total}
' \
"$TEST_URL"
Prüfen Sie zunächst mit einem schreibgeschützten Health Check, ob die Regel greift. Führen Sie erst danach Geschäftstests aus, die Daten schreiben. Verwenden Sie pfctl -d nicht zur Bereinigung, da auf dem Rechner bereits andere Firewall-Regeln aktiv sein können. Das Skript leert ausschließlich seinen eigenen Anchor und löscht nur seine eigene Pipe, sodass parallele Aufgaben unbeeinträchtigt bleiben.
Remote-Verwaltungssitzung vor Fehlkonfigurationen schützen
Halten Sie vor der Ausführung ein zweites Verwaltungsterminal offen. Vergewissern Sie sich, dass die Regeln weder Verwaltungsports noch das Standard-Gateway oder beliebige Zieladressen erfassen. Nutzen Testziel und Verwaltungsverbindung dieselbe IP-Adresse, sollten Sie einen separaten Testzugang einrichten, statt sich auf die Reihenfolge der Regeln zu verlassen.
Clientverhalten als automatisierte Assertions prüfen
Bei der Abnahme unter schlechten Netzwerkbedingungen reicht es nicht aus zu prüfen, ob eine Anfrage irgendwann zurückkommt. Der Testcode sollte die Anzahl der Versuche, den endgültigen Fehlertyp, die gesamte Wartezeit und die Anfragekennung protokollieren. Für Schreiboperationen sollten Server und Client stabile Idempotenzschlüssel verwenden. Nach einer Zeitüberschreitung sollte der Client zunächst das Ergebnis abfragen und erst danach entscheiden, ob ein erneuter Versuch erforderlich ist.
Ergänzen Sie die Netzwerkschicht um eine beobachtbare Kapselung und prüfen Sie folgende Grenzen:
- Eine einzelne Verbindung lässt sich nach Überschreiten des Grenzwerts abbrechen, statt unbegrenzt zu warten.
- Die Anzahl der Wiederholungsversuche ist begrenzt und die Intervalle enthalten einen Backoff, sodass kein Anfragesturm entsteht.
- Nach einem Abbruch durch den Benutzer sendet keine Hintergrundaufgabe die Anfrage unbemerkt erneut.
- Ein unterbrochener Upload behält einen eindeutigen Status und wird nicht als abgeschlossen angezeigt.
- Nach Wiederherstellung der Verbindung kann der Vorgang fortgesetzt werden, ohne doppelte Datensätze anzulegen.
Simulatortests lassen sich mit einer expliziten Gerätekennung ausführen. Dadurch hängen sie nicht von einem Gerätenamen ab, der zufällig auf dem Rechner vorhanden ist.
export SIMULATOR_UDID="replace-with-booted-simulator-udid"
xcodebuild test \
-scheme NetworkBehaviorTests \
-destination "platform=iOS Simulator,id=${SIMULATOR_UDID}" \
-resultBundlePath build/NetworkBehavior.xcresult
Speichern Sie für jedes Netzwerkszenario ein separates Ergebnispaket und schreiben Sie die Szenarioparameter in das Testprotokoll. Ein Fehlerbericht kann dann beantworten, bei welcher Latenz und welchem Paketverlust der Fehler auftrat, statt lediglich einen nicht reproduzierbaren roten Status zu hinterlassen.
Regeln bereinigen und Regression abschließen
Das Skript führt die Bereinigung aus, wenn es regulär beendet wird oder ein Unterbrechungssignal empfängt. Nach einem unerwarteten Abbruch der Remote-Sitzung muss der Zustand dennoch manuell geprüft werden. Führen Sie nach der erneuten Verbindung folgende Befehle aus:
sudo pfctl -a com.apple/hexvm-nettest -sr
sudo dnctl list
curl -sS -o /dev/null \
-w 'code=%{http_code} connect=%{time_connect} total=%{time_total}
' \
"$TEST_URL"
Der dedizierte Anchor sollte leer sein, und in der Liste darf keine Pipe mit der Nummer 310 mehr erscheinen. Wiederholen Sie anschließend die Ausgangsmessung und prüfen Sie, ob Verbindungszeit und Gesamtdauer wieder im normalen Bereich vor dem Test liegen.
Führen Sie abschließend eine Regression ohne Netzwerkdrosselung durch. Prüfen Sie insbesondere, ob die Korrekturen für schlechte Netzwerkbedingungen unter normalen Bedingungen die Reihenfolge der Anfragen, Cache-Treffer oder Reaktionsfähigkeit der Oberfläche verändert haben. Speichern Sie Szenarioparameter, Clientversion, Version der Zielschnittstelle, Pfad zum Ergebnispaket und Resultat der Bereinigung in einem gemeinsamen Laufprotokoll. So wird aus einem einmaligen manuellen Test eine überprüfbare, reproduzierbare und sicher beendbare technische Testumgebung.
Häufig gestellte Fragen
Warum sollte nicht der gesamte ausgehende Verkehr gedrosselt werden?
Eine globale Regel erfasst auch SSH, VNC und Downloads. Dadurch kann die Verwaltungssitzung abbrechen. Sicherer ist eine Regel für IP-Adresse, Protokoll und Port des Testziels.
Wie lässt sich die vollständige Bereinigung der Regeln prüfen?
Zuerst wird der eigene pf-Anchor geleert, danach die zugehörige dnctl-Pipe gelöscht. Eine erneute Basismessung muss anschließend wieder normale Werte zeigen.
Welche Fehlerfälle sollte ein iOS-Client im schlechten Netz bestehen?
Zu prüfen sind begrenzte Wiederholungen, Zeitüberschreitungen, Abbruch, Offline-Hinweise, Schutz vor doppeltem Senden und eine saubere Wiederaufnahme.
Wählen Sie für Ihren nächsten Build einen exklusiven Cloud-Mac
Wählen Sie Mac-mini-Modell, Mietdauer und Region passend zu Ihrer Workload. Jede Bestellung entspricht einem eigenen physischen Knoten. Die tatsächliche Verfügbarkeit wird in Echtzeit über die Konsole angezeigt.