Fix abstract unix socket test
There was a race between the subprocess listening on the socket and
the test trying to connect.
Also the Android bits of the test harness needed to be taught about
the abstract_socket_test program, similar to how process_test is
handled.
TEST=Fixes tests
Change-Id: I5e1c5d2e23e4bff2a01cd5c491a45e1c58d2578e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/201861
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Zach Anderson <zra@google.com>
diff --git a/pkg/test_runner/lib/src/command.dart b/pkg/test_runner/lib/src/command.dart
index 27ca02d..8ba9f27 100644
--- a/pkg/test_runner/lib/src/command.dart
+++ b/pkg/test_runner/lib/src/command.dart
@@ -609,6 +609,7 @@
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<String> arguments;
final bool useElf;
@@ -617,6 +618,7 @@
AdbPrecompilationCommand(
this.buildPath,
this.processTestFilename,
+ this.abstractSocketTestFilename,
this.precompiledTestDirectory,
this.arguments,
this.useElf,
@@ -627,6 +629,7 @@
AdbPrecompilationCommand indexedCopy(int index) => AdbPrecompilationCommand(
buildPath,
processTestFilename,
+ abstractSocketTestFilename,
precompiledTestDirectory,
arguments,
useElf,
@@ -662,17 +665,28 @@
class AdbDartkCommand extends Command implements AdbCommand {
final String buildPath;
final String processTestFilename;
+ final String abstractSocketTestFilename;
final String kernelFile;
final List<String> arguments;
final List<String> 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 ff3e1f1..3c8e5bb 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -639,6 +639,7 @@
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 @@
'$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 e8a4d82..27623e3 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -125,6 +125,13 @@
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 @@
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 @@
}
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 7c84792..0553e6a 100644
--- a/tests/standalone/io/unix_socket_test.dart
+++ b/tests/standalone/io/unix_socket_test.dart
@@ -175,7 +175,11 @@
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 @@
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<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
List<int> data = [];
var completer = Completer<void>();
@@ -206,6 +236,9 @@
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 0549fea..e63b9d8 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 @@
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 @@
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<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
List<int> data = [];
var completer = Completer<void>();
@@ -208,6 +238,9 @@
Expect.fail('Failed with exception:\n$e\n$st');
} finally {
process?.kill(ProcessSignal.sigkill);
+ await stdoutFuture;
+ await stderrFuture;
+ await process?.exitCode;
}
}