Migrate devicelab tests and test runners to null safety. (#85999)
* Migrate devicelab tests and test runners to null safety.
This commit is contained in:
parent
930e5c20c0
commit
8fcace1d6c
@ -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';
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
|
|
||||||
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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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()
|
|||||||
'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 @@
|
|||||||
// 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 @@
|
|||||||
// 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 @@
|
|||||||
// 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 @@
|
|||||||
// 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';
|
|||||||
|
|
||||||
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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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();
|
|||||||
|
|
||||||
@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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 @@
|
|||||||
// 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';
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group('AuthenticatedCocoonClient', () {
|
group('AuthenticatedCocoonClient', () {
|
||||||
FileSystem fs;
|
late FileSystem fs;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
fs = MemoryFileSystem();
|
fs = MemoryFileSystem();
|
||||||
|
@ -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';
|
|||||||
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() {
|
|||||||
);
|
);
|
||||||
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 @@
|
|||||||
// 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() {
|
|||||||
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 @@
|
|||||||
// 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 @@
|
|||||||
// 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 @@
|
|||||||
// 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() {
|
|||||||
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() {
|
|||||||
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 @@
|
|||||||
// 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';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user