Try to be more consistent about deleting test apps in devicelab logic (#146931)

Fixes #137555.

This is an updated version of https://github.com/flutter/flutter/pull/146856, which was reverted in https://github.com/flutter/flutter/pull/146927. The first commit is identical to the original PR, and subsequent commits are the fixes to address failures detected in devicelab post-commit.
This commit is contained in:
Ian Hickson 2024-04-17 13:19:42 -07:00 committed by GitHub
parent 72b4b2921d
commit fb7e8b0653
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 75 additions and 35 deletions

View file

@ -32,6 +32,7 @@ void main() {
'-d',
deviceId,
]);
await device.uninstallApp();
});
final String outputPath = Platform.environment['FLUTTER_TEST_OUTPUTS_DIR'] ?? p.join(complexLayoutPath, 'build');

View file

@ -16,6 +16,7 @@ Future<String> _runWithMode(String mode, String deviceId) async {
'-d',
deviceId,
]);
await evalFlutter('install', options: <String>['--uninstall-only', '-d', deviceId]);
return stderr.toString();
}

View file

@ -29,6 +29,7 @@ class HelloWorldMemoryTest extends MemoryTest {
await recordStart();
await Future<void>.delayed(const Duration(milliseconds: 3000));
await recordEnd();
await device!.uninstallApp();
}
}

View file

@ -65,6 +65,7 @@ Future<TaskResult> run() async {
await Future<void>.delayed(const Duration(seconds: 30));
process.stdin.write('q');
await adb.cancel();
await device.uninstallApp();
});
if (!isUsingValidationLayers || impellerBackendCount != 1) {

View file

@ -7,6 +7,5 @@ import 'package:flutter_devicelab/framework/framework.dart' show task;
import 'package:flutter_devicelab/tasks/platform_channels_benchmarks.dart' as platform_channels_benchmarks;
Future<void> main() async {
await task(
platform_channels_benchmarks.runTask(DeviceOperatingSystem.android));
await task(platform_channels_benchmarks.runTask(DeviceOperatingSystem.android));
}

View file

@ -16,9 +16,9 @@ void main() {
final Device device = await devices.workingDevice;
await device.unlock();
final Directory appDir = dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
section('TEST WHETHER `flutter drive --route` WORKS on IOS');
section('TEST WHETHER `flutter drive --route` WORKS ON iOS');
await inDirectory(appDir, () async {
return flutter(
await flutter(
'drive',
options: <String>[
'--verbose',
@ -29,6 +29,7 @@ void main() {
'lib/route.dart',
],
);
await device.uninstallApp();
});
return TaskResult.success(null);
});

View file

@ -118,6 +118,7 @@ void main() {
if (result != 0) {
throw 'Received unexpected exit code $result from run process.';
}
await device.uninstallApp();
});
return TaskResult.success(null);
});

View file

@ -161,6 +161,13 @@ Future<void> main() async {
await stderr.cancel();
run.kill();
await inDirectory(path.join(tempDir.path, 'app'), () async {
await flutter(
'install',
options: <String>['--uninstall-only'],
);
});
if (nextCompleterIdx == sentinelCompleters.values.length) {
return TaskResult.success(null);
}

View file

@ -154,6 +154,13 @@ void main() {
await lifecycles.close();
await stdout.cancel();
await stderr.cancel();
await inDirectory(path.join(tempDir.path, 'app'), () async {
await flutter(
'install',
options: <String>['--uninstall-only'],
);
});
return TaskResult.success(null);
}

View file

@ -53,7 +53,7 @@ class DriverTest {
...extraOptions,
];
await flutter('drive', options: options, environment: environment);
await flutter('install', options: <String>['--uninstall-only', '-d', deviceId], environment: environment);
return TaskResult.success(null);
});
}

View file

@ -34,8 +34,7 @@ TaskFunction androidViewsTest({
final int exitCode = await exec(
'./gradlew',
<String>['-q', 'dependencies'],
workingDirectory:
'${flutterDirectory.path}/dev/integration_tests/android_views/android'
workingDirectory: '${flutterDirectory.path}/dev/integration_tests/android_views/android'
);
if (exitCode != 0) {
return TaskResult.failure('Failed to download gradle dependencies');
@ -51,6 +50,12 @@ TaskFunction androidViewsTest({
environment: environment,
workingDirectory: '${flutterDirectory.path}/dev/integration_tests/android_views'
);
await flutter(
'install',
options: <String>['--uninstall-only'],
environment: environment,
workingDirectory: '${flutterDirectory.path}/dev/integration_tests/android_views',
);
return TaskResult.success(null);
};
}

View file

@ -61,7 +61,6 @@ abstract class BuildTestTask {
await flutter('build', options: getBuildArgs(deviceOperatingSystem));
copyArtifacts();
});
}
/// Run Flutter drive test from [getTestArgs] against the application under test on the device.
@ -73,8 +72,8 @@ abstract class BuildTestTask {
await inDirectory<void>(workingDirectory, () async {
section('DRIVE START');
await flutter('drive', options: getTestArgs(deviceOperatingSystem, device.deviceId));
await device.uninstallApp();
});
return parseTaskResult();
}

