[dds][dart_runtime_service] Dynamically allocate ChromeDriver ports and fix SSE test flakiness

This change addresses flakiness in SSE tests caused by port conflicts
and race conditions during connection teardown.

Key changes:
- Dynamically allocates ChromeDriver ports in `sse_smoke_test.dart` and `sse_client_test.dart` instead of using a hardcoded port (4444). This avoids conflicts when tests run in parallel on CI bots.
- Adds support for locating ChromeDriver via the `CHROMEDRIVER_PATH` environment variable in both test suites.
- Updates `sse_smoke_driver.dart` to introduce a brief delay before closing connections. This ensures the client-side SseClient has sufficient time to flush its final POST request to the server, avoiding "Bad state: No element" errors.
- Modifies `test_helper.dart` to filter out `--mark_main_isolate_as_system_isolate` from arguments forwarded to spawned testee processes. This is necessary under modern `dart test` runners to ensure processes pause at start as expected.

Change-Id: Idf45cd69f366ec6b6f81cfed955aea337b277dcc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/508343
Auto-Submit: Ben Konyi <bkonyi@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
This commit is contained in:
Ben Konyi
2026-06-02 12:46:31 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent d8fab3228b
commit ab6780d13e
5 changed files with 1510 additions and 1463 deletions
@@ -25,19 +25,27 @@ void main() {
late HttpServer server;
late WebDriver webdriver;
late Process chromeDriver;
late int chromeDriverPort;
setUpAll(() async {
final socket = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
chromeDriverPort = socket.port;
await socket.close();
var chromedriverPath = Platform.environment['CHROMEDRIVER_PATH'];
final Uri chromedriverUri;
if (chromedriverPath == null) {
chromedriverPath = '../../../third_party/webdriver/chrome/chromedriver';
if (Platform.isWindows) {
chromedriverPath = '$chromedriverPath.exe';
}
chromedriverUri = resolveTestRelativePath(chromedriverPath);
} else {
chromedriverUri = Uri.file(chromedriverPath);
}
final chromedriverUri = resolveTestRelativePath(chromedriverPath);
try {
chromeDriver = await Process.start(chromedriverUri.toFilePath(), [
'--port=4444',
'--port=$chromeDriverPort',
'--url-base=wd/hub',
]);
final started = Completer<void>();
@@ -91,7 +99,10 @@ void main() {
'binary': ?Platform.environment['CHROME_PATH'],
},
});
webdriver = await createDriver(desired: capabilities);
webdriver = await createDriver(
desired: capabilities,
uri: Uri.parse('http://localhost:$chromeDriverPort/wd/hub/'),
);
});
tearDown(() async {
@@ -23,9 +23,11 @@ Future<void> main() async {
final client = SseClient(serviceUri);
await client.onConnected;
channel.sink.add('Success');
await Future<void>.delayed(const Duration(milliseconds: 500));
client.close();
} catch (e) {
channel.sink.add('Error: $e');
await Future<void>.delayed(const Duration(milliseconds: 500));
}
channel.close();
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -56,7 +56,7 @@ Future<io.Process> spawnDartProcess(
if (pauseOnStart) '--pause-isolates-on-start',
if (disableServiceAuthCodes) '--disable-service-auth-codes',
'--write-service-info=$serviceInfoUri',
...io.Platform.executableArguments,
...io.Platform.executableArguments.where((arg) => arg != '--mark_main_isolate_as_system_isolate'),
resolveTestRelativePath(script).toFilePath(),
];
final process = await io.Process.start(executable, arguments);
+17 -5
View File
@@ -22,6 +22,7 @@ import 'common/test_helper.dart';
void main() {
late Process chromeDriver;
late int chromeDriverPort;
late DartDevelopmentService dds;
late SseHandler handler;
Process? process;
@@ -29,14 +30,24 @@ void main() {
late WebDriver webdriver;
setUpAll(() async {
var chromedriverPath = '../../../third_party/webdriver/chrome/chromedriver';
if (Platform.isWindows) {
chromedriverPath = '$chromedriverPath.exe';
final socket = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
chromeDriverPort = socket.port;
await socket.close();
var chromedriverPath = Platform.environment['CHROMEDRIVER_PATH'];
final Uri chromedriverUri;
if (chromedriverPath == null) {
chromedriverPath = '../../../third_party/webdriver/chrome/chromedriver';
if (Platform.isWindows) {
chromedriverPath = '$chromedriverPath.exe';
}
chromedriverUri = resolveTestRelativePath(chromedriverPath);
} else {
chromedriverUri = Uri.file(chromedriverPath);
}
final chromedriverUri = resolveTestRelativePath(chromedriverPath);
try {
chromeDriver = await Process.start(chromedriverUri.toFilePath(), [
'--port=4444',
'--port=$chromeDriverPort',
'--url-base=wd/hub',
]);
} catch (e) {
@@ -71,6 +82,7 @@ void main() {
});
webdriver = await createDriver(
desired: capabilities,
uri: Uri.parse('http://localhost:$chromeDriverPort/wd/hub/'),
);
});