Unverified Commit 8fcace1d authored by Darren Austin's avatar Darren Austin Committed by GitHub

Migrate devicelab tests and test runners to null safety. (#85999)

* Migrate devicelab tests and test runners to null safety.
parent 930e5c20
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
...@@ -15,43 +13,43 @@ import 'package:flutter_devicelab/framework/task_result.dart'; ...@@ -15,43 +13,43 @@ import 'package:flutter_devicelab/framework/task_result.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;
ArgResults args; late ArgResults args;
List<String> _taskNames = <String>[]; List<String> _taskNames = <String>[];
/// The device-id to run test on. /// The device-id to run test on.
String deviceId; String? deviceId;
/// The git branch being tested on. /// The git branch being tested on.
String gitBranch; String? gitBranch;
/// The build of the local engine to use. /// The build of the local engine to use.
/// ///
/// Required for A/B test mode. /// Required for A/B test mode.
String localEngine; String? localEngine;
/// The path to the engine "src/" directory. /// The path to the engine "src/" directory.
String localEngineSrcPath; String? localEngineSrcPath;
/// Name of the LUCI builder this test is currently running on. /// Name of the LUCI builder this test is currently running on.
/// ///
/// This is only passed on CI runs for Cocoon to be able to uniquely identify /// This is only passed on CI runs for Cocoon to be able to uniquely identify
/// this test run. /// this test run.
String luciBuilder; String? luciBuilder;
/// Whether to exit on first test failure. /// Whether to exit on first test failure.
bool exitOnFirstTestFailure; bool exitOnFirstTestFailure = false;
/// Path to write test results to. /// Path to write test results to.
String resultsPath; String? resultsPath;
/// File containing a service account token. /// File containing a service account token.
/// ///
/// If passed, the test run results will be uploaded to Flutter infrastructure. /// If passed, the test run results will be uploaded to Flutter infrastructure.
String serviceAccountTokenFile; String? serviceAccountTokenFile;
/// Suppresses standard output, prints only standard error output. /// Suppresses standard output, prints only standard error output.
bool silent; bool silent = false;
/// Runs tasks. /// Runs tasks.
/// ///
...@@ -68,15 +66,15 @@ Future<void> main(List<String> rawArgs) async { ...@@ -68,15 +66,15 @@ Future<void> main(List<String> rawArgs) async {
return; return;
} }
deviceId = args['device-id'] as String; deviceId = args['device-id'] as String?;
exitOnFirstTestFailure = args['exit'] as bool; exitOnFirstTestFailure = (args['exit'] as bool?) ?? false;
gitBranch = args['git-branch'] as String; gitBranch = args['git-branch'] as String?;
localEngine = args['local-engine'] as String; localEngine = args['local-engine'] as String?;
localEngineSrcPath = args['local-engine-src-path'] as String; localEngineSrcPath = args['local-engine-src-path'] as String?;
luciBuilder = args['luci-builder'] as String; luciBuilder = args['luci-builder'] as String?;
resultsPath = args['results-file'] as String; resultsPath = args['results-file'] as String?;
serviceAccountTokenFile = args['service-account-token-file'] as String; serviceAccountTokenFile = args['service-account-token-file'] as String?;
silent = args['silent'] as bool; silent = (args['silent'] as bool?) ?? false;
if (!args.wasParsed('task')) { if (!args.wasParsed('task')) {
if (args.wasParsed('stage') || args.wasParsed('all')) { if (args.wasParsed('stage') || args.wasParsed('all')) {
...@@ -137,7 +135,7 @@ Future<void> _runABTest() async { ...@@ -137,7 +135,7 @@ Future<void> _runABTest() async {
print('$taskName A/B test. Will run $runsPerTest times.'); print('$taskName A/B test. Will run $runsPerTest times.');
final ABTest abTest = ABTest(localEngine, taskName); final ABTest abTest = ABTest(localEngine!, taskName);
for (int i = 1; i <= runsPerTest; i++) { for (int i = 1; i <= runsPerTest; i++) {
section('Run #$i'); section('Run #$i');
...@@ -177,17 +175,17 @@ Future<void> _runABTest() async { ...@@ -177,17 +175,17 @@ Future<void> _runABTest() async {
abTest.addBResult(localEngineResult); abTest.addBResult(localEngineResult);
if (!silent && i < runsPerTest) { if (silent != true && i < runsPerTest) {
section('A/B results so far'); section('A/B results so far');
print(abTest.printSummary()); print(abTest.printSummary());
} }
} }
abTest.finalize(); abTest.finalize();
final File jsonFile = _uniqueFile(args['ab-result-file'] as String ?? 'ABresults#.json'); final File jsonFile = _uniqueFile(args['ab-result-file'] as String? ?? 'ABresults#.json');
jsonFile.writeAsStringSync(const JsonEncoder.withIndent(' ').convert(abTest.jsonMap)); jsonFile.writeAsStringSync(const JsonEncoder.withIndent(' ').convert(abTest.jsonMap));
if (!silent) { if (silent != true) {
section('Raw results'); section('Raw results');
print(abTest.rawResults()); print(abTest.rawResults());
} }
...@@ -214,9 +212,9 @@ File _uniqueFile(String filenameTemplate) { ...@@ -214,9 +212,9 @@ File _uniqueFile(String filenameTemplate) {
} }
void addTasks({ void addTasks({
List<ManifestTask> tasks, required List<ManifestTask> tasks,
ArgResults args, required ArgResults args,
List<String> taskNames, required List<String> taskNames,
}) { }) {
if (args.wasParsed('continue-from')) { if (args.wasParsed('continue-from')) {
final int index = tasks.indexWhere((ManifestTask task) => task.name == args['continue-from']); final int index = tasks.indexWhere((ManifestTask task) => task.name == args['continue-from']);
...@@ -286,7 +284,7 @@ final ArgParser _argParser = ArgParser() ...@@ -286,7 +284,7 @@ final ArgParser _argParser = ArgParser()
'produces a report containing averages, noise, and the speed-up\n' 'produces a report containing averages, noise, and the speed-up\n'
'between the two engines. --local-engine is required when running\n' 'between the two engines. --local-engine is required when running\n'
'an A/B test.', 'an A/B test.',
callback: (String value) { callback: (String? value) {
if (value != null && int.tryParse(value) == null) { if (value != null && int.tryParse(value) == null) {
throw ArgParserException('Option --ab must be a number, but was "$value".'); throw ArgParserException('Option --ab must be a number, but was "$value".');
} }
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:io'; import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_devicelab/framework/ab.dart'; import 'package:flutter_devicelab/framework/ab.dart';
import 'package:flutter_devicelab/framework/task_result.dart'; import 'package:flutter_devicelab/framework/task_result.dart';
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:collection/collection.dart' show ListEquality, MapEquality; import 'package:collection/collection.dart' show ListEquality, MapEquality;
import 'package:flutter_devicelab/framework/devices.dart'; import 'package:flutter_devicelab/framework/devices.dart';
...@@ -13,12 +11,11 @@ import 'common.dart'; ...@@ -13,12 +11,11 @@ import 'common.dart';
void main() { void main() {
group('device', () { group('device', () {
Device device; late Device device;
setUp(() { setUp(() {
FakeDevice.resetLog(); FakeDevice.resetLog();
device = null; device = FakeDevice(deviceId: 'fakeDeviceId');
device = FakeDevice();
}); });
tearDown(() { tearDown(() {
...@@ -131,9 +128,9 @@ void expectLog(List<CommandArgs> log) { ...@@ -131,9 +128,9 @@ void expectLog(List<CommandArgs> log) {
} }
CommandArgs cmd({ CommandArgs cmd({
String command, required String command,
List<String> arguments, List<String>? arguments,
Map<String, String> environment, Map<String, String>? environment,
}) { }) {
return CommandArgs( return CommandArgs(
command: command, command: command,
...@@ -146,11 +143,11 @@ typedef ExitErrorFactory = dynamic Function(); ...@@ -146,11 +143,11 @@ typedef ExitErrorFactory = dynamic Function();
@immutable @immutable
class CommandArgs { class CommandArgs {
const CommandArgs({ this.command, this.arguments, this.environment }); const CommandArgs({ required this.command, this.arguments, this.environment });
final String command; final String command;
final List<String> arguments; final List<String>? arguments;
final Map<String, String> environment; final Map<String, String>? environment;
@override @override
String toString() => 'CommandArgs(command: $command, arguments: $arguments, environment: $environment)'; String toString() => 'CommandArgs(command: $command, arguments: $arguments, environment: $environment)';
...@@ -177,7 +174,7 @@ class CommandArgs { ...@@ -177,7 +174,7 @@ class CommandArgs {
} }
class FakeDevice extends AndroidDevice { class FakeDevice extends AndroidDevice {
FakeDevice({String deviceId}) : super(deviceId: deviceId); FakeDevice({required String deviceId}) : super(deviceId: deviceId);
static String output = ''; static String output = '';
...@@ -206,7 +203,7 @@ class FakeDevice extends AndroidDevice { ...@@ -206,7 +203,7 @@ class FakeDevice extends AndroidDevice {
} }
@override @override
Future<String> shellEval(String command, List<String> arguments, { Map<String, String> environment, bool silent = false }) async { Future<String> shellEval(String command, List<String> arguments, { Map<String, String>? environment, bool silent = false }) async {
commandLog.add(CommandArgs( commandLog.add(CommandArgs(
command: command, command: command,
arguments: arguments, arguments: arguments,
...@@ -216,7 +213,7 @@ class FakeDevice extends AndroidDevice { ...@@ -216,7 +213,7 @@ class FakeDevice extends AndroidDevice {
} }
@override @override
Future<void> shellExec(String command, List<String> arguments, { Map<String, String> environment, bool silent = false }) async { Future<void> shellExec(String command, List<String> arguments, { Map<String, String>? environment, bool silent = false }) async {
commandLog.add(CommandArgs( commandLog.add(CommandArgs(
command: command, command: command,
arguments: arguments, arguments: arguments,
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
...@@ -17,14 +15,14 @@ import 'package:http/testing.dart'; ...@@ -17,14 +15,14 @@ import 'package:http/testing.dart';
import 'common.dart'; import 'common.dart';
void main() { void main() {
ProcessResult _processResult; late ProcessResult _processResult;
ProcessResult runSyncStub(String executable, List<String> args, ProcessResult runSyncStub(String executable, List<String> args,
{Map<String, String> environment, {Map<String, String>? environment,
bool includeParentEnvironment, bool includeParentEnvironment = true,
bool runInShell, bool runInShell = false,
Encoding stderrEncoding, Encoding? stderrEncoding,
Encoding stdoutEncoding, Encoding? stdoutEncoding,
String workingDirectory}) => String? workingDirectory}) =>
_processResult; _processResult;
// Expected test values. // Expected test values.
...@@ -33,9 +31,9 @@ void main() { ...@@ -33,9 +31,9 @@ void main() {
const String serviceAccountToken = 'test_token'; const String serviceAccountToken = 'test_token';
group('Cocoon', () { group('Cocoon', () {
Client mockClient; late Client mockClient;
Cocoon cocoon; late Cocoon cocoon;
FileSystem fs; late FileSystem fs;
setUp(() { setUp(() {
fs = MemoryFileSystem(); fs = MemoryFileSystem();
...@@ -183,7 +181,7 @@ void main() { ...@@ -183,7 +181,7 @@ void main() {
}); });
group('AuthenticatedCocoonClient', () { group('AuthenticatedCocoonClient', () {
FileSystem fs; late FileSystem fs;
setUp(() { setUp(() {
fs = MemoryFileSystem(); fs = MemoryFileSystem();
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_devicelab/framework/host_agent.dart'; import 'package:flutter_devicelab/framework/host_agent.dart';
...@@ -12,7 +10,7 @@ import 'package:platform/platform.dart'; ...@@ -12,7 +10,7 @@ import 'package:platform/platform.dart';
import 'common.dart'; import 'common.dart';
void main() { void main() {
FileSystem fs; late FileSystem fs;
setUp(() { setUp(() {
fs = MemoryFileSystem(); fs = MemoryFileSystem();
hostAgent.resetDumpDirectory(); hostAgent.resetDumpDirectory();
...@@ -31,8 +29,8 @@ void main() { ...@@ -31,8 +29,8 @@ void main() {
); );
final HostAgent agent = HostAgent(platform: fakePlatform, fileSystem: fs); final HostAgent agent = HostAgent(platform: fakePlatform, fileSystem: fs);
expect(agent.dumpDirectory.existsSync(), isTrue); expect(agent.dumpDirectory!.existsSync(), isTrue);
expect(agent.dumpDirectory.path, environmentDir.path); expect(agent.dumpDirectory!.path, environmentDir.path);
}); });
test('not set by environment', () async { test('not set by environment', () async {
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:io'; import 'dart:io';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
...@@ -31,7 +29,7 @@ void main() { ...@@ -31,7 +29,7 @@ void main() {
Future<void> expectScriptResult( Future<void> expectScriptResult(
List<String> testNames, List<String> testNames,
int expectedExitCode, int expectedExitCode,
{String deviceId} {String? deviceId}
) async { ) async {
final ProcessResult result = await runScript(testNames, <String>[ final ProcessResult result = await runScript(testNames, <String>[
if (deviceId != null) ...<String>['-d', deviceId], if (deviceId != null) ...<String>['-d', deviceId],
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_devicelab/framework/running_processes.dart'; import 'package:flutter_devicelab/framework/running_processes.dart';
import 'common.dart'; import 'common.dart';
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_devicelab/framework/task_result.dart'; import 'package:flutter_devicelab/framework/task_result.dart';
import 'common.dart'; import 'common.dart';
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'package:flutter_devicelab/framework/runner.dart'; import 'package:flutter_devicelab/framework/runner.dart';
...@@ -24,7 +22,7 @@ void main() { ...@@ -24,7 +22,7 @@ void main() {
deviceId: 'FAKE_SUCCESS', deviceId: 'FAKE_SUCCESS',
isolateParams: isolateParams, isolateParams: isolateParams,
); );
expect(result.data['benchmark'], 'data'); expect(result.data!['benchmark'], 'data');
}); });
test('runs build only when build arg is given', () async { test('runs build only when build arg is given', () async {
...@@ -44,7 +42,7 @@ void main() { ...@@ -44,7 +42,7 @@ void main() {
deviceId: 'FAKE_SUCCESS', deviceId: 'FAKE_SUCCESS',
isolateParams: isolateParams, isolateParams: isolateParams,
); );
expect(result.data['benchmark'], 'data'); expect(result.data!['benchmark'], 'data');
}); });
test('sets environment', () async { test('sets environment', () async {
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_devicelab/framework/utils.dart'; import 'package:flutter_devicelab/framework/utils.dart';
import 'common.dart'; import 'common.dart';
......
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