Commit 4d490666 authored by Zachary Anderson's avatar Zachary Anderson Committed by GitHub

Clean up pre-existing DevFS during creation (#10843)

parent 02245234
...@@ -143,9 +143,24 @@ class FuchsiaReloadCommand extends FlutterCommand { ...@@ -143,9 +143,24 @@ class FuchsiaReloadCommand extends FlutterCommand {
return _vmServiceCache[port]; return _vmServiceCache[port];
} }
Future<bool> _checkPort(int port) async {
bool connected = true;
Socket s;
try {
s = await Socket.connect("$_address", port);
} catch (_) {
connected = false;
}
if (s != null)
await s.close();
return connected;
}
Future<List<FlutterView>> _getViews(List<int> ports) async { Future<List<FlutterView>> _getViews(List<int> ports) async {
final List<FlutterView> views = <FlutterView>[]; final List<FlutterView> views = <FlutterView>[];
for (int port in ports) { for (int port in ports) {
if (!await _checkPort(port))
continue;
final VMService vmService = _getVMService(port); final VMService vmService = _getVMService(port);
await vmService.getVM(); await vmService.getVM();
await vmService.waitForViews(); await vmService.waitForViews();
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert' show BASE64, UTF8; import 'dart:convert' show BASE64, UTF8;
import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
import 'asset.dart'; import 'asset.dart';
import 'base/context.dart'; import 'base/context.dart';
import 'base/file_system.dart'; import 'base/file_system.dart';
...@@ -185,10 +187,7 @@ class ServiceProtocolDevFSOperations implements DevFSOperations { ...@@ -185,10 +187,7 @@ class ServiceProtocolDevFSOperations implements DevFSOperations {
@override @override
Future<dynamic> destroy(String fsName) async { Future<dynamic> destroy(String fsName) async {
await vmService.vm.invokeRpcRaw( await vmService.vm.deleteDevFS(fsName);
'_deleteDevFS',
params: <String, dynamic> { 'fsName': fsName },
);
} }
@override @override
...@@ -352,7 +351,16 @@ class DevFS { ...@@ -352,7 +351,16 @@ class DevFS {
Future<Uri> create() async { Future<Uri> create() async {
printTrace('DevFS: Creating new filesystem on the device ($_baseUri)'); printTrace('DevFS: Creating new filesystem on the device ($_baseUri)');
_baseUri = await _operations.create(fsName); try {
_baseUri = await _operations.create(fsName);
} on rpc.RpcException catch (rpcException) {
// 1001 is kFileSystemAlreadyExists in //dart/runtime/vm/json_stream.h
if (rpcException.code != 1001)
rethrow;
printTrace('DevFS: Creating failed. Destroying and trying again');
await destroy();
_baseUri = await _operations.create(fsName);
}
printTrace('DevFS: Created new filesystem on the device ($_baseUri)'); printTrace('DevFS: Created new filesystem on the device ($_baseUri)');
return _baseUri; return _baseUri;
} }
......
...@@ -13,6 +13,7 @@ import 'package:flutter_tools/src/base/file_system.dart'; ...@@ -13,6 +13,7 @@ import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/devfs.dart'; import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/vmservice.dart'; import 'package:flutter_tools/src/vmservice.dart';
import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'src/common.dart'; import 'src/common.dart';
...@@ -335,7 +336,34 @@ void main() { ...@@ -335,7 +336,34 @@ void main() {
testUsingContext('delete dev file system', () async { testUsingContext('delete dev file system', () async {
expect(vmService.messages, isEmpty, reason: 'prior test timeout'); expect(vmService.messages, isEmpty, reason: 'prior test timeout');
await devFS.destroy(); await devFS.destroy();
vmService.expectMessages(<String>['_deleteDevFS {fsName: test}']); vmService.expectMessages(<String>['destroy test']);
expect(devFS.assetPathsToEvict, isEmpty);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
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');
devFS = new DevFS(vmService, 'test', tempDir);
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); expect(devFS.assetPathsToEvict, isEmpty);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
...@@ -390,15 +418,29 @@ class MockVMService extends BasicMock implements VMService { ...@@ -390,15 +418,29 @@ class MockVMService extends BasicMock implements VMService {
class MockVM implements VM { class MockVM implements VM {
final MockVMService _service; final MockVMService _service;
final Uri _baseUri = Uri.parse('file:///tmp/devfs/test'); final Uri _baseUri = Uri.parse('file:///tmp/devfs/test');
bool _devFSExists = false;
static const int kFileSystemAlreadyExists = 1001;
MockVM(this._service); MockVM(this._service);
@override @override
Future<Map<String, dynamic>> createDevFS(String fsName) async { Future<Map<String, dynamic>> createDevFS(String fsName) async {
_service.messages.add('create $fsName'); _service.messages.add('create $fsName');
if (_devFSExists) {
throw new rpc.RpcException(kFileSystemAlreadyExists, 'File system already exists');
}
_devFSExists = true;
return <String, dynamic>{'uri': '$_baseUri'}; 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 @override
Future<Map<String, dynamic>> invokeRpcRaw(String method, { Future<Map<String, dynamic>> invokeRpcRaw(String method, {
Map<String, dynamic> params: const <String, dynamic>{}, Map<String, dynamic> params: const <String, dynamic>{},
......
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