mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[flutter_tools] allow pulling performance data from assemble (#55699)
This commit is contained in:
parent
46a5c550db
commit
a58d50deb1
@ -666,7 +666,7 @@ class _BuildInstance {
|
||||
Future<bool> _invokeInternal(Node node) async {
|
||||
final PoolResource resource = await resourcePool.request();
|
||||
final Stopwatch stopwatch = Stopwatch()..start();
|
||||
bool passed = true;
|
||||
bool succeeded = true;
|
||||
bool skipped = false;
|
||||
|
||||
// The build system produces a list of aggregate input and output
|
||||
@ -702,7 +702,7 @@ class _BuildInstance {
|
||||
skipped = true;
|
||||
logger.printTrace('Skipping target: ${node.target.name}');
|
||||
updateGraph();
|
||||
return passed;
|
||||
return succeeded;
|
||||
}
|
||||
logger.printTrace('${node.target.name}: Starting due to ${node.invalidatedReasons}');
|
||||
await node.target.build(environment);
|
||||
@ -741,7 +741,7 @@ class _BuildInstance {
|
||||
// TODO(jonahwilliams): throw specific exception for expected errors to mark
|
||||
// as non-fatal. All others should be fatal.
|
||||
node.target.clearStamp(environment);
|
||||
passed = false;
|
||||
succeeded = false;
|
||||
skipped = false;
|
||||
exceptionMeasurements[node.target.name] = ExceptionMeasurement(
|
||||
node.target.name, exception, stackTrace);
|
||||
@ -752,11 +752,11 @@ class _BuildInstance {
|
||||
target: node.target.name,
|
||||
elapsedMilliseconds: stopwatch.elapsedMilliseconds,
|
||||
skipped: skipped,
|
||||
passed: passed,
|
||||
succeeded: succeeded,
|
||||
analyicsName: node.target.analyticsName,
|
||||
);
|
||||
}
|
||||
return passed;
|
||||
return succeeded;
|
||||
}
|
||||
}
|
||||
|
||||
@ -781,14 +781,14 @@ class PerformanceMeasurement {
|
||||
@required this.target,
|
||||
@required this.elapsedMilliseconds,
|
||||
@required this.skipped,
|
||||
@required this.passed,
|
||||
@required this.succeeded,
|
||||
@required this.analyicsName,
|
||||
});
|
||||
|
||||
final int elapsedMilliseconds;
|
||||
final String target;
|
||||
final bool skipped;
|
||||
final bool passed;
|
||||
final bool succeeded;
|
||||
final String analyicsName;
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import '../build_system/targets/macos.dart';
|
||||
import '../build_system/targets/web.dart';
|
||||
import '../build_system/targets/windows.dart';
|
||||
import '../cache.dart';
|
||||
import '../convert.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../project.dart';
|
||||
import '../reporting/reporting.dart';
|
||||
@ -72,6 +73,10 @@ class AssembleCommand extends FlutterCommand {
|
||||
abbr: 'd',
|
||||
help: 'Allows passing configuration to a target with --define=target=key=value.',
|
||||
);
|
||||
argParser.addOption(
|
||||
'performance-measurement-file',
|
||||
help: 'Output individual target performance to a JSON file.'
|
||||
);
|
||||
argParser.addMultiOption(
|
||||
'input',
|
||||
abbr: 'i',
|
||||
@ -231,6 +236,10 @@ class AssembleCommand extends FlutterCommand {
|
||||
if (argResults.wasParsed('build-outputs')) {
|
||||
writeListIfChanged(result.outputFiles, stringArg('build-outputs'));
|
||||
}
|
||||
if (argResults.wasParsed('performance-measurement-file')) {
|
||||
final File outFile = globals.fs.file(argResults['performance-measurement-file']);
|
||||
writePerformanceData(result.performance.values, outFile);
|
||||
}
|
||||
if (argResults.wasParsed('depfile')) {
|
||||
final File depfileFile = globals.fs.file(stringArg('depfile'));
|
||||
final Depfile depfile = Depfile(result.inputFiles, result.outputFiles);
|
||||
@ -262,6 +271,26 @@ void writeListIfChanged(List<File> files, String path) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Output performance measurement data in [outFile].
|
||||
@visibleForTesting
|
||||
void writePerformanceData(Iterable<PerformanceMeasurement> measurements, File outFile) {
|
||||
final Map<String, Object> jsonData = <String, Object>{
|
||||
'targets': <Object>[
|
||||
for (final PerformanceMeasurement measurement in measurements)
|
||||
<String, Object>{
|
||||
'name': measurement.analyicsName,
|
||||
'skipped': measurement.skipped,
|
||||
'succeeded': measurement.succeeded,
|
||||
'elapsedMilliseconds': measurement.elapsedMilliseconds,
|
||||
}
|
||||
]
|
||||
};
|
||||
if (!outFile.parent.existsSync()) {
|
||||
outFile.parent.createSync(recursive: true);
|
||||
}
|
||||
outFile.writeAsStringSync(json.encode(jsonData));
|
||||
}
|
||||
|
||||
class _CompositeTarget extends Target {
|
||||
_CompositeTarget(this.dependencies);
|
||||
|
||||
|
||||
@ -3,11 +3,14 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:file_testing/file_testing.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/assemble.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
@ -97,6 +100,37 @@ void main() {
|
||||
expect(testLogger.errorText, isNot(contains(testStackTrace.toString())));
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble outputs JSON performance data to provided file', () async {
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: true, performance: <String, PerformanceMeasurement>{
|
||||
'hello': PerformanceMeasurement(
|
||||
target: 'hello',
|
||||
analyicsName: 'bar',
|
||||
elapsedMilliseconds: 123,
|
||||
skipped: false,
|
||||
succeeded: true,
|
||||
),
|
||||
});
|
||||
});
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
|
||||
await commandRunner.run(<String>[
|
||||
'assemble',
|
||||
'-o Output',
|
||||
'--performance-measurement-file=out.json',
|
||||
'debug_macos_bundle_flutter_assets',
|
||||
]);
|
||||
|
||||
expect(globals.fs.file('out.json'), exists);
|
||||
expect(
|
||||
json.decode(globals.fs.file('out.json').readAsStringSync()),
|
||||
containsPair('targets', contains(
|
||||
containsPair('name', 'bar'),
|
||||
)),
|
||||
);
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble does not inject engine revision with local-engine', () async {
|
||||
Environment environment;
|
||||
when(globals.artifacts.isLocalEngine).thenReturn(true);
|
||||
@ -170,6 +204,36 @@ void main() {
|
||||
expect(inputs.readAsStringSync(), contains('fizz'));
|
||||
expect(inputs.lastModifiedSync(), isNot(theDistantPast));
|
||||
});
|
||||
|
||||
testWithoutContext('writePerformanceData outputs performance data in JSON form', () {
|
||||
final List<PerformanceMeasurement> performanceMeasurement = <PerformanceMeasurement>[
|
||||
PerformanceMeasurement(
|
||||
analyicsName: 'foo',
|
||||
target: 'hidden',
|
||||
skipped: false,
|
||||
succeeded: true,
|
||||
elapsedMilliseconds: 123,
|
||||
)
|
||||
];
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final File outFile = fileSystem.currentDirectory
|
||||
.childDirectory('foo')
|
||||
.childFile('out.json');
|
||||
|
||||
writePerformanceData(performanceMeasurement, outFile);
|
||||
|
||||
expect(outFile, exists);
|
||||
expect(json.decode(outFile.readAsStringSync()), <String, Object>{
|
||||
'targets': <Object>[
|
||||
<String, Object>{
|
||||
'name': 'foo',
|
||||
'skipped': false,
|
||||
'succeeded': true,
|
||||
'elapsedMilliseconds': 123,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class MockBuildSystem extends Mock implements BuildSystem {}
|
||||
|
||||
@ -119,14 +119,14 @@ void main() {
|
||||
analyicsName: 'kernel_snapshot',
|
||||
target: 'kernel_snapshot',
|
||||
elapsedMilliseconds: 1000,
|
||||
passed: true,
|
||||
succeeded: true,
|
||||
skipped: false,
|
||||
),
|
||||
'anything': PerformanceMeasurement(
|
||||
analyicsName: 'android_aot',
|
||||
target: 'anything',
|
||||
elapsedMilliseconds: 1000,
|
||||
passed: true,
|
||||
succeeded: true,
|
||||
skipped: false,
|
||||
),
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user