Add ServiceProtocolDiscovery

This commit is contained in:
John McCutchan 2016-03-04 15:01:26 -08:00
parent 96a0e7cbb2
commit 9cb7001a39
3 changed files with 133 additions and 0 deletions

View File

@ -0,0 +1,52 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'device.dart';
/// Discover service protocol ports on devices.
class ServiceProtocolDiscovery {
/// [logReader] A [DeviceLogReader] to look for Observatory messages in.
ServiceProtocolDiscovery(DeviceLogReader logReader)
: _logReader = logReader {
assert(_logReader != null);
if (!_logReader.isReading)
_logReader.start();
_logReader.lines.listen(_onLine);
}
final DeviceLogReader _logReader;
Completer _completer = new Completer();
/// The [Future] returned by this function will complete when the next
/// service protocol port is found.
Future<int> nextPort() {
return _completer.future;
}
void _onLine(String line) {
int portNumber = 0;
if (line.startsWith('Observatory listening on http://')) {
try {
RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)");
var port = portExp.firstMatch(line).group(1);
portNumber = int.parse(port);
} catch (_) {
// Ignore errors.
}
}
if (portNumber != 0) {
_located(portNumber);
}
}
void _located(int port) {
assert(_completer != null);
assert(!_completer.isCompleted);
_completer.complete(port);
_completer = new Completer();
}
}

View File

@ -0,0 +1,47 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:test/test.dart';
import 'package:flutter_tools/src/service_protocol.dart';
import 'src/mocks.dart';
main() => defineTests();
defineTests() {
group('service_protocol', () {
test('Discovery Heartbeat', () async {
MockDeviceLogReader logReader = new MockDeviceLogReader();
ServiceProtocolDiscovery discoverer =
new ServiceProtocolDiscovery(logReader);
// Get next port future.
Future nextPort = discoverer.nextPort();
expect(nextPort, isNotNull);
// Inject some lines.
logReader.addLine('HELLO WORLD');
logReader.addLine(
'Observatory listening on http://127.0.0.1:9999');
// Await the port.
expect(await nextPort, 9999);
// Get next port future.
nextPort = discoverer.nextPort();
logReader.addLine(
'Observatory listening on http://127.0.0.1:3333');
expect(await nextPort, 3333);
// Get next port future.
nextPort = discoverer.nextPort();
// Inject some bad lines.
logReader.addLine('Observatory listening on http://127.0.0.1');
logReader.addLine('Observatory listening on http://127.0.0.1:');
logReader.addLine(
'Observatory listening on http://127.0.0.1:apple');
int port = await nextPort.timeout(
const Duration(milliseconds: 100), onTimeout: () => 77);
// Expect the timeout port.
expect(port, 77);
});
});
}

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/build_configuration.dart';
@ -51,6 +52,39 @@ class MockDeviceStore extends DeviceStore {
iOSSimulator: new MockIOSSimulator());
}
class MockDeviceLogReader extends DeviceLogReader {
String get name => 'MockLogReader';
final StreamController<String> _linesStreamController =
new StreamController<String>.broadcast();
final Completer _finishedCompleter = new Completer();
Stream<String> get lines => _linesStreamController.stream;
void addLine(String line) {
_linesStreamController.add(line);
}
bool _started = false;
Future start() {
assert(!_started);
_started = true;
return new Future.value(this);
}
bool get isReading => _started;
Future stop() {
assert(_started);
_started = false;
return new Future.value(this);
}
Future get finished => _finishedCompleter.future;
}
void applyMocksToCommand(FlutterCommand command) {
command
..applicationPackages = new MockApplicationPackageStore()