xcodebuild mit Timeout oder I/O-Stalls endet. Eine belastbare Entscheidungsmatrix verbindet Schalter wie -parallel-testing-enabled, die erlaubte Destination-Anzahl und ein hartes Simulator-Budget mit Buildsperre, Pfadlayout und dokumentierten Bereinigungsschwellen für 1TB- und 2TB-SSDs.
Dieser Text ergänzt die Orchestrierungssicht aus Nomad-Affinität, Buildsperre & 1TB/2TB-Matrix, die I/O- und Watchman-Leitplanken in Watchman, FSEvents und Disk-Abnahme sowie die WAL-/Freigaben-Matrix in SQLite WAL auf gemeinsamen Volumes, falls Tests Datenbanken oder Artefakte auf Netzwerk-Freigaben anfassen. Ziel ist eine reproduzierbare Abnahme — nicht maximale Parallelität um jeden Preis.
Parallel Testing: Parameter- und Simulator-Budget-Matrix
Die folgende Tabelle fasst die wichtigsten Hebel für xcodebuild test bzw. xcodebuild build-for-testing zusammen. Werte sind Startpunkte für Mehrregionen-Setups; kalibrieren Sie sie anhand realer XCTest-Laufzeiten, CoreSimulator-Footprints und Ihrer Derived-Data-Retention.
| Steuergröße | Empfohlene Ausprägung (M4, 24–64 GB) | Risiko bei Überschreitung |
|---|---|---|
-parallel-testing-enabled |
YES nur, wenn jede Destination isolierten Simulator- und Cache-Raum hat; sonst NO und Parallelität über mehrere Knoten statt innerhalb eines Laufs | Flaky Tests, Race auf gemeinsamen Fixtures, schwer nachvollziehbare Timeouts |
Destination-Anzahl (-destination …) |
1–2 pro Job auf 1TB-Knoten mit UI-Tests; bis 3–4 auf 2TB, wenn keine großen Medien-Assets im Bundle liegen | RAM-Druck durch parallele Runner; Speicherfresser durch parallele CoreSimulator-Instanzen |
| Simulator-Konkurrenz (max. gleichzeitig bootete Geräte / Runner) | Hard-Cap z. B. 2 (1TB) bzw. 3–4 (2TB) pro Host; Queue im CI statt implizitem Oversubscribe | Unable to boot simulator, erhöhte APFS-Fragmentierung, I/O-Warteschlangen |
Koppeln Sie die Tabelle mit einem einfachen Laufzeit-Contract: Wenn die mittlere Testpipeline länger als Ihr SLO wird, senken Sie zuerst die Destination-Anzahl oder das Simulator-Budget, bevor Sie -parallel-testing-enabled weiter aufblasen. Horizontal skalieren (zweiter M4 in einer anderen Region) entkoppelt thermische und Speicher-Spitzen oft sauberer als ein einzelner „Monster-Job“.
Verwechseln Sie Parallel Testing nicht mit -parallelizeTargets oder reinem Build-Parallelismus: Tests starten zusätzliche Prozesse, Simulatoren und Log-Ströme. In der Queue-Metrik sollte daher neben CPU-Auslastung immer scheibenbezogene Latenz (P95 I/O-Wartezeit, freier Speicher, Simulator-Boot-Zeit) stehen — sonst optimieren Sie den falschen Engpass und kaufen sich nur mehr Flakiness ein.
Buildsperre
Parallel Testing ändert nichts daran, dass ein Writer pro gemeinsam genutztem Arbeitsbaum gelten sollte. Kombinieren Sie Scheduler-Constraints aus Ihrer Orchestrierungsschicht (z. B. Affinität und distinct_hosts wie im oben verlinkten Nomad-Leitfaden skizziert) mit einer expliziten flock-Umkreisung um xcodebuild, wenn mehrere Jobs dasselbe Checkout oder dieselbe Promotion-Stufe anfassen könnten.
Legen Sie die Sperrdatei auf einem persistenten Pfad ab (nicht unter /tmp, der nach Neustarts leer sein kann) und pro Repository-Instanz, nicht global pro Host — so blockieren sich nur konfliktierende Pipelines, nicht unabhängige Projekte.
flock -n /var/db/ci/locks/myproject.lock \ xcodebuild -scheme "App" -workspace App.xcworkspace \ -parallel-testing-enabled YES \ -destination "platform=iOS Simulator,name=iPhone 16" \ -destination "platform=iOS Simulator,name=iPhone 16 Pro" \ test
Testen Sie die Buildsperre absichtlich mit zwei gleichzeitigen Jobs auf demselben Tree: Einer muss deterministisch warten oder mit klarem Exit scheitern (flock -n). Ohne diese Abnahme ist „Parallel Testing an“ nur ein Schalter, kein Sicherheitsmodell.
Derived-Data-Pfad
Setzen Sie -derivedDataPath bewusst — idealerweise auf einem schnellen lokalen APFS-Volume pro Mac mini M4, nicht auf WAN-gemounteten Freigaben, sofern Sie nicht die WAL-/Freigaben-Regeln aus dem SQLite-Artikel exakt einhalten. Ein stabiler Pfad wie /var/tmp/ci/DerivedData/<job-id> erleichtert Retention und automatisches Aufräumen nach dem Lauf.
Trennen Sie globalen Xcode-Cache und job-spezifisches Derived Data logisch (z. B. unterschiedliche Unterverzeichnisse oder Symlinks), damit parallele Jobs nicht still in denselben Modul-Cache schreiben. Dokumentieren Sie die Variable im CI-Manifest und spiegeln Sie sie in Monitoring-Tags, damit Speicher-Alerts dem richtigen Team zugeordnet werden.
Wenn mehrere Regionen dieselbe Derived-Data-Quelle lesen müssen, bevorzugen Sie read-only-Mounts plus explizite Promotion eines einzigen Schreibers — nicht zwei gleichberechtigte Schreibpfade, die APFS-Metadaten oder Netzwerk-Locks im Streit lassen.
Datenträger-Bereinigungsschwellen
Parallel Testing multipliziert CoreSimulator-Daten, Logs und Zwischenarchive. Die folgenden Wasserstände sind pragmatische Abnahme-Grenzen für dedizierte CI-Knoten; passen Sie sie an Ihre Retention und an die Fan-out-Breite Ihrer Artefakte an.
Planen Sie gezielte Bereinigungsfenster ein, statt nur auf df-Alarme zu reagieren: ein Cron- oder Nomad-Task kann verwaiste Simulator-UDIDs, alte *.xcresult-Bundles und job-lokales Derived Data nach TTL löschen, ohne laufende Locks zu verletzen. APFS-Snapshots für Diagnose sind hilfreich — aber jeder Snapshot kostet differenziell Speicher; dokumentieren Sie, wer Snapshots anlegt und wann sie wieder verschwinden.
| SSD-Profil | Warnschwelle (frei, gleitend 24h) | Maßnahme / Scheduling |
|---|---|---|
| 1TB | < ca. 220 GB frei | Keine zusätzlichen parallelen Simulator-Stacks; Cleanup-Job für Derived Data & CoreSimulator-Caches; ggf. zweiten Knoten aktivieren |
| 2TB | < ca. 380 GB frei | Destination-Anzahl senken; alte Xcode-Archives rotieren; große Medien-Fixtures aus dem parallelen Pfad auslagern |
Abnahme-Checkliste 1TB / 2TB (kurz)
- Preflight: Freier Speicher über Schwellwert; kein anderer Job mit gleichem
derivedDataPathohne Sperre. - Simulator-Budget: Maximal erlaubte gleichzeitige Geräte pro Host in CI-Config und Monitoring gespiegelt.
- Destination-Matrix: Tabelle (oben) für 1TB vs. 2TB signiert; Änderungen nur per Review.
- Post-Run: Automatisches Prunen von Job-
DerivedDataund optionalxcrun simctl delete unavailablein Wartungsfenstern. - Eskalation: Dreimalige Warnstufe innerhalb eines Sprints → zusätzlicher M4-Knoten oder Umstieg auf 2TB-Pool, statt Schwellen nur zu erhöhen.
Wenn Sie diese Matrix produktiv ausrollen möchten, bestellen Sie passende Mac mini M4-Instanzen direkt über die öffentliche Kaufseite — ohne Account-Zwang — und gleichen Sie Disk- und Regionwahl mit den Tabellen oben ab; bei Fragen zur Konfiguration helfen Ihnen die verlinkten Tiefgang-Artikel und die Preisübersicht bei der Kalkulation zusätzlicher Testknoten.
xcodebuild-Schalter variieren je nach installierter Version; die Schwellen sind Richtwerte für APFS auf dedizierten M4-Build-Hosts, keine Garantien. Passen Sie Caps an Ihre App-Größe und Testtiefe an.
M4-Testknoten für Xcode Parallel Testing skalieren
Wenn Parameter-Tabelle, Buildsperre und Derived-Data-Disziplin stehen, skalieren Sie mit zusätzlicher Hardware statt mit übergeladenen Simulatoren: Die öffentlichen Seiten Tarife und Bestellung sind bei clustervps ohne vorherige Anmeldung erreichbar — Region und SSD (1TB/2TB) wählen, SSH-fähigen Mac mini M4 für Ihre parallele Testfarm bereitstellen und die Matrix aus diesem Artikel 1:1 gegen Ihre Pipeline legen.