diff --git a/dev/benchmarks/microbenchmarks/lib/stocks/animation_bench.dart b/dev/benchmarks/microbenchmarks/lib/stocks/animation_bench.dart index f6f74f4638..e7cb0115bf 100644 --- a/dev/benchmarks/microbenchmarks/lib/stocks/animation_bench.dart +++ b/dev/benchmarks/microbenchmarks/lib/stocks/animation_bench.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; diff --git a/dev/benchmarks/microbenchmarks/lib/stocks/build_bench.dart b/dev/benchmarks/microbenchmarks/lib/stocks/build_bench.dart index 791760a55a..0466f9776d 100644 --- a/dev/benchmarks/microbenchmarks/lib/stocks/build_bench.dart +++ b/dev/benchmarks/microbenchmarks/lib/stocks/build_bench.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; @@ -20,6 +21,7 @@ Future main() async { await benchmarkWidgets((WidgetTester tester) async { stocks.main(); await tester.pump(); // Start startup animation + new Timer(const Duration(milliseconds: 1100), () { }); // workaround for https://github.com/flutter/flutter/issues/7433 await tester.pump(const Duration(seconds: 1)); // Complete startup animation await tester.tapAt(new Point(20.0, 20.0)); // Open drawer await tester.pump(); // Start drawer animation diff --git a/dev/benchmarks/microbenchmarks/lib/stocks/layout_bench.dart b/dev/benchmarks/microbenchmarks/lib/stocks/layout_bench.dart index b19036d308..bb5753428c 100644 --- a/dev/benchmarks/microbenchmarks/lib/stocks/layout_bench.dart +++ b/dev/benchmarks/microbenchmarks/lib/stocks/layout_bench.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; @@ -19,6 +20,7 @@ Future main() async { await benchmarkWidgets((WidgetTester tester) async { stocks.main(); await tester.pump(); // Start startup animation + new Timer(const Duration(milliseconds: 1100), () { }); // workaround for https://github.com/flutter/flutter/issues/7433 await tester.pump(const Duration(seconds: 1)); // Complete startup animation await tester.tapAt(new Point(20.0, 20.0)); // Open drawer await tester.pump(); // Start drawer animation diff --git a/dev/devicelab/bin/tasks/microbenchmarks.dart b/dev/devicelab/bin/tasks/microbenchmarks.dart index 020a1cc1c0..2b01640fca 100644 --- a/dev/devicelab/bin/tasks/microbenchmarks.dart +++ b/dev/devicelab/bin/tasks/microbenchmarks.dart @@ -3,88 +3,13 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; - -import 'package:path/path.dart' as path; import 'package:flutter_devicelab/framework/adb.dart'; import 'package:flutter_devicelab/framework/framework.dart'; -import 'package:flutter_devicelab/framework/utils.dart'; +import 'package:flutter_devicelab/tasks/microbenchmarks.dart'; -/// Runs benchmarks in `dev/benchmarks/microbenchmarks` in the device lab and -/// reports results to the dashboard. +/// Runs microbenchmarks on Android. Future main() async { - await task(() async { - Device device = await devices.workingDevice; - await device.unlock(); - - Future> _runMicrobench(String benchmarkPath) async { - print('Running $benchmarkPath'); - Directory appDir = dir(path.join(flutterDirectory.path, 'dev/benchmarks/microbenchmarks')); - Process flutterProcess = await inDirectory(appDir, () async { - return await _startFlutter( - options: [ - '--release', - '-d', - device.deviceId, - benchmarkPath, - ], - canFail: false, - ); - }); - - return await _readJsonResults(flutterProcess); - } - - Map allResults = {}; - allResults.addAll(await _runMicrobench('lib/stocks/layout_bench.dart')); - allResults.addAll(await _runMicrobench('lib/stocks/build_bench.dart')); - allResults.addAll(await _runMicrobench('lib/stocks/animation_bench.dart')); - allResults.addAll(await _runMicrobench('lib/gestures/velocity_tracker_bench.dart')); - - return new TaskResult.success(allResults, benchmarkScoreKeys: allResults.keys.toList()); - }); -} - -Future _startFlutter({String command = 'run', List options: const [], bool canFail: false, Map env}) { - List args = ['run']..addAll(options); - return startProcess(path.join(flutterDirectory.path, 'bin', 'flutter'), args, env: env); -} - -Future> _readJsonResults(Process process) { - // IMPORTANT: keep these values in sync with dev/benchmarks/microbenchmarks/lib/common.dart - const String jsonStart = '================ RESULTS ================'; - const String jsonEnd = '================ FORMATTED =============='; - bool jsonStarted = false; - StringBuffer jsonBuf = new StringBuffer(); - Completer> completer = new Completer>(); - StreamSubscription stdoutSub; - - int prefixLength = 0; - stdoutSub = process.stdout - .transform(const Utf8Decoder()) - .transform(const LineSplitter()) - .listen((String line) { - print(line); - - if (line.contains(jsonStart)) { - jsonStarted = true; - prefixLength = line.indexOf(jsonStart); - return; - } - - if (line.contains(jsonEnd)) { - jsonStarted = false; - stdoutSub.cancel(); - process.kill(ProcessSignal.SIGINT); // flutter run doesn't quit automatically - completer.complete(JSON.decode(jsonBuf.toString())); - return; - } - - if (jsonStarted) - jsonBuf.writeln(line.substring(prefixLength)); - }); - - return completer.future; + deviceOperatingSystem = DeviceOperatingSystem.android; + await task(createMicrobenchmarkTask()); } diff --git a/dev/devicelab/bin/tasks/microbenchmarks_ios.dart b/dev/devicelab/bin/tasks/microbenchmarks_ios.dart new file mode 100644 index 0000000000..554d123281 --- /dev/null +++ b/dev/devicelab/bin/tasks/microbenchmarks_ios.dart @@ -0,0 +1,15 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter_devicelab/framework/adb.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/tasks/microbenchmarks.dart'; + +/// Runs microbenchmarks on iOS. +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.ios; + await task(createMicrobenchmarkTask()); +} diff --git a/dev/devicelab/lib/tasks/microbenchmarks.dart b/dev/devicelab/lib/tasks/microbenchmarks.dart new file mode 100644 index 0000000000..431ed7dd36 --- /dev/null +++ b/dev/devicelab/lib/tasks/microbenchmarks.dart @@ -0,0 +1,93 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:path/path.dart' as path; + +import 'package:flutter_devicelab/framework/adb.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/framework/utils.dart'; + +/// Creates a device lab task that runs benchmarks in +/// `dev/benchmarks/microbenchmarks` reports results to the dashboard. +TaskFunction createMicrobenchmarkTask() { + return () async { + Device device = await devices.workingDevice; + await device.unlock(); + + Future> _runMicrobench(String benchmarkPath) async { + print('Running $benchmarkPath'); + Directory appDir = dir(path.join(flutterDirectory.path, 'dev/benchmarks/microbenchmarks')); + Process flutterProcess = await inDirectory(appDir, () async { + return await _startFlutter( + options: [ + '--profile', // --release doesn't work on iOS due to code signing issues + '-d', + device.deviceId, + benchmarkPath, + ], + canFail: false, + ); + }); + + return await _readJsonResults(flutterProcess); + } + + Map allResults = {}; + allResults.addAll(await _runMicrobench('lib/stocks/layout_bench.dart')); + allResults.addAll(await _runMicrobench('lib/stocks/build_bench.dart')); + allResults.addAll(await _runMicrobench('lib/gestures/velocity_tracker_bench.dart')); + if (deviceOperatingSystem == DeviceOperatingSystem.android) { + // TODO(yjbanov): Run on iOS when https://github.com/flutter/flutter/issues/7433 is fixed. + allResults.addAll(await _runMicrobench('lib/stocks/animation_bench.dart')); + } + + return new TaskResult.success(allResults, benchmarkScoreKeys: allResults.keys.toList()); + }; +} + +Future _startFlutter({String command = 'run', List options: const [], bool canFail: false, Map env}) { + List args = ['run']..addAll(options); + return startProcess(path.join(flutterDirectory.path, 'bin', 'flutter'), args, env: env); +} + +Future> _readJsonResults(Process process) { + // IMPORTANT: keep these values in sync with dev/benchmarks/microbenchmarks/lib/common.dart + const String jsonStart = '================ RESULTS ================'; + const String jsonEnd = '================ FORMATTED =============='; + bool jsonStarted = false; + StringBuffer jsonBuf = new StringBuffer(); + Completer> completer = new Completer>(); + StreamSubscription stdoutSub; + + int prefixLength = 0; + stdoutSub = process.stdout + .transform(const Utf8Decoder()) + .transform(const LineSplitter()) + .listen((String line) { + print(line); + + if (line.contains(jsonStart)) { + jsonStarted = true; + prefixLength = line.indexOf(jsonStart); + return; + } + + if (line.contains(jsonEnd)) { + jsonStarted = false; + stdoutSub.cancel(); + process.kill(ProcessSignal.SIGINT); // flutter run doesn't quit automatically + completer.complete(JSON.decode(jsonBuf.toString())); + return; + } + + if (jsonStarted) + jsonBuf.writeln(line.substring(prefixLength)); + }); + + return completer.future; +}