Skip to content

Marathon integration - #3173

Open
Polyphemus980 wants to merge 7 commits into
masterfrom
feat/marathon
Open

Marathon integration#3173
Polyphemus980 wants to merge 7 commits into
masterfrom
feat/marathon

Conversation

@Polyphemus980

Copy link
Copy Markdown
Contributor

Summary

  • Add Marathon integration for running Patrol tests in parallel on Android and iOS simulators with docs and e2e_app examples.
  • Make multi-simulator iOS runs work by dynamically binding native port pairs and injecting them into the app via XCUIApplication.launchEnvironment, then reading them in Dart over a method channel (getRuntimePorts).
  • Fix long-standing iOS/macOS test-startup sync: wait for appReady per test before runDartTest, add a 60s timeout, and remove the obsolete 1s delay workaround.

Why iOS needed the port work

  • Parallel xcodebuild on one Mac starts multiple host-side PatrolServers, so they can no longer all use 8081/8082.
  • Now we scan port pairs (8081/8082, 8083/8084, …) until a free one is found.
  • Flutter does not expose XCTest launchEnvironment to Dart Platform.environment, so ports are read from native ProcessInfo over a method channel.

@github-actions github-actions Bot added docs Concerns doc comments, READMEs, or docs package: patrol Related to the patrol package (native automation, test bundling) package: patrol_cli Related to the patrol_cli package labels Jul 16, 2026
@Polyphemus980 Polyphemus980 changed the title Feat/marathon Marathon integration Jul 16, 2026
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

🚀 Preview Deployment Ready!

Preview URL: https://pr-3173-patrol-docs.vercel.app


Latest Deployment

  • Commit: 01aa92b
  • Branch: feat/marathon
  • Triggered by: @pdenert
  • Deployed at: 2026-07-29 10:54:55 UTC

This preview URL is stable and will be updated with each new commit to this PR.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces Marathon integration for running Patrol tests in parallel on Android and iOS simulators, including necessary configuration files, helper scripts, and documentation. To support parallel execution, the native iOS and macOS test runners have been updated to dynamically bind to available ports and communicate them to the Dart side via a new method channel. The review feedback highlights a potential runtime crash in Swift when casting the port to UInt16 without validation, and recommends using %ld format specifiers with explicit (long) casts in Objective-C runner macros to prevent compiler warnings on 64-bit architectures.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

# Conflicts:
#	packages/patrol/CHANGELOG.md
Copilot AI review requested due to automatic review settings July 29, 2026 10:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Marathon-based parallel Patrol testing, including dynamic Darwin port allocation and improved app-start synchronization.

Changes:

  • Adds Marathon documentation, configurations, scripts, and smoke tests.
  • Introduces runtime port injection for parallel iOS/macOS execution.
  • Replaces fixed startup delays with readiness checks and timeouts.

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/patrol/lib/src/platform/platform_automator.dart Passes host and port configuration.
packages/patrol/lib/src/platform/mobile/patrol_runtime_ports.dart Reads injected Darwin ports.
packages/patrol/lib/src/platform/mobile/patrol_app_service_io.dart Resolves the app-service port dynamically.
packages/patrol/lib/src/platform/mobile/mobile_automator_native.dart Lazily creates the mobile client.
packages/patrol/lib/src/platform/mobile/mobile_automator_config.dart Adds dynamic test-server port resolution.
packages/patrol/lib/src/platform/ios/ios_automator_native.dart Lazily creates the iOS client.
packages/patrol/lib/src/platform/ios/ios_automator_config.dart Updates iOS config construction.
packages/patrol/lib/src/platform/android/android_automator_config.dart Updates Android config construction.
packages/patrol/darwin/patrol/Sources/PatrolImpl/SwiftPatrolPlugin.swift Exposes runtime ports through a method channel.
packages/patrol/darwin/patrol/Sources/PatrolImpl/ObjCPatrolAppServiceClient.swift Supports explicit ports and removes startup delay.
packages/patrol/darwin/patrol/Sources/PatrolImpl/AutomatorServer/PatrolServer.swift Scans and binds available port pairs.
packages/patrol/darwin/patrol/Sources/patrol/include/PatrolIntegrationTestMacosRunner.h Injects ports and adds readiness checks.
packages/patrol/darwin/patrol/Sources/patrol/include/PatrolIntegrationTestIosRunner.h Adds Marathon selection, ports, and synchronization.
packages/patrol/CHANGELOG.md Announces Marathon integration.
packages/patrol_cli/lib/src/test_bundler.dart Loads runtime ports in generated bundles.
docs/index.mdx Links the Marathon guide.
docs/documentation/integrations/meta.json Adds Marathon to navigation.
docs/documentation/integrations/marathon.mdx Documents Marathon setup and usage.
dev/e2e_app/run_marathon_ios Adds an iOS Marathon runner script.
dev/e2e_app/run_marathon_android Adds an Android Marathon runner script.
dev/e2e_app/patrol_test/marathon_smoke_test.dart Adds iOS sharding smoke tests.
dev/e2e_app/Marathonfile.ios Configures iOS Marathon runs.
dev/e2e_app/Marathonfile.android Configures Android Marathon runs.
dev/e2e_app/Marathondevices Defines the iOS simulator pool.
dev/e2e_app/ios/Podfile.lock Updates resolved iOS dependencies.
Comments suppressed due to low confidence (2)

