mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
435 lines
16 KiB
Dart
435 lines
16 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// @dart = 2.8
|
|
|
|
import 'package:fake_async/fake_async.dart';
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
|
import 'package:flutter_tools/src/device_port_forwarder.dart';
|
|
import 'package:flutter_tools/src/protocol_discovery.dart';
|
|
|
|
import '../src/common.dart';
|
|
import '../src/fake_devices.dart';
|
|
|
|
void main() {
|
|
group('service_protocol discovery', () {
|
|
FakeDeviceLogReader logReader;
|
|
ProtocolDiscovery discoverer;
|
|
|
|
setUp(() {
|
|
logReader = FakeDeviceLogReader();
|
|
discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
ipv6: false,
|
|
hostPort: null,
|
|
devicePort: null,
|
|
throttleDuration: const Duration(milliseconds: 5),
|
|
logger: BufferLogger.test(),
|
|
);
|
|
});
|
|
|
|
testWithoutContext('returns non-null uri future', () async {
|
|
expect(discoverer.uri, isNotNull);
|
|
});
|
|
|
|
group('no port forwarding', () {
|
|
tearDown(() {
|
|
discoverer.cancel();
|
|
logReader.dispose();
|
|
});
|
|
|
|
testWithoutContext('discovers uri if logs already produced output', () async {
|
|
logReader.addLine('HELLO WORLD');
|
|
logReader.addLine('Observatory listening on http://127.0.0.1:9999');
|
|
final Uri uri = await discoverer.uri;
|
|
expect(uri.port, 9999);
|
|
expect('$uri', 'http://127.0.0.1:9999');
|
|
});
|
|
|
|
testWithoutContext('does not discover uri with no host', () async {
|
|
final Future<Uri> pendingUri = discoverer.uri;
|
|
logReader.addLine('Observatory listening on http12asdasdsd9999');
|
|
await Future<void>.delayed(const Duration(milliseconds: 10));
|
|
logReader.addLine('Observatory listening on http://127.0.0.1:9999');
|
|
|
|
await Future<void>.delayed(Duration.zero);
|
|
|
|
final Uri uri = await pendingUri;
|
|
expect(uri, isNotNull);
|
|
expect(uri.port, 9999);
|
|
expect('$uri', 'http://127.0.0.1:9999');
|
|
});
|
|
|
|
testWithoutContext('discovers uri if logs already produced output and no listener is attached', () async {
|
|
logReader.addLine('HELLO WORLD');
|
|
logReader.addLine('Observatory listening on http://127.0.0.1:9999');
|
|
|
|
await Future<void>.delayed(Duration.zero);
|
|
|
|
final Uri uri = await discoverer.uri;
|
|
expect(uri, isNotNull);
|
|
expect(uri.port, 9999);
|
|
expect('$uri', 'http://127.0.0.1:9999');
|
|
});
|
|
|
|
testWithoutContext('uri throws if logs produce bad line and no listener is attached', () async {
|
|
logReader.addLine('Observatory listening on http://127.0.0.1:apple');
|
|
|
|
await Future<void>.delayed(Duration.zero);
|
|
|
|
expect(discoverer.uri, throwsA(isFormatException));
|
|
});
|
|
|
|
testWithoutContext('discovers uri if logs not yet produced output', () async {
|
|
final Future<Uri> uriFuture = discoverer.uri;
|
|
logReader.addLine('Observatory listening on http://127.0.0.1:3333');
|
|
final Uri uri = await uriFuture;
|
|
expect(uri.port, 3333);
|
|
expect('$uri', 'http://127.0.0.1:3333');
|
|
});
|
|
|
|
testWithoutContext('discovers uri with Ascii Esc code', () async {
|
|
logReader.addLine('Observatory listening on http://127.0.0.1:3333\x1b[');
|
|
final Uri uri = await discoverer.uri;
|
|
expect(uri.port, 3333);
|
|
expect('$uri', 'http://127.0.0.1:3333');
|
|
});
|
|
|
|
testWithoutContext('uri throws if logs produce bad line', () async {
|
|
logReader.addLine('Observatory listening on http://127.0.0.1:apple');
|
|
expect(discoverer.uri, throwsA(isFormatException));
|
|
});
|
|
|
|
testWithoutContext('uri is null when the log reader closes early', () async {
|
|
final Future<Uri> uriFuture = discoverer.uri;
|
|
await logReader.dispose();
|
|
|
|
expect(await uriFuture, isNull);
|
|
});
|
|
|
|
testWithoutContext('uri waits for correct log line', () async {
|
|
final Future<Uri> uriFuture = discoverer.uri;
|
|
logReader.addLine('Observatory not listening...');
|
|
final Uri timeoutUri = Uri.parse('http://timeout');
|
|
final Uri actualUri = await uriFuture.timeout(
|
|
const Duration(milliseconds: 100),
|
|
onTimeout: () => timeoutUri,
|
|
);
|
|
expect(actualUri, timeoutUri);
|
|
});
|
|
|
|
testWithoutContext('discovers uri if log line contains Android prefix', () async {
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:52584');
|
|
final Uri uri = await discoverer.uri;
|
|
expect(uri.port, 52584);
|
|
expect('$uri', 'http://127.0.0.1:52584');
|
|
});
|
|
|
|
testWithoutContext('discovers uri if log line contains auth key', () async {
|
|
final Future<Uri> uriFuture = discoverer.uri;
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:54804/PTwjm8Ii8qg=/');
|
|
final Uri uri = await uriFuture;
|
|
expect(uri.port, 54804);
|
|
expect('$uri', 'http://127.0.0.1:54804/PTwjm8Ii8qg=/');
|
|
});
|
|
|
|
testWithoutContext('discovers uri if log line contains non-localhost', () async {
|
|
final Future<Uri> uriFuture = discoverer.uri;
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:54804/PTwjm8Ii8qg=/');
|
|
final Uri uri = await uriFuture;
|
|
expect(uri.port, 54804);
|
|
expect('$uri', 'http://127.0.0.1:54804/PTwjm8Ii8qg=/');
|
|
});
|
|
|
|
testWithoutContext('skips uri if port does not match the requested vmservice - requested last', () async {
|
|
discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
ipv6: false,
|
|
hostPort: null,
|
|
devicePort: 12346,
|
|
throttleDuration: const Duration(milliseconds: 200),
|
|
logger: BufferLogger.test(),
|
|
);
|
|
final Future<Uri> uriFuture = discoverer.uri;
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
final Uri uri = await uriFuture;
|
|
expect(uri.port, 12346);
|
|
expect('$uri', 'http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
});
|
|
|
|
testWithoutContext('skips uri if port does not match the requested vmservice - requested first', () async {
|
|
discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
ipv6: false,
|
|
hostPort: null,
|
|
devicePort: 12346,
|
|
throttleDuration: const Duration(milliseconds: 200),
|
|
logger: BufferLogger.test(),
|
|
);
|
|
final Future<Uri> uriFuture = discoverer.uri;
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
final Uri uri = await uriFuture;
|
|
expect(uri.port, 12346);
|
|
expect('$uri', 'http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
});
|
|
|
|
testWithoutContext('first uri in the stream is the last one from the log', () async {
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
final Uri uri = await discoverer.uris.first;
|
|
expect(uri.port, 12345);
|
|
expect('$uri', 'http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
});
|
|
|
|
testWithoutContext('first uri in the stream is the last one from the log that matches the port', () async {
|
|
discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
ipv6: false,
|
|
hostPort: null,
|
|
devicePort: 12345,
|
|
throttleDuration: const Duration(milliseconds: 200),
|
|
logger: BufferLogger.test(),
|
|
);
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12344/PTwjm8Ii8qg=/');
|
|
final Uri uri = await discoverer.uris.first;
|
|
expect(uri.port, 12345);
|
|
expect('$uri', 'http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
});
|
|
|
|
testWithoutContext('protocol discovery does not crash if the log reader is closed while delaying', () async {
|
|
discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
ipv6: false,
|
|
hostPort: null,
|
|
devicePort: 12346,
|
|
throttleDuration: const Duration(milliseconds: 10),
|
|
logger: BufferLogger.test(),
|
|
);
|
|
final Future<List<Uri>> results = discoverer.uris.toList();
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
await logReader.dispose();
|
|
|
|
// Give time for throttle to finish.
|
|
await Future<void>.delayed(const Duration(milliseconds: 11));
|
|
expect(await results, isEmpty);
|
|
});
|
|
|
|
testWithoutContext('uris in the stream are throttled', () async {
|
|
const Duration kThrottleDuration = Duration(milliseconds: 10);
|
|
|
|
FakeAsync().run((FakeAsync time) {
|
|
discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
ipv6: false,
|
|
hostPort: null,
|
|
devicePort: null,
|
|
throttleDuration: kThrottleDuration,
|
|
logger: BufferLogger.test(),
|
|
);
|
|
|
|
final List<Uri> discoveredUris = <Uri>[];
|
|
discoverer.uris.listen((Uri uri) {
|
|
discoveredUris.add(uri);
|
|
});
|
|
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
|
|
time.elapse(kThrottleDuration);
|
|
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12344/PTwjm8Ii8qg=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12343/PTwjm8Ii8qg=/');
|
|
|
|
time.elapse(kThrottleDuration);
|
|
|
|
expect(discoveredUris.length, 2);
|
|
expect(discoveredUris[0].port, 12345);
|
|
expect('${discoveredUris[0]}', 'http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
expect(discoveredUris[1].port, 12343);
|
|
expect('${discoveredUris[1]}', 'http://127.0.0.1:12343/PTwjm8Ii8qg=/');
|
|
});
|
|
});
|
|
|
|
testWithoutContext('uris in the stream are throttled when they match the port', () async {
|
|
const Duration kThrottleTimeInMilliseconds = Duration(milliseconds: 10);
|
|
|
|
FakeAsync().run((FakeAsync time) {
|
|
discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
ipv6: false,
|
|
hostPort: null,
|
|
devicePort: 12345,
|
|
throttleDuration: kThrottleTimeInMilliseconds,
|
|
logger: BufferLogger.test(),
|
|
);
|
|
|
|
final List<Uri> discoveredUris = <Uri>[];
|
|
discoverer.uris.listen((Uri uri) {
|
|
discoveredUris.add(uri);
|
|
});
|
|
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12346/PTwjm8Ii8qg=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
|
|
time.elapse(kThrottleTimeInMilliseconds);
|
|
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12345/PTwjm8Ii8qc=/');
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:12344/PTwjm8Ii8qf=/');
|
|
|
|
time.elapse(kThrottleTimeInMilliseconds);
|
|
|
|
expect(discoveredUris.length, 2);
|
|
expect(discoveredUris[0].port, 12345);
|
|
expect('${discoveredUris[0]}', 'http://127.0.0.1:12345/PTwjm8Ii8qg=/');
|
|
expect(discoveredUris[1].port, 12345);
|
|
expect('${discoveredUris[1]}', 'http://127.0.0.1:12345/PTwjm8Ii8qc=/');
|
|
});
|
|
});
|
|
});
|
|
|
|
group('port forwarding', () {
|
|
testWithoutContext('default port', () async {
|
|
final FakeDeviceLogReader logReader = FakeDeviceLogReader();
|
|
final ProtocolDiscovery discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
portForwarder: MockPortForwarder(99),
|
|
hostPort: null,
|
|
devicePort: null,
|
|
ipv6: false,
|
|
logger: BufferLogger.test(),
|
|
);
|
|
|
|
// Get next port future.
|
|
final Future<Uri> nextUri = discoverer.uri;
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:54804/PTwjm8Ii8qg=/');
|
|
final Uri uri = await nextUri;
|
|
expect(uri.port, 99);
|
|
expect('$uri', 'http://127.0.0.1:99/PTwjm8Ii8qg=/');
|
|
|
|
await discoverer.cancel();
|
|
await logReader.dispose();
|
|
});
|
|
|
|
testWithoutContext('specified port', () async {
|
|
final FakeDeviceLogReader logReader = FakeDeviceLogReader();
|
|
final ProtocolDiscovery discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
portForwarder: MockPortForwarder(99),
|
|
hostPort: 1243,
|
|
devicePort: null,
|
|
ipv6: false,
|
|
logger: BufferLogger.test(),
|
|
);
|
|
|
|
// Get next port future.
|
|
final Future<Uri> nextUri = discoverer.uri;
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:54804/PTwjm8Ii8qg=/');
|
|
final Uri uri = await nextUri;
|
|
expect(uri.port, 1243);
|
|
expect('$uri', 'http://127.0.0.1:1243/PTwjm8Ii8qg=/');
|
|
|
|
await discoverer.cancel();
|
|
await logReader.dispose();
|
|
});
|
|
|
|
testWithoutContext('specified port zero', () async {
|
|
final FakeDeviceLogReader logReader = FakeDeviceLogReader();
|
|
final ProtocolDiscovery discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
portForwarder: MockPortForwarder(99),
|
|
hostPort: 0,
|
|
devicePort: null,
|
|
ipv6: false,
|
|
logger: BufferLogger.test(),
|
|
);
|
|
|
|
// Get next port future.
|
|
final Future<Uri> nextUri = discoverer.uri;
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:54804/PTwjm8Ii8qg=/');
|
|
final Uri uri = await nextUri;
|
|
expect(uri.port, 99);
|
|
expect('$uri', 'http://127.0.0.1:99/PTwjm8Ii8qg=/');
|
|
|
|
await discoverer.cancel();
|
|
await logReader.dispose();
|
|
});
|
|
|
|
testWithoutContext('ipv6', () async {
|
|
final FakeDeviceLogReader logReader = FakeDeviceLogReader();
|
|
final ProtocolDiscovery discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
portForwarder: MockPortForwarder(99),
|
|
hostPort: 54777,
|
|
ipv6: true,
|
|
devicePort: null,
|
|
logger: BufferLogger.test(),
|
|
);
|
|
|
|
// Get next port future.
|
|
final Future<Uri> nextUri = discoverer.uri;
|
|
logReader.addLine('I/flutter : Observatory listening on http://127.0.0.1:54804/PTwjm8Ii8qg=/');
|
|
final Uri uri = await nextUri;
|
|
expect(uri.port, 54777);
|
|
expect('$uri', 'http://[::1]:54777/PTwjm8Ii8qg=/');
|
|
|
|
await discoverer.cancel();
|
|
await logReader.dispose();
|
|
});
|
|
|
|
testWithoutContext('ipv6 with Ascii Escape code', () async {
|
|
final FakeDeviceLogReader logReader = FakeDeviceLogReader();
|
|
final ProtocolDiscovery discoverer = ProtocolDiscovery.observatory(
|
|
logReader,
|
|
portForwarder: MockPortForwarder(99),
|
|
hostPort: 54777,
|
|
ipv6: true,
|
|
devicePort: null,
|
|
logger: BufferLogger.test(),
|
|
);
|
|
|
|
// Get next port future.
|
|
final Future<Uri> nextUri = discoverer.uri;
|
|
logReader.addLine('I/flutter : Observatory listening on http://[::1]:54777/PTwjm8Ii8qg=/\x1b[');
|
|
final Uri uri = await nextUri;
|
|
expect(uri.port, 54777);
|
|
expect('$uri', 'http://[::1]:54777/PTwjm8Ii8qg=/');
|
|
|
|
await discoverer.cancel();
|
|
await logReader.dispose();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
class MockPortForwarder extends DevicePortForwarder {
|
|
MockPortForwarder([this.availablePort]);
|
|
|
|
final int availablePort;
|
|
|
|
@override
|
|
Future<int> forward(int devicePort, { int hostPort }) async {
|
|
hostPort ??= 0;
|
|
if (hostPort == 0) {
|
|
return availablePort;
|
|
}
|
|
return hostPort;
|
|
}
|
|
|
|
@override
|
|
List<ForwardedPort> get forwardedPorts => throw 'not implemented';
|
|
|
|
@override
|
|
Future<void> unforward(ForwardedPort forwardedPort) {
|
|
throw 'not implemented';
|
|
}
|
|
|
|
@override
|
|
Future<void> dispose() async {}
|
|
}
|