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>
This commit is contained in:
Zach Anderson
2021-06-01 17:30:54 +00:00
committed by commit-bot@chromium.org
parent ab91ef643c
commit 8beec1d9cc
5 changed files with 103 additions and 10 deletions
+17 -3
View File
@@ -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<String> 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<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) {
+4 -1
View File
@@ -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));
@@ -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)
];
}
}
+34 -1
View File
@@ -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<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
List<int> data = [];
var completer = Completer<void>();
@@ -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;
}
}
+35 -2
View File
@@ -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<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
List<int> data = [];
var completer = Completer<void>();
@@ -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;
}
}