View file

@ -65,12 +65,13 @@ class ApluginPlatformInterfaceMacOS {
pluginImplPubspecContent = pluginImplPubspecContent.replaceFirst(
' pluginClass: ApluginPlatformImplementationPlugin',
' pluginClass: ApluginPlatformImplementationPlugin\n'
' dartPluginClass: ApluginPlatformInterfaceMacOS\n',
' dartPluginClass: ApluginPlatformInterfaceMacOS\n',
);
pluginImplPubspecContent = pluginImplPubspecContent.replaceFirst(
' platforms:\n',
' implements: aplugin_platform_interface\n'
' platforms:\n');
' platforms:\n',
);
await pluginImplPubspec.writeAsString(pluginImplPubspecContent,
flush: true);
@ -104,8 +105,8 @@ class ApluginPlatformInterfaceMacOS {
pluginInterfacePubspecContent.replaceFirst(
'dependencies:',
'dependencies:\n'
' aplugin_platform_implementation:\n'
' path: ../aplugin_platform_implementation\n');
' aplugin_platform_implementation:\n'
' path: ../aplugin_platform_implementation\n');
await pluginInterfacePubspec.writeAsString(pluginInterfacePubspecContent,
flush: true);
@ -135,8 +136,8 @@ class ApluginPlatformInterfaceMacOS {
appPubspecContent = appPubspecContent.replaceFirst(
'dependencies:',
'dependencies:\n'
' aplugin_platform_interface:\n'
' path: ../aplugin_platform_interface\n');
' aplugin_platform_interface:\n'
' path: ../aplugin_platform_interface\n');
await appPubspec.writeAsString(appPubspecContent, flush: true);
section('Flutter run for macos');
@ -207,6 +208,11 @@ class ApluginPlatformInterfaceMacOS {
unawaited(stdoutSub.cancel());
unawaited(stderrSub.cancel());
await flutter(
'install',
options: <String>['--uninstall-only', '-d', 'macos'],
);
return TaskResult.success(null);
} finally {
rmTree(tempDir);

View file

@ -82,6 +82,7 @@ Future<TaskResult> _runWithTempDir(Directory tempDir) async {
process.stdin.write('q');
await process.stdin.flush();
process.kill(ProcessSignal.sigint);
await device.uninstallApp();
return entrypoint;
});
if (entrypoint.contains('$_messagePrefix $_entrypointName')) {

View file

@ -80,7 +80,6 @@ TaskFunction createGalleryTransitionHybridTest({bool semanticsEnabled = false})
}
class GalleryTransitionTest {
GalleryTransitionTest({
this.semanticsEnabled = false,
this.testFile = 'transitions_perf',
@ -154,6 +153,7 @@ class GalleryTransitionTest {
'-v',
'--verbose-system-logs'
]);
await flutter('install', options: <String>['--uninstall-only', '-d', deviceId]);
});
final String testOutputDirectory = Platform.environment['FLUTTER_TEST_OUTPUTS_DIR'] ?? '${galleryDirectory.path}/build';
@ -384,11 +384,11 @@ class GalleryTransitionBuildTest extends BuildTestTask {
String getApplicationBinaryPath() {
if (deviceOperatingSystem == DeviceOperatingSystem.android) {
return '$applicationBinaryPath/app-profile.apk';
} else if (deviceOperatingSystem == DeviceOperatingSystem.ios) {
return '$applicationBinaryPath/Flutter Gallery.app';
} else {
return applicationBinaryPath!;
}
if (deviceOperatingSystem == DeviceOperatingSystem.ios) {
return '$applicationBinaryPath/Flutter Gallery.app';
}
return applicationBinaryPath!;
}
}

View file

@ -168,6 +168,8 @@ TaskFunction createHotModeTest({
<Future<void>>[stdoutDone.future, stderrDone.future]);
await process.exitCode;
await flutter('install', options: <String>['--uninstall-only', '-d', deviceIdOverride!]);
freshRestartReloadsData =
json.decode(benchmarkFile.readAsStringSync()) as Map<String, dynamic>;
}

View file

@ -208,7 +208,7 @@ class DriverTest {
...extraOptions,
];
await flutter('drive', options: options, environment: environment);
await flutter('install', options: <String>['--uninstall-only', '-d', deviceId], environment: environment);
return TaskResult.success(null);
});
}
@ -267,6 +267,7 @@ class IntegrationTest {
if (withTalkBack) {
await disableTalkBack();
}
await flutter('install', options: <String>['--uninstall-only', '-d', deviceId], environment: environment);
return TaskResult.success(null);
});

