Skip to content

Commit

Permalink
Add et query tests and et test commands
Browse files Browse the repository at this point in the history
- `et query tests` enumerates all test binaries encoded in BUILD.gn files.
- `et test` (builds, then) runs a set of tests in parallel
- Tests
  • Loading branch information
johnmccutchan committed Mar 28, 2024
1 parent 4e6692c commit a1e3b83
Show file tree
Hide file tree
Showing 15 changed files with 796 additions and 186 deletions.
12 changes: 6 additions & 6 deletions tools/engine_tool/lib/src/build_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,9 @@ void debugCheckBuilds(List<Build> builds) {
}

/// Build the build target in the environment.
Future<int> runBuild(
Environment environment,
Build build, {
List<String> extraGnArgs = const <String>[],
}) async {
Future<int> runBuild(Environment environment, Build build,
{List<String> extraGnArgs = const <String>[],
List<String> targets = const <String>[]}) async {
// If RBE config files aren't in the tree, then disable RBE.
final String rbeConfigPath = p.join(
environment.engine.srcDir.path,
Expand All @@ -79,10 +77,11 @@ Future<int> runBuild(
'rbe',
);
final List<String> gnArgs = <String>[
...extraGnArgs,
if (!io.Directory(rbeConfigPath).existsSync()) '--no-rbe',
...extraGnArgs,
];

// TODO(loic-sharma): Fetch dependencies if needed.
final BuildRunner buildRunner = BuildRunner(
platform: environment.platform,
processRunner: environment.processRunner,
Expand All @@ -91,6 +90,7 @@ Future<int> runBuild(
build: build,
extraGnArgs: gnArgs,
runTests: false,
extraNinjaArgs: targets,
);

Spinner? spinner;
Expand Down
18 changes: 2 additions & 16 deletions tools/engine_tool/lib/src/commands/build_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,12 @@ final class BuildCommand extends CommandBase {
}) {
builds = runnableBuilds(environment, configs);
debugCheckBuilds(builds);
argParser.addOption(
configFlag,
abbr: 'c',
defaultsTo: 'host_debug',
help: 'Specify the build config to use',
allowed: <String>[
for (final Build config in runnableBuilds(environment, configs))
config.name,
],
allowedHelp: <String, String>{
for (final Build config in runnableBuilds(environment, configs))
config.name: config.gn.join(' '),
},
);
addConfigOption(argParser, runnableBuilds(environment, configs));
argParser.addFlag(
rbeFlag,
defaultsTo: true,
help: 'RBE is enabled by default when available. Use --no-rbe to '
'disable it.',
'disable it.',
);
}

Expand Down Expand Up @@ -63,7 +50,6 @@ final class BuildCommand extends CommandBase {
if (!useRbe) '--no-rbe',
];

// TODO(loic-sharma): Fetch dependencies if needed.
return runBuild(environment, build, extraGnArgs: extraGnArgs);
}
}
24 changes: 21 additions & 3 deletions tools/engine_tool/lib/src/commands/command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,35 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:engine_build_configs/engine_build_configs.dart';

import '../environment.dart';
import 'flags.dart';

/// The base class that all commands and subcommands should inherit from.
abstract base class CommandBase extends Command<int> {
/// Constructs the base command.
CommandBase({
required this.environment
});
CommandBase({required this.environment});

/// The host system environment.
final Environment environment;
}

/// Adds the -c (--config) option to the parser.
void addConfigOption(ArgParser parser, List<Build> builds,
{String defaultsTo = 'host_debug'}) {
parser.addOption(
configFlag,
abbr: 'c',
defaultsTo: defaultsTo,
help: 'Specify the build config to use',
allowed: <String>[
for (final Build config in builds) config.name,
],
allowedHelp: <String, String>{
for (final Build config in builds) config.name: config.gn.join(' '),
},
);
}
2 changes: 2 additions & 0 deletions tools/engine_tool/lib/src/commands/command_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'format_command.dart';
import 'lint_command.dart';
import 'query_command.dart';
import 'run_command.dart';
import 'test_command.dart';

const int _usageLineLength = 80;

Expand All @@ -31,6 +32,7 @@ final class ToolCommandRunner extends CommandRunner<int> {
BuildCommand(environment: environment, configs: configs),
RunCommand(environment: environment, configs: configs),
LintCommand(environment: environment),
TestCommand(environment: environment, configs: configs),
];
commands.forEach(addCommand);

Expand Down
115 changes: 1 addition & 114 deletions tools/engine_tool/lib/src/commands/lint_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
// found in the LICENSE file.

import 'dart:io' show Directory;
import 'dart:math';

import 'package:path/path.dart' as p;

import '../dart_utils.dart';
import '../environment.dart';
import '../logger.dart';

import '../proc_utils.dart';
import '../worker_pool.dart';
import 'command.dart';
Expand Down Expand Up @@ -113,114 +111,3 @@ final class LintCommand extends CommandBase {
return r ? 0 : 1;
}
}

/// A WorkerPoolProgressReporter designed to work with ProcessTasks.
class ProcessTaskProgressReporter implements WorkerPoolProgressReporter {
/// Construct a new reporter.
ProcessTaskProgressReporter(this._environment);

final Environment _environment;
Spinner? _spinner;
bool _finished = false;
int _longestName = 0;

@override
void onRun(Set<WorkerTask> tasks) {
for (final WorkerTask task in tasks) {
_longestName = max(_longestName, task.name.length);
}
}

@override
void onFinish() {
_finished = true;
_updateSpinner(<ProcessTask>[]);
}

List<ProcessTask> _makeProcessTaskList(WorkerPool pool) {
final List<ProcessTask> runningTasks = <ProcessTask>[];
for (final WorkerTask task in pool.running) {
if (task is! ProcessTask) {
continue;
}
runningTasks.add(task);
}
return runningTasks;
}

@override
void onTaskStart(WorkerPool pool, WorkerTask task) {
final List<ProcessTask> running = _makeProcessTaskList(pool);
_updateSpinner(running);
}

@override
void onTaskDone(WorkerPool pool, WorkerTask task, [Object? err]) {
final List<ProcessTask> running = _makeProcessTaskList(pool);
task as ProcessTask;
final ProcessArtifacts pa = task.processArtifacts;
final String dt = _formatDurationShort(task.runTime);
if (pa.exitCode != 0) {
final String paPath = task.processArtifactsPath;
_environment.logger.clearLine();
_environment.logger.status(
'FAIL: ${task.name.padLeft(_longestName)} after $dt [details in $paPath]');
} else {
_environment.logger.clearLine();
_environment.logger
.status('OKAY: ${task.name.padLeft(_longestName)} after $dt');
}
_updateSpinner(running);
}

void _updateSpinner(List<ProcessTask> tasks) {
if (_spinner != null) {
_spinner!.finish();
_spinner = null;
}
if (_finished) {
return;
}
_environment.logger.clearLine();
String runStatus = '[';
for (final ProcessTask pt in tasks) {
if (runStatus != '[') {
runStatus += ' ';
}
runStatus += pt.name;
}
if (tasks.isNotEmpty) {
runStatus += '...';
}
runStatus += '] ';
_environment.logger.status('Linting $runStatus', newline: false);
_spinner = _environment.logger.startSpinner();
}
}

String _formatDurationShort(Duration dur) {
int micros = dur.inMicroseconds;
String r = '';
if (micros >= Duration.microsecondsPerMinute) {
final int minutes = micros ~/ Duration.microsecondsPerMinute;
micros -= minutes * Duration.microsecondsPerMinute;
r += '${minutes}m';
}
if (micros >= Duration.microsecondsPerSecond) {
final int seconds = micros ~/ Duration.microsecondsPerSecond;
micros -= seconds * Duration.microsecondsPerSecond;
if (r.isNotEmpty) {
r += '.';
}
r += '${seconds}s';
}
if (micros >= Duration.microsecondsPerMillisecond) {
final int millis = micros ~/ Duration.microsecondsPerMillisecond;
micros -= millis * Duration.microsecondsPerMillisecond;
if (r.isNotEmpty) {
r += '.';
}
r += '${millis}ms';
}
return r;
}
69 changes: 67 additions & 2 deletions tools/engine_tool/lib/src/commands/query_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io';

import 'package:engine_build_configs/engine_build_configs.dart';

import 'package:path/path.dart' as p;

import '../build_utils.dart';
import '../gn_utils.dart';
import 'command.dart';
import 'flags.dart';

Expand Down Expand Up @@ -42,6 +48,10 @@ final class QueryCommand extends CommandBase {
environment: environment,
configs: configs,
));
addSubcommand(QueryTestsCommand(
environment: environment,
configs: configs,
));
}

/// Build configurations loaded from the engine from under ci/builders.
Expand All @@ -55,9 +65,9 @@ final class QueryCommand extends CommandBase {
'and tests.';
}

/// The 'query builds' command.
/// The 'query builders' command.
final class QueryBuildersCommand extends CommandBase {
/// Constructs the 'query build' command.
/// Constructs the 'query builders' command.
QueryBuildersCommand({
required super.environment,
required this.configs,
Expand Down Expand Up @@ -120,3 +130,58 @@ final class QueryBuildersCommand extends CommandBase {
return 0;
}
}

/// The query tests command.
final class QueryTestsCommand extends CommandBase {
/// Constructs the 'query tests' command.
QueryTestsCommand({
required super.environment,
required this.configs,
}) {
builds = runnableBuilds(environment, configs);
debugCheckBuilds(builds);
argParser.addOption(
configFlag,
abbr: 'c',
defaultsTo: 'host_debug',
help: 'Specify the build config to use',
allowed: <String>[
for (final Build config in runnableBuilds(environment, configs))
config.name,
],
allowedHelp: <String, String>{
for (final Build config in runnableBuilds(environment, configs))
config.name: config.gn.join(' '),
},
);
}

/// Build configurations loaded from the engine from under ci/builders.
final Map<String, BuilderConfig> configs;

/// List of compatible builds.
late final List<Build> builds;

@override
String get name => 'tests';

@override
String get description => 'Provides information about test targets';

@override
Future<int> run() async {
final String configName = argResults![configFlag] as String;
final Build? build =
builds.where((Build build) => build.name == configName).firstOrNull;
if (build == null) {
environment.logger.error('Could not find config $configName');
return 1;
}
final Map<String, TestTarget> targets = await findTestTargets(environment,
Directory(p.join(environment.engine.outDir.path, build.ninja.config)));
for (final TestTarget target in targets.values) {
environment.logger.status(target.label);
}
return 0;
}
}
22 changes: 5 additions & 17 deletions tools/engine_tool/lib/src/commands/run_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,15 @@ final class RunCommand extends CommandBase {
}) {
builds = runnableBuilds(environment, configs);
debugCheckBuilds(builds);

argParser.addOption(
configFlag,
abbr: 'c',
defaultsTo: '',
help:
'Specify the build config to use for the target build (usually auto detected)',
allowed: <String>[
for (final Build build in runnableBuilds(environment, configs))
build.name,
],
allowedHelp: <String, String>{
for (final Build build in runnableBuilds(environment, configs))
build.name: build.gn.join(' '),
},
);
// We default to nothing in order to automatically detect attached devices
// and select an appropriate target from them.
addConfigOption(argParser, runnableBuilds(environment, configs),
defaultsTo: '');
argParser.addFlag(
rbeFlag,
defaultsTo: true,
help: 'RBE is enabled by default when available. Use --no-rbe to '
'disable it.',
'disable it.',
);
}

Expand Down
Loading

0 comments on commit a1e3b83

Please sign in to comment.