Commit ba4bba74 authored by Todd Volkert's avatar Todd Volkert Committed by GitHub

Support IPv6 in test platform (#9795)

parent 2b04e300
......@@ -41,9 +41,6 @@ export 'dart:io'
// File NO! Use `file_system.dart`
// FileSystemEntity NO! Use `file_system.dart`
GZIP,
InternetAddress,
IOException,
IOSink,
HttpClient,
HttpClientRequest,
HttpClientResponse,
......@@ -51,6 +48,10 @@ export 'dart:io'
HttpRequest,
HttpServer,
HttpStatus,
InternetAddress,
InternetAddressType,
IOException,
IOSink,
// Link NO! Use `file_system.dart`
pid,
// Platform NO! use `platform.dart`
......
......@@ -43,6 +43,11 @@ class TestCommand extends FlutterCommand {
help: 'Whether to merge converage data with "coverage/lcov.base.info".\n'
'Implies collecting coverage data. (Requires lcov)'
);
argParser.addFlag('ipv6',
negatable: false,
hide: true,
help: 'Whether to use IPv6 for the test harness server socket.'
);
argParser.addOption('coverage-path',
defaultsTo: 'coverage/lcov.info',
help: 'Where to store coverage information (if coverage is enabled).'
......@@ -197,6 +202,10 @@ class TestCommand extends FlutterCommand {
}
testArgs.addAll(files);
final InternetAddressType serverType = argResults['ipv6']
? InternetAddressType.IP_V6
: InternetAddressType.IP_V4;
final String shellPath = artifacts.getArtifactPath(Artifact.flutterTester);
if (!fs.isFileSync(shellPath))
throwToolExit('Cannot find Flutter shell at $shellPath');
......@@ -204,6 +213,7 @@ class TestCommand extends FlutterCommand {
shellPath: shellPath,
collector: collector,
debuggerMode: argResults['start-paused'],
serverType: serverType,
);
Cache.releaseLockEarly();
......
......@@ -40,7 +40,10 @@ const String _kStartTimeoutTimerMessage = 'sky_shell test process has entered ma
/// The address at which our WebSocket server resides and at which the sky_shell
/// processes will host the Observatory server.
final InternetAddress _kHost = InternetAddress.LOOPBACK_IP_V4;
final Map<InternetAddressType, InternetAddress> _kHosts = <InternetAddressType, InternetAddress>{
InternetAddressType.IP_V4: InternetAddress.LOOPBACK_IP_V4,
InternetAddressType.IP_V6: InternetAddress.LOOPBACK_IP_V6,
};
/// Configure the `test` package to work with Flutter.
///
......@@ -53,6 +56,7 @@ void installHook({
bool debuggerMode: false,
int observatoryPort,
int diagnosticPort,
InternetAddressType serverType: InternetAddressType.IP_V4,
}) {
hack.registerPlatformPlugin(
<TestPlatform>[TestPlatform.vm],
......@@ -62,6 +66,7 @@ void installHook({
debuggerMode: debuggerMode,
explicitObservatoryPort: observatoryPort,
explicitDiagnosticPort: diagnosticPort,
host: _kHosts[serverType],
),
);
}
......@@ -77,6 +82,7 @@ class _FlutterPlatform extends PlatformPlugin {
this.debuggerMode,
this.explicitObservatoryPort,
this.explicitDiagnosticPort,
this.host,
}) {
assert(shellPath != null);
}
......@@ -86,6 +92,7 @@ class _FlutterPlatform extends PlatformPlugin {
final bool debuggerMode;
final int explicitObservatoryPort;
final int explicitDiagnosticPort;
final InternetAddress host;
// Each time loadChannel() is called, we spin up a local WebSocket server,
// then spin up the engine in a subprocess. We pass the engine a Dart file
......@@ -123,7 +130,10 @@ class _FlutterPlatform extends PlatformPlugin {
return remoteChannel;
}
Future<Null> _startTest(String testPath, StreamChannel<dynamic> controller, int ourTestCount) async {
Future<Null> _startTest(
String testPath,
StreamChannel<dynamic> controller,
int ourTestCount) async {
printTrace('test $ourTestCount: starting test $testPath');
dynamic outOfBandError; // error that we couldn't send to the harness that we need to send via our future
......@@ -135,7 +145,7 @@ class _FlutterPlatform extends PlatformPlugin {
controller.sink.done.whenComplete(() { controllerSinkClosed = true; });
// Prepare our WebSocket server to talk to the engine subproces.
final HttpServer server = await HttpServer.bind(_kHost, 0);
final HttpServer server = await HttpServer.bind(host, 0);
finalizers.add(() async {
printTrace('test $ourTestCount: shutting down test harness socket server');
await server.close(force: true);
......@@ -171,7 +181,7 @@ class _FlutterPlatform extends PlatformPlugin {
listenerFile.createSync();
listenerFile.writeAsStringSync(_generateTestMain(
testUrl: fs.path.toUri(fs.path.absolute(testPath)).toString(),
encodedWebsocketUrl: Uri.encodeComponent("ws://${_kHost.address}:${server.port}"),
encodedWebsocketUrl: Uri.encodeComponent(_getWebSocketUrl(server)),
));
// Start the engine subprocess.
......@@ -215,7 +225,7 @@ class _FlutterPlatform extends PlatformPlugin {
if (debuggerMode) {
printStatus('The test process has been started.');
printStatus('You can now connect to it using observatory. To connect, load the following Web site in your browser:');
printStatus(' http://${_kHost.address}:$detectedPort/');
printStatus(' http://${host.address}:$detectedPort/');
printStatus('You should first set appropriate breakpoints, then resume the test in the debugger.');
} else {
printTrace('test $ourTestCount: using observatory port $detectedPort from pid ${process.pid} to collect coverage');
......@@ -333,7 +343,7 @@ class _FlutterPlatform extends PlatformPlugin {
if (subprocessActive && collector != null) {
printTrace('test $ourTestCount: collecting coverage');
await collector.collectCoverage(process, _kHost, processObservatoryPort);
await collector.collectCoverage(process, host, processObservatoryPort);
}
} catch (error, stack) {
printTrace('test $ourTestCount: error caught during test; ${controllerSinkClosed ? "reporting to console" : "sending to test framework"}');
......@@ -374,6 +384,12 @@ class _FlutterPlatform extends PlatformPlugin {
return null;
}
String _getWebSocketUrl(HttpServer server) {
return host.type == InternetAddressType.IP_V4
? "ws://${host.address}:${server.port}"
: "ws://[${host.address}]:${server.port}";
}
String _generateTestMain({
String testUrl,
String encodedWebsocketUrl,
......@@ -475,14 +491,14 @@ void main() {
return processManager.start(command, environment: environment);
}
String get observatoryPortString => 'Observatory listening on http://${_kHost.address}:';
String get diagnosticPortString => 'Diagnostic server listening on http://${_kHost.address}:';
void _pipeStandardStreamsToConsole(
Process process, {
void startTimeoutTimer(),
void reportObservatoryPort(int port),
}) {
final String observatoryPortString = 'Observatory listening on http://${host.address}:';
final String diagnosticPortString = 'Diagnostic server listening on http://${host.address}:';
for (Stream<List<int>> stream in
<Stream<List<int>>>[process.stderr, process.stdout]) {
stream.transform(UTF8.decoder)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment