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

Support IPv6 in coverage collection (#9841)

Builds on engine fixes to #9813

Also fixes #7366
parent 0652737f
......@@ -28,9 +28,9 @@ class CoverageCollector {
/// has been run to completion so that all coverage data has been recorded.
///
/// The returned [Future] completes when the coverage is collected.
Future<Null> collectCoverage(Process process, InternetAddress host, int port) async {
Future<Null> collectCoverage(Process process, Uri observatoryUri) async {
assert(process != null);
assert(port != null);
assert(observatoryUri != null);
final int pid = process.pid;
int exitCode;
......@@ -40,16 +40,27 @@ class CoverageCollector {
if (exitCode != null)
throw new Exception('Failed to collect coverage, process terminated before coverage could be collected.');
printTrace('pid $pid (port $port): collecting coverage data...');
final Map<String, dynamic> data = await coverage.collect(host.address, port, false, false).timeout(
const Duration(seconds: 30),
onTimeout: () { throw new Exception('Failed to collect coverage, it took more than thirty seconds.'); },
);
printTrace('pid $pid (port $port): ${ exitCode != null ? "process terminated prematurely with exit code $exitCode; aborting" : "collected coverage data; merging..." }');
printTrace('pid $pid: collecting coverage data from $observatoryUri...');
final Map<String, dynamic> data = await coverage
.collect(observatoryUri, false, false)
.timeout(
const Duration(seconds: 30),
onTimeout: () {
throw new Exception('Failed to collect coverage, it took more than thirty seconds.');
},
);
printTrace(() {
final StringBuffer buf = new StringBuffer()
..write('pid $pid ($observatoryUri): ')
..write(exitCode == null
? 'collected coverage data; merging...'
: 'process terminated prematurely with exit code $exitCode; aborting');
return buf.toString();
}());
if (exitCode != null)
throw new Exception('Failed to collect coverage, process terminated while coverage was being collected.');
_addHitmap(coverage.createHitmap(data['coverage']));
printTrace('pid $pid (port $port): done merging coverage data into global coverage map.');
printTrace('pid $pid ($observatoryUri): done merging coverage data into global coverage map.');
}
/// Returns a future that will complete with the formatted coverage data
......
......@@ -215,22 +215,22 @@ class _FlutterPlatform extends PlatformPlugin {
// Pipe stdout and stderr from the subprocess to our printStatus console.
// We also keep track of what observatory port the engine used, if any.
int processObservatoryPort;
Uri processObservatoryUri;
_pipeStandardStreamsToConsole(
process,
reportObservatoryPort: (int detectedPort) {
assert(processObservatoryPort == null);
reportObservatoryUri: (Uri detectedUri) {
assert(processObservatoryUri == null);
assert(explicitObservatoryPort == null ||
explicitObservatoryPort == detectedPort);
explicitObservatoryPort == detectedUri.port);
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://${host.address}:$detectedPort/');
printStatus(' $detectedUri');
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');
printTrace('test $ourTestCount: using observatory uri $detectedUri from pid ${process.pid} to collect coverage');
}
processObservatoryPort = detectedPort;
processObservatoryUri = detectedUri;
},
startTimeoutTimer: () {
new Future<_InitialResult>.delayed(_kTestStartupTimeout).then((_) => timeout.complete());
......@@ -343,7 +343,7 @@ class _FlutterPlatform extends PlatformPlugin {
if (subprocessActive && collector != null) {
printTrace('test $ourTestCount: collecting coverage');
await collector.collectCoverage(process, host, processObservatoryPort);
await collector.collectCoverage(process, processObservatoryUri);
}
} catch (error, stack) {
printTrace('test $ourTestCount: error caught during test; ${controllerSinkClosed ? "reporting to console" : "sending to test framework"}');
......@@ -475,6 +475,8 @@ void main() {
} else {
command.addAll(<String>['--disable-observatory', '--disable-diagnostic']);
}
if (host.type == InternetAddressType.IP_V6)
command.add('--ipv6');
command.addAll(<String>[
'--enable-dart-profiling',
'--non-interactive',
......@@ -494,10 +496,10 @@ void main() {
void _pipeStandardStreamsToConsole(
Process process, {
void startTimeoutTimer(),
void reportObservatoryPort(int port),
void reportObservatoryUri(Uri uri),
}) {
final String observatoryPortString = 'Observatory listening on http://${host.address}:';
final String diagnosticPortString = 'Diagnostic server listening on http://${host.address}:';
final String observatoryString = 'Observatory listening on ';
final String diagnosticServerString = 'Diagnostic server listening on ';
for (Stream<List<int>> stream in
<Stream<List<int>>>[process.stderr, process.stdout]) {
......@@ -511,16 +513,16 @@ void main() {
} else if (line.startsWith('error: Unable to read Dart source \'package:test/')) {
printTrace('Shell: $line');
printError('\n\nFailed to load test harness. Are you missing a dependency on flutter_test?\n');
} else if (line.startsWith(observatoryPortString)) {
} else if (line.startsWith(observatoryString)) {
printTrace('Shell: $line');
try {
final int port = int.parse(line.substring(observatoryPortString.length, line.length - 1)); // last character is a slash
if (reportObservatoryPort != null)
reportObservatoryPort(port);
final Uri uri = Uri.parse(line.substring(observatoryString.length));
if (reportObservatoryUri != null)
reportObservatoryUri(uri);
} catch (error) {
printError('Could not parse shell observatory port message: $error');
}
} else if (line.startsWith(diagnosticPortString)) {
} else if (line.startsWith(diagnosticServerString)) {
printTrace('Shell: $line');
} else if (line != null) {
printStatus('Shell: $line');
......
......@@ -10,7 +10,7 @@ environment:
dependencies:
archive: ^1.0.20
args: ^0.13.4
coverage: ^0.8.0
coverage: ^0.9.2
crypto: '>=1.1.1 <3.0.0'
file: 2.3.2
http: ^0.11.3+12
......
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