Unverified Commit 534b0608 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] remove vm service (#55794)

Finishes the gradual vm service migration by deleting the flutter tooling's vm_service
parent c55b3220
......@@ -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,
......
......@@ -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;
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;
});
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'
}
)
],
);
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment