[flutter_tools] remove vm service (#55794)
Finishes the gradual vm service migration by deleting the flutter tooling's vm_service
This commit is contained in:
parent
c55b32204e
commit
534b0608ce
@ -4,6 +4,8 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
|
||||
import '../base/common.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../convert.dart';
|
||||
@ -123,39 +125,37 @@ class ScreenshotCommand extends FlutterCommand {
|
||||
}
|
||||
|
||||
Future<void> runSkia(File outputFile) async {
|
||||
final Map<String, dynamic> skp = await _invokeVmServiceRpc('_flutter.screenshotSkp');
|
||||
final Uri observatoryUri = Uri.parse(stringArg(_kObservatoryUri));
|
||||
final vm_service.VmService vmService = await connectToVmService(observatoryUri);
|
||||
final vm_service.Response skp = await vmService.screenshotSkp();
|
||||
outputFile ??= globals.fsUtils.getUniqueFile(
|
||||
globals.fs.currentDirectory,
|
||||
'flutter',
|
||||
'skp',
|
||||
);
|
||||
final IOSink sink = outputFile.openWrite();
|
||||
sink.add(base64.decode(skp['skp'] as String));
|
||||
sink.add(base64.decode(skp.json['skp'] as String));
|
||||
await sink.close();
|
||||
_showOutputFileInfo(outputFile);
|
||||
_ensureOutputIsNotJsonRpcError(outputFile);
|
||||
}
|
||||
|
||||
Future<void> runRasterizer(File outputFile) async {
|
||||
final Map<String, dynamic> response = await _invokeVmServiceRpc('_flutter.screenshot');
|
||||
final Uri observatoryUri = Uri.parse(stringArg(_kObservatoryUri));
|
||||
final vm_service.VmService vmService = await connectToVmService(observatoryUri);
|
||||
final vm_service.Response response = await vmService.screenshot();
|
||||
outputFile ??= globals.fsUtils.getUniqueFile(
|
||||
globals.fs.currentDirectory,
|
||||
'flutter',
|
||||
'png',
|
||||
);
|
||||
final IOSink sink = outputFile.openWrite();
|
||||
sink.add(base64.decode(response['screenshot'] as String));
|
||||
sink.add(base64.decode(response.json['screenshot'] as String));
|
||||
await sink.close();
|
||||
_showOutputFileInfo(outputFile);
|
||||
_ensureOutputIsNotJsonRpcError(outputFile);
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> _invokeVmServiceRpc(String method) async {
|
||||
final Uri observatoryUri = Uri.parse(stringArg(_kObservatoryUri));
|
||||
final VMService vmService = await VMService.connect(observatoryUri);
|
||||
return await vmService.vm.invokeRpcRaw(method);
|
||||
}
|
||||
|
||||
void _ensureOutputIsNotJsonRpcError(File outputFile) {
|
||||
if (outputFile.lengthSync() >= 1000) {
|
||||
return;
|
||||
|
@ -6,7 +6,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:package_config/package_config.dart';
|
||||
import 'package:vm_service/vm_service.dart' as vmservice;
|
||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
|
||||
import 'asset.dart';
|
||||
import 'base/context.dart';
|
||||
@ -223,40 +223,22 @@ abstract class DevFSOperations {
|
||||
class ServiceProtocolDevFSOperations implements DevFSOperations {
|
||||
ServiceProtocolDevFSOperations(this.vmService);
|
||||
|
||||
final VMService vmService;
|
||||
final vm_service.VmService vmService;
|
||||
|
||||
@override
|
||||
Future<Uri> create(String fsName) async {
|
||||
final Map<String, dynamic> response = await vmService.vm.createDevFS(fsName);
|
||||
return Uri.parse(response['uri'] as String);
|
||||
final vm_service.Response response = await vmService.createDevFS(fsName);
|
||||
return Uri.parse(response.json['uri'] as String);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<dynamic> destroy(String fsName) async {
|
||||
await vmService.vm.deleteDevFS(fsName);
|
||||
await vmService.deleteDevFS(fsName);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<dynamic> writeFile(String fsName, Uri deviceUri, DevFSContent content) async {
|
||||
List<int> bytes;
|
||||
try {
|
||||
bytes = await content.contentsAsBytes();
|
||||
} on Exception catch (e) {
|
||||
return e;
|
||||
}
|
||||
final String fileContents = base64.encode(bytes);
|
||||
try {
|
||||
return await vmService.vm.invokeRpcRaw(
|
||||
'_writeDevFSFile',
|
||||
params: <String, dynamic>{
|
||||
'fsName': fsName,
|
||||
'uri': deviceUri.toString(),
|
||||
'fileContents': fileContents,
|
||||
},
|
||||
);
|
||||
} on Exception catch (error) {
|
||||
globals.printTrace('DevFS: Failed to write $deviceUri: $error');
|
||||
}
|
||||
throw UnsupportedError('Use the HTTP devFS api.');
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,7 +252,7 @@ class DevFSException implements Exception {
|
||||
class _DevFSHttpWriter {
|
||||
_DevFSHttpWriter(
|
||||
this.fsName,
|
||||
VMService serviceProtocol, {
|
||||
vm_service.VmService serviceProtocol, {
|
||||
@required OperatingSystemUtils osUtils,
|
||||
})
|
||||
: httpAddress = serviceProtocol.httpAddress,
|
||||
@ -392,22 +374,25 @@ class UpdateFSReport {
|
||||
class DevFS {
|
||||
/// Create a [DevFS] named [fsName] for the local files in [rootDirectory].
|
||||
DevFS(
|
||||
VMService serviceProtocol,
|
||||
vm_service.VmService serviceProtocol,
|
||||
this.fsName,
|
||||
this.rootDirectory, {
|
||||
@required OperatingSystemUtils osUtils,
|
||||
@visibleForTesting bool disableUpload = false,
|
||||
}) : _operations = ServiceProtocolDevFSOperations(serviceProtocol),
|
||||
_httpWriter = _DevFSHttpWriter(
|
||||
fsName,
|
||||
serviceProtocol,
|
||||
osUtils: osUtils,
|
||||
);
|
||||
),
|
||||
_disableUpload = disableUpload;
|
||||
|
||||
DevFS.operations(
|
||||
this._operations,
|
||||
this.fsName,
|
||||
this.rootDirectory,
|
||||
) : _httpWriter = null;
|
||||
) : _httpWriter = null,
|
||||
_disableUpload = false;
|
||||
|
||||
final DevFSOperations _operations;
|
||||
final _DevFSHttpWriter _httpWriter;
|
||||
@ -417,6 +402,7 @@ class DevFS {
|
||||
List<Uri> sources = <Uri>[];
|
||||
DateTime lastCompiled;
|
||||
PackageConfig lastPackageConfig;
|
||||
final bool _disableUpload;
|
||||
|
||||
Uri _baseUri;
|
||||
Uri get baseUri => _baseUri;
|
||||
@ -435,7 +421,7 @@ class DevFS {
|
||||
globals.printTrace('DevFS: Creating new filesystem on the device ($_baseUri)');
|
||||
try {
|
||||
_baseUri = await _operations.create(fsName);
|
||||
} on vmservice.RPCError catch (rpcException) {
|
||||
} on vm_service.RPCError catch (rpcException) {
|
||||
// 1001 is kFileSystemAlreadyExists in //dart/runtime/vm/json_stream.h
|
||||
if (rpcException.code != 1001) {
|
||||
rethrow;
|
||||
@ -542,7 +528,9 @@ class DevFS {
|
||||
globals.printTrace('Updating files');
|
||||
if (dirtyEntries.isNotEmpty) {
|
||||
try {
|
||||
await _httpWriter.write(dirtyEntries);
|
||||
if (!_disableUpload) {
|
||||
await _httpWriter.write(dirtyEntries);
|
||||
}
|
||||
} on SocketException catch (socketException, stackTrace) {
|
||||
globals.printTrace('DevFS sync failed. Lost connection to device: $socketException');
|
||||
throw DevFSException('Lost connection to device.', socketException, stackTrace);
|
||||
|
@ -5,6 +5,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
|
||||
import '../application_package.dart';
|
||||
import '../artifacts.dart';
|
||||
@ -46,8 +47,8 @@ final String _ipv4Loopback = InternetAddress.loopbackIPv4.address;
|
||||
final String _ipv6Loopback = InternetAddress.loopbackIPv6.address;
|
||||
|
||||
// Enables testing the fuchsia isolate discovery
|
||||
Future<VMService> _kDefaultFuchsiaIsolateDiscoveryConnector(Uri uri) {
|
||||
return VMService.connect(uri);
|
||||
Future<vm_service.VmService> _kDefaultFuchsiaIsolateDiscoveryConnector(Uri uri) {
|
||||
return connectToVmService(uri);
|
||||
}
|
||||
|
||||
/// Read the log for a particular device.
|
||||
@ -619,15 +620,14 @@ class FuchsiaDevice extends Device {
|
||||
// netstat shows that the local port is actually being used on the IPv6
|
||||
// loopback (::1).
|
||||
final Uri uri = Uri.parse('http://[$_ipv6Loopback]:$port');
|
||||
final VMService vmService = await VMService.connect(uri);
|
||||
final vm_service.VmService vmService = await connectToVmService(uri);
|
||||
final List<FlutterView> flutterViews = await vmService.getFlutterViews();
|
||||
for (final FlutterView flutterView in flutterViews) {
|
||||
if (flutterView.uiIsolate == null) {
|
||||
continue;
|
||||
}
|
||||
final Uri address = vmService.httpAddress;
|
||||
if (flutterView.uiIsolate.name.contains(isolateName)) {
|
||||
return address.port;
|
||||
return vmService.httpAddress.port;
|
||||
}
|
||||
}
|
||||
} on SocketException catch (err) {
|
||||
@ -662,11 +662,11 @@ class FuchsiaIsolateDiscoveryProtocol {
|
||||
]);
|
||||
|
||||
static const Duration _pollDuration = Duration(seconds: 10);
|
||||
final Map<int, VMService> _ports = <int, VMService>{};
|
||||
final Map<int, vm_service.VmService> _ports = <int, vm_service.VmService>{};
|
||||
final FuchsiaDevice _device;
|
||||
final String _isolateName;
|
||||
final Completer<Uri> _foundUri = Completer<Uri>();
|
||||
final Future<VMService> Function(Uri) _vmServiceConnector;
|
||||
final Future<vm_service.VmService> Function(Uri) _vmServiceConnector;
|
||||
// whether to only poll once.
|
||||
final bool _pollOnce;
|
||||
Timer _pollingTimer;
|
||||
@ -702,7 +702,7 @@ class FuchsiaIsolateDiscoveryProtocol {
|
||||
Future<void> _findIsolate() async {
|
||||
final List<int> ports = await _device.servicePorts();
|
||||
for (final int port in ports) {
|
||||
VMService service;
|
||||
vm_service.VmService service;
|
||||
if (_ports.containsKey(port)) {
|
||||
service = _ports[port];
|
||||
} else {
|
||||
@ -721,11 +721,10 @@ class FuchsiaIsolateDiscoveryProtocol {
|
||||
if (flutterView.uiIsolate == null) {
|
||||
continue;
|
||||
}
|
||||
final Uri address = service.httpAddress;
|
||||
if (flutterView.uiIsolate.name.contains(_isolateName)) {
|
||||
_foundUri.complete(_device.ipv6
|
||||
? Uri.parse('http://[$_ipv6Loopback]:${address.port}/')
|
||||
: Uri.parse('http://$_ipv4Loopback:${address.port}/'));
|
||||
? Uri.parse('http://[$_ipv6Loopback]:${service.httpAddress.port}/')
|
||||
: Uri.parse('http://$_ipv4Loopback:${service.httpAddress.port}/'));
|
||||
_status.stop();
|
||||
return;
|
||||
}
|
||||
|
@ -187,10 +187,10 @@ class FlutterDevice {
|
||||
// FYI, this message is used as a sentinel in tests.
|
||||
globals.printTrace('Connecting to service protocol: $observatoryUri');
|
||||
isWaitingForVm = true;
|
||||
VMService service;
|
||||
vm_service.VmService service;
|
||||
|
||||
try {
|
||||
service = await VMService.connect(
|
||||
service = await connectToVmService(
|
||||
observatoryUri,
|
||||
reloadSources: reloadSources,
|
||||
restart: restart,
|
||||
@ -226,9 +226,6 @@ class FlutterDevice {
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
// TODO(jonahwilliams): remove once all callsites are updated.
|
||||
VMService get flutterDeprecatedVmService => vmService as VMService;
|
||||
|
||||
Future<void> refreshViews() async {
|
||||
if (vmService == null) {
|
||||
return;
|
||||
@ -254,8 +251,6 @@ class FlutterDevice {
|
||||
return _views;
|
||||
}
|
||||
|
||||
Future<void> getVMs() => flutterDeprecatedVmService.getVMOld();
|
||||
|
||||
Future<void> exitApps() async {
|
||||
if (!device.supportsFlutterExit) {
|
||||
await device.stopApp(package);
|
||||
@ -308,7 +303,7 @@ class FlutterDevice {
|
||||
}) {
|
||||
// One devFS per device. Shared by all running instances.
|
||||
devFS = DevFS(
|
||||
flutterDeprecatedVmService,
|
||||
vmService,
|
||||
fsName,
|
||||
rootDirectory,
|
||||
osUtils: globals.os,
|
||||
@ -316,16 +311,17 @@ class FlutterDevice {
|
||||
return devFS.create();
|
||||
}
|
||||
|
||||
List<Future<vm_service.ReloadReport>> reloadSources(
|
||||
Future<List<Future<vm_service.ReloadReport>>> reloadSources(
|
||||
String entryPath, {
|
||||
bool pause = false,
|
||||
}) {
|
||||
}) async {
|
||||
final String deviceEntryUri = devFS.baseUri
|
||||
.resolveUri(globals.fs.path.toUri(entryPath)).toString();
|
||||
final vm_service.VM vm = await vmService.getVM();
|
||||
return <Future<vm_service.ReloadReport>>[
|
||||
for (final Isolate isolate in flutterDeprecatedVmService.vm.isolates)
|
||||
for (final vm_service.IsolateRef isolateRef in vm.isolates)
|
||||
vmService.reloadSources(
|
||||
isolate.id,
|
||||
isolateRef.id,
|
||||
pause: pause,
|
||||
rootLibUri: deviceEntryUri,
|
||||
)
|
||||
@ -867,7 +863,7 @@ abstract class ResidentRunner {
|
||||
void writeVmserviceFile() {
|
||||
if (debuggingOptions.vmserviceOutFile != null) {
|
||||
try {
|
||||
final String address = flutterDevices.first.flutterDeprecatedVmService.wsAddress.toString();
|
||||
final String address = flutterDevices.first.vmService.wsAddress.toString();
|
||||
final File vmserviceOutFile = globals.fs.file(debuggingOptions.vmserviceOutFile);
|
||||
vmserviceOutFile.createSync(recursive: true);
|
||||
vmserviceOutFile.writeAsStringSync(address);
|
||||
@ -899,13 +895,6 @@ abstract class ResidentRunner {
|
||||
await Future.wait(futures);
|
||||
}
|
||||
|
||||
Future<void> refreshVM() async {
|
||||
final List<Future<void>> futures = <Future<void>>[
|
||||
for (final FlutterDevice device in flutterDevices) device.getVMs(),
|
||||
];
|
||||
await Future.wait(futures);
|
||||
}
|
||||
|
||||
Future<void> debugDumpApp() async {
|
||||
await refreshViews();
|
||||
for (final FlutterDevice device in flutterDevices) {
|
||||
@ -1086,7 +1075,6 @@ abstract class ResidentRunner {
|
||||
compileExpression: compileExpression,
|
||||
reloadMethod: reloadMethod,
|
||||
);
|
||||
await device.getVMs();
|
||||
await device.refreshViews();
|
||||
if (device.views.isNotEmpty) {
|
||||
viewFound = true;
|
||||
@ -1122,7 +1110,7 @@ abstract class ResidentRunner {
|
||||
<String, dynamic>{
|
||||
'reuseWindows': true,
|
||||
},
|
||||
flutterDevices.first.flutterDeprecatedVmService.httpAddress,
|
||||
flutterDevices.first.vmService.httpAddress,
|
||||
'http://${_devtoolsServer.address.host}:${_devtoolsServer.port}',
|
||||
false, // headless mode,
|
||||
false, // machine mode
|
||||
|
@ -83,8 +83,8 @@ class ColdRunner extends ResidentRunner {
|
||||
if (flutterDevices.first.observatoryUris != null) {
|
||||
// For now, only support one debugger connection.
|
||||
connectionInfoCompleter?.complete(DebugConnectionInfo(
|
||||
httpUri: flutterDevices.first.flutterDeprecatedVmService.httpAddress,
|
||||
wsUri: flutterDevices.first.flutterDeprecatedVmService.wsAddress,
|
||||
httpUri: flutterDevices.first.vmService.httpAddress,
|
||||
wsUri: flutterDevices.first.vmService.wsAddress,
|
||||
));
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ class ColdRunner extends ResidentRunner {
|
||||
if (device.vmService != null) {
|
||||
globals.printStatus('Tracing startup on ${device.device.name}.');
|
||||
await downloadStartupTrace(
|
||||
device.flutterDeprecatedVmService,
|
||||
device.vmService,
|
||||
awaitFirstFrame: awaitFirstFrameWhenTracing,
|
||||
);
|
||||
}
|
||||
@ -197,7 +197,7 @@ class ColdRunner extends ResidentRunner {
|
||||
// Caution: This log line is parsed by device lab tests.
|
||||
globals.printStatus(
|
||||
'An Observatory debugger and profiler on $dname is available at: '
|
||||
'${device.flutterDeprecatedVmService.httpAddress}',
|
||||
'${device.vmService.httpAddress}',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ class HotRunner extends ResidentRunner {
|
||||
from: projectRootPath,
|
||||
);
|
||||
for (final FlutterDevice device in flutterDevices) {
|
||||
final List<Future<vm_service.ReloadReport>> reportFutures = device.reloadSources(
|
||||
final List<Future<vm_service.ReloadReport>> reportFutures = await device.reloadSources(
|
||||
entryPath, pause: false,
|
||||
);
|
||||
final List<vm_service.ReloadReport> reports = await Future.wait(reportFutures);
|
||||
@ -257,8 +257,8 @@ class HotRunner extends ResidentRunner {
|
||||
// Only handle one debugger connection.
|
||||
connectionInfoCompleter.complete(
|
||||
DebugConnectionInfo(
|
||||
httpUri: flutterDevices.first.flutterDeprecatedVmService.httpAddress,
|
||||
wsUri: flutterDevices.first.flutterDeprecatedVmService.wsAddress,
|
||||
httpUri: flutterDevices.first.vmService.httpAddress,
|
||||
wsUri: flutterDevices.first.vmService.wsAddress,
|
||||
baseUri: baseUris.first.toString(),
|
||||
),
|
||||
);
|
||||
@ -820,7 +820,6 @@ class HotRunner extends ResidentRunner {
|
||||
final Stopwatch reloadTimer = Stopwatch()..start();
|
||||
|
||||
globals.printTrace('Refreshing active FlutterViews before reloading.');
|
||||
await refreshVM();
|
||||
await refreshViews();
|
||||
|
||||
final Stopwatch devFSTimer = Stopwatch()..start();
|
||||
@ -847,7 +846,7 @@ class HotRunner extends ResidentRunner {
|
||||
await device.resetAssetDirectory();
|
||||
_shouldResetAssetDirectory = false;
|
||||
}
|
||||
final List<Future<vm_service.ReloadReport>> reportFutures = device.reloadSources(
|
||||
final List<Future<vm_service.ReloadReport>> reportFutures = await device.reloadSources(
|
||||
entryPath, pause: pause,
|
||||
);
|
||||
allReportsFutures.add(Future.wait(reportFutures).then(
|
||||
@ -1117,7 +1116,7 @@ class HotRunner extends ResidentRunner {
|
||||
// Caution: This log line is parsed by device lab tests.
|
||||
globals.printStatus(
|
||||
'An Observatory debugger and profiler on $dname is available at: '
|
||||
'${device.flutterDeprecatedVmService.httpAddress}',
|
||||
'${device.vmService.httpAddress}',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -185,29 +185,27 @@ class CoverageCollector extends TestWatcher {
|
||||
Future<void> handleTestTimedOut(ProcessEvent event) async { }
|
||||
}
|
||||
|
||||
Future<VMService> _defaultConnect(Uri serviceUri) {
|
||||
return VMService.connect(
|
||||
Future<vm_service.VmService> _defaultConnect(Uri serviceUri) {
|
||||
return connectToVmService(
|
||||
serviceUri, compression: CompressionOptions.compressionOff);
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> collect(Uri serviceUri, bool Function(String) libraryPredicate, {
|
||||
bool waitPaused = false,
|
||||
String debugName,
|
||||
Future<VMService> Function(Uri) connector = _defaultConnect,
|
||||
Future<vm_service.VmService> Function(Uri) connector = _defaultConnect,
|
||||
}) async {
|
||||
final VMService vmService = await connector(serviceUri);
|
||||
await vmService.getVMOld();
|
||||
final vm_service.VmService vmService = await connector(serviceUri);
|
||||
final Map<String, dynamic> result = await _getAllCoverage(
|
||||
vmService, libraryPredicate);
|
||||
await vmService.close();
|
||||
vmService.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> _getAllCoverage(VMService service, bool Function(String) libraryPredicate) async {
|
||||
await service.getVMOld();
|
||||
Future<Map<String, dynamic>> _getAllCoverage(vm_service.VmService service, bool Function(String) libraryPredicate) async {
|
||||
final vm_service.VM vm = await service.getVM();
|
||||
final List<Map<String, dynamic>> coverage = <Map<String, dynamic>>[];
|
||||
for (final Isolate isolateRef in service.vm.isolates) {
|
||||
await isolateRef.load();
|
||||
for (final vm_service.IsolateRef isolateRef in vm.isolates) {
|
||||
Map<String, Object> scriptList;
|
||||
try {
|
||||
final vm_service.ScriptList actualScriptList = await service.getScripts(isolateRef.id);
|
||||
@ -228,24 +226,22 @@ Future<Map<String, dynamic>> _getAllCoverage(VMService service, bool Function(St
|
||||
}
|
||||
final String scriptId = script['id'] as String;
|
||||
futures.add(
|
||||
isolateRef.invokeRpcRaw('getSourceReport', params: <String, dynamic>{
|
||||
'forceCompile': true,
|
||||
'scriptId': scriptId,
|
||||
'isolateId': isolateRef.id,
|
||||
'reports': <String>['Coverage'],
|
||||
})
|
||||
.then((Map<String, dynamic> report) {
|
||||
sourceReports[scriptId] = report;
|
||||
service.getSourceReport(
|
||||
isolateRef.id,
|
||||
<String>['Coverage'],
|
||||
scriptId: scriptId,
|
||||
forceCompile: true,
|
||||
)
|
||||
.then((vm_service.SourceReport report) {
|
||||
sourceReports[scriptId] = report.json;
|
||||
})
|
||||
);
|
||||
futures.add(
|
||||
isolateRef.invokeRpcRaw('getObject', params: <String, dynamic>{
|
||||
'isolateId': isolateRef.id,
|
||||
'objectId': scriptId,
|
||||
})
|
||||
.then((Map<String, dynamic> script) {
|
||||
scripts[scriptId] = script;
|
||||
})
|
||||
service
|
||||
.getObject(isolateRef.id, scriptId)
|
||||
.then((vm_service.Obj script) {
|
||||
scripts[scriptId] = script.json;
|
||||
})
|
||||
);
|
||||
}
|
||||
await Future.wait(futures);
|
||||
|
@ -6,6 +6,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:stream_channel/stream_channel.dart';
|
||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
|
||||
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
|
||||
import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
|
||||
@ -521,9 +522,9 @@ class FlutterPlatform extends PlatformPlugin {
|
||||
processObservatoryUri = detectedUri;
|
||||
{
|
||||
globals.printTrace('Connecting to service protocol: $processObservatoryUri');
|
||||
final Future<VMService> localVmService = VMService.connect(processObservatoryUri,
|
||||
final Future<vm_service.VmService> localVmService = connectToVmService(processObservatoryUri,
|
||||
compileExpression: _compileExpressionService);
|
||||
localVmService.then((VMService vmservice) {
|
||||
localVmService.then((vm_service.VmService vmservice) {
|
||||
globals.printTrace('Successfully connected to service protocol: $processObservatoryUri');
|
||||
});
|
||||
}
|
||||
|
@ -24,15 +24,15 @@ class Tracing {
|
||||
static const String firstUsefulFrameEventName = kFirstFrameRasterizedEventName;
|
||||
|
||||
static Future<Tracing> connect(Uri uri) async {
|
||||
final VMService observatory = await VMService.connect(uri);
|
||||
final vm_service.VmService observatory = await connectToVmService(uri);
|
||||
return Tracing(observatory);
|
||||
}
|
||||
|
||||
final VMService vmService;
|
||||
final vm_service.VmService vmService;
|
||||
|
||||
Future<void> startTracing() async {
|
||||
await vmService.vm.setVMTimelineFlags(<String>['Compiler', 'Dart', 'Embedder', 'GC']);
|
||||
await vmService.vm.clearVMTimeline();
|
||||
await vmService.setVMTimelineFlags(<String>['Compiler', 'Dart', 'Embedder', 'GC']);
|
||||
await vmService.clearVMTimeline();
|
||||
}
|
||||
|
||||
/// Stops tracing; optionally wait for first frame.
|
||||
@ -73,15 +73,15 @@ class Tracing {
|
||||
}
|
||||
status.stop();
|
||||
}
|
||||
final Map<String, dynamic> timeline = await vmService.vm.getVMTimeline();
|
||||
await vmService.vm.setVMTimelineFlags(<String>[]);
|
||||
return timeline;
|
||||
final vm_service.Timeline timeline = await vmService.getVMTimeline();
|
||||
await vmService.setVMTimelineFlags(<String>[]);
|
||||
return timeline.json;
|
||||
}
|
||||
}
|
||||
|
||||
/// Download the startup trace information from the given observatory client and
|
||||
/// store it to build/start_up_info.json.
|
||||
Future<void> downloadStartupTrace(VMService observatory, { bool awaitFirstFrame = true }) async {
|
||||
Future<void> downloadStartupTrace(vm_service.VmService vmService, { bool awaitFirstFrame = true }) async {
|
||||
final String traceInfoFilePath = globals.fs.path.join(getBuildDirectory(), 'start_up_info.json');
|
||||
final File traceInfoFile = globals.fs.file(traceInfoFilePath);
|
||||
|
||||
@ -95,7 +95,7 @@ Future<void> downloadStartupTrace(VMService observatory, { bool awaitFirstFrame
|
||||
traceInfoFile.parent.createSync();
|
||||
}
|
||||
|
||||
final Tracing tracing = Tracing(observatory);
|
||||
final Tracing tracing = Tracing(vmService);
|
||||
|
||||
final Map<String, dynamic> timeline = await tracing.stopTracingAndDownloadTimeline(
|
||||
awaitFirstFrame: awaitFirstFrame,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,18 +9,15 @@ import 'package:meta/meta.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:process/process.dart';
|
||||
import 'package:quiver/testing/async.dart';
|
||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
|
||||
import 'package:flutter_tools/src/base/common.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';
|
||||
import 'package:flutter_tools/src/base/net.dart';
|
||||
import 'package:flutter_tools/src/base/terminal.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/attach.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/device.dart';
|
||||
import 'package:flutter_tools/src/ios/devices.dart';
|
||||
import 'package:flutter_tools/src/mdns_discovery.dart';
|
||||
@ -76,16 +73,12 @@ void main() {
|
||||
FakeDeviceLogReader mockLogReader;
|
||||
MockPortForwarder portForwarder;
|
||||
MockAndroidDevice device;
|
||||
MockProcessManager mockProcessManager;
|
||||
MockHttpClient httpClient;
|
||||
Completer<void> vmServiceDoneCompleter;
|
||||
|
||||
setUp(() {
|
||||
mockProcessManager = MockProcessManager();
|
||||
mockLogReader = FakeDeviceLogReader();
|
||||
portForwarder = MockPortForwarder();
|
||||
device = MockAndroidDevice();
|
||||
vmServiceDoneCompleter = Completer<void>();
|
||||
when(device.portForwarder)
|
||||
.thenReturn(portForwarder);
|
||||
when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort')))
|
||||
@ -144,114 +137,6 @@ void main() {
|
||||
Logger: () => logger,
|
||||
});
|
||||
|
||||
testUsingContext('finds all observatory ports and forwards them', () async {
|
||||
testFileSystem.file(testFileSystem.path.join('.packages')).createSync();
|
||||
testFileSystem.file(testFileSystem.path.join('lib', 'main.dart')).createSync();
|
||||
testFileSystem
|
||||
.file(testFileSystem.path.join('build', 'flutter_assets', 'AssetManifest.json'))
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync('{}');
|
||||
|
||||
when(device.name).thenReturn('MockAndroidDevice');
|
||||
when(device.getLogReader(includePastLogs: anyNamed('includePastLogs')))
|
||||
|
||||
.thenReturn(mockLogReader);
|
||||
|
||||
final Process dartProcess = MockProcess();
|
||||
final StreamController<List<int>> compilerStdoutController = StreamController<List<int>>();
|
||||
|
||||
when(dartProcess.stdout).thenAnswer((_) => compilerStdoutController.stream);
|
||||
when(dartProcess.stderr)
|
||||
.thenAnswer((_) => Stream<List<int>>.fromFuture(Future<List<int>>.value(const <int>[])));
|
||||
|
||||
when(dartProcess.stdin).thenAnswer((_) => MockStdIn());
|
||||
|
||||
final Completer<int> dartProcessExitCode = Completer<int>();
|
||||
when(dartProcess.exitCode).thenAnswer((_) => dartProcessExitCode.future);
|
||||
when(mockProcessManager.start(any)).thenAnswer((_) => Future<Process>.value(dartProcess));
|
||||
|
||||
testDeviceManager.addDevice(device);
|
||||
|
||||
final List<String> observatoryLogs = <String>[];
|
||||
|
||||
await FakeAsync().run((FakeAsync time) {
|
||||
unawaited(runZoned(() async {
|
||||
final StreamSubscription<String> loggerSubscription = logger.stream.listen((String message) {
|
||||
// The "Observatory URL on device" message is output by the ProtocolDiscovery when it found the observatory.
|
||||
if (message.startsWith('[verbose] Observatory URL on device')) {
|
||||
observatoryLogs.add(message);
|
||||
}
|
||||
if (message == '[stdout] Waiting for a connection from Flutter on MockAndroidDevice...') {
|
||||
observatoryLogs.add(message);
|
||||
}
|
||||
if (message == '[stdout] Lost connection to device.') {
|
||||
observatoryLogs.add(message);
|
||||
}
|
||||
if (message.contains('Hot reload.')) {
|
||||
observatoryLogs.add(message);
|
||||
}
|
||||
if (message.contains('Hot restart.')) {
|
||||
observatoryLogs.add(message);
|
||||
}
|
||||
});
|
||||
|
||||
final TestHotRunnerFactory testHotRunnerFactory = TestHotRunnerFactory();
|
||||
final Future<void> task = createTestCommandRunner(
|
||||
AttachCommand(hotRunnerFactory: testHotRunnerFactory)
|
||||
).run(<String>['attach']);
|
||||
|
||||
// First iteration of the attach loop.
|
||||
mockLogReader.addLine('Observatory listening on http://127.0.0.1:0001');
|
||||
mockLogReader.addLine('Observatory listening on http://127.0.0.1:1234');
|
||||
|
||||
time.elapse(const Duration(milliseconds: 200));
|
||||
|
||||
compilerStdoutController
|
||||
.add(utf8.encode('result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n'));
|
||||
time.flushMicrotasks();
|
||||
|
||||
// Second iteration of the attach loop.
|
||||
mockLogReader.addLine('Observatory listening on http://127.0.0.1:0002');
|
||||
mockLogReader.addLine('Observatory listening on http://127.0.0.1:1235');
|
||||
|
||||
time.elapse(const Duration(milliseconds: 200));
|
||||
|
||||
compilerStdoutController
|
||||
.add(utf8.encode('result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n'));
|
||||
time.flushMicrotasks();
|
||||
|
||||
dartProcessExitCode.complete(0);
|
||||
|
||||
await loggerSubscription.cancel();
|
||||
await testHotRunnerFactory.exitApp();
|
||||
await task;
|
||||
}));
|
||||
});
|
||||
|
||||
expect(observatoryLogs.length, 9);
|
||||
expect(observatoryLogs[0], '[stdout] Waiting for a connection from Flutter on MockAndroidDevice...');
|
||||
expect(observatoryLogs[1], '[verbose] Observatory URL on device: http://127.0.0.1:1234');
|
||||
expect(observatoryLogs[2], '[stdout] Lost connection to device.');
|
||||
expect(observatoryLogs[3].contains('Hot reload.'), isTrue);
|
||||
expect(observatoryLogs[4].contains('Hot restart.'), isTrue);
|
||||
expect(observatoryLogs[5], '[verbose] Observatory URL on device: http://127.0.0.1:1235');
|
||||
expect(observatoryLogs[6], '[stdout] Lost connection to device.');
|
||||
expect(observatoryLogs[7].contains('Hot reload.'), isTrue);
|
||||
expect(observatoryLogs[8].contains('Hot restart.'), isTrue);
|
||||
|
||||
verify(portForwarder.forward(1234, hostPort: anyNamed('hostPort'))).called(1);
|
||||
verify(portForwarder.forward(1235, hostPort: anyNamed('hostPort'))).called(1);
|
||||
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => testFileSystem,
|
||||
HttpClientFactory: () => () => httpClient,
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Logger: () => logger,
|
||||
VMServiceConnector: () => getFakeVmServiceFactory(
|
||||
vmServiceDoneCompleter: vmServiceDoneCompleter,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('Fails with tool exit on bad Observatory uri', () async {
|
||||
when(device.getLogReader(includePastLogs: anyNamed('includePastLogs')))
|
||||
.thenAnswer((_) {
|
||||
@ -797,50 +682,54 @@ VMServiceConnector getFakeVmServiceFactory({
|
||||
CompressionOptions compression,
|
||||
Device device,
|
||||
}) async {
|
||||
final VMService vmService = VMServiceMock();
|
||||
final VM vm = VMMock();
|
||||
|
||||
when(vmService.vm).thenReturn(vm);
|
||||
when(vmService.isClosed).thenReturn(false);
|
||||
when(vmService.done).thenAnswer((_) {
|
||||
return Future<void>.value(null);
|
||||
});
|
||||
when(vmService.onDone).thenAnswer((_) {
|
||||
return Future<void>.value(null);
|
||||
});
|
||||
when(vmService.getVM()).thenAnswer((_) async {
|
||||
return vm_service.VM(
|
||||
pid: 1,
|
||||
architectureBits: 64,
|
||||
hostCPU: '',
|
||||
name: '',
|
||||
isolates: <vm_service.IsolateRef>[],
|
||||
isolateGroups: <vm_service.IsolateGroupRef>[],
|
||||
startTime: 0,
|
||||
targetCPU: '',
|
||||
operatingSystem: '',
|
||||
version: '',
|
||||
);
|
||||
});
|
||||
when(vmService.getIsolate(any))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return fakeUnpausedIsolate;
|
||||
});
|
||||
when(vmService.callMethod(kListViewsMethod))
|
||||
.thenAnswer((_) async {
|
||||
return vm_service.Response.parse(<String, Object>{
|
||||
'views': <Object>[
|
||||
<String, Object>{
|
||||
'id': '1',
|
||||
'isolate': fakeUnpausedIsolate.toJson()
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
when(vm.createDevFS(any))
|
||||
.thenAnswer((_) => Future<Map<String, dynamic>>.value(<String, dynamic>{'uri': '/',}));
|
||||
|
||||
return vmService;
|
||||
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
||||
requests: <VmServiceExpectation>[
|
||||
FakeVmServiceRequest(
|
||||
id: '1',
|
||||
method: kListViewsMethod,
|
||||
args: null,
|
||||
jsonResponse: <String, Object>{
|
||||
'views': <Object>[
|
||||
<String, Object>{
|
||||
'id': '1',
|
||||
'isolate': fakeUnpausedIsolate.toJson()
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
FakeVmServiceRequest(
|
||||
id: '2',
|
||||
method: 'getVM',
|
||||
args: null,
|
||||
jsonResponse: vm_service.VM.parse(<String, Object>{})
|
||||
.toJson(),
|
||||
),
|
||||
FakeVmServiceRequest(
|
||||
id: '3',
|
||||
method: '_createDevFS',
|
||||
args: <String, Object>{
|
||||
'fsName': globals.fs.currentDirectory.absolute.path,
|
||||
},
|
||||
jsonResponse: <String, Object>{
|
||||
'uri': globals.fs.currentDirectory.absolute.path,
|
||||
},
|
||||
),
|
||||
FakeVmServiceRequest(
|
||||
id: '4',
|
||||
method: kListViewsMethod,
|
||||
args: null,
|
||||
jsonResponse: <String, Object>{
|
||||
'views': <Object>[
|
||||
<String, Object>{
|
||||
'id': '1',
|
||||
'isolate': fakeUnpausedIsolate.toJson()
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
return fakeVmServiceHost.vmService;
|
||||
};
|
||||
}
|
||||
|
||||
@ -884,8 +773,6 @@ class TestHotRunnerFactory extends HotRunnerFactory {
|
||||
}
|
||||
}
|
||||
|
||||
class VMMock extends Mock implements VM {}
|
||||
class VMServiceMock extends Mock implements VMService {}
|
||||
class MockProcessManager extends Mock implements ProcessManager {}
|
||||
class MockProcess extends Mock implements Process {}
|
||||
class MockHttpClientRequest extends Mock implements HttpClientRequest {}
|
||||
|
@ -2,49 +2,49 @@
|
||||
// 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/base/io.dart';
|
||||
import 'package:flutter_tools/src/test/coverage_collector.dart';
|
||||
import 'package:flutter_tools/src/vmservice.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
|
||||
import '../src/common.dart';
|
||||
|
||||
void main() {
|
||||
MockVMService mockVMService;
|
||||
testWithoutContext('Coverage collector Can handle coverage SentinelException', () async {
|
||||
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
||||
requests: <VmServiceExpectation>[
|
||||
FakeVmServiceRequest(
|
||||
id: '1',
|
||||
method: 'getVM',
|
||||
args: null,
|
||||
jsonResponse: (vm_service.VM.parse(<String, Object>{})
|
||||
..isolates = <vm_service.IsolateRef>[
|
||||
vm_service.IsolateRef.parse(<String, Object>{
|
||||
'id': '1'
|
||||
}),
|
||||
]
|
||||
).toJson(),
|
||||
),
|
||||
const FakeVmServiceRequest(
|
||||
id: '2',
|
||||
method: 'getScripts',
|
||||
args: <String, Object>{
|
||||
'isolateId': '1',
|
||||
},
|
||||
jsonResponse: <String, Object>{
|
||||
'type': 'Sentinel'
|
||||
}
|
||||
)
|
||||
],
|
||||
);
|
||||
|
||||
setUp(() {
|
||||
mockVMService = MockVMService();
|
||||
});
|
||||
|
||||
test('Coverage collector Can handle coverage sentinenl data', () async {
|
||||
when(mockVMService.getScripts(any))
|
||||
.thenThrow(vm_service.SentinelException.parse('getScripts', <String, Object>{}));
|
||||
final Map<String, Object> result = await collect(null, (String predicate) => true, connector: (Uri uri) async {
|
||||
return mockVMService;
|
||||
});
|
||||
final Map<String, Object> result = await collect(
|
||||
null,
|
||||
(String predicate) => true,
|
||||
connector: (Uri uri) async {
|
||||
return fakeVmServiceHost.vmService;
|
||||
},
|
||||
);
|
||||
|
||||
expect(result, <String, Object>{'type': 'CodeCoverage', 'coverage': <Object>[]});
|
||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||
});
|
||||
}
|
||||
|
||||
class MockVMService extends Mock implements VMService {
|
||||
@override
|
||||
final MockVM vm = MockVM();
|
||||
}
|
||||
|
||||
class MockVM extends Mock implements VM {
|
||||
@override
|
||||
final List<MockIsolate> isolates = <MockIsolate>[ MockIsolate() ];
|
||||
}
|
||||
|
||||
class MockIsolate extends Mock implements Isolate {}
|
||||
|
||||
class MockProcess extends Mock implements Process {
|
||||
final Completer<int>completer = Completer<int>();
|
||||
|
||||
@override
|
||||
Future<int> get exitCode => completer.future;
|
||||
}
|
||||
|
@ -126,13 +126,21 @@ void main() {
|
||||
// simulate package
|
||||
await _createPackage(fs, 'somepkg', 'somefile.txt');
|
||||
|
||||
final RealMockVMService vmService = RealMockVMService();
|
||||
final RealMockVM vm = RealMockVM();
|
||||
final Map<String, dynamic> response = <String, dynamic>{ 'uri': 'file://abc' };
|
||||
when(vm.createDevFS(any)).thenAnswer((Invocation invocation) {
|
||||
return Future<Map<String, dynamic>>.value(response);
|
||||
});
|
||||
when(vmService.vm).thenReturn(vm);
|
||||
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
||||
requests: <VmServiceExpectation>[
|
||||
FakeVmServiceRequest(
|
||||
id: '1',
|
||||
method: '_createDevFS',
|
||||
args: <String, Object>{
|
||||
'fsName': 'test',
|
||||
},
|
||||
jsonResponse: <String, Object>{
|
||||
'uri': Uri.parse('test').toString(),
|
||||
}
|
||||
)
|
||||
],
|
||||
);
|
||||
setHttpAddress(Uri.parse('http://localhost'), fakeVmServiceHost.vmService);
|
||||
|
||||
reset(httpClient);
|
||||
|
||||
@ -152,7 +160,7 @@ void main() {
|
||||
});
|
||||
|
||||
final DevFS devFS = DevFS(
|
||||
vmService,
|
||||
fakeVmServiceHost.vmService,
|
||||
'test',
|
||||
tempDir,
|
||||
osUtils: osUtils,
|
||||
@ -183,101 +191,43 @@ void main() {
|
||||
});
|
||||
|
||||
group('devfs remote', () {
|
||||
MockVMService vmService;
|
||||
final MockResidentCompiler residentCompiler = MockResidentCompiler();
|
||||
DevFS devFS;
|
||||
|
||||
setUpAll(() async {
|
||||
tempDir = _newTempDir(fs);
|
||||
basePath = tempDir.path;
|
||||
vmService = MockVMService();
|
||||
await vmService.setUp();
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
vmService.resetState();
|
||||
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
||||
requests: <VmServiceExpectation>[
|
||||
FakeVmServiceRequest(
|
||||
id: '1',
|
||||
method: '_createDevFS',
|
||||
args: <String, Object>{
|
||||
'fsName': 'test',
|
||||
},
|
||||
jsonResponse: <String, Object>{
|
||||
'uri': Uri.parse('test').toString(),
|
||||
}
|
||||
)
|
||||
],
|
||||
);
|
||||
setHttpAddress(Uri.parse('http://localhost'), fakeVmServiceHost.vmService);
|
||||
devFS = DevFS(
|
||||
vmService,
|
||||
fakeVmServiceHost.vmService,
|
||||
'test',
|
||||
tempDir,
|
||||
osUtils: FakeOperatingSystemUtils(),
|
||||
// TODO(jonahwilliams): remove and prevent usage of http writer.
|
||||
disableUpload: true,
|
||||
);
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
await vmService.tearDown();
|
||||
_cleanupTempDirs();
|
||||
});
|
||||
|
||||
testUsingContext('create dev file system', () async {
|
||||
// simulate workspace
|
||||
final File file = fs.file(fs.path.join(basePath, filePath));
|
||||
await file.parent.create(recursive: true);
|
||||
file.writeAsBytesSync(<int>[1, 2, 3]);
|
||||
|
||||
// simulate package
|
||||
await _createPackage(fs, 'somepkg', 'somefile.txt');
|
||||
|
||||
await devFS.create();
|
||||
vmService.expectMessages(<String>['create test']);
|
||||
expect(devFS.assetPathsToEvict, isEmpty);
|
||||
|
||||
final UpdateFSReport report = await devFS.update(
|
||||
mainUri: Uri.parse('lib/foo.txt'),
|
||||
generator: residentCompiler,
|
||||
pathToReload: 'lib/foo.txt.dill',
|
||||
trackWidgetCreation: false,
|
||||
invalidatedFiles: <Uri>[],
|
||||
packageConfig: PackageConfig.empty,
|
||||
);
|
||||
vmService.expectMessages(<String>[
|
||||
'writeFile test lib/foo.txt.dill',
|
||||
]);
|
||||
expect(devFS.assetPathsToEvict, isEmpty);
|
||||
expect(report.syncedBytes, 22);
|
||||
expect(report.success, true);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
HttpClient: () => () => HttpClient(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('delete dev file system', () async {
|
||||
expect(vmService.messages, isEmpty, reason: 'prior test timeout');
|
||||
await devFS.destroy();
|
||||
vmService.expectMessages(<String>['destroy test']);
|
||||
expect(devFS.assetPathsToEvict, isEmpty);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('cleanup preexisting file system', () async {
|
||||
// simulate workspace
|
||||
final File file = fs.file(fs.path.join(basePath, filePath));
|
||||
await file.parent.create(recursive: true);
|
||||
file.writeAsBytesSync(<int>[1, 2, 3]);
|
||||
|
||||
// simulate package
|
||||
await _createPackage(fs, 'somepkg', 'somefile.txt');
|
||||
await devFS.create();
|
||||
vmService.expectMessages(<String>['create test']);
|
||||
expect(devFS.assetPathsToEvict, isEmpty);
|
||||
|
||||
// Try to create again.
|
||||
await devFS.create();
|
||||
vmService.expectMessages(<String>['create test', 'destroy test', 'create test']);
|
||||
expect(devFS.assetPathsToEvict, isEmpty);
|
||||
|
||||
// Really destroy.
|
||||
await devFS.destroy();
|
||||
vmService.expectMessages(<String>['destroy test']);
|
||||
expect(devFS.assetPathsToEvict, isEmpty);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('reports unsuccessful compile when errors are returned', () async {
|
||||
await devFS.create();
|
||||
final DateTime previousCompile = devFS.lastCompiled;
|
||||
@ -345,98 +295,6 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
class MockVMService extends BasicMock implements VMService {
|
||||
MockVMService() {
|
||||
_vm = MockVM(this);
|
||||
}
|
||||
|
||||
Uri _httpAddress;
|
||||
HttpServer _server;
|
||||
MockVM _vm;
|
||||
|
||||
@override
|
||||
Uri get httpAddress => _httpAddress;
|
||||
|
||||
@override
|
||||
VM get vm => _vm;
|
||||
|
||||
Future<void> setUp() async {
|
||||
try {
|
||||
_server = await HttpServer.bind(InternetAddress.loopbackIPv6, 0);
|
||||
_httpAddress = Uri.parse('http://[::1]:${_server.port}');
|
||||
} on SocketException {
|
||||
// Fall back to IPv4 if the host doesn't support binding to IPv6 localhost
|
||||
_server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
|
||||
_httpAddress = Uri.parse('http://127.0.0.1:${_server.port}');
|
||||
}
|
||||
_server.listen((HttpRequest request) {
|
||||
final String fsName = request.headers.value('dev_fs_name');
|
||||
final String devicePath = utf8.decode(base64.decode(request.headers.value('dev_fs_uri_b64')));
|
||||
messages.add('writeFile $fsName $devicePath');
|
||||
request.drain<List<int>>().then<void>((List<int> value) {
|
||||
request.response
|
||||
..write('Got it')
|
||||
..close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> tearDown() async {
|
||||
await _server?.close();
|
||||
}
|
||||
|
||||
void resetState() {
|
||||
_vm = MockVM(this);
|
||||
messages.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
||||
|
||||
}
|
||||
|
||||
class MockVM implements VM {
|
||||
MockVM(this._service);
|
||||
|
||||
final MockVMService _service;
|
||||
final Uri _baseUri = Uri.parse('file:///tmp/devfs/test');
|
||||
bool _devFSExists = false;
|
||||
|
||||
static const int kFileSystemAlreadyExists = 1001;
|
||||
|
||||
@override
|
||||
Future<Map<String, dynamic>> createDevFS(String fsName) async {
|
||||
_service.messages.add('create $fsName');
|
||||
if (_devFSExists) {
|
||||
throw vm_service.RPCError('File system already exists', kFileSystemAlreadyExists, '');
|
||||
}
|
||||
_devFSExists = true;
|
||||
return <String, dynamic>{'uri': '$_baseUri'};
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, dynamic>> deleteDevFS(String fsName) async {
|
||||
_service.messages.add('destroy $fsName');
|
||||
_devFSExists = false;
|
||||
return <String, dynamic>{'type': 'Success'};
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, dynamic>> invokeRpcRaw(
|
||||
String method, {
|
||||
Map<String, dynamic> params = const <String, dynamic>{},
|
||||
Duration timeout,
|
||||
bool timeoutFatal = true,
|
||||
bool truncateLogs = true,
|
||||
}) async {
|
||||
_service.messages.add('$method $params');
|
||||
return <String, dynamic>{'success': true};
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
||||
}
|
||||
|
||||
class RealMockResidentCompiler extends Mock implements ResidentCompiler {}
|
||||
|
||||
final List<Directory> _tempDirs = <Directory>[];
|
||||
@ -474,14 +332,6 @@ Future<File> _createPackage(FileSystem fs, String pkgName, String pkgFileName, {
|
||||
..writeAsStringSync(sb.toString());
|
||||
}
|
||||
|
||||
class RealMockVM extends Mock implements VM {
|
||||
|
||||
}
|
||||
|
||||
class RealMockVMService extends Mock implements VMService {
|
||||
|
||||
}
|
||||
|
||||
class MyHttpOverrides extends HttpOverrides {
|
||||
MyHttpOverrides(this._httpClient);
|
||||
@override
|
||||
@ -497,3 +347,4 @@ class MockHttpClientRequest extends Mock implements HttpClientRequest {}
|
||||
class MockHttpHeaders extends Mock implements HttpHeaders {}
|
||||
class MockHttpClientResponse extends Mock implements HttpClientResponse {}
|
||||
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
|
||||
class MockVMService extends Mock implements vm_service.VmService {}
|
||||
|
@ -628,21 +628,34 @@ void main() {
|
||||
|
||||
group('FuchsiaIsolateDiscoveryProtocol', () {
|
||||
MockPortForwarder portForwarder;
|
||||
MockVMService vmService;
|
||||
|
||||
setUp(() {
|
||||
portForwarder = MockPortForwarder();
|
||||
vmService = MockVMService();
|
||||
});
|
||||
|
||||
Future<Uri> findUri(List<FlutterView> views, String expectedIsolateName) async {
|
||||
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
||||
requests: <VmServiceExpectation>[
|
||||
FakeVmServiceRequest(
|
||||
id: '1',
|
||||
method: kListViewsMethod,
|
||||
args: null,
|
||||
jsonResponse: <String, Object>{
|
||||
'views': <Object>[
|
||||
for (FlutterView view in views)
|
||||
view.toJson()
|
||||
],
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
final MockFuchsiaDevice fuchsiaDevice =
|
||||
MockFuchsiaDevice('123', portForwarder, false);
|
||||
final FuchsiaIsolateDiscoveryProtocol discoveryProtocol =
|
||||
FuchsiaIsolateDiscoveryProtocol(
|
||||
fuchsiaDevice,
|
||||
expectedIsolateName,
|
||||
(Uri uri) async => vmService,
|
||||
(Uri uri) async => fakeVmServiceHost.vmService,
|
||||
true, // only poll once.
|
||||
);
|
||||
|
||||
@ -650,17 +663,7 @@ void main() {
|
||||
.thenAnswer((Invocation invocation) async => <int>[1]);
|
||||
when(portForwarder.forward(1))
|
||||
.thenAnswer((Invocation invocation) async => 2);
|
||||
when(vmService.getVMOld())
|
||||
.thenAnswer((Invocation invocation) => Future<void>.value(null));
|
||||
when(vmService.httpAddress).thenReturn(Uri.parse('example'));
|
||||
when(vmService.callMethod(kListViewsMethod)).thenAnswer((Invocation invocation) async {
|
||||
return vm_service.Response.parse(<String, Object>{
|
||||
'views': <Object>[
|
||||
for (FlutterView view in views)
|
||||
view.toJson()
|
||||
],
|
||||
});
|
||||
});
|
||||
setHttpAddress(Uri.parse('example'), fakeVmServiceHost.vmService);
|
||||
return await discoveryProtocol.uri;
|
||||
}
|
||||
|
||||
@ -1121,8 +1124,6 @@ class MockFuchsiaDevice extends Mock implements FuchsiaDevice {
|
||||
|
||||
class MockPortForwarder extends Mock implements DevicePortForwarder {}
|
||||
|
||||
class MockVMService extends Mock implements VMService {}
|
||||
|
||||
class FuchsiaDeviceWithFakeDiscovery extends FuchsiaDevice {
|
||||
FuchsiaDeviceWithFakeDiscovery(String id, {String name}) : super(id, name: name);
|
||||
|
||||
|
@ -11,7 +11,6 @@ import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/device.dart';
|
||||
import 'package:flutter_tools/src/ios/devices.dart';
|
||||
import 'package:flutter_tools/src/ios/mac.dart';
|
||||
import 'package:flutter_tools/src/vmservice.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
@ -177,4 +176,4 @@ Runner(libsystem_asl.dylib)[297] <Notice>: libMobileGestalt
|
||||
}
|
||||
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
class MockVmService extends Mock implements VMService, VmService {}
|
||||
class MockVmService extends Mock implements VmService {}
|
||||
|
@ -146,29 +146,21 @@ void main() {
|
||||
when(mockFlutterDevice.vmService).thenAnswer((Invocation invocation) {
|
||||
return fakeVmServiceHost.vmService;
|
||||
});
|
||||
when(mockFlutterDevice.flutterDeprecatedVmService).thenAnswer((Invocation invocation) {
|
||||
return mockVMService;
|
||||
});
|
||||
when(mockFlutterDevice.refreshViews()).thenAnswer((Invocation invocation) async { });
|
||||
when(mockFlutterDevice.getVMs()).thenAnswer((Invocation invocation) async { });
|
||||
when(mockFlutterDevice.reloadSources(any, pause: anyNamed('pause'))).thenReturn(<Future<vm_service.ReloadReport>>[
|
||||
Future<vm_service.ReloadReport>.value(vm_service.ReloadReport.parse(<String, dynamic>{
|
||||
'type': 'ReloadReport',
|
||||
'success': true,
|
||||
'details': <String, dynamic>{
|
||||
'loadedLibraryCount': 1,
|
||||
'finalLibraryCount': 1,
|
||||
'receivedLibraryCount': 1,
|
||||
'receivedClassesCount': 1,
|
||||
'receivedProceduresCount': 1,
|
||||
},
|
||||
})),
|
||||
]);
|
||||
// VMService mocks.
|
||||
when(mockVMService.wsAddress).thenReturn(testUri);
|
||||
when(mockVMService.done).thenAnswer((Invocation invocation) {
|
||||
final Completer<void> result = Completer<void>.sync();
|
||||
return result.future;
|
||||
when(mockFlutterDevice.reloadSources(any, pause: anyNamed('pause'))).thenAnswer((Invocation invocation) async {
|
||||
return <Future<vm_service.ReloadReport>>[
|
||||
Future<vm_service.ReloadReport>.value(vm_service.ReloadReport.parse(<String, dynamic>{
|
||||
'type': 'ReloadReport',
|
||||
'success': true,
|
||||
'details': <String, dynamic>{
|
||||
'loadedLibraryCount': 1,
|
||||
'finalLibraryCount': 1,
|
||||
'receivedLibraryCount': 1,
|
||||
'receivedClassesCount': 1,
|
||||
'receivedProceduresCount': 1,
|
||||
},
|
||||
})),
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
@ -955,6 +947,7 @@ void main() {
|
||||
|
||||
test('HotRunner writes vm service file when providing debugging option', () => testbed.run(() async {
|
||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
||||
setWsAddress(testUri, fakeVmServiceHost.vmService);
|
||||
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
|
||||
residentRunner = HotRunner(
|
||||
<FlutterDevice>[
|
||||
@ -1029,6 +1022,7 @@ void main() {
|
||||
test('ColdRunner writes vm service file when providing debugging option', () => testbed.run(() async {
|
||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
||||
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
|
||||
setWsAddress(testUri, fakeVmServiceHost.vmService);
|
||||
residentRunner = ColdRunner(
|
||||
<FlutterDevice>[
|
||||
mockFlutterDevice,
|
||||
@ -1111,7 +1105,7 @@ void main() {
|
||||
}
|
||||
|
||||
class MockFlutterDevice extends Mock implements FlutterDevice {}
|
||||
class MockVMService extends Mock implements VMService {}
|
||||
class MockVMService extends Mock implements vm_service.VmService {}
|
||||
class MockDevFS extends Mock implements DevFS {}
|
||||
class MockDevice extends Mock implements Device {}
|
||||
class MockDeviceLogReader extends Mock implements DeviceLogReader {}
|
||||
|
@ -91,20 +91,17 @@ final Map<String, Object> listViews = <String, dynamic>{
|
||||
typedef ServiceCallback = Future<Map<String, dynamic>> Function(Map<String, Object>);
|
||||
|
||||
void main() {
|
||||
testUsingContext('VmService registers reloadSources', () {
|
||||
testUsingContext('VmService registers reloadSources', () async {
|
||||
Future<void> reloadSources(String isolateId, { bool pause, bool force}) async {}
|
||||
|
||||
final MockVMService mockVMService = MockVMService();
|
||||
VMService(
|
||||
null,
|
||||
null,
|
||||
setUpVmService(
|
||||
reloadSources,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
mockVMService,
|
||||
Completer<void>(),
|
||||
const Stream<dynamic>.empty(),
|
||||
);
|
||||
|
||||
verify(mockVMService.registerService('reloadSources', 'Flutter Tools')).called(1);
|
||||
@ -112,20 +109,17 @@ void main() {
|
||||
Logger: () => BufferLogger.test()
|
||||
});
|
||||
|
||||
testUsingContext('VmService registers reloadMethod', () {
|
||||
testUsingContext('VmService registers reloadMethod', () async {
|
||||
Future<void> reloadMethod({ String classId, String libraryId,}) async {}
|
||||
|
||||
final MockVMService mockVMService = MockVMService();
|
||||
VMService(
|
||||
null,
|
||||
null,
|
||||
setUpVmService(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
reloadMethod,
|
||||
mockVMService,
|
||||
Completer<void>(),
|
||||
const Stream<dynamic>.empty(),
|
||||
);
|
||||
|
||||
verify(mockVMService.registerService('reloadMethod', 'Flutter Tools')).called(1);
|
||||
@ -133,20 +127,17 @@ void main() {
|
||||
Logger: () => BufferLogger.test()
|
||||
});
|
||||
|
||||
testUsingContext('VmService registers flutterMemoryInfo service', () {
|
||||
testUsingContext('VmService registers flutterMemoryInfo service', () async {
|
||||
final MockDevice mockDevice = MockDevice();
|
||||
|
||||
final MockVMService mockVMService = MockVMService();
|
||||
VMService(
|
||||
null,
|
||||
null,
|
||||
setUpVmService(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
mockDevice,
|
||||
null,
|
||||
mockVMService,
|
||||
Completer<void>(),
|
||||
const Stream<dynamic>.empty(),
|
||||
);
|
||||
|
||||
verify(mockVMService.registerService('flutterMemoryInfo', 'Flutter Tools')).called(1);
|
||||
@ -156,17 +147,13 @@ void main() {
|
||||
|
||||
testUsingContext('VMService returns correct FlutterVersion', () async {
|
||||
final MockVMService mockVMService = MockVMService();
|
||||
VMService(
|
||||
null,
|
||||
null,
|
||||
setUpVmService(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
mockVMService,
|
||||
Completer<void>(),
|
||||
const Stream<dynamic>.empty(),
|
||||
);
|
||||
|
||||
verify(mockVMService.registerService('flutterVersion', 'Flutter Tools')).called(1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user