Commit 9cb7001a authored by John McCutchan's avatar John McCutchan

Add ServiceProtocolDiscovery

parent 96a0e7cb
// 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();
}
}
// 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);
});
});
}
......@@ -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()
......
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