Terminate simulator app on "q" (#113581)
This commit is contained in:
parent
3f89d6393f
commit
4d28e6d064
9
.ci.yaml
9
.ci.yaml
@ -3690,6 +3690,15 @@ targets:
|
|||||||
["devicelab", "ios", "mac"]
|
["devicelab", "ios", "mac"]
|
||||||
task_name: hot_mode_dev_cycle_ios__benchmark
|
task_name: hot_mode_dev_cycle_ios__benchmark
|
||||||
|
|
||||||
|
- name: Mac_ios hot_mode_dev_cycle_ios_simulator
|
||||||
|
recipe: devicelab/devicelab_drone
|
||||||
|
bringup: true
|
||||||
|
timeout: 60
|
||||||
|
properties:
|
||||||
|
tags: >
|
||||||
|
["devicelab", "ios", "mac"]
|
||||||
|
task_name: hot_mode_dev_cycle_ios_simulator
|
||||||
|
|
||||||
- name: Mac_ios fullscreen_textfield_perf_ios__e2e_summary
|
- name: Mac_ios fullscreen_textfield_perf_ios__e2e_summary
|
||||||
recipe: devicelab/devicelab_drone
|
recipe: devicelab/devicelab_drone
|
||||||
presubmit: false
|
presubmit: false
|
||||||
|
@ -168,6 +168,7 @@
|
|||||||
/dev/devicelab/bin/tasks/fullscreen_textfield_perf_impeller_ios__e2e_summary.dart @zanderso @flutter/engine
|
/dev/devicelab/bin/tasks/fullscreen_textfield_perf_impeller_ios__e2e_summary.dart @zanderso @flutter/engine
|
||||||
/dev/devicelab/bin/tasks/fullscreen_textfield_perf_ios__e2e_summary.dart @zanderso @flutter/engine
|
/dev/devicelab/bin/tasks/fullscreen_textfield_perf_ios__e2e_summary.dart @zanderso @flutter/engine
|
||||||
/dev/devicelab/bin/tasks/hello_world_ios__compile.dart @zanderso @flutter/engine
|
/dev/devicelab/bin/tasks/hello_world_ios__compile.dart @zanderso @flutter/engine
|
||||||
|
/dev/devicelab/bin/tasks/hot_mode_dev_cycle_ios_simulator.dart @jmagman @flutter/tool
|
||||||
/dev/devicelab/bin/tasks/hot_mode_dev_cycle_ios__benchmark.dart @zanderso @flutter/tool
|
/dev/devicelab/bin/tasks/hot_mode_dev_cycle_ios__benchmark.dart @zanderso @flutter/tool
|
||||||
/dev/devicelab/bin/tasks/hot_mode_dev_cycle_macos_target__benchmark.dart @zanderso @flutter/tool
|
/dev/devicelab/bin/tasks/hot_mode_dev_cycle_macos_target__benchmark.dart @zanderso @flutter/tool
|
||||||
/dev/devicelab/bin/tasks/imagefiltered_transform_animation_perf_impeller_ios__timeline_summary.dart @zanderso @flutter/engine
|
/dev/devicelab/bin/tasks/imagefiltered_transform_animation_perf_impeller_ios__timeline_summary.dart @zanderso @flutter/engine
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2014 The Flutter 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 'package:flutter_devicelab/framework/devices.dart';
|
||||||
|
import 'package:flutter_devicelab/framework/framework.dart';
|
||||||
|
import 'package:flutter_devicelab/framework/ios.dart';
|
||||||
|
import 'package:flutter_devicelab/framework/task_result.dart';
|
||||||
|
import 'package:flutter_devicelab/tasks/hot_mode_tests.dart';
|
||||||
|
|
||||||
|
Future<void> main() async {
|
||||||
|
await task(() async {
|
||||||
|
deviceOperatingSystem = DeviceOperatingSystem.ios;
|
||||||
|
String? simulatorDeviceId;
|
||||||
|
try {
|
||||||
|
await testWithNewIOSSimulator('TestHotReloadSim', (String deviceId) async {
|
||||||
|
simulatorDeviceId = deviceId;
|
||||||
|
// This isn't actually a benchmark test, so do not use the returned `benchmarkScoreKeys` result.
|
||||||
|
await createHotModeTest(deviceIdOverride: deviceId, checkAppRunningOnLocalDevice: true)();
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
await removeIOSimulator(simulatorDeviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TaskResult.success(null);
|
||||||
|
});
|
||||||
|
}
|
@ -6,5 +6,5 @@ import 'package:flutter_devicelab/framework/framework.dart';
|
|||||||
import 'package:flutter_devicelab/tasks/hot_mode_tests.dart';
|
import 'package:flutter_devicelab/tasks/hot_mode_tests.dart';
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
await task(createHotModeTest(deviceIdOverride: 'linux'));
|
await task(createHotModeTest(deviceIdOverride: 'linux', checkAppRunningOnLocalDevice: true));
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,11 @@ import 'dart:convert';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
import 'package:process/process.dart';
|
||||||
|
|
||||||
import '../framework/devices.dart';
|
import '../framework/devices.dart';
|
||||||
import '../framework/framework.dart';
|
import '../framework/framework.dart';
|
||||||
|
import '../framework/running_processes.dart';
|
||||||
import '../framework/task_result.dart';
|
import '../framework/task_result.dart';
|
||||||
import '../framework/utils.dart';
|
import '../framework/utils.dart';
|
||||||
|
|
||||||
@ -18,7 +20,11 @@ final Directory flutterGalleryDir = dir(path.join(flutterDirectory.path, 'dev/in
|
|||||||
const String kSourceLine = 'fontSize: (orientation == Orientation.portrait) ? 32.0 : 24.0';
|
const String kSourceLine = 'fontSize: (orientation == Orientation.portrait) ? 32.0 : 24.0';
|
||||||
const String kReplacementLine = 'fontSize: (orientation == Orientation.portrait) ? 34.0 : 24.0';
|
const String kReplacementLine = 'fontSize: (orientation == Orientation.portrait) ? 34.0 : 24.0';
|
||||||
|
|
||||||
TaskFunction createHotModeTest({String? deviceIdOverride, Map<String, String>? environment}) {
|
TaskFunction createHotModeTest({
|
||||||
|
String? deviceIdOverride,
|
||||||
|
Map<String, String>? environment,
|
||||||
|
bool checkAppRunningOnLocalDevice = false,
|
||||||
|
}) {
|
||||||
// This file is modified during the test and needs to be restored at the end.
|
// This file is modified during the test and needs to be restored at the end.
|
||||||
final File flutterFrameworkSource = file(path.join(
|
final File flutterFrameworkSource = file(path.join(
|
||||||
flutterDirectory.path, 'packages/flutter/lib/src/widgets/framework.dart',
|
flutterDirectory.path, 'packages/flutter/lib/src/widgets/framework.dart',
|
||||||
@ -96,7 +102,7 @@ TaskFunction createHotModeTest({String? deviceIdOverride, Map<String, String>? e
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
largeReloadData = await captureReloadData(options, environment, benchmarkFile, (String line, Process process) {
|
largeReloadData = await captureReloadData(options, environment, benchmarkFile, (String line, Process process) async {
|
||||||
if (!line.contains('Reloaded ')) {
|
if (!line.contains('Reloaded ')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -108,6 +114,9 @@ TaskFunction createHotModeTest({String? deviceIdOverride, Map<String, String>? e
|
|||||||
process.stdin.writeln('r');
|
process.stdin.writeln('r');
|
||||||
hotReloadCount += 1;
|
hotReloadCount += 1;
|
||||||
} else {
|
} else {
|
||||||
|
if (checkAppRunningOnLocalDevice) {
|
||||||
|
await _checkAppRunning(true);
|
||||||
|
}
|
||||||
process.stdin.writeln('q');
|
process.stdin.writeln('q');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -150,6 +159,9 @@ TaskFunction createHotModeTest({String? deviceIdOverride, Map<String, String>? e
|
|||||||
json.decode(benchmarkFile.readAsStringSync()) as Map<String, dynamic>;
|
json.decode(benchmarkFile.readAsStringSync()) as Map<String, dynamic>;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (checkAppRunningOnLocalDevice) {
|
||||||
|
await _checkAppRunning(false);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
flutterFrameworkSource.writeAsStringSync(oldContents);
|
flutterFrameworkSource.writeAsStringSync(oldContents);
|
||||||
}
|
}
|
||||||
@ -257,3 +269,23 @@ Future<Map<String, dynamic>> captureReloadData(
|
|||||||
benchmarkFile.deleteSync();
|
benchmarkFile.deleteSync();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _checkAppRunning(bool shouldBeRunning) async {
|
||||||
|
late Set<RunningProcessInfo> galleryProcesses;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
final String exe = Platform.isWindows ? '.exe' : '';
|
||||||
|
galleryProcesses = await getRunningProcesses(
|
||||||
|
processName: 'Flutter Gallery$exe',
|
||||||
|
processManager: const LocalProcessManager(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (galleryProcesses.isNotEmpty == shouldBeRunning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give the app time to shut down.
|
||||||
|
sleep(const Duration(seconds: 1));
|
||||||
|
}
|
||||||
|
print(galleryProcesses.join('\n'));
|
||||||
|
throw TaskResult.failure('Flutter Gallery app is ${shouldBeRunning ? 'not' : 'still'} running');
|
||||||
|
}
|
||||||
|
@ -257,6 +257,25 @@ class SimControl {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<RunResult> stopApp(String deviceId, String appIdentifier) async {
|
||||||
|
RunResult result;
|
||||||
|
try {
|
||||||
|
result = await _processUtils.run(
|
||||||
|
<String>[
|
||||||
|
..._xcode.xcrunCommand(),
|
||||||
|
'simctl',
|
||||||
|
'terminate',
|
||||||
|
deviceId,
|
||||||
|
appIdentifier,
|
||||||
|
],
|
||||||
|
throwOnError: true,
|
||||||
|
);
|
||||||
|
} on ProcessException catch (exception) {
|
||||||
|
throwToolExit('Unable to terminate $appIdentifier on $deviceId:\n$exception');
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> takeScreenshot(String deviceId, String outputPath) async {
|
Future<void> takeScreenshot(String deviceId, String outputPath) async {
|
||||||
try {
|
try {
|
||||||
await _processUtils.run(
|
await _processUtils.run(
|
||||||
@ -536,8 +555,7 @@ class IOSSimulator extends Device {
|
|||||||
ApplicationPackage app, {
|
ApplicationPackage app, {
|
||||||
String? userIdentifier,
|
String? userIdentifier,
|
||||||
}) async {
|
}) async {
|
||||||
// Currently we don't have a way to stop an app running on iOS.
|
return (await _simControl.stopApp(id, app.id)).exitCode == 0;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String get logFilePath {
|
String get logFilePath {
|
||||||
|
@ -901,6 +901,24 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
throwsToolExit(message: r'Unable to launch'),
|
throwsToolExit(message: r'Unable to launch'),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWithoutContext('.stopApp() handles exceptions', () async {
|
||||||
|
fakeProcessManager.addCommand(const FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'xcrun',
|
||||||
|
'simctl',
|
||||||
|
'terminate',
|
||||||
|
deviceId,
|
||||||
|
appId,
|
||||||
|
],
|
||||||
|
exception: ProcessException('xcrun', <String>[]),
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(
|
||||||
|
() async => simControl.stopApp(deviceId, appId),
|
||||||
|
throwsToolExit(message: r'Unable to terminate'),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('startApp', () {
|
group('startApp', () {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user