[dart2js] Add support for BabelJS to test.py
This adds support for BabelJS to test.py's dart2js compiler configuration. When --babel is specified directly or through a named configuration, test.py will run an additional step after dart2js that post-processes the javascript output by running it through BabelJS with the specified Babel configuration. BabelJS is added to the DEPS in its standalone form. d8 is used to run BabelJS standalone to avoid adding a dependency on NodeJS. d8 can only write to stdout but not to files or stderr, which makes it necessary to change the test_runner to handle commands that expect their output to be piped to a file. Changes: * Add --babel option to test.py. * Add babel option to pkg/smith. * Switch IE11 builder to use babel transformation. * Fix option list comparison bugs in pkg/smith. * Change dart2js compiler configuration to generate files using the test name rather than just "out.js" (update test that relied on this). * Remove runtime_configuration dependency on test_suite. * Remove obsolete blocks adding --preview-dart-2 dart2js arguments. * Make dart2js' compiler configuration more like DDC's. * Remove createCommand method that is no longer used. * Remove support for "OtherResources" which was only used for dart:isolate tests on dart2js and DDC. * Skip co19_2 tests that are slow to transform with babel. * Simplify the timeout handling in the test runner with Future.timeout. Change-Id: I32e4917b2a57ecbe684538e40d744f0101c552a0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/90402 Commit-Queue: Alexander Thomas <athom@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
b1d3a212a7
commit
182d55dfda
@@ -168,7 +168,6 @@ deps = {
|
||||
}],
|
||||
"dep_type": "cipd",
|
||||
},
|
||||
|
||||
Var("dart_root") + "/tests/co19_2/src": {
|
||||
"packages": [{
|
||||
"package": "dart/third_party/co19",
|
||||
@@ -176,11 +175,16 @@ deps = {
|
||||
}],
|
||||
"dep_type": "cipd",
|
||||
},
|
||||
|
||||
Var("dart_root") + "/third_party/markupsafe":
|
||||
Var("chromium_git") + "/chromium/src/third_party/markupsafe.git" +
|
||||
"@" + Var("markupsafe_rev"),
|
||||
|
||||
Var("dart_root") + "/third_party/babel": {
|
||||
"packages": [{
|
||||
"package": "dart/third_party/babel",
|
||||
"version": "version:7.4.5",
|
||||
}],
|
||||
"dep_type": "cipd",
|
||||
},
|
||||
Var("dart_root") + "/third_party/zlib":
|
||||
Var("chromium_git") + "/chromium/src/third_party/zlib.git" +
|
||||
"@" + Var("zlib_rev"),
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'dart:io';
|
||||
// - "windows" -> "win".
|
||||
// - "macos" -> "mac".
|
||||
// - toString() on enum classes is just name.
|
||||
// - builderTag defaults to empty string, not null.
|
||||
// - builderTag and babel default to empty string, not null.
|
||||
// Need to migrate test.dart to not expect the above before it can use this.
|
||||
|
||||
// READ ME! If you add a new field to this, make sure to add it to
|
||||
@@ -247,6 +247,7 @@ class Configuration {
|
||||
|
||||
var configuration = Configuration(
|
||||
name, architecture, compiler, mode, runtime, system,
|
||||
babel: stringOption("babel"),
|
||||
builderTag: stringOption("builder-tag"),
|
||||
vmOptions: stringListOption("vm-options"),
|
||||
dart2jsOptions: stringListOption("dart2js-options"),
|
||||
@@ -285,13 +286,15 @@ class Configuration {
|
||||
|
||||
final System system;
|
||||
|
||||
final String babel;
|
||||
|
||||
final String builderTag;
|
||||
|
||||
final List<String> vmOptions;
|
||||
|
||||
final List<String> dart2jsOptions;
|
||||
|
||||
int timeout;
|
||||
final int timeout;
|
||||
|
||||
final bool enableAsserts;
|
||||
|
||||
@@ -323,7 +326,8 @@ class Configuration {
|
||||
|
||||
Configuration(this.name, this.architecture, this.compiler, this.mode,
|
||||
this.runtime, this.system,
|
||||
{String builderTag,
|
||||
{String babel,
|
||||
String builderTag,
|
||||
List<String> vmOptions,
|
||||
List<String> dart2jsOptions,
|
||||
int timeout,
|
||||
@@ -340,10 +344,11 @@ class Configuration {
|
||||
bool useHotReload,
|
||||
bool useHotReloadRollback,
|
||||
bool useSdk})
|
||||
: builderTag = builderTag ?? "",
|
||||
: babel = babel ?? "",
|
||||
builderTag = builderTag ?? "",
|
||||
vmOptions = vmOptions ?? <String>[],
|
||||
dart2jsOptions = dart2jsOptions ?? <String>[],
|
||||
timeout = timeout,
|
||||
timeout = timeout ?? -1,
|
||||
enableAsserts = enableAsserts ?? false,
|
||||
isChecked = isChecked ?? false,
|
||||
isCsp = isCsp ?? false,
|
||||
@@ -366,6 +371,7 @@ class Configuration {
|
||||
mode == other.mode &&
|
||||
runtime == other.runtime &&
|
||||
system == other.system &&
|
||||
babel == other.babel &&
|
||||
builderTag == other.builderTag &&
|
||||
vmOptions.join(" & ") == other.vmOptions.join(" & ") &&
|
||||
dart2jsOptions.join(" & ") == other.dart2jsOptions.join(" & ") &&
|
||||
@@ -397,6 +403,7 @@ class Configuration {
|
||||
mode.hashCode ^
|
||||
runtime.hashCode ^
|
||||
system.hashCode ^
|
||||
babel.hashCode ^
|
||||
builderTag.hashCode ^
|
||||
vmOptions.join(" & ").hashCode ^
|
||||
dart2jsOptions.join(" & ").hashCode ^
|
||||
@@ -429,11 +436,13 @@ class Configuration {
|
||||
fields.add("runtime: $runtime");
|
||||
fields.add("system: $system");
|
||||
|
||||
if (builderTag != "") fields.add("builder-tag: $builderTag");
|
||||
if (vmOptions != "") fields.add("vm-options: [${vmOptions.join(", ")}]");
|
||||
if (dart2jsOptions != "")
|
||||
if (babel.isNotEmpty) fields.add("babel: $babel");
|
||||
if (builderTag.isNotEmpty) fields.add("builder-tag: $builderTag");
|
||||
if (vmOptions.isNotEmpty)
|
||||
fields.add("vm-options: [${vmOptions.join(", ")}]");
|
||||
if (dart2jsOptions.isNotEmpty)
|
||||
fields.add("dart2js-options: [${dart2jsOptions.join(", ")}]");
|
||||
if (timeout != 0) fields.add("timeout: $timeout");
|
||||
if (timeout > 0) fields.add("timeout: $timeout");
|
||||
if (enableAsserts) fields.add("enable-asserts");
|
||||
if (isChecked) fields.add("checked");
|
||||
if (isCsp) fields.add("csp");
|
||||
@@ -464,20 +473,25 @@ class Configuration {
|
||||
fields.add("runtime: $runtime ${other.runtime}");
|
||||
fields.add("system: $system ${other.system}");
|
||||
|
||||
if (builderTag != "" || other.builderTag != "") {
|
||||
var tag = builderTag == "" ? "(none)" : builderTag;
|
||||
var otherTag = other.builderTag == "" ? "(none)" : other.builderTag;
|
||||
fields.add("builder-tag: $tag $otherTag");
|
||||
if (babel.isNotEmpty || other.babel.isNotEmpty) {
|
||||
var ours = babel == "" ? "(none)" : babel;
|
||||
var theirs = other.babel == "" ? "(none)" : other.babel;
|
||||
fields.add("babel: $ours $theirs");
|
||||
}
|
||||
if (vmOptions != "" || other.vmOptions != "") {
|
||||
var tag = "[${vmOptions.join(", ")}]";
|
||||
var otherTag = "[${other.vmOptions.join(", ")}]";
|
||||
fields.add("vm-options: $tag $otherTag");
|
||||
if (builderTag.isNotEmpty || other.builderTag.isNotEmpty) {
|
||||
var ours = builderTag == "" ? "(none)" : builderTag;
|
||||
var theirs = other.builderTag == "" ? "(none)" : other.builderTag;
|
||||
fields.add("builder-tag: $ours $theirs");
|
||||
}
|
||||
if (dart2jsOptions != "" || other.dart2jsOptions != "") {
|
||||
var tag = "[${dart2jsOptions.join(", ")}]";
|
||||
var otherTag = "[${other.dart2jsOptions.join(", ")}]";
|
||||
fields.add("dart2js-options: $tag $otherTag");
|
||||
if (vmOptions.isNotEmpty || other.vmOptions.isNotEmpty) {
|
||||
var ours = "[${vmOptions.join(", ")}]";
|
||||
var theirs = "[${other.vmOptions.join(", ")}]";
|
||||
fields.add("vm-options: $ours $theirs");
|
||||
}
|
||||
if (dart2jsOptions.isNotEmpty || other.dart2jsOptions.isNotEmpty) {
|
||||
var ours = "[${dart2jsOptions.join(", ")}]";
|
||||
var theirs = "[${other.dart2jsOptions.join(", ")}]";
|
||||
fields.add("dart2js-options: $ours $theirs");
|
||||
}
|
||||
fields.add("timeout: $timeout ${other.timeout}");
|
||||
if (enableAsserts || other.enableAsserts) {
|
||||
|
||||
@@ -10,6 +10,17 @@ LayoutTests/*: SkipByDesign # d8 is not a browser
|
||||
LibTest/html/*: SkipByDesign # d8 is not a browser
|
||||
WebPlatformTest/*: SkipByDesign # d8 is not a browser
|
||||
|
||||
[ $compiler == dart2js && $runtime == ie11 ]
|
||||
LibTest/collection/ListBase/ListBase_class_A01_t04: SkipSlow # slow babeljs transformation
|
||||
LibTest/collection/ListBase/ListBase_class_A01_t05: SkipSlow # slow babeljs transformation
|
||||
LibTest/collection/ListBase/ListBase_class_A01_t06: SkipSlow # slow babeljs transformation
|
||||
LibTest/collection/ListMixin/ListMixin_class_A01_t04: SkipSlow # slow babeljs transformation
|
||||
LibTest/collection/ListMixin/ListMixin_class_A01_t05: SkipSlow # slow babeljs transformation
|
||||
LibTest/collection/ListMixin/ListMixin_class_A01_t06: SkipSlow # slow babeljs transformation
|
||||
LibTest/core/List/List_class_A01_t04: SkipSlow # slow babeljs transformation
|
||||
LibTest/core/List/List_class_A01_t05: SkipSlow # slow babeljs transformation
|
||||
LibTest/core/List/List_class_A01_t06: SkipSlow # slow babeljs transformation
|
||||
|
||||
[ $compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk ]
|
||||
Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign
|
||||
LibTest/io/*: SkipByDesign # dart:io not supported.
|
||||
|
||||
@@ -10,7 +10,7 @@ main() {
|
||||
// This is somewhat brittle and relies on an implementation detail
|
||||
// of our test runner, but I can think of no other way to test this.
|
||||
// -- ahe
|
||||
if (!thisScript.endsWith('/out.js')) {
|
||||
if (!thisScript.endsWith('/compute_this_script_test.js')) {
|
||||
throw 'Unexpected script: "$thisScript"';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
library async_spawnuri_test;
|
||||
|
||||
import 'package:unittest/unittest.dart';
|
||||
import 'package:unittest/html_config.dart';
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:isolate';
|
||||
import 'dart:html';
|
||||
|
||||
// OtherScripts=async_oneshot.dart async_periodictimer.dart async_cancellingisolate.dart
|
||||
main() {
|
||||
useHtmlConfiguration();
|
||||
|
||||
test('one shot timer in pure isolate', () {
|
||||
var response = new ReceivePort();
|
||||
var remote = Isolate.spawnUri(
|
||||
Uri.parse('async_oneshot.dart'), ['START'], response.sendPort);
|
||||
remote.catchError((x) => expect("Error in oneshot isolate", x));
|
||||
expect(remote.then((_) => response.first), completion('DONE'));
|
||||
});
|
||||
|
||||
test('periodic timer in pure isolate', () {
|
||||
var response = new ReceivePort();
|
||||
var remote = Isolate.spawnUri(
|
||||
Uri.parse('async_periodictimer.dart'), ['START'], response.sendPort);
|
||||
remote.catchError((x) => expect("Error in periodic timer isolate", x));
|
||||
expect(remote.then((_) => response.first), completion('DONE'));
|
||||
});
|
||||
|
||||
test('cancellation in pure isolate', () {
|
||||
var response = new ReceivePort();
|
||||
var remote = Isolate.spawnUri(Uri.parse('async_cancellingisolate.dart'),
|
||||
['START'], response.sendPort);
|
||||
remote.catchError((x) => expect("Error in cancelling isolate", x));
|
||||
expect(remote.then((_) => response.first), completion('DONE'));
|
||||
});
|
||||
}
|
||||
@@ -2,11 +2,6 @@
|
||||
// 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.
|
||||
|
||||
// Note: the following comment is used by test.dart to additionally compile the
|
||||
// other isolate's code.
|
||||
// OtherScripts=issue_12474_child.dart
|
||||
// OtherScripts=package/issue_12474_lib.dart
|
||||
|
||||
import 'dart:isolate';
|
||||
|
||||
final SPAWN_PACKAGE_ROOT = Uri.parse(".");
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2015, 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.
|
||||
//
|
||||
// OtherScripts=error_at_spawnuri_iso.dart
|
||||
|
||||
library error_at_spawnuri;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2015, 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.
|
||||
//
|
||||
// OtherScripts=error_exit_at_spawning_shared.dart
|
||||
|
||||
library error_exit_at_spawnuri;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2015, 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.
|
||||
//
|
||||
// OtherScripts=exit_at_spawnuri_iso.dart
|
||||
|
||||
library exit_at_spawn;
|
||||
|
||||
|
||||
@@ -2,13 +2,7 @@
|
||||
// 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.
|
||||
|
||||
// Note: the following comment is used by test.dart to additionally compile the
|
||||
// other isolate's code.
|
||||
// OtherScripts=issue_21398_child_isolate1.dart
|
||||
// OtherScripts=issue_21398_child_isolate11.dart
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'dart:async';
|
||||
import "package:expect/expect.dart";
|
||||
import 'package:async_helper/async_helper.dart';
|
||||
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
// 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.
|
||||
|
||||
// Note: the following comment is used by test.dart to additionally compile the
|
||||
// other isolate's code.
|
||||
// OtherScripts=deferred_loaded_lib.dart
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'dart:async';
|
||||
import "package:expect/expect.dart";
|
||||
import 'package:async_helper/async_helper.dart';
|
||||
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
// 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.
|
||||
|
||||
// Note: the following comment is used by test.dart to additionally compile the
|
||||
// other isolate's code.
|
||||
// OtherScripts=issue_21398_child_isolate.dart
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'dart:async';
|
||||
import "package:expect/expect.dart";
|
||||
import 'package:async_helper/async_helper.dart';
|
||||
|
||||
|
||||
@@ -2,12 +2,6 @@
|
||||
// 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.
|
||||
|
||||
// Note: the following comment is used by test.dart to additionally compile the
|
||||
// other isolate's code.
|
||||
// OtherScripts=issue_24243_child1_isolate.dart
|
||||
// OtherScripts=issue_24243_child2_isolate.dart
|
||||
// OtherScripts=issue_24243_child3_isolate.dart
|
||||
|
||||
import 'dart:collection';
|
||||
import 'dart:isolate';
|
||||
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Negative test to make sure that we are reaching all assertions.
|
||||
// Note: the following comment is used by test.dart to additionally compile the
|
||||
// other isolate's code.
|
||||
// OtherScripts=spawn_uri_child_isolate.dart
|
||||
library spawn_tests;
|
||||
|
||||
import 'dart:isolate';
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Example of nested spawning of isolates from a URI
|
||||
// Note: the following comment is used by test.dart to additionally compile the
|
||||
// other isolate's code.
|
||||
// OtherScripts=spawn_uri_nested_child1_vm_isolate.dart spawn_uri_nested_child2_vm_isolate.dart
|
||||
library NestedSpawnUriLibrary;
|
||||
|
||||
import 'dart:isolate';
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Example of spawning an isolate from a URI
|
||||
// Note: the following comment is used by test.dart to additionally compile the
|
||||
// other isolate's code.
|
||||
// OtherScripts=spawn_uri_child_isolate.dart
|
||||
library spawn_tests;
|
||||
|
||||
import 'dart:isolate';
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Example of spawning an isolate from a URI
|
||||
// Note: the following comment is used by test.dart to additionally compile the
|
||||
// other isolate's code.
|
||||
// OtherScripts=spawn_uri_child_isolate.dart
|
||||
library spawn_tests;
|
||||
|
||||
import 'dart:isolate';
|
||||
|
||||
@@ -10,7 +10,6 @@ collection/list_test: RuntimeError
|
||||
convert/chunked_conversion_utf88_test: Slow
|
||||
convert/utf85_test: Slow
|
||||
developer/timeline_test: Skip # Not supported
|
||||
html/async_spawnuri_test: SkipByDesign
|
||||
html/async_test: SkipByDesign
|
||||
html/custom/document_register_basic_test: Slow
|
||||
html/custom/document_register_type_extensions_test/construction: Slow
|
||||
@@ -82,7 +81,6 @@ typed_data/setRange_3_test: RuntimeError # TODO(dart2js-team): Please triage thi
|
||||
|
||||
[ $compiler == dart2js && $runtime == d8 ]
|
||||
async/dart2js_uncaught_error_test: RuntimeError
|
||||
html/async_spawnuri_test: RuntimeError
|
||||
html/async_test: RuntimeError
|
||||
html/audiobuffersourcenode_test: RuntimeError
|
||||
html/audiocontext_test: RuntimeError
|
||||
@@ -494,7 +492,6 @@ html/mirrors_js_typed_interop_test: SkipByDesign
|
||||
html/postmessage_structured_test: SkipByDesign
|
||||
|
||||
[ $compiler == dart2js && !$csp && $minified ]
|
||||
html/async_spawnuri_test: RuntimeError
|
||||
html/async_test: RuntimeError
|
||||
html/audiobuffersourcenode_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
|
||||
html/audiocontext_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
|
||||
|
||||
@@ -41,7 +41,6 @@ convert/json_utf8_chunk_test: Slow, Pass
|
||||
convert/streamed_conversion_json_utf8_encode_test: Pass, Timeout # Issue 29922
|
||||
convert/streamed_conversion_utf8_decode_test: Slow, Pass, Timeout # Issue 29922
|
||||
convert/utf85_test: Slow, Pass
|
||||
html/async_spawnuri_test: RuntimeError # Issue 29922
|
||||
html/async_test: RuntimeError # Issue 29922
|
||||
html/callback_list_test: Skip # Test requires user interaction to accept permissions.
|
||||
html/custom/attribute_changed_callback_test: Skip # Issue 31577
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
# Uploads a new version of d8 CIPD package
|
||||
set -e
|
||||
set -x
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: update.sh version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
version=$1
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
cleanup() {
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
trap cleanup EXIT HUP INT QUIT TERM PIPE
|
||||
cd "$tmpdir"
|
||||
|
||||
for file in "babel.js" "babel.min.js" "LICENSE"
|
||||
do
|
||||
curl -o $file "https://unpkg.com/@babel/standalone@$version/$file"
|
||||
done
|
||||
|
||||
cipd create \
|
||||
-name dart/third_party/babel \
|
||||
-in . \
|
||||
-install-mode copy \
|
||||
-tag version:$version
|
||||
@@ -43,6 +43,7 @@
|
||||
"tests/standalone/",
|
||||
"tests/standalone_2/",
|
||||
"tests/ffi/",
|
||||
"third_party/babel/babel.min.js",
|
||||
"third_party/d8/",
|
||||
"third_party/observatory_pub_packages/packages/web_components/",
|
||||
"third_party/pkg/",
|
||||
@@ -245,7 +246,12 @@
|
||||
"options": {
|
||||
"use-sdk": true
|
||||
}},
|
||||
"dart2js-win-(ie11|edge)": {
|
||||
"dart2js-win-ie11": {
|
||||
"options": {
|
||||
"use-sdk": true,
|
||||
"babel": "{\"presets\":[\"es2015\"]}"
|
||||
}},
|
||||
"dart2js-win-edge": {
|
||||
"options": {
|
||||
"use-sdk": true
|
||||
}},
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2019, 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.
|
||||
|
||||
|
||||
const babelStandalonePath = arguments[0];
|
||||
load(babelStandalonePath);
|
||||
const inputFilePath = arguments[2];
|
||||
const input = read(inputFilePath);
|
||||
const options = JSON.parse(arguments[1]);
|
||||
const output = Babel.transform(input, options).code;
|
||||
console.log(output);
|
||||
@@ -257,7 +257,8 @@ class ProcessCommand extends Command {
|
||||
}
|
||||
|
||||
class CompilationCommand extends ProcessCommand {
|
||||
final String _outputFile;
|
||||
/// The primary output file that will be created by this command.
|
||||
final String outputFile;
|
||||
|
||||
/// If true, then the compilation is run even if the input files are older
|
||||
/// than the output file.
|
||||
@@ -266,7 +267,7 @@ class CompilationCommand extends ProcessCommand {
|
||||
|
||||
CompilationCommand._(
|
||||
String displayName,
|
||||
this._outputFile,
|
||||
this.outputFile,
|
||||
this._alwaysCompile,
|
||||
this._bootstrapDependencies,
|
||||
String executable,
|
||||
@@ -279,7 +280,7 @@ class CompilationCommand extends ProcessCommand {
|
||||
|
||||
CompilationCommand indexedCopy(int index) => CompilationCommand._(
|
||||
displayName,
|
||||
_outputFile,
|
||||
outputFile,
|
||||
_alwaysCompile,
|
||||
_bootstrapDependencies,
|
||||
executable,
|
||||
@@ -291,7 +292,7 @@ class CompilationCommand extends ProcessCommand {
|
||||
bool get outputIsUpToDate {
|
||||
if (_alwaysCompile) return false;
|
||||
|
||||
var file = new io.File(new Path("$_outputFile.deps").toNativePath());
|
||||
var file = new io.File(new Path("$outputFile.deps").toNativePath());
|
||||
if (!file.existsSync()) return false;
|
||||
|
||||
var lines = file.readAsLinesSync();
|
||||
@@ -305,7 +306,7 @@ class CompilationCommand extends ProcessCommand {
|
||||
|
||||
dependencies.addAll(_bootstrapDependencies);
|
||||
var jsOutputLastModified = TestUtils.lastModifiedCache
|
||||
.getLastModified(new Uri(scheme: 'file', path: _outputFile));
|
||||
.getLastModified(new Uri(scheme: 'file', path: outputFile));
|
||||
if (jsOutputLastModified == null) return false;
|
||||
|
||||
for (var dependency in dependencies) {
|
||||
@@ -321,14 +322,14 @@ class CompilationCommand extends ProcessCommand {
|
||||
|
||||
void _buildHashCode(HashCodeBuilder builder) {
|
||||
super._buildHashCode(builder);
|
||||
builder.addJson(_outputFile);
|
||||
builder.addJson(outputFile);
|
||||
builder.addJson(_alwaysCompile);
|
||||
builder.addJson(_bootstrapDependencies);
|
||||
}
|
||||
|
||||
bool _equal(CompilationCommand other) =>
|
||||
super._equal(other) &&
|
||||
_outputFile == other._outputFile &&
|
||||
outputFile == other.outputFile &&
|
||||
_alwaysCompile == other._alwaysCompile &&
|
||||
deepJsonCompare(_bootstrapDependencies, other._bootstrapDependencies);
|
||||
}
|
||||
@@ -352,7 +353,7 @@ class FastaCompilationCommand extends CompilationCommand {
|
||||
@override
|
||||
FastaCompilationCommand indexedCopy(int index) => FastaCompilationCommand._(
|
||||
_compilerLocation,
|
||||
_outputFile,
|
||||
outputFile,
|
||||
_bootstrapDependencies,
|
||||
executable,
|
||||
arguments,
|
||||
@@ -442,7 +443,7 @@ class VMKernelCompilationCommand extends CompilationCommand {
|
||||
|
||||
VMKernelCompilationCommand indexedCopy(int index) =>
|
||||
VMKernelCompilationCommand._(
|
||||
_outputFile,
|
||||
outputFile,
|
||||
_alwaysCompile,
|
||||
_bootstrapDependencies,
|
||||
executable,
|
||||
|
||||
@@ -118,8 +118,6 @@ abstract class CompilerConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(ahe): It shouldn't be necessary to pass [buildDir] to any of these
|
||||
// functions. It is fixed for a given configuration.
|
||||
String computeCompilerPath() {
|
||||
throw "Unknown compiler for: $runtimeType";
|
||||
}
|
||||
@@ -130,15 +128,6 @@ abstract class CompilerConfiguration {
|
||||
|
||||
List<Uri> bootstrapDependencies() => const <Uri>[];
|
||||
|
||||
/// Creates a [Command] to compile [inputFile] to [outputFile].
|
||||
Command createCommand(String inputFile, String outputFile,
|
||||
List<String> sharedOptions, Map<String, String> environment) {
|
||||
// TODO(rnystrom): See if this method can be unified with
|
||||
// computeCompilationArtifact() and/or computeCompilerArguments() for the
|
||||
// other compilers.
|
||||
throw new UnsupportedError("$this does not support createCommand().");
|
||||
}
|
||||
|
||||
CommandArtifact computeCompilationArtifact(
|
||||
|
||||
/// Each test has its own temporary directory to avoid name collisions.
|
||||
@@ -486,10 +475,26 @@ class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
|
||||
List<String> arguments, Map<String, String> environmentOverrides) {
|
||||
var compilerArguments = arguments.toList()
|
||||
..addAll(_configuration.dart2jsOptions);
|
||||
return new CommandArtifact([
|
||||
computeCompilationCommand(
|
||||
'$tempDir/out.js', compilerArguments, environmentOverrides)
|
||||
], '$tempDir/out.js', 'application/javascript');
|
||||
|
||||
var commands = <Command>[];
|
||||
// TODO(athom): input filename extraction is copied from DDC. Maybe this
|
||||
// should be passed to computeCompilationArtifact, instead?
|
||||
var inputFile = arguments.last;
|
||||
var inputFilename = (new Uri.file(inputFile)).pathSegments.last;
|
||||
var out = "$tempDir/${inputFilename.replaceAll('.dart', '.js')}";
|
||||
var babel = _configuration.babel;
|
||||
var babelOut = out;
|
||||
if (babel != null && babel.isNotEmpty) {
|
||||
out = out.replaceAll('.js', '.raw.js');
|
||||
}
|
||||
commands.add(computeCompilationCommand(
|
||||
out, compilerArguments, environmentOverrides));
|
||||
|
||||
if (babel != null && babel.isNotEmpty) {
|
||||
commands.add(computeBabelCommand(out, babelOut, babel));
|
||||
}
|
||||
|
||||
return new CommandArtifact(commands, babelOut, 'application/javascript');
|
||||
}
|
||||
|
||||
List<String> computeRuntimeArguments(
|
||||
@@ -507,6 +512,22 @@ class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
|
||||
return runtimeConfiguration.dart2jsPreambles(preambleDir)
|
||||
..add(artifact.filename);
|
||||
}
|
||||
|
||||
Command computeBabelCommand(String input, String output, String options) {
|
||||
var uri = Repository.uri;
|
||||
var babelTransform =
|
||||
uri.resolve('tools/testing/dart/babel_transform.js').toFilePath();
|
||||
var babelStandalone =
|
||||
uri.resolve('third_party/babel/babel.min.js').toFilePath();
|
||||
return Command.compilation(
|
||||
'babel',
|
||||
output,
|
||||
[],
|
||||
_configuration.runtimeConfiguration.d8FileName,
|
||||
[babelTransform, "--", babelStandalone, options, input],
|
||||
{},
|
||||
alwaysCompile: true); // TODO(athom): ensure dependency tracking works.
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for `dartdevc` and `dartdevk` (DDC with Kernel)
|
||||
@@ -537,7 +558,7 @@ class DevCompilerConfiguration extends CompilerConfiguration {
|
||||
return result;
|
||||
}
|
||||
|
||||
Command createCommand(String inputFile, String outputFile,
|
||||
Command _createCommand(String inputFile, String outputFile,
|
||||
List<String> sharedOptions, Map<String, String> environment) {
|
||||
/// This can be disabled to test DDC's hybrid mode (automatically converting
|
||||
/// Analyzer summaries to Kernel files).
|
||||
@@ -629,7 +650,7 @@ class DevCompilerConfiguration extends CompilerConfiguration {
|
||||
var outputFile = "$tempDir/${inputFilename.replaceAll('.dart', '.js')}";
|
||||
|
||||
return new CommandArtifact(
|
||||
[createCommand(inputFile, outputFile, sharedOptions, environment)],
|
||||
[_createCommand(inputFile, outputFile, sharedOptions, environment)],
|
||||
outputFile,
|
||||
"application/javascript");
|
||||
}
|
||||
@@ -1206,12 +1227,6 @@ class FastaCompilerConfiguration extends CompilerConfiguration {
|
||||
@override
|
||||
List<Uri> bootstrapDependencies() => [_platformDill];
|
||||
|
||||
@override
|
||||
Command createCommand(String inputFile, String outputFile,
|
||||
List<String> sharedOptions, Map<String, String> environment) {
|
||||
throw new UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
CommandArtifact computeCompilationArtifact(String tempDir,
|
||||
List<String> arguments, Map<String, String> environmentOverrides) {
|
||||
|
||||
@@ -165,6 +165,7 @@ class TestConfiguration {
|
||||
final String outputDirectory;
|
||||
final String packageRoot;
|
||||
final String suiteDirectory;
|
||||
String get babel => configuration.babel;
|
||||
String get builderTag => configuration.builderTag;
|
||||
final List<String> reproducingArguments;
|
||||
|
||||
@@ -211,24 +212,30 @@ class TestConfiguration {
|
||||
/// build/none_vm_release_x64
|
||||
String get buildDirectory => system.outputDirectory + configurationDirectory;
|
||||
|
||||
int _timeout;
|
||||
|
||||
// TODO(whesse): Put non-default timeouts explicitly in configs, not this.
|
||||
/// Calculates a default timeout based on the compiler and runtime used,
|
||||
/// and the mode, architecture, etc.
|
||||
int get timeout {
|
||||
if (configuration.timeout == null) {
|
||||
var isReload = hotReload || hotReloadRollback;
|
||||
if (_timeout == null) {
|
||||
if (configuration.timeout > 0) {
|
||||
_timeout = configuration.timeout;
|
||||
} else {
|
||||
var isReload = hotReload || hotReloadRollback;
|
||||
|
||||
var compilerMulitiplier = compilerConfiguration.timeoutMultiplier;
|
||||
var runtimeMultiplier = runtimeConfiguration.timeoutMultiplier(
|
||||
mode: mode,
|
||||
isChecked: isChecked,
|
||||
isReload: isReload,
|
||||
arch: architecture);
|
||||
var compilerMulitiplier = compilerConfiguration.timeoutMultiplier;
|
||||
var runtimeMultiplier = runtimeConfiguration.timeoutMultiplier(
|
||||
mode: mode,
|
||||
isChecked: isChecked,
|
||||
isReload: isReload,
|
||||
arch: architecture);
|
||||
|
||||
configuration.timeout = 60 * compilerMulitiplier * runtimeMultiplier;
|
||||
_timeout = 60 * compilerMulitiplier * runtimeMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
return configuration.timeout;
|
||||
return _timeout;
|
||||
}
|
||||
|
||||
List<String> get standardOptions {
|
||||
|
||||
@@ -225,7 +225,7 @@ compact, color, line, verbose, silent, status, buildbot, diff''',
|
||||
new _Option.bool(
|
||||
'silent_failures',
|
||||
"Don't complain about failing tests. This is useful when in "
|
||||
"combination with --write-results.",
|
||||
"combination with --write-results.",
|
||||
hide: true),
|
||||
new _Option.bool('report_in_json',
|
||||
'When listing with --list, output result summary in JSON.',
|
||||
@@ -253,12 +253,12 @@ compact, color, line, verbose, silent, status, buildbot, diff''',
|
||||
new _Option.bool(
|
||||
'write_results',
|
||||
'Write results to a "${TestUtils.resultsFileName}" json file '
|
||||
'located at the debug_output_directory.',
|
||||
'located at the debug_output_directory.',
|
||||
hide: true),
|
||||
new _Option.bool(
|
||||
'write_logs',
|
||||
'Include the stdout and stderr of tests that don\'t match expectations '
|
||||
'in the "${TestUtils.logsFileName}" file',
|
||||
'in the "${TestUtils.logsFileName}" file',
|
||||
hide: true),
|
||||
new _Option.bool(
|
||||
'reset_browser_configuration',
|
||||
@@ -302,6 +302,11 @@ options. Used to be able to make sane updates to the status files.''',
|
||||
'dart2js_options', 'Extra options for dart2js compilation step.',
|
||||
hide: true),
|
||||
new _Option('shared_options', 'Extra shared options.', hide: true),
|
||||
new _Option(
|
||||
'babel',
|
||||
'''Transforms dart2js output with Babel. The value must be
|
||||
Babel options JSON.''',
|
||||
hide: true),
|
||||
new _Option(
|
||||
'suite_dir', 'Additional directory to add to the testing matrix.',
|
||||
hide: true),
|
||||
@@ -700,6 +705,7 @@ compiler.''',
|
||||
isMinified: data["minified"] as bool,
|
||||
vmOptions: vmOptions,
|
||||
dart2jsOptions: dart2jsOptions,
|
||||
babel: data['babel'] as String,
|
||||
builderTag: data["builder_tag"] as String,
|
||||
previewDart2: true);
|
||||
var configuration = new TestConfiguration(
|
||||
|
||||
@@ -8,9 +8,7 @@ import 'command.dart';
|
||||
import 'compiler_configuration.dart';
|
||||
import 'configuration.dart';
|
||||
import 'repository.dart';
|
||||
// TODO(ahe): Remove this import, we can precompute all the values required
|
||||
// from TestSuite once the refactoring is complete.
|
||||
import 'test_suite.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
/// Describes the commands to run a given test case or its compiled output.
|
||||
///
|
||||
@@ -82,7 +80,6 @@ abstract class RuntimeConfiguration {
|
||||
}
|
||||
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
@@ -92,9 +89,74 @@ abstract class RuntimeConfiguration {
|
||||
throw "Unimplemented runtime '$runtimeType'";
|
||||
}
|
||||
|
||||
/**
|
||||
* The output directory for this suite's configuration.
|
||||
*/
|
||||
String get buildDir => _configuration.buildDirectory;
|
||||
|
||||
List<String> dart2jsPreambles(Uri preambleDir) => [];
|
||||
|
||||
bool get shouldSkipNegativeTests => false;
|
||||
|
||||
/// Returns the path to the Dart VM executable.
|
||||
String get dartVmBinaryFileName {
|
||||
// Controlled by user with the option "--dart".
|
||||
var dartExecutable = _configuration.dartPath;
|
||||
|
||||
if (dartExecutable == null) {
|
||||
dartExecutable = dartVmExecutableFileName;
|
||||
}
|
||||
|
||||
TestUtils.ensureExists(dartExecutable, _configuration);
|
||||
return dartExecutable;
|
||||
}
|
||||
|
||||
String get dartVmExecutableFileName {
|
||||
return _configuration.useSdk
|
||||
? '$buildDir/dart-sdk/bin/dart$executableBinarySuffix'
|
||||
: '$buildDir/dart$executableBinarySuffix';
|
||||
}
|
||||
|
||||
String get dartPrecompiledBinaryFileName {
|
||||
// Controlled by user with the option "--dart_precompiled".
|
||||
var dartExecutable = _configuration.dartPrecompiledPath;
|
||||
|
||||
if (dartExecutable == null || dartExecutable == '') {
|
||||
var suffix = executableBinarySuffix;
|
||||
dartExecutable = '$buildDir/dart_precompiled_runtime$suffix';
|
||||
}
|
||||
|
||||
TestUtils.ensureExists(dartExecutable, _configuration);
|
||||
return dartExecutable;
|
||||
}
|
||||
|
||||
String get processTestBinaryFileName {
|
||||
var suffix = executableBinarySuffix;
|
||||
var processTestExecutable = '$buildDir/process_test$suffix';
|
||||
TestUtils.ensureExists(processTestExecutable, _configuration);
|
||||
return processTestExecutable;
|
||||
}
|
||||
|
||||
String get d8FileName {
|
||||
var suffix = executableBinarySuffix;
|
||||
var d8Dir = Repository.dir.append('third_party/d8');
|
||||
var d8Path = d8Dir.append('${Platform.operatingSystem}/d8$suffix');
|
||||
var d8 = d8Path.toNativePath();
|
||||
TestUtils.ensureExists(d8, _configuration);
|
||||
return d8;
|
||||
}
|
||||
|
||||
String get jsShellFileName {
|
||||
var executableSuffix = executableBinarySuffix;
|
||||
var executable = 'jsshell$executableSuffix';
|
||||
var jsshellDir = Repository.uri.resolve("tools/testing/bin").path;
|
||||
var jsshell = '$jsshellDir/$executable';
|
||||
TestUtils.ensureExists(jsshell, _configuration);
|
||||
return jsshell;
|
||||
}
|
||||
|
||||
String get executableBinarySuffix => Platform.isWindows ? '.exe' : '';
|
||||
String get executableScriptSuffix => Platform.isWindows ? '.bat' : '';
|
||||
}
|
||||
|
||||
/// The 'none' runtime configuration.
|
||||
@@ -102,7 +164,6 @@ class NoneRuntimeConfiguration extends RuntimeConfiguration {
|
||||
NoneRuntimeConfiguration() : super._subclass();
|
||||
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
@@ -130,7 +191,6 @@ class D8RuntimeConfiguration extends CommandLineJavaScriptRuntime {
|
||||
D8RuntimeConfiguration() : super('d8');
|
||||
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
@@ -140,7 +200,7 @@ class D8RuntimeConfiguration extends CommandLineJavaScriptRuntime {
|
||||
checkArtifact(artifact);
|
||||
return [
|
||||
Command.jsCommandLine(
|
||||
moniker, suite.d8FileName, arguments, environmentOverrides)
|
||||
moniker, d8FileName, arguments, environmentOverrides)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -154,7 +214,6 @@ class JsshellRuntimeConfiguration extends CommandLineJavaScriptRuntime {
|
||||
JsshellRuntimeConfiguration() : super('jsshell');
|
||||
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
@@ -163,7 +222,7 @@ class JsshellRuntimeConfiguration extends CommandLineJavaScriptRuntime {
|
||||
checkArtifact(artifact);
|
||||
return [
|
||||
Command.jsCommandLine(
|
||||
moniker, suite.jsShellFileName, arguments, environmentOverrides)
|
||||
moniker, jsShellFileName, arguments, environmentOverrides)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -214,7 +273,6 @@ class DartVmRuntimeConfiguration extends RuntimeConfiguration {
|
||||
//// The standalone Dart VM binary, "dart" or "dart.exe".
|
||||
class StandaloneDartRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
@@ -232,9 +290,9 @@ class StandaloneDartRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||
if (isCrashExpected) {
|
||||
arguments.insert(0, '--suppress-core-dump');
|
||||
}
|
||||
String executable = suite.dartVmBinaryFileName;
|
||||
String executable = dartVmBinaryFileName;
|
||||
if (type == 'application/kernel-ir-fully-linked') {
|
||||
executable = suite.dartVmExecutableFileName;
|
||||
executable = dartVmExecutableFileName;
|
||||
}
|
||||
return [Command.vm(executable, arguments, environmentOverrides)];
|
||||
}
|
||||
@@ -248,7 +306,6 @@ class DartPrecompiledRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||
useElf = useElf;
|
||||
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
@@ -261,8 +318,7 @@ class DartPrecompiledRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||
}
|
||||
|
||||
return [
|
||||
Command.vm(
|
||||
suite.dartPrecompiledBinaryFileName, arguments, environmentOverrides)
|
||||
Command.vm(dartPrecompiledBinaryFileName, arguments, environmentOverrides)
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -272,7 +328,6 @@ class DartkAdbRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||
static const String DeviceTestDir = '/data/local/tmp/testing/test';
|
||||
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
@@ -284,8 +339,8 @@ class DartkAdbRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||
throw "dart cannot run files of type '$type'.";
|
||||
}
|
||||
|
||||
final String buildPath = suite.buildDir;
|
||||
final String processTest = suite.processTestBinaryFileName;
|
||||
final String buildPath = buildDir;
|
||||
final String processTest = processTestBinaryFileName;
|
||||
return [
|
||||
Command.adbDartk(buildPath, processTest, script, arguments, extraLibs)
|
||||
];
|
||||
@@ -305,7 +360,6 @@ class DartPrecompiledAdbRuntimeConfiguration
|
||||
useElf = useElf;
|
||||
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
@@ -317,8 +371,8 @@ class DartPrecompiledAdbRuntimeConfiguration
|
||||
throw "dart_precompiled cannot run files of type '$type'.";
|
||||
}
|
||||
|
||||
String precompiledRunner = suite.dartPrecompiledBinaryFileName;
|
||||
String processTest = suite.processTestBinaryFileName;
|
||||
String precompiledRunner = dartPrecompiledBinaryFileName;
|
||||
String processTest = processTestBinaryFileName;
|
||||
return [
|
||||
Command.adbPrecompiled(
|
||||
precompiledRunner, processTest, script, arguments, useBlobs, useElf)
|
||||
@@ -343,17 +397,16 @@ class SelfCheckRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||
}
|
||||
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
List<String> extraLibs,
|
||||
bool isCrashExpected) {
|
||||
String executable = suite.dartVmBinaryFileName;
|
||||
String executable = dartVmBinaryFileName;
|
||||
return selfCheckers
|
||||
.map((String tester) => Command.vmBatch(
|
||||
executable, tester, arguments, environmentOverrides,
|
||||
checked: suite.configuration.isChecked))
|
||||
checked: _configuration.isChecked))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -366,7 +419,6 @@ class SelfCheckRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||
// TODO(ahe): Remove this class.
|
||||
class DummyRuntimeConfiguration extends DartVmRuntimeConfiguration {
|
||||
List<Command> computeRuntimeCommands(
|
||||
TestSuite suite,
|
||||
CommandArtifact artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
|
||||
@@ -244,7 +244,7 @@ class TestCase extends UniqueObject {
|
||||
* it is longer than MAX_HEAD characters, and just keeps the head and
|
||||
* the last TAIL_LENGTH characters of the output.
|
||||
*/
|
||||
class OutputLog {
|
||||
class OutputLog implements StreamConsumer<List<int>> {
|
||||
static const int MAX_HEAD = 500 * 1024;
|
||||
static const int TAIL_LENGTH = 10 * 1024;
|
||||
List<int> head = <int>[];
|
||||
@@ -252,6 +252,7 @@ class OutputLog {
|
||||
List<int> complete;
|
||||
bool dataDropped = false;
|
||||
bool hasNonUtf8 = false;
|
||||
StreamSubscription _subscription;
|
||||
|
||||
OutputLog();
|
||||
|
||||
@@ -325,6 +326,53 @@ be increased, please contact dart-engprod or file an issue.
|
||||
}
|
||||
return complete;
|
||||
}
|
||||
|
||||
@override
|
||||
Future addStream(Stream<List<int>> stream) {
|
||||
_subscription = stream.listen(this.add);
|
||||
return _subscription.asFuture();
|
||||
}
|
||||
|
||||
@override
|
||||
Future close() {
|
||||
toList();
|
||||
return _subscription?.cancel();
|
||||
}
|
||||
|
||||
Future cancel() {
|
||||
return _subscription?.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
// An [OutputLog] that tees the output to a file as well.
|
||||
class FileOutputLog extends OutputLog {
|
||||
io.File _outputFile;
|
||||
io.IOSink _sink;
|
||||
|
||||
FileOutputLog(this._outputFile);
|
||||
|
||||
@override
|
||||
void add(List<int> data) {
|
||||
super.add(data);
|
||||
_sink ??= _outputFile.openWrite();
|
||||
_sink.add(data);
|
||||
}
|
||||
|
||||
@override
|
||||
Future close() {
|
||||
return Future.wait([
|
||||
super.close(),
|
||||
if (_sink != null) _sink.flush().whenComplete(_sink.close)
|
||||
]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future cancel() {
|
||||
return Future.wait([
|
||||
super.cancel(),
|
||||
if (_sink != null) _sink.flush().whenComplete(_sink.close)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to get a list of all child pids for a parent process.
|
||||
@@ -381,16 +429,19 @@ class RunningProcess {
|
||||
int timeout;
|
||||
bool timedOut = false;
|
||||
DateTime startTime;
|
||||
Timer timeoutTimer;
|
||||
int pid;
|
||||
OutputLog stdout = new OutputLog();
|
||||
OutputLog stderr = new OutputLog();
|
||||
OutputLog stdout;
|
||||
OutputLog stderr = OutputLog();
|
||||
StreamConsumer stdoutConsumer;
|
||||
List<String> diagnostics = <String>[];
|
||||
bool compilationSkipped = false;
|
||||
Completer<CommandOutput> completer;
|
||||
TestConfiguration configuration;
|
||||
|
||||
RunningProcess(this.command, this.timeout, {this.configuration});
|
||||
RunningProcess(this.command, this.timeout,
|
||||
{this.configuration, io.File outputFile}) {
|
||||
stdout = outputFile != null ? FileOutputLog(outputFile) : OutputLog();
|
||||
}
|
||||
|
||||
Future<CommandOutput> run() {
|
||||
completer = new Completer<CommandOutput>();
|
||||
@@ -410,44 +461,10 @@ class RunningProcess {
|
||||
environment: processEnvironment,
|
||||
workingDirectory: command.workingDirectory);
|
||||
processFuture.then((io.Process process) {
|
||||
StreamSubscription stdoutSubscription =
|
||||
_drainStream(process.stdout, stdout);
|
||||
StreamSubscription stderrSubscription =
|
||||
_drainStream(process.stderr, stderr);
|
||||
|
||||
var stdoutCompleter = new Completer<Null>();
|
||||
var stderrCompleter = new Completer<Null>();
|
||||
|
||||
bool stdoutDone = false;
|
||||
bool stderrDone = false;
|
||||
var stdoutFuture = process.stdout.pipe(stdout);
|
||||
var stderrFuture = process.stderr.pipe(stderr);
|
||||
pid = process.pid;
|
||||
|
||||
// This timer is used to close stdio to the subprocess once we got
|
||||
// the exitCode. Sometimes descendants of the subprocess keep stdio
|
||||
// handles alive even though the direct subprocess is dead.
|
||||
Timer watchdogTimer;
|
||||
|
||||
closeStdout([_]) {
|
||||
if (!stdoutDone) {
|
||||
stdoutCompleter.complete();
|
||||
stdoutDone = true;
|
||||
if (stderrDone && watchdogTimer != null) {
|
||||
watchdogTimer.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closeStderr([_]) {
|
||||
if (!stderrDone) {
|
||||
stderrCompleter.complete();
|
||||
stderrDone = true;
|
||||
|
||||
if (stdoutDone && watchdogTimer != null) {
|
||||
watchdogTimer.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close stdin so that tests that try to block on input will fail.
|
||||
process.stdin.close();
|
||||
timeoutHandler() async {
|
||||
@@ -507,30 +524,31 @@ class RunningProcess {
|
||||
}
|
||||
}
|
||||
|
||||
stdoutSubscription.asFuture().then(closeStdout);
|
||||
stderrSubscription.asFuture().then(closeStderr);
|
||||
|
||||
process.exitCode.then((exitCode) {
|
||||
if (!stdoutDone || !stderrDone) {
|
||||
watchdogTimer = new Timer(MAX_STDIO_DELAY, () {
|
||||
DebugLogger.warning(
|
||||
"$MAX_STDIO_DELAY_PASSED_MESSAGE (command: $command)");
|
||||
watchdogTimer = null;
|
||||
stdoutSubscription.cancel();
|
||||
stderrSubscription.cancel();
|
||||
closeStdout();
|
||||
closeStderr();
|
||||
});
|
||||
}
|
||||
|
||||
Future.wait([stdoutCompleter.future, stderrCompleter.future])
|
||||
.then((_) {
|
||||
// Wait for the process to finish or timeout
|
||||
process.exitCode
|
||||
.timeout(Duration(seconds: timeout), onTimeout: timeoutHandler)
|
||||
.then((exitCode) {
|
||||
// This timeout is used to close stdio to the subprocess once we got
|
||||
// the exitCode. Sometimes descendants of the subprocess keep stdio
|
||||
// handles alive even though the direct subprocess is dead.
|
||||
Future.wait([stdoutFuture, stderrFuture]).timeout(MAX_STDIO_DELAY,
|
||||
onTimeout: () async {
|
||||
DebugLogger.warning(
|
||||
"$MAX_STDIO_DELAY_PASSED_MESSAGE (command: $command)");
|
||||
await stdout.cancel();
|
||||
await stderr.cancel();
|
||||
_commandComplete(exitCode);
|
||||
return null;
|
||||
}).then((_) {
|
||||
if (stdout is FileOutputLog) {
|
||||
// Prevent logging data that has already been written to a file
|
||||
// and is unlikely too add value in the logs because the command
|
||||
// succeeded.
|
||||
stdout.complete = <int>[];
|
||||
}
|
||||
_commandComplete(exitCode);
|
||||
});
|
||||
});
|
||||
|
||||
timeoutTimer =
|
||||
new Timer(new Duration(seconds: timeout), timeoutHandler);
|
||||
}).catchError((e) {
|
||||
// TODO(floitsch): should we try to report the stacktrace?
|
||||
print("Process error:");
|
||||
@@ -543,9 +561,6 @@ class RunningProcess {
|
||||
}
|
||||
|
||||
void _commandComplete(int exitCode) {
|
||||
if (timeoutTimer != null) {
|
||||
timeoutTimer.cancel();
|
||||
}
|
||||
var commandOutput = _createCommandOutput(command, exitCode);
|
||||
completer.complete(commandOutput);
|
||||
}
|
||||
@@ -573,11 +588,6 @@ class RunningProcess {
|
||||
return commandOutput;
|
||||
}
|
||||
|
||||
StreamSubscription _drainStream(
|
||||
Stream<List<int>> source, OutputLog destination) {
|
||||
return source.listen(destination.add);
|
||||
}
|
||||
|
||||
Map<String, String> _createProcessEnvironment() {
|
||||
var environment = new Map<String, String>.from(io.Platform.environment);
|
||||
|
||||
@@ -1209,7 +1219,8 @@ class CommandExecutorImpl implements CommandExecutor {
|
||||
return _getBatchRunner(name)
|
||||
.runCommand(name, command, timeout, command.arguments);
|
||||
} else if (command is CompilationCommand &&
|
||||
globalConfiguration.batchDart2JS) {
|
||||
globalConfiguration.batchDart2JS &&
|
||||
command.displayName == 'dart2js') {
|
||||
return _getBatchRunner("dart2js")
|
||||
.runCommand("dart2js", command, timeout, command.arguments);
|
||||
} else if (command is AnalysisCommand && globalConfiguration.batch) {
|
||||
@@ -1243,6 +1254,12 @@ class CommandExecutorImpl implements CommandExecutor {
|
||||
var name = command.displayName;
|
||||
return _getBatchRunner(command.displayName + command.dartFile)
|
||||
.runCommand(name, command, timeout, command.arguments);
|
||||
} else if (command is CompilationCommand &&
|
||||
command.displayName == 'babel') {
|
||||
return new RunningProcess(command, timeout,
|
||||
configuration: globalConfiguration,
|
||||
outputFile: io.File(command.outputFile))
|
||||
.run();
|
||||
} else if (command is ProcessCommand) {
|
||||
return new RunningProcess(command, timeout,
|
||||
configuration: globalConfiguration)
|
||||
|
||||
@@ -140,12 +140,6 @@ abstract class TestSuite {
|
||||
|
||||
Map<String, String> get environmentOverrides => _environmentOverrides;
|
||||
|
||||
/**
|
||||
* Whether or not binaries should be found in the root build directory or
|
||||
* in the built SDK.
|
||||
*/
|
||||
bool get useSdk => configuration.useSdk;
|
||||
|
||||
/**
|
||||
* The output directory for this suite's configuration.
|
||||
*/
|
||||
@@ -165,80 +159,6 @@ abstract class TestSuite {
|
||||
return name;
|
||||
}
|
||||
|
||||
/// Returns the name of the Dart VM executable.
|
||||
String get dartVmBinaryFileName {
|
||||
// Controlled by user with the option "--dart".
|
||||
var dartExecutable = configuration.dartPath;
|
||||
|
||||
if (dartExecutable == null) {
|
||||
dartExecutable = dartVmExecutableFileName;
|
||||
}
|
||||
|
||||
TestUtils.ensureExists(dartExecutable, configuration);
|
||||
return dartExecutable;
|
||||
}
|
||||
|
||||
String get dartVmExecutableFileName {
|
||||
return useSdk
|
||||
? '$buildDir/dart-sdk/bin/dart$executableBinarySuffix'
|
||||
: '$buildDir/dart$executableBinarySuffix';
|
||||
}
|
||||
|
||||
String get dartPrecompiledBinaryFileName {
|
||||
// Controlled by user with the option "--dart_precompiled".
|
||||
var dartExecutable = configuration.dartPrecompiledPath;
|
||||
|
||||
if (dartExecutable == null || dartExecutable == '') {
|
||||
var suffix = executableBinarySuffix;
|
||||
dartExecutable = '$buildDir/dart_precompiled_runtime$suffix';
|
||||
}
|
||||
|
||||
TestUtils.ensureExists(dartExecutable, configuration);
|
||||
return dartExecutable;
|
||||
}
|
||||
|
||||
String get processTestBinaryFileName {
|
||||
var suffix = executableBinarySuffix;
|
||||
var processTestExecutable = '$buildDir/process_test$suffix';
|
||||
TestUtils.ensureExists(processTestExecutable, configuration);
|
||||
return processTestExecutable;
|
||||
}
|
||||
|
||||
String get d8FileName {
|
||||
var suffix = getExecutableSuffix('d8');
|
||||
var d8Dir = Repository.dir.append('third_party/d8');
|
||||
var d8Path = d8Dir.append('${Platform.operatingSystem}/d8$suffix');
|
||||
var d8 = d8Path.toNativePath();
|
||||
TestUtils.ensureExists(d8, configuration);
|
||||
return d8;
|
||||
}
|
||||
|
||||
String get jsShellFileName {
|
||||
var executableSuffix = getExecutableSuffix('jsshell');
|
||||
var executable = 'jsshell$executableSuffix';
|
||||
var jsshellDir = '${Repository.dir.toNativePath()}/tools/testing/bin';
|
||||
return '$jsshellDir/$executable';
|
||||
}
|
||||
|
||||
/**
|
||||
* The file extension (if any) that should be added to the given executable
|
||||
* name for the current platform.
|
||||
*/
|
||||
// TODO(ahe): Get rid of this. Use executableBinarySuffix instead.
|
||||
String getExecutableSuffix(String executable) {
|
||||
if (Platform.operatingSystem == 'windows') {
|
||||
if (executable == 'd8' || executable == 'vm' || executable == 'none') {
|
||||
return '.exe';
|
||||
} else {
|
||||
return '.bat';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
String get executableBinarySuffix => Platform.isWindows ? '.exe' : '';
|
||||
String get executableScriptSuffix => Platform.isWindows ? '.bat' : '';
|
||||
|
||||
/**
|
||||
* Call the callback function onTest with a [TestCase] argument for each
|
||||
* test in the suite. When all tests have been processed, call [onDone].
|
||||
@@ -585,7 +505,7 @@ class StandardTestSuite extends TestSuite {
|
||||
extraVmOptions = configuration.vmOptions,
|
||||
super(configuration, suiteName, statusFilePaths) {
|
||||
// Initialize _dart2JsBootstrapDependencies
|
||||
if (!useSdk) {
|
||||
if (!configuration.useSdk) {
|
||||
_dart2JsBootstrapDependencies = [];
|
||||
} else {
|
||||
_dart2JsBootstrapDependencies = [
|
||||
@@ -933,7 +853,6 @@ class StandardTestSuite extends TestSuite {
|
||||
|
||||
return commands
|
||||
..addAll(configuration.runtimeConfiguration.computeRuntimeCommands(
|
||||
this,
|
||||
compilationArtifact,
|
||||
runtimeArguments,
|
||||
environment,
|
||||
@@ -1028,30 +947,28 @@ class StandardTestSuite extends TestSuite {
|
||||
var fileName = info.filePath.toNativePath();
|
||||
var optionsFromFile = info.optionsFromFile;
|
||||
var compilationTempDir = createCompilationOutputDirectory(info.filePath);
|
||||
var jsWrapperFileName = '$compilationTempDir/test.js';
|
||||
var nameNoExt = info.filePath.filenameWithoutExtension;
|
||||
var outputDir = compilationTempDir;
|
||||
var commonArguments =
|
||||
commonArgumentsFromFile(info.filePath, optionsFromFile);
|
||||
|
||||
// Use existing HTML document if available.
|
||||
String content;
|
||||
var customHtml = new File(
|
||||
info.filePath.directoryPath.append('$nameNoExt.html').toNativePath());
|
||||
if (customHtml.existsSync()) {
|
||||
jsWrapperFileName = '$tempDir/$nameNoExt.js';
|
||||
outputDir = tempDir;
|
||||
content = customHtml.readAsStringSync().replaceAll(
|
||||
'%TEST_SCRIPTS%', '<script src="$nameNoExt.js"></script>');
|
||||
} else {
|
||||
// Synthesize an HTML file for the test.
|
||||
if (configuration.compiler == Compiler.dart2js) {
|
||||
var scriptPath = _createUrlPathFromFile(new Path(jsWrapperFileName));
|
||||
var scriptPath = _createUrlPathFromFile(
|
||||
new Path('$compilationTempDir/$nameNoExt.js'));
|
||||
content = dart2jsHtml(fileName, scriptPath);
|
||||
} else {
|
||||
var jsDir =
|
||||
new Path(compilationTempDir).relativeTo(Repository.dir).toString();
|
||||
jsWrapperFileName =
|
||||
new Path('$compilationTempDir/$nameNoExt.js').toNativePath();
|
||||
// Always run with synchronous starts of `async` functions.
|
||||
// If we want to make this dependent on other parameters or flags,
|
||||
// this flag could be become conditional.
|
||||
content = dartdevcHtml(nameNoExt, jsDir, configuration.compiler);
|
||||
}
|
||||
}
|
||||
@@ -1062,36 +979,21 @@ class StandardTestSuite extends TestSuite {
|
||||
// Construct the command(s) that compile all the inputs needed by the
|
||||
// browser test.
|
||||
var commands = <Command>[];
|
||||
const supportedCompilers = {
|
||||
Compiler.dart2js,
|
||||
Compiler.dartdevc,
|
||||
Compiler.dartdevk
|
||||
};
|
||||
assert(supportedCompilers.contains(configuration.compiler));
|
||||
var sharedOptions = optionsFromFile["sharedOptions"] as List<String>;
|
||||
var dart2jsOptions = optionsFromFile["dart2jsOptions"] as List<String>;
|
||||
var ddcOptions = optionsFromFile["ddcOptions"] as List<String>;
|
||||
|
||||
void addCompileCommand(String fileName, String toPath) {
|
||||
switch (configuration.compiler) {
|
||||
case Compiler.dart2js:
|
||||
commands.add(_dart2jsCompileCommand(
|
||||
fileName, toPath, tempDir, optionsFromFile));
|
||||
break;
|
||||
|
||||
case Compiler.dartdevc:
|
||||
case Compiler.dartdevk:
|
||||
var ddcOptions = optionsFromFile["sharedOptions"] as List<String>;
|
||||
ddcOptions.addAll(optionsFromFile["ddcOptions"] as List<String>);
|
||||
commands.add(configuration.compilerConfiguration.createCommand(
|
||||
fileName, toPath, ddcOptions, environmentOverrides));
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
addCompileCommand(fileName, jsWrapperFileName);
|
||||
|
||||
// Some tests require compiling multiple input scripts.
|
||||
for (var name in optionsFromFile['otherScripts'] as List<String>) {
|
||||
var namePath = new Path(name);
|
||||
var fromPath = info.filePath.directoryPath.join(namePath).toNativePath();
|
||||
var toPath = new Path('$tempDir/${namePath.filename}.js').toNativePath();
|
||||
addCompileCommand(fromPath, toPath);
|
||||
}
|
||||
var args = configuration.compilerConfiguration.computeCompilerArguments(
|
||||
null, sharedOptions, null, dart2jsOptions, ddcOptions, commonArguments);
|
||||
var compilation = configuration.compilerConfiguration
|
||||
.computeCompilationArtifact(outputDir, args, environmentOverrides);
|
||||
commands.addAll(compilation.commands);
|
||||
|
||||
if (info.optionsFromFile['isMultiHtmlTest'] as bool) {
|
||||
// Variables for browser multi-tests.
|
||||
@@ -1128,43 +1030,6 @@ class StandardTestSuite extends TestSuite {
|
||||
enqueueNewTestCase(fullName, commands, expectations, info);
|
||||
}
|
||||
|
||||
/// Creates a [Command] to compile a single .dart file using dart2js.
|
||||
Command _dart2jsCompileCommand(String inputFile, String outputFile,
|
||||
String dir, Map<String, dynamic> optionsFromFile) {
|
||||
var args = <String>[];
|
||||
|
||||
if (compilerPath.endsWith('.dart')) {
|
||||
// Run the compiler script via the Dart VM.
|
||||
args.add(compilerPath);
|
||||
}
|
||||
|
||||
args.addAll(configuration.standardOptions);
|
||||
args.addAll(configuration.dart2jsOptions);
|
||||
|
||||
var packages = packagesArgument(optionsFromFile['packageRoot'] as String,
|
||||
optionsFromFile['packages'] as String);
|
||||
if (packages != null) args.add(packages);
|
||||
|
||||
args.add('--out=$outputFile');
|
||||
args.add(inputFile);
|
||||
|
||||
var options = optionsFromFile['sharedOptions'] as List<String>;
|
||||
if (options != null) args.addAll(options);
|
||||
options = optionsFromFile['dart2jsOptions'] as List<String>;
|
||||
if (options != null) args.addAll(options);
|
||||
if (configuration.compiler == Compiler.dart2js) {
|
||||
if (configuration.noPreviewDart2) {
|
||||
args.add("--no-preview-dart-2");
|
||||
} else {
|
||||
args.add("--preview-dart-2");
|
||||
}
|
||||
}
|
||||
|
||||
return Command.compilation(Compiler.dart2js.name, outputFile,
|
||||
dart2JsBootstrapDependencies, compilerPath, args, environmentOverrides,
|
||||
alwaysCompile: !useSdk);
|
||||
}
|
||||
|
||||
List<String> commonArgumentsFromFile(
|
||||
Path filePath, Map<String, dynamic> optionsFromFile) {
|
||||
var args = configuration.standardOptions.toList();
|
||||
@@ -1185,14 +1050,6 @@ class StandardTestSuite extends TestSuite {
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration.compiler == Compiler.dart2js) {
|
||||
if (configuration.noPreviewDart2) {
|
||||
args.add("--no-preview-dart-2");
|
||||
} else {
|
||||
args.add("--preview-dart-2");
|
||||
}
|
||||
}
|
||||
|
||||
args.add(filePath.toNativePath());
|
||||
|
||||
return args;
|
||||
@@ -1241,12 +1098,6 @@ class StandardTestSuite extends TestSuite {
|
||||
* // Environment=ENV_VAR1=foo bar
|
||||
* // Environment=ENV_VAR2=bazz
|
||||
*
|
||||
* - For tests that depend on compiling other files with dart2js (e.g.
|
||||
* isolate tests that use multiple source scripts), you can specify
|
||||
* additional files to compile using a comment too, as follows:
|
||||
*
|
||||
* // OtherScripts=file1.dart file2.dart
|
||||
*
|
||||
* - Most tests are not web tests, but can (and will be) wrapped within
|
||||
* an HTML file and another script file to test them also on browser
|
||||
* environments (e.g. language and corelib tests are run this way).
|
||||
@@ -1272,7 +1123,6 @@ class StandardTestSuite extends TestSuite {
|
||||
}
|
||||
RegExp testOptionsRegExp = new RegExp(r"// VMOptions=(.*)");
|
||||
RegExp environmentRegExp = new RegExp(r"// Environment=(.*)");
|
||||
RegExp otherScriptsRegExp = new RegExp(r"// OtherScripts=(.*)");
|
||||
RegExp otherResourcesRegExp = new RegExp(r"// OtherResources=(.*)");
|
||||
RegExp sharedObjectsRegExp = new RegExp(r"// SharedObjects=(.*)");
|
||||
RegExp packageRootRegExp = new RegExp(r"// PackageRoot=(.*)");
|
||||
@@ -1365,12 +1215,6 @@ class StandardTestSuite extends TestSuite {
|
||||
}
|
||||
}
|
||||
|
||||
var otherScripts = <String>[];
|
||||
matches = otherScriptsRegExp.allMatches(contents);
|
||||
for (var match in matches) {
|
||||
otherScripts.addAll(wordSplit(match[1]));
|
||||
}
|
||||
|
||||
var otherResources = <String>[];
|
||||
matches = otherResourcesRegExp.allMatches(contents);
|
||||
for (var match in matches) {
|
||||
@@ -1438,7 +1282,6 @@ class StandardTestSuite extends TestSuite {
|
||||
"hasCompileError": hasCompileError,
|
||||
"hasRuntimeError": hasRuntimeError,
|
||||
"hasStaticWarning": hasStaticWarning,
|
||||
"otherScripts": otherScripts,
|
||||
"otherResources": otherResources,
|
||||
"sharedObjects": sharedObjects,
|
||||
"isMultitest": isMultitest,
|
||||
@@ -1461,7 +1304,6 @@ class StandardTestSuite extends TestSuite {
|
||||
"hasCompileError": false,
|
||||
"hasRuntimeError": false,
|
||||
"hasStaticWarning": false,
|
||||
"otherScripts": const [],
|
||||
"isMultitest": false,
|
||||
"isMultiHtmlTest": false,
|
||||
"subtestNames": const [],
|
||||
|
||||
Reference in New Issue
Block a user