packages/patrol/darwin/patrol/Sources/patrol/include/PatrolIntegrationTestIosRunner.h:253

  • On a listDartTests failure, listedTests remains nil, so the loop below never exits—even after the client's two-hour HTTP timeout fires. Record the error and stop discovery instead of turning an RPC failure into an infinite hang.
          listDartTestsWithCompletion:^(NSArray<NSDictionary *> *_Nullable tests, NSError *_Nullable err) {         \
            if (err != NULL) {                                                                                      \
              NSLog(@"listDartTests(): failed, err: %@", err);                                                      \
            }                                                                                                       \
            listedTests = tests;                                                                                    \

packages/patrol/darwin/patrol/Sources/patrol/include/PatrolIntegrationTestMacosRunner.h:73

  • On a listDartTests failure, dartTests remains nil, so the loop below never exits—even after the client's two-hour HTTP timeout fires. Record the error and stop discovery instead of turning an RPC failure into an infinite hang.
        listDartTestsWithCompletion:^(NSArray<NSDictionary *> *_Nullable tests, NSError *_Nullable err) {     \
          if (err != NULL) {                                                                                  \
            NSLog(@"listDartTests(): failed, err: %@", err);                                                  \
          }                                                                                                   \
                                                                                                              \
          dartTests = tests;                                                                                  \

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +13 to +20
MobileAutomatorConfig({
String? host,
String? port,
Duration? connectionTimeout,
Duration? findTimeout,
void Function(String)? logger,
}) : host =
host ??
const String.fromEnvironment(
'PATROL_HOST',
defaultValue: 'localhost',
),
port =
port ??
const String.fromEnvironment(
'PATROL_TEST_SERVER_PORT',
defaultValue: '8081',
),
}) : host = host ?? _defaultHost(),
_portOverride = port,
@@ -0,0 +1,66 @@
import 'dart:io' show Platform;
Comment on lines +35 to +36
+(NSString *)patrolSelectorForDartTestName : (NSString *)dartTestName { \
return [dartTestName stringByReplacingOccurrencesOfString:@" " withString:@"+"]; \
Comment on lines +223 to +229
NSError *err = nil; \
[server startAndReturnError:&err]; \
if (err != nil) { \
NSLog(@"patrolServer.start(): failed, err: %@", err); \
} \
\
/* Create a client for PatrolAppService, which lets us list and run Dart tests */ \
__block ObjCPatrolAppServiceClient *appServiceClient = [[ObjCPatrolAppServiceClient alloc] init]; \
appServiceClientSingleton = [[ObjCPatrolAppServiceClient alloc] initWithPort:server.boundAppPort]; \
Comment on lines +39 to +43
NSError *_Nullable __autoreleasing *_Nullable err = NULL; \
[server startAndReturnError:err]; \
if (err != NULL) { \
NSLog(@"patrolServer.start(): failed, err: %@", err); \
} \
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Concerns doc comments, READMEs, or docs package: patrol_cli Related to the patrol_cli package package: patrol Related to the patrol package (native automation, test bundling)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants