diff --git a/pkg/test_runner/lib/src/command.dart b/pkg/test_runner/lib/src/command.dart index 27ca02d528c..8ba9f2774ae 100644 --- a/pkg/test_runner/lib/src/command.dart +++ b/pkg/test_runner/lib/src/command.dart @@ -609,6 +609,7 @@ abstract class AdbCommand { class AdbPrecompilationCommand extends Command implements AdbCommand { final String buildPath; // Path to the output directory of the build. final String processTestFilename; + final String abstractSocketTestFilename; final String precompiledTestDirectory; final List arguments; final bool useElf; @@ -617,6 +618,7 @@ class AdbPrecompilationCommand extends Command implements AdbCommand { AdbPrecompilationCommand( this.buildPath, this.processTestFilename, + this.abstractSocketTestFilename, this.precompiledTestDirectory, this.arguments, this.useElf, @@ -627,6 +629,7 @@ class AdbPrecompilationCommand extends Command implements AdbCommand { AdbPrecompilationCommand indexedCopy(int index) => AdbPrecompilationCommand( buildPath, processTestFilename, + abstractSocketTestFilename, precompiledTestDirectory, arguments, useElf, @@ -662,17 +665,28 @@ class AdbPrecompilationCommand extends Command implements AdbCommand { class AdbDartkCommand extends Command implements AdbCommand { final String buildPath; final String processTestFilename; + final String abstractSocketTestFilename; final String kernelFile; final List arguments; final List extraLibraries; - AdbDartkCommand(this.buildPath, this.processTestFilename, this.kernelFile, - this.arguments, this.extraLibraries, + AdbDartkCommand( + this.buildPath, + this.processTestFilename, + this.abstractSocketTestFilename, + this.kernelFile, + this.arguments, + this.extraLibraries, {int index = 0}) : super._("adb_precompilation", index: index); AdbDartkCommand indexedCopy(int index) => AdbDartkCommand( - buildPath, processTestFilename, kernelFile, arguments, extraLibraries, + buildPath, + processTestFilename, + abstractSocketTestFilename, + kernelFile, + arguments, + extraLibraries, index: index); _buildHashCode(HashCodeBuilder builder) { diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart index ff3e1f19344..3c8e5bb4d46 100644 --- a/pkg/test_runner/lib/src/process_queue.dart +++ b/pkg/test_runner/lib/src/process_queue.dart @@ -639,6 +639,7 @@ class CommandExecutorImpl implements CommandExecutor { AdbDevice device, AdbPrecompilationCommand command, int timeout) async { var buildPath = command.buildPath; var processTest = command.processTestFilename; + var abstractSocketTest = command.abstractSocketTestFilename; var testdir = command.precompiledTestDirectory; var arguments = command.arguments; var devicedir = DartPrecompiledAdbRuntimeConfiguration.deviceDir; @@ -662,10 +663,12 @@ class CommandExecutorImpl implements CommandExecutor { '$devicedir/dart_precompiled_runtime')); steps.add( () => device.pushCachedData(processTest, '$devicedir/process_test')); + steps.add(() => device.pushCachedData( + abstractSocketTest, '$devicedir/abstract_socket_test')); steps.add(() => device.runAdbShellCommand([ 'chmod', '777', - '$devicedir/dart_precompiled_runtime $devicedir/process_test' + '$devicedir/dart_precompiled_runtime $devicedir/process_test $devicedir/abstract_socket_test' ])); steps.addAll(_pushLibraries(command, device, devicedir, deviceTestDir)); diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart index e8a4d823235..27623e323bd 100644 --- a/pkg/test_runner/lib/src/runtime_configuration.dart +++ b/pkg/test_runner/lib/src/runtime_configuration.dart @@ -125,6 +125,13 @@ abstract class RuntimeConfiguration { return processTestExecutable; } + String get abstractSocketTestBinaryFileName { + var abstractSocketTestExecutable = + '$buildDir/abstract_socket_test$executableExtension'; + TestUtils.ensureExists(abstractSocketTestExecutable, _configuration); + return abstractSocketTestExecutable; + } + String get d8FileName { var d8Dir = Repository.dir.append('third_party/d8'); var d8Path = @@ -358,8 +365,10 @@ class DartkAdbRuntimeConfiguration extends DartVmRuntimeConfiguration { var buildPath = buildDir; var processTest = processTestBinaryFileName; + var abstractSocketTest = abstractSocketTestBinaryFileName; return [ - AdbDartkCommand(buildPath, processTest, script, arguments, extraLibs) + AdbDartkCommand(buildPath, processTest, abstractSocketTest, script, + arguments, extraLibs) ]; } } @@ -385,9 +394,10 @@ class DartPrecompiledAdbRuntimeConfiguration } var processTest = processTestBinaryFileName; + var abstractSocketTest = abstractSocketTestBinaryFileName; return [ - AdbPrecompilationCommand( - buildDir, processTest, script, arguments, useElf, extraLibs) + AdbPrecompilationCommand(buildDir, processTest, abstractSocketTest, + script, arguments, useElf, extraLibs) ]; } } diff --git a/tests/standalone/io/unix_socket_test.dart b/tests/standalone/io/unix_socket_test.dart index 7c84792d0a0..0553e6a7e8c 100644 --- a/tests/standalone/io/unix_socket_test.dart +++ b/tests/standalone/io/unix_socket_test.dart @@ -175,7 +175,11 @@ Future testShortAbstractAddress() async { if (!Platform.isLinux && !Platform.isAndroid) { return; } + var retries = 10; + var retryDelay = const Duration(seconds: 1); Process? process; + Future? stdoutFuture; + Future? stderrFuture; try { var socketAddress = '@hidden'; var abstractSocketServer = getAbstractSocketTestFileName(); @@ -184,10 +188,36 @@ Future testShortAbstractAddress() async { if (!File(abstractSocketServer).existsSync()) { return; } + + // Start up a subprocess that listens on '@hidden'. process = await Process.start(abstractSocketServer, [socketAddress]); + stdoutFuture = process.stdout + .transform(const Utf8Decoder(allowMalformed: true)) + .listen(stdout.write) + .asFuture(null); + stderrFuture = process.stderr + .transform(const Utf8Decoder(allowMalformed: true)) + .listen(stderr.write) + .asFuture(null); var serverAddress = InternetAddress(socketAddress, type: InternetAddressType.unix); - Socket client = await Socket.connect(serverAddress, 0); + + // The subprocess may take some time to start, so retry setting up the + // connection a few times. + Socket? client; + while (true) { + try { + client = await Socket.connect(serverAddress, 0); + break; + } catch (e, st) { + if (retries <= 0) { + rethrow; + } + retries--; + } + await Future.delayed(retryDelay); + } + List sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; List data = []; var completer = Completer(); @@ -206,6 +236,9 @@ Future testShortAbstractAddress() async { Expect.fail('Failed with exception:\n$e\n$st'); } finally { process?.kill(ProcessSignal.sigkill); + await stdoutFuture; + await stderrFuture; + await process?.exitCode; } } diff --git a/tests/standalone_2/io/unix_socket_test.dart b/tests/standalone_2/io/unix_socket_test.dart index 0549fead22a..e63b9d80fd4 100644 --- a/tests/standalone_2/io/unix_socket_test.dart +++ b/tests/standalone_2/io/unix_socket_test.dart @@ -5,8 +5,8 @@ // @dart = 2.9 import 'dart:async'; -import 'dart:io'; import 'dart:convert'; +import 'dart:io'; import 'package:expect/expect.dart'; @@ -177,7 +177,11 @@ Future testShortAbstractAddress() async { if (!Platform.isLinux && !Platform.isAndroid) { return; } + var retries = 10; + var retryDelay = const Duration(seconds: 1); Process process; + var stdoutFuture; + var stderrFuture; try { var socketAddress = '@hidden'; var abstractSocketServer = getAbstractSocketTestFileName(); @@ -186,10 +190,36 @@ Future testShortAbstractAddress() async { if (!File(abstractSocketServer).existsSync()) { return; } + + // Start up a subprocess that listens on '@hidden'. process = await Process.start(abstractSocketServer, [socketAddress]); + stdoutFuture = process.stdout + .transform(const Utf8Decoder(allowMalformed: true)) + .listen(stdout.write) + .asFuture(null); + stderrFuture = process.stderr + .transform(const Utf8Decoder(allowMalformed: true)) + .listen(stderr.write) + .asFuture(null); var serverAddress = InternetAddress(socketAddress, type: InternetAddressType.unix); - Socket client = await Socket.connect(serverAddress, 0); + + // The subprocess may take some time to start, so retry setting up the + // connection a few times. + Socket client; + while (true) { + try { + client = await Socket.connect(serverAddress, 0); + break; + } catch (e, st) { + if (retries <= 0) { + rethrow; + } + retries--; + } + await Future.delayed(retryDelay); + } + List sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; List data = []; var completer = Completer(); @@ -208,6 +238,9 @@ Future testShortAbstractAddress() async { Expect.fail('Failed with exception:\n$e\n$st'); } finally { process?.kill(ProcessSignal.sigkill); + await stdoutFuture; + await stderrFuture; + await process?.exitCode; } }