blob: eea706f91736a030f084d26df33c546541b66042 [file] [log] [blame]
// 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.
// TODO(rnystrom): This test is only run by the analyzer and front end
// configurations, so nothing is actually *executing* it. It's likely broken.
// We should either remove it or get it working again.
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_suite.dart";
import "package:test_runner/src/test_progress.dart" as progress;
final DEFAULT_TIMEOUT = 20;
final LONG_TIMEOUT = 30;
List<String> packageOptions() {
if (Platform.packageConfig != null) {
return <String>['--packages=${Platform.packageConfig}'];
} else {
return <String>[];
}
}
class TestController {
static int numTests = 0;
static int numCompletedTests = 0;
// Used as TestCase.completedCallback.
static processCompletedTest(TestCase testCase) {
numCompletedTests++;
if (testCase.displayName == "fail-unexpected") {
if (!testCase.unexpectedOutput) {
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} passed unexpectedly, "
"result == ${testCase.result}";
}
} else {
if (testCase.unexpectedOutput) {
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} failed, "
"result == ${testCase.result}";
}
}
}
static void finished() {
if (numTests != numCompletedTests) {
throw "bad completion count. "
"expected: $numTests, actual: $numCompletedTests";
}
}
}
class CustomTestSuite extends TestSuite {
CustomTestSuite(TestConfiguration configuration)
: super(configuration, "CustomTestSuite", []);
void findTestCases(TestCaseEvent onTest, Map testCache) {
void enqueueTestCase(TestCase testCase) {
TestController.numTests++;
onTest(testCase);
}
var testCaseCrash = _makeCrashTestCase("crash", [Expectation.crash]);
var testCasePass = _makeNormalTestCase("pass", [Expectation.pass]);
var testCaseFail = _makeNormalTestCase("fail", [Expectation.fail]);
var testCaseTimeout = _makeNormalTestCase("timeout", [Expectation.timeout]);
var testCaseFailUnexpected =
_makeNormalTestCase("fail-unexpected", [Expectation.pass]);
enqueueTestCase(testCaseCrash);
enqueueTestCase(testCasePass);
enqueueTestCase(testCaseFail);
enqueueTestCase(testCaseTimeout);
enqueueTestCase(testCaseFailUnexpected);
}
TestCase _makeNormalTestCase(
String name, Iterable<Expectation> expectations) {
var args = packageOptions();
args.addAll([Platform.script.toFilePath(), name]);
var command = ProcessCommand('custom', Platform.executable, args, {});
return _makeTestCase(name, DEFAULT_TIMEOUT, command, expectations);
}
TestCase _makeCrashTestCase(String name, Iterable<Expectation> expectations) {
var crashCommand = ProcessCommand(
'custom_crash', getProcessTestFileName(), ["0", "0", "1", "1"], {});
// The crash test sometimes times out. Run it with a large timeout
// to help diagnose the delay.
// The test loads a new executable, which may sometimes take a long time.
// It involves a wait on the VM event loop, and possible system
// delays.
return _makeTestCase(name, LONG_TIMEOUT, crashCommand, expectations);
}
TestCase _makeTestCase(String name, timeout, Command command,
Iterable<Expectation> expectations) {
var configuration = OptionsParser().parse(['--timeout', '$timeout'])[0];
return TestCase(
name, [command], configuration, Set<Expectation>.from(expectations));
}
}
void testProcessQueue() {
var maxProcesses = 2;
var maxBrowserProcesses = maxProcesses;
var config = OptionsParser().parse(['--noBatch'])[0];
ProcessQueue(config, maxProcesses, maxBrowserProcesses,
[CustomTestSuite(config)], [EventListener()], TestController.finished);
}
class EventListener extends progress.EventListener {
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 'pass':
return;
case 'fail-unexpected':
case 'fail':
throw "This test always fails, to test the test scripts.";
break;
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";
}
}
}
String getPlatformExecutableExtension() {
var os = Platform.operatingSystem;
if (os == 'windows') return '.exe';
return ''; // Linux and Mac OS.
}
String getProcessTestFileName() {
var extension = getPlatformExecutableExtension();
var executable = Platform.executable;
var dirIndex = executable.lastIndexOf('dart');
var buffer = StringBuffer(executable.substring(0, dirIndex));
buffer.write('process_test$extension');
return buffer.toString();
}