This reverts commit adc9dde3ba8563eebb824feb689f95eb947ab745. - Fixed issue where `FallbackDiscovery` would hold on to a `VmService` when launching on iOS devices, causing DDS to fail to start - Fixed `flutter drive` case where DDS is already running in another flutter_tools instance
This commit is contained in:
parent
a4d570f0dd
commit
3a5a3eaf68
@ -11,6 +11,7 @@ void main() {
|
||||
macroPerfTest(
|
||||
'picture_cache_perf',
|
||||
kPictureCacheRouteName,
|
||||
timeout: const Duration(seconds: 60),
|
||||
pageDelay: const Duration(seconds: 1),
|
||||
driverOps: (FlutterDriver driver) async {
|
||||
final SerializableFinder tabBarView = find.byValueKey('tabbar_view');
|
||||
|
@ -38,6 +38,10 @@ void main() {
|
||||
await binding.endOfFrame;
|
||||
});
|
||||
|
||||
tearDownAll(() {
|
||||
vmService.dispose();
|
||||
});
|
||||
|
||||
test('Image painting events - deduplicates across frames', () async {
|
||||
final Completer<Event> completer = Completer<Event>();
|
||||
vmService.onExtensionEvent.first.then(completer.complete);
|
||||
|
50
packages/flutter_tools/lib/src/base/dds.dart
Normal file
50
packages/flutter_tools/lib/src/base/dds.dart
Normal file
@ -0,0 +1,50 @@
|
||||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:dds/dds.dart' as dds;
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import 'io.dart' as io;
|
||||
import 'logger.dart';
|
||||
|
||||
/// Helper class to launch a [dds.DartDevelopmentService]. Allows for us to
|
||||
/// mock out this functionality for testing purposes.
|
||||
class DartDevelopmentService {
|
||||
DartDevelopmentService({@required this.logger});
|
||||
|
||||
final Logger logger;
|
||||
dds.DartDevelopmentService _ddsInstance;
|
||||
|
||||
Future<void> startDartDevelopmentService(
|
||||
Uri observatoryUri,
|
||||
bool ipv6,
|
||||
) async {
|
||||
final Uri ddsUri = Uri(
|
||||
scheme: 'http',
|
||||
host: (ipv6 ?
|
||||
io.InternetAddress.loopbackIPv6 :
|
||||
io.InternetAddress.loopbackIPv4
|
||||
).host,
|
||||
port: 0,
|
||||
);
|
||||
logger.printTrace(
|
||||
'Launching a Dart Developer Service (DDS) instance at $ddsUri, '
|
||||
'connecting to VM service at $observatoryUri.',
|
||||
);
|
||||
try {
|
||||
_ddsInstance = await dds.DartDevelopmentService.startDartDevelopmentService(
|
||||
observatoryUri,
|
||||
serviceUri: ddsUri,
|
||||
);
|
||||
logger.printTrace('DDS is listening at ${_ddsInstance.uri}.');
|
||||
} on dds.DartDevelopmentServiceException catch (e) {
|
||||
logger.printError('Warning: Failed to start DDS: ${e.message}');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> shutdown() async => await _ddsInstance?.shutdown();
|
||||
}
|
@ -102,6 +102,7 @@ class AttachCommand extends FlutterCommand {
|
||||
'and progress in machine friendly format.',
|
||||
);
|
||||
usesTrackWidgetCreation(verboseHelp: verboseHelp);
|
||||
addDdsOptions(verboseHelp: verboseHelp);
|
||||
hotRunnerFactory ??= HotRunnerFactory();
|
||||
}
|
||||
|
||||
@ -388,7 +389,7 @@ class AttachCommand extends FlutterCommand {
|
||||
);
|
||||
flutterDevice.observatoryUris = observatoryUris;
|
||||
final List<FlutterDevice> flutterDevices = <FlutterDevice>[flutterDevice];
|
||||
final DebuggingOptions debuggingOptions = DebuggingOptions.enabled(getBuildInfo());
|
||||
final DebuggingOptions debuggingOptions = DebuggingOptions.enabled(getBuildInfo(), disableDds: boolArg('disable-dds'));
|
||||
|
||||
return getBuildInfo().isDebug
|
||||
? hotRunnerFactory.build(
|
||||
|
@ -5,6 +5,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:dds/dds.dart' as dds;
|
||||
import 'package:vm_service/vm_service_io.dart' as vm_service;
|
||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
import 'package:meta/meta.dart';
|
||||
@ -244,6 +245,17 @@ class DriveCommand extends RunCommandBase {
|
||||
throwToolExit('Application failed to start. Will not run test. Quitting.', exitCode: 1);
|
||||
}
|
||||
observatoryUri = result.observatoryUri.toString();
|
||||
// TODO(bkonyi): add web support (https://github.com/flutter/flutter/issues/61259)
|
||||
if (!isWebPlatform) {
|
||||
try {
|
||||
// If there's another flutter_tools instance still connected to the target
|
||||
// application, DDS will already be running remotely and this call will fail.
|
||||
// We can ignore this and continue to use the remote DDS instance.
|
||||
await device.dds.startDartDevelopmentService(Uri.parse(observatoryUri), ipv6);
|
||||
} on dds.DartDevelopmentServiceException catch(_) {
|
||||
globals.printTrace('Note: DDS is already connected to $observatoryUri.');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
globals.printStatus('Will connect to already running application instance.');
|
||||
observatoryUri = stringArg('use-existing-app');
|
||||
|
@ -219,6 +219,7 @@ class RunCommand extends RunCommandBase {
|
||||
'Currently this is only supported on Android devices. This option '
|
||||
'cannot be paired with --use-application-binary.'
|
||||
);
|
||||
addDdsOptions(verboseHelp: verboseHelp);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -385,6 +386,7 @@ class RunCommand extends RunCommandBase {
|
||||
buildInfo,
|
||||
startPaused: boolArg('start-paused'),
|
||||
disableServiceAuthCodes: boolArg('disable-service-auth-codes'),
|
||||
disableDds: boolArg('disable-dds'),
|
||||
dartFlags: stringArg('dart-flags') ?? '',
|
||||
useTestFonts: boolArg('use-test-fonts'),
|
||||
enableSoftwareRendering: boolArg('enable-software-rendering'),
|
||||
|
@ -16,6 +16,7 @@ import 'application_package.dart';
|
||||
import 'artifacts.dart';
|
||||
import 'base/config.dart';
|
||||
import 'base/context.dart';
|
||||
import 'base/dds.dart';
|
||||
import 'base/file_system.dart';
|
||||
import 'base/io.dart';
|
||||
import 'base/logger.dart';
|
||||
@ -584,6 +585,12 @@ abstract class Device {
|
||||
/// Get the port forwarder for this device.
|
||||
DevicePortForwarder get portForwarder;
|
||||
|
||||
/// Get the DDS instance for this device.
|
||||
DartDevelopmentService get dds => _dds ??= DartDevelopmentService(
|
||||
logger: globals.logger,
|
||||
);
|
||||
DartDevelopmentService _dds;
|
||||
|
||||
/// Clear the device's logs.
|
||||
void clearLogs();
|
||||
|
||||
@ -757,6 +764,7 @@ class DebuggingOptions {
|
||||
this.buildInfo, {
|
||||
this.startPaused = false,
|
||||
this.disableServiceAuthCodes = false,
|
||||
this.disableDds = false,
|
||||
this.dartFlags = '',
|
||||
this.enableSoftwareRendering = false,
|
||||
this.skiaDeterministicRendering = false,
|
||||
@ -799,6 +807,7 @@ class DebuggingOptions {
|
||||
startPaused = false,
|
||||
dartFlags = '',
|
||||
disableServiceAuthCodes = false,
|
||||
disableDds = false,
|
||||
enableSoftwareRendering = false,
|
||||
skiaDeterministicRendering = false,
|
||||
traceSkia = false,
|
||||
@ -818,6 +827,7 @@ class DebuggingOptions {
|
||||
final bool startPaused;
|
||||
final String dartFlags;
|
||||
final bool disableServiceAuthCodes;
|
||||
final bool disableDds;
|
||||
final bool enableSoftwareRendering;
|
||||
final bool skiaDeterministicRendering;
|
||||
final bool traceSkia;
|
||||
|
@ -52,6 +52,13 @@ Future<vm_service.VmService> _kDefaultFuchsiaIsolateDiscoveryConnector(Uri uri)
|
||||
return connectToVmService(uri);
|
||||
}
|
||||
|
||||
Future<void> _kDefaultDartDevelopmentServiceStarter(
|
||||
Device device,
|
||||
Uri observatoryUri,
|
||||
) async {
|
||||
await device.dds.startDartDevelopmentService(observatoryUri, true);
|
||||
}
|
||||
|
||||
/// Read the log for a particular device.
|
||||
class _FuchsiaLogReader extends DeviceLogReader {
|
||||
_FuchsiaLogReader(this._device, this._systemClock, [this._app]);
|
||||
@ -695,6 +702,7 @@ class FuchsiaIsolateDiscoveryProtocol {
|
||||
this._device,
|
||||
this._isolateName, [
|
||||
this._vmServiceConnector = _kDefaultFuchsiaIsolateDiscoveryConnector,
|
||||
this._ddsStarter = _kDefaultDartDevelopmentServiceStarter,
|
||||
this._pollOnce = false,
|
||||
]);
|
||||
|
||||
@ -704,6 +712,7 @@ class FuchsiaIsolateDiscoveryProtocol {
|
||||
final String _isolateName;
|
||||
final Completer<Uri> _foundUri = Completer<Uri>();
|
||||
final Future<vm_service.VmService> Function(Uri) _vmServiceConnector;
|
||||
final Future<void> Function(Device, Uri) _ddsStarter;
|
||||
// whether to only poll once.
|
||||
final bool _pollOnce;
|
||||
Timer _pollingTimer;
|
||||
@ -746,6 +755,7 @@ class FuchsiaIsolateDiscoveryProtocol {
|
||||
final int localPort = await _device.portForwarder.forward(port);
|
||||
try {
|
||||
final Uri uri = Uri.parse('http://[$_ipv6Loopback]:$localPort');
|
||||
await _ddsStarter(_device, uri);
|
||||
service = await _vmServiceConnector(uri);
|
||||
_ports[port] = service;
|
||||
} on SocketException catch (err) {
|
||||
|
@ -431,7 +431,7 @@ class IOSDevice extends Device {
|
||||
);
|
||||
final Uri localUri = await fallbackDiscovery.discover(
|
||||
assumedDevicePort: assumedObservatoryPort,
|
||||
deivce: this,
|
||||
device: this,
|
||||
usesIpv6: ipv6,
|
||||
hostVmservicePort: debuggingOptions.hostVmServicePort,
|
||||
packageId: packageId,
|
||||
|
@ -67,7 +67,7 @@ class FallbackDiscovery {
|
||||
Future<Uri> discover({
|
||||
@required int assumedDevicePort,
|
||||
@required String packageId,
|
||||
@required Device deivce,
|
||||
@required Device device,
|
||||
@required bool usesIpv6,
|
||||
@required int hostVmservicePort,
|
||||
@required String packageName,
|
||||
@ -84,7 +84,7 @@ class FallbackDiscovery {
|
||||
try {
|
||||
final Uri result = await _mDnsObservatoryDiscovery.getObservatoryUri(
|
||||
packageId,
|
||||
deivce,
|
||||
device,
|
||||
usesIpv6: usesIpv6,
|
||||
hostVmservicePort: hostVmservicePort,
|
||||
);
|
||||
@ -173,6 +173,10 @@ class FallbackDiscovery {
|
||||
'success',
|
||||
flutterUsage: _flutterUsage,
|
||||
).send();
|
||||
|
||||
// We absolutely must dispose this vmService instance, otherwise
|
||||
// DDS will fail to start.
|
||||
vmService.dispose();
|
||||
return Uri.parse('http://localhost:$hostPort');
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +209,8 @@ class FlutterDevice {
|
||||
ReloadMethod reloadMethod,
|
||||
GetSkSLMethod getSkSLMethod,
|
||||
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
|
||||
bool disableDds = false,
|
||||
bool ipv6 = false,
|
||||
}) {
|
||||
final Completer<void> completer = Completer<void>();
|
||||
StreamSubscription<void> subscription;
|
||||
@ -219,7 +221,12 @@ class FlutterDevice {
|
||||
globals.printTrace('Connecting to service protocol: $observatoryUri');
|
||||
isWaitingForVm = true;
|
||||
vm_service.VmService service;
|
||||
|
||||
if (!disableDds) {
|
||||
await device.dds.startDartDevelopmentService(
|
||||
observatoryUri,
|
||||
ipv6,
|
||||
);
|
||||
}
|
||||
try {
|
||||
service = await connectToVmService(
|
||||
observatoryUri,
|
||||
@ -1005,12 +1012,14 @@ abstract class ResidentRunner {
|
||||
await stopEchoingDeviceLog();
|
||||
await preExit();
|
||||
await exitApp();
|
||||
await shutdownDartDevelopmentService();
|
||||
}
|
||||
|
||||
Future<void> detach() async {
|
||||
await shutdownDevtools();
|
||||
await stopEchoingDeviceLog();
|
||||
await preExit();
|
||||
await shutdownDartDevelopmentService();
|
||||
appFinished();
|
||||
}
|
||||
|
||||
@ -1177,6 +1186,14 @@ abstract class ResidentRunner {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> shutdownDartDevelopmentService() async {
|
||||
await Future.wait<void>(
|
||||
flutterDevices.map<Future<void>>(
|
||||
(FlutterDevice device) => device.device?.dds?.shutdown()
|
||||
).where((Future<void> element) => element != null)
|
||||
);
|
||||
}
|
||||
|
||||
@protected
|
||||
void cacheInitialDillCompilation() {
|
||||
if (_dillOutputPath != null) {
|
||||
@ -1230,9 +1247,11 @@ abstract class ResidentRunner {
|
||||
reloadSources: reloadSources,
|
||||
restart: restart,
|
||||
compileExpression: compileExpression,
|
||||
disableDds: debuggingOptions.disableDds,
|
||||
reloadMethod: reloadMethod,
|
||||
getSkSLMethod: getSkSLMethod,
|
||||
printStructuredErrorLogMethod: printStructuredErrorLog,
|
||||
ipv6: ipv6,
|
||||
);
|
||||
// This will wait for at least one flutter view before returning.
|
||||
final Status status = globals.logger.startProgress(
|
||||
|
@ -298,6 +298,19 @@ abstract class FlutterCommand extends Command<void> {
|
||||
_usesPortOption = true;
|
||||
}
|
||||
|
||||
void addDdsOptions({@required bool verboseHelp}) {
|
||||
argParser.addFlag(
|
||||
'disable-dds',
|
||||
hide: !verboseHelp,
|
||||
help: 'Disable the Dart Developer Service (DDS). This flag should only be provided'
|
||||
' when attaching to an application with an existing DDS instance (e.g.,'
|
||||
' attaching to an application currently connected to by "flutter run") or'
|
||||
' when running certain tests.\n'
|
||||
'Note: passing this flag may degrade IDE functionality if a DDS instance is not'
|
||||
' already connected to the target application.'
|
||||
);
|
||||
}
|
||||
|
||||
/// Gets the vmservice port provided to in the 'observatory-port' or
|
||||
/// 'host-vmservice-port option.
|
||||
///
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:dds/dds.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:package_config/package_config.dart';
|
||||
import 'package:stream_channel/stream_channel.dart';
|
||||
@ -514,7 +515,7 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
Uri processObservatoryUri;
|
||||
_pipeStandardStreamsToConsole(
|
||||
process,
|
||||
reportObservatoryUri: (Uri detectedUri) {
|
||||
reportObservatoryUri: (Uri detectedUri) async {
|
||||
assert(processObservatoryUri == null);
|
||||
assert(explicitObservatoryPort == null ||
|
||||
explicitObservatoryPort == detectedUri.port);
|
||||
@ -527,13 +528,14 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
globals.printTrace('test $ourTestCount: using observatory uri $detectedUri from pid ${process.pid}');
|
||||
}
|
||||
processObservatoryUri = detectedUri;
|
||||
await DartDevelopmentService.startDartDevelopmentService(processObservatoryUri);
|
||||
{
|
||||
globals.printTrace('Connecting to service protocol: $processObservatoryUri');
|
||||
final Future<vm_service.VmService> localVmService = connectToVmService(processObservatoryUri,
|
||||
compileExpression: _compileExpressionService);
|
||||
localVmService.then((vm_service.VmService vmservice) {
|
||||
unawaited(localVmService.then((vm_service.VmService vmservice) {
|
||||
globals.printTrace('Successfully connected to service protocol: $processObservatoryUri');
|
||||
});
|
||||
}));
|
||||
}
|
||||
gotProcessObservatoryUri.complete();
|
||||
watcher?.handleStartedProcess(
|
||||
@ -870,8 +872,9 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
void _pipeStandardStreamsToConsole(
|
||||
Process process, {
|
||||
void startTimeoutTimer(),
|
||||
void reportObservatoryUri(Uri uri),
|
||||
Future<void> reportObservatoryUri(Uri uri),
|
||||
}) {
|
||||
|
||||
const String observatoryString = 'Observatory listening on ';
|
||||
for (final Stream<List<int>> stream in <Stream<List<int>>>[
|
||||
process.stderr,
|
||||
@ -881,7 +884,7 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
.transform<String>(utf8.decoder)
|
||||
.transform<String>(const LineSplitter())
|
||||
.listen(
|
||||
(String line) {
|
||||
(String line) async {
|
||||
if (line == _kStartTimeoutTimerMessage) {
|
||||
if (startTimeoutTimer != null) {
|
||||
startTimeoutTimer();
|
||||
@ -894,7 +897,7 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
try {
|
||||
final Uri uri = Uri.parse(line.substring(observatoryString.length));
|
||||
if (reportObservatoryUri != null) {
|
||||
reportObservatoryUri(uri);
|
||||
await reportObservatoryUri(uri);
|
||||
}
|
||||
} on Exception catch (error) {
|
||||
globals.printError('Could not parse shell observatory port message: $error');
|
||||
|
@ -22,12 +22,6 @@ class Tracing {
|
||||
Tracing(this.vmService);
|
||||
|
||||
static const String firstUsefulFrameEventName = kFirstFrameRasterizedEventName;
|
||||
|
||||
static Future<Tracing> connect(Uri uri) async {
|
||||
final vm_service.VmService observatory = await connectToVmService(uri);
|
||||
return Tracing(observatory);
|
||||
}
|
||||
|
||||
final vm_service.VmService vmService;
|
||||
|
||||
Future<void> startTracing() async {
|
||||
|
@ -11,6 +11,7 @@ dependencies:
|
||||
# To update these, use "flutter update-packages --force-upgrade".
|
||||
archive: 2.0.13
|
||||
args: 1.6.0
|
||||
dds: 1.3.1
|
||||
dwds: 5.1.0
|
||||
completion: 0.2.2
|
||||
coverage: 0.14.0
|
||||
@ -64,6 +65,7 @@ dependencies:
|
||||
http_parser: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
io: 0.3.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
js: 0.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
json_rpc_2: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
logging: 0.11.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
matcher: 0.12.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
mime: 0.9.6+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
@ -108,4 +110,4 @@ dartdoc:
|
||||
# Exclude this package from the hosted API docs.
|
||||
nodoc: true
|
||||
|
||||
# PUBSPEC CHECKSUM: 9693
|
||||
# PUBSPEC CHECKSUM: f65b
|
||||
|
@ -7,6 +7,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/dds.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
@ -71,6 +72,7 @@ void main() {
|
||||
|
||||
FakeDeviceLogReader mockLogReader;
|
||||
MockPortForwarder portForwarder;
|
||||
MockDartDevelopmentService mockDds;
|
||||
MockAndroidDevice device;
|
||||
MockHttpClient httpClient;
|
||||
|
||||
@ -78,6 +80,7 @@ void main() {
|
||||
mockLogReader = FakeDeviceLogReader();
|
||||
portForwarder = MockPortForwarder();
|
||||
device = MockAndroidDevice();
|
||||
mockDds = MockDartDevelopmentService();
|
||||
when(device.portForwarder)
|
||||
.thenReturn(portForwarder);
|
||||
when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort')))
|
||||
@ -86,6 +89,8 @@ void main() {
|
||||
.thenReturn(<ForwardedPort>[ForwardedPort(hostPort, devicePort)]);
|
||||
when(portForwarder.unforward(any))
|
||||
.thenAnswer((_) async {});
|
||||
when(device.dds).thenReturn(mockDds);
|
||||
when(mockDds.startDartDevelopmentService(any, false)).thenReturn(null);
|
||||
|
||||
final HttpClientRequest httpClientRequest = MockHttpClientRequest();
|
||||
httpClient = MockHttpClient();
|
||||
@ -286,11 +291,14 @@ void main() {
|
||||
const int hostPort = 42;
|
||||
final FakeDeviceLogReader mockLogReader = FakeDeviceLogReader();
|
||||
final MockPortForwarder portForwarder = MockPortForwarder();
|
||||
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
|
||||
final MockAndroidDevice device = MockAndroidDevice();
|
||||
final MockHotRunner mockHotRunner = MockHotRunner();
|
||||
final MockHotRunnerFactory mockHotRunnerFactory = MockHotRunnerFactory();
|
||||
when(device.portForwarder)
|
||||
.thenReturn(portForwarder);
|
||||
when(device.dds)
|
||||
.thenReturn(mockDds);
|
||||
when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort')))
|
||||
.thenAnswer((_) async => hostPort);
|
||||
when(portForwarder.forwardedPorts)
|
||||
@ -309,6 +317,7 @@ void main() {
|
||||
)).thenReturn(mockHotRunner);
|
||||
when(mockHotRunner.exited).thenReturn(false);
|
||||
when(mockHotRunner.isWaitingForObservatory).thenReturn(false);
|
||||
when(mockDds.startDartDevelopmentService(any, false)).thenReturn(null);
|
||||
|
||||
testDeviceManager.addDevice(device);
|
||||
when(device.getLogReader(includePastLogs: anyNamed('includePastLogs')))
|
||||
@ -359,10 +368,14 @@ void main() {
|
||||
const int hostPort = 42;
|
||||
final FakeDeviceLogReader mockLogReader = FakeDeviceLogReader();
|
||||
final MockPortForwarder portForwarder = MockPortForwarder();
|
||||
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
|
||||
final MockIOSDevice device = MockIOSDevice();
|
||||
final MockHotRunner mockHotRunner = MockHotRunner();
|
||||
final MockHotRunnerFactory mockHotRunnerFactory = MockHotRunnerFactory();
|
||||
when(device.portForwarder).thenReturn(portForwarder);
|
||||
when(device.portForwarder)
|
||||
.thenReturn(portForwarder);
|
||||
when(device.dds)
|
||||
.thenReturn(mockDds);
|
||||
when(device.getLogReader(includePastLogs: anyNamed('includePastLogs')))
|
||||
.thenAnswer((_) => mockLogReader);
|
||||
when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort')))
|
||||
@ -383,6 +396,7 @@ void main() {
|
||||
)).thenReturn(mockHotRunner);
|
||||
when(mockHotRunner.exited).thenReturn(false);
|
||||
when(mockHotRunner.isWaitingForObservatory).thenReturn(false);
|
||||
when(mockDds.startDartDevelopmentService(any, false)).thenReturn(null);
|
||||
|
||||
testDeviceManager.addDevice(device);
|
||||
|
||||
@ -415,6 +429,7 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
portForwarder = MockPortForwarder();
|
||||
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
|
||||
device = MockAndroidDevice();
|
||||
|
||||
when(device.portForwarder)
|
||||
@ -425,6 +440,10 @@ void main() {
|
||||
.thenReturn(<ForwardedPort>[ForwardedPort(hostPort, devicePort)]);
|
||||
when(portForwarder.unforward(any))
|
||||
.thenAnswer((_) async {});
|
||||
when(device.dds)
|
||||
.thenReturn(mockDds);
|
||||
when(mockDds.startDartDevelopmentService(any, any))
|
||||
.thenReturn(null);
|
||||
});
|
||||
|
||||
testUsingContext('succeeds in ipv4 mode', () async {
|
||||
@ -795,6 +814,7 @@ class TestHotRunnerFactory extends HotRunnerFactory {
|
||||
}
|
||||
}
|
||||
|
||||
class MockDartDevelopmentService extends Mock implements DartDevelopmentService {}
|
||||
class MockProcessManager extends Mock implements ProcessManager {}
|
||||
class MockProcess extends Mock implements Process {}
|
||||
class MockHttpClientRequest extends Mock implements HttpClientRequest {}
|
||||
|
@ -8,6 +8,7 @@ import 'package:file/memory.dart';
|
||||
import 'package:file_testing/file_testing.dart';
|
||||
import 'package:flutter_tools/src/android/android_device.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/dds.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
@ -67,6 +68,12 @@ void main() {
|
||||
tryToDelete(tempDir);
|
||||
});
|
||||
|
||||
void applyDdsMocks(Device device) {
|
||||
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
|
||||
when(device.dds).thenReturn(mockDds);
|
||||
when(mockDds.startDartDevelopmentService(any, any)).thenReturn(null);
|
||||
}
|
||||
|
||||
testUsingContext('returns 1 when test file is not found', () async {
|
||||
testDeviceManager.addDevice(MockDevice());
|
||||
|
||||
@ -188,7 +195,9 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('returns 0 when test ends successfully', () async {
|
||||
testDeviceManager.addDevice(MockAndroidDevice());
|
||||
final MockAndroidDevice mockDevice = MockAndroidDevice();
|
||||
applyDdsMocks(mockDevice);
|
||||
testDeviceManager.addDevice(mockDevice);
|
||||
|
||||
final String testApp = globals.fs.path.join(tempDir.path, 'test', 'e2e.dart');
|
||||
final String testFile = globals.fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart');
|
||||
@ -226,7 +235,9 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('returns exitCode set by test runner', () async {
|
||||
testDeviceManager.addDevice(MockDevice());
|
||||
final MockDevice mockDevice = MockDevice();
|
||||
applyDdsMocks(mockDevice);
|
||||
testDeviceManager.addDevice(mockDevice);
|
||||
|
||||
final String testApp = globals.fs.path.join(tempDir.path, 'test', 'e2e.dart');
|
||||
final String testFile = globals.fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart');
|
||||
@ -373,6 +384,7 @@ void main() {
|
||||
|
||||
Future<Device> appStarterSetup() async {
|
||||
final Device mockDevice = MockDevice();
|
||||
applyDdsMocks(mockDevice);
|
||||
testDeviceManager.addDevice(mockDevice);
|
||||
|
||||
final FakeDeviceLogReader mockDeviceLogReader = FakeDeviceLogReader();
|
||||
@ -508,6 +520,7 @@ void main() {
|
||||
|
||||
Future<Device> appStarterSetup() async {
|
||||
final Device mockDevice = MockDevice();
|
||||
applyDdsMocks(mockDevice);
|
||||
testDeviceManager.addDevice(mockDevice);
|
||||
|
||||
final FakeDeviceLogReader mockDeviceLogReader = FakeDeviceLogReader();
|
||||
@ -791,5 +804,5 @@ class MockDevice extends Mock implements Device {
|
||||
}
|
||||
|
||||
class MockAndroidDevice extends Mock implements AndroidDevice { }
|
||||
|
||||
class MockDartDevelopmentService extends Mock implements DartDevelopmentService { }
|
||||
class MockLaunchResult extends Mock implements LaunchResult { }
|
||||
|
@ -139,6 +139,8 @@ class TestFlutterDevice extends FlutterDevice {
|
||||
ReloadMethod reloadMethod,
|
||||
GetSkSLMethod getSkSLMethod,
|
||||
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
|
||||
bool disableDds = false,
|
||||
bool ipv6 = false,
|
||||
}) async {
|
||||
throw exception;
|
||||
}
|
||||
|
@ -728,6 +728,7 @@ void main() {
|
||||
fuchsiaDevice,
|
||||
expectedIsolateName,
|
||||
(Uri uri) async => fakeVmServiceHost.vmService,
|
||||
(Device device, Uri uri) => null,
|
||||
true, // only poll once.
|
||||
);
|
||||
|
||||
|
@ -578,6 +578,8 @@ class TestFlutterDevice extends FlutterDevice {
|
||||
ReloadMethod reloadMethod,
|
||||
GetSkSLMethod getSkSLMethod,
|
||||
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
|
||||
bool disableDds = false,
|
||||
bool ipv6 = false,
|
||||
}) async {
|
||||
throw exception;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ void main() {
|
||||
|
||||
expect(await fallbackDiscovery.discover(
|
||||
assumedDevicePort: 23,
|
||||
deivce: null,
|
||||
device: null,
|
||||
hostVmservicePort: 1,
|
||||
packageId: null,
|
||||
usesIpv6: false,
|
||||
@ -86,7 +86,7 @@ void main() {
|
||||
});
|
||||
expect(await fallbackDiscovery.discover(
|
||||
assumedDevicePort: 23,
|
||||
deivce: null,
|
||||
device: null,
|
||||
hostVmservicePort: 1,
|
||||
packageId: null,
|
||||
usesIpv6: false,
|
||||
@ -117,7 +117,7 @@ void main() {
|
||||
|
||||
expect(await fallbackDiscovery.discover(
|
||||
assumedDevicePort: 23,
|
||||
deivce: null,
|
||||
device: null,
|
||||
hostVmservicePort: 1,
|
||||
packageId: 'hello',
|
||||
usesIpv6: false,
|
||||
@ -139,7 +139,7 @@ void main() {
|
||||
|
||||
expect(await fallbackDiscovery.discover(
|
||||
assumedDevicePort: 23,
|
||||
deivce: null,
|
||||
device: null,
|
||||
hostVmservicePort: 1,
|
||||
packageId: 'hello',
|
||||
usesIpv6: false,
|
||||
@ -161,7 +161,7 @@ void main() {
|
||||
|
||||
expect(await fallbackDiscovery.discover(
|
||||
assumedDevicePort: 23,
|
||||
deivce: null,
|
||||
device: null,
|
||||
hostVmservicePort: 1,
|
||||
packageId: 'hello',
|
||||
usesIpv6: false,
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_tools/src/base/dds.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/widget_cache.dart';
|
||||
@ -2052,8 +2053,11 @@ void main() {
|
||||
testUsingContext('connect sets up log reader', () => testbed.run(() async {
|
||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
||||
final MockDevice mockDevice = MockDevice();
|
||||
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
|
||||
final MockDeviceLogReader mockLogReader = MockDeviceLogReader();
|
||||
when(mockDevice.getLogReader(app: anyNamed('app'))).thenReturn(mockLogReader);
|
||||
when(mockDevice.dds).thenReturn(mockDds);
|
||||
when(mockDds.startDartDevelopmentService(any, any)).thenReturn(null);
|
||||
|
||||
final TestFlutterDevice flutterDevice = TestFlutterDevice(
|
||||
mockDevice,
|
||||
@ -2085,6 +2089,7 @@ void main() {
|
||||
}
|
||||
|
||||
class MockFlutterDevice extends Mock implements FlutterDevice {}
|
||||
class MockDartDevelopmentService extends Mock implements DartDevelopmentService {}
|
||||
class MockVMService extends Mock implements vm_service.VmService {}
|
||||
class MockDevFS extends Mock implements DevFS {}
|
||||
class MockDevice extends Mock implements Device {}
|
||||
@ -2138,6 +2143,8 @@ class FakeFlutterDevice extends FlutterDevice {
|
||||
Future<void> connect({
|
||||
ReloadSources reloadSources,
|
||||
Restart restart,
|
||||
bool disableDds = false,
|
||||
bool ipv6 = false,
|
||||
CompileExpression compileExpression,
|
||||
ReloadMethod reloadMethod,
|
||||
GetSkSLMethod getSkSLMethod,
|
||||
|
@ -21,7 +21,14 @@ void main() {
|
||||
tempDir = createResolvedTempDirectorySync('attach_test.');
|
||||
await _project.setUpIn(tempDir);
|
||||
_flutterRun = FlutterRunTestDriver(tempDir, logPrefix: ' RUN ');
|
||||
_flutterAttach = FlutterRunTestDriver(tempDir, logPrefix: 'ATTACH ');
|
||||
_flutterAttach = FlutterRunTestDriver(
|
||||
tempDir,
|
||||
logPrefix: 'ATTACH ',
|
||||
// Only one DDS instance can be connected to the VM service at a time.
|
||||
// DDS can also only initialize if the VM service doesn't have any existing
|
||||
// clients, so we'll just let _flutterRun be responsible for spawning DDS.
|
||||
spawnDdsInstance: false,
|
||||
);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
@ -58,7 +65,11 @@ void main() {
|
||||
await _flutterRun.run(withDebugger: true);
|
||||
await _flutterAttach.attach(_flutterRun.vmServicePort);
|
||||
await _flutterAttach.quit();
|
||||
_flutterAttach = FlutterRunTestDriver(tempDir, logPrefix: 'ATTACH-2');
|
||||
_flutterAttach = FlutterRunTestDriver(
|
||||
tempDir,
|
||||
logPrefix: 'ATTACH-2',
|
||||
spawnDdsInstance: false,
|
||||
);
|
||||
await _flutterAttach.attach(_flutterRun.vmServicePort);
|
||||
await _flutterAttach.hotReload();
|
||||
});
|
||||
|
@ -30,7 +30,6 @@ void main() {
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await _flutter.stop();
|
||||
tryToDelete(tempDir);
|
||||
});
|
||||
|
||||
@ -101,7 +100,6 @@ void main() {
|
||||
// We don't expect to see any output but want to write to stdout anyway.
|
||||
completer.complete();
|
||||
});
|
||||
|
||||
await _flutter.stop();
|
||||
|
||||
expect(stdout.toString(), isNot(contains(_exceptionStart)));
|
||||
@ -118,7 +116,6 @@ void main() {
|
||||
machine: false,
|
||||
);
|
||||
await _flutter.resume();
|
||||
|
||||
final Completer<void> completer = Completer<void>();
|
||||
bool lineFound = false;
|
||||
|
||||
|
@ -428,6 +428,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
|
||||
FlutterRunTestDriver(
|
||||
Directory projectFolder, {
|
||||
String logPrefix,
|
||||
this.spawnDdsInstance = true,
|
||||
}) : super(projectFolder, logPrefix: logPrefix);
|
||||
|
||||
String _currentRunningAppId;
|
||||
@ -449,6 +450,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
|
||||
if (!chrome)
|
||||
'--disable-service-auth-codes',
|
||||
if (machine) '--machine',
|
||||
if (!spawnDdsInstance) '--disable-dds',
|
||||
'-d',
|
||||
if (chrome)
|
||||
...<String>[
|
||||
@ -480,6 +482,8 @@ class FlutterRunTestDriver extends FlutterTestDriver {
|
||||
<String>[
|
||||
'attach',
|
||||
'--machine',
|
||||
if (!spawnDdsInstance)
|
||||
'--disable-dds',
|
||||
'-d',
|
||||
'flutter-tester',
|
||||
'--debug-port',
|
||||
@ -682,6 +686,8 @@ class FlutterRunTestDriver extends FlutterTestDriver {
|
||||
void _throwErrorResponse(String message) {
|
||||
throw '$message\n\n$_lastResponse\n\n${_errorBuffer.toString()}'.trim();
|
||||
}
|
||||
|
||||
final bool spawnDdsInstance;
|
||||
}
|
||||
|
||||
class FlutterTestTestDriver extends FlutterTestDriver {
|
||||
|
@ -39,6 +39,15 @@ void main() {
|
||||
tryToDelete(tempDir);
|
||||
});
|
||||
|
||||
test('getSupportedProtocols includes DDS', () async {
|
||||
final ProtocolList protocolList =
|
||||
await vmService.getSupportedProtocols();
|
||||
expect(protocolList.protocols, hasLength(2));
|
||||
for (final Protocol protocol in protocolList.protocols) {
|
||||
expect(protocol.protocolName, anyOf('VM Service', 'DDS'));
|
||||
}
|
||||
});
|
||||
|
||||
test('flutterVersion can be called', () async {
|
||||
final Response response =
|
||||
await vmService.callServiceExtension('s0.flutterVersion');
|
||||
|
Loading…
x
Reference in New Issue
Block a user