Unverified Commit 52bd2ccb authored by Alexander Aprelev's avatar Alexander Aprelev Committed by GitHub

Report devfs stats (#25586)

* Collect devfs stats for better analytics

* Fix fields initialization

* Fix lints
parent 50f9b883
...@@ -350,6 +350,32 @@ class _DevFSHttpWriter { ...@@ -350,6 +350,32 @@ class _DevFSHttpWriter {
} }
} }
// Basic statistics for DevFS update operation.
class UpdateFSReport {
UpdateFSReport({bool success = false,
int invalidatedSourcesCount = 0, int syncedBytes = 0}) {
_success = success;
_invalidatedSourcesCount = invalidatedSourcesCount;
_syncedBytes = syncedBytes;
}
bool get success => _success;
int get invalidatedSourcesCount => _invalidatedSourcesCount;
int get syncedBytes => _syncedBytes;
void incorporateResults(UpdateFSReport report) {
if (!report._success) {
_success = false;
}
_invalidatedSourcesCount += report._invalidatedSourcesCount;
_syncedBytes += report._syncedBytes;
}
bool _success;
int _invalidatedSourcesCount;
int _syncedBytes;
}
class DevFS { class DevFS {
/// Create a [DevFS] named [fsName] for the local files in [rootDirectory]. /// Create a [DevFS] named [fsName] for the local files in [rootDirectory].
DevFS(VMService serviceProtocol, DevFS(VMService serviceProtocol,
...@@ -422,7 +448,7 @@ class DevFS { ...@@ -422,7 +448,7 @@ class DevFS {
/// Updates files on the device. /// Updates files on the device.
/// ///
/// Returns the number of bytes synced. /// Returns the number of bytes synced.
Future<int> update({ Future<UpdateFSReport> update({
@required String mainPath, @required String mainPath,
String target, String target,
AssetBundle bundle, AssetBundle bundle,
...@@ -487,7 +513,7 @@ class DevFS { ...@@ -487,7 +513,7 @@ class DevFS {
} }
// Update modified files // Update modified files
int numBytes = 0; int syncedBytes = 0;
final Map<Uri, DevFSContent> dirtyEntries = <Uri, DevFSContent>{}; final Map<Uri, DevFSContent> dirtyEntries = <Uri, DevFSContent>{};
_entries.forEach((Uri deviceUri, DevFSContent content) { _entries.forEach((Uri deviceUri, DevFSContent content) {
String archivePath; String archivePath;
...@@ -498,7 +524,7 @@ class DevFS { ...@@ -498,7 +524,7 @@ class DevFS {
// files to incremental compiler next time user does hot reload. // files to incremental compiler next time user does hot reload.
if (content.isModified || ((bundleDirty || bundleFirstUpload) && archivePath != null)) { if (content.isModified || ((bundleDirty || bundleFirstUpload) && archivePath != null)) {
dirtyEntries[deviceUri] = content; dirtyEntries[deviceUri] = content;
numBytes += content.size; syncedBytes += content.size;
if (archivePath != null && (!bundleFirstUpload || content.isModifiedAfter(firstBuildTime))) if (archivePath != null && (!bundleFirstUpload || content.isModifiedAfter(firstBuildTime)))
assetPathsToEvict.add(archivePath); assetPathsToEvict.add(archivePath);
} }
...@@ -516,7 +542,7 @@ class DevFS { ...@@ -516,7 +542,7 @@ class DevFS {
if (content is DevFSFileContent) { if (content is DevFSFileContent) {
filesUris.add(uri); filesUris.add(uri);
invalidatedFiles.add(content.file.uri.toString()); invalidatedFiles.add(content.file.uri.toString());
numBytes -= content.size; syncedBytes -= content.size;
} }
} }
} }
...@@ -545,7 +571,7 @@ class DevFS { ...@@ -545,7 +571,7 @@ class DevFS {
if (!dirtyEntries.containsKey(entryUri)) { if (!dirtyEntries.containsKey(entryUri)) {
final DevFSFileContent content = DevFSFileContent(fs.file(compiledBinary)); final DevFSFileContent content = DevFSFileContent(fs.file(compiledBinary));
dirtyEntries[entryUri] = content; dirtyEntries[entryUri] = content;
numBytes += content.size; syncedBytes += content.size;
} }
} }
} }
...@@ -576,7 +602,8 @@ class DevFS { ...@@ -576,7 +602,8 @@ class DevFS {
} }
printTrace('DevFS: Sync finished'); printTrace('DevFS: Sync finished');
return numBytes; return UpdateFSReport(success: true, syncedBytes: syncedBytes,
invalidatedSourcesCount: invalidatedFiles.length);
} }
void _scanFile(Uri deviceUri, FileSystemEntity file) { void _scanFile(Uri deviceUri, FileSystemEntity file) {
......
...@@ -368,7 +368,7 @@ class FlutterDevice { ...@@ -368,7 +368,7 @@ class FlutterDevice {
return 0; return 0;
} }
Future<bool> updateDevFS({ Future<UpdateFSReport> updateDevFS({
String mainPath, String mainPath,
String target, String target,
AssetBundle bundle, AssetBundle bundle,
...@@ -384,9 +384,9 @@ class FlutterDevice { ...@@ -384,9 +384,9 @@ class FlutterDevice {
'Syncing files to device ${device.name}...', 'Syncing files to device ${device.name}...',
expectSlowOperation: true, expectSlowOperation: true,
); );
int bytes = 0; UpdateFSReport report;
try { try {
bytes = await devFS.update( report = await devFS.update(
mainPath: mainPath, mainPath: mainPath,
target: target, target: target,
bundle: bundle, bundle: bundle,
...@@ -403,11 +403,11 @@ class FlutterDevice { ...@@ -403,11 +403,11 @@ class FlutterDevice {
); );
} on DevFSException { } on DevFSException {
devFSStatus.cancel(); devFSStatus.cancel();
return false; return UpdateFSReport(success: false);
} }
devFSStatus.stop(); devFSStatus.stop();
printTrace('Synced ${getSizeAsMB(bytes)}.'); printTrace('Synced ${getSizeAsMB(report.syncedBytes)}.');
return true; return report;
} }
void updateReloadStatus(bool wasReloadSuccessful) { void updateReloadStatus(bool wasReloadSuccessful) {
......
...@@ -19,6 +19,7 @@ import 'build_info.dart'; ...@@ -19,6 +19,7 @@ import 'build_info.dart';
import 'compile.dart'; import 'compile.dart';
import 'dart/dependencies.dart'; import 'dart/dependencies.dart';
import 'dart/pub.dart'; import 'dart/pub.dart';
import 'devfs.dart';
import 'device.dart'; import 'device.dart';
import 'globals.dart'; import 'globals.dart';
import 'resident_runner.dart'; import 'resident_runner.dart';
...@@ -193,12 +194,12 @@ class HotRunner extends ResidentRunner { ...@@ -193,12 +194,12 @@ class HotRunner extends ResidentRunner {
return 3; return 3;
} }
final Stopwatch initialUpdateDevFSsTimer = Stopwatch()..start(); final Stopwatch initialUpdateDevFSsTimer = Stopwatch()..start();
final bool devfsResult = await _updateDevFS(fullRestart: true); final UpdateFSReport devfsResult = await _updateDevFS(fullRestart: true);
_addBenchmarkData( _addBenchmarkData(
'hotReloadInitialDevFSSyncMilliseconds', 'hotReloadInitialDevFSSyncMilliseconds',
initialUpdateDevFSsTimer.elapsed.inMilliseconds, initialUpdateDevFSsTimer.elapsed.inMilliseconds,
); );
if (!devfsResult) if (!devfsResult.success)
return 3; return 3;
await refreshViews(); await refreshViews();
...@@ -329,10 +330,10 @@ class HotRunner extends ResidentRunner { ...@@ -329,10 +330,10 @@ class HotRunner extends ResidentRunner {
return devFSUris; return devFSUris;
} }
Future<bool> _updateDevFS({ bool fullRestart = false }) async { Future<UpdateFSReport> _updateDevFS({ bool fullRestart = false }) async {
if (!await _refreshDartDependencies()) { if (!await _refreshDartDependencies()) {
// Did not update DevFS because of a Dart source error. // Did not update DevFS because of a Dart source error.
return false; return UpdateFSReport(success: false);
} }
final bool isFirstUpload = assetBundle.wasBuiltOnce() == false; final bool isFirstUpload = assetBundle.wasBuiltOnce() == false;
final bool rebuildBundle = assetBundle.needsBuild(); final bool rebuildBundle = assetBundle.needsBuild();
...@@ -340,12 +341,12 @@ class HotRunner extends ResidentRunner { ...@@ -340,12 +341,12 @@ class HotRunner extends ResidentRunner {
printTrace('Updating assets'); printTrace('Updating assets');
final int result = await assetBundle.build(); final int result = await assetBundle.build();
if (result != 0) if (result != 0)
return false; return UpdateFSReport(success: false);
} }
final List<bool> results = <bool>[]; final UpdateFSReport results = UpdateFSReport(success: true);
for (FlutterDevice device in flutterDevices) { for (FlutterDevice device in flutterDevices) {
results.add(await device.updateDevFS( results.incorporateResults(await device.updateDevFS(
mainPath: mainPath, mainPath: mainPath,
target: target, target: target,
bundle: assetBundle, bundle: assetBundle,
...@@ -358,16 +359,15 @@ class HotRunner extends ResidentRunner { ...@@ -358,16 +359,15 @@ class HotRunner extends ResidentRunner {
pathToReload: getReloadPath(fullRestart: fullRestart), pathToReload: getReloadPath(fullRestart: fullRestart),
)); ));
} }
// If there any failures reported, bail out. if (!results.success) {
if (results.any((bool result) => !result)) { return results;
return false;
} }
if (!hotRunnerConfig.stableDartDependencies) { if (!hotRunnerConfig.stableDartDependencies) {
// Clear the set after the sync so they are recomputed next time. // Clear the set after the sync so they are recomputed next time.
_dartDependencies = null; _dartDependencies = null;
} }
return true; return results;
} }
Future<void> _evictDirtyAssets() { Future<void> _evictDirtyAssets() {
...@@ -460,8 +460,8 @@ class HotRunner extends ResidentRunner { ...@@ -460,8 +460,8 @@ class HotRunner extends ResidentRunner {
final Stopwatch restartTimer = Stopwatch()..start(); final Stopwatch restartTimer = Stopwatch()..start();
// TODO(aam): Add generator reset logic once we switch to using incremental // TODO(aam): Add generator reset logic once we switch to using incremental
// compiler for full application recompilation on restart. // compiler for full application recompilation on restart.
final bool updatedDevFS = await _updateDevFS(fullRestart: true); final UpdateFSReport updatedDevFS = await _updateDevFS(fullRestart: true);
if (!updatedDevFS) { if (!updatedDevFS.success) {
for (FlutterDevice device in flutterDevices) { for (FlutterDevice device in flutterDevices) {
if (device.generator != null) if (device.generator != null)
device.generator.reject(); device.generator.reject();
...@@ -618,11 +618,11 @@ class HotRunner extends ResidentRunner { ...@@ -618,11 +618,11 @@ class HotRunner extends ResidentRunner {
final Stopwatch reloadTimer = Stopwatch()..start(); final Stopwatch reloadTimer = Stopwatch()..start();
final Stopwatch devFSTimer = Stopwatch()..start(); final Stopwatch devFSTimer = Stopwatch()..start();
final bool updatedDevFS = await _updateDevFS(); final UpdateFSReport updatedDevFS = await _updateDevFS();
// Record time it took to synchronize to DevFS. // Record time it took to synchronize to DevFS.
_addBenchmarkData('hotReloadDevFSSyncMilliseconds', _addBenchmarkData('hotReloadDevFSSyncMilliseconds',
devFSTimer.elapsed.inMilliseconds); devFSTimer.elapsed.inMilliseconds);
if (!updatedDevFS) if (!updatedDevFS.success)
return OperationResult(1, 'DevFS synchronization failed'); return OperationResult(1, 'DevFS synchronization failed');
String reloadMessage; String reloadMessage;
final Stopwatch vmReloadTimer = Stopwatch()..start(); final Stopwatch vmReloadTimer = Stopwatch()..start();
......
...@@ -119,7 +119,7 @@ void main() { ...@@ -119,7 +119,7 @@ void main() {
devFSOperations.expectMessages(<String>['create test']); devFSOperations.expectMessages(<String>['create test']);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
int bytes = await devFS.update( UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -130,7 +130,7 @@ void main() { ...@@ -130,7 +130,7 @@ void main() {
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
bytes = await devFS.update( report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -141,7 +141,8 @@ void main() { ...@@ -141,7 +141,8 @@ void main() {
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
...@@ -150,7 +151,7 @@ void main() { ...@@ -150,7 +151,7 @@ void main() {
final File file = fs.file(fs.path.join(basePath, filePath2)); final File file = fs.file(fs.path.join(basePath, filePath2));
await file.parent.create(recursive: true); await file.parent.create(recursive: true);
file.writeAsBytesSync(<int>[1, 2, 3, 4, 5, 6, 7]); file.writeAsBytesSync(<int>[1, 2, 3, 4, 5, 6, 7]);
final int bytes = await devFS.update( final UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -160,13 +161,14 @@ void main() { ...@@ -160,13 +161,14 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill', 'writeFile test lib/foo.txt.dill build/app.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('modify existing file on local file system', () async { testUsingContext('modify existing file on local file system', () async {
int bytes = await devFS.update( UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -176,12 +178,13 @@ void main() { ...@@ -176,12 +178,13 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill', 'writeFile test lib/foo.txt.dill build/app.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
final File file = fs.file(fs.path.join(basePath, filePath)); final File file = fs.file(fs.path.join(basePath, filePath));
// Set the last modified time to 5 seconds in the past. // Set the last modified time to 5 seconds in the past.
updateFileModificationTime(file.path, DateTime.now(), -5); updateFileModificationTime(file.path, DateTime.now(), -5);
bytes = await devFS.update( report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -191,10 +194,11 @@ void main() { ...@@ -191,10 +194,11 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill', 'writeFile test lib/foo.txt.dill build/app.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
await file.writeAsBytes(<int>[1, 2, 3, 4, 5, 6]); await file.writeAsBytes(<int>[1, 2, 3, 4, 5, 6]);
bytes = await devFS.update( report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -204,11 +208,12 @@ void main() { ...@@ -204,11 +208,12 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill', 'writeFile test lib/foo.txt.dill build/app.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
// Set the last modified time to 5 seconds in the past. // Set the last modified time to 5 seconds in the past.
updateFileModificationTime(file.path, DateTime.now(), -5); updateFileModificationTime(file.path, DateTime.now(), -5);
bytes = await devFS.update( report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -218,10 +223,11 @@ void main() { ...@@ -218,10 +223,11 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill.track.dill', 'writeFile test lib/foo.txt.dill build/app.dill.track.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
await file.writeAsBytes(<int>[1, 2, 3, 4, 5, 6]); await file.writeAsBytes(<int>[1, 2, 3, 4, 5, 6]);
bytes = await devFS.update( report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -231,7 +237,8 @@ void main() { ...@@ -231,7 +237,8 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill.track.dill', 'writeFile test lib/foo.txt.dill build/app.dill.track.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
...@@ -240,7 +247,7 @@ void main() { ...@@ -240,7 +247,7 @@ void main() {
testUsingContext('delete a file from the local file system', () async { testUsingContext('delete a file from the local file system', () async {
final File file = fs.file(fs.path.join(basePath, filePath)); final File file = fs.file(fs.path.join(basePath, filePath));
await file.delete(); await file.delete();
final int bytes = await devFS.update( final UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -251,14 +258,15 @@ void main() { ...@@ -251,14 +258,15 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill', 'writeFile test lib/foo.txt.dill build/app.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('add new package', () async { testUsingContext('add new package', () async {
await _createPackage(fs, 'newpkg', 'anotherfile.txt'); await _createPackage(fs, 'newpkg', 'anotherfile.txt');
int bytes = await devFS.update( UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -268,9 +276,10 @@ void main() { ...@@ -268,9 +276,10 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill', 'writeFile test lib/foo.txt.dill build/app.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
bytes = await devFS.update( report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -280,7 +289,8 @@ void main() { ...@@ -280,7 +289,8 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill.track.dill', 'writeFile test lib/foo.txt.dill build/app.dill.track.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
...@@ -302,7 +312,7 @@ void main() { ...@@ -302,7 +312,7 @@ void main() {
.map<String>((File file) => canonicalizePath(file.path)) .map<String>((File file) => canonicalizePath(file.path))
.toList()); .toList());
} }
final int bytes = await devFS.update( final UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
fileFilter: fileFilter, fileFilter: fileFilter,
generator: residentCompiler, generator: residentCompiler,
...@@ -313,14 +323,15 @@ void main() { ...@@ -313,14 +323,15 @@ void main() {
'writeFile test lib/foo.txt.dill build/app.dill', 'writeFile test lib/foo.txt.dill build/app.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('add an asset bundle', () async { testUsingContext('add an asset bundle', () async {
assetBundle.entries['a.txt'] = DevFSStringContent('abc'); assetBundle.entries['a.txt'] = DevFSStringContent('abc');
final int bytes = await devFS.update( final UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
bundle: assetBundle, bundle: assetBundle,
bundleDirty: true, bundleDirty: true,
...@@ -334,14 +345,14 @@ void main() { ...@@ -334,14 +345,14 @@ void main() {
]); ]);
expect(devFS.assetPathsToEvict, unorderedMatches(<String>['a.txt'])); expect(devFS.assetPathsToEvict, unorderedMatches(<String>['a.txt']));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 25); expect(report.syncedBytes, 25);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('add a file to the asset bundle - bundleDirty', () async { testUsingContext('add a file to the asset bundle - bundleDirty', () async {
assetBundle.entries['b.txt'] = DevFSStringContent('abcd'); assetBundle.entries['b.txt'] = DevFSStringContent('abcd');
final int bytes = await devFS.update( final UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
bundle: assetBundle, bundle: assetBundle,
bundleDirty: true, bundleDirty: true,
...@@ -358,14 +369,14 @@ void main() { ...@@ -358,14 +369,14 @@ void main() {
expect(devFS.assetPathsToEvict, unorderedMatches(<String>[ expect(devFS.assetPathsToEvict, unorderedMatches(<String>[
'a.txt', 'b.txt'])); 'a.txt', 'b.txt']));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 29); expect(report.syncedBytes, 29);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('add a file to the asset bundle', () async { testUsingContext('add a file to the asset bundle', () async {
assetBundle.entries['c.txt'] = DevFSStringContent('12'); assetBundle.entries['c.txt'] = DevFSStringContent('12');
final int bytes = await devFS.update( final UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
bundle: assetBundle, bundle: assetBundle,
generator: residentCompiler, generator: residentCompiler,
...@@ -379,14 +390,14 @@ void main() { ...@@ -379,14 +390,14 @@ void main() {
expect(devFS.assetPathsToEvict, unorderedMatches(<String>[ expect(devFS.assetPathsToEvict, unorderedMatches(<String>[
'c.txt'])); 'c.txt']));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 24); expect(report.syncedBytes, 24);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('delete a file from the asset bundle', () async { testUsingContext('delete a file from the asset bundle', () async {
assetBundle.entries.remove('c.txt'); assetBundle.entries.remove('c.txt');
final int bytes = await devFS.update( final UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
bundle: assetBundle, bundle: assetBundle,
generator: residentCompiler, generator: residentCompiler,
...@@ -399,14 +410,15 @@ void main() { ...@@ -399,14 +410,15 @@ void main() {
]); ]);
expect(devFS.assetPathsToEvict, unorderedMatches(<String>['c.txt'])); expect(devFS.assetPathsToEvict, unorderedMatches(<String>['c.txt']));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('delete all files from the asset bundle', () async { testUsingContext('delete all files from the asset bundle', () async {
assetBundle.entries.clear(); assetBundle.entries.clear();
final int bytes = await devFS.update( final UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
bundle: assetBundle, bundle: assetBundle,
bundleDirty: true, bundleDirty: true,
...@@ -423,7 +435,8 @@ void main() { ...@@ -423,7 +435,8 @@ void main() {
'a.txt', 'b.txt' 'a.txt', 'b.txt'
])); ]));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
...@@ -466,7 +479,7 @@ void main() { ...@@ -466,7 +479,7 @@ void main() {
vmService.expectMessages(<String>['create test']); vmService.expectMessages(<String>['create test']);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
final int bytes = await devFS.update( final UpdateFSReport report = await devFS.update(
mainPath: 'lib/foo.txt', mainPath: 'lib/foo.txt',
generator: residentCompiler, generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill', pathToReload: 'lib/foo.txt.dill',
...@@ -476,7 +489,8 @@ void main() { ...@@ -476,7 +489,8 @@ void main() {
'writeFile test lib/foo.txt.dill', 'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 22); expect(report.syncedBytes, 22);
expect(report.success, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
......
...@@ -112,7 +112,8 @@ void main() { ...@@ -112,7 +112,8 @@ void main() {
trackWidgetCreation: anyNamed('trackWidgetCreation'), trackWidgetCreation: anyNamed('trackWidgetCreation'),
projectRootPath: anyNamed('projectRootPath'), projectRootPath: anyNamed('projectRootPath'),
pathToReload: anyNamed('pathToReload'), pathToReload: anyNamed('pathToReload'),
)).thenAnswer((Invocation _) => Future<int>.value(1000)); )).thenAnswer((Invocation _) => Future<UpdateFSReport>.value(
UpdateFSReport(success: true, syncedBytes: 1000, invalidatedSourcesCount: 1)));
when(mockDevFs.assetPathsToEvict).thenReturn(Set<String>()); when(mockDevFs.assetPathsToEvict).thenReturn(Set<String>());
when(mockDevFs.baseUri).thenReturn(Uri.file('test')); when(mockDevFs.baseUri).thenReturn(Uri.file('test'));
......
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