diff options
author | Steve Block <steveblock@google.com> | 2010-08-27 11:02:25 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-09-02 17:17:20 +0100 |
commit | e8b154fd68f9b33be40a3590e58347f353835f5c (patch) | |
tree | 0733ce26384183245aaa5656af26c653636fe6c1 /WebKitTools/Scripts/webkitpy/layout_tests/layout_package | |
parent | da56157816334089526a7a115a85fd85a6e9a1dc (diff) | |
download | external_webkit-e8b154fd68f9b33be40a3590e58347f353835f5c.zip external_webkit-e8b154fd68f9b33be40a3590e58347f353835f5c.tar.gz external_webkit-e8b154fd68f9b33be40a3590e58347f353835f5c.tar.bz2 |
Merge WebKit at r66079 : Initial merge by git
Change-Id: Ie2e1440fb9d487d24e52c247342c076fecaecac7
Diffstat (limited to 'WebKitTools/Scripts/webkitpy/layout_tests/layout_package')
6 files changed, 397 insertions, 136 deletions
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py index 81cdc9b..a9e015f 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py @@ -298,7 +298,20 @@ class Printer(object): self._write("") def print_test_result(self, result, expected, exp_str, got_str): - """Print the result of the test as determined by --print.""" + """Print the result of the test as determined by --print. + + This routine is used to print the details of each test as it completes. + + Args: + result - The actual TestResult object + expected - Whether the result we got was an expected result + exp_str - What we expected to get (used for tracing) + got_str - What we actually got (used for tracing) + + Note that we need all of these arguments even though they seem + somewhat redundant, in order to keep this routine from having to + known anything about the set of expectations. + """ if (self.enabled('trace-everything') or self.enabled('trace-unexpected') and not expected): self._print_test_trace(result, exp_str, got_str) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py index c8648bc..40c691f 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py @@ -51,27 +51,6 @@ def get_options(args): return option_parser.parse_args(args) -def get_result(filename, result_type=test_expectations.PASS, run_time=0): - failures = [] - if result_type == test_expectations.TIMEOUT: - failures = [test_failures.FailureTimeout()] - elif result_type == test_expectations.CRASH: - failures = [test_failures.FailureCrash()] - return dump_render_tree_thread.TestResult(filename, failures, run_time, - total_time_for_all_diffs=0, - time_for_diffs=0) - - -def get_result_summary(port_obj, test_files, expectations_str): - expectations = test_expectations.TestExpectations( - port_obj, test_files, expectations_str, - port_obj.test_platform_name(), is_debug_mode=False, - is_lint_mode=False, tests_are_present=False) - - rs = run_webkit_tests.ResultSummary(expectations, test_files) - return rs, expectations - - class TestUtilityFunctions(unittest.TestCase): def test_configure_logging(self): # FIXME: We need to figure out how to reset the basic logger. @@ -155,6 +134,28 @@ class Testprinter(unittest.TestCase): is_fully_parallel) return printer, regular_output, buildbot_output + def get_result(self, test, result_type=test_expectations.PASS, run_time=0): + failures = [] + if result_type == test_expectations.TIMEOUT: + failures = [test_failures.FailureTimeout()] + elif result_type == test_expectations.CRASH: + failures = [test_failures.FailureCrash()] + path = os.path.join(self._port.layout_tests_dir(), test) + return dump_render_tree_thread.TestResult(path, failures, run_time, + total_time_for_all_diffs=0, + time_for_diffs=0) + + def get_result_summary(self, tests, expectations_str): + test_paths = [os.path.join(self._port.layout_tests_dir(), test) for + test in tests] + expectations = test_expectations.TestExpectations( + self._port, test_paths, expectations_str, + self._port.test_platform_name(), is_debug_mode=False, + is_lint_mode=False, tests_are_present=False) + + rs = run_webkit_tests.ResultSummary(expectations, test_paths) + return test_paths, rs, expectations + def test_help_printer(self): # Here and below we'll call the "regular" printer err and the # buildbot printer out; this corresponds to how things run on the @@ -244,10 +245,18 @@ class Testprinter(unittest.TestCase): def test_print_test_result(self): - result = get_result('foo.html') + # Note here that we don't use meaningful exp_str and got_str values; + # the actual contents of the string are treated opaquely by + # print_test_result() when tracing, and usually we don't want + # to test what exactly is printed, just that something + # was printed (or that nothing was printed). + # + # FIXME: this is actually some goofy layering; it would be nice + # we could refactor it so that the args weren't redundant. Maybe + # the TestResult should contain what was expected, and the + # strings could be derived from the TestResult? printer, err, out = self.get_printer(['--print', 'nothing']) - result = get_result(os.path.join(self._port.layout_tests_dir(), - 'foo.html')) + result = self.get_result('passes/image.html') printer.print_test_result(result, expected=False, exp_str='', got_str='') self.assertTrue(err.empty()) @@ -259,7 +268,7 @@ class Testprinter(unittest.TestCase): printer.print_test_result(result, expected=False, exp_str='', got_str='') self.assertEquals(err.get(), - [' foo.html -> unexpected pass\n']) + [' passes/image.html -> unexpected pass\n']) printer, err, out = self.get_printer(['--print', 'everything']) printer.print_test_result(result, expected=True, exp_str='', @@ -269,7 +278,7 @@ class Testprinter(unittest.TestCase): printer.print_test_result(result, expected=False, exp_str='', got_str='') self.assertEquals(err.get(), - [' foo.html -> unexpected pass\n']) + [' passes/image.html -> unexpected pass\n']) printer, err, out = self.get_printer(['--print', 'nothing']) printer.print_test_result(result, expected=False, exp_str='', @@ -277,11 +286,24 @@ class Testprinter(unittest.TestCase): self.assertTrue(err.empty()) printer, err, out = self.get_printer(['--print', - 'trace-unexpected']) + 'trace-unexpected']) printer.print_test_result(result, expected=True, exp_str='', got_str='') self.assertTrue(err.empty()) + printer, err, out = self.get_printer(['--print', + 'trace-unexpected']) + printer.print_test_result(result, expected=False, exp_str='', + got_str='') + self.assertFalse(err.empty()) + + printer, err, out = self.get_printer(['--print', + 'trace-unexpected']) + result = self.get_result("passes/text.html") + printer.print_test_result(result, expected=False, exp_str='', + got_str='') + self.assertFalse(err.empty()) + err.reset() printer.print_test_result(result, expected=False, exp_str='', got_str='') @@ -297,104 +319,106 @@ class Testprinter(unittest.TestCase): got_str='') def test_print_progress(self): - test_files = ['foo.html', 'bar.html'] expectations = '' # test that we print nothing printer, err, out = self.get_printer(['--print', 'nothing']) - rs, exp = get_result_summary(self._port, test_files, expectations) + tests = ['passes/text.html', 'failures/expected/timeout.html', + 'failures/expected/crash.html'] + paths, rs, exp = self.get_result_summary(tests, expectations) - printer.print_progress(rs, False, test_files) + printer.print_progress(rs, False, paths) self.assertTrue(out.empty()) self.assertTrue(err.empty()) - printer.print_progress(rs, True, test_files) + printer.print_progress(rs, True, paths) self.assertTrue(out.empty()) self.assertTrue(err.empty()) # test regular functionality printer, err, out = self.get_printer(['--print', 'one-line-progress']) - printer.print_progress(rs, False, test_files) + printer.print_progress(rs, False, paths) self.assertTrue(out.empty()) self.assertFalse(err.empty()) err.reset() out.reset() - printer.print_progress(rs, True, test_files) + printer.print_progress(rs, True, paths) self.assertFalse(err.empty()) self.assertTrue(out.empty()) def test_print_progress__detailed(self): - test_files = ['pass/pass.html', 'pass/timeout.html', 'fail/crash.html'] - expectations = 'pass/timeout.html = TIMEOUT' + tests = ['passes/text.html', 'failures/expected/timeout.html', + 'failures/expected/crash.html'] + expectations = 'failures/expected/timeout.html = TIMEOUT' # first, test that it is disabled properly # should still print one-line-progress printer, err, out = self.get_printer( ['--print', 'detailed-progress'], single_threaded=False) - rs, exp = get_result_summary(self._port, test_files, expectations) - printer.print_progress(rs, False, test_files) + paths, rs, exp = self.get_result_summary(tests, expectations) + printer.print_progress(rs, False, paths) self.assertFalse(err.empty()) self.assertTrue(out.empty()) # now test the enabled paths printer, err, out = self.get_printer( ['--print', 'detailed-progress'], single_threaded=True) - rs, exp = get_result_summary(self._port, test_files, expectations) - printer.print_progress(rs, False, test_files) + paths, rs, exp = self.get_result_summary(tests, expectations) + printer.print_progress(rs, False, paths) self.assertFalse(err.empty()) self.assertTrue(out.empty()) err.reset() out.reset() - printer.print_progress(rs, True, test_files) + printer.print_progress(rs, True, paths) self.assertFalse(err.empty()) self.assertTrue(out.empty()) - rs.add(get_result('pass/pass.html', test_expectations.TIMEOUT), False) - rs.add(get_result('pass/timeout.html'), True) - rs.add(get_result('fail/crash.html', test_expectations.CRASH), True) + rs.add(self.get_result('passes/text.html', test_expectations.TIMEOUT), False) + rs.add(self.get_result('failures/expected/timeout.html'), True) + rs.add(self.get_result('failures/expected/crash.html', test_expectations.CRASH), True) err.reset() out.reset() - printer.print_progress(rs, False, test_files) + printer.print_progress(rs, False, paths) self.assertFalse(err.empty()) self.assertTrue(out.empty()) # We only clear the meter when retrying w/ detailed-progress. err.reset() out.reset() - printer.print_progress(rs, True, test_files) - self.assertEqual(err.get(), ['']) + printer.print_progress(rs, True, paths) + self.assertFalse(err.empty()) self.assertTrue(out.empty()) printer, err, out = self.get_printer( ['--print', 'detailed-progress,unexpected'], single_threaded=True) - rs, exp = get_result_summary(self._port, test_files, expectations) - printer.print_progress(rs, False, test_files) + paths, rs, exp = self.get_result_summary(tests, expectations) + printer.print_progress(rs, False, paths) self.assertFalse(err.empty()) self.assertTrue(out.empty()) err.reset() out.reset() - printer.print_progress(rs, True, test_files) + printer.print_progress(rs, True, paths) self.assertFalse(err.empty()) self.assertTrue(out.empty()) - rs.add(get_result('pass/pass.html', test_expectations.TIMEOUT), False) - rs.add(get_result('pass/timeout.html'), True) - rs.add(get_result('fail/crash.html', test_expectations.CRASH), True) + rs.add(self.get_result('passes/text.html', test_expectations.TIMEOUT), False) + rs.add(self.get_result('failures/expected/timeout.html'), True) + rs.add(self.get_result('failures/expected/crash.html', test_expectations.CRASH), True) err.reset() out.reset() - printer.print_progress(rs, False, test_files) + printer.print_progress(rs, False, paths) self.assertFalse(err.empty()) self.assertTrue(out.empty()) # We only clear the meter when retrying w/ detailed-progress. err.reset() out.reset() - printer.print_progress(rs, True, test_files) - self.assertEqual(err.get(), ['']) + printer.print_progress(rs, True, paths) + self.assertFalse(err.empty()) self.assertTrue(out.empty()) def test_write(self): @@ -416,42 +440,72 @@ class Testprinter(unittest.TestCase): printer.write("foo", "config") self.assertFalse(err.empty()) + # FIXME: this should be logged somewhere, but it actually + # disappears into the ether in the logging subsystem. + printer, err, out = self.get_printer(['--verbose']) + printer.write("foo") + self.assertTrue(err.empty()) + self.assertTrue(out.empty()) + def test_print_unexpected_results(self): # This routine is the only one that prints stuff that the bots # care about. + # + # FIXME: there's some weird layering going on here. It seems + # like we shouldn't be both using an expectations string and + # having to specify whether or not the result was expected. + # This whole set of tests should probably be rewritten. + # + # FIXME: Plus, the fact that we're having to call into + # run_webkit_tests is clearly a layering inversion. def get_unexpected_results(expected, passing, flaky): - rs, exp = get_result_summary(self._port, test_files, expectations) + """Return an unexpected results summary matching the input description. + + There are a lot of different combinations of test results that + can be tested; this routine produces various combinations based + on the values of the input flags. + + Args + expected: whether the tests ran as expected + passing: whether the tests should all pass + flaky: whether the tests should be flaky (if False, they + produce the same results on both runs; if True, they + all pass on the second run). + + """ + paths, rs, exp = self.get_result_summary(tests, expectations) if expected: - rs.add(get_result('pass/pass.html', test_expectations.PASS), + rs.add(self.get_result('passes/text.html', test_expectations.PASS), expected) - rs.add(get_result('pass/timeout.html', + rs.add(self.get_result('failures/expected/timeout.html', test_expectations.TIMEOUT), expected) - rs.add(get_result('fail/crash.html', test_expectations.CRASH), + rs.add(self.get_result('failures/expected/crash.html', test_expectations.CRASH), expected) elif passing: - rs.add(get_result('pass/pass.html'), expected) - rs.add(get_result('pass/timeout.html'), expected) - rs.add(get_result('fail/crash.html'), expected) + rs.add(self.get_result('passes/text.html'), expected) + rs.add(self.get_result('failures/expected/timeout.html'), expected) + rs.add(self.get_result('failures/expected/crash.html'), expected) else: - rs.add(get_result('pass/pass.html', test_expectations.TIMEOUT), + rs.add(self.get_result('passes/text.html', test_expectations.TIMEOUT), expected) - rs.add(get_result('pass/timeout.html', + rs.add(self.get_result('failures/expected/timeout.html', test_expectations.CRASH), expected) - rs.add(get_result('fail/crash.html', + rs.add(self.get_result('failures/expected/crash.html', test_expectations.TIMEOUT), expected) retry = rs if flaky: - retry, exp = get_result_summary(self._port, test_files, + paths, retry, exp = self.get_result_summary(tests, expectations) - retry.add(get_result('pass/pass.html'), True) - retry.add(get_result('pass/timeout.html'), True) - retry.add(get_result('fail/crash.html'), True) + retry.add(self.get_result('passes/text.html'), True) + retry.add(self.get_result('failures/expected/timeout.html'), True) + retry.add(self.get_result('failures/expected/crash.html'), True) unexpected_results = run_webkit_tests.summarize_unexpected_results( self._port, exp, rs, retry) return unexpected_results - test_files = ['pass/pass.html', 'pass/timeout.html', 'fail/crash.html'] + tests = ['passes/text.html', 'failures/expected/timeout.html', + 'failures/expected/crash.html'] expectations = '' printer, err, out = self.get_printer(['--print', 'nothing']) @@ -501,6 +555,33 @@ class Testprinter(unittest.TestCase): self.assertTrue(err.empty()) self.assertFalse(out.empty()) + expectations = """ +failures/expected/crash.html = CRASH +failures/expected/timeout.html = TIMEOUT +""" + err.reset() + out.reset() + ur = get_unexpected_results(expected=False, passing=False, flaky=False) + printer.print_unexpected_results(ur) + self.assertTrue(err.empty()) + self.assertFalse(out.empty()) + + err.reset() + out.reset() + ur = get_unexpected_results(expected=False, passing=True, flaky=False) + printer.print_unexpected_results(ur) + self.assertTrue(err.empty()) + self.assertFalse(out.empty()) + + # Test handling of --verbose as well. + err.reset() + out.reset() + printer, err, out = self.get_printer(['--verbose']) + ur = get_unexpected_results(expected=False, passing=False, flaky=False) + printer.print_unexpected_results(ur) + self.assertTrue(err.empty()) + self.assertFalse(out.empty()) + def test_print_unexpected_results_buildbot(self): # FIXME: Test that print_unexpected_results() produces the printer the # buildbot is expecting. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py index e154932..086321d 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py @@ -152,10 +152,7 @@ class TestExpectations: for item in TestExpectationsFile.EXPECTATIONS.items(): if item[1] == expectation: return item[0].upper() - return "" - - def get_timeline_for_test(self, test): - return self._expected_failures.get_timeline_for_test(test) + raise ValueError(expectation) def get_tests_with_result_type(self, result_type): return self._expected_failures.get_tests_with_result_type(result_type) @@ -208,15 +205,15 @@ class ModifiersAndExpectations: class ExpectationsJsonEncoder(simplejson.JSONEncoder): - """JSON encoder that can handle ModifiersAndExpectations objects. - """ - + """JSON encoder that can handle ModifiersAndExpectations objects.""" def default(self, obj): - if isinstance(obj, ModifiersAndExpectations): - return {"modifiers": obj.modifiers, - "expectations": obj.expectations} - else: - return JSONEncoder.default(self, obj) + # A ModifiersAndExpectations object has two fields, each of which + # is a dict. Since JSONEncoders handle all the builtin types directly, + # the only time this routine should be called is on the top level + # object (i.e., the encoder shouldn't recurse). + assert isinstance(obj, ModifiersAndExpectations) + return {"modifiers": obj.modifiers, + "expectations": obj.expectations} class TestExpectationsFile: @@ -463,9 +460,6 @@ class TestExpectationsFile: def get_non_fatal_errors(self): return self._non_fatal_errors - def contains(self, test): - return test in self._test_to_expectations - def remove_platform_from_expectations(self, tests, platform): """Returns a copy of the expectations with the tests matching the platform remove. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py index cf3c560..22214b0 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py @@ -33,16 +33,8 @@ import os import sys import unittest -try: - d = os.path.dirname(__file__) -except NameError: - d = os.path.dirname(sys.argv[0]) - -sys.path.append(os.path.abspath(os.path.join(d, '..'))) -sys.path.append(os.path.abspath(os.path.join(d, '../../thirdparty'))) - -import port -from test_expectations import * +from webkitpy.layout_tests import port +from webkitpy.layout_tests.layout_package.test_expectations import * class FunctionsTest(unittest.TestCase): def test_result_was_expected(self): @@ -87,8 +79,7 @@ class FunctionsTest(unittest.TestCase): set([PASS, CRASH])) -class TestExpectationsTest(unittest.TestCase): - +class Base(unittest.TestCase): def __init__(self, testFunc, setUp=None, tearDown=None, description=None): self._port = port.get('test', None) self._exp = None @@ -98,53 +89,151 @@ class TestExpectationsTest(unittest.TestCase): return os.path.join(self._port.layout_tests_dir(), test_name) def get_basic_tests(self): - return [self.get_test('text/article-element.html'), - self.get_test('image/canvas-bg.html'), - self.get_test('image/canvas-zoom.html'), - self.get_test('misc/crash.html'), - self.get_test('misc/passing.html')] + return [self.get_test('failures/expected/text.html'), + self.get_test('failures/expected/image_checksum.html'), + self.get_test('failures/expected/crash.html'), + self.get_test('failures/expected/missing_text.html'), + self.get_test('passes/text.html')] def get_basic_expectations(self): return """ -BUG_TEST : text/article-element.html = TEXT -BUG_TEST SKIP : misc/crash.html = CRASH -BUG_TEST REBASELINE : misc/missing-expectation.html = MISSING -BUG_TEST : image = IMAGE +BUG_TEST : failures/expected/text.html = TEXT +BUG_TEST SKIP : failures/expected/crash.html = CRASH +BUG_TEST REBASELINE : failure/expected/missing_image.html = MISSING +BUG_TEST : failures/expected/image_checksum.html = IMAGE """ - def parse_exp(self, expectations, overrides=None): + def parse_exp(self, expectations, overrides=None, is_lint_mode=False, + is_debug_mode=False, tests_are_present=True): self._exp = TestExpectations(self._port, tests=self.get_basic_tests(), expectations=expectations, test_platform_name=self._port.test_platform_name(), - is_debug_mode=False, - is_lint_mode=False, - tests_are_present=True, + is_debug_mode=is_debug_mode, + is_lint_mode=is_lint_mode, + tests_are_present=tests_are_present, overrides=overrides) def assert_exp(self, test, result): self.assertEquals(self._exp.get_expectations(self.get_test(test)), set([result])) + +class TestExpectationsTest(Base): def test_basic(self): self.parse_exp(self.get_basic_expectations()) - self.assert_exp('text/article-element.html', TEXT) - self.assert_exp('image/canvas-zoom.html', IMAGE) - self.assert_exp('misc/passing.html', PASS) + self.assert_exp('failures/expected/text.html', TEXT) + self.assert_exp('failures/expected/image_checksum.html', IMAGE) + self.assert_exp('passes/text.html', PASS) + + def test_defer(self): + self.parse_exp('BUGX DEFER : failures/expected/text.html = TEXT') + self.assertEqual(self._exp.get_options( + self.get_test('failures/expected/text.html')), ['bugx', 'defer']) + + def test_precedence(self): + # This tests handling precedence of specific lines over directories + # and tests expectations covering entire directories. + exp_str = """ +BUGX : failures/expected/text.html = TEXT +BUGX DEFER : failures/expected = IMAGE +""" + self.parse_exp(exp_str) + self.assert_exp('failures/expected/text.html', TEXT) + self.assert_exp('failures/expected/crash.html', IMAGE) + + self.parse_exp(exp_str, tests_are_present=False) + self.assert_exp('failures/expected/text.html', TEXT) + self.assert_exp('failures/expected/crash.html', IMAGE) + + def test_release_mode(self): + self.parse_exp('BUGX DEBUG : failures/expected/text.html = TEXT', + is_debug_mode=True) + self.assert_exp('failures/expected/text.html', TEXT) + self.parse_exp('BUGX RELEASE : failures/expected/text.html = TEXT', + is_debug_mode=True) + self.assert_exp('failures/expected/text.html', PASS) + self.parse_exp('BUGX DEBUG : failures/expected/text.html = TEXT', + is_debug_mode=False) + self.assert_exp('failures/expected/text.html', PASS) + self.parse_exp('BUGX RELEASE : failures/expected/text.html = TEXT', + is_debug_mode=False) + self.assert_exp('failures/expected/text.html', TEXT) + + def test_get_options(self): + self.parse_exp(self.get_basic_expectations()) + self.assertEqual(self._exp.get_options( + self.get_test('passes/text.html')), []) - def test_duplicates(self): + def test_expectations_json_for_all_platforms(self): + self.parse_exp(self.get_basic_expectations()) + json_str = self._exp.get_expectations_json_for_all_platforms() + # FIXME: test actual content? + self.assertTrue(json_str) + + def test_get_expectations_string(self): + self.parse_exp(self.get_basic_expectations()) + self.assertEquals(self._exp.get_expectations_string( + self.get_test('failures/expected/text.html')), + 'TEXT') + + def test_expectation_to_string(self): + # Normal cases are handled by other tests. + self.parse_exp(self.get_basic_expectations()) + self.assertRaises(ValueError, self._exp.expectation_to_string, + -1) + + def test_syntax_missing_expectation(self): + # This is missing the expectation. + self.assertRaises(SyntaxError, self.parse_exp, + 'BUG_TEST: failures/expected/text.html', + is_debug_mode=True) + + def test_syntax_invalid_option(self): + self.assertRaises(SyntaxError, self.parse_exp, + 'BUG_TEST FOO: failures/expected/text.html = PASS') + + def test_syntax_invalid_expectation(self): + # This is missing the expectation. + self.assertRaises(SyntaxError, self.parse_exp, + 'BUG_TEST: failures/expected/text.html = FOO') + + def test_syntax_missing_bugid(self): + # This should log a non-fatal error. + self.parse_exp('SLOW : failures/expected/text.html = TEXT') + self.assertEqual( + len(self._exp._expected_failures.get_non_fatal_errors()), 1) + + def test_semantic_slow_and_timeout(self): + # A test cannot be SLOW and expected to TIMEOUT. + self.assertRaises(SyntaxError, self.parse_exp, + 'BUG_TEST SLOW : failures/expected/timeout.html = TIMEOUT') + + def test_semantic_wontfix_defer(self): + # A test cannot be WONTFIX and DEFER. + self.assertRaises(SyntaxError, self.parse_exp, + 'BUG_TEST WONTFIX DEFER : failures/expected/text.html = TEXT') + + def test_semantic_rebaseline(self): + # Can't lint a file w/ 'REBASELINE' in it. + self.assertRaises(SyntaxError, self.parse_exp, + 'BUG_TEST REBASELINE : failures/expected/text.html = TEXT', + is_lint_mode=True) + + def test_semantic_duplicates(self): self.assertRaises(SyntaxError, self.parse_exp, """ -BUG_TEST : text/article-element.html = TEXT -BUG_TEST : text/article-element.html = IMAGE""") +BUG_TEST : failures/expected/text.html = TEXT +BUG_TEST : failures/expected/text.html = IMAGE""") + self.assertRaises(SyntaxError, self.parse_exp, self.get_basic_expectations(), """ -BUG_TEST : text/article-element.html = TEXT -BUG_TEST : text/article-element.html = IMAGE""") +BUG_TEST : failures/expected/text.html = TEXT +BUG_TEST : failures/expected/text.html = IMAGE""") def test_overrides(self): self.parse_exp(self.get_basic_expectations(), """ -BUG_OVERRIDE : text/article-element.html = IMAGE""") - self.assert_exp('text/article-element.html', IMAGE) +BUG_OVERRIDE : failures/expected/text.html = IMAGE""") + self.assert_exp('failures/expected/text.html', IMAGE) def test_matches_an_expected_result(self): @@ -153,16 +242,34 @@ BUG_OVERRIDE : text/article-element.html = IMAGE""") self.get_test(test), result, pixel_tests_enabled) self.parse_exp(self.get_basic_expectations()) - self.assertTrue(match('text/article-element.html', TEXT, True)) - self.assertTrue(match('text/article-element.html', TEXT, False)) - self.assertFalse(match('text/article-element.html', CRASH, True)) - self.assertFalse(match('text/article-element.html', CRASH, False)) + self.assertTrue(match('failures/expected/text.html', TEXT, True)) + self.assertTrue(match('failures/expected/text.html', TEXT, False)) + self.assertFalse(match('failures/expected/text.html', CRASH, True)) + self.assertFalse(match('failures/expected/text.html', CRASH, False)) + self.assertTrue(match('failures/expected/image_checksum.html', IMAGE, + True)) + self.assertTrue(match('failures/expected/image_checksum.html', PASS, + False)) + self.assertTrue(match('failures/expected/crash.html', SKIP, False)) + self.assertTrue(match('passes/text.html', PASS, False)) - self.assertTrue(match('image/canvas-bg.html', IMAGE, True)) - self.assertTrue(match('image/canvas-bg.html', PASS, False)) - self.assertTrue(match('misc/crash.html', SKIP, False)) - self.assertTrue(match('misc/passing.html', PASS, False)) +class RebaseliningTest(Base): + """Test rebaselining-specific functionality.""" + def test_no_get_rebaselining_failures(self): + self.parse_exp(self.get_basic_expectations()) + self.assertEqual(len(self._exp.get_rebaselining_failures()), 0) + + def test_basic(self): + self.parse_exp(""" +BUG_TEST REBASELINE : failures/expected/text.html = TEXT +""") + self.assertEqual(len(self._exp.get_rebaselining_failures()), 1) + + new_exp_str = self._exp.remove_platform_from_expectations( + self.get_test('failures/expected/text.html'), 'TEST') + # FIXME: actually test rebaselining + # self.assertEqual(new_exp_str, '\n') if __name__ == '__main__': unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py index 3be9240..340d075 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py @@ -73,11 +73,11 @@ class TestFailure(object): @staticmethod def message(): """Returns a string describing the failure in more detail.""" - raise NotImplemented + raise NotImplementedError def result_html_output(self, filename): """Returns an HTML string to be included on the results.html page.""" - raise NotImplemented + raise NotImplementedError def should_kill_dump_render_tree(self): """Returns True if we should kill DumpRenderTree before the next @@ -108,10 +108,8 @@ class FailureWithType(TestFailure): use the standard OutputLinks. """ - def __init__(self, test_type): + def __init__(self): TestFailure.__init__(self) - # FIXME: This class no longer needs to know the test_type. - self._test_type = test_type # Filename suffixes used by ResultHtmlOutput. OUT_FILENAMES = [] @@ -202,8 +200,8 @@ class FailureTextMismatch(FailureWithType): OUT_FILENAMES_WDIFF = ["-actual.txt", "-expected.txt", "-diff.txt", "-wdiff.html", "-pretty-diff.html"] - def __init__(self, test_type, has_wdiff): - FailureWithType.__init__(self, test_type) + def __init__(self, has_wdiff): + FailureWithType.__init__(self) if has_wdiff: self.OUT_FILENAMES = self.OUT_FILENAMES_WDIFF diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures_unittest.py new file mode 100644 index 0000000..92fe276 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures_unittest.py @@ -0,0 +1,68 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""""Tests code paths not covered by the regular unit tests.""" + +from webkitpy.layout_tests.layout_package.test_failures import * +import unittest + +class Test(unittest.TestCase): + def assertResultHtml(self, failure_obj): + self.assertNotEqual(failure_obj.result_html_output('foo'), None) + + def test_crash(self): + self.assertResultHtml(FailureCrash()) + + def test_hash_incorrect(self): + self.assertResultHtml(FailureImageHashIncorrect()) + + def test_missing(self): + self.assertResultHtml(FailureMissingResult()) + + def test_missing_image(self): + self.assertResultHtml(FailureMissingImage()) + + def test_missing_image_hash(self): + self.assertResultHtml(FailureMissingImageHash()) + + def test_timeout(self): + self.assertResultHtml(FailureTimeout()) + + def test_unknown_failure_type(self): + class UnknownFailure(TestFailure): + pass + + failure_obj = UnknownFailure() + self.assertRaises(ValueError, determine_result_type, [failure_obj]) + self.assertRaises(NotImplementedError, failure_obj.message) + self.assertRaises(NotImplementedError, failure_obj.result_html_output, + "foo.txt") + + +if __name__ == '__main__': + unittest.main() |