blob: 3f86e751c91a8bc8cf03a96a991c10dec3ba53f8 [file] [log] [blame]
#! /usr/bin/python
import sys
import os
import StringIO
import unittest
# Show DepricationWarnings come from buildbot - it isn't default with Python 2.7 or newer.
# See https://bugs.webkit.org/show_bug.cgi?id=90161 for details.
import warnings
warnings.simplefilter('default')
class BuildBotConfigLoader(object):
def _add_webkitpy_to_sys_path(self):
# When files are passed to the python interpreter on the command line (e.g. python test.py) __file__ is a relative path.
absolute_file_path = os.path.abspath(__file__)
webkit_org_config_dir = os.path.dirname(absolute_file_path)
build_slave_support_dir = os.path.dirname(webkit_org_config_dir)
webkit_tools_dir = os.path.dirname(build_slave_support_dir)
scripts_dir = os.path.join(webkit_tools_dir, 'Scripts')
sys.path.append(scripts_dir)
def _create_mock_passwords_dict(self):
config_dict = json.load(open('config.json'))
return dict([(slave['name'], '1234') for slave in config_dict['slaves']])
def _mock_open(self, filename):
if filename == 'passwords.json':
return StringIO.StringIO(json.dumps(self._create_mock_passwords_dict()))
return __builtins__.open(filename)
def _add_dependant_modules_to_sys_modules(self):
from webkitpy.thirdparty.autoinstalled import buildbot
sys.modules['buildbot'] = buildbot
def load_config(self, master_cfg_path):
# Before we can use webkitpy.thirdparty, we need to fix our path to include webkitpy.
# FIXME: If we're ever run by test-webkitpy we won't need this step.
self._add_webkitpy_to_sys_path()
# master.cfg expects the buildbot module to be in sys.path.
self._add_dependant_modules_to_sys_modules()
# master.cfg expects a passwords.json file which is not checked in. Fake it by mocking open().
globals()['open'] = self._mock_open
# Because the master_cfg_path may have '.' in its name, we can't just use import, we have to use execfile.
# We pass globals() as both the globals and locals to mimic exectuting in the global scope, so
# that globals defined in master.cfg will be global to this file too.
execfile(master_cfg_path, globals(), globals())
globals()['open'] = __builtins__.open # Stop mocking open().
class MasterCfgTest(unittest.TestCase):
def test_nrwt_leaks_parsing(self):
run_webkit_tests = RunWebKitTests() # pylint is confused by the way we import the module ... pylint: disable-msg=E0602
log_text = """
12:44:24.295 77706 13981 total leaks found for a total of 197,936 bytes!
12:44:24.295 77706 1 unique leaks found!
"""
expected_incorrect_lines = [
'13981 total leaks found for a total of 197,936 bytes!',
'1 unique leaks found!',
]
run_webkit_tests._parseNewRunWebKitTestsOutput(log_text)
self.assertEqual(run_webkit_tests.incorrectLayoutLines, expected_incorrect_lines)
def test_nrwt_missing_results(self):
run_webkit_tests = RunWebKitTests() # pylint is confused by the way we import the module ... pylint: disable-msg=E0602
log_text = """
Expected to fail, but passed: (2)
animations/additive-transform-animations.html
animations/cross-fade-webkit-mask-box-image.html
Unexpected flakiness: text-only failures (2)
fast/events/touch/touch-inside-iframe.html [ Failure Pass ]
http/tests/inspector-enabled/console-clear-arguments-on-frame-navigation.html [ Failure Pass ]
Unexpected flakiness: timeouts (1)
svg/text/foreignObject-repaint.xml [ Timeout Pass ]
Regressions: Unexpected missing results (1)
svg/custom/zero-path-square-cap-rendering2.svg [ Missing ]
Regressions: Unexpected text-only failures (1)
svg/custom/zero-path-square-cap-rendering2.svg [ Failure ]
"""
run_webkit_tests._parseNewRunWebKitTestsOutput(log_text)
self.assertEqual(set(run_webkit_tests.incorrectLayoutLines),
set(['2 new passes', '3 flakes', '1 missing results', '1 failures']))
class StubStdio(object):
def __init__(self, stdio):
self._stdio = stdio
def getText(self):
return self._stdio
class StubRemoteCommand(object):
def __init__(self, rc, stdio):
self.rc = rc
self.logs = {'stdio': StubStdio(stdio)}
class RunQtAPITestsTest(unittest.TestCase):
def assertResults(self, expected_result, expected_text, stdio):
rc = 0
cmd = StubRemoteCommand(rc, stdio)
step = RunQtAPITests()
step.commandComplete(cmd)
actual_results = step.evaluateCommand(cmd)
actual_text = str(step.getText2(cmd, actual_results)[0])
self.assertEqual(expected_result, actual_results)
self.assertEqual(actual_text, expected_text)
def test_timeout(self):
self.assertResults(FAILURE, "API tests", """INFO:Exec:Running... WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview
INFO:Exec:Running... WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests
Qml debugging is enabled. Only use this in a safe environment!
INFO:Exec:Finished WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview
ERROR:Exec:Timeout, process 'WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests' (2336) was terminated
INFO:Exec:Finished WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests
********* Start testing of tst_QQuickWebView *********
Config: Using QTest library 5.0.0, Qt 5.0.0
PASS : tst_QQuickWebView::initTestCase()
QWARN : tst_QQuickWebView::accessPage() QQuickCanvas: platform does not support threaded rendering!
.
.
.
**********************************************************************
** TOTALS: 16 passed, 0 failed, 0 skipped, 0 crashed **
**********************************************************************""")
def test_success(self):
self.assertResults(SUCCESS, "API tests", """INFO:Exec:Running... WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview
INFO:Exec:Running... WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests
Qml debugging is enabled. Only use this in a safe environment!
INFO:Exec:Finished WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview
********* Start testing of tst_QQuickWebView *********
Config: Using QTest library 5.0.0, Qt 5.0.0
PASS : tst_QQuickWebView::initTestCase()
QWARN : tst_QQuickWebView::accessPage() QQuickCanvas: platform does not support threaded rendering!
.
.
.
**********************************************************************
** TOTALS: 16 passed, 0 failed, 0 skipped, 0 crashed **
**********************************************************************""")
def test_failure(self):
self.assertResults(WARNINGS, "16 passed, 1 failed, 0 skipped, 0 crashed", """********* Start testing of tst_QDeclarativeWebView *********
PASS : tst_QDeclarativeWebView::pressGrabTime()
PASS : tst_QDeclarativeWebView::renderingEnabled()
PASS : tst_QDeclarativeWebView::setHtml()
PASS : tst_QDeclarativeWebView::settings()
FAIL! : tst_QDeclarativeWebView::backgroundColor() Compared values are not the same
Loc: [/ramdisk/qt-linux-release/build/Source/WebKit/qt/tests/qdeclarativewebview/tst_qdeclarativewebview.cpp(532)]
PASS : tst_QDeclarativeWebView::cleanupTestCase()
.
.
.
**********************************************************************
** TOTALS: 16 passed, 1 failed, 0 skipped, 0 crashed **
**********************************************************************""")
def test_timeout_and_failure(self):
self.assertResults(FAILURE, "Failure: timeout occured during testing", """INFO:Exec:Finished WebKitBuild/Release/Source/WebKit/qt/tests/benchmarks/painting/tst_painting
ERROR:Exec:Timeout, process 'WebKitBuild/Release/Source/WebKit/qt/tests/qwebpage/tst_qwebpage' (13000) was terminated
INFO:Exec:Finished WebKitBuild/Release/Source/WebKit/qt/tests/qwebpage/tst_qwebpage
********* Start testing of tst_Loading *********
Config: Using QTest library 4.8.0, Qt 4.8.0
PASS : tst_Loading::initTestCase()
QDEBUG : tst_Loading::load(amazon) loaded the Generic plugin
RESULT : tst_Loading::load():"amazon":
1,843 msecs per iteration (total: 1,843, iterations: 1)
RESULT : tst_Loading::load():"kde":
139 msecs per iteration (total: 139, iterations: 1)
RESULT : tst_Loading::load():"apple":
740 msecs per iteration (total: 740, iterations: 1)
PASS : tst_Loading::load()
PASS : tst_Loading::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped
********* Finished testing of tst_Loading *********
.
.
.
PASS : tst_QDeclarativeWebView::renderingEnabled()
PASS : tst_QDeclarativeWebView::setHtml()
PASS : tst_QDeclarativeWebView::settings()
FAIL! : tst_QDeclarativeWebView::backgroundColor() Compared values are not the same
Loc: [/ramdisk/qt-linux-release/build/Source/WebKit/qt/tests/qdeclarativewebview/tst_qdeclarativewebview.cpp(532)]
PASS : tst_QDeclarativeWebView::cleanupTestCase()
Totals: 16 passed, 3 failed, 1 skipped
.
.
.
**********************************************************************
** TOTALS: 73 passed, 3 failed, 1 skipped, 0 crashed **
**********************************************************************""")
def test_crash(self):
self.assertResults(FAILURE, "API tests", """********* Start testing of tst_QQuickWebView *********
Config: Using QTest library 5.0.0, Qt 5.0.0
PASS : tst_QQuickWebView::initTestCase()
PASS : tst_QQuickWebView::accessPage()
CRASHED: WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview
CRASHED: WebKitBuild/Release/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_hello
********* Start testing of tst_publicapi *********
Config: Using QTest library 5.0.0, Qt 5.0.0
PASS : tst_publicapi::initTestCase()
PASS : tst_publicapi::publicAPI()
PASS : tst_publicapi::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped
********* Finished testing of tst_publicapi *********
**********************************************************************
** TOTALS: 92 passed, 0 failed, 0 skipped, 2 crashed **
**********************************************************************""")
class RunUnitTestsTest(unittest.TestCase):
def assertFailures(self, expected_failure_count, stdio):
if expected_failure_count:
rc = 1
expected_results = FAILURE
expected_text = '{0} unit tests failed or timed out'.format(expected_failure_count)
else:
rc = 0
expected_results = SUCCESS
expected_text = 'run-api-tests'
cmd = StubRemoteCommand(rc, stdio)
step = RunUnitTests()
step.commandComplete(cmd)
actual_results = step.evaluateCommand(cmd)
actual_failure_count = step.failedTestCount
actual_text = step.getText(cmd, actual_results)[0]
self.assertEqual(expected_results, actual_results)
self.assertEqual(expected_failure_count, actual_failure_count)
self.assertEqual(expected_text, actual_text)
def test_no_failures_or_timeouts(self):
self.assertFailures(0, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from WebViewDestructionWithHostWindow
[ RUN ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[ OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
[----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (127 ms total)
[ PASSED ] 1 test.
""")
def test_one_failure(self):
self.assertFailures(1, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from WebViewDestructionWithHostWindow
[ RUN ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[ OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
[----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (127 ms total)
[ PASSED ] 1 test.
Tests that failed:
WebKit2.WebKit2.CanHandleRequest
""")
def test_multiple_failures(self):
self.assertFailures(4, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from WebViewDestructionWithHostWindow
[ RUN ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[ OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
[----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (127 ms total)
[ PASSED ] 1 test.
Tests that failed:
WebKit2.WebKit2.CanHandleRequest
WebKit2.WebKit2.DocumentStartUserScriptAlertCrashTest
WebKit2.WebKit2.HitTestResultNodeHandle
WebKit2.WebKit2.InjectedBundleBasic
""")
def test_one_timeout(self):
self.assertFailures(1, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from WebViewDestructionWithHostWindow
[ RUN ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[ OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
[----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (127 ms total)
[ PASSED ] 1 test.
Tests that timed out:
WebKit2.WebKit2.CanHandleRequest
""")
def test_multiple_timeouts(self):
self.assertFailures(4, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from WebViewDestructionWithHostWindow
[ RUN ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[ OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
[----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (127 ms total)
[ PASSED ] 1 test.
Tests that timed out:
WebKit2.WebKit2.CanHandleRequest
WebKit2.WebKit2.DocumentStartUserScriptAlertCrashTest
WebKit2.WebKit2.HitTestResultNodeHandle
WebKit2.WebKit2.InjectedBundleBasic
""")
def test_multiple_failures_and_timeouts(self):
self.assertFailures(8, """Note: Google Test filter = WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from WebViewDestructionWithHostWindow
[ RUN ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose
[ OK ] WebViewDestructionWithHostWindow.DestroyViewWindowWithoutClose (127 ms)
[----------] 1 test from WebViewDestructionWithHostWindow (127 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (127 ms total)
[ PASSED ] 1 test.
Tests that failed:
WebKit2.WebKit2.CanHandleRequest
WebKit2.WebKit2.DocumentStartUserScriptAlertCrashTest
WebKit2.WebKit2.HitTestResultNodeHandle
Tests that timed out:
WebKit2.WebKit2.InjectedBundleBasic
WebKit2.WebKit2.LoadCanceledNoServerRedirectCallback
WebKit2.WebKit2.MouseMoveAfterCrash
WebKit2.WebKit2.ResponsivenessTimerDoesntFireEarly
WebKit2.WebKit2.WebArchive
""")
class SVNMirrorTest(unittest.TestCase):
def setUp(self):
self.config = json.load(open('config.json'))
def get_SVNMirrorFromConfig(self, builderName):
SVNMirror = None
for builder in self.config['builders']:
if builder['name'] == builderName:
SVNMirror = builder.pop('SVNMirror', 'http://svn.webkit.org/repository/webkit/')
return SVNMirror
def test_CheckOutSource(self):
# SVN mirror feature isn't unittestable now with source.oldsource.SVN(==source.SVN) , only with source.svn.SVN(==SVN)
# https://bugs.webkit.org/show_bug.cgi?id=85887
if issubclass(CheckOutSource, source.SVN):
return
# Compare CheckOutSource.baseURL with SVNMirror (or with the default URL) in config.json for all builders
for builder in c['builders']:
for buildStepFactory, kwargs in builder['factory'].steps:
if str(buildStepFactory).split('.')[-1] == 'CheckOutSource':
CheckOutSourceInstance = buildStepFactory(**kwargs)
self.assertEqual(CheckOutSourceInstance.baseURL, self.get_SVNMirrorFromConfig(builder['name']))
class BuildStepsConstructorTest(unittest.TestCase):
# "Passing a BuildStep subclass to factory.addStep is deprecated. Please pass a BuildStep instance instead. Support will be dropped in v0.8.7."
# It checks if all builder's all buildsteps can be insantiated after migration.
# https://bugs.webkit.org/show_bug.cgi?id=89001
# http://buildbot.net/buildbot/docs/0.8.6p1/manual/customization.html#writing-buildstep-constructors
@staticmethod
def generateTests():
for builderNumber, builder in enumerate(c['builders']):
for stepNumber, step in enumerate(builder['factory'].steps):
builderName = builder['name'].encode('ascii', 'ignore')
setattr(BuildStepsConstructorTest, 'test_builder%02d_step%02d' % (builderNumber, stepNumber), BuildStepsConstructorTest.createTest(builderName, step))
@staticmethod
def createTest(builderName, step):
def doTest(self):
try:
buildStepFactory, kwargs = step
buildStepFactory(**kwargs)
except TypeError as e:
buildStepName = str(buildStepFactory).split('.')[-1]
self.fail("Error during instantiation %s buildstep for %s builder: %s\n" % (buildStepName, builderName, e))
return doTest
# FIXME: We should run this file as part of test-webkitpy.
# Unfortunately test-webkitpy currently requires that unittests
# be located in a directory with a valid module name.
# 'build.webkit.org-config' is not a valid module name (due to '.' and '-')
# so for now this is a stand-alone test harness.
if __name__ == '__main__':
BuildBotConfigLoader().load_config('master.cfg')
BuildStepsConstructorTest.generateTests()
unittest.main()