Commit 604f1761 authored by xster's avatar xster Committed by Jenn Magder

Add more flutter build ios-framework tests before the impending jonahpocalypse (#44308)

parent dfbbfcd3
...@@ -152,7 +152,7 @@ Future<void> main() async { ...@@ -152,7 +152,7 @@ Future<void> main() async {
section('Check assets in release AAR'); section('Check assets in release AAR');
checkItContains<String>( checkCollectionContains<String>(
<String>[ <String>[
...flutterAssets, ...flutterAssets,
// AOT snapshots // AOT snapshots
...@@ -278,7 +278,7 @@ Future<void> main() async { ...@@ -278,7 +278,7 @@ Future<void> main() async {
'flutter_debug-1.0.aar', 'flutter_debug-1.0.aar',
)); ));
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
], debugAar); ], debugAar);
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter_devicelab/framework/apk_utils.dart';
import 'package:flutter_devicelab/framework/framework.dart'; import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/ios.dart';
import 'package:flutter_devicelab/framework/utils.dart'; import 'package:flutter_devicelab/framework/utils.dart';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
...@@ -69,7 +69,29 @@ Future<void> main() async { ...@@ -69,7 +69,29 @@ Future<void> main() async {
'vm_snapshot_data', 'vm_snapshot_data',
)); ));
section('Check profile, release builds has Dart dylib'); section('Check debug build has no Dart AOT');
// There's still an App.framework with a dylib, but it's empty.
checkFileExists(path.join(
outputPath,
'Debug',
'App.framework',
'App',
));
final String aotSymbols = await dylibSymbols(path.join(
outputPath,
'Debug',
'App.framework',
'App',
));
if (aotSymbols.contains('architecture') ||
aotSymbols.contains('_kDartVmSnapshot')) {
throw TaskResult.failure('Debug App.framework contains AOT');
}
section('Check profile, release builds has Dart AOT dylib');
for (String mode in <String>['Profile', 'Release']) { for (String mode in <String>['Profile', 'Release']) {
checkFileExists(path.join( checkFileExists(path.join(
...@@ -79,6 +101,25 @@ Future<void> main() async { ...@@ -79,6 +101,25 @@ Future<void> main() async {
'App', 'App',
)); ));
final String aotSymbols = await dylibSymbols(path.join(
outputPath,
mode,
'App.framework',
'App',
));
if (!aotSymbols.contains('armv7')) {
throw TaskResult.failure('$mode App.framework armv7 architecture missing');
}
if (!aotSymbols.contains('arm64')) {
throw TaskResult.failure('$mode App.framework arm64 architecture missing');
}
if (!aotSymbols.contains('_kDartVmSnapshot')) {
throw TaskResult.failure('$mode App.framework missing Dart AOT');
}
checkFileNotExists(path.join( checkFileNotExists(path.join(
outputPath, outputPath,
mode, mode,
......
...@@ -31,7 +31,7 @@ Future<void> main() async { ...@@ -31,7 +31,7 @@ Future<void> main() async {
'release', 'release',
'app-release.aab', 'app-release.aab',
); );
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...baseAabFiles, ...baseAabFiles,
...flutterAabAssets, ...flutterAabAssets,
'base/lib/arm64-v8a/libapp.so', 'base/lib/arm64-v8a/libapp.so',
...@@ -66,7 +66,7 @@ Future<void> main() async { ...@@ -66,7 +66,7 @@ Future<void> main() async {
'productionRelease', 'productionRelease',
'app-production-release.aab', 'app-production-release.aab',
); );
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...baseAabFiles, ...baseAabFiles,
...flutterAabAssets, ...flutterAabAssets,
'base/lib/arm64-v8a/libapp.so', 'base/lib/arm64-v8a/libapp.so',
...@@ -102,7 +102,7 @@ Future<void> main() async { ...@@ -102,7 +102,7 @@ Future<void> main() async {
'flavor_underscoreRelease', 'flavor_underscoreRelease',
'app-flavor_underscore-release.aab', 'app-flavor_underscore-release.aab',
); );
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...baseAabFiles, ...baseAabFiles,
...flutterAabAssets, ...flutterAabAssets,
'base/lib/arm64-v8a/libapp.so', 'base/lib/arm64-v8a/libapp.so',
...@@ -137,7 +137,7 @@ Future<void> main() async { ...@@ -137,7 +137,7 @@ Future<void> main() async {
'productionRelease', 'productionRelease',
'app-production-release.aab', 'app-production-release.aab',
); );
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...baseAabFiles, ...baseAabFiles,
...flutterAabAssets, ...flutterAabAssets,
'base/lib/arm64-v8a/libapp.so', 'base/lib/arm64-v8a/libapp.so',
...@@ -163,14 +163,14 @@ Future<void> main() async { ...@@ -163,14 +163,14 @@ Future<void> main() async {
); );
final Iterable<String> bundleFiles = await getFilesInAppBundle(releaseBundle); final Iterable<String> bundleFiles = await getFilesInAppBundle(releaseBundle);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...baseAabFiles, ...baseAabFiles,
...flutterAabAssets, ...flutterAabAssets,
'base/lib/armeabi-v7a/libapp.so', 'base/lib/armeabi-v7a/libapp.so',
'base/lib/armeabi-v7a/libflutter.so', 'base/lib/armeabi-v7a/libflutter.so',
], bundleFiles); ], bundleFiles);
checkItDoesNotContain<String>(<String>[ checkCollectionDoesNotContain<String>(<String>[
'base/lib/arm64-v8a/libapp.so', 'base/lib/arm64-v8a/libapp.so',
'base/lib/arm64-v8a/libflutter.so', 'base/lib/arm64-v8a/libflutter.so',
], bundleFiles); ], bundleFiles);
......
...@@ -19,7 +19,7 @@ Future<void> main() async { ...@@ -19,7 +19,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath); final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
...baseApkFiles, ...baseApkFiles,
...@@ -30,7 +30,7 @@ Future<void> main() async { ...@@ -30,7 +30,7 @@ Future<void> main() async {
'lib/x86_64/libflutter.so', 'lib/x86_64/libflutter.so',
], apkFiles); ], apkFiles);
checkItDoesNotContain<String>(<String>[ checkCollectionDoesNotContain<String>(<String>[
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
'lib/armeabi-v7a/libapp.so', 'lib/armeabi-v7a/libapp.so',
'lib/x86/libapp.so', 'lib/x86/libapp.so',
...@@ -44,7 +44,7 @@ Future<void> main() async { ...@@ -44,7 +44,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath); final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...baseApkFiles, ...baseApkFiles,
'lib/armeabi-v7a/libflutter.so', 'lib/armeabi-v7a/libflutter.so',
...@@ -53,7 +53,7 @@ Future<void> main() async { ...@@ -53,7 +53,7 @@ Future<void> main() async {
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
], apkFiles); ], apkFiles);
checkItDoesNotContain<String>(debugAssets, apkFiles); checkCollectionDoesNotContain<String>(debugAssets, apkFiles);
}); });
await runPluginProjectTest((FlutterPluginProject pluginProject) async { await runPluginProjectTest((FlutterPluginProject pluginProject) async {
...@@ -63,7 +63,7 @@ Future<void> main() async { ...@@ -63,7 +63,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath); final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...baseApkFiles, ...baseApkFiles,
'lib/armeabi-v7a/libflutter.so', 'lib/armeabi-v7a/libflutter.so',
...@@ -72,7 +72,7 @@ Future<void> main() async { ...@@ -72,7 +72,7 @@ Future<void> main() async {
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
], apkFiles); ], apkFiles);
checkItDoesNotContain<String>(debugAssets, apkFiles); checkCollectionDoesNotContain<String>(debugAssets, apkFiles);
}); });
await runPluginProjectTest((FlutterPluginProject pluginProject) async { await runPluginProjectTest((FlutterPluginProject pluginProject) async {
...@@ -83,25 +83,25 @@ Future<void> main() async { ...@@ -83,25 +83,25 @@ Future<void> main() async {
final Iterable<String> armApkFiles = await getFilesInApk(pluginProject.releaseArmApkPath); final Iterable<String> armApkFiles = await getFilesInApk(pluginProject.releaseArmApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...baseApkFiles, ...baseApkFiles,
'lib/armeabi-v7a/libflutter.so', 'lib/armeabi-v7a/libflutter.so',
'lib/armeabi-v7a/libapp.so', 'lib/armeabi-v7a/libapp.so',
], armApkFiles); ], armApkFiles);
checkItDoesNotContain<String>(debugAssets, armApkFiles); checkCollectionDoesNotContain<String>(debugAssets, armApkFiles);
final Iterable<String> arm64ApkFiles = await getFilesInApk(pluginProject.releaseArm64ApkPath); final Iterable<String> arm64ApkFiles = await getFilesInApk(pluginProject.releaseArm64ApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...baseApkFiles, ...baseApkFiles,
'lib/arm64-v8a/libflutter.so', 'lib/arm64-v8a/libflutter.so',
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
], arm64ApkFiles); ], arm64ApkFiles);
checkItDoesNotContain<String>(debugAssets, arm64ApkFiles); checkCollectionDoesNotContain<String>(debugAssets, arm64ApkFiles);
}); });
await runProjectTest((FlutterProject project) async { await runProjectTest((FlutterProject project) async {
......
...@@ -19,7 +19,7 @@ Future<void> main() async { ...@@ -19,7 +19,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath); final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
...baseApkFiles, ...baseApkFiles,
...@@ -29,7 +29,7 @@ Future<void> main() async { ...@@ -29,7 +29,7 @@ Future<void> main() async {
'lib/x86_64/libflutter.so', 'lib/x86_64/libflutter.so',
], apkFiles); ], apkFiles);
checkItDoesNotContain<String>(<String>[ checkCollectionDoesNotContain<String>(<String>[
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
'lib/armeabi-v7a/libapp.so', 'lib/armeabi-v7a/libapp.so',
'lib/x86/libapp.so', 'lib/x86/libapp.so',
...@@ -45,7 +45,7 @@ Future<void> main() async { ...@@ -45,7 +45,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath); final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
...baseApkFiles, ...baseApkFiles,
...@@ -54,7 +54,7 @@ Future<void> main() async { ...@@ -54,7 +54,7 @@ Future<void> main() async {
'lib/x86_64/libflutter.so', 'lib/x86_64/libflutter.so',
], apkFiles); ], apkFiles);
checkItDoesNotContain<String>(<String>[ checkCollectionDoesNotContain<String>(<String>[
'lib/armeabi-v7a/libapp.so', 'lib/armeabi-v7a/libapp.so',
'lib/x86/libapp.so', 'lib/x86/libapp.so',
'lib/x86_64/libapp.so', 'lib/x86_64/libapp.so',
...@@ -69,7 +69,7 @@ Future<void> main() async { ...@@ -69,7 +69,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath); final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
...baseApkFiles, ...baseApkFiles,
...@@ -78,7 +78,7 @@ Future<void> main() async { ...@@ -78,7 +78,7 @@ Future<void> main() async {
'lib/x86_64/libflutter.so', 'lib/x86_64/libflutter.so',
], apkFiles); ], apkFiles);
checkItDoesNotContain<String>(<String>[ checkCollectionDoesNotContain<String>(<String>[
'lib/armeabi-v7a/libapp.so', 'lib/armeabi-v7a/libapp.so',
'lib/x86/libapp.so', 'lib/x86/libapp.so',
'lib/x86_64/libapp.so', 'lib/x86_64/libapp.so',
...@@ -92,14 +92,14 @@ Future<void> main() async { ...@@ -92,14 +92,14 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath); final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...baseApkFiles, ...baseApkFiles,
'lib/armeabi-v7a/libflutter.so', 'lib/armeabi-v7a/libflutter.so',
'lib/armeabi-v7a/libapp.so', 'lib/armeabi-v7a/libapp.so',
], apkFiles); ], apkFiles);
checkItDoesNotContain<String>(<String>[ checkCollectionDoesNotContain<String>(<String>[
...debugAssets, ...debugAssets,
'lib/arm64-v8a/libflutter.so', 'lib/arm64-v8a/libflutter.so',
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
...@@ -113,14 +113,14 @@ Future<void> main() async { ...@@ -113,14 +113,14 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath); final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...baseApkFiles, ...baseApkFiles,
'lib/arm64-v8a/libflutter.so', 'lib/arm64-v8a/libflutter.so',
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
], apkFiles); ], apkFiles);
checkItDoesNotContain<String>(<String>[ checkCollectionDoesNotContain<String>(<String>[
...debugAssets, ...debugAssets,
'lib/armeabi-v7a/libflutter.so', 'lib/armeabi-v7a/libflutter.so',
'lib/armeabi-v7a/libapp.so', 'lib/armeabi-v7a/libapp.so',
......
...@@ -123,7 +123,7 @@ Future<void> main() async { ...@@ -123,7 +123,7 @@ Future<void> main() async {
section('Verify snapshots in app-demo-debug.apk'); section('Verify snapshots in app-demo-debug.apk');
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
], await getFilesInApk(demoDebugApk)); ], await getFilesInApk(demoDebugApk));
...@@ -166,7 +166,7 @@ Future<void> main() async { ...@@ -166,7 +166,7 @@ Future<void> main() async {
section('Verify snapshots in app-demo-debug.apk'); section('Verify snapshots in app-demo-debug.apk');
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
], await getFilesInApk(demoDebugApk2)); ], await getFilesInApk(demoDebugApk2));
...@@ -201,7 +201,7 @@ Future<void> main() async { ...@@ -201,7 +201,7 @@ Future<void> main() async {
section('Verify snapshots in app-demo-staging.apk'); section('Verify snapshots in app-demo-staging.apk');
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
], await getFilesInApk(demoStagingApk)); ], await getFilesInApk(demoStagingApk));
...@@ -238,7 +238,7 @@ Future<void> main() async { ...@@ -238,7 +238,7 @@ Future<void> main() async {
section('Verify AOT blobs in app-demo-release-unsigned.apk'); section('Verify AOT blobs in app-demo-release-unsigned.apk');
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
'lib/arm64-v8a/libflutter.so', 'lib/arm64-v8a/libflutter.so',
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
...@@ -276,7 +276,7 @@ Future<void> main() async { ...@@ -276,7 +276,7 @@ Future<void> main() async {
section('Verify AOT blobs in app-demo-prod-unsigned.apk'); section('Verify AOT blobs in app-demo-prod-unsigned.apk');
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
'lib/arm64-v8a/libflutter.so', 'lib/arm64-v8a/libflutter.so',
......
...@@ -198,7 +198,7 @@ Future<void> main() async { ...@@ -198,7 +198,7 @@ Future<void> main() async {
section('Check files in debug APK'); section('Check files in debug APK');
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...debugAssets, ...debugAssets,
...baseApkFiles, ...baseApkFiles,
...@@ -253,7 +253,7 @@ Future<void> main() async { ...@@ -253,7 +253,7 @@ Future<void> main() async {
section('Check files in release APK'); section('Check files in release APK');
checkItContains<String>(<String>[ checkCollectionContains<String>(<String>[
...flutterAssets, ...flutterAssets,
...baseApkFiles, ...baseApkFiles,
'lib/arm64-v8a/libapp.so', 'lib/arm64-v8a/libapp.so',
......
...@@ -76,36 +76,6 @@ Future<Iterable<String>> getFilesInAar(String aar) { ...@@ -76,36 +76,6 @@ Future<Iterable<String>> getFilesInAar(String aar) {
return getFilesInApk(aar); return getFilesInApk(aar);
} }
void checkItContains<T>(Iterable<T> values, Iterable<T> collection) {
for (T value in values) {
if (!collection.contains(value)) {
throw TaskResult.failure('Expected to find `$value` in `${collection.toString()}`.');
}
}
}
void checkItDoesNotContain<T>(Iterable<T> values, Iterable<T> collection) {
for (T value in values) {
if (collection.contains(value)) {
throw TaskResult.failure('Did not expect to find `$value` in `$collection`.');
}
}
}
/// Checks that [str] contains the specified [Pattern]s, otherwise throws
/// a [TaskResult].
void checkFileContains(List<Pattern> patterns, String filePath) {
final String fileContent = File(filePath).readAsStringSync();
for (Pattern pattern in patterns) {
if (!fileContent.contains(pattern)) {
throw TaskResult.failure(
'Expected to find `$pattern` in `$filePath` '
'instead it found:\n$fileContent'
);
}
}
}
TaskResult failure(String message, ProcessResult result) { TaskResult failure(String message, ProcessResult result) {
print('Unexpected process result:'); print('Unexpected process result:');
print('Exit code: ${result.exitCode}'); print('Exit code: ${result.exitCode}');
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:io' as dart_io; import 'dart:io' as dart_io;
import 'package:file/file.dart'; import 'package:file/file.dart';
...@@ -101,3 +102,50 @@ It is defined by environment variable $_kProvisioningConfigFileEnvironmentVariab ...@@ -101,3 +102,50 @@ It is defined by environment variable $_kProvisioningConfigFileEnvironmentVariab
return file.readAsString(); return file.readAsString();
} }
void _checkExitCode(int code) {
if (code != 0) {
throw Exception(
'Unexpected exit code = $code!',
);
}
}
Future<void> _execAndCheck(String executable, List<String> args) async {
_checkExitCode(await exec(executable, args));
}
// Measure the CPU/GPU percentage for [duration] while a Flutter app is running
// on an iOS device (e.g., right after a Flutter driver test has finished, which
// doesn't close the Flutter app, and the Flutter app has an indefinite
// animation). The return should have a format like the following json
// ```
// {"gpu_percentage":12.6,"cpu_percentage":18.15}
// ```
Future<Map<String, dynamic>> measureIosCpuGpu({
Duration duration = const Duration(seconds: 10),
String deviceId,
}) async {
await _execAndCheck('pub', <String>[
'global',
'activate',
'gauge',
'0.1.4',
]);
await _execAndCheck('pub', <String>[
'global',
'run',
'gauge',
'ioscpugpu',
'new',
if (deviceId != null) ...<String>['-w', deviceId],
'-l',
'${duration.inMilliseconds}',
]);
return json.decode(file('$cwd/result.json').readAsStringSync());
}
Future<String> dylibSymbols(String pathToDylib) {
return eval('nm', <String>['-g', pathToDylib]);
}
...@@ -13,6 +13,8 @@ import 'package:path/path.dart' as path; ...@@ -13,6 +13,8 @@ import 'package:path/path.dart' as path;
import 'package:process/process.dart'; import 'package:process/process.dart';
import 'package:stack_trace/stack_trace.dart'; import 'package:stack_trace/stack_trace.dart';
import 'framework.dart';
/// Virtual current working directory, which affect functions, such as [exec]. /// Virtual current working directory, which affect functions, such as [exec].
String cwd = Directory.current.path; String cwd = Directory.current.path;
...@@ -632,45 +634,34 @@ void checkFileNotExists(String file) { ...@@ -632,45 +634,34 @@ void checkFileNotExists(String file) {
} }
} }
void _checkExitCode(int code) { /// Check that `collection` contains all entries in `values`.
if (code != 0) { void checkCollectionContains<T>(Iterable<T> values, Iterable<T> collection) {
throw Exception( for (T value in values) {
'Unexpected exit code = $code!', if (!collection.contains(value)) {
); throw TaskResult.failure('Expected to find `$value` in `${collection.toString()}`.');
}
} }
} }
Future<void> _execAndCheck(String executable, List<String> args) async { /// Check that `collection` does not contain any entries in `values`
_checkExitCode(await exec(executable, args)); void checkCollectionDoesNotContain<T>(Iterable<T> values, Iterable<T> collection) {
for (T value in values) {
if (collection.contains(value)) {
throw TaskResult.failure('Did not expect to find `$value` in `$collection`.');
}
}
} }
// Measure the CPU/GPU percentage for [duration] while a Flutter app is running /// Checks that the contents of a [File] at `filePath` contains the specified
// on an iOS device (e.g., right after a Flutter driver test has finished, which /// [Pattern]s, otherwise throws a [TaskResult].
// doesn't close the Flutter app, and the Flutter app has an indefinite void checkFileContains(List<Pattern> patterns, String filePath) {
// animation). The return should have a format like the following json final String fileContent = File(filePath).readAsStringSync();
// ``` for (Pattern pattern in patterns) {
// {"gpu_percentage":12.6,"cpu_percentage":18.15} if (!fileContent.contains(pattern)) {
// ``` throw TaskResult.failure(
Future<Map<String, dynamic>> measureIosCpuGpu({ 'Expected to find `$pattern` in `$filePath` '
Duration duration = const Duration(seconds: 10), 'instead it found:\n$fileContent'
String deviceId, );
}) async { }
await _execAndCheck('pub', <String>[ }
'global',
'activate',
'gauge',
'0.1.4',
]);
await _execAndCheck('pub', <String>[
'global',
'run',
'gauge',
'ioscpugpu',
'new',
if (deviceId != null) ...<String>['-w', deviceId],
'-l',
'${duration.inMilliseconds}',
]);
return json.decode(file('$cwd/result.json').readAsStringSync());
} }
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