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