21ae9657a9
The with_envs.py works with the test script by providing the required environment variables. This change in theory does nothing since the `product download` is in 12.20230413.0.1, but `run` is removed before that, https://fxrev.dev/831319. So the DEPS cannot really download the images. The issue will be addressed in a coming change. Bug: #38752 Change-Id: Ib5f3d1d619921651208fa442201ba607a99e54d5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319867 Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Alexander Thomas <athom@google.com> Commit-Queue: Zijie He <zijiehe@google.com>
506 lines
16 KiB
Dart
506 lines
16 KiB
Dart
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:io';
|
|
|
|
import 'command.dart';
|
|
import 'compiler_configuration.dart';
|
|
import 'configuration.dart';
|
|
import 'fuchsia.dart';
|
|
import 'repository.dart';
|
|
import 'utils.dart';
|
|
|
|
/// Describes the commands to run a given test case or its compiled output.
|
|
///
|
|
/// A single runtime configuration object exists per test suite, and is thus
|
|
/// shared between multiple test cases, it should not be mutated after
|
|
/// construction.
|
|
abstract class RuntimeConfiguration {
|
|
late TestConfiguration _configuration;
|
|
|
|
static RuntimeConfiguration _makeInstance(TestConfiguration configuration) {
|
|
switch (configuration.runtime) {
|
|
case Runtime.chrome:
|
|
case Runtime.chromeOnAndroid:
|
|
case Runtime.firefox:
|
|
case Runtime.ie11:
|
|
case Runtime.ie10:
|
|
case Runtime.ie9:
|
|
case Runtime.safari:
|
|
// TODO(ahe): Replace this with one or more browser runtimes.
|
|
return DummyRuntimeConfiguration();
|
|
|
|
case Runtime.jsshell:
|
|
return JsshellRuntimeConfiguration(configuration.compiler);
|
|
|
|
case Runtime.d8:
|
|
return D8RuntimeConfiguration(configuration.compiler);
|
|
|
|
case Runtime.none:
|
|
return NoneRuntimeConfiguration();
|
|
|
|
case Runtime.vm:
|
|
if (configuration.system == System.android) {
|
|
return DartkAdbRuntimeConfiguration();
|
|
} else if (configuration.system == System.fuchsia) {
|
|
return DartkFuchsiaEmulatorRuntimeConfiguration();
|
|
}
|
|
return StandaloneDartRuntimeConfiguration();
|
|
|
|
case Runtime.dartPrecompiled:
|
|
if (configuration.system == System.android) {
|
|
return DartPrecompiledAdbRuntimeConfiguration(
|
|
configuration.useElf,
|
|
);
|
|
} else {
|
|
return DartPrecompiledRuntimeConfiguration(
|
|
configuration.useElf,
|
|
);
|
|
}
|
|
}
|
|
throw "unreachable";
|
|
}
|
|
|
|
factory RuntimeConfiguration(TestConfiguration configuration) {
|
|
return _makeInstance(configuration).._configuration = configuration;
|
|
}
|
|
|
|
RuntimeConfiguration._subclass();
|
|
|
|
int timeoutMultiplier(
|
|
{required Mode mode,
|
|
bool isChecked = false,
|
|
bool isReload = false,
|
|
required Architecture arch,
|
|
required System system}) {
|
|
return 1;
|
|
}
|
|
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
// TODO(ahe): Make this method abstract.
|
|
throw "Unimplemented runtime '$runtimeType'";
|
|
}
|
|
|
|
/// The output directory for this suite's configuration.
|
|
String get buildDir => _configuration.buildDirectory;
|
|
|
|
List<String> dart2jsPreambles(Uri preambleDir) => [];
|
|
|
|
/// Returns the path to the Dart VM executable.
|
|
///
|
|
/// Controlled by user with the option "--dart".
|
|
String get dartVmBinaryFileName =>
|
|
_configuration.dartPath ?? dartVmExecutableFileName;
|
|
|
|
String get dartVmExecutableFileName {
|
|
return _configuration.useSdk
|
|
? '$buildDir/dart-sdk/bin/dart$executableExtension'
|
|
: '$buildDir/dart$executableExtension';
|
|
}
|
|
|
|
String get dartPrecompiledBinaryFileName {
|
|
// Controlled by user with the option "--dart-precompiled".
|
|
var dartExecutable = _configuration.dartPrecompiledPath;
|
|
|
|
if (dartExecutable == null || dartExecutable == '') {
|
|
var dir = buildDir;
|
|
|
|
// gen_snapshot can run with different word sizes, but the simulators
|
|
// cannot.
|
|
dir = dir.replaceAll("SIMARM_X64", "SIMARM");
|
|
|
|
dartExecutable = '$dir/dart_precompiled_runtime$executableExtension';
|
|
}
|
|
|
|
TestUtils.ensureExists(dartExecutable, _configuration);
|
|
return dartExecutable;
|
|
}
|
|
|
|
String get processTestBinaryFileName {
|
|
var processTestExecutable = '$buildDir/process_test$executableExtension';
|
|
TestUtils.ensureExists(processTestExecutable, _configuration);
|
|
return processTestExecutable;
|
|
}
|
|
|
|
String get abstractSocketTestBinaryFileName {
|
|
var abstractSocketTestExecutable =
|
|
'$buildDir/abstract_socket_test$executableExtension';
|
|
TestUtils.ensureExists(abstractSocketTestExecutable, _configuration);
|
|
return abstractSocketTestExecutable;
|
|
}
|
|
|
|
String get d8FileName {
|
|
var d8Dir = Repository.dir.append('third_party/d8');
|
|
var d8Path =
|
|
d8Dir.append('${Platform.operatingSystem}/d8$executableExtension');
|
|
var d8 = d8Path.toNativePath();
|
|
TestUtils.ensureExists(d8, _configuration);
|
|
return d8;
|
|
}
|
|
|
|
String get jsShellFileName {
|
|
var executable = 'jsshell$executableExtension';
|
|
var jsshellDir = Repository.uri.resolve("tools/testing/bin").path;
|
|
var jsshell = '$jsshellDir/$executable';
|
|
TestUtils.ensureExists(jsshell, _configuration);
|
|
return jsshell;
|
|
}
|
|
}
|
|
|
|
/// The 'none' runtime configuration.
|
|
class NoneRuntimeConfiguration extends RuntimeConfiguration {
|
|
NoneRuntimeConfiguration() : super._subclass();
|
|
|
|
@override
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
return <Command>[];
|
|
}
|
|
}
|
|
|
|
class CommandLineJavaScriptRuntime extends RuntimeConfiguration {
|
|
final String moniker;
|
|
|
|
CommandLineJavaScriptRuntime(this.moniker) : super._subclass();
|
|
|
|
void checkArtifact(CommandArtifact artifact) {
|
|
var type = artifact.mimeType;
|
|
if (type != 'application/javascript' && type != 'application/wasm') {
|
|
throw "Runtime '$moniker' cannot run files of type '$type'.";
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Chrome/V8-based development shell (d8).
|
|
class D8RuntimeConfiguration extends CommandLineJavaScriptRuntime {
|
|
final Compiler compiler;
|
|
|
|
D8RuntimeConfiguration(this.compiler) : super('d8');
|
|
|
|
@override
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
// TODO(ahe): Avoid duplication of this method between d8 and jsshell.
|
|
checkArtifact(artifact!);
|
|
if (compiler == Compiler.dart2wasm) {
|
|
return [
|
|
Dart2WasmCommandLineCommand(
|
|
moniker, d8FileName, arguments, environmentOverrides)
|
|
];
|
|
} else {
|
|
return [
|
|
JSCommandLineCommand(
|
|
moniker, d8FileName, arguments, environmentOverrides)
|
|
];
|
|
}
|
|
}
|
|
|
|
@override
|
|
List<String> dart2jsPreambles(Uri preambleDir) {
|
|
return [preambleDir.resolve('d8.js').toFilePath()];
|
|
}
|
|
}
|
|
|
|
/// Firefox/SpiderMonkey-based development shell (jsshell).
|
|
class JsshellRuntimeConfiguration extends CommandLineJavaScriptRuntime {
|
|
final Compiler compiler;
|
|
|
|
JsshellRuntimeConfiguration(this.compiler) : super('jsshell');
|
|
|
|
@override
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
checkArtifact(artifact!);
|
|
if (compiler == Compiler.dart2wasm) {
|
|
return [
|
|
Dart2WasmCommandLineCommand(
|
|
moniker, jsShellFileName, arguments, environmentOverrides)
|
|
];
|
|
} else {
|
|
return [
|
|
JSCommandLineCommand(
|
|
moniker, jsShellFileName, arguments, environmentOverrides)
|
|
];
|
|
}
|
|
}
|
|
|
|
@override
|
|
List<String> dart2jsPreambles(Uri preambleDir) {
|
|
return ['-f', preambleDir.resolve('jsshell.js').toFilePath(), '-f'];
|
|
}
|
|
}
|
|
|
|
class QemuConfig {
|
|
static const all = <Architecture, QemuConfig>{
|
|
Architecture.ia32:
|
|
QemuConfig('qemu-i386', ['-L', '/usr/lib/i386-linux-gnu/']),
|
|
Architecture.x64:
|
|
QemuConfig('qemu-x86_64', ['-L', '/usr/lib/x86_64-linux-gnu/']),
|
|
Architecture.x64c:
|
|
QemuConfig('qemu-x86_64', ['-L', '/usr/lib/x86_64-linux-gnu/']),
|
|
Architecture.arm:
|
|
QemuConfig('qemu-arm', ['-L', '/usr/arm-linux-gnueabihf/']),
|
|
Architecture.arm64:
|
|
QemuConfig('qemu-aarch64', ['-L', '/usr/aarch64-linux-gnu/']),
|
|
Architecture.arm64c:
|
|
QemuConfig('qemu-aarch64', ['-L', '/usr/aarch64-linux-gnu/']),
|
|
Architecture.riscv32:
|
|
QemuConfig('qemu-riscv32', ['-L', '/usr/riscv32-linux-gnu/']),
|
|
Architecture.riscv64:
|
|
QemuConfig('qemu-riscv64', ['-L', '/usr/riscv64-linux-gnu/']),
|
|
};
|
|
|
|
final String executable;
|
|
final List<String> arguments;
|
|
|
|
const QemuConfig(this.executable, this.arguments);
|
|
}
|
|
|
|
/// Common runtime configuration for runtimes based on the Dart VM.
|
|
class DartVmRuntimeConfiguration extends RuntimeConfiguration {
|
|
DartVmRuntimeConfiguration() : super._subclass();
|
|
|
|
@override
|
|
int timeoutMultiplier(
|
|
{required Mode mode,
|
|
bool isChecked = false,
|
|
bool isReload = false,
|
|
required Architecture arch,
|
|
required System system}) {
|
|
var multiplier = 1;
|
|
|
|
switch (arch) {
|
|
case Architecture.simarm:
|
|
case Architecture.simarm64:
|
|
case Architecture.simarm64c:
|
|
case Architecture.simriscv32:
|
|
case Architecture.simriscv64:
|
|
multiplier *= 4;
|
|
break;
|
|
}
|
|
|
|
// TODO(dart-engprod): Remove after replacing Cavium with GCE instances.
|
|
if (arch == Architecture.arm64 && system == System.linux) {
|
|
multiplier *= 4;
|
|
}
|
|
|
|
if (_configuration.useQemu) {
|
|
multiplier *= 2;
|
|
}
|
|
|
|
// Configurations where `kernel-service` doesn't run from AppJIT snapshot
|
|
// will make tests run very slow due to the `kernel-service` code slowly
|
|
// warming up the JIT. This is especially noticable in `debug` mode.
|
|
if (arch == Architecture.ia32) {
|
|
multiplier *= 2;
|
|
}
|
|
|
|
if (mode.isDebug) {
|
|
multiplier *= 2;
|
|
}
|
|
if (isReload) {
|
|
multiplier *= 2;
|
|
}
|
|
if (_configuration.sanitizer != Sanitizer.none) {
|
|
multiplier *= 4;
|
|
}
|
|
if (_configuration.rr) {
|
|
multiplier *= 2;
|
|
}
|
|
return multiplier;
|
|
}
|
|
}
|
|
|
|
//// The standalone Dart VM binary, "dart" or "dart.exe".
|
|
class StandaloneDartRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
|
@override
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
var script = artifact?.filename;
|
|
var type = artifact?.mimeType;
|
|
if (script != null &&
|
|
type != 'application/dart' &&
|
|
type != 'application/dart-snapshot' &&
|
|
type != 'application/kernel-ir' &&
|
|
type != 'application/kernel-ir-fully-linked') {
|
|
throw "Dart VM cannot run files of type '$type'.";
|
|
}
|
|
if (isCrashExpected) {
|
|
arguments.insert(0, '--suppress-core-dump');
|
|
}
|
|
var executable = dartVmBinaryFileName;
|
|
if (type == 'application/kernel-ir-fully-linked') {
|
|
executable = dartVmExecutableFileName;
|
|
}
|
|
if (_configuration.useQemu) {
|
|
final config = QemuConfig.all[_configuration.architecture]!;
|
|
arguments.insert(0, executable);
|
|
arguments.insertAll(0, config.arguments);
|
|
executable = config.executable;
|
|
}
|
|
var command = VMCommand(executable, arguments, environmentOverrides);
|
|
if (_configuration.rr && !isCrashExpected) {
|
|
return [RRCommand(command)];
|
|
}
|
|
return [command];
|
|
}
|
|
}
|
|
|
|
class DartPrecompiledRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
|
final bool useElf;
|
|
DartPrecompiledRuntimeConfiguration(this.useElf);
|
|
|
|
@override
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
var script = artifact?.filename;
|
|
var type = artifact?.mimeType;
|
|
if (script != null && type != 'application/dart-precompiled') {
|
|
throw "dart_precompiled cannot run files of type '$type'.";
|
|
}
|
|
|
|
var executable = dartPrecompiledBinaryFileName;
|
|
|
|
if (_configuration.useQemu) {
|
|
final config = QemuConfig.all[_configuration.architecture]!;
|
|
arguments.insert(0, executable);
|
|
arguments.insertAll(0, config.arguments);
|
|
executable = config.executable;
|
|
}
|
|
|
|
var command = VMCommand(executable, arguments, environmentOverrides);
|
|
if (_configuration.rr && !isCrashExpected) {
|
|
return [RRCommand(command)];
|
|
}
|
|
return [command];
|
|
}
|
|
}
|
|
|
|
class DartkAdbRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
|
static const String deviceDir = '/data/local/tmp/testing';
|
|
static const String deviceTestDir = '/data/local/tmp/testing/test';
|
|
|
|
@override
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
var script = artifact?.filename;
|
|
var type = artifact?.mimeType;
|
|
if (script != null && type != 'application/kernel-ir-fully-linked') {
|
|
throw "dart cannot run files of type '$type'.";
|
|
}
|
|
|
|
var buildPath = buildDir;
|
|
var processTest = processTestBinaryFileName;
|
|
var abstractSocketTest = abstractSocketTestBinaryFileName;
|
|
return [
|
|
AdbDartkCommand(buildPath, processTest, abstractSocketTest, script!,
|
|
arguments, extraLibs)
|
|
];
|
|
}
|
|
}
|
|
|
|
class DartPrecompiledAdbRuntimeConfiguration
|
|
extends DartVmRuntimeConfiguration {
|
|
static const deviceDir = '/data/local/tmp/precompilation-testing';
|
|
static const deviceTestDir = '/data/local/tmp/precompilation-testing/test';
|
|
|
|
final bool useElf;
|
|
DartPrecompiledAdbRuntimeConfiguration(this.useElf);
|
|
|
|
@override
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
var script = artifact?.filename;
|
|
var type = artifact?.mimeType;
|
|
if (script != null && type != 'application/dart-precompiled') {
|
|
throw "dart_precompiled cannot run files of type '$type'.";
|
|
}
|
|
|
|
var processTest = processTestBinaryFileName;
|
|
var abstractSocketTest = abstractSocketTestBinaryFileName;
|
|
return [
|
|
AdbPrecompilationCommand(buildDir, processTest, abstractSocketTest,
|
|
script!, arguments, useElf, extraLibs)
|
|
];
|
|
}
|
|
}
|
|
|
|
class DartkFuchsiaEmulatorRuntimeConfiguration
|
|
extends DartVmRuntimeConfiguration {
|
|
@override
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
var script = artifact?.filename;
|
|
var type = artifact?.mimeType;
|
|
if (script != null &&
|
|
type != 'application/dart' &&
|
|
type != 'application/dart-snapshot' &&
|
|
type != 'application/kernel-ir' &&
|
|
type != 'application/kernel-ir-fully-linked') {
|
|
throw "Dart VM cannot run files of type '$type'.";
|
|
}
|
|
if (isCrashExpected) {
|
|
arguments.insert(0, '--suppress-core-dump');
|
|
}
|
|
var runtimeArgs = FuchsiaEmulator.getTestArgs(
|
|
_configuration.mode.name, _configuration.architecture.name, arguments);
|
|
runtimeArgs.insert(runtimeArgs.length - 1, '--disable-dart-dev');
|
|
return [
|
|
VMCommand(FuchsiaEmulator.fsshTool, runtimeArgs, environmentOverrides)
|
|
];
|
|
}
|
|
}
|
|
|
|
/// Temporary runtime configuration for browser runtimes that haven't been
|
|
/// migrated yet.
|
|
// TODO(ahe): Remove this class.
|
|
class DummyRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
|
@override
|
|
List<Command> computeRuntimeCommands(
|
|
CommandArtifact? artifact,
|
|
List<String> arguments,
|
|
Map<String, String> environmentOverrides,
|
|
List<String> extraLibs,
|
|
bool isCrashExpected) {
|
|
throw "Unimplemented runtime '$runtimeType'";
|
|
}
|
|
}
|