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