Some minor cleanup in devicelab (#36571)
This commit is contained in:
parent
d28f3c7cbb
commit
295530dcaf
@ -11,6 +11,7 @@ import 'package:flutter_devicelab/framework/utils.dart';
|
|||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
|
final String dot = Platform.isWindows ? '-' : '•';
|
||||||
await task(() async {
|
await task(() async {
|
||||||
final Stopwatch clock = Stopwatch()..start();
|
final Stopwatch clock = Stopwatch()..start();
|
||||||
final Process analysis = await startProcess(
|
final Process analysis = await startProcess(
|
||||||
@ -27,9 +28,9 @@ Future<void> main() async {
|
|||||||
print('analyzer stdout: $entry');
|
print('analyzer stdout: $entry');
|
||||||
if (entry == 'Building flutter tool...') {
|
if (entry == 'Building flutter tool...') {
|
||||||
// ignore this line
|
// ignore this line
|
||||||
} else if (entry.startsWith('info • Document all public members •')) {
|
} else if (entry.startsWith('info $dot Document all public members $dot')) {
|
||||||
publicMembers += 1;
|
publicMembers += 1;
|
||||||
} else if (entry.startsWith('info •') || entry.startsWith('warning •') || entry.startsWith('error •')) {
|
} else if (entry.startsWith('info $dot') || entry.startsWith('warning $dot') || entry.startsWith('error $dot')) {
|
||||||
otherErrors += 1;
|
otherErrors += 1;
|
||||||
} else if (entry.contains(' (ran in ') && !sawFinalLine) {
|
} else if (entry.contains(' (ran in ') && !sawFinalLine) {
|
||||||
// ignore this line once
|
// ignore this line once
|
||||||
|
@ -256,9 +256,18 @@ Future<ProcessResult> _resultOfGradleTask({String workingDirectory, String task,
|
|||||||
'app:$task',
|
'app:$task',
|
||||||
...?options,
|
...?options,
|
||||||
];
|
];
|
||||||
final String gradle = Platform.isWindows ? 'gradlew.bat' : './gradlew';
|
final String gradle = path.join(workingDirectory, Platform.isWindows ? 'gradlew.bat' : './gradlew');
|
||||||
print('Running Gradle: ${path.join(workingDirectory, gradle)} ${args.join(' ')}');
|
print('┌── $gradle');
|
||||||
print(File(path.join(workingDirectory, gradle)).readAsStringSync());
|
print('│ ' + File(path.join(workingDirectory, gradle)).readAsLinesSync().join('\n│ '));
|
||||||
|
print('└─────────────────────────────────────────────────────────────────────────────────────');
|
||||||
|
print(
|
||||||
|
'Running Gradle:\n'
|
||||||
|
' Executable: $gradle\n'
|
||||||
|
' Arguments: ${args.join(' ')}\n'
|
||||||
|
' Working directory: $workingDirectory\n'
|
||||||
|
' JAVA_HOME: $javaHome\n'
|
||||||
|
''
|
||||||
|
);
|
||||||
return Process.run(
|
return Process.run(
|
||||||
gradle,
|
gradle,
|
||||||
args,
|
args,
|
||||||
|
@ -14,11 +14,6 @@ import 'package:stack_trace/stack_trace.dart';
|
|||||||
import 'running_processes.dart';
|
import 'running_processes.dart';
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
|
||||||
/// Maximum amount of time a single task is allowed to take to run.
|
|
||||||
///
|
|
||||||
/// If exceeded the task is considered to have failed.
|
|
||||||
const Duration _kDefaultTaskTimeout = Duration(minutes: 15);
|
|
||||||
|
|
||||||
/// Represents a unit of work performed in the CI environment that can
|
/// Represents a unit of work performed in the CI environment that can
|
||||||
/// succeed, fail and be retried independently of others.
|
/// succeed, fail and be retried independently of others.
|
||||||
typedef TaskFunction = Future<TaskResult> Function();
|
typedef TaskFunction = Future<TaskResult> Function();
|
||||||
@ -55,7 +50,7 @@ class _TaskRunner {
|
|||||||
(String method, Map<String, String> parameters) async {
|
(String method, Map<String, String> parameters) async {
|
||||||
final Duration taskTimeout = parameters.containsKey('timeoutInMinutes')
|
final Duration taskTimeout = parameters.containsKey('timeoutInMinutes')
|
||||||
? Duration(minutes: int.parse(parameters['timeoutInMinutes']))
|
? Duration(minutes: int.parse(parameters['timeoutInMinutes']))
|
||||||
: _kDefaultTaskTimeout;
|
: null;
|
||||||
final TaskResult result = await run(taskTimeout);
|
final TaskResult result = await run(taskTimeout);
|
||||||
return ServiceExtensionResponse.result(json.encode(result.toJson()));
|
return ServiceExtensionResponse.result(json.encode(result.toJson()));
|
||||||
});
|
});
|
||||||
@ -90,7 +85,10 @@ class _TaskRunner {
|
|||||||
).toSet();
|
).toSet();
|
||||||
beforeRunningDartInstances.forEach(print);
|
beforeRunningDartInstances.forEach(print);
|
||||||
|
|
||||||
TaskResult result = await _performTask().timeout(taskTimeout);
|
Future<TaskResult> futureResult = _performTask();
|
||||||
|
if (taskTimeout != null)
|
||||||
|
futureResult = futureResult.timeout(taskTimeout);
|
||||||
|
TaskResult result = await futureResult;
|
||||||
|
|
||||||
section('Checking running Dart$exe processes after task...');
|
section('Checking running Dart$exe processes after task...');
|
||||||
final List<RunningProcessInfo> afterRunningDartInstances = await getRunningProcesses(
|
final List<RunningProcessInfo> afterRunningDartInstances = await getRunningProcesses(
|
||||||
|
@ -11,10 +11,6 @@ import 'package:vm_service_client/vm_service_client.dart';
|
|||||||
|
|
||||||
import 'package:flutter_devicelab/framework/utils.dart';
|
import 'package:flutter_devicelab/framework/utils.dart';
|
||||||
|
|
||||||
/// Slightly longer than task timeout that gives the task runner a chance to
|
|
||||||
/// clean-up before forcefully quitting it.
|
|
||||||
const Duration taskTimeoutWithGracePeriod = Duration(minutes: 26);
|
|
||||||
|
|
||||||
/// Runs a task in a separate Dart VM and collects the result using the VM
|
/// Runs a task in a separate Dart VM and collects the result using the VM
|
||||||
/// service protocol.
|
/// service protocol.
|
||||||
///
|
///
|
||||||
@ -71,21 +67,11 @@ Future<Map<String, dynamic>> runTask(
|
|||||||
stderr.writeln('[$taskName] [STDERR] $line');
|
stderr.writeln('[$taskName] [STDERR] $line');
|
||||||
});
|
});
|
||||||
|
|
||||||
String waitingFor = 'connection';
|
|
||||||
try {
|
try {
|
||||||
final VMIsolateRef isolate = await _connectToRunnerIsolate(await uri.future);
|
final VMIsolateRef isolate = await _connectToRunnerIsolate(await uri.future);
|
||||||
waitingFor = 'task completion';
|
final Map<String, dynamic> taskResult = await isolate.invokeExtension('ext.cocoonRunTask');
|
||||||
final Map<String, dynamic> taskResult =
|
await runner.exitCode;
|
||||||
await isolate.invokeExtension('ext.cocoonRunTask').timeout(taskTimeoutWithGracePeriod);
|
|
||||||
waitingFor = 'task process to exit';
|
|
||||||
await runner.exitCode.timeout(const Duration(seconds: 60));
|
|
||||||
return taskResult;
|
return taskResult;
|
||||||
} on TimeoutException catch (timeout) {
|
|
||||||
runner.kill(ProcessSignal.sigint);
|
|
||||||
return <String, dynamic>{
|
|
||||||
'success': false,
|
|
||||||
'reason': 'Timeout in runner.dart waiting for $waitingFor: ${timeout.message}',
|
|
||||||
};
|
|
||||||
} finally {
|
} finally {
|
||||||
if (!runnerFinished)
|
if (!runnerFinished)
|
||||||
runner.kill(ProcessSignal.sigkill);
|
runner.kill(ProcessSignal.sigkill);
|
||||||
@ -104,14 +90,7 @@ Future<VMIsolateRef> _connectToRunnerIsolate(Uri vmServiceUri) async {
|
|||||||
pathSegments.add('ws');
|
pathSegments.add('ws');
|
||||||
final String url = vmServiceUri.replace(scheme: 'ws', pathSegments:
|
final String url = vmServiceUri.replace(scheme: 'ws', pathSegments:
|
||||||
pathSegments).toString();
|
pathSegments).toString();
|
||||||
final DateTime started = DateTime.now();
|
final Stopwatch stopwatch = Stopwatch()..start();
|
||||||
|
|
||||||
// TODO(yjbanov): due to lack of imagination at the moment the handshake with
|
|
||||||
// the task process is very rudimentary and requires this small
|
|
||||||
// delay to let the task process open up the VM service port.
|
|
||||||
// Otherwise we almost always hit the non-ready case first and
|
|
||||||
// wait a whole 1 second, which is annoying.
|
|
||||||
await Future<void>.delayed(const Duration(milliseconds: 100));
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
@ -127,17 +106,9 @@ Future<VMIsolateRef> _connectToRunnerIsolate(Uri vmServiceUri) async {
|
|||||||
throw 'not ready yet';
|
throw 'not ready yet';
|
||||||
return isolate;
|
return isolate;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const Duration connectionTimeout = Duration(seconds: 10);
|
if (stopwatch.elapsed > const Duration(seconds: 10))
|
||||||
if (DateTime.now().difference(started) > connectionTimeout) {
|
print('VM service still not ready after ${stopwatch.elapsed}: $error\nContinuing to retry...');
|
||||||
throw TimeoutException(
|
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||||
'Failed to connect to the task runner process',
|
|
||||||
connectionTimeout,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
print('VM service not ready yet: $error');
|
|
||||||
const Duration pauseBetweenRetries = Duration(milliseconds: 200);
|
|
||||||
print('Will retry in $pauseBetweenRetries.');
|
|
||||||
await Future<void>.delayed(pauseBetweenRetries);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user