f8b363a335
Change-Id: I24016d9a827e0506b2d5a6b6eed3356afaf90dbd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/500602 Reviewed-by: Bob Nystrom <rnystrom@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
184 lines
5.5 KiB
Dart
184 lines
5.5 KiB
Dart
// Copyright (c) 2013, 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:async";
|
|
import "dart:io";
|
|
|
|
import "package:status_file/expectation.dart";
|
|
import "package:test_runner/src/command.dart";
|
|
import "package:test_runner/src/configuration.dart";
|
|
import "package:test_runner/src/options.dart";
|
|
import "package:test_runner/src/process_queue.dart";
|
|
import "package:test_runner/src/repository.dart";
|
|
import "package:test_runner/src/test_case.dart";
|
|
import "package:test_runner/src/test_file.dart";
|
|
import "package:test_runner/src/test_progress.dart" as progress;
|
|
import "package:test_runner/src/test_suite.dart";
|
|
|
|
final defaultTimeout = 30;
|
|
|
|
class TestController {
|
|
static int numTests = 0;
|
|
static int numCompletedTests = 0;
|
|
|
|
// Used as TestCase.completedCallback.
|
|
static void processCompletedTest(TestCase testCase) {
|
|
final passed = testCase.result.canBeOutcomeOf(testCase.realExpected);
|
|
numCompletedTests++;
|
|
|
|
// This test is expected to pass but actually fails
|
|
if (testCase.displayName == "fail-unexpected") {
|
|
if (passed) _fail(testCase, 'passed unexpectedly');
|
|
return;
|
|
}
|
|
|
|
// This test is expected to pass but actually times out
|
|
if (testCase.displayName == "timeout") {
|
|
if (passed || testCase.result != Expectation.timeout) {
|
|
_fail(testCase, 'did not timeout');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Other tests are either
|
|
// * expected to pass and actually pass
|
|
// * expected to fail and actually fail
|
|
// * expected to <X> and actually <X>
|
|
if (!passed) _fail(testCase, 'did not pass');
|
|
}
|
|
|
|
static Never _fail(TestCase testCase, String message) {
|
|
var stdout = String.fromCharCodes(testCase.lastCommandOutput.stdout);
|
|
var stderr = String.fromCharCodes(testCase.lastCommandOutput.stderr);
|
|
print("stdout = [$stdout]");
|
|
print("stderr = [$stderr]");
|
|
throw "Test case '${testCase.displayName}' $message\n"
|
|
" Actual: ${testCase.result}\n"
|
|
" Expected: ${testCase.realExpected} "
|
|
"(${testCase.expectedOutcomes.join(', ')}))";
|
|
}
|
|
|
|
static void finished() {
|
|
if (numTests != numCompletedTests) {
|
|
throw "bad completion count. "
|
|
"expected: $numTests, actual: $numCompletedTests";
|
|
}
|
|
}
|
|
}
|
|
|
|
class CustomTestSuite extends TestSuite {
|
|
CustomTestSuite(TestConfiguration configuration)
|
|
: super(configuration, "CustomTestSuite", []);
|
|
|
|
@override
|
|
void findTestCases(TestCaseEvent onTest, Map testCache) {
|
|
void enqueueTestCase(TestCase testCase) {
|
|
TestController.numTests++;
|
|
onTest(testCase);
|
|
}
|
|
|
|
var testCaseCrash = _makeTestCase("crash", defaultTimeout, [
|
|
Expectation.crash,
|
|
]);
|
|
var testCasePass = _makeTestCase("pass", defaultTimeout, [
|
|
Expectation.pass,
|
|
]);
|
|
var testCaseFail = _makeTestCase("fail", defaultTimeout, [
|
|
Expectation.runtimeError,
|
|
]);
|
|
var testCaseTimeout = _makeTestCase("timeout", 5, [Expectation.timeout]);
|
|
var testCaseFailUnexpected = _makeTestCase(
|
|
"fail-unexpected",
|
|
defaultTimeout,
|
|
[Expectation.pass],
|
|
);
|
|
|
|
enqueueTestCase(testCaseCrash);
|
|
enqueueTestCase(testCasePass);
|
|
enqueueTestCase(testCaseFail);
|
|
enqueueTestCase(testCaseTimeout);
|
|
enqueueTestCase(testCaseFailUnexpected);
|
|
}
|
|
|
|
TestCase _makeTestCase(
|
|
String name,
|
|
timeout,
|
|
Iterable<Expectation> expectations,
|
|
) {
|
|
var configuration = OptionsParser().parse(['--timeout', '$timeout'])[0];
|
|
final args = [
|
|
if (Platform.packageConfig != null)
|
|
'--packages=${Platform.packageConfig}',
|
|
Platform.script.toFilePath(),
|
|
name,
|
|
];
|
|
final command = VMCommand(Platform.executable, args, {});
|
|
final testFile = TestFile.vmUnitTest(
|
|
'suite/dummy_test',
|
|
hasCompileError: expectations.any(
|
|
(e) => e.canBeOutcomeOf(Expectation.compileTimeError),
|
|
),
|
|
hasRuntimeError: expectations.any(
|
|
(e) => e.canBeOutcomeOf(Expectation.runtimeError),
|
|
),
|
|
hasCrash: expectations.any((e) => e.canBeOutcomeOf(Expectation.crash)),
|
|
);
|
|
return TestCase(
|
|
name,
|
|
[command],
|
|
configuration,
|
|
Set<Expectation>.from(expectations),
|
|
testFile,
|
|
);
|
|
}
|
|
}
|
|
|
|
void testProcessQueue() {
|
|
var maxProcesses = 2;
|
|
var maxBrowserProcesses = maxProcesses;
|
|
var config = OptionsParser().parse(['--no-batch'])[0];
|
|
ProcessQueue(
|
|
config,
|
|
maxProcesses,
|
|
maxBrowserProcesses,
|
|
[CustomTestSuite(config)],
|
|
[EventListener()],
|
|
TestController.finished,
|
|
);
|
|
}
|
|
|
|
class EventListener extends progress.EventListener {
|
|
@override
|
|
void done(TestCase test) {
|
|
TestController.processCompletedTest(test);
|
|
}
|
|
}
|
|
|
|
void main(List<String> arguments) {
|
|
// This script is in [sdk]/tests/standalone/io.
|
|
Repository.uri = Platform.script.resolve('../../..');
|
|
// Run the test_runner_test if there are no command-line options.
|
|
// Otherwise, run one of the component tests that always pass,
|
|
// fail, or timeout.
|
|
if (arguments.isEmpty) {
|
|
testProcessQueue();
|
|
} else {
|
|
switch (arguments[0]) {
|
|
case 'crash':
|
|
exit(253);
|
|
case 'fail-unexpected':
|
|
case 'fail':
|
|
throw "This test always fails, to test the test scripts.";
|
|
case 'pass':
|
|
return;
|
|
case 'timeout':
|
|
// This process should be killed by the test after DEFAULT_TIMEOUT
|
|
Timer(const Duration(hours: 42), () {});
|
|
break;
|
|
default:
|
|
throw "Unknown option ${arguments[0]} passed to test_runner_test";
|
|
}
|
|
}
|
|
}
|