From 4d490666b36d45f6c0cd60e41e1daaf3c19a2fc1 Mon Sep 17 00:00:00 2001 From: Zachary Anderson Date: Thu, 22 Jun 2017 09:48:31 -0700 Subject: [PATCH] Clean up pre-existing DevFS during creation (#10843) --- .../lib/src/commands/fuchsia_reload.dart | 15 +++++++ packages/flutter_tools/lib/src/devfs.dart | 18 +++++--- packages/flutter_tools/test/devfs_test.dart | 44 ++++++++++++++++++- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart b/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart index 4af62daf712..e439d379272 100644 --- a/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart +++ b/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart @@ -143,9 +143,24 @@ class FuchsiaReloadCommand extends FlutterCommand { return _vmServiceCache[port]; } + Future _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> _getViews(List ports) async { final List views = []; for (int port in ports) { + if (!await _checkPort(port)) + continue; final VMService vmService = _getVMService(port); await vmService.getVM(); await vmService.waitForViews(); diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart index 2657e925420..39b9766be16 100644 --- a/packages/flutter_tools/lib/src/devfs.dart +++ b/packages/flutter_tools/lib/src/devfs.dart @@ -5,6 +5,8 @@ import 'dart:async'; import 'dart:convert' show BASE64, UTF8; +import 'package:json_rpc_2/json_rpc_2.dart' as rpc; + import 'asset.dart'; import 'base/context.dart'; import 'base/file_system.dart'; @@ -185,10 +187,7 @@ class ServiceProtocolDevFSOperations implements DevFSOperations { @override Future destroy(String fsName) async { - await vmService.vm.invokeRpcRaw( - '_deleteDevFS', - params: { 'fsName': fsName }, - ); + await vmService.vm.deleteDevFS(fsName); } @override @@ -352,7 +351,16 @@ class DevFS { Future create() async { 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)'); return _baseUri; } diff --git a/packages/flutter_tools/test/devfs_test.dart b/packages/flutter_tools/test/devfs_test.dart index 34030cc2846..f931e9b2f1e 100644 --- a/packages/flutter_tools/test/devfs_test.dart +++ b/packages/flutter_tools/test/devfs_test.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/devfs.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 'src/common.dart'; @@ -335,7 +336,34 @@ void main() { testUsingContext('delete dev file system', () async { expect(vmService.messages, isEmpty, reason: 'prior test timeout'); await devFS.destroy(); - vmService.expectMessages(['_deleteDevFS {fsName: test}']); + vmService.expectMessages(['destroy test']); + expect(devFS.assetPathsToEvict, isEmpty); + }, overrides: { + 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([1, 2, 3]); + + // simulate package + await _createPackage(fs, 'somepkg', 'somefile.txt'); + + devFS = new DevFS(vmService, 'test', tempDir); + await devFS.create(); + vmService.expectMessages(['create test']); + expect(devFS.assetPathsToEvict, isEmpty); + + // Try to create again. + await devFS.create(); + vmService.expectMessages(['create test', 'destroy test', 'create test']); + expect(devFS.assetPathsToEvict, isEmpty); + + // Really destroy. + await devFS.destroy(); + vmService.expectMessages(['destroy test']); expect(devFS.assetPathsToEvict, isEmpty); }, overrides: { FileSystem: () => fs, @@ -390,15 +418,29 @@ class MockVMService extends BasicMock implements VMService { class MockVM implements VM { final MockVMService _service; final Uri _baseUri = Uri.parse('file:///tmp/devfs/test'); + bool _devFSExists = false; + + static const int kFileSystemAlreadyExists = 1001; MockVM(this._service); @override Future> createDevFS(String fsName) async { _service.messages.add('create $fsName'); + if (_devFSExists) { + throw new rpc.RpcException(kFileSystemAlreadyExists, 'File system already exists'); + } + _devFSExists = true; return {'uri': '$_baseUri'}; } + @override + Future> deleteDevFS(String fsName) async { + _service.messages.add('destroy $fsName'); + _devFSExists = false; + return {'type': 'Success'}; + } + @override Future> invokeRpcRaw(String method, { Map params: const {},