Remove unused support files for old version of tools/test.py.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com//9360017

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@4033 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
whesse@google.com
2012-02-08 14:11:42 +00:00
parent 0a0f1d9504
commit 9f27aa3a69
19 changed files with 0 additions and 2149 deletions
-9
View File
@@ -1,9 +0,0 @@
# Copyright (c) 2011, 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.
from testing import test_configuration
def GetConfiguration(context, root):
return test_configuration.BrowserTestConfiguration(
context, root, fatal_static_type_errors=True)
-31
View File
@@ -1,31 +0,0 @@
# Copyright (c) 2011, 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.
from testing import test_configuration
def GetConfiguration(context, root):
return ClientCompilationTestConfiguration(context, root)
class ClientCompilationTestConfiguration(
test_configuration.CompilationTestConfiguration):
def __init__(self, context, root):
super(ClientCompilationTestConfiguration, self).__init__(context, root)
def SourceDirs(self):
return [
'async',
'base',
'box2d',
'dom',
'json',
'observable',
'samples',
'streams',
'testing',
'tests',
'touch',
'util',
'view',
'weld']
-99
View File
@@ -1,99 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2011, 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 os
from os.path import join, exists
import re
import test
import utils
class JUnitTestCase(test.TestCase):
def __init__(self, path, context, classnames, mode, arch):
super(JUnitTestCase, self).__init__(context, path)
self.classnames = classnames
self.mode = mode
self.arch = arch
def IsBatchable(self):
return False
def IsNegative(self):
return False
def GetLabel(self):
return "%s/%s %s" % (self.mode, self.arch, '/'.join(self.path))
def GetClassPath(self):
third_party = join(self.context.workspace, 'third_party')
jars = ['args4j/2.0.12/args4j-2.0.12.jar',
'guava/r09/guava-r09.jar',
'json/r2_20080312/json.jar',
'rhino/1_7R3/js.jar',
'hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar',
'hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar',
'hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar',
'hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar',
'junit/v4_8_2/junit.jar']
jars = [ join(third_party, jar) for jar in jars ]
buildroot = utils.GetBuildRoot(self.context.os, self.mode, self.arch)
dartc_classes = [ os.path.join(buildroot, 'compiler', 'lib', 'dartc.jar'),
os.path.join(buildroot, 'compiler', 'lib', 'corelib.jar') ]
test_classes = os.path.join(buildroot, 'compiler-tests.jar')
closure_jar = os.path.sep.join([buildroot, 'closure_out', 'compiler.jar'])
return os.path.pathsep.join(
dartc_classes + [test_classes] + [closure_jar] + jars)
def GetCommand(self):
test_py = join(join(self.context.workspace, 'tools'), 'test.py')
d8 = self.context.GetD8(self.mode, self.arch)
# Note that it is important to run all the JUnit tests in the same process.
# This way we have a chance of causing problems with static state early.
return ['java', '-ea', '-classpath', self.GetClassPath(),
'-Dcom.google.dart.runner.d8=' + d8,
'-Dcom.google.dart.corelib.SharedTests.test_py=' + test_py,
'org.junit.runner.JUnitCore'] + self.classnames
def GetName(self):
return self.path[-1]
class JUnitTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(JUnitTestConfiguration, self).__init__(context, root)
def ListTests(self, current_path, path, mode, arch, component):
test_path = current_path + ['junit_tests']
if not self.Contains(path, test_path):
return []
classes = []
javatests_path = join(join(join(self.root, '..'), '..'), 'javatests')
javatests_path = os.path.normpath(javatests_path)
for root, dirs, files in os.walk(javatests_path):
if root.endswith('com/google/dart/compiler/vm'):
continue
for f in [x for x in files if self.IsTest(x)]:
classname = []
classname.extend(root[len(javatests_path) + 1:].split(os.path.sep))
classname.append(f[:-5]) # Remove .java suffix.
classname = '.'.join(classname)
if classname == 'com.google.dart.corelib.SharedTests':
continue
classes.append(classname)
return [JUnitTestCase(test_path, self.context, classes, mode, arch)]
def IsTest(self, name):
return name.endswith('Tests.java')
def GetTestStatus(self, sections, defs):
status = join(self.root, 'dartc.status')
if exists(status):
test.ReadConfigurationInto(status, sections, defs)
def GetConfiguration(context, root):
return JUnitTestConfiguration(context, root)
-67
View File
@@ -1,67 +0,0 @@
# Copyright (c) 2011, 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 os
from os.path import join, exists
import test
from testing import test_runner
class VmTestCase(test.TestCase):
def __init__(self, path, context, mode, arch, flags):
super(VmTestCase, self).__init__(context, path)
self.mode = mode
self.arch = arch
self.flags = flags
def IsNegative(self):
# TODO(kasperl): Figure out how to support negative tests. Maybe
# just have a TEST_CASE_NEGATIVE macro?
return False
def GetLabel(self):
return '%s%s vm %s' % (self.mode, self.arch, '/'.join(self.path))
def GetCommand(self):
command = self.context.GetRunTests(self.mode, self.arch)
command += [ self.GetName() ]
# Add flags being set in the context.
for flag in self.context.flags:
command.append(flag)
if self.flags: command += self.flags
return command
def GetName(self):
return self.path[-1]
class VmTestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(VmTestConfiguration, self).__init__(context, root)
def ListTests(self, current_path, path, mode, arch, component):
if component != 'vm': return []
run_tests = self.context.GetRunTests(mode, arch)
output = test_runner.Execute(run_tests + ['--list'], self.context)
if output.exit_code != 0:
print output.stdout
print output.stderr
return [ ]
tests = [ ]
for test_line in output.stdout.strip().split('\n'):
name_and_flags = test_line.split()
name = name_and_flags[0]
flags = name_and_flags[1:]
test_path = current_path + [name]
if self.Contains(path, test_path):
tests.append(VmTestCase(test_path, self.context, mode, arch, flags))
return tests
def GetTestStatus(self, sections, defs):
status = join(self.root, 'vm.status')
if exists(status): test.ReadConfigurationInto(status, sections, defs)
def GetConfiguration(context, root):
return VmTestConfiguration(context, root)
-143
View File
@@ -1,143 +0,0 @@
# Copyright (c) 2011, 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 os
from os.path import join, exists
import re
import test
import utils
class Error(Exception):
pass
class Co19TestCase(test.TestCase):
def __init__(self, path, context, filename, mode, arch, component):
super(Co19TestCase, self).__init__(context, path)
self.filename = filename
self.mode = mode
self.arch = arch
self.component = component
self._is_negative = None
def IsNegative(self):
if self._is_negative is None :
contents = self.GetSource()
if '@compile-error' in contents or '@runtime-error' in contents:
self._is_negative = True
else:
self._is_negative = False
return self._is_negative
def GetLabel(self):
return "%s%s %s %s" % (self.mode, self.arch, self.component,
"/".join(self.path))
def GetCommand(self):
# Parse the options by reading the .dart source file.
source = self.GetSource()
vm_options = utils.ParseTestOptions(test.VM_OPTIONS_PATTERN, source,
self.context.workspace)
dart_options = utils.ParseTestOptions(test.DART_OPTIONS_PATTERN, source,
self.context.workspace)
# Combine everything into a command array and return it.
command = self.context.GetDart(self.mode, self.arch, self.component)
command += self.context.flags
if self.mode == 'release': command += ['--optimize']
if vm_options: command += vm_options
if dart_options: command += dart_options
else:
command += [self.filename]
return command
def GetName(self):
return self.path[-1]
def GetPath(self):
return os.path.dirname(self.filename)
def GetSource(self):
return file(self.filename).read()
class Co19TestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(Co19TestConfiguration, self).__init__(context, root)
def ListTests(self, current_path, path, mode, arch, component):
tests = []
src_dir = join(self.root, "src")
strip = len(src_dir.split(os.path.sep))
for root, dirs, files in os.walk(src_dir):
ignore_dirs = [d for d in dirs if d.startswith('.')]
for d in ignore_dirs:
dirs.remove(d)
for f in [x for x in files if self.IsTest(x)]:
test_path = [] + current_path
test_path.extend(root.split(os.path.sep)[strip:])
test_name = short_name = f
# remove suffixes
if short_name.endswith(".dart"):
short_name = short_name[:-5] # Remove .dart suffix.
else:
raise Error('Unknown suffix in "%s", fix IsTest() predicate' % f)
test_path.append(short_name)
# test full name and shorted name matches given path pattern
if self.Contains(path, test_path): pass
elif self.Contains(path, test_path + [test_name]): pass
else:
continue
tests.append(Co19TestCase(test_path,
self.context,
join(root, f),
mode,
arch,
component))
return tests
_TESTNAME_PATTERN = re.compile(r'.*_t[0-9]{2}\.dart$')
def IsTest(self, name):
return self._TESTNAME_PATTERN.match(name)
def GetTestStatus(self, sections, defs):
status = join(self.root, "co19-runtime.status")
if exists(status):
test.ReadConfigurationInto(status, sections, defs)
status = join(self.root, "co19-compiler.status")
if exists(status):
test.ReadConfigurationInto(status, sections, defs)
status = join(self.root, "co19-frog.status")
if exists(status):
test.ReadConfigurationInto(status, sections, defs)
status = join(self.root, "co19-leg.status")
if exists(status):
test.ReadConfigurationInto(status, sections, defs)
def Contains(self, path, file):
""" reimplemented for support '**' glob pattern """
if len(path) > len(file):
return
# ** matches to any number of directories, a/**/d matches a/b/c/d
# paths like a/**/x/**/b not allowed
patterns = [p.pattern for p in path]
if '**' in patterns:
idx = patterns.index('**')
patterns[idx : idx] = ['*'] * (len(file) - len(path))
path = [test.Pattern(p) for p in patterns]
for i in xrange(len(path)):
if not path[i].match(file[i]):
return False
return True
def GetConfiguration(context, root):
return Co19TestConfiguration(context, root)
-8
View File
@@ -1,8 +0,0 @@
# Copyright (c) 2011, 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.
from testing import test_configuration
def GetConfiguration(context, root):
return test_configuration.StandardTestConfiguration(context, root)
-8
View File
@@ -1,8 +0,0 @@
# Copyright (c) 2011, 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.
from testing import test_configuration
def GetConfiguration(context, root):
return test_configuration.StandardTestConfiguration(context, root)
-8
View File
@@ -1,8 +0,0 @@
# Copyright (c) 2011, 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.
from testing import test_configuration
def GetConfiguration(context, root):
return test_configuration.StandardTestConfiguration(context, root)
-8
View File
@@ -1,8 +0,0 @@
# Copyright (c) 2011, 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.
from testing import test_configuration
def GetConfiguration(context, root):
return test_configuration.StandardTestConfiguration(context, root)
-139
View File
@@ -1,139 +0,0 @@
# Copyright (c) 2011, 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 os
import re
import shutil
import sys
import tempfile
import test
from testing import test_case,test_configuration
import utils
from os.path import join, exists, isdir
def GeneratedName(src):
return re.sub('\.dart$', '-generatedTest.dart', src)
class DartStubTestCase(test_case.StandardTestCase):
def __init__(self, context, path, filename, mode, arch, component):
super(DartStubTestCase, self).__init__(context, path, filename, mode, arch,
component)
self.filename = filename
self.mode = mode
self.arch = arch
self.component = component
def IsBatchable(self):
return False
def GetStubs(self):
source = self.GetSource()
stub_classes = utils.ParseTestOptions(test.ISOLATE_STUB_PATTERN, source,
self.context.workspace)
if stub_classes is None:
return (None, None, None)
(interface, _, classes) = stub_classes[0].partition(':')
(interface, _, implementation) = interface.partition('+')
return (interface, classes, implementation)
def IsFailureOutput(self, output):
return output.exit_code != 0 or not '##DONE##' in output.stdout
def BeforeRun(self):
if not self.context.generate:
return
(interface, classes, _) = self.GetStubs()
if interface is None:
return
d = join(self.GetPath(), 'generated')
if not isdir(d):
os.mkdir(d)
tmpdir = tempfile.mkdtemp()
src = join(self.GetPath(), interface)
dest = join(self.GetPath(), GeneratedName(interface))
(_, tmp) = tempfile.mkstemp()
command = self.context.GetDartC(self.mode, self.arch)
self.RunCommand(command + [ src,
# dartc generates output even if it has no
# output to generate.
'-noincremental',
'-out', tmpdir,
'-isolate-stub-out', tmp,
'-generate-isolate-stubs', classes ])
shutil.rmtree(tmpdir)
# Copy comments and # commands from the beginning of the source to
# the beginning of the generated file, then copy the remaining
# source to the end.
d = open(dest, 'w')
s = open(src, 'r')
t = open(tmp, 'r')
while True:
line = s.readline()
if not (re.match('^\s+$', line) or line.startswith('//')
or line.startswith('#')):
break
d.write(line)
d.write(t.read())
os.remove(tmp)
d.write(line)
d.write(s.read())
def GetCommand(self):
# Parse the options by reading the .dart source file.
source = self.GetSource()
vm_options = utils.ParseTestOptions(test.VM_OPTIONS_PATTERN, source,
self.context.workspace)
dart_options = utils.ParseTestOptions(test.DART_OPTIONS_PATTERN, source,
self.context.workspace)
(interface, _, implementation) = self.GetStubs()
# Combine everything into a command array and return it.
command = self.context.GetDart(self.mode, self.arch, self.component)
if interface is None:
f = self.filename
else:
f = GeneratedName(interface)
files = [ join(self.GetPath(), f) ]
if vm_options: command += vm_options
if dart_options: command += dart_options
else: command += files
return command
class DartStubTestConfiguration(test_configuration.StandardTestConfiguration):
def __init__(self, context, root):
super(DartStubTestConfiguration, self).__init__(context, root)
def ListTests(self, current_path, path, mode, arch, component):
dartc = self.context.GetDartC(mode, arch)
self.context.generate = os.access(dartc[0], os.X_OK)
tests = []
for root, dirs, files in os.walk(join(self.root, 'src')):
# Skip remnants from the subdirectory that used to be used for
# generated code.
if root.endswith('generated'):
continue
for f in [x for x in files if self.IsTest(x)]:
# If we can generate code, do not use the checked-in generated
# code. Conversely, if we cannot, then only use the
# checked-in generated code.
if self.context.generate == f.endswith('-generatedTest.dart'):
continue
test_path = current_path + [ f[:-5] ] # Remove .dart suffix.
if not self.Contains(path, test_path):
continue
tests.append(DartStubTestCase(self.context,
test_path,
join(root, f),
mode,
arch,
component))
return tests
def GetConfiguration(context, root):
return DartStubTestConfiguration(context, root)
-66
View File
@@ -1,66 +0,0 @@
#!/usr/bin/env python
#
# Copyright (c) 2011, 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.
#
"""
Runs a Dart unit test in different configurations: dartium, chromium, ia32, x64,
arm, simarm, and dartc. Example:
run.py --arch=dartium --mode=release --test=Test.dart
"""
import optparse
import sys
from testing import architecture
import utils
def AreOptionsValid(options):
if not options.arch in ['ia32', 'x64', 'arm', 'simarm', 'dartc', 'dartium',
'chromium', 'frogium']:
print 'Unknown arch %s' % options.arch
return None
return options.test
def Flags():
result = optparse.OptionParser()
result.add_option("-v", "--verbose",
help="Print messages",
default=False,
action="store_true")
result.add_option("-t", "--test",
help="App or Dart file containing the test",
type="string",
action="store",
default=None)
result.add_option("--arch",
help="The architecture to run tests for",
metavar="[ia32,x64,arm,simarm,dartc,chromium,dartium]",
default=utils.GuessArchitecture())
result.add_option("-m", "--mode",
help="The test modes in which to run",
metavar='[debug,release]',
default='debug')
result.set_usage("run.py --arch ARCH --mode MODE -t TEST")
return result
def Main():
parser = Flags()
(options, args) = parser.parse_args()
if not AreOptionsValid(options):
parser.print_help()
return 1
return architecture.GetArchitecture(options.arch, options.mode,
options.test).RunTest(options.verbose)
if __name__ == '__main__':
sys.exit(Main())
Regular → Executable
View File
-605
View File
@@ -1,605 +0,0 @@
# Copyright (c) 2011, 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 os
import platform
import re
import shutil
import subprocess
import sys
import tempfile
import utils
OS_GUESS = utils.GuessOS()
HTML_CONTENTS = """
<html>
<head>
<title> Test %(title)s </title>
<style>
.unittest-table { font-family:monospace; border:1px; }
.unittest-pass { background: #6b3;}
.unittest-fail { background: #d55;}
.unittest-error { background: #a11;}
</style>
</head>
<body>
<h1> Running %(title)s </h1>
<script type="text/javascript" src="%(controller_script)s"></script>
<script type="text/javascript">
// If nobody intercepts the error, finish the test.
onerror = function() { window.layoutTestController.notifyDone() };
document.onreadystatechange = function() {
if (document.readyState != "loaded") return;
// If 'startedDartTest' is not set, that means that the test did not have
// a chance to load. This will happen when a load error occurs in the VM.
// Give the machine time to start up.
setTimeout(function() {
// A window.postMessage might have been enqueued after this timeout.
// Just sleep another time to give the browser the time to process the
// posted message.
setTimeout(function() {
if (layoutTestController && !layoutTestController.startedDartTest) {
layoutTestController.notifyDone();
}
}, 0);
}, 50);
};
</script>
<script type="%(script_type)s" src="%(source_script)s"></script>
</body>
</html>
"""
DART_TEST_AS_LIBRARY = """
#library('test');
#source('%(test)s');
"""
DART_CONTENTS = """
#library('test');
#import('%(dom_library)s');
#import('%(test_framework)s');
#import('%(library)s', prefix: "Test");
waitForDone() {
window.postMessage('unittest-suite-wait-for-done', '*');
}
pass() {
document.body.innerHTML = 'PASS';
window.postMessage('unittest-suite-done', '*');
}
fail(e, trace) {
document.body.innerHTML = 'FAIL: $e, $trace';
window.postMessage('unittest-suite-done', '*');
}
main() {
bool needsToWait = false;
bool mainIsFinished = false;
TestRunner.waitForDoneCallback = () { needsToWait = true; };
TestRunner.doneCallback = () {
if (mainIsFinished) {
pass();
} else {
needsToWait = false;
}
};
try {
Test.main();
if (needsToWait) {
waitForDone();
} else {
pass();
}
mainIsFinished = true;
} catch(var e, var trace) {
fail(e, trace);
}
}
"""
# Patterns for matching test options in .dart files.
DART_OPTIONS_PATTERN = re.compile(r'// DartOptions=(.*)')
# Pattern for checking if the test is a web test.
DOM_IMPORT_PATTERN = re.compile(r'#import.*(dart:(dom|html)|html\.dart).*\);',
re.MULTILINE)
# Pattern for matching the output of a browser test.
BROWSER_OUTPUT_PASS_PATTERN = re.compile(r'^Content-Type: text/plain\nPASS$',
re.MULTILINE)
# Pattern for matching flaky errors of browser tests. xvfb-run by default uses
# DISPLAY=:99, we keep that in the error pattern to avoid matching real
# errors when DISPLAY is set incorrectly.
BROWSER_FLAKY_DISPLAY_ERR_PATTERN = re.compile(
r'Gtk-WARNING \*\*: cannot open display: :99', re.MULTILINE)
# Pattern for checking if the test is a library in itself.
LIBRARY_DEFINITION_PATTERN = re.compile(r'^#library\(.*\);',
re.MULTILINE)
SOURCE_OR_IMPORT_PATTERN = re.compile(r'^#(source|import)\(.*\);',
re.MULTILINE)
class Error(Exception):
"""Base class for exceptions in this module."""
pass
def _IsWebTest(source):
"""Returns True if the source includes a dart dom library #import."""
return DOM_IMPORT_PATTERN.search(source)
def IsLibraryDefinition(test, source):
"""Returns True if the source has a #library statement."""
if LIBRARY_DEFINITION_PATTERN.search(source):
return True
if SOURCE_OR_IMPORT_PATTERN.search(source):
print ('WARNING for %s: Browser tests need a #library '
'for a file that #import or #source' % test)
return False
class Architecture(object):
"""Definitions for different ways to test based on the component flag."""
def __init__(self, root_path, arch, mode, component, test):
self.root_path = root_path
self.arch = arch
self.mode = mode
self.component = component
self.test = test
self.build_root = utils.GetBuildRoot(OS_GUESS, self.mode, self.arch)
source = file(test).read()
self.vm_options = []
self.dart_options = utils.ParseTestOptions(DART_OPTIONS_PATTERN,
source,
root_path)
self.is_web_test = _IsWebTest(source)
self.temp_dir = None
def GetVMOption(self, option):
for flag in self.vm_options:
if flag.startswith('--%s=' % option):
return flag.split('=')[1]
return None
def HasFatalTypeErrors(self):
"""Returns True if this type of component supports --fatal-type-errors."""
return False
def GetTestFrameworkPath(self):
"""Path to dart source (TestFramework.dart) for testing framework."""
return os.path.join(self.root_path, 'tests', 'isolate', 'src',
'TestFramework.dart')
class BrowserArchitecture(Architecture):
"""Architecture that runs compiled dart->JS through a browser."""
def __init__(self, root_path, arch, mode, component, test):
super(BrowserArchitecture, self).__init__(root_path, arch, mode, component,
test)
self.temp_dir = tempfile.mkdtemp()
if not self.is_web_test: self.GenerateWebTestScript()
def GetTestScriptFile(self):
"""Returns the name of the .dart file to compile."""
if self.is_web_test: return os.path.abspath(self.test)
return os.path.join(self.temp_dir, 'test.dart')
def GetHtmlContents(self):
"""Fills in the HTML_CONTENTS template with info for this architecture."""
script_type = self.GetScriptType()
controller_path = os.path.join(self.root_path, 'client', 'testing',
'unittest', 'test_controller.js')
return HTML_CONTENTS % {
'title': self.test,
'controller_script': controller_path,
'script_type': script_type,
'source_script': self.GetScriptPath()
}
def GetHtmlPath(self):
"""Creates a path for the generated .html file.
Resources for web tests are relative to the 'html' file. We
output the 'html' file in the 'out' directory instead of the temporary
directory because we can easily go the the resources in 'client' through
'out'.
Returns:
Created path for the generated .html file.
"""
if self.is_web_test:
html_path = os.path.join(self.root_path, 'client', self.build_root)
if not os.path.exists(html_path):
os.makedirs(html_path)
return html_path
return self.temp_dir
def GetTestContents(self, library_file):
"""Pastes a preamble on the front of the .dart file before testing."""
unittest_path = os.path.join(self.root_path, 'client', 'testing',
'unittest', 'unittest.dart')
if self.component == 'chromium':
dom_path = os.path.join(self.root_path, 'client', 'testing',
'unittest', 'dom_for_unittest.dart')
else:
dom_path = os.path.join('dart:dom')
test_framework_path = self.GetTestFrameworkPath()
test_path = os.path.abspath(self.test)
inputs = {
'unittest': unittest_path,
'test': test_path,
'dom_library': dom_path,
'test_framework': test_framework_path,
'library': library_file
}
return DART_CONTENTS % inputs
def GenerateWebTestScript(self):
"""Creates a .dart file to run in the test."""
if IsLibraryDefinition(self.test, file(self.test).read()):
library_file = os.path.abspath(self.test)
else:
library_file = 'test_as_library.dart'
test_as_library = DART_TEST_AS_LIBRARY % {
'test': os.path.abspath(self.test)
}
test_as_library_file = os.path.join(self.temp_dir, library_file)
f = open(test_as_library_file, 'w')
f.write(test_as_library)
f.close()
app_output_file = self.GetTestScriptFile()
f = open(app_output_file, 'w')
f.write(self.GetTestContents(library_file))
f.close()
def GetRunCommand(self, fatal_static_type_errors=False):
"""Returns a command line to execute for the test."""
fatal_static_type_errors = fatal_static_type_errors # shutup lint!
# Find DRT
# For some reason, DRT needs to be called via an absolute path
drt_location = self.GetVMOption('browser')
if drt_location is not None:
drt_location = os.path.abspath(drt_location)
else:
drt_location = os.path.join(self.root_path, 'client', 'tests', 'drt',
'DumpRenderTree')
# On Mac DumpRenderTree is a .app folder
if platform.system() == 'Darwin':
drt_location += '.app/Contents/MacOS/DumpRenderTree'
drt_flags = ['--no-timeout']
if len(self.vm_options) > 0:
dart_flags = '--dart-flags='
dart_flags += ' '.join(self.vm_options)
drt_flags.append(dart_flags)
html_output_file = os.path.join(self.GetHtmlPath(), self.GetHtmlName())
f = open(html_output_file, 'w')
f.write(self.GetHtmlContents())
f.close()
drt_flags.append(html_output_file)
return [drt_location] + drt_flags
def HasFailed(self, output):
"""Return True if the 'PASS' result string isn't in the output."""
return not BROWSER_OUTPUT_PASS_PATTERN.search(output)
def WasFlakyDrt(self, error):
"""Return whether the error indicates a flaky error from running.
DumpRenderTree within xvfb-run.
"""
return BROWSER_FLAKY_DISPLAY_ERR_PATTERN.search(error)
def RunTest(self, verbose):
"""Calls GetRunCommand() and executes the returned commandline.
Args:
verbose: if True, print additional diagnostics to stdout.
Returns:
Return code from executable. 0 == PASS, 253 = CRASH, anything
else is treated as FAIL
"""
retcode = self.Compile()
if retcode != 0: return 1
command = self.GetRunCommand()
unused_status, output, err = ExecutePipedCommand(command, verbose)
if not self.HasFailed(output):
return 0
# TODO(sigmund): print better error message, including how to run test
# locally, and translate error traces using source map info.
print '(FAIL) test page:\033[31m %s \033[0m' % command[2]
if verbose:
print 'Additional info: '
print output
print err
return 1
def Cleanup(self):
"""Removes temporary files created for the test."""
if self.temp_dir:
shutil.rmtree(self.temp_dir)
self.temp_dir = None
class ChromiumArchitecture(BrowserArchitecture):
"""Architecture that runs compiled dart->JS through a chromium DRT."""
def __init__(self, root_path, arch, mode, component, test):
super(ChromiumArchitecture, self).__init__(root_path, arch, mode, component, test)
def GetScriptType(self):
return 'text/javascript'
def GetScriptPath(self):
"""Returns the name of the output .js file to create."""
path = self.GetTestScriptFile()
return os.path.abspath(os.path.join(self.temp_dir,
os.path.basename(path) + '.js'))
def GetHtmlName(self):
"""Returns the name of the output .html file to create."""
relpath = os.path.relpath(self.test, self.root_path)
return relpath.replace(os.sep, '_') + '.html'
def Compile(self):
return ExecuteCommand(self.GetCompileCommand())
class DartcChromiumArchitecture(ChromiumArchitecture):
"""ChromiumArchitecture that compiles code using dartc."""
def __init__(self, root_path, arch, mode, component, test):
super(DartcChromiumArchitecture, self).__init__(
root_path, arch, mode, component, test)
def GetCompileCommand(self, fatal_static_type_errors=False):
"""Returns cmdline as an array to invoke the compiler on this test."""
# We need an absolute path because the compilation will run
# in a temporary directory.
build_root = utils.GetBuildRoot(OS_GUESS, self.mode, 'ia32')
dartc = os.path.abspath(os.path.join(build_root, 'compiler', 'bin',
'dartc'))
if utils.IsWindows(): dartc += '.exe'
cmd = [dartc, '--work', self.temp_dir]
if self.mode == 'release':
cmd += ['--optimize']
cmd += self.vm_options
cmd += ['--out', self.GetScriptPath()]
if fatal_static_type_errors:
# TODO(zundel): update to --fatal_type_errors for both VM and Compiler
cmd.append('-fatal-type-errors')
cmd.append(self.GetTestScriptFile())
return cmd
class FrogChromiumArchitecture(ChromiumArchitecture):
"""ChromiumArchitecture that compiles code using frog."""
def __init__(self, root_path, arch, mode, component, test):
super(FrogChromiumArchitecture, self).__init__(
root_path, arch, mode, component, test)
def GetCompileCommand(self, fatal_static_type_errors=False):
"""Returns cmdline as an array to invoke the compiler on this test."""
# Get a frog executable from the command line. Default to frogsh.
# We need an absolute path because the compilation will run
# in a temporary directory.
frog = self.GetVMOption('frog')
if frog is not None:
frog = os.path.abspath(frog)
else:
frog = os.path.abspath(utils.GetDartRunner(self.mode, self.arch, 'frogsh'))
frog_libdir = self.GetVMOption('froglib')
if frog_libdir is not None:
frog_libdir = os.path.abspath(frog_libdir)
else:
frog_libdir = os.path.abspath(os.path.join(self.root_path, 'frog', 'lib'))
cmd = [frog,
'--libdir=%s' % frog_libdir,
'--compile-only',
'--out=%s' % self.GetScriptPath()]
cmd.extend(self.vm_options)
cmd.append(self.GetTestScriptFile())
return cmd
class DartiumArchitecture(BrowserArchitecture):
"""Architecture that runs dart in an VM embedded in DumpRenderTree."""
def __init__(self, root_path, arch, mode, component, test):
super(DartiumArchitecture, self).__init__(root_path, arch, mode, component, test)
def GetScriptType(self):
return 'application/dart'
def GetScriptPath(self):
return 'file:///' + self.GetTestScriptFile()
def GetHtmlName(self):
path = os.path.relpath(self.test, self.root_path).replace(os.sep, '_')
return path + '.dartium.html'
def GetCompileCommand(self, fatal_static_type_errors=False):
fatal_static_type_errors = fatal_static_type_errors # shutup lint!
return None
def Compile(self):
return 0
class WebDriverArchitecture(FrogChromiumArchitecture):
"""Architecture that runs compiled dart->JS (via frog) through a variety of
real browsers using WebDriver."""
def __init__(self, root_path, arch, mode, component, test):
super(WebDriverArchitecture, self).__init__(root_path, arch, mode,
component, test)
def GetRunCommand(self, fatal_static_type_errors=False):
"""Returns a command line to execute for the test."""
flags = self.vm_options
browser_flag = 'chrome'
if 'ff' in flags or 'firefox' in flags:
browser_flag = 'ff'
elif 'ie' in flags or 'explorer' in flags or 'internet-explorer' in flags:
browser_flag = 'ie'
elif 'safari' in flags:
browser_flag = 'safari'
selenium_location = os.path.join(self.root_path, 'tools', 'testing',
'run_selenium.py')
html_output_file = os.path.join(self.GetHtmlPath(), self.GetHtmlName())
f = open(html_output_file, 'w')
f.write(self.GetHtmlContents())
f.close()
return [selenium_location, '--out', html_output_file, '--browser',
browser_flag]
class StandaloneArchitecture(Architecture):
"""Base class for architectures that run tests without a browser."""
def __init__(self, root_path, arch, mode, component, test):
super(StandaloneArchitecture, self).__init__(root_path, arch, mode, component,
test)
def GetExecutable(self):
"""Returns the path to the Dart test runner (executes the .dart file)."""
return utils.GetDartRunner(self.mode, self.arch, self.component)
def GetCompileCommand(self, fatal_static_type_errors=False):
fatal_static_type_errors = fatal_static_type_errors # shutup lint!
return None
def GetOptions(self):
return []
def GetRunCommand(self, fatal_static_type_errors=False):
"""Returns a command line to execute for the test."""
dart = self.GetExecutable()
command = [dart] + self.GetOptions() + self.vm_options
if fatal_static_type_errors:
command += self.GetFatalTypeErrorsFlags()
if self.dart_options:
command += self.dart_options
else:
command += [self.test]
return command
def GetFatalTypeErrorsFlags(self):
return []
def RunTest(self, verbose):
command = self.GetRunCommand()
return ExecuteCommand(command, verbose)
def Cleanup(self):
return
class LegArchitecture(StandaloneArchitecture):
def __init__(self, root_path, arch, mode, component, test):
super(LegArchitecture, self).__init__(root_path, arch, mode, component,
test)
def GetOptions(self):
return ['--leg_only']
def GetExecutable(self):
"""Returns the path to the Dart test runner (executes the .dart file)."""
return utils.GetDartRunner(self.mode, self.arch, 'frog')
# Long term, we should do the running machinery that is currently in
# DartRunner.java
class DartcArchitecture(StandaloneArchitecture):
"""Runs the Dart ->JS compiler then runs the result in a standalone JS VM."""
def __init__(self, root_path, arch, mode, component, test):
super(DartcArchitecture, self).__init__(root_path, arch, mode, component, test)
def GetOptions(self):
if self.mode == 'release': return ['--optimize']
return []
def GetFatalTypeErrorsFlags(self):
return ['--fatal-type-errors']
def HasFatalTypeErrors(self):
return True
def ExecutePipedCommand(cmd, verbose):
"""Execute a command in a subprocess."""
if verbose:
print 'Executing: ' + ' '.join(cmd)
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(output, err) = pipe.communicate()
if pipe.returncode != 0 and verbose:
print 'Execution failed: ' + output + '\n' + err
print output
print err
return pipe.returncode, output, err
def ExecuteCommand(cmd, verbose=False):
"""Execute a command in a subprocess."""
if verbose: print 'Executing: ' + ' '.join(cmd)
return subprocess.call(cmd)
def GetArchitecture(arch, mode, component, test):
root_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..'))
if component == 'chromium':
return DartcChromiumArchitecture(root_path, arch, mode, component, test)
elif component == 'dartium':
return DartiumArchitecture(root_path, arch, mode, component, test)
elif component == 'frogium':
return FrogChromiumArchitecture(root_path, arch, mode, component, test)
elif component == 'webdriver':
return WebDriverArchitecture(root_path, arch, mode, component, test)
elif component in ['vm', 'frog', 'frogsh']:
return StandaloneArchitecture(root_path, arch, mode, component, test)
elif component == 'leg':
return LegArchitecture(root_path, arch, mode, component, test)
elif component == 'dartc':
return DartcArchitecture(root_path, arch, mode, component, test)
-178
View File
@@ -1,178 +0,0 @@
# Copyright (c) 2011, 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.
"""Common TestCase subclasses used to define a single test."""
import os
import tempfile
import test
from testing import architecture
class Error(Exception):
pass
class StandardTestCase(test.TestCase):
"""A test case defined by a *Test.dart file."""
def __init__(self, context, path, filename, mode, arch, component,
vm_options=None):
super(StandardTestCase, self).__init__(context, path)
self.filename = filename
self.mode = mode
self.arch = arch
self.component = component
self.run_arch = architecture.GetArchitecture(self.arch, self.mode,
self.component,
self.filename)
for flag in context.flags:
self.run_arch.vm_options.append(flag)
if vm_options:
for flag in vm_options:
self.run_arch.vm_options.append(flag)
def IsNegative(self):
return self.GetName().endswith('NegativeTest')
def GetLabel(self):
return '%s%s %s %s' % (self.mode, self.arch, self.component,
'/'.join(self.path))
def GetCommand(self):
return self.run_arch.GetRunCommand()
def GetName(self):
return self.path[-1]
def GetPath(self):
return os.path.dirname(self.filename)
def GetSource(self):
return file(self.filename).read()
def Cleanup(self):
# TODO(ngeoffray): We run out of space on the build bots for these tests if
# the temp directories are not removed right after running the test.
if not self.context.keep_temporary_files:
self.run_arch.Cleanup()
class MultiTestCase(StandardTestCase):
"""Multiple test cases defined within a single *Test.dart file."""
def __init__(self, context, path, filename, kind, mode, arch, component,
vm_options = None):
super(MultiTestCase, self).__init__(context, path, filename, mode, arch,
component, vm_options)
self.kind = kind
def GetCommand(self):
"""Returns a commandline to execute to perform the test."""
return self.run_arch.GetRunCommand(
fatal_static_type_errors=(self.kind == 'static type error'))
def IsNegative(self):
"""Determine if this is a negative test. by looking at @ directives.
A negative test is considered to pas if its outcome is FAIL.
Returns:
True if this is a negative test.
"""
if self.kind == 'compile-time error':
return True
if self.kind == 'runtime error':
return True
if self.kind == 'static type error':
return self.run_arch.HasFatalTypeErrors()
return False
class BrowserTestCase(StandardTestCase):
"""A test case that executes inside DumpRenderTree or a browser."""
def __init__(self, context, path, filename,
fatal_static_type_errors, mode, arch, component, vm_options=None):
super(BrowserTestCase, self).__init__(
context, path, filename, mode, arch, component, vm_options)
self.fatal_static_type_errors = fatal_static_type_errors
def Run(self):
"""Optionally compiles and then runs the specified test."""
command = self.run_arch.GetCompileCommand(self.fatal_static_type_errors)
if command:
# We change the directory where dartc will be launched because
# it is not predictable on the location of the compiled file. In
# case the test is a web test, we make sure the app file is not
# in a subdirectory.
cwd = None
if self.run_arch.is_web_test: cwd = self.run_arch.temp_dir
command = command[:1] + self.context.flags + command[1:]
test_output = self.RunCommand(command, cwd=cwd, cleanup=False)
# If errors were found, fail fast and show compile errors:
if test_output.output.exit_code != 0:
return test_output
command = self.run_arch.GetRunCommand()
# Don't clean up just in case test turned out flaky and we want to retry.
test_output = self.RunCommand(command, cleanup=False)
# The return value of DumpRenderedTree does not indicate test failing, but
# the output does.
if self.run_arch.HasFailed(test_output.output.stdout):
test_output.output.exit_code = 1
# DumpRenderTree is sometimes flaky in xvfb-run, try again in that case.
if (self.run_arch.WasFlakyDrt(test_output.output.stderr)):
print "\nFlaky Gtw-WARNING error found, trying again..."
test_output = self.RunCommand(command, cleanup=False)
if self.run_arch.HasFailed(test_output.output.stdout):
test_output.output.exit_code = 1
self.Cleanup();
return test_output
class CompilationTestCase(test.TestCase):
"""Run the dartc compiler on a given top level .dart file."""
def __init__(self, path, context, filename, mode, arch, component):
super(CompilationTestCase, self).__init__(context, path)
self.filename = filename
self.mode = mode
self.arch = arch
self.component = component
self.run_arch = architecture.GetArchitecture(self.arch,
self.mode,
self.component,
self.filename)
self.temp_dir = tempfile.mkdtemp(prefix='dartc-output-')
def IsNegative(self):
return False
def GetLabel(self):
return '%s/%s %s %s' % (self.mode, self.arch, self.component,
'/'.join(self.path))
def GetCommand(self):
"""Returns a command line to run the test."""
cmd = self.context.GetDartC(self.mode, self.arch)
cmd += self.context.flags
cmd += ['-check-only',
'-fatal-type-errors',
'-Werror',
'-out', self.temp_dir,
self.filename]
return cmd
def GetName(self):
return self.path[-1]
def Cleanup(self):
if not self.context.keep_temporary_files:
self.run_arch.Cleanup()
-326
View File
@@ -1,326 +0,0 @@
# Copyright (c) 2011, 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.
"""Common Testconfiguration subclasses used to define a class of tests."""
import atexit
import fileinput
import os
import re
import shutil
import test
from testing import test_case
import utils
# Patterns for matching test options in .dart files.
VM_OPTIONS_PATTERN = re.compile(r"// VMOptions=(.*)")
class Error(Exception):
pass
class TestConfigurationError(Error):
pass
class StandardTestConfiguration(test.TestConfiguration):
"""Configuration that looks for .dart files in the tests/*/src dirs."""
LEGAL_KINDS = set(['compile-time error',
'runtime error',
'static type error',
'dynamic type error'])
def __init__(self, context, root, flags = []):
super(StandardTestConfiguration, self).__init__(context, root, flags)
def _Cleanup(self, tests):
"""Remove any temporary files created by running the test."""
if self.context.keep_temporary_files:
return
dirs = []
for t in tests:
if t.run_arch:
temp_dir = t.run_arch.temp_dir
if temp_dir:
dirs.append(temp_dir)
if not dirs:
return
if not utils.Daemonize():
return
os.execlp('rm', *(['rm', '-rf'] + dirs))
def CreateTestCases(self, test_path, path, filename, mode, arch, component):
"""Given a .dart filename, create a StandardTestCase from it."""
# Look for VM specified as comments in the source file. If
# several sets of VM options are specified create a separate
# test for each set.
source = file(filename).read()
vm_options_list = utils.ParseTestOptionsMultiple(VM_OPTIONS_PATTERN,
source,
test_path)
tags = {}
if filename.endswith('.dart'):
tags = self.SplitMultiTest(test_path, filename)
if component in ['dartium', 'chromium', 'frogium', 'webdriver']:
if tags:
return []
else:
if vm_options_list:
tests = []
for options in vm_options_list:
tests.append(test_case.BrowserTestCase(
self.context, test_path, filename, False, mode, arch, component,
options + self.flags))
return tests
else:
return [test_case.BrowserTestCase(
self.context, test_path, filename, False, mode, arch, component,
self.flags)]
else:
tests = []
if tags:
for tag in sorted(tags):
kind, test_source = tags[tag]
if not self.Contains(path, test_path + [tag]):
continue
if vm_options_list:
for options in vm_options_list:
tests.append(test_case.MultiTestCase(self.context,
test_path + [tag],
test_source,
kind,
mode, arch, component,
options + self.flags))
else:
tests.append(test_case.MultiTestCase(self.context,
test_path + [tag],
test_source,
kind,
mode, arch, component,
self.flags))
else:
if vm_options_list:
for options in vm_options_list:
tests.append(test_case.StandardTestCase(self.context,
test_path, filename, mode, arch, component,
options + self.flags))
else:
tests.append(test_case.StandardTestCase(self.context,
test_path, filename, mode, arch, component, self.flags))
return tests
def ListTests(self, current_path, path, mode, arch, component):
"""Searches for *Test.dart files and returns list of TestCases."""
tests = []
for root, unused_dirs, files in os.walk(os.path.join(self.root, 'src')):
for f in [x for x in files if self.IsTest(x)]:
if f.endswith('.dart'):
test_path = current_path + [f[:-5]] # Remove .dart suffix.
elif f.endswith('.app'):
# TODO(zundel): .app files are used only the dromaeo test
# and should be removed.
test_path = current_path + [f[:-4]] # Remove .app suffix.
if not self.Contains(path, test_path):
continue
tests.extend(self.CreateTestCases(test_path, path,
os.path.join(root, f),
mode, arch, component))
atexit.register(lambda: self._Cleanup(tests))
return tests
def IsTest(self, name):
"""Returns True if the file name is a test file."""
return name.endswith('Test.dart') or name.endswith('Test.app')
def GetTestStatus(self, sections, defs):
"""Reads the .status file of the TestSuite."""
basename = os.path.basename(self.root)
for component in ['%s.status', '%s-leg.status']:
status = os.path.join(self.root, component % basename)
if os.path.exists(status):
test.ReadConfigurationInto(status, sections, defs)
def FindReferencedFiles(self, lines):
"""Scours the lines containing source code for include directives."""
referenced_files = []
for line in lines:
m = re.match("#(source|import)\(['\"](.*)['\"]\);", line)
if m:
file_name = m.group(2)
if not file_name.startswith('dart:'):
referenced_files.append(file_name)
return referenced_files
def SplitMultiTest(self, test_path, filename):
"""Takes a file with multiple test case defined.
Splits the file into multiple TestCase instances.
Args:
test_path: temporary dir to write split test case data.
filename: name of the file to split.
Returns:
sequence of test cases split from file.
Raises:
TestConfigurationError: when a problem with the multi-test-case
syntax is encountered.
"""
(name, extension) = os.path.splitext(os.path.basename(filename))
with open(filename, 'r') as s:
source = s.read()
lines = source.splitlines()
tags = {}
for line in lines:
(unused_code, sep, info) = line.partition(' /// ')
if sep:
(tag, sep, kind) = info.partition(': ')
if tag in tags:
if kind != 'continued':
raise TestConfigurationError('duplicated tag %s' % tag)
elif kind not in StandardTestConfiguration.LEGAL_KINDS:
raise TestConfigurationError('unrecognized kind %s' % kind)
else:
tags[tag] = kind
if not tags:
return {}
# Prepare directory for generated tests.
tests = {}
generated_test_dir = os.path.join(utils.GetBuildRoot(utils.GuessOS()),
'generated_tests')
generated_test_dir = os.path.join(generated_test_dir, *test_path[:-1])
if not os.path.exists(generated_test_dir):
os.makedirs(generated_test_dir)
# Copy referenced files to generated tests directory.
referenced_files = self.FindReferencedFiles(lines)
for referenced_file in referenced_files:
shutil.copy(os.path.join(os.path.dirname(filename), referenced_file),
os.path.join(generated_test_dir, referenced_file))
# Generate test for each tag found in the main test file.
for tag in tags:
test_lines = []
for line in lines:
if ' /// ' in line:
if ' /// %s:' % tag in line:
test_lines.append(line)
else:
test_lines.append('// %s' % line)
else:
test_lines.append(line)
test_filename = os.path.join(generated_test_dir,
'%s_%s%s' % (name, tag, extension))
with open(test_filename, 'w') as test_file:
for line in test_lines:
print >> test_file, line
tests[tag] = (tags[tag], test_filename)
test_filename = os.path.join(generated_test_dir,
'%s%s' % (name, extension))
with open(test_filename, 'w') as test_file:
for line in lines:
if ' /// ' not in line:
print >> test_file, line
else:
print >> test_file, '//', line
tests['none'] = ('', test_filename)
return tests
class BrowserTestConfiguration(StandardTestConfiguration):
"""A configuration used to run tests inside a browser."""
def __init__(self, context, root, fatal_static_type_errors=False):
super(BrowserTestConfiguration, self).__init__(context, root)
self.fatal_static_type_errors = fatal_static_type_errors
def ListTests(self, current_path, path, mode, arch, component):
"""Searches for *Test .dart files and returns list of TestCases."""
tests = []
for root, unused_dirs, files in os.walk(self.root):
for f in [x for x in files if self.IsTest(x)]:
relative = os.path.relpath(root, self.root).split(os.path.sep)
test_path = current_path + relative + [os.path.splitext(f)[0]]
if not self.Contains(path, test_path):
continue
tests.append(test_case.BrowserTestCase(self.context,
test_path,
os.path.join(root, f),
self.fatal_static_type_errors,
mode, arch, component))
atexit.register(lambda: self._Cleanup(tests))
return tests
def IsTest(self, name):
return name.endswith('_tests.dart') or name.endswith('Test.dart')
class CompilationTestConfiguration(test.TestConfiguration):
"""Configuration that searches specific directories for apps to compile.
Expects a status file named dartc.status
"""
def __init__(self, context, root):
super(CompilationTestConfiguration, self).__init__(context, root)
def ListTests(self, current_path, path, mode, arch, component):
"""Searches for files satisfying IsTest() and returns list of TestCases."""
tests = []
client_path = os.path.normpath(os.path.join(self.root, '..', '..'))
for src_dir in self.SourceDirs():
for root, dirs, files in os.walk(os.path.join(client_path, src_dir)):
ignore_dirs = [d for d in dirs if d.startswith('.')]
for d in ignore_dirs:
dirs.remove(d)
for f in files:
filename = [os.path.basename(client_path)]
filename.extend(root[len(client_path) + 1:].split(os.path.sep))
filename.append(f) # Remove .lib or .app suffix.
test_path = current_path + filename
test_dart_file = os.path.join(root, f)
if (not self.Contains(path, test_path)
or not self.IsTest(test_dart_file)):
continue
tests.append(test_case.CompilationTestCase(test_path,
self.context,
test_dart_file,
mode,
arch,
component))
atexit.register(lambda: self._Cleanup(tests))
return tests
def SourceDirs(self):
"""Returns a list of directories to scan for files to compile."""
raise TestConfigurationError(
'Subclasses must implement SourceDirs()')
def IsTest(self, name):
"""Returns True if name is a test case to be compiled."""
if not name.endswith('.dart'):
return False
if os.path.exists(name):
# TODO(dgrove): can we end reading the input early?
for line in fileinput.input(name):
if re.match('#', line):
fileinput.close()
return True
fileinput.close()
return False
return False
def GetTestStatus(self, sections, defs):
status = os.path.join(self.root, 'dartc.status')
if os.path.exists(status):
test.ReadConfigurationInto(status, sections, defs)
def _Cleanup(self, tests):
if not utils.Daemonize(): return
os.execlp('rm', *(['rm', '-rf'] + [t.temp_dir for t in tests]))
raise
-430
View File
@@ -1,430 +0,0 @@
# Copyright (c) 2011, 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.
#
"""Classes and methods for executing tasks for the test.py framework.
This module includes:
- Managing parallel execution of tests using threads
- Windows and Unix specific code for spawning tasks and retrieving results
- Evaluating the output of each test as pass/fail/crash/timeout
"""
import ctypes
import os
import Queue
import signal
import subprocess
import sys
import tempfile
import threading
import time
import traceback
import testing
import utils
class Error(Exception):
pass
class CommandOutput(object):
"""Represents the output of running a command."""
def __init__(self, pid, exit_code, timed_out, stdout, stderr):
self.pid = pid
self.exit_code = exit_code
self.timed_out = timed_out
self.stdout = stdout
self.stderr = stderr
self.failed = None
class TestOutput(object):
"""Represents the output of running a TestCase."""
def __init__(self, test, command, output):
"""Represents the output of running a TestCase.
Args:
test: A TestCase instance.
command: the command line that was run
output: A CommandOutput instance.
"""
self.test = test
self.command = command
self.output = output
def UnexpectedOutput(self):
"""Compare the result of running the expected from the TestConfiguration.
Returns:
True if the test had an unexpected output.
"""
return not self.GetOutcome() in self.test.outcomes
def GetOutcome(self):
"""Returns one of testing.CRASH, testing.TIMEOUT, testing.FAIL, or
testing.PASS."""
if self.HasCrashed():
return testing.CRASH
if self.HasTimedOut():
return testing.TIMEOUT
if self.HasFailed():
return testing.FAIL
return testing.PASS
def HasCrashed(self):
"""Returns True if the test should be considered testing.CRASH."""
if utils.IsWindows():
if self.output.exit_code == 3:
# The VM uses std::abort to terminate on asserts.
# std::abort terminates with exit code 3 on Windows.
return True
return (0x80000000 & self.output.exit_code
and not 0x3FFFFF00 & self.output.exit_code)
else:
# Timed out tests will have exit_code -signal.SIGTERM.
if self.output.timed_out:
return False
if self.output.exit_code == 253:
# The Java dartc runners exit 253 in case of unhandled exceptions.
return True
return self.output.exit_code < 0
def HasTimedOut(self):
"""Returns True if the test should be considered as testing.TIMEOUT."""
return self.output.timed_out
def HasFailed(self):
"""Returns True if the test should be considered as testing.FAIL."""
execution_failed = self.test.DidFail(self.output)
if self.test.IsNegative():
return not execution_failed
else:
return execution_failed
def Execute(args, context, timeout=None, cwd=None):
"""Executes the specified command.
Args:
args: sequence of the executable name + arguments.
context: An instance of Context object with global settings for test.py.
timeout: optional timeout to wait for results in seconds.
cwd: optionally change to this working directory.
Returns:
An instance of CommandOutput with the collected results.
"""
(fd_out, outname) = tempfile.mkstemp()
(fd_err, errname) = tempfile.mkstemp()
(process, exit_code, timed_out) = RunProcess(context, timeout, args=args,
stdout=fd_out, stderr=fd_err,
cwd=cwd)
os.close(fd_out)
os.close(fd_err)
output = file(outname).read()
errors = file(errname).read()
utils.CheckedUnlink(outname)
utils.CheckedUnlink(errname)
result = CommandOutput(process.pid, exit_code, timed_out,
output, errors)
return result
def KillProcessWithID(pid):
"""Stop a process (with SIGTERM on Unix)."""
if utils.IsWindows():
os.popen('taskkill /T /F /PID %d' % pid)
else:
os.kill(pid, signal.SIGTERM)
MAX_SLEEP_TIME = 0.1
INITIAL_SLEEP_TIME = 0.0001
SLEEP_TIME_FACTOR = 1.25
SEM_INVALID_VALUE = -1
SEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h
def Win32SetErrorMode(mode):
"""Some weird Windows stuff you just have to do."""
prev_error_mode = SEM_INVALID_VALUE
try:
prev_error_mode = ctypes.windll.kernel32.SetErrorMode(mode)
except ImportError:
pass
return prev_error_mode
def RunProcess(context, timeout, args, **rest):
"""Handles the OS specific details of running a task and saving results."""
if context.verbose: print '#', ' '.join(args)
popen_args = args
prev_error_mode = SEM_INVALID_VALUE
if utils.IsWindows():
popen_args = '"' + subprocess.list2cmdline(args) + '"'
if context.suppress_dialogs:
# Try to change the error mode to avoid dialogs on fatal errors. Don't
# touch any existing error mode flags by merging the existing error mode.
# See http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx.
error_mode = SEM_NOGPFAULTERRORBOX
prev_error_mode = Win32SetErrorMode(error_mode)
Win32SetErrorMode(error_mode | prev_error_mode)
process = subprocess.Popen(shell=utils.IsWindows(),
args=popen_args,
**rest)
if (utils.IsWindows() and context.suppress_dialogs
and prev_error_mode != SEM_INVALID_VALUE):
Win32SetErrorMode(prev_error_mode)
# Compute the end time - if the process crosses this limit we
# consider it timed out.
if timeout is None: end_time = None
else: end_time = time.time() + timeout
timed_out = False
# Repeatedly check the exit code from the process in a
# loop and keep track of whether or not it times out.
exit_code = None
sleep_time = INITIAL_SLEEP_TIME
while exit_code is None:
if (not end_time is None) and (time.time() >= end_time):
# Kill the process and wait for it to exit.
KillProcessWithID(process.pid)
# Drain the output pipe from the process to avoid deadlock
process.communicate()
exit_code = process.wait()
timed_out = True
else:
exit_code = process.poll()
time.sleep(sleep_time)
sleep_time *= SLEEP_TIME_FACTOR
if sleep_time > MAX_SLEEP_TIME:
sleep_time = MAX_SLEEP_TIME
return (process, exit_code, timed_out)
class TestRunner(object):
"""Base class for runners."""
def __init__(self, work_queue, tasks, progress):
self.work_queue = work_queue
self.tasks = tasks
self.terminate = False
self.progress = progress
self.threads = []
self.shutdown_lock = threading.Lock()
class BatchRunner(TestRunner):
"""Implements communication with a set of subprocesses using threads."""
def __init__(self, work_queue, tasks, progress, batch_cmd):
super(BatchRunner, self).__init__(work_queue, tasks, progress)
self.runners = {}
self.last_activity = {}
self.context = progress.context
# Scale the number of tasks to the nubmer of CPUs on the machine
# 1:1 is too much of an overload on many machines in batch mode,
# so scale the ratio of threads to CPUs back. On Windows running
# more than one task is not safe.
if tasks == testing.USE_DEFAULT_CPUS:
if utils.IsWindows():
tasks = 1
else:
tasks = .75 * testing.HOST_CPUS
# Start threads
for i in xrange(tasks):
thread = threading.Thread(target=self.RunThread, args=[batch_cmd, i])
self.threads.append(thread)
thread.daemon = True
thread.start()
def RunThread(self, batch_cmd, thread_number):
"""A thread started to feed a single TestRunner."""
try:
runner = None
while not self.terminate and not self.work_queue.empty():
runner = subprocess.Popen(batch_cmd,
stdin=subprocess.PIPE,
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE)
self.runners[thread_number] = runner
self.FeedTestRunner(runner, thread_number)
if thread_number in self.last_activity:
del self.last_activity[thread_number]
# Cleanup
self.EndRunner(runner)
except:
self.Shutdown()
raise
finally:
if thread_number in self.last_activity:
del self.last_activity[thread_number]
if runner: self.EndRunner(runner)
def EndRunner(self, runner):
"""Cleans up a single runner, killing the child if necessary."""
with self.shutdown_lock:
if runner:
returncode = runner.poll()
if returncode is None:
runner.kill()
for (found_runner, thread_number) in self.runners.items():
if runner == found_runner:
del self.runners[thread_number]
break
try:
runner.communicate()
except ValueError:
pass
def CheckForTimeouts(self):
now = time.time()
for (thread_number, start_time) in self.last_activity.items():
if now - start_time > self.context.timeout:
self.runners[thread_number].kill()
def WaitForCompletion(self):
"""Wait for threads to finish, and monitor test runners for timeouts."""
for t in self.threads:
while True:
self.CheckForTimeouts()
t.join(timeout=5)
if not t.isAlive():
break
def FeedTestRunner(self, runner, thread_number):
"""Feed commands to the fork'ed TestRunner through a Popen object."""
last_case = {}
last_buf = ''
while not self.terminate:
# Is the runner still alive?
returninfo = runner.poll()
if returninfo is not None:
buf = last_buf + '\n' + runner.stdout.read()
if last_case:
self.RecordPassFail(last_case, buf, testing.CRASH)
else:
with self.progress.lock:
print >>sys. stderr, ('%s: runner unexpectedly exited: %d'
% (threading.currentThread().name,
returninfo))
print 'Crash Output: '
print
print buf
return
try:
case = self.work_queue.get_nowait()
with self.progress.lock:
self.progress.AboutToRun(case.case)
except Queue.Empty:
return
test_case = case.case
cmd = ' '.join(test_case.GetCommand()[1:])
try:
print >>runner.stdin, cmd
except IOError:
with self.progress.lock:
traceback.print_exc()
# Child exited before starting the next command.
buf = last_buf + '\n' + runner.stdout.read()
self.RecordPassFail(last_case, buf, testing.CRASH)
# We never got a chance to run this command - queue it back up.
self.work_queue.put(case)
return
buf = ''
self.last_activity[thread_number] = time.time()
while not self.terminate:
line = runner.stdout.readline()
if self.terminate:
break
case.case.duration = time.time() - self.last_activity[thread_number]
if not line:
# EOF. Child has exited.
if case.case.duration > self.context.timeout:
with self.progress.lock:
print 'Child timed out after %d seconds' % self.context.timeout
self.RecordPassFail(case, buf, testing.TIMEOUT)
elif buf:
self.RecordPassFail(case, buf, testing.CRASH)
return
# Look for TestRunner batch status escape sequence. e.g.
# >>> TEST PASS
if line.startswith('>>> '):
result = line.split()
if result[1] == 'TEST':
outcome = result[2].lower()
# Read the rest of the output buffer (possible crash output)
if outcome == testing.CRASH:
buf += runner.stdout.read()
self.RecordPassFail(case, buf, outcome)
# Always handle crashes by restarting the runner.
if outcome == testing.CRASH:
return
break
elif result[1] == 'BATCH':
pass
else:
print 'Unknown cmd from batch runner: %s' % line
else:
buf += line
# If the process crashes before the next command is executed,
# save info to report diagnostics.
last_buf = buf
last_case = case
def RecordPassFail(self, case, stdout_buf, outcome):
"""An unexpected failure occurred."""
if outcome == testing.PASS or outcome == testing.OKAY:
exit_code = 0
elif outcome == testing.CRASH:
exit_code = -1
elif outcome == testing.FAIL or outcome == testing.TIMEOUT:
exit_code = 1
else:
assert False, 'Unexpected outcome: %s' % outcome
cmd_output = CommandOutput(0, exit_code,
outcome == testing.TIMEOUT, stdout_buf, '')
test_output = TestOutput(case.case,
case.case.GetCommand(),
cmd_output)
with self.progress.lock:
if test_output.UnexpectedOutput():
self.progress.failed.append(test_output)
else:
self.progress.succeeded += 1
if outcome == testing.CRASH:
self.progress.crashed += 1
self.progress.remaining -= 1
self.progress.HasRun(test_output)
def Shutdown(self):
"""Kill all active runners."""
print 'Shutting down remaining runners.'
self.terminate = True
for runner in self.runners.values():
runner.kill()
# Give threads a chance to exit gracefully
time.sleep(2)
for runner in self.runners.values():
self.EndRunner(runner)
-8
View File
@@ -1,8 +0,0 @@
# Copyright (c) 2011, 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.
from testing import test_configuration
def GetConfiguration(context, root):
return test_configuration.StandardTestConfiguration(context, root)
-8
View File
@@ -1,8 +0,0 @@
# Copyright (c) 2012, 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.
from testing import test_configuration
def GetConfiguration(context, root):
return test_configuration.StandardTestConfiguration(context, root)
-8
View File
@@ -1,8 +0,0 @@
# Copyright (c) 2011, 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.
from testing import test_configuration
def GetConfiguration(context, root):
return test_configuration.StandardTestConfiguration(context, root)