Shut down gradle at the end of each task (#20968)
Apparently Gradle leaks memory and it's causing failures.
diff --git a/dev/devicelab/README.md b/dev/devicelab/README.md
index 2a0eba6..e584e5a 100644
--- a/dev/devicelab/README.md
+++ b/dev/devicelab/README.md
@@ -108,6 +108,12 @@
You can find where your Android SDK is using `flutter doctor`.
+## Warnings
+
+Running devicelab will do things to your environment.
+
+Notably, it will start and stop gradle, for instance.
+
## Running all tests
To run all tests defined in `manifest.yaml`, use option `-a` (`--all`):
diff --git a/dev/devicelab/lib/framework/runner.dart b/dev/devicelab/lib/framework/runner.dart
index 1332c9b..7985e86 100644
--- a/dev/devicelab/lib/framework/runner.dart
+++ b/dev/devicelab/lib/framework/runner.dart
@@ -6,6 +6,7 @@
import 'dart:convert';
import 'dart:io';
+import 'package:path/path.dart' as path;
import 'package:vm_service_client/vm_service_client.dart';
import 'package:flutter_devicelab/framework/utils.dart';
@@ -81,6 +82,7 @@
} finally {
if (!runnerFinished)
runner.kill(ProcessSignal.sigkill);
+ await cleanupSystem();
await stdoutSub.cancel();
await stderrSub.cancel();
}
@@ -125,3 +127,40 @@
}
}
}
+
+Future<void> cleanupSystem() async {
+ print('\n\nCleaning up system after task...');
+ final String javaHome = await findJavaHome();
+ if (javaHome != null) {
+ // To shut gradle down, we have to call "gradlew --stop".
+ // To call gradlew, we need to have a gradle-wrapper.properties file along
+ // with a shell script, a .jar file, etc. We get these from various places
+ // as you see in the code below, and we save them all into a temporary dir
+ // which we can then delete after.
+ // All the steps below are somewhat tolerant of errors, because it doesn't
+ // really matter if this succeeds every time or not.
+ print('\nTelling Gradle to shut down (JAVA_HOME=$javaHome)');
+ final String gradlewBinaryName = Platform.isWindows ? 'gradlew.bat' : 'gradlew';
+ final Directory tempDir = Directory.systemTemp.createTempSync('flutter_devicelab_shutdown_gradle.');
+ recursiveCopy(new Directory(path.join(flutterDirectory.path, 'bin', 'cache', 'artifacts', 'gradle_wrapper')), tempDir);
+ copy(new File(path.join(path.join(flutterDirectory.path, 'packages', 'flutter_tools'), 'templates', 'create', 'android.tmpl', 'gradle', 'wrapper', 'gradle-wrapper.properties')), new Directory(path.join(tempDir.path, 'gradle', 'wrapper')));
+ if (!Platform.isWindows) {
+ await exec(
+ 'chmod',
+ <String>['a+x', path.join(tempDir.path, gradlewBinaryName)],
+ canFail: true,
+ );
+ }
+ await exec(
+ path.join(tempDir.path, gradlewBinaryName),
+ <String>['--stop'],
+ environment: <String, String>{ 'JAVA_HOME': javaHome },
+ workingDirectory: tempDir.path,
+ canFail: true,
+ );
+ rmTree(tempDir);
+ print('\n');
+ } else {
+ print('Could not determine JAVA_HOME; not shutting down Gradle.');
+ }
+}
\ No newline at end of file
diff --git a/dev/devicelab/lib/framework/utils.dart b/dev/devicelab/lib/framework/utils.dart
index fd85a9b..f4fffdb 100644
--- a/dev/devicelab/lib/framework/utils.dart
+++ b/dev/devicelab/lib/framework/utils.dart
@@ -236,7 +236,7 @@
_runningProcesses.add(processInfo);
process.exitCode.then((int exitCode) {
- print('exitcode: $exitCode');
+ print('"$executable" exit code: $exitCode');
_runningProcesses.remove(processInfo);
});
@@ -266,8 +266,9 @@
List<String> arguments, {
Map<String, String> environment,
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
+ String workingDirectory,
}) async {
- final Process process = await startProcess(executable, arguments, environment: environment);
+ final Process process = await startProcess(executable, arguments, environment: environment, workingDirectory: workingDirectory);
final Completer<Null> stdoutDone = new Completer<Null>();
final Completer<Null> stderrDone = new Completer<Null>();
@@ -288,7 +289,7 @@
final int exitCode = await process.exitCode;
if (exitCode != 0 && !canFail)
- fail('Executable failed with exit code $exitCode.');
+ fail('Executable "$executable" failed with exit code $exitCode.');
return exitCode;
}
@@ -301,8 +302,9 @@
List<String> arguments, {
Map<String, String> environment,
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
+ String workingDirectory,
}) async {
- final Process process = await startProcess(executable, arguments, environment: environment);
+ final Process process = await startProcess(executable, arguments, environment: environment, workingDirectory: workingDirectory);
final StringBuffer output = new StringBuffer();
final Completer<Null> stdoutDone = new Completer<Null>();
@@ -325,7 +327,7 @@
final int exitCode = await process.exitCode;
if (exitCode != 0 && !canFail)
- fail('Executable failed with exit code $exitCode.');
+ fail('Executable "$executable" failed with exit code $exitCode.');
return output.toString().trimRight();
}