View file

@ -47,7 +47,9 @@ TaskFunction createMicrobenchmarkTask({
environment: environment,
);
});
return readJsonResults(flutterProcess);
final Future<Map<String, double>> result = readJsonResults(flutterProcess);
await device.uninstallApp();
return result;
}
return run();

View file

@ -99,6 +99,7 @@ TaskFunction createNativeAssetsTest({
if (runFlutterResult != 0) {
print('Flutter run returned non-zero exit code: $runFlutterResult.');
}
await flutter('install', options: <String>['--uninstall-only', '-d', deviceIdOverride!]);
});
final int expectedNumberOfTransitions = buildMode == 'debug' ? 4 : 1;

View file

@ -1245,9 +1245,10 @@ class PerfTest {
/// If null, the device is selected depending on the current environment.
final Device? device;
/// The function called instead of the actually `flutter drive`.
/// The function called instead of the actual `flutter drive`.
///
/// If it is not `null`, `flutter drive` will not happen in the PerfTests.
/// If it is not `null`, `flutter drive` and `flutter install --uninstall-only`
/// will not happen in the PerfTests.
final FlutterDriveCallback? flutterDriveCallback;
/// Whether the perf test should enable Impeller.
@ -1260,6 +1261,8 @@ class PerfTest {
final bool disablePartialRepaint;
/// Number of seconds to time out the test after, allowing debug callbacks to run.
///
/// Passed to `--timeout`.
final int? timeoutSeconds;
/// The keys of the values that need to be reported.
@ -1393,6 +1396,7 @@ class PerfTest {
flutterDriveCallback!(options);
} else {
await flutter('drive', options: options);
await flutter('install', options: <String>['--uninstall-only', '-d', deviceId]);
}
} finally {
await resetManifest();
@ -2127,6 +2131,8 @@ class DevToolsMemoryTest {
}
}
await _device.uninstallApp();
return TaskResult.success(
<String, dynamic>{'maxRss': maxRss, 'maxAdbTotal': maxAdbTotal},
benchmarkScoreKeys: <String>['maxRss', 'maxAdbTotal'],
@ -2199,13 +2205,12 @@ class ReportedDurationTest {
await device!.stop(package);
await adb.cancel();
await device!.uninstallApp();
_device = null;
final Map<String, dynamic> reportedDuration = <String, dynamic>{
'duration': duration,
};
_device = null;
return TaskResult.success(reportedDuration, benchmarkScoreKeys: reportedDuration.keys.toList());
});
}

View file

@ -20,7 +20,7 @@ TaskFunction runTask(adb.DeviceOperatingSystem operatingSystem) {
final Directory appDir = utils.dir(path.join(utils.flutterDirectory.path,
'dev/benchmarks/platform_channels_benchmarks'));
final Process flutterProcess = await utils.inDirectory(appDir, () async {
return utils.inDirectory(appDir, () async {
final List<String> createArgs = <String>[
'--platforms',
'ios,android',
@ -39,15 +39,13 @@ TaskFunction runTask(adb.DeviceOperatingSystem operatingSystem) {
'-d',
device.deviceId,
];
return utils.startFlutter(
final Process flutterProcess = await utils.startFlutter(
'run',
options: options,
);
final Map<String, double> results = await microbenchmarks.readJsonResults(flutterProcess);
await device.uninstallApp();
return TaskResult.success(results, benchmarkScoreKeys: results.keys.toList());
});
final Map<String, double> results =
await microbenchmarks.readJsonResults(flutterProcess);
return TaskResult.success(results,
benchmarkScoreKeys: results.keys.toList());
};
}

View file

@ -109,7 +109,7 @@ class AndroidRunOutputTest extends RunOutputTask {
@override
bool isExpectedStderr(String line) {
// TODO(egarciad): Remove once https://github.com/flutter/flutter/issues/95131 is fixed.
// TODO(egarciad): Remove (because https://github.com/flutter/flutter/issues/95131 is now fixed)
return line.contains('Mapping new ns');
}
@ -321,6 +321,8 @@ abstract class RunOutputTask {
await run.exitCode;
await device.uninstallApp();
if (stderr.isNotEmpty) {
throw 'flutter run ${release ? '--release' : ''} had unexpected output on standard error.';
}

View file

@ -125,7 +125,6 @@ TaskFunction createWebDevModeTest(String webDevice, bool enableIncrementalCompil
// Start `flutter run` again to make sure it loads from the previous
// state. dev compilers loads up from previously compiled JavaScript.
{
final Stopwatch sw = Stopwatch()..start();
final Process process = await startFlutter(
'run',