summaryrefslogtreecommitdiffstats
path: root/WebKitTools
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-08-19 17:55:56 +0100
committerIain Merrick <husky@google.com>2010-08-23 11:05:40 +0100
commitf486d19d62f1bc33246748b14b14a9dfa617b57f (patch)
tree195485454c93125455a30e553a73981c3816144d /WebKitTools
parent6ba0b43722d16bc295606bec39f396f596e4fef1 (diff)
downloadexternal_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.zip
external_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.tar.gz
external_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.tar.bz2
Merge WebKit at r65615 : Initial merge by git.
Change-Id: Ifbf384f4531e3b58475a662e38195c2d9152ae79
Diffstat (limited to 'WebKitTools')
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json10
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg11
-rw-r--r--WebKitTools/ChangeLog872
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.cpp16
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.h2
-rw-r--r--WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp5
-rw-r--r--WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h1
-rw-r--r--WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp40
-rw-r--r--WebKitTools/DumpRenderTree/chromium/LayoutTestController.h4
-rw-r--r--WebKitTools/DumpRenderTree/chromium/MockSpellCheck.cpp11
-rw-r--r--WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp13
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShell.cpp2
-rw-r--r--WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp21
-rw-r--r--WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm10
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp2
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp14
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h2
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp9
-rw-r--r--WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp18
-rw-r--r--WebKitTools/DumpRenderTree/wscript4
-rw-r--r--WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp10
-rw-r--r--WebKitTools/MiniBrowser/mac/BrowserWindowController.m3
-rw-r--r--WebKitTools/MiniBrowser/win/BrowserView.cpp3
-rw-r--r--WebKitTools/QtTestBrowser/launcherwindow.cpp33
-rw-r--r--WebKitTools/QtTestBrowser/launcherwindow.h5
-rw-r--r--WebKitTools/QtTestBrowser/mainwindow.cpp4
-rw-r--r--WebKitTools/QtTestBrowser/webview.cpp59
-rw-r--r--WebKitTools/QtTestBrowser/webview.h4
-rwxr-xr-xWebKitTools/Scripts/build-webkit23
-rwxr-xr-xWebKitTools/Scripts/commit-log-editor51
-rwxr-xr-xWebKitTools/Scripts/create-html-entity-table183
-rw-r--r--WebKitTools/Scripts/deduplicate-tests84
-rwxr-xr-xWebKitTools/Scripts/old-run-webkit-tests71
-rwxr-xr-xWebKitTools/Scripts/prepare-ChangeLog11
-rwxr-xr-xWebKitTools/Scripts/webkit-patch6
-rw-r--r--WebKitTools/Scripts/webkitdirs.pm25
-rw-r--r--WebKitTools/Scripts/webkitpy/common/checkout/scm.py34
-rw-r--r--WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py55
-rw-r--r--WebKitTools/Scripts/webkitpy/common/config/committers.py9
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests.py167
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py147
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py90
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py4
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py93
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py6
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py9
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py4
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py74
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py46
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/test.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py14
-rwxr-xr-xWebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py142
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py113
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py71
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py6
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py22
-rw-r--r--WebKitTools/Scripts/webkitpy/style/checker.py15
-rw-r--r--WebKitTools/Scripts/webkitpy/style/checkers/common.py19
-rw-r--r--WebKitTools/Scripts/webkitpy/style/checkers/common_unittest.py32
-rw-r--r--WebKitTools/Scripts/webkitpy/style/checkers/test_expectations.py124
-rw-r--r--WebKitTools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py172
-rw-r--r--WebKitTools/Scripts/webkitpy/style/checkers/text.py11
-rw-r--r--WebKitTools/Scripts/webkitpy/style_references.py2
-rw-r--r--WebKitTools/Scripts/webkitpy/thirdparty/simplejson/decoder.py2
-rwxr-xr-xWebKitTools/Scripts/webkitpy/tool/main.py14
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/steps/runtests.py1
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py2
-rw-r--r--WebKitTools/TestResultServer/handlers/testfilehandler.py31
-rwxr-xr-xWebKitTools/TestResultServer/model/jsonresults.py127
-rwxr-xr-xWebKitTools/TestResultServer/model/jsonresults_unittest.py127
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp33
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h10
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp72
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h1
-rw-r--r--WebKitTools/WebKitTestRunner/PlatformWebView.h1
-rw-r--r--WebKitTools/WebKitTestRunner/StringFunctions.h10
-rw-r--r--WebKitTools/WebKitTestRunner/TestController.cpp81
-rw-r--r--WebKitTools/WebKitTestRunner/TestController.h19
-rw-r--r--WebKitTools/WebKitTestRunner/TestInvocation.cpp15
-rw-r--r--WebKitTools/WebKitTestRunner/TestInvocation.h5
-rw-r--r--WebKitTools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj4
-rw-r--r--WebKitTools/WebKitTestRunner/mac/PlatformWebViewMac.mm5
-rw-r--r--WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm10
-rw-r--r--WebKitTools/WebKitTestRunner/mac/TestInvocationMac.mm36
-rw-r--r--WebKitTools/WebKitTestRunner/win/PlatformWebViewWin.cpp7
-rw-r--r--WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp28
-rw-r--r--WebKitTools/WebKitTestRunner/win/TestInvocationWin.cpp42
-rw-r--r--WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj4
-rw-r--r--WebKitTools/gdb/webcore.py171
-rw-r--r--WebKitTools/gdb/webkit.py272
-rw-r--r--WebKitTools/gdb/wtf.py133
-rw-r--r--WebKitTools/wx/browser/wscript4
-rw-r--r--WebKitTools/wx/build/settings.py123
-rw-r--r--WebKitTools/wx/build/waf_extensions.py7
98 files changed, 3623 insertions, 912 deletions
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json
index eda05f1..49d770d 100644
--- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json
@@ -8,6 +8,7 @@
{ "name": "apple-xserve-4", "platform": "mac-snowleopard" },
{ "name": "apple-xserve-5", "platform": "mac-snowleopard" },
{ "name": "apple-xserve-6", "platform": "mac-snowleopard" },
+ { "name": "apple-xserve-7", "platform": "mac-snowleopard" },
{ "name": "apple-pixel-1", "platform": "mac-leopard" },
@@ -66,7 +67,7 @@
},
{ "name": "SnowLeopard Intel Release (Build)", "type": "Build", "builddir": "snowleopard-intel-release",
"platform": "mac-snowleopard", "configuration": "release", "architectures": ["x86_64"],
- "triggers": ["snowleopard-intel-release-tests"],
+ "triggers": ["snowleopard-intel-release-tests", "snowleopard-intel-release-tests-wk2"],
"slavenames": ["apple-xserve-4", "test-slave"]
},
{ "name": "SnowLeopard Intel Release (Tests)", "type": "Test", "builddir": "snowleopard-intel-release-tests",
@@ -77,6 +78,10 @@
"platform": "mac-snowleopard", "configuration": "debug", "architectures": ["x86_64"],
"slavenames": ["apple-macpro-1", "apple-macpro-3", "test-slave"]
},
+ { "name": "SnowLeopard Intel Release (WebKit2 Tests)", "type": "TestWebKit2", "builddir": "snowleopard-intel-release-tests-wk2",
+ "platform": "mac-snowleopard", "configuration": "release", "architectures": ["x86_64"],
+ "slavenames": ["apple-xserve-7", "test-slave"]
+ },
{
"name": "Windows Release (Build)", "type": "Build", "builddir": "win-release",
"platform": "win", "configuration": "release", "architectures": ["i386"],
@@ -205,6 +210,9 @@
{ "type": "Triggerable", "name": "snowleopard-intel-release-tests",
"builderNames": ["SnowLeopard Intel Release (Tests)"]
},
+ { "type": "Triggerable", "name": "snowleopard-intel-release-tests-wk2",
+ "builderNames": ["SnowLeopard Intel Release (WebKit2 Tests)"]
+ },
{ "type": "Triggerable", "name": "win-release-tests",
"builderNames": ["Windows Release (Tests)"]
},
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
index 5ff4681..acedbd2 100644
--- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
@@ -247,6 +247,9 @@ class RunWebKitTests(shell.Test):
class NewRunWebKitTests(RunWebKitTests):
command = ["python", "./WebKitTools/Scripts/new-run-webkit-tests", "--noshow-results",
"--verbose", "--results-directory", "layout-test-results",
+ "--builder-name", WithProperties("%(buildername)s"),
+ "--build-number", WithProperties("%(buildnumber)s"),
+ "--test-results-server", "test-results.appspot.com",
WithProperties("--%(configuration)s"), "--use-drt"]
@@ -306,6 +309,12 @@ class RunWebKitLeakTests(RunWebKitTests):
return RunWebKitTests.start(self)
+class RunWebKit2Tests(RunWebKitTests):
+ def start(self):
+ self.setCommand(self.command + ["--webkit-test-runner"])
+ return RunWebKitTests.start(self)
+
+
class ArchiveTestResults(shell.ShellCommand):
command = ["python", "./WebKitTools/BuildSlaveSupport/test-result-archive",
WithProperties("--platform=%(platform)s"), WithProperties("--%(configuration)s"), "archive"]
@@ -405,6 +414,8 @@ class BuildAndTestLeaksFactory(BuildAndTestFactory):
class NewBuildAndTestFactory(BuildAndTestFactory):
TestClass = NewRunWebKitTests
+class TestWebKit2Factory(TestFactory):
+ TestClass = RunWebKit2Tests
def loadBuilderConfig(c):
# FIXME: These file handles are leaked.
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index e911169..324c32d 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,875 @@
+2010-08-18 Adam Roben <aroben@apple.com>
+
+ Fix hang when saving crash logs on Windows
+
+ * Scripts/old-run-webkit-tests:
+ (setUpWindowsCrashLogSaving):
+ (END):
+ Pass -s to regtool so it will write the Auto value as a string instead
+ of as a number. This was causing a "do you want to debug?" dialog to
+ appear.
+
+2010-08-17 Victor Wang <victorw@chromium.org>
+
+ Unreviewed. Fixed chromium incremental test json upload.
+ Quote builder name and test results server in url.
+
+ * Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py:
+
+2010-08-17 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] [Symbian] Consistently use Q_OS_SYMBIAN to guard all Symbian platform dependencies
+ https://bugs.webkit.org/show_bug.cgi?id=44124
+
+ Q_WS_S60 is not defined for Symbian^4 devices as Q_WS_S60 used to guard
+ Avkon UI framework dependencies. Use Q_OS_SYMBIAN everywhere to mark
+ Symbian dependencies.
+
+ * DumpRenderTree/qt/DumpRenderTreeQt.cpp:
+ (WebCore::DumpRenderTree::open):
+ * QtTestBrowser/launcherwindow.cpp:
+ (LauncherWindow::init):
+ (LauncherWindow::toggleFullScreenMode):
+ (LauncherWindow::showFPS):
+ (LauncherWindow::updateFPS):
+ * QtTestBrowser/launcherwindow.h:
+ (WindowOptions::WindowOptions):
+ * QtTestBrowser/mainwindow.cpp:
+ (MainWindow::buildUI):
+
+2010-08-17 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by David Levin.
+
+ new-run-webkit-tests: remove --show-sources option
+
+ --show-sources is pretty much obsolete with --trace everything, so
+ I'm removing it.
+
+ Also rename a couple of methods in the TestTextDiff class to make their
+ intended visibility (private) more obvious.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44143
+
+ * Scripts/webkitpy/layout_tests/layout_package/printing.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/test_types/image_diff.py:
+ * Scripts/webkitpy/layout_tests/test_types/test_type_base.py:
+ * Scripts/webkitpy/layout_tests/test_types/text_diff.py:
+
+2010-08-17 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by David Levin.
+
+ remove --fuzzy-image-diff in new-run-webkit-tests (it doesn't work)
+
+ This code bit-rotted at some point more than a year ago, and nobody seems
+ to miss it. old-run-webkit-tests has a --tolerance flag that new-run-webkit-tests
+ should support instead, making this flag unnecessary anyway.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44141
+
+ * Scripts/webkitpy/layout_tests/layout_package/test_failures.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py: Removed.
+
+2010-08-17 Victor Wang <victorw@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ Update json results generator to have incremental json including
+ results for tests that pass in current run but failed before.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44119
+
+ * Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py:
+ * Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+
+2010-08-17 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ fix test-webkitpy, add easy way to find a checkout root
+
+ test-webkitpy currently doesn't work right if run from someplace other
+ than the checkout root, and it spews a bunch of debug logging because
+ the deduplicate_tests tests contaminates the test environment.
+
+ This patch cleans up the deduplicate_tests unit tests, and creates
+ two new methods in scm.py: find_checkout_root() and default_scm(),
+ both of which use a single algorithm for guessing what checkout root
+ to use if you aren't explicitly told one from a path.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44001
+
+ * Scripts/deduplicate-tests:
+ * Scripts/webkitpy/common/checkout/scm.py:
+ * Scripts/webkitpy/common/checkout/scm_unittest.py:
+ * Scripts/webkitpy/layout_tests/deduplicate_tests.py:
+ * Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/test.py:
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py:
+ * Scripts/webkitpy/tool/main.py:
+
+2010-08-17 Victor Wang <victorw@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ Add support to the test results server for downloading json that
+ contains test list only.
+
+ This is for json results generator to generate incremental json
+ results so that it includes results not only for tests failed in
+ current run, but also tests failed before.
+
+ Also set the results type to "N" (no data) instead of "P" (pass)
+ if test results cannot be found in incremental json file.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44117
+
+ * TestResultServer/handlers/testfilehandler.py:
+ * TestResultServer/model/jsonresults.py:
+ * TestResultServer/model/jsonresults_unittest.py:
+
+2010-08-17 Adam Roben <aroben@apple.com>
+
+ Use the right path style
+
+ * Scripts/old-run-webkit-tests:
+
+2010-08-17 Adam Roben <aroben@apple.com>
+
+ Fix typo
+
+ * Scripts/old-run-webkit-tests:
+
+2010-08-17 Adam Roben <aroben@apple.com>
+
+ Don't hang when running run-webkit-tests as a non-Administrator on
+ Vista/7
+
+ * Scripts/old-run-webkit-tests:
+ (setUpWindowsCrashLogSaving): Use regtool to set NTSD as the
+ post-mortem debugger, rather than using NTSD itself. The latter waits
+ for user input when it fails to set the registry values; the former
+ does not.
+
+2010-08-17 Adam Roben <aroben@apple.com>
+
+ Teach run-webkit-tests, DumpRenderTree, and WebKitTestRunner how to
+ save crash logs on Windows
+
+ The crash logs are saved to /tmp/layout-test-results and have names
+ like CrashLog_02bc_2010-08-17_14-36-20-108.txt.
+
+ Unfortunately, crashes in the WebKit2 web process are recorded as
+ time-outs by run-webkit-tests. Fixing this is covered by
+ <http://webkit.org/b/44121>.
+
+ Fixes <http://webkit.org/b/37859> <rdar://problem/7883560>
+ DumpRenderTree should save a stack trace and/or dump file when it
+ crashes
+
+ Reviewed by Sam Weinig.
+
+ * DumpRenderTree/win/DumpRenderTree.cpp:
+ (exceptionFilter):
+ (main):
+ * WebKitTestRunner/win/TestControllerWin.cpp:
+ (WTR::exceptionFilter):
+ (WTR::TestController::platformInitialize):
+ These changes set up an exception filter that prints #CRASHED to
+ stderr, then lets the exception propagate normally. This allows
+ run-webkit-tests to detect when we've crashed even when a post-mortem
+ debugger attaches to the process.
+
+ * Scripts/old-run-webkit-tests:
+ (top level): Declared some variables used by the crash-log-saving
+ code.
+ (openDumpTool): Copy _NT_SYMBOL_PATH into the clean environment so
+ that the post-mortem debugger has access to it.
+ (toCygwinPath): Added. This is the opposite of toWindowsPath.
+ (readFromDumpToolWithTimer): If the dump tool prints #CRASHED to
+ stderr, consider it a crash.
+ (setUpWindowsCrashLogSaving): Added. Saves the current post-mortem
+ debugger, then sets ntsd as the post-mortem debugger. ntsd is
+ configured to save a crash log and then quit automatically.
+ (END): Added. Restores the previous post-mortem debugger when the
+ script exits.
+
+2010-08-17 Victor Wang <victorw@chromium.org>
+
+ Reviewed by ojan@chromium.org.
+
+ Update test results server:
+ 1. Normalize test results and times after merging (prune tests where
+ all runs pass or do not have data, truncate all test items to max
+ number of builds)
+ 2. times should be int not string.
+ 3. when inserting a new test item, should keep old data regardless
+ whether or not they have same item type with new one.
+
+ https://bugs.webkit.org/show_bug.cgi?id=43861
+
+ * TestResultServer/model/jsonresults.py:
+ * TestResultServer/model/jsonresults_unittest.py:
+
+2010-08-16 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ Add WebKit2 Mac tester to buildbot.
+
+ * BuildSlaveSupport/build.webkit.org-config/config.json:
+ * BuildSlaveSupport/build.webkit.org-config/master.cfg:
+
+2010-08-16 Paul Sawaya <psawaya@apple.com>
+
+ Reviewed by Chris Marrin.
+
+ Added shader validation via ANGLE
+ https://bugs.webkit.org/show_bug.cgi?id=42405
+
+ Added ANGLE to webkit build
+
+ * Scripts/build-webkit:
+
+2010-08-16 Kevin Ollivier <kevino@theolliviers.com>
+
+ [wx] Build fix, do not build WebCore as a convenience library as this leads to
+ errors in the Win build w/export symbols and causes problems with DOM bindings
+ debugging in gdb.
+
+ * DumpRenderTree/wscript:
+ * Scripts/build-webkit:
+ * wx/browser/wscript:
+ * wx/build/settings.py:
+ * wx/build/waf_extensions.py:
+
+2010-08-16 Dan Bernstein <mitz@apple.com>
+
+ Build fix.
+
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::createOtherPage): Initialize the contentsSizeChanged member.
+ (WTR::TestController::initialize): Ditto.
+
+2010-08-16 Balazs Kelemen <kb@inf.u-szeged.hu>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Handle content size change in WebKit2
+ Re-landing after fix.
+
+ https://bugs.webkit.org/show_bug.cgi?id=43198
+
+ * MiniBrowser/mac/BrowserWindowController.m:
+ (-[BrowserWindowController awakeFromNib]): Initialize WKPageUICallback::contetsSizeChanged to 0.
+ * MiniBrowser/win/BrowserView.cpp:
+ (BrowserView::create): Initialize WKPageUICallback::contetsSizeChanged to 0.
+
+2010-08-16 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r65419.
+ http://trac.webkit.org/changeset/65419
+ https://bugs.webkit.org/show_bug.cgi?id=44053
+
+ Broke the Windows build (Requested by bbandix on #webkit).
+
+ * MiniBrowser/mac/BrowserWindowController.m:
+ (-[BrowserWindowController awakeFromNib]):
+ * MiniBrowser/win/BrowserView.cpp:
+ (BrowserView::create):
+
+2010-08-16 Balazs Kelemen <kb@inf.u-szeged.hu>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Handle content size change in WebKit2
+
+ https://bugs.webkit.org/show_bug.cgi?id=43198
+
+ * MiniBrowser/mac/BrowserWindowController.m:
+ (-[BrowserWindowController awakeFromNib]): Initialize WKPageUICallback::contetsSizeChanged to 0.
+ * MiniBrowser/win/BrowserView.cpp:
+ (BrowserView::create): Initialize WKPageUICallback::contetsSizeChanged to 0.
+
+2010-08-16 Ariya Hidayat <ariya@sencha.com>
+
+ Add my new email address to committers.py.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-08-16 Zoltan Horvath <zoltan@webkit.org>
+
+ Add my old e-mail addresses to committers.py.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-08-15 Jon Honeycutt <jhoneycutt@apple.com>
+
+ WebEditorClient::didBeginEditing is never called in WebKit2
+ https://bugs.webkit.org/show_bug.cgi?id=42939
+
+ Reviewed by Sam Weinig.
+
+ * WebKitTestRunner/PlatformWebView.h:
+ Declare focus().
+
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::resetStateToConsistentValues):
+ Focus the PlatformWebView.
+
+ * WebKitTestRunner/mac/PlatformWebViewMac.mm:
+ (WTR::PlatformWebView::focus):
+ Stubbed.
+
+ * WebKitTestRunner/win/PlatformWebViewWin.cpp:
+ (WTR::PlatformWebView::focus):
+ Focus the view.
+
+2010-08-15 Jon Honeycutt <jhoneycutt@apple.com>
+
+ run-webkit-tests should not strip editing callbacks when using
+ WebKitTestRunner on Windows
+ https://bugs.webkit.org/show_bug.cgi?id=44000
+
+ Reviewed by Mark Rowe.
+
+ * Scripts/old-run-webkit-tests:
+ Leave $stripEditingCallbacks undefined until we look for command-line
+ arguments. If using WebKit2, set it to 0 if not explicity set on the
+ command line. Later, set it to isCygwin() to match old behavior if it is
+ not yet defined.
+
+2010-08-15 Kevin Ollivier <kevino@theolliviers.com>
+
+ [wx] Build fix, remove define always set to the correct value by wtf/Platform.h.
+
+ * wx/build/settings.py:
+
+2010-08-14 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [GTK] autogen.sh not executed if build-webkit options change
+ https://bugs.webkit.org/show_bug.cgi?id=42266
+
+ Rerun autogen.sh in situations where the arguments to build-webkit have
+ changed since the previous build. This will fix some issues on the bots
+ where the build does not notice changes to default build-webkit arguments.
+
+ * Scripts/webkitdirs.pm: Add special logic for detecting changes to build-webkit arguments.
+
+2010-08-14 Eric Seidel <eric@webkit.org>
+
+ Unreviewed. Another fix to support python 2.3.
+
+ Add support for MathML entities
+ https://bugs.webkit.org/show_bug.cgi?id=43949
+
+ * Scripts/webkitpy/thirdparty/simplejson/decoder.py:
+ - It looks like our simplejson is version 1.7.3 which
+ should be python 2.3 compatible. But someone modified
+ our copy slightly from the original source.
+ I've removed the relative import in hopes this fixes
+ the problem.
+
+2010-08-13 Eric Seidel <eric@webkit.org>
+
+ Unreviewed. Build fix only.
+
+ Add support for MathML entities
+ https://bugs.webkit.org/show_bug.cgi?id=43949
+
+ * Scripts/create-html-entity-table:
+ - Hack sys.path to avoid executing 2.5 dependent python
+ on systems (like chromium-win and Tiger) which do not have 2.5 python.
+
+2010-08-13 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Rename some concepts in HTML entity search to be more self-documenting
+ https://bugs.webkit.org/show_bug.cgi?id=44004
+
+ Reflect name change in generator script.
+
+ * Scripts/create-html-entity-table:
+
+2010-08-12 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Add support for MathML entities
+ https://bugs.webkit.org/show_bug.cgi?id=43949
+
+ A script for generating the C++ state data structure describing all the
+ entities from a JSON description.
+
+ * Scripts/create-html-entity-table: Added.
+
+2010-08-13 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Rewrite new-run-webkit-test's wait_for_threads_to_finish loop to
+ check for exceptions on all threads, not just the first thread.
+
+ This change also changes the logging behavior for wedged threads
+ to only dump the stacks of threads that are actually wedged.
+
+ Refactor the thread classes in the dump_render_tree_thread module
+ to make the contract between TestRunner and TestShellThread clearer.
+
+ Added a bunch of unit tests.
+ https://bugs.webkit.org/show_bug.cgi?id=38561
+
+ * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py:
+
+2010-08-13 Kenichi Ishibashi <bashi@google.com>
+
+ Reviewed by Shinichiro Hamaji.
+
+ Add test_expectations.txt syntax checker to check-webkit-style.
+ https://bugs.webkit.org/show_bug.cgi?id=43899
+
+ Just utilizing layout_tests/layout_package/test_expectations.py for checking
+ the syntax of test_expectations.txt.
+ This change also moves tab checking class from style/checkers/text.py to
+ style/checkers/common.py for sharing code.
+
+ * Scripts/webkitpy/layout_tests/layout_package/test_expectations.py:
+ * Scripts/webkitpy/style/checker.py:
+ * Scripts/webkitpy/style/checkers/common.py:
+ * Scripts/webkitpy/style/checkers/common_unittest.py:
+ * Scripts/webkitpy/style/checkers/test_expectations.py: Added.
+ * Scripts/webkitpy/style/checkers/test_expectations_unittest.py: Added.
+ * Scripts/webkitpy/style/checkers/text.py:
+ * Scripts/webkitpy/style_references.py:
+
+2010-08-12 Jon Honeycutt <jhoneycutt@apple.com>
+
+ WebKitTestRunner does not correctly resize WebView for W3C SVG tests
+ https://bugs.webkit.org/show_bug.cgi?id=43945
+
+ Reviewed by Sam Weinig.
+
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::sizeWebViewForCurrentTest):
+ Allow for a Windows-style path.
+
+ * WebKitTestRunner/win/PlatformWebViewWin.cpp:
+ (WTR::PlatformWebView::resizeTo):
+ Call SetWindowPos to resize the view window.
+
+2010-08-12 David Levin <levin@chromium.org>
+
+ Build break fix.
+
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::resetStateToConsistentValues): Removed usage
+ of a variable that doesn't exist in the class.
+
+2010-08-12 Jon Honeycutt <jhoneycutt@apple.com>
+
+ WebKitTestRunner needs to run tests without using native controls
+ https://bugs.webkit.org/show_bug.cgi?id=43772
+
+ Reviewed by Sam Weinig.
+
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::initialize):
+ Call platformInitializeContext().
+
+ * WebKitTestRunner/TestController.h:
+ Declare platformInitializeContext().
+
+ * WebKitTestRunner/mac/TestControllerMac.mm:
+ (WTR::TestController::platformInitializeContext):
+ Stubbed.
+
+ * WebKitTestRunner/win/TestControllerWin.cpp:
+ (WTR::TestController::platformInitializeContext):
+ Call WKContextSetShouldPaintNativeControls() to disable native control
+ drawing.
+
+2010-08-12 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ WebKitTestRunner should be more aggressive about ensuring consistent state between tests
+ https://bugs.webkit.org/show_bug.cgi?id=43653
+
+ * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+ (WTR::InjectedBundle::InjectedBundle):
+ (WTR::InjectedBundle::didReceiveMessage):
+ (WTR::InjectedBundle::beginTesting):
+ (WTR::InjectedBundle::done):
+ * WebKitTestRunner/InjectedBundle/InjectedBundle.h:
+ (WTR::InjectedBundle::isTestRunning):
+ (WTR::InjectedBundle::):
+ * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+ (WTR::InjectedBundlePage::stopLoading):
+ (WTR::InjectedBundlePage::didStartProvisionalLoadForFrame):
+ (WTR::InjectedBundlePage::dump):
+ (WTR::InjectedBundlePage::didFinishLoadForFrame):
+ (WTR::InjectedBundlePage::didFailLoadWithErrorForFrame):
+ (WTR::InjectedBundlePage::didReceiveTitleForFrame):
+ (WTR::InjectedBundlePage::didClearWindowForFrame):
+ (WTR::InjectedBundlePage::didFinishDocumentLoadForFrame):
+ (WTR::InjectedBundlePage::willAddMessageToConsole):
+ (WTR::InjectedBundlePage::willSetStatusbarText):
+ (WTR::InjectedBundlePage::willRunJavaScriptAlert):
+ (WTR::InjectedBundlePage::willRunJavaScriptConfirm):
+ (WTR::InjectedBundlePage::shouldBeginEditing):
+ (WTR::InjectedBundlePage::shouldEndEditing):
+ (WTR::InjectedBundlePage::shouldInsertNode):
+ (WTR::InjectedBundlePage::shouldInsertText):
+ (WTR::InjectedBundlePage::shouldDeleteRange):
+ (WTR::InjectedBundlePage::shouldChangeSelectedRange):
+ (WTR::InjectedBundlePage::shouldApplyStyle):
+ (WTR::InjectedBundlePage::didBeginEditing):
+ (WTR::InjectedBundlePage::didEndEditing):
+ (WTR::InjectedBundlePage::didChange):
+ (WTR::InjectedBundlePage::didChangeSelection):
+ Don't do any work if we are not currently running a test.
+
+ * WebKitTestRunner/InjectedBundle/InjectedBundlePage.h:
+ * WebKitTestRunner/StringFunctions.h:
+ (WTR::toCF):
+ Add conversion function for WKURLRef -> CFURLRef
+
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::TestController):
+ (WTR::TestController::initialize):
+ (WTR::TestController::resetStateToConsistentValues):
+ (WTR::TestController::runTest):
+ (WTR::TestController::didFinishLoadForFrame):
+ * WebKitTestRunner/TestController.h:
+ (WTR::TestController::):
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::invoke):
+ * WebKitTestRunner/TestInvocation.h:
+ Move resetting code to TestController.
+
+ * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
+ * WebKitTestRunner/mac/TestControllerMac.mm:
+ (WTR::TestController::runUntil):
+ * WebKitTestRunner/mac/TestInvocationMac.mm: Removed.
+ * WebKitTestRunner/win/TestControllerWin.cpp:
+ (WTR::TestController::runUntil):
+ * WebKitTestRunner/win/TestInvocationWin.cpp: Removed.
+ * WebKitTestRunner/win/WebKitTestRunner.vcproj:
+ Move runUntil to TestController.
+
+2010-08-12 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Unreviewed.
+
+ Adding myself to the committers list.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-08-12 Hayato Ito <hayato@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ Merge pretty printers for gdb.
+ https://bugs.webkit.org/show_bug.cgi?id=43850
+
+ We need to update webcore.py because basic string classes have moved to WTF from WebCore.
+ It is good timing to merge webcore.py and wtf.py and name it 'webkit.py'.
+ webcore.py is left for backward compatibility.
+
+ * gdb/webcore.py:
+ * gdb/webkit.py: Added.
+ * gdb/wtf.py: Removed.
+
+2010-08-11 Tony Chang <tony@chromium.org>
+
+ Reviewed by David Levin.
+
+ [chromium] add google-chrome layout test result directories
+ https://bugs.webkit.org/show_bug.cgi?id=43889
+
+ * Scripts/webkitpy/layout_tests/port/chromium_win.py:
+ * Scripts/webkitpy/layout_tests/port/factory.py:
+ * Scripts/webkitpy/layout_tests/port/google_chrome.py: Added.
+ * Scripts/webkitpy/layout_tests/test_types/image_diff.py:
+
+2010-08-11 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ [DRT/Chromium] Disable accelerated compositing
+ https://bugs.webkit.org/show_bug.cgi?id=43894
+
+ Disable accelerated compositing because DRT is not ready for
+ it. This change fixes hundreds of test crashes on Windows and
+ Linux.
+
+ * DumpRenderTree/chromium/TestShell.cpp:
+ (TestShell::resetWebSettings):
+
+2010-08-11 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Unreviewed. Adding my Collabora personality to the list.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-08-11 Martin Robinson <mrobinson@igalia.com>
+
+ Adding myself as a reviewer.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-08-11 Daniel Bates <dbates@rim.com>
+
+ Reviewed by Darin Adler.
+
+ Perl warnings when running commit-log-editor
+ https://bugs.webkit.org/show_bug.cgi?id=43856
+
+ Fixes Perl warnings introduced by the patch for Bug #40548.
+
+ Perl doesn't have symbolic names for True/False. Instead, we
+ should use boolean values. Moreover, the variable installedEditorApplication
+ is not be used and should be renamed builtEditorApplication so that it
+ uses the existing machinery to set the commit log editor application.
+
+ * Scripts/commit-log-editor:
+
+2010-08-11 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Trying waiting for httpd lock in the EWS
+ https://bugs.webkit.org/show_bug.cgi?id=43833
+
+ If this works, we can probably run the tests on the mac-ews, which
+ would be very exciting. :)
+
+ * Scripts/webkitpy/tool/steps/runtests.py:
+
+2010-08-11 Marcus Bulach <bulach@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Check in a script to list redundant test outputs.
+ https://bugs.webkit.org/show_bug.cgi?id=37630
+
+ If e.g. platform/mac-leopard is missing an expected test output, we
+ fall back on platform/mac. This means it's possible to grow redundant
+ test outputs, where we have the same expected data in both a platform
+ directory and another platform it falls back on.
+ (original patch by Evan Marting <evan@chromium.org> https://bugs.webkit.org/attachment.cgi?id=53398)
+
+ * Scripts/deduplicate-tests: Added.
+ * Scripts/webkitpy/layout_tests/deduplicate_tests.py: Added.
+ * Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py: Added.
+
+2010-08-11 Antonio Gomes <tonikitoo@webkit.org>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] QtTestBrowser: after switching between QWebView and QGraphicsWebView, rotation actions get broken
+ https://bugs.webkit.org/show_bug.cgi?id=43853
+
+ LauncherWindow::createChrome is connecting menu itens to WebViewGraphicsBased's slots directly.
+ It behaviors badly when user launches the QtTestBrowser in QWebView mode, since then switching to
+ QGraphicsWebView mode, createChrome is not called again, and menu items end up not getting connected
+ to slots at all.
+
+ * QtTestBrowser/launcherwindow.cpp:
+ (LauncherWindow::createChrome):
+ (LauncherWindow::animatedFlip):
+ (LauncherWindow::animatedYFlip):
+ * QtTestBrowser/launcherwindow.h:
+
+2010-08-11 Antonio Gomes <tonikitoo@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] QtTestBrowser: switching between QWebView and QGraphicsWebView modes is broken
+ https://bugs.webkit.org/show_bug.cgi?id=43851
+
+ All window options data (including the bool holding if the view is either QWebView or
+ QGraphicsWebView based) is stored in m_windowOptions, a class member of LauncherWindow.
+ When toggle the view from QWebView to QGraphicsWebView based (and vice-versa), we were
+ not updating LauncherWindow::WindowOptions::m_useGraphicsView bit, and then things were
+ getting broken.
+
+ Patch addresses this issue.
+
+ * QtTestBrowser/launcherwindow.cpp:
+ (LauncherWindow::createChrome):
+ (LauncherWindow::toggleWebView):
+ (LauncherWindow::toggleAcceleratedCompositing):
+
+2010-08-10 Antonio Gomes <tonikitoo@webkit.org>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] QtTestBrowser: lazy instantiate "YRotation" state machine and related objects
+ https://bugs.webkit.org/show_bug.cgi?id=43831
+
+ Only instantiate QStateMachine and friends associated to the YRotation action on demand.
+
+ * QtTestBrowser/webview.cpp:
+ (WebViewGraphicsBased::WebViewGraphicsBased):
+ (WebViewGraphicsBased::animatedYFlip):
+
+2010-08-11 Darin Adler <darin@apple.com>
+
+ Reviewed by John Sullivan.
+
+ Improved editor options for prepare-ChangeLog and commit-log-editor
+ https://bugs.webkit.org/show_bug.cgi?id=40548
+
+ * Scripts/commit-log-editor: Split editor strings on spaces so EDITOR
+ values like "xed --launch --wait" work properly.
+
+ * Scripts/prepare-ChangeLog: Added a new CHANGE_LOG_EDITOR so we can
+ use a command line tool with the $openChangeLogs feature.
+
+2010-08-11 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: remove InjectDispatch.js
+ https://bugs.webkit.org/show_bug.cgi?id=43835
+
+ * DumpRenderTree/chromium/DRTDevToolsAgent.cpp:
+ * DumpRenderTree/chromium/DRTDevToolsAgent.h:
+
+2010-08-10 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ webkit-patch should refuse to run under Win32 Python
+ https://bugs.webkit.org/show_bug.cgi?id=40962
+
+ Given that there are lots of places in webkit-patch's code that
+ assume unix-style filenames (forward slashes), webkit-patch fails
+ with weird file-not-found errors when run under a native windows
+ Python. It would be nice if we just trapped this and errored out
+ at the beginning, rather than producing unpredictable errors.
+
+ * Scripts/webkit-patch:
+
+2010-08-10 Kent Tamura <tkent@chromium.org>
+
+ Unreviewed, build fix.
+
+ Chromium build fix for r65107.
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::suspendAnimations):
+ (LayoutTestController::resumeAnimations):
+
+2010-08-10 Sergio Villar Senin <svillar@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] http/tests/media/video-cookie.html fails
+ https://bugs.webkit.org/show_bug.cgi?id=42240
+
+ * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+ (LayoutTestController::setAlwaysAcceptCookies): create the
+ SoupCookieJar if it does not exist. Otherwise the accept policy
+ won't be set.
+
+2010-08-10 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Add suspendAnimations/resumeAnimation API to DRT
+ https://bugs.webkit.org/show_bug.cgi?id=43733
+
+ Adds suspendAnimations() and resumeAnimations() to LayoutTestController.
+ Calls functions with the same names on AnimationController for the
+ mainFrame.
+
+ * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+ * DumpRenderTree/LayoutTestController.cpp:
+ (suspendAnimationsCallback):
+ (resumeAnimationsCallback):
+ (LayoutTestController::staticFunctions):
+ * DumpRenderTree/LayoutTestController.h:
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::LayoutTestController):
+ (LayoutTestController::suspendAnimations):
+ (LayoutTestController::resumeAnimations):
+ * DumpRenderTree/chromium/LayoutTestController.h:
+ * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+ (LayoutTestController::suspendAnimations):
+ (LayoutTestController::resumeAnimations):
+ * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+ (LayoutTestController::suspendAnimations):
+ (LayoutTestController::resumeAnimations):
+ * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+ (LayoutTestController::suspendAnimations):
+ (LayoutTestController::resumeAnimations):
+ * DumpRenderTree/qt/LayoutTestControllerQt.h:
+ * DumpRenderTree/win/LayoutTestControllerWin.cpp:
+ (LayoutTestController::suspendAnimations):
+ (LayoutTestController::resumeAnimations):
+ * DumpRenderTree/wx/LayoutTestControllerWx.cpp:
+ (LayoutTestController::suspendAnimations):
+ (LayoutTestController::resumeAnimations):
+
+2010-08-10 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ [Chromium/DRT] Enable saving layout test results.
+ https://bugs.webkit.org/show_bug.cgi?id=43796
+
+ * BuildSlaveSupport/build.webkit.org-config/master.cfg: Added more
+ parameters to the new-run-webkit-tests, including the name
+ of the test results server.
+
+2010-08-10 Jian Li <jianli@chromium.org>
+
+ More chromium build fix.
+
+ * DumpRenderTree/chromium/MockSpellCheck.cpp:
+ (MockSpellCheck::spellCheckWord):
+ (MockSpellCheck::initializeIfNeeded):
+ * DumpRenderTree/chromium/NotificationPresenter.cpp:
+ (NotificationPresenter::grantPermission):
+ (NotificationPresenter::show):
+ (NotificationPresenter::checkPermission):
+
+2010-08-10 Jian Li <jianli@chromium.org>
+
+ Chromium build fix.
+
+ * DumpRenderTree/chromium/MockSpellCheck.cpp:
+ * DumpRenderTree/chromium/NotificationPresenter.cpp:
+
+2010-08-10 Victor Wang <victorw@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ Update test results server merge logic so the aggregated
+ results and times are updated for tests that are
+ in aggragated json but not in incremental json.
+
+ Also update unittest to test this case.
+
+ https://bugs.webkit.org/show_bug.cgi?id=43769
+
+ * TestResultServer/model/jsonresults.py:
+ * TestResultServer/model/jsonresults_unittest.py:
+
2010-08-09 Antonio Gomes <tonikitoo@webkit.org>
Reviewed by Ariya Hidayat.
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
index 52b539c..700b44c 100644
--- a/WebKitTools/DumpRenderTree/LayoutTestController.cpp
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
@@ -1545,6 +1545,20 @@ static JSValueRef numberOfActiveAnimationsCallback(JSContextRef context, JSObjec
return JSValueMakeNumber(context, controller->numberOfActiveAnimations());
}
+static JSValueRef suspendAnimationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->suspendAnimations();
+ return JSValueMakeUndefined(context);
+}
+
+static JSValueRef resumeAnimationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->resumeAnimations();
+ return JSValueMakeUndefined(context);
+}
+
static JSValueRef waitForPolicyDelegateCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
{
LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
@@ -1850,6 +1864,8 @@ JSStaticFunction* LayoutTestController::staticFunctions()
{ "markerTextForListItem", markerTextForListItemCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "numberOfActiveAnimations", numberOfActiveAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "suspendAnimations", suspendAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "resumeAnimations", resumeAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "overridePreference", overridePreferenceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "pageNumberForElementById", pageNumberForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "pageSizeAndMarginsInPixels", pageSizeAndMarginsInPixelsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.h b/WebKitTools/DumpRenderTree/LayoutTestController.h
index f76870b..2bab542 100644
--- a/WebKitTools/DumpRenderTree/LayoutTestController.h
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.h
@@ -251,6 +251,8 @@ public:
bool pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId);
bool sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId);
unsigned numberOfActiveAnimations() const;
+ void suspendAnimations() const;
+ void resumeAnimations() const;
void addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains);
void removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains);
diff --git a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp
index b05fe21..4736676 100644
--- a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp
@@ -84,11 +84,6 @@ WebCString DRTDevToolsAgent::injectedScriptSource()
return webkit_support::GetDevToolsInjectedScriptSource();
}
-WebCString DRTDevToolsAgent::injectedScriptDispatcherSource()
-{
- return webkit_support::GetDevToolsInjectedScriptDispatcherSource();
-}
-
WebCString DRTDevToolsAgent::debuggerScriptSource()
{
return webkit_support::GetDevToolsDebuggerScriptSource();
diff --git a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h
index df52866..899a23f 100644
--- a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h
+++ b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h
@@ -62,7 +62,6 @@ public:
virtual void forceRepaint();
virtual void runtimeFeatureStateChanged(const WebKit::WebString& feature, bool enabled);
virtual WebKit::WebCString injectedScriptSource();
- virtual WebKit::WebCString injectedScriptDispatcherSource();
virtual WebKit::WebCString debuggerScriptSource();
void asyncCall(const DRTDevToolsCallArgs&);
diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
index e82a65e..beae21e 100644
--- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
@@ -117,6 +117,8 @@ LayoutTestController::LayoutTestController(TestShell* shell)
bindMethod("pauseTransitionAtTimeOnElementWithId", &LayoutTestController::pauseTransitionAtTimeOnElementWithId);
bindMethod("elementDoesAutoCompleteForElementWithId", &LayoutTestController::elementDoesAutoCompleteForElementWithId);
bindMethod("numberOfActiveAnimations", &LayoutTestController::numberOfActiveAnimations);
+ bindMethod("suspendAnimations", &LayoutTestController::suspendAnimations);
+ bindMethod("resumeAnimations", &LayoutTestController::resumeAnimations);
bindMethod("disableImageLoading", &LayoutTestController::disableImageLoading);
bindMethod("setIconDatabaseEnabled", &LayoutTestController::setIconDatabaseEnabled);
bindMethod("setCustomPolicyDelegate", &LayoutTestController::setCustomPolicyDelegate);
@@ -838,6 +840,32 @@ int LayoutTestController::numberOfActiveAnimations()
return controller->numberOfActiveAnimations();
}
+void LayoutTestController::suspendAnimations()
+{
+ WebFrame* webFrame = m_shell->webView()->mainFrame();
+ if (!webFrame)
+ return;
+
+ WebAnimationController* controller = webFrame->animationController();
+ if (!controller)
+ return;
+
+ controller->suspendAnimations();
+}
+
+void LayoutTestController::resumeAnimations()
+{
+ WebFrame* webFrame = m_shell->webView()->mainFrame();
+ if (!webFrame)
+ return;
+
+ WebAnimationController* controller = webFrame->animationController();
+ if (!controller)
+ return;
+
+ controller->resumeAnimations();
+}
+
void LayoutTestController::pauseAnimationAtTimeOnElementWithId(const CppArgumentList& arguments, CppVariant* result)
{
result->set(false);
@@ -875,6 +903,18 @@ void LayoutTestController::numberOfActiveAnimations(const CppArgumentList&, CppV
result->set(numberOfActiveAnimations());
}
+void LayoutTestController::suspendAnimations(const CppArgumentList&, CppVariant* result)
+{
+ suspendAnimations();
+ result->setNull();
+}
+
+void LayoutTestController::resumeAnimations(const CppArgumentList&, CppVariant* result)
+{
+ resumeAnimations();
+ result->setNull();
+}
+
void LayoutTestController::disableImageLoading(const CppArgumentList&, CppVariant* result)
{
m_shell->webView()->settings()->setLoadsImagesAutomatically(false);
diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h
index fb91544..352e89f 100644
--- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h
+++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h
@@ -207,6 +207,8 @@ public:
void pauseTransitionAtTimeOnElementWithId(const CppArgumentList&, CppVariant*);
void elementDoesAutoCompleteForElementWithId(const CppArgumentList&, CppVariant*);
void numberOfActiveAnimations(const CppArgumentList&, CppVariant*);
+ void suspendAnimations(const CppArgumentList&, CppVariant*);
+ void resumeAnimations(const CppArgumentList&, CppVariant*);
void disableImageLoading(const CppArgumentList&, CppVariant*);
@@ -395,6 +397,8 @@ private:
bool pauseTransitionAtTimeOnElementWithId(const WebKit::WebString& propertyName, double time, const WebKit::WebString& elementId);
bool elementDoesAutoCompleteForElementWithId(const WebKit::WebString&);
int numberOfActiveAnimations();
+ void suspendAnimations();
+ void resumeAnimations();
// Used for test timeouts.
ScopedRunnableMethodFactory<LayoutTestController> m_timeoutFactory;
diff --git a/WebKitTools/DumpRenderTree/chromium/MockSpellCheck.cpp b/WebKitTools/DumpRenderTree/chromium/MockSpellCheck.cpp
index fe70cab..0bf3802 100644
--- a/WebKitTools/DumpRenderTree/chromium/MockSpellCheck.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/MockSpellCheck.cpp
@@ -31,11 +31,12 @@
#include "config.h"
#include "MockSpellCheck.h"
-#include "public/WebString.h"
#include <wtf/ASCIICType.h>
#include <wtf/Assertions.h>
+#include <wtf/text/WTFString.h>
+
+#include "public/WebString.h"
-using namespace WebCore;
using namespace WebKit;
MockSpellCheck::MockSpellCheck()
@@ -59,7 +60,7 @@ bool MockSpellCheck::spellCheckWord(const WebString& text, int* misspelledOffset
// Convert to a String because we store String instances in
// m_misspelledWords and WebString has no find().
- const String stringText(text.data(), text.length());
+ const WTF::String stringText(text.data(), text.length());
// Extract the first possible English word from the given string.
// The given string may include non-ASCII characters or numbers. So, we
@@ -82,7 +83,7 @@ bool MockSpellCheck::spellCheckWord(const WebString& text, int* misspelledOffset
// extracted word if this word is a known misspelled word.
// (See the comment in MockSpellCheck::initializeIfNeeded() why we use a
// misspelled-word table.)
- String word = stringText.substring(wordOffset, wordLength);
+ WTF::String word = stringText.substring(wordOffset, wordLength);
if (!m_misspelledWords.contains(word))
return true;
@@ -137,7 +138,7 @@ bool MockSpellCheck::initializeIfNeeded()
m_misspelledWords.clear();
for (size_t i = 0; i < arraysize(misspelledWords); ++i)
- m_misspelledWords.add(String::fromUTF8(misspelledWords[i]), false);
+ m_misspelledWords.add(WTF::String::fromUTF8(misspelledWords[i]), false);
// Mark as initialized to prevent this object from being initialized twice
// or more.
diff --git a/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp b/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp
index 86903be..95353a7 100644
--- a/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp
@@ -31,36 +31,37 @@
#include "config.h"
#include "NotificationPresenter.h"
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
#include "googleurl/src/gurl.h"
#include "public/WebNotification.h"
#include "public/WebNotificationPermissionCallback.h"
#include "public/WebSecurityOrigin.h"
#include "public/WebString.h"
#include "public/WebURL.h"
-#include <wtf/text/CString.h>
-using namespace WebCore;
using namespace WebKit;
void NotificationPresenter::grantPermission(const WebString& origin)
{
// Make sure it's in the form of an origin.
GURL url(origin);
- m_allowedOrigins.add(String(url.GetOrigin().spec().c_str()));
+ m_allowedOrigins.add(WTF::String(url.GetOrigin().spec().c_str()));
}
// The output from all these methods matches what DumpRenderTree produces.
bool NotificationPresenter::show(const WebNotification& notification)
{
if (!notification.replaceId().isEmpty()) {
- String replaceId(notification.replaceId().data(), notification.replaceId().length());
+ WTF::String replaceId(notification.replaceId().data(), notification.replaceId().length());
if (m_replacements.find(replaceId) != m_replacements.end())
printf("REPLACING NOTIFICATION %s\n",
m_replacements.find(replaceId)->second.utf8().data());
WebString identifier = notification.isHTML() ?
notification.url().spec().utf16() : notification.title();
- m_replacements.set(replaceId, String(identifier.data(), identifier.length()));
+ m_replacements.set(replaceId, WTF::String(identifier.data(), identifier.length()));
}
if (notification.isHTML()) {
@@ -103,7 +104,7 @@ void NotificationPresenter::objectDestroyed(const WebKit::WebNotification& notif
WebNotificationPresenter::Permission NotificationPresenter::checkPermission(const WebURL& url)
{
// Check with the layout test controller
- String origin = String(static_cast<GURL>(url).GetOrigin().spec().c_str());
+ WTF::String origin = WTF::String(static_cast<GURL>(url).GetOrigin().spec().c_str());
bool allowed = m_allowedOrigins.find(origin) != m_allowedOrigins.end();
return allowed ? WebNotificationPresenter::PermissionAllowed
: WebNotificationPresenter::PermissionDenied;
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp
index 64c20b0..7ea36e1 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp
@@ -225,6 +225,8 @@ void TestShell::resetWebSettings(WebView& webView)
#else
settings->setEditingBehavior(WebSettings::EditingBehaviorWin);
#endif
+ // FIXME: crbug.com/51879
+ settings->setAcceleratedCompositingEnabled(false);
}
void TestShell::runFileTest(const TestParams& params)
diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
index b0c1cba..db44a60 100644
--- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
@@ -52,6 +52,8 @@ bool webkit_web_frame_pause_animation(WebKitWebFrame* frame, const gchar* name,
bool webkit_web_frame_pause_transition(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element);
bool webkit_web_frame_pause_svg_animation(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element);
unsigned int webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame);
+void webkit_web_frame_suspend_animations(WebKitWebFrame* frame);
+void webkit_web_frame_resume_animations(WebKitWebFrame* frame);
void webkit_application_cache_set_maximum_size(unsigned long long size);
unsigned int webkit_worker_thread_count(void);
void webkit_white_list_access_from_origin(const gchar* sourceOrigin, const gchar* destinationProtocol, const gchar* destinationHost, bool allowDestinationSubdomains);
@@ -250,6 +252,15 @@ void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies)
SoupSession* session = webkit_get_default_session();
SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR));
+ /* If the jar was not created - we create it on demand, i.e, just
+ in case we have HTTP requests - then we must create it here in
+ order to set the proper accept policy */
+ if (!jar) {
+ jar = soup_cookie_jar_new();
+ soup_session_add_feature(session, SOUP_SESSION_FEATURE(jar));
+ g_object_unref(jar);
+ }
+
SoupCookieJarAcceptPolicy policy;
if (alwaysAcceptCookies)
@@ -620,6 +631,16 @@ unsigned LayoutTestController::numberOfActiveAnimations() const
return webkit_web_frame_number_of_active_animations(mainFrame);
}
+void LayoutTestController::suspendAnimations() const
+{
+ webkit_web_frame_suspend_animations(mainFrame);
+}
+
+void LayoutTestController::resumeAnimations() const
+{
+ webkit_web_frame_resume_animations(mainFrame);
+}
+
void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value)
{
gchar* name = JSStringCopyUTF8CString(key);
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
index c0eb722..a85ac2e 100644
--- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -631,6 +631,16 @@ unsigned LayoutTestController::numberOfActiveAnimations() const
return [mainFrame _numberOfActiveAnimations];
}
+void LayoutTestController::suspendAnimations() const
+{
+ return [mainFrame _suspendAnimations];
+}
+
+void LayoutTestController::resumeAnimations() const
+{
+ return [mainFrame _resumeAnimations];
+}
+
void LayoutTestController::waitForPolicyDelegate()
{
setWaitToDump(true);
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
index c6c39b5..4a57d1d 100644
--- a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
@@ -571,7 +571,7 @@ void DumpRenderTree::open(const QUrl& url)
m_page->event(&ev);
QWebSettings::clearMemoryCaches();
-#if !(defined(Q_WS_S60) && QT_VERSION <= QT_VERSION_CHECK(4, 6, 2))
+#if !(defined(Q_OS_SYMBIAN) && QT_VERSION <= QT_VERSION_CHECK(4, 6, 2))
QFontDatabase::removeAllApplicationFonts();
#endif
#if defined(Q_WS_X11)
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
index e682fd0..74baf37 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
@@ -484,6 +484,20 @@ unsigned LayoutTestController::numberOfActiveAnimations() const
return DumpRenderTreeSupportQt::numberOfActiveAnimations(frame);
}
+void LayoutTestController::suspendAnimations() const
+{
+ QWebFrame* frame = m_drt->webPage()->mainFrame();
+ Q_ASSERT(frame);
+ DumpRenderTreeSupportQt::suspendAnimations(frame);
+}
+
+void LayoutTestController::resumeAnimations() const
+{
+ QWebFrame* frame = m_drt->webPage()->mainFrame();
+ Q_ASSERT(frame);
+ DumpRenderTreeSupportQt::resumeAnimations(frame);
+}
+
void LayoutTestController::disableImageLoading()
{
m_drt->webPage()->settings()->setAttribute(QWebSettings::AutoLoadImages, false);
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
index f9986b1..207e093 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
@@ -167,6 +167,8 @@ public slots:
bool elementDoesAutoCompleteForElementWithId(const QString& elementId);
unsigned numberOfActiveAnimations() const;
+ void suspendAnimations() const;
+ void resumeAnimations() const;
void addOriginAccessWhitelistEntry(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains);
void removeOriginAccessWhitelistEntry(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains);
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
index a1b72e1..67e5d4b 100644
--- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
@@ -1232,8 +1232,17 @@ RetainPtr<CFURLCacheRef> sharedCFURLCache()
}
#endif
+static LONG WINAPI exceptionFilter(EXCEPTION_POINTERS*)
+{
+ fputs("#CRASHED\n", stderr);
+ fflush(stderr);
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
int main(int argc, char* argv[])
{
+ ::SetUnhandledExceptionFilter(exceptionFilter);
+
leakChecking = false;
_setmode(1, _O_BINARY);
diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
index 31bc6ce..1ff88e5 100644
--- a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
@@ -1060,6 +1060,24 @@ unsigned LayoutTestController::numberOfActiveAnimations() const
return number;
}
+void LayoutTestController::suspendAnimations() const
+{
+ COMPtr<IWebFramePrivate> framePrivate(Query, frame);
+ if (!framePrivate)
+ return;
+
+ framePrivate->suspendAnimations();
+}
+
+void LayoutTestController::resumeAnimations() const
+{
+ COMPtr<IWebFramePrivate> framePrivate(Query, frame);
+ if (!framePrivate)
+ return;
+
+ framePrivate->resumeAnimations();
+}
+
static _bstr_t bstrT(JSStringRef jsString)
{
// The false parameter tells the _bstr_t constructor to adopt the BSTR we pass it.
diff --git a/WebKitTools/DumpRenderTree/wscript b/WebKitTools/DumpRenderTree/wscript
index 75d208f..4aaedb4 100644
--- a/WebKitTools/DumpRenderTree/wscript
+++ b/WebKitTools/DumpRenderTree/wscript
@@ -58,8 +58,8 @@ def build(bld):
includes = ' '.join(include_paths),
source = sources,
target = 'DumpRenderTree',
- uselib = 'JSCORE ICU WXWEBKIT WX ' + get_config(),
+ uselib = 'ICU WX ' + get_config(),
libpath = [output_dir],
- uselib_local = '',
+ uselib_local = 'jscore wxwebkit',
install_path = output_dir)
diff --git a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
index 7c80ff2..9fee1e3 100644
--- a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
+++ b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
@@ -264,6 +264,16 @@ unsigned LayoutTestController::numberOfActiveAnimations() const
return 0;
}
+void LayoutTestController::suspendAnimations() const
+{
+ // FIXME: implement
+}
+
+void LayoutTestController::resumeAnimations() const
+{
+ // FIXME: implement
+}
+
unsigned LayoutTestController::workerThreadCount() const
{
// FIXME: implement
diff --git a/WebKitTools/MiniBrowser/mac/BrowserWindowController.m b/WebKitTools/MiniBrowser/mac/BrowserWindowController.m
index 9a987d2..9842448 100644
--- a/WebKitTools/MiniBrowser/mac/BrowserWindowController.m
+++ b/WebKitTools/MiniBrowser/mac/BrowserWindowController.m
@@ -411,7 +411,8 @@ static WKStringRef runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKSt
closePage,
runJavaScriptAlert,
runJavaScriptConfirm,
- runJavaScriptPrompt
+ runJavaScriptPrompt,
+ 0 /* contentsSizeChanged */
};
WKPageSetPageUIClient(_webView.pageRef, &uiClient);
}
diff --git a/WebKitTools/MiniBrowser/win/BrowserView.cpp b/WebKitTools/MiniBrowser/win/BrowserView.cpp
index 49e46bf..ee67a08 100644
--- a/WebKitTools/MiniBrowser/win/BrowserView.cpp
+++ b/WebKitTools/MiniBrowser/win/BrowserView.cpp
@@ -83,7 +83,8 @@ void BrowserView::create(RECT webViewRect, BrowserWindow* parentWindow)
createNewPage,
showPage,
closePage,
- runJavaScriptAlert
+ runJavaScriptAlert,
+ 0 /* contentsSizeChanged */
};
WKPageSetPageUIClient(WKViewGetPage(m_webView), &uiClient);
}
diff --git a/WebKitTools/QtTestBrowser/launcherwindow.cpp b/WebKitTools/QtTestBrowser/launcherwindow.cpp
index 095a984..9b7aa0d 100644
--- a/WebKitTools/QtTestBrowser/launcherwindow.cpp
+++ b/WebKitTools/QtTestBrowser/launcherwindow.cpp
@@ -65,7 +65,7 @@ void LauncherWindow::init()
QSplitter* splitter = new QSplitter(Qt::Vertical, this);
setCentralWidget(splitter);
-#if defined(Q_WS_S60)
+#if defined(Q_OS_SYMBIAN)
setWindowState(Qt::WindowMaximized);
#else
setWindowState(Qt::WindowNoState);
@@ -218,7 +218,7 @@ void LauncherWindow::createChrome()
QMenu* toolsMenu = menuBar()->addMenu("&Develop");
QMenu* graphicsViewMenu = toolsMenu->addMenu("QGraphicsView");
- QAction* toggleGraphicsView = graphicsViewMenu->addAction("Toggle use of QGraphicsView", this, SLOT(initializeView()));
+ QAction* toggleGraphicsView = graphicsViewMenu->addAction("Toggle use of QGraphicsView", this, SLOT(toggleWebView(bool)));
toggleGraphicsView->setCheckable(true);
toggleGraphicsView->setChecked(isGraphicsBased());
@@ -339,16 +339,12 @@ void LauncherWindow::createChrome()
QAction* flipAnimated = graphicsViewMenu->addAction("Animated Flip");
flipAnimated->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
flipAnimated->setEnabled(isGraphicsBased());
+ connect(flipAnimated, SIGNAL(triggered()), SLOT(animatedFlip()));
QAction* flipYAnimated = graphicsViewMenu->addAction("Animated Y-Flip");
flipYAnimated->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
flipYAnimated->setEnabled(isGraphicsBased());
-
- if (isGraphicsBased()) {
- WebViewGraphicsBased* view = static_cast<WebViewGraphicsBased*>(m_view);
- connect(flipAnimated, SIGNAL(triggered()), view, SLOT(animatedFlip()));
- connect(flipYAnimated, SIGNAL(triggered()), view, SLOT(animatedYFlip()));
- }
+ connect(flipYAnimated, SIGNAL(triggered()), SLOT(animatedYFlip()));
QAction* cloneWindow = graphicsViewMenu->addAction("Clone Window", this, SLOT(cloneWindow()));
cloneWindow->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)));
@@ -669,6 +665,12 @@ void LauncherWindow::setTouchMocking(bool on)
#endif
}
+void LauncherWindow::toggleWebView(bool graphicsBased)
+{
+ m_windowOptions.useGraphicsView = graphicsBased;
+ initializeView();
+}
+
void LauncherWindow::toggleAcceleratedCompositing(bool toggle)
{
m_windowOptions.useCompositing = toggle;
@@ -692,6 +694,15 @@ void LauncherWindow::toggleWebGL(bool toggle)
page()->settings()->setAttribute(QWebSettings::WebGLEnabled, toggle);
}
+void LauncherWindow::animatedFlip()
+{
+ qobject_cast<WebViewGraphicsBased*>(m_view)->animatedFlip();
+}
+
+void LauncherWindow::animatedYFlip()
+{
+ qobject_cast<WebViewGraphicsBased*>(m_view)->animatedYFlip();
+}
void LauncherWindow::toggleSpatialNavigation(bool b)
{
page()->settings()->setAttribute(QWebSettings::SpatialNavigationEnabled, b);
@@ -702,7 +713,7 @@ void LauncherWindow::toggleFullScreenMode(bool enable)
if (enable)
setWindowState(Qt::WindowFullScreen);
else {
-#if defined(Q_WS_S60)
+#if defined(Q_OS_SYMBIAN)
setWindowState(Qt::WindowMaximized);
#else
setWindowState(Qt::WindowNoState);
@@ -760,7 +771,7 @@ void LauncherWindow::showFPS(bool enable)
view->setFrameRateMeasurementEnabled(enable);
if (!enable) {
-#if defined(Q_WS_MAEMO_5) && defined(Q_WS_S60)
+#if defined(Q_WS_MAEMO_5) && defined(Q_OS_SYMBIAN)
setWindowTitle("");
#else
statusBar()->clearMessage();
@@ -819,7 +830,7 @@ void LauncherWindow::updateFPS(int fps)
{
QString fpsStatusText = QString("Current FPS: %1").arg(fps);
-#if defined(Q_WS_MAEMO_5) && defined(Q_WS_S60)
+#if defined(Q_WS_MAEMO_5) && defined(Q_OS_SYMBIAN)
setWindowTitle(fpsStatusText);
#else
statusBar()->showMessage(fpsStatusText);
diff --git a/WebKitTools/QtTestBrowser/launcherwindow.h b/WebKitTools/QtTestBrowser/launcherwindow.h
index 9319d24..65f390d 100644
--- a/WebKitTools/QtTestBrowser/launcherwindow.h
+++ b/WebKitTools/QtTestBrowser/launcherwindow.h
@@ -82,7 +82,7 @@ public:
, useCompositing(true)
, useTiledBackingStore(false)
, useWebGL(false)
-#if defined(Q_WS_MAEMO_5) || defined(Q_WS_S60)
+#if defined(Q_WS_MAEMO_5) || defined(Q_OS_SYMBIAN)
, useFrameFlattening(true)
#else
, useFrameFlattening(false)
@@ -151,6 +151,7 @@ protected slots:
void initializeView();
void setTouchMocking(bool on);
+ void toggleWebView(bool graphicsBased);
void toggleAcceleratedCompositing(bool toggle);
void toggleTiledBackingStore(bool toggle);
void toggleResizesToContents(bool toggle);
@@ -166,6 +167,8 @@ protected slots:
#endif
void changeViewportUpdateMode(int mode);
+ void animatedFlip();
+ void animatedYFlip();
void selectElements();
void showFPS(bool enable);
void showUserAgentDialog();
diff --git a/WebKitTools/QtTestBrowser/mainwindow.cpp b/WebKitTools/QtTestBrowser/mainwindow.cpp
index abb608f..1a9aa5f 100644
--- a/WebKitTools/QtTestBrowser/mainwindow.cpp
+++ b/WebKitTools/QtTestBrowser/mainwindow.cpp
@@ -48,7 +48,7 @@ MainWindow::MainWindow(const QString& url)
void MainWindow::buildUI()
{
QToolBar* bar = addToolBar("Navigation");
-#if defined(Q_WS_S60)
+#if defined(Q_OS_SYMBIAN)
bar->setIconSize(QSize(16, 16));
#endif
QAction* reloadAction = page()->action(QWebPage::Reload);
@@ -65,7 +65,7 @@ void MainWindow::buildUI()
QCompleter* completer = new QCompleter(this);
urlEdit->setCompleter(completer);
completer->setModel(&urlModel);
-#if defined(Q_WS_S60)
+#if defined(Q_OS_SYMBIAN)
addToolBarBreak();
addToolBar("Location")->addWidget(urlEdit);
#else
diff --git a/WebKitTools/QtTestBrowser/webview.cpp b/WebKitTools/QtTestBrowser/webview.cpp
index c8eecd6..bc8fad1 100644
--- a/WebKitTools/QtTestBrowser/webview.cpp
+++ b/WebKitTools/QtTestBrowser/webview.cpp
@@ -42,6 +42,7 @@ WebViewGraphicsBased::WebViewGraphicsBased(QWidget* parent)
, m_numPaintsSinceLastMeasure(0)
, m_measureFps(false)
, m_resizesToContents(false)
+ , m_machine(0)
{
setScene(new QGraphicsScene(this));
scene()->addItem(m_item);
@@ -50,30 +51,6 @@ WebViewGraphicsBased::WebViewGraphicsBased(QWidget* parent)
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
- QStateMachine* machine = new QStateMachine(this);
- QState* s0 = new QState(machine);
- s0->assignProperty(this, "yRotation", 0);
-
- QState* s1 = new QState(machine);
- s1->assignProperty(this, "yRotation", 90);
-
- QAbstractTransition* t1 = s0->addTransition(this, SIGNAL(yFlipRequest()), s1);
- QPropertyAnimation* yRotationAnim = new QPropertyAnimation(this, "yRotation", this);
- yRotationAnim->setDuration(1000);
- t1->addAnimation(yRotationAnim);
-
- QState* s2 = new QState(machine);
- s2->assignProperty(this, "yRotation", -90);
- s1->addTransition(s1, SIGNAL(propertiesAssigned()), s2);
-
- QAbstractTransition* t2 = s2->addTransition(s0);
- t2->addAnimation(yRotationAnim);
-
- machine->setInitialState(s0);
- machine->start();
-#endif
-
m_updateTimer = new QTimer(this);
m_updateTimer->setInterval(1000);
connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateFrameRate()));
@@ -193,7 +170,39 @@ void WebViewGraphicsBased::animatedFlip()
void WebViewGraphicsBased::animatedYFlip()
{
- emit yFlipRequest();
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ if (!m_machine) {
+ m_machine = new QStateMachine(this);
+
+ QState* s0 = new QState(m_machine);
+ s0->assignProperty(this, "yRotation", 0);
+
+ QState* s1 = new QState(m_machine);
+ s1->assignProperty(this, "yRotation", 90);
+
+ QAbstractTransition* t1 = s0->addTransition(s1);
+ QPropertyAnimation* yRotationAnim = new QPropertyAnimation(this, "yRotation", this);
+ t1->addAnimation(yRotationAnim);
+
+ QState* s2 = new QState(m_machine);
+ s2->assignProperty(this, "yRotation", -90);
+ s1->addTransition(s1, SIGNAL(propertiesAssigned()), s2);
+
+ QState* s3 = new QState(m_machine);
+ s3->assignProperty(this, "yRotation", 0);
+
+ QAbstractTransition* t2 = s2->addTransition(s3);
+ t2->addAnimation(yRotationAnim);
+
+ QFinalState* final = new QFinalState(m_machine);
+ s3->addTransition(s3, SIGNAL(propertiesAssigned()), final);
+
+ m_machine->setInitialState(s0);
+ yRotationAnim->setDuration(1000);
+ }
+
+ m_machine->start();
+#endif
}
void WebViewGraphicsBased::paintEvent(QPaintEvent* event)
diff --git a/WebKitTools/QtTestBrowser/webview.h b/WebKitTools/QtTestBrowser/webview.h
index 5e7c0c3..d0e1e57 100644
--- a/WebKitTools/QtTestBrowser/webview.h
+++ b/WebKitTools/QtTestBrowser/webview.h
@@ -41,6 +41,8 @@
#include <QGraphicsWidget>
#include <QTime>
+class QStateMachine;
+
class WebViewTraditional : public QWebView {
Q_OBJECT
@@ -110,7 +112,6 @@ public slots:
void contentsSizeChanged(const QSize&);
signals:
- void yFlipRequest();
void currentFPSUpdated(int fps);
private:
@@ -123,6 +124,7 @@ private:
bool m_measureFps;
qreal m_yRotation;
bool m_resizesToContents;
+ QStateMachine* m_machine;
FpsTimer m_fpsTimer;
};
diff --git a/WebKitTools/Scripts/build-webkit b/WebKitTools/Scripts/build-webkit
index 3b8dd9c..acd7736 100755
--- a/WebKitTools/Scripts/build-webkit
+++ b/WebKitTools/Scripts/build-webkit
@@ -341,6 +341,9 @@ if (isGtk()) {
# Apple builds JavaScriptGlue, and only on the Mac.
splice @projects, 1, 0, "JavaScriptGlue";
+ # ANGLE must come before WebCore
+ splice @projects, 0, 0, "ANGLE";
+
# WebKit2 is only supported in SnowLeopard and later at present.
push @projects, ("WebKit2", "WebKitTools/MiniBrowser") if osXVersion()->{"minor"} >= 6;
@@ -404,9 +407,13 @@ if (isInspectorFrontend()) {
if (isWx()) {
downloadWafIfNeeded();
- push @projects, 'WebKitTools/DumpRenderTree';
- push @projects, 'WebKitTools/wx/browser';
- push @projects, 'WebKit/wx/bindings/python';
+ @options = ();
+ if (defined($makeArgs)) {
+ @options = split(/ /, $makeArgs);
+ }
+ @projects = ();
+ my $result = buildWafProject('.', $clean, @options);
+ exit exitStatus($result) if exitStatus($result);
}
if (isChromium()) {
@@ -439,16 +446,6 @@ for my $dir (@projects) {
if ($dir eq "WebKit") {
$result = buildVisualStudioProject("win/WebKit.vcproj/WebKit.sln", $clean);
}
- } elsif (isWx()) {
- @options = ();
- if (defined($makeArgs)) {
- @options = split(/ /, $makeArgs);
- }
- if ($dir eq "WebKit" && isWx()) {
- chdir 'wx' or die;
- }
-
- $result = buildWafProject($dir, $clean, @options);
}
if (exitStatus($result)) {
diff --git a/WebKitTools/Scripts/commit-log-editor b/WebKitTools/Scripts/commit-log-editor
index a642731..1be0fd0 100755
--- a/WebKitTools/Scripts/commit-log-editor
+++ b/WebKitTools/Scripts/commit-log-editor
@@ -62,26 +62,40 @@ if (!$log) {
my $baseDir = baseProductDir();
my $editor = $ENV{SVN_LOG_EDITOR};
-if (!$editor || isCommitLogEditor($editor)) {
- $editor = $ENV{CVS_LOG_EDITOR};
-}
-if (!$editor || isCommitLogEditor($editor)) {
+$editor = $ENV{CVS_LOG_EDITOR} if !$editor;
+$editor = "" if isCommitLogEditor($editor);
+
+my $splitEditor = 1;
+if (!$editor) {
my $builtEditorApplication = "$baseDir/Release/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
- $editor = $builtEditorApplication if -x $builtEditorApplication;
+ if (-x $builtEditorApplication) {
+ $editor = $builtEditorApplication;
+ $splitEditor = 0;
+ }
}
-if (!$editor || isCommitLogEditor($editor)) {
+if (!$editor) {
my $builtEditorApplication = "$baseDir/Debug/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
- $editor = $builtEditorApplication if -x $builtEditorApplication;
-}
-if (!$editor || isCommitLogEditor($editor)) {
- my $installedEditorApplication = "$ENV{HOME}/Applications/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
- $editor = $installedEditorApplication if -x $installedEditorApplication;
+ if (-x $builtEditorApplication) {
+ $editor = $builtEditorApplication;
+ $splitEditor = 0;
+ }
}
-if (!$editor || isCommitLogEditor($editor)) {
- $editor = $ENV{EDITOR};
+if (!$editor) {
+ my $builtEditorApplication = "$ENV{HOME}/Applications/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
+ if (-x $builtEditorApplication) {
+ $editor = $builtEditorApplication;
+ $splitEditor = 0;
+ }
}
-if (!$editor || isCommitLogEditor($editor)) {
- $editor = "/usr/bin/vi";
+
+$editor = $ENV{EDITOR} if !$editor;
+$editor = "/usr/bin/vi" if !$editor;
+
+my @editor;
+if ($splitEditor) {
+ @editor = split ' ', $editor;
+} else {
+ @editor = ($editor);
}
my $inChangesToBeCommitted = !isGit();
@@ -124,9 +138,8 @@ if ($regenerateLog && $existingLog && scalar(@changeLogs) > 0) {
$keepExistingLog = 0 if ($key eq "r");
}
-# Don't change anything if there's already a log message
-# (as can happen with git-commit --amend)
-exec $editor, @ARGV if $existingLog && $keepExistingLog;
+# Don't change anything if there's already a log message (as can happen with git-commit --amend).
+exec (@editor, @ARGV) if $existingLog && $keepExistingLog;
my $topLevel = determineVCSRoot();
@@ -248,7 +261,7 @@ if (isGit() && scalar keys %changeLogSort == 0) {
print NEWLOG $logContents;
close NEWLOG;
-system $editor, "$log.edit";
+system (@editor, "$log.edit");
open NEWLOG, "$log.edit" or exit;
my $foundComment = 0;
diff --git a/WebKitTools/Scripts/create-html-entity-table b/WebKitTools/Scripts/create-html-entity-table
new file mode 100755
index 0000000..46c8c52
--- /dev/null
+++ b/WebKitTools/Scripts/create-html-entity-table
@@ -0,0 +1,183 @@
+#!/usr/bin/env python
+# 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.
+
+import os.path
+import string
+import sys
+
+# Hack sys.path to avoid executing webkitpy __init__.py code which may
+# use Python 2.5 features. This code needs to run on Python 2.3 in order
+# to support Mac OS X Tiger.
+scripts_directory = sys.path[0]
+sys.path.append("%s/webkitpy/thirdparty" % scripts_directory)
+
+import simplejson
+
+
+def convert_entity_to_cpp_name(entity):
+ postfix = "EntityName"
+ if entity[-1] == ";":
+ return "%sSemicolon%s" % (entity[:-1], postfix)
+ return "%s%s" % (entity, postfix)
+
+
+def convert_entity_to_uchar_array(entity):
+ return "{'%s'}" % "', '".join(entity)
+
+
+def convert_value_to_int(value):
+ assert(value[0] == "U")
+ assert(value[1] == "+")
+ return "0x" + value[2:]
+
+
+def offset_table_entry(offset):
+ return " &staticEntityTable[%s]," % offset
+
+
+program_name = os.path.basename(__file__)
+if len(sys.argv) < 4 or sys.argv[1] != "-o":
+ print >> sys.stderr, "Usage: %s -o OUTPUT_FILE INPUT_FILE" % program_name
+ exit(1)
+
+output_path = sys.argv[2]
+input_path = sys.argv[3]
+
+html_entity_names_file = open(input_path)
+entries = simplejson.load(html_entity_names_file)
+html_entity_names_file.close()
+
+entries = sorted(entries, key=lambda entry: entry['entity'])
+entity_count = len(entries)
+
+output_file = open(output_path, "w")
+
+print >> output_file, """/*
+ * 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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.
+ */
+
+// THIS FILE IS GENERATED BY WebKitTools/Scripts/create-html-entity-table
+// DO NOT EDIT (unless you are a ninja)!
+
+#include "config.h"
+#include "HTMLEntityTable.h"
+
+namespace WebCore {
+
+namespace {
+"""
+
+for entry in entries:
+ print >> output_file, "const UChar %sEntityName[] = %s;" % (
+ convert_entity_to_cpp_name(entry["entity"]),
+ convert_entity_to_uchar_array(entry["entity"]))
+
+print >> output_file, """
+HTMLEntityTableEntry staticEntityTable[%s] = {""" % entity_count
+
+index = {}
+offset = 0
+for entry in entries:
+ letter = entry["entity"][0]
+ if not index.get(letter):
+ index[letter] = offset
+ print >> output_file, ' { %sEntityName, %s, %s },' % (
+ convert_entity_to_cpp_name(entry["entity"]),
+ len(entry["entity"]),
+ convert_value_to_int(entry["value"]))
+ offset += 1
+
+print >> output_file, """};
+"""
+
+print >> output_file, "const HTMLEntityTableEntry* uppercaseOffset[] = {"
+for letter in string.uppercase:
+ print >> output_file, offset_table_entry(index[letter])
+print >> output_file, offset_table_entry(index['a'])
+print >> output_file, """};
+
+const HTMLEntityTableEntry* lowercaseOffset[] = {"""
+for letter in string.lowercase:
+ print >> output_file, offset_table_entry(index[letter])
+print >> output_file, offset_table_entry(entity_count)
+print >> output_file, """};
+
+}
+
+const HTMLEntityTableEntry* HTMLEntityTable::firstEntryStartingWith(UChar c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return uppercaseOffset[c - 'A'];
+ if (c >= 'a' && c <= 'z')
+ return lowercaseOffset[c - 'a'];
+ return 0;
+}
+
+const HTMLEntityTableEntry* HTMLEntityTable::lastEntryStartingWith(UChar c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return uppercaseOffset[c - 'A' + 1] - 1;
+ if (c >= 'a' && c <= 'z')
+ return lowercaseOffset[c - 'a' + 1] - 1;
+ return 0;
+}
+
+const HTMLEntityTableEntry* HTMLEntityTable::firstEntry()
+{
+ return &staticEntityTable[0];
+}
+
+const HTMLEntityTableEntry* HTMLEntityTable::lastEntry()
+{
+ return &staticEntityTable[%s - 1];
+}
+
+}
+""" % entity_count
diff --git a/WebKitTools/Scripts/deduplicate-tests b/WebKitTools/Scripts/deduplicate-tests
new file mode 100644
index 0000000..f0afe13
--- /dev/null
+++ b/WebKitTools/Scripts/deduplicate-tests
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+# 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:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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.
+
+"""deduplicate-tests -- print test results duplicated between platforms.
+
+If platform/mac-leopard is missing an expected test output, we fall back on
+platform/mac. This means it's possible to grow redundant test outputs,
+where we have the same expected data in both a platform directory and another
+platform it falls back on.
+
+This command dumps out all such files. You can use it like this:
+ deduplicate-tests --verbose # print out the duplicated files
+ deduplicate-tests | xargs git rm # delete them
+"""
+
+
+import optparse
+import webkitpy.common.system.logutils as logutils
+import webkitpy.layout_tests.deduplicate_tests as deduplicate_tests
+
+
+def parse_args():
+ """Provides a default set of command line args.
+
+ Returns a tuple of options, args from optparse"""
+
+ configuration_options = [
+ optparse.make_option("-v", "--verbose", dest="verbose",
+ action="store_true", default=False,
+ help="Verbose output."),
+ optparse.make_option("-g", "--glob", dest="glob_pattern",
+ default="*-expected*",
+ help="Specify the glob to filter the files, defaults to *-expected*."),
+ ]
+
+ option_list = (configuration_options)
+ option_parser = optparse.OptionParser(option_list=option_list)
+
+ options, _ = option_parser.parse_args()
+
+ return options
+
+
+def run(options):
+ logutils.configure_logging()
+ if options.verbose:
+ format = ("* %(test)s\n"
+ "\tredundantly on %(platform)s and %(fallback)s\n"
+ "\tconsider deleting %(path)s")
+ else:
+ format = "%(path)s"
+
+ for dupe in deduplicate_tests.deduplicate(options.glob_pattern):
+ print(format % dupe)
+
+
+def main():
+ options = parse_args()
+ run(options)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/WebKitTools/Scripts/old-run-webkit-tests b/WebKitTools/Scripts/old-run-webkit-tests
index 97ef3dc..68aa6ed 100755
--- a/WebKitTools/Scripts/old-run-webkit-tests
+++ b/WebKitTools/Scripts/old-run-webkit-tests
@@ -105,12 +105,14 @@ sub readSkippedFiles($);
sub recordActualResultsAndDiff($$);
sub sampleDumpTool();
sub setFileHandleNonBlocking(*$);
+sub setUpWindowsCrashLogSaving();
sub slowestcmp($$);
sub splitpath($);
sub stopRunningTestsEarlyIfNeeded();
sub stripExtension($);
sub stripMetrics($$);
sub testCrashedOrTimedOut($$$$$);
+sub toCygwinPath($);
sub toURL($);
sub toWindowsPath($);
sub validateSkippedArg($$;$);
@@ -149,7 +151,7 @@ my $root;
my $runSample = 1;
my $shouldCheckLeaks = 0;
my $showHelp = 0;
-my $stripEditingCallbacks = isCygwin();
+my $stripEditingCallbacks;
my $testHTTP = 1;
my $testWebSocket = 1;
my $testMedia = 1;
@@ -184,6 +186,12 @@ my $prettyDiffTag = "pretty-diff";
my $diffsTag = "diffs";
my $errorTag = "stderr";
+# These are defined here instead of closer to where they are used so that they
+# will always be accessible from the END block that uses them, even if the user
+# presses Ctrl-C before Perl has finished evaluating this whole file.
+my $windowsPostMortemDebuggerKey = "/HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/AeDebug";
+my %previousWindowsPostMortemDebuggerValues;
+
my $realPlatform;
my @macPlatforms = ("mac-tiger", "mac-leopard", "mac-snowleopard", "mac");
@@ -355,11 +363,13 @@ if ($useWebKitTestRunner) {
$realPlatform = $platform;
$platform = "mac-wk2";
} elsif (isAppleWinWebKit()) {
+ $stripEditingCallbacks = 0 unless defined $stripEditingCallbacks;
$realPlatform = $platform;
$platform = "win-wk2";
}
}
+$stripEditingCallbacks = isCygwin() unless defined $stripEditingCallbacks;
my $ignoreSkipped = $treatSkipped eq "ignore";
my $skippedOnly = $treatSkipped eq "only";
@@ -380,6 +390,8 @@ $testMedia = 0 if $shouldCheckLeaks && isTiger();
# Generating remote links causes a lot of unnecessary spew on GTK build bot
$useRemoteLinksToTests = 0 if isGtk();
+setUpWindowsCrashLogSaving() if isCygwin();
+
setConfigurationProductDir(Cwd::abs_path($root)) if (defined($root));
my $productDir = productDir();
$productDir .= "/bin" if isQt();
@@ -1397,6 +1409,7 @@ sub openDumpTool()
} elsif (isCygwin()) {
$CLEAN_ENV{HOMEDRIVE} = $ENV{'HOMEDRIVE'};
$CLEAN_ENV{HOMEPATH} = $ENV{'HOMEPATH'};
+ $CLEAN_ENV{_NT_SYMBOL_PATH} = $ENV{_NT_SYMBOL_PATH};
setPathForRunningWebKitApp(\%CLEAN_ENV);
}
@@ -1719,6 +1732,14 @@ sub convertPathUsingCygpath($$)
return $convertedPath;
}
+sub toCygwinPath($)
+{
+ my ($path) = @_;
+ return unless isCygwin();
+
+ return convertPathUsingCygpath($path, "-u");
+}
+
sub toWindowsPath($)
{
my ($path) = @_;
@@ -2069,6 +2090,10 @@ sub readFromDumpToolWithTimer(**)
}
}
if (defined($lineError)) {
+ if ($lineError =~ /#CRASHED/) {
+ $status = "crashed";
+ last;
+ }
if ($lineError =~ /#EOF/) {
$haveSeenEofError = 1;
} else {
@@ -2345,3 +2370,47 @@ sub stopRunningTestsEarlyIfNeeded()
return 0;
}
+
+sub setUpWindowsCrashLogSaving()
+{
+ return unless isCygwin();
+
+ unless (defined $ENV{_NT_SYMBOL_PATH}) {
+ print "The _NT_SYMBOL_PATH environment variable is not set. Crash logs will not be saved.\nSee <http://trac.webkit.org/wiki/BuildingOnWindows#GettingCrashLogs>.\n";
+ return;
+ }
+
+ my $ntsdPath = File::Spec->catfile(toCygwinPath($ENV{PROGRAMFILES}), "Debugging Tools for Windows (x86)", "ntsd.exe");
+ unless (-f $ntsdPath) {
+ $ntsdPath = File::Spec->catfile(toCygwinPath($ENV{SYSTEMROOT}), "system32", "ntsd.exe");
+ unless (-f $ntsdPath) {
+ print STDERR "Can't find ntsd.exe. Crash logs will not be saved.\nSee <http://trac.webkit.org/wiki/BuildingOnWindows#GettingCrashLogs>.\n";
+ return;
+ }
+ }
+
+ my %values = (
+ Debugger => '"' . toWindowsPath($ntsdPath) . '" -p %ld -e %ld -g -lines -c ".logopen /t \"' . toWindowsPath($testResultsDirectory) . '\CrashLog.txt\";!analyze -vv;~*kpn;q"',
+ Auto => 1
+ );
+
+ foreach my $value (keys %values) {
+ chomp($previousWindowsPostMortemDebuggerValues{$value} = `regtool get "$windowsPostMortemDebuggerKey/$value"`);
+ my $result = system "regtool", "set", "-s", "$windowsPostMortemDebuggerKey/$value", $values{$value};
+ next unless $result;
+
+ print "Failed to set \"$windowsPostMortemDebuggerKey/$value\". Crash logs will not be saved.\nSee <http://trac.webkit.org/wiki/BuildingOnWindows#GettingCrashLogs>.\n";
+ return;
+ }
+
+ print "Crash logs will be saved to $testResultsDirectory.\n";
+}
+
+END {
+ return unless isCygwin();
+
+ foreach my $value (keys %previousWindowsPostMortemDebuggerValues) {
+ my $result = system "regtool", "set", "-s", "$windowsPostMortemDebuggerKey/$value", $previousWindowsPostMortemDebuggerValues{$value};
+ !$result or print "Failed to restore \"$windowsPostMortemDebuggerKey/$value\" to its previous value \"$previousWindowsPostMortemDebuggerValues{$value}\"\n.";
+ }
+}
diff --git a/WebKitTools/Scripts/prepare-ChangeLog b/WebKitTools/Scripts/prepare-ChangeLog
index 1488939..45aca1b 100755
--- a/WebKitTools/Scripts/prepare-ChangeLog
+++ b/WebKitTools/Scripts/prepare-ChangeLog
@@ -433,11 +433,16 @@ if ($spewDiff && @changed_files) {
# Open ChangeLogs.
if ($openChangeLogs && @logs) {
print STDERR " Opening the edited ChangeLog files.\n";
- my $editor = $ENV{"CHANGE_LOG_EDIT_APPLICATION"};
+ my $editor = $ENV{CHANGE_LOG_EDITOR};
if ($editor) {
- system "open", "-a", $editor, @logs;
+ system ((split ' ', $editor), @logs);
} else {
- system "open", "-e", @logs;
+ $editor = $ENV{CHANGE_LOG_EDIT_APPLICATION};
+ if ($editor) {
+ system "open", "-a", $editor, @logs;
+ } else {
+ system "open", "-e", @logs;
+ }
}
}
diff --git a/WebKitTools/Scripts/webkit-patch b/WebKitTools/Scripts/webkit-patch
index 8300b9f..007f919 100755
--- a/WebKitTools/Scripts/webkit-patch
+++ b/WebKitTools/Scripts/webkit-patch
@@ -38,6 +38,7 @@ import sys
from webkitpy.common.system.logutils import configure_logging
import webkitpy.python24.versioning as versioning
+_log = logging.getLogger("webkit-patch")
def main():
# This is a hack to let us enable DEBUG logging as early as possible.
@@ -50,6 +51,11 @@ def main():
configure_logging(logging_level=logging_level)
versioning.check_version()
+
+ if sys.platform == "win32":
+ _log.fatal("webkit-patch is only supported under Cygwin Python, "
+ "not Win32 Python")
+ sys.exit(1)
# Import webkit-patch code only after version-checking so that
# script doesn't error out before having a chance to report the
diff --git a/WebKitTools/Scripts/webkitdirs.pm b/WebKitTools/Scripts/webkitdirs.pm
index 028d63d..6530244 100644
--- a/WebKitTools/Scripts/webkitdirs.pm
+++ b/WebKitTools/Scripts/webkitdirs.pm
@@ -1302,6 +1302,21 @@ sub autotoolsFlag($$)
return $prefix . '-' . $feature;
}
+sub autogenArgumentsHaveChanged($@)
+{
+ my ($filename, @currentArguments) = @_;
+
+ if (! -e $filename) {
+ return 1;
+ }
+
+ open(AUTOTOOLS_ARGUMENTS, $filename);
+ chomp(my $previousArguments = <AUTOTOOLS_ARGUMENTS>);
+ close(AUTOTOOLS_ARGUMENTS);
+
+ return $previousArguments ne join(" ", @currentArguments);
+}
+
sub buildAutotoolsProject($@)
{
my ($clean, @buildParams) = @_;
@@ -1357,8 +1372,16 @@ sub buildAutotoolsProject($@)
# If GNUmakefile exists, don't run autogen.sh. The makefile should be
# smart enough to track autotools dependencies and re-run autogen.sh
# when build files change.
+ my $autogenArgumentsFile = "previous-autogen-arguments.txt";
my $result;
- if (! -e "GNUmakefile") {
+ if (!(-e "GNUmakefile") or autogenArgumentsHaveChanged($autogenArgumentsFile, @buildArgs)) {
+
+ # Write autogen.sh arguments to a file so that we can detect
+ # when they change and automatically re-run it.
+ open(AUTOTOOLS_ARGUMENTS, ">$autogenArgumentsFile");
+ print AUTOTOOLS_ARGUMENTS join(" ", @buildArgs);
+ close(AUTOTOOLS_ARGUMENTS);
+
print "Calling configure in " . $dir . "\n\n";
print "Installation prefix directory: $prefix\n" if(defined($prefix));
diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
index 569558a..5a6c48c 100644
--- a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
+++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
@@ -38,6 +38,40 @@ from webkitpy.common.system.executive import Executive, run_command, ScriptError
from webkitpy.common.system.deprecated_logging import error, log
+def find_checkout_root():
+ """Returns the current checkout root (as determined by default_scm().
+
+ Returns the absolute path to the top of the WebKit checkout, or None
+ if it cannot be determined.
+
+ """
+ scm_system = default_scm()
+ if scm_system:
+ return scm_system.checkout_root
+ return None
+
+
+def default_scm():
+ """Return the default SCM object as determined by the CWD and running code.
+
+ Returns the default SCM object for the current working directory; if the
+ CWD is not in a checkout, then we attempt to figure out if the SCM module
+ itself is part of a checkout, and return that one. If neither is part of
+ a checkout, None is returned.
+
+ """
+ cwd = os.getcwd()
+ scm_system = detect_scm_system(cwd)
+ if not scm_system:
+ script_directory = os.path.abspath(sys.path[0])
+ scm_system = detect_scm_system(script_directory)
+ if scm_system:
+ log("The current directory (%s) is not a WebKit checkout, using %s" % (cwd, scm_system.checkout_root))
+ else:
+ error("FATAL: Failed to determine the SCM system for either %s or %s" % (cwd, script_directory))
+ return scm_system
+
+
def detect_scm_system(path):
absolute_path = os.path.abspath(path)
diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py
index 852f838..87d5539 100644
--- a/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py
@@ -36,6 +36,7 @@ import os
import os.path
import re
import stat
+import sys
import subprocess
import tempfile
import unittest
@@ -44,10 +45,11 @@ import shutil
from datetime import date
from webkitpy.common.checkout.api import Checkout
-from webkitpy.common.checkout.scm import detect_scm_system, SCM, SVN, CheckoutNeedsUpdate, commit_error_handler, AuthenticationError, AmbiguousCommitError
+from webkitpy.common.checkout.scm import detect_scm_system, SCM, SVN, CheckoutNeedsUpdate, commit_error_handler, AuthenticationError, AmbiguousCommitError, find_checkout_root, default_scm
from webkitpy.common.config.committers import Committer # FIXME: This should not be needed
from webkitpy.common.net.bugzilla import Attachment # FIXME: This should not be needed
from webkitpy.common.system.executive import Executive, run_command, ScriptError
+from webkitpy.common.system.outputcapture import OutputCapture
# Eventually we will want to write tests which work for both scms. (like update_webkit, changed_files, etc.)
# Perhaps through some SCMTest base-class which both SVNTest and GitTest inherit from.
@@ -174,6 +176,57 @@ class SVNTestRepository:
# Change back to a valid directory so that later calls to os.getcwd() do not fail.
os.chdir(detect_scm_system(os.path.dirname(__file__)).checkout_root)
+
+class StandaloneFunctionsTest(unittest.TestCase):
+ """This class tests any standalone/top-level functions in the package."""
+ def setUp(self):
+ self.orig_cwd = os.path.abspath(os.getcwd())
+ self.orig_abspath = os.path.abspath
+
+ # We capture but ignore the output from stderr to reduce unwanted
+ # logging.
+ self.output = OutputCapture()
+ self.output.capture_output()
+
+ def tearDown(self):
+ os.chdir(self.orig_cwd)
+ os.path.abspath = self.orig_abspath
+ self.output.restore_output()
+
+ def test_find_checkout_root(self):
+ # Test from inside the tree.
+ os.chdir(sys.path[0])
+ dir = find_checkout_root()
+ self.assertNotEqual(dir, None)
+ self.assertTrue(os.path.exists(dir))
+
+ # Test from outside the tree.
+ os.chdir(os.path.expanduser("~"))
+ dir = find_checkout_root()
+ self.assertNotEqual(dir, None)
+ self.assertTrue(os.path.exists(dir))
+
+ # Mock out abspath() to test being not in a checkout at all.
+ os.path.abspath = lambda x: "/"
+ self.assertRaises(SystemExit, find_checkout_root)
+ os.path.abspath = self.orig_abspath
+
+ def test_default_scm(self):
+ # Test from inside the tree.
+ os.chdir(sys.path[0])
+ scm = default_scm()
+ self.assertNotEqual(scm, None)
+
+ # Test from outside the tree.
+ os.chdir(os.path.expanduser("~"))
+ dir = find_checkout_root()
+ self.assertNotEqual(dir, None)
+
+ # Mock out abspath() to test being not in a checkout at all.
+ os.path.abspath = lambda x: "/"
+ self.assertRaises(SystemExit, default_scm)
+ os.path.abspath = self.orig_abspath
+
# For testing the SCM baseclass directly.
class SCMClassTests(unittest.TestCase):
def setUp(self):
diff --git a/WebKitTools/Scripts/webkitpy/common/config/committers.py b/WebKitTools/Scripts/webkitpy/common/config/committers.py
index 5ebf18a..7543d69 100644
--- a/WebKitTools/Scripts/webkitpy/common/config/committers.py
+++ b/WebKitTools/Scripts/webkitpy/common/config/committers.py
@@ -139,6 +139,7 @@ committers_unable_to_review = [
Committer("Krzysztof Kowalczyk", "kkowalczyk@gmail.com"),
Committer("Leandro Pereira", ["leandro@profusion.mobi", "leandro@webkit.org"], "acidx"),
Committer("Levi Weintraub", "lweintraub@apple.com"),
+ Committer("Lucas De Marchi", ["lucas.demarchi@profusion.mobi", "demarchi@webkit.org"], "demarchi"),
Committer("Luiz Agostini", ["luiz@webkit.org", "luiz.agostini@openbossa.org"], "lca"),
Committer("Mads Ager", "ager@chromium.org"),
Committer("Marcus Voltis Bulach", "bulach@chromium.org"),
@@ -146,7 +147,6 @@ committers_unable_to_review = [
Committer("Matt Perry", "mpcomplete@chromium.org"),
Committer("Maxime Britto", ["maxime.britto@gmail.com", "britto@apple.com"]),
Committer("Maxime Simon", ["simon.maxime@gmail.com", "maxime.simon@webkit.org"], "maxime.simon"),
- Committer("Martin Robinson", ["mrobinson@igalia.com", "mrobinson@webkit.org", "martin.james.robinson@gmail.com"], "mrobinson"),
Committer("Michelangelo De Simone", "michelangelo@webkit.org", "michelangelo"),
Committer("Mike Belshe", ["mbelshe@chromium.org", "mike@belshe.com"]),
Committer("Mike Fenton", ["mifenton@rim.com", "mike.fenton@torchmobile.com"], "mfenton"),
@@ -179,7 +179,7 @@ committers_unable_to_review = [
Committer("Yuzo Fujishima", "yuzo@google.com", "yuzo"),
Committer("Zhenyao Mo", "zmo@google.com", "zhenyao"),
Committer("Zoltan Herczeg", "zherczeg@webkit.org", "zherczeg"),
- Committer("Zoltan Horvath", "zoltan@webkit.org", "zoltan"),
+ Committer("Zoltan Horvath", ["zoltan@webkit.org", "hzoltan@inf.u-szeged.hu", "horvath.zoltan.6@stud.u-szeged.hu"], "zoltan"),
]
@@ -200,7 +200,7 @@ reviewers_list = [
Reviewer("Anders Carlsson", ["andersca@apple.com", "acarlsson@apple.com"], "andersca"),
Reviewer("Antonio Gomes", "tonikitoo@webkit.org", "tonikitoo"),
Reviewer("Antti Koivisto", ["koivisto@iki.fi", "antti@apple.com"], "anttik"),
- Reviewer("Ariya Hidayat", ["ariya.hidayat@gmail.com", "ariya@webkit.org"], "ariya"),
+ Reviewer("Ariya Hidayat", ["ariya@sencha.com", "ariya.hidayat@gmail.com", "ariya@webkit.org"], "ariya"),
Reviewer("Beth Dakin", "bdakin@apple.com", "dethbakin"),
Reviewer("Brady Eidson", "beidson@apple.com", "bradee-oh"),
Reviewer("Cameron Zwarich", ["zwarich@apple.com", "cwzwarich@apple.com", "cwzwarich@webkit.org"]),
@@ -225,7 +225,7 @@ reviewers_list = [
Reviewer("Gavin Barraclough", "barraclough@apple.com", "gbarra"),
Reviewer("Geoffrey Garen", "ggaren@apple.com", "ggaren"),
Reviewer("George Staikos", ["staikos@kde.org", "staikos@webkit.org"]),
- Reviewer("Gustavo Noronha Silva", ["gns@gnome.org", "kov@webkit.org"], "kov"),
+ Reviewer("Gustavo Noronha Silva", ["gns@gnome.org", "kov@webkit.org", "gustavo.noronha@collabora.co.uk"], "kov"),
Reviewer("Holger Freyther", ["zecke@selfish.org", "zecke@webkit.org"], "zecke"),
Reviewer("Jan Alonzo", ["jmalonzo@gmail.com", "jmalonzo@webkit.org"], "janm"),
Reviewer("Jeremy Orlow", "jorlow@chromium.org", "jorlow"),
@@ -244,6 +244,7 @@ reviewers_list = [
Reviewer("Laszlo Gombos", "laszlo.1.gombos@nokia.com", "lgombos"),
Reviewer("Maciej Stachowiak", "mjs@apple.com", "othermaciej"),
Reviewer("Mark Rowe", "mrowe@apple.com", "bdash"),
+ Reviewer("Martin Robinson", ["mrobinson@igalia.com", "mrobinson@webkit.org", "martin.james.robinson@gmail.com"], "mrobinson"),
Reviewer("Nate Chapin", "japhet@chromium.org", "japhet"),
Reviewer("Nikolas Zimmermann", ["zimmermann@kde.org", "zimmermann@physik.rwth-aachen.de", "zimmermann@webkit.org"], "wildfox"),
Reviewer("Ojan Vafai", "ojan@chromium.org", "ojan"),
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests.py
new file mode 100644
index 0000000..bb63f5e
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests.py
@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+# 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:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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.
+
+"""deduplicate_tests -- lists duplicated between platforms.
+
+If platform/mac-leopard is missing an expected test output, we fall back on
+platform/mac. This means it's possible to grow redundant test outputs,
+where we have the same expected data in both a platform directory and another
+platform it falls back on.
+"""
+
+import collections
+import fnmatch
+import os
+import subprocess
+import sys
+import re
+import webkitpy.common.system.executive as executive
+import webkitpy.common.system.logutils as logutils
+import webkitpy.layout_tests.port.factory as port_factory
+
+_log = logutils.get_logger(__file__)
+
+_BASE_PLATFORM = 'base'
+
+
+def port_fallbacks():
+ """Get the port fallback information.
+ Returns:
+ A dictionary mapping platform name to a list of other platforms to fall
+ back on. All platforms fall back on 'base'.
+ """
+ fallbacks = {_BASE_PLATFORM: []}
+ for port_name in os.listdir(os.path.join('LayoutTests', 'platform')):
+ try:
+ platforms = port_factory.get(port_name).baseline_search_path()
+ except NotImplementedError:
+ _log.error("'%s' lacks baseline_search_path(), please fix." % port_name)
+ fallbacks[port_name] = [_BASE_PLATFORM]
+ continue
+ fallbacks[port_name] = [os.path.basename(p) for p in platforms][1:]
+ fallbacks[port_name].append(_BASE_PLATFORM)
+ return fallbacks
+
+
+def parse_git_output(git_output, glob_pattern):
+ """Parses the output of git ls-tree and filters based on glob_pattern.
+ Args:
+ git_output: result of git ls-tree -r HEAD LayoutTests.
+ glob_pattern: a pattern to filter the files.
+ Returns:
+ A dictionary mapping (test name, hash of content) => [paths]
+ """
+ hashes = collections.defaultdict(set)
+ for line in git_output.split('\n'):
+ if not line:
+ break
+ attrs, path = line.strip().split('\t')
+ if not fnmatch.fnmatch(path, glob_pattern):
+ continue
+ path = path[len('LayoutTests/'):]
+ match = re.match(r'^(platform/.*?/)?(.*)', path)
+ test = match.group(2)
+ _, _, hash = attrs.split(' ')
+ hashes[(test, hash)].add(path)
+ return hashes
+
+
+def cluster_file_hashes(glob_pattern):
+ """Get the hashes of all the test expectations in the tree.
+ We cheat and use git's hashes.
+ Args:
+ glob_pattern: a pattern to filter the files.
+ Returns:
+ A dictionary mapping (test name, hash of content) => [paths]
+ """
+
+ # A map of file hash => set of all files with that hash.
+ hashes = collections.defaultdict(set)
+
+ # Fill in the map.
+ cmd = ('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests')
+ try:
+ git_output = executive.Executive().run_command(cmd)
+ except OSError, e:
+ if e.errno == 2: # No such file or directory.
+ _log.error("Error: 'No such file' when running git.")
+ _log.error("This script requires git.")
+ sys.exit(1)
+ raise e
+ return parse_git_output(git_output, glob_pattern)
+
+
+def extract_platforms(paths):
+ """Extracts the platforms from a list of paths matching ^platform/(.*?)/.
+ Args:
+ paths: a list of paths.
+ Returns:
+ A dictionary containing all platforms from paths.
+ """
+ platforms = {}
+ for path in paths:
+ match = re.match(r'^platform/(.*?)/', path)
+ if match:
+ platform = match.group(1)
+ else:
+ platform = _BASE_PLATFORM
+ platforms[platform] = path
+ return platforms
+
+
+def find_dups(hashes, port_fallbacks):
+ """Yields info about redundant test expectations.
+ Args:
+ hashes: a list of hashes as returned by cluster_file_hashes.
+ port_fallbacks: a list of fallback information as returned by get_port_fallbacks.
+ Returns:
+ a tuple containing (test, platform, fallback, platforms)
+ """
+ for (test, hash), cluster in hashes.items():
+ if len(cluster) < 2:
+ continue # Common case: only one file with that hash.
+
+ # Compute the list of platforms we have this particular hash for.
+ platforms = extract_platforms(cluster)
+ if len(platforms) == 1:
+ continue
+
+ # See if any of the platforms are redundant with each other.
+ for platform in platforms.keys():
+ for fallback in port_fallbacks[platform]:
+ if fallback in platforms.keys():
+ yield test, platform, fallback, platforms[platform]
+
+
+def deduplicate(glob_pattern):
+ """Traverses LayoutTests and returns information about duplicated files.
+ Args:
+ glob pattern to filter the files in LayoutTests.
+ Returns:
+ a dictionary containing test, path, platform and fallback.
+ """
+ fallbacks = port_fallbacks()
+ hashes = cluster_file_hashes(glob_pattern)
+ return [{'test': test, 'path': path, 'platform': platform, 'fallback': fallback}
+ for test, platform, fallback, path in find_dups(hashes, fallbacks)]
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py
new file mode 100644
index 0000000..66dda32
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+# 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:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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.
+
+"""Unit tests for deduplicate_tests.py."""
+
+import deduplicate_tests
+import os
+import unittest
+import webkitpy.common.checkout.scm as scm
+
+
+class MockExecutive(object):
+ last_run_command = []
+ response = ''
+
+ class Executive(object):
+ def run_command(self,
+ args,
+ cwd=None,
+ input=None,
+ error_handler=None,
+ return_exit_code=False,
+ return_stderr=True,
+ decode_output=True):
+ MockExecutive.last_run_command += [args]
+ return MockExecutive.response
+
+
+class ListDuplicatesTest(unittest.TestCase):
+ def setUp(self):
+ MockExecutive.last_run_command = []
+ MockExecutive.response = ''
+ deduplicate_tests.executive = MockExecutive
+ self._original_cwd = os.getcwd()
+ checkout_root = scm.find_checkout_root()
+ self.assertNotEqual(checkout_root, None)
+ os.chdir(checkout_root)
+
+ def tearDown(self):
+ os.chdir(self._original_cwd)
+
+ def test_parse_git_output(self):
+ git_output = (
+ '100644 blob 5053240b3353f6eb39f7cb00259785f16d121df2\tLayoutTests/mac/foo-expected.txt\n'
+ '100644 blob a004548d107ecc4e1ea08019daf0a14e8634a1ff\tLayoutTests/platform/chromium/foo-expected.txt\n'
+ '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/foo-expected.txt\n'
+ '100644 blob abcdebc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/animage.png\n'
+ '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/foo-expected.txt\n'
+ '100644 blob abcdebc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/animage.png\n'
+ '100644 blob 4303df5389ca87cae83dd3236b8dd84e16606517\tLayoutTests/platform/mac/foo-expected.txt\n')
+ hashes = deduplicate_tests.parse_git_output(git_output, '*')
+ expected = {('mac/foo-expected.txt', '5053240b3353f6eb39f7cb00259785f16d121df2'): set(['mac/foo-expected.txt']),
+ ('animage.png', 'abcdebc762e3aec5df03b5c04485b2cb3b65ffb1'): set(['platform/chromium-linux/animage.png', 'platform/chromium-win/animage.png']),
+ ('foo-expected.txt', '4303df5389ca87cae83dd3236b8dd84e16606517'): set(['platform/mac/foo-expected.txt']),
+ ('foo-expected.txt', 'd6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1'): set(['platform/chromium-linux/foo-expected.txt', 'platform/chromium-win/foo-expected.txt']),
+ ('foo-expected.txt', 'a004548d107ecc4e1ea08019daf0a14e8634a1ff'): set(['platform/chromium/foo-expected.txt'])}
+ self.assertEquals(expected, hashes)
+
+ hashes = deduplicate_tests.parse_git_output(git_output, '*.png')
+ expected = {('animage.png', 'abcdebc762e3aec5df03b5c04485b2cb3b65ffb1'): set(['platform/chromium-linux/animage.png', 'platform/chromium-win/animage.png'])}
+ self.assertEquals(expected, hashes)
+
+ def test_extract_platforms(self):
+ self.assertEquals({'foo': 'platform/foo/bar',
+ 'zoo': 'platform/zoo/com'},
+ deduplicate_tests.extract_platforms(['platform/foo/bar', 'platform/zoo/com']))
+ self.assertEquals({'foo': 'platform/foo/bar',
+ deduplicate_tests._BASE_PLATFORM: 'what/'},
+ deduplicate_tests.extract_platforms(['platform/foo/bar', 'what/']))
+
+ def test_unique(self):
+ MockExecutive.response = (
+ '100644 blob 5053240b3353f6eb39f7cb00259785f16d121df2\tLayoutTests/mac/foo-expected.txt\n'
+ '100644 blob a004548d107ecc4e1ea08019daf0a14e8634a1ff\tLayoutTests/platform/chromium/foo-expected.txt\n'
+ '100644 blob abcd0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/foo-expected.txt\n'
+ '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/foo-expected.txt\n'
+ '100644 blob 4303df5389ca87cae83dd3236b8dd84e16606517\tLayoutTests/platform/mac/foo-expected.txt\n')
+ result = deduplicate_tests.deduplicate('*')
+ self.assertEquals(1, len(MockExecutive.last_run_command))
+ self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
+ self.assertEquals(0, len(result))
+
+ def test_duplicates(self):
+ MockExecutive.response = (
+ '100644 blob 5053240b3353f6eb39f7cb00259785f16d121df2\tLayoutTests/mac/foo-expected.txt\n'
+ '100644 blob a004548d107ecc4e1ea08019daf0a14e8634a1ff\tLayoutTests/platform/chromium/foo-expected.txt\n'
+ '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/foo-expected.txt\n'
+ '100644 blob abcdebc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-linux/animage.png\n'
+ '100644 blob d6bb0bc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/foo-expected.txt\n'
+ '100644 blob abcdebc762e3aec5df03b5c04485b2cb3b65ffb1\tLayoutTests/platform/chromium-win/animage.png\n'
+ '100644 blob 4303df5389ca87cae83dd3236b8dd84e16606517\tLayoutTests/platform/mac/foo-expected.txt\n')
+
+ result = deduplicate_tests.deduplicate('*')
+ self.assertEquals(1, len(MockExecutive.last_run_command))
+ self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
+ self.assertEquals(2, len(result))
+ self.assertEquals({'test': 'animage.png',
+ 'path': 'platform/chromium-linux/animage.png',
+ 'fallback': 'chromium-win',
+ 'platform': 'chromium-linux'},
+ result[0])
+ self.assertEquals({'test': 'foo-expected.txt',
+ 'path': 'platform/chromium-linux/foo-expected.txt',
+ 'fallback': 'chromium-win',
+ 'platform': 'chromium-linux'},
+ result[1])
+
+ result = deduplicate_tests.deduplicate('*.txt')
+ self.assertEquals(2, len(MockExecutive.last_run_command))
+ self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
+ self.assertEquals(1, len(result))
+ self.assertEquals({'test': 'foo-expected.txt',
+ 'path': 'platform/chromium-linux/foo-expected.txt',
+ 'fallback': 'chromium-win',
+ 'platform': 'chromium-linux'},
+ result[0])
+
+ result = deduplicate_tests.deduplicate('*.png')
+ self.assertEquals(3, len(MockExecutive.last_run_command))
+ self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
+ self.assertEquals(1, len(result))
+ self.assertEquals({'test': 'animage.png',
+ 'path': 'platform/chromium-linux/animage.png',
+ 'fallback': 'chromium-win',
+ 'platform': 'chromium-linux'},
+ result[0])
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
index 6364511..6343400 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
@@ -54,9 +54,9 @@ _log = logging.getLogger("webkitpy.layout_tests.layout_package."
"dump_render_tree_thread")
-def process_output(port, test_info, test_types, test_args, configuration,
- output_dir, crash, timeout, test_run_time, actual_checksum,
- output, error):
+def _process_output(port, test_info, test_types, test_args, configuration,
+ output_dir, crash, timeout, test_run_time, actual_checksum,
+ output, error):
"""Receives the output from a DumpRenderTree process, subjects it to a
number of tests, and returns a list of failure types the test produced.
@@ -118,6 +118,21 @@ def process_output(port, test_info, test_types, test_args, configuration,
total_time_for_all_diffs, time_for_diffs)
+def _pad_timeout(timeout):
+ """Returns a safe multiple of the per-test timeout value to use
+ to detect hung test threads.
+
+ """
+ # When we're running one test per DumpRenderTree process, we can
+ # enforce a hard timeout. The DumpRenderTree watchdog uses 2.5x
+ # the timeout; we want to be larger than that.
+ return timeout * 3
+
+
+def _milliseconds_to_seconds(msecs):
+ return float(msecs) / 1000.0
+
+
class TestResult(object):
def __init__(self, filename, failures, test_run_time,
@@ -162,7 +177,7 @@ class SingleTestThread(threading.Thread):
driver.run_test(test_info.uri.strip(), test_info.timeout,
test_info.image_hash())
end = time.time()
- self._test_result = process_output(self._port,
+ self._test_result = _process_output(self._port,
test_info, self._test_types, self._test_args,
self._configuration, self._output_dir, crash, timeout, end - start,
actual_checksum, output, error)
@@ -172,8 +187,42 @@ class SingleTestThread(threading.Thread):
return self._test_result
-class TestShellThread(threading.Thread):
+class WatchableThread(threading.Thread):
+ """This class abstracts an interface used by
+ run_webkit_tests.TestRunner._wait_for_threads_to_finish for thread
+ management."""
+ def __init__(self):
+ threading.Thread.__init__(self)
+ self._canceled = False
+ self._exception_info = None
+ self._next_timeout = None
+ self._thread_id = None
+
+ def cancel(self):
+ """Set a flag telling this thread to quit."""
+ self._canceled = True
+
+ def clear_next_timeout(self):
+ """Mark a flag telling this thread to stop setting timeouts."""
+ self._timeout = 0
+
+ def exception_info(self):
+ """If run() terminated on an uncaught exception, return it here
+ ((type, value, traceback) tuple).
+ Returns None if run() terminated normally. Meant to be called after
+ joining this thread."""
+ return self._exception_info
+
+ def id(self):
+ """Return a thread identifier."""
+ return self._thread_id
+
+ def next_timeout(self):
+ """Return the time the test is supposed to finish by."""
+ return self._next_timeout
+
+class TestShellThread(WatchableThread):
def __init__(self, port, filename_list_queue, result_queue,
test_types, test_args, image_path, shell_args, options):
"""Initialize all the local state for this DumpRenderTree thread.
@@ -192,7 +241,7 @@ class TestShellThread(threading.Thread):
command-line options should match those expected by
run_webkit_tests; they are typically passed via the
run_webkit_tests.TestRunner class."""
- threading.Thread.__init__(self)
+ WatchableThread.__init__(self)
self._port = port
self._filename_list_queue = filename_list_queue
self._result_queue = result_queue
@@ -203,8 +252,6 @@ class TestShellThread(threading.Thread):
self._image_path = image_path
self._shell_args = shell_args
self._options = options
- self._canceled = False
- self._exception_info = None
self._directory_timing_stats = {}
self._test_results = []
self._num_tests = 0
@@ -231,17 +278,6 @@ class TestShellThread(threading.Thread):
"""
return self._test_results
- def cancel(self):
- """Set a flag telling this thread to quit."""
- self._canceled = True
-
- def get_exception_info(self):
- """If run() terminated on an uncaught exception, return it here
- ((type, value, traceback) tuple).
- Returns None if run() terminated normally. Meant to be called after
- joining this thread."""
- return self._exception_info
-
def get_total_time(self):
return max(self._stop_time - self._start_time, 0.0)
@@ -251,6 +287,7 @@ class TestShellThread(threading.Thread):
def run(self):
"""Delegate main work to a helper method and watch for uncaught
exceptions."""
+ self._thread_id = thread.get_ident()
self._start_time = time.time()
self._num_tests = 0
try:
@@ -384,10 +421,10 @@ class TestShellThread(threading.Thread):
worker.start()
- # When we're running one test per DumpRenderTree process, we can
- # enforce a hard timeout. The DumpRenderTree watchdog uses 2.5x
- # the timeout; we want to be larger than that.
- worker.join(int(test_info.timeout) * 3.0 / 1000.0)
+ thread_timeout = _milliseconds_to_seconds(
+ _pad_timeout(test_info.timeout))
+ thread._next_timeout = time.time() + thread_timeout
+ worker.join(thread_timeout)
if worker.isAlive():
# If join() returned with the thread still running, the
# DumpRenderTree is completely hung and there's nothing
@@ -433,11 +470,16 @@ class TestShellThread(threading.Thread):
not self._options.pixel_tests)):
image_hash = ""
start = time.time()
+
+ thread_timeout = _milliseconds_to_seconds(
+ _pad_timeout(test_info.timeout))
+ self._next_timeout = start + thread_timeout
+
crash, timeout, actual_checksum, output, error = \
self._driver.run_test(test_info.uri, test_info.timeout, image_hash)
end = time.time()
- result = process_output(self._port, test_info, self._test_types,
+ result = _process_output(self._port, test_info, self._test_types,
self._test_args, self._options.configuration,
self._options.results_directory, crash,
timeout, end - start, actual_checksum,
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
index 6c36c93..c6c3066 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
@@ -57,7 +57,7 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGeneratorBase
def __init__(self, port, builder_name, build_name, build_number,
results_file_base_path, builder_base_url,
test_timings, expectations, result_summary, all_tests,
- generate_incremental_results=False):
+ generate_incremental_results=False, test_results_server=None):
"""Modifies the results.json file. Grabs it off the archive directory
if it is not found locally.
@@ -68,7 +68,7 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGeneratorBase
super(JSONLayoutResultsGenerator, self).__init__(
builder_name, build_name, build_number, results_file_base_path,
builder_base_url, {}, port.test_repository_paths(),
- generate_incremental_results)
+ generate_incremental_results, test_results_server)
self._port = port
self._expectations = expectations
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
index e746bc0..15eceee 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
@@ -84,10 +84,14 @@ class JSONResultsGeneratorBase(object):
RESULTS_FILENAME = "results.json"
INCREMENTAL_RESULTS_FILENAME = "incremental_results.json"
+ URL_FOR_TEST_LIST_JSON = \
+ "http://%s/testfile?builder=%s&name=%s&testlistjson=1"
+
def __init__(self, builder_name, build_name, build_number,
results_file_base_path, builder_base_url,
test_results_map, svn_repositories=None,
- generate_incremental_results=False):
+ generate_incremental_results=False,
+ test_results_server=None):
"""Modifies the results.json file. Grabs it off the archive directory
if it is not found locally.
@@ -103,6 +107,9 @@ class JSONResultsGeneratorBase(object):
svn_repositories: A (json_field_name, svn_path) pair for SVN
repositories that tests rely on. The SVN revision will be
included in the JSON with the given json_field_name.
+ generate_incremental_results: If true, generate incremental json file
+ from current run results.
+ test_results_server: server that hosts test results json.
"""
self._builder_name = builder_name
self._build_name = build_name
@@ -121,6 +128,8 @@ class JSONResultsGeneratorBase(object):
if not self._svn_repositories:
self._svn_repositories = {}
+ self._test_results_server = test_results_server
+
self._json = None
self._archived_results = None
@@ -144,25 +153,24 @@ class JSONResultsGeneratorBase(object):
def get_json(self, incremental=False):
"""Gets the results for the results.json file."""
- if incremental:
- results_json = {}
- else:
+ results_json = {}
+ if not incremental:
if self._json:
return self._json
- if not self._archived_results:
- self._archived_results, error = \
- self._get_archived_json_results()
- if error:
- # If there was an error don't write a results.json
- # file at all as it would lose all the information on the
- # bot.
- _log.error("Archive directory is inaccessible. Not "
- "modifying or clobbering the results.json "
- "file: " + str(error))
- return None
+ if self._archived_results:
+ results_json = self._archived_results
- results_json = self._archived_results
+ if not results_json:
+ results_json, error = self._get_archived_json_results(incremental)
+ if error:
+ # If there was an error don't write a results.json
+ # file at all as it would lose all the information on the
+ # bot.
+ _log.error("Archive directory is inaccessible. Not "
+ "modifying or clobbering the results.json "
+ "file: " + str(error))
+ return None
builder_name = self._builder_name
if results_json and builder_name not in results_json:
@@ -186,7 +194,7 @@ class JSONResultsGeneratorBase(object):
all_failing_tests = self._get_failed_test_names()
all_failing_tests.update(tests.iterkeys())
for test in all_failing_tests:
- self._insert_test_time_and_result(test, tests)
+ self._insert_test_time_and_result(test, tests, incremental)
return results_json
@@ -253,24 +261,40 @@ class JSONResultsGeneratorBase(object):
return ""
return ""
- def _get_archived_json_results(self):
+ def _get_archived_json_results(self, for_incremental=False):
"""Reads old results JSON file if it exists.
Returns (archived_results, error) tuple where error is None if results
were successfully read.
+
+ if for_incremental is True, download JSON file that only contains test
+ name list from test-results server. This is for generating incremental
+ JSON so the file generated has info for tests that failed before but
+ pass or are skipped from current run.
"""
results_json = {}
old_results = None
error = None
- if os.path.exists(self._results_file_path):
+ if os.path.exists(self._results_file_path) and not for_incremental:
with codecs.open(self._results_file_path, "r", "utf-8") as file:
old_results = file.read()
- elif self._builder_base_url:
- # Check if we have the archived JSON file on the buildbot server.
- results_file_url = (self._builder_base_url +
- self._build_name + "/" + self.RESULTS_FILENAME)
- _log.error("Local results.json file does not exist. Grabbing "
- "it off the archive at " + results_file_url)
+ elif self._builder_base_url or for_incremental:
+ if for_incremental:
+ if not self._test_results_server:
+ # starting from fresh if no test results server specified.
+ return {}, None
+
+ results_file_url = (self.URL_FOR_TEST_LIST_JSON %
+ (urllib2.quote(self._test_results_server),
+ urllib2.quote(self._builder_name),
+ self.RESULTS_FILENAME))
+ else:
+ # Check if we have the archived JSON file on the buildbot
+ # server.
+ results_file_url = (self._builder_base_url +
+ self._build_name + "/" + self.RESULTS_FILENAME)
+ _log.error("Local results.json file does not exist. Grabbing "
+ "it off the archive at " + results_file_url)
try:
results_file = urllib2.urlopen(results_file_url)
@@ -387,7 +411,7 @@ class JSONResultsGeneratorBase(object):
int(time.time()),
self.TIME)
- def _insert_test_time_and_result(self, test_name, tests):
+ def _insert_test_time_and_result(self, test_name, tests, incremental=False):
""" Insert a test item with its results to the given tests dictionary.
Args:
@@ -401,9 +425,20 @@ class JSONResultsGeneratorBase(object):
tests[test_name] = self._create_results_and_times_json()
thisTest = tests[test_name]
- self._insert_item_run_length_encoded(result, thisTest[self.RESULTS])
- self._insert_item_run_length_encoded(time, thisTest[self.TIMES])
- self._normalize_results_json(thisTest, test_name, tests)
+ if self.RESULTS in thisTest:
+ self._insert_item_run_length_encoded(result, thisTest[self.RESULTS])
+ else:
+ thisTest[self.RESULTS] = [[1, result]]
+
+ if self.TIMES in thisTest:
+ self._insert_item_run_length_encoded(time, thisTest[self.TIMES])
+ else:
+ thisTest[self.TIMES] = [[1, time]]
+
+ # Don't normalize the incremental results json because we need results
+ # for tests that pass or have no data from current run.
+ if not incremental:
+ self._normalize_results_json(thisTest, test_name, tests)
def _convert_json_to_current_version(self, results_json):
"""If the JSON does not match the current version, converts it to the
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py
index f838a7b..81cdc9b 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py
@@ -123,12 +123,6 @@ def print_options():
help="show detailed help on controlling print output"),
optparse.make_option("-v", "--verbose", action="store_true",
default=False, help="include debug-level logging"),
-
- # FIXME: we should remove this; it's pretty much obsolete with the
- # --print trace-everything option.
- optparse.make_option("--sources", action="store_true",
- help=("show expected result file path for each test "
- "(implies --verbose)")),
]
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 38223dd..e154932 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
@@ -460,6 +460,9 @@ class TestExpectationsFile:
return ExpectationsJsonEncoder(separators=(',', ':')).encode(
self._all_expectations)
+ def get_non_fatal_errors(self):
+ return self._non_fatal_errors
+
def contains(self, test):
return test in self._test_to_expectations
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 60bdbca..3be9240 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py
@@ -250,15 +250,6 @@ class FailureImageHashMismatch(FailureWithType):
return "Image mismatch"
-class FailureFuzzyFailure(FailureWithType):
- """Image hashes didn't match."""
- OUT_FILENAMES = ["-actual.png", "-expected.png"]
-
- @staticmethod
- def message():
- return "Fuzzy image match also failed"
-
-
class FailureImageHashIncorrect(FailureWithType):
"""Actual result hash is incorrect."""
# Chrome doesn't know to display a .checksum file as text, so don't bother
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
index 8072bc0..e9a81e7 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
@@ -69,9 +69,9 @@ class ChromiumWinPort(chromium.ChromiumPort):
def baseline_search_path(self):
port_names = []
- if self._name == 'chromium-win-xp':
+ if self._name.endswith('-win-xp'):
port_names.append("chromium-win-xp")
- if self._name in ('chromium-win-xp', 'chromium-win-vista'):
+ if self._name.endswith('-win-xp') or self._name.endswith('-win-vista'):
port_names.append("chromium-win-vista")
# FIXME: This may need to include mac-snowleopard like win.py.
port_names.extend(["chromium-win", "chromium", "win", "mac"])
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py
index 95b90da..258bf33 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py
@@ -83,5 +83,8 @@ def get(port_name=None, options=None):
elif port_to_use.startswith('chromium-win'):
import chromium_win
return chromium_win.ChromiumWinPort(port_name, options)
+ elif port_to_use.startswith('google-chrome'):
+ import google_chrome
+ return google_chrome.GetGoogleChromePort(port_name, options)
raise NotImplementedError('unsupported port: %s' % port_to_use)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py
new file mode 100644
index 0000000..1ea053b
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+# 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.
+
+# 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.
+
+
+def GetGoogleChromePort(port_name, options):
+ """Some tests have slightly different results when compiled as Google
+ Chrome vs Chromium. In those cases, we prepend an additional directory to
+ to the baseline paths."""
+ if port_name == 'google-chrome-linux32':
+ import chromium_linux
+
+ class GoogleChromeLinux32Port(chromium_linux.ChromiumLinuxPort):
+ def baseline_search_path(self):
+ paths = chromium_linux.ChromiumLinuxPort.baseline_search_path(
+ self)
+ paths.insert(0, self._webkit_baseline_path(self._name))
+ return paths
+ return GoogleChromeLinux32Port(port_name, options)
+ elif port_name == 'google-chrome-linux64':
+ import chromium_linux
+
+ class GoogleChromeLinux64Port(chromium_linux.ChromiumLinuxPort):
+ def baseline_search_path(self):
+ paths = chromium_linux.ChromiumLinuxPort.baseline_search_path(
+ self)
+ paths.insert(0, self._webkit_baseline_path(self._name))
+ return paths
+ return GoogleChromeLinux64Port(port_name, options)
+ elif port_name.startswith('google-chrome-mac'):
+ import chromium_mac
+
+ class GoogleChromeMacPort(chromium_mac.ChromiumMacPort):
+ def baseline_search_path(self):
+ paths = chromium_mac.ChromiumMacPort.baseline_search_path(
+ self)
+ paths.insert(0, self._webkit_baseline_path(
+ 'google-chrome-mac'))
+ return paths
+ return GoogleChromeMacPort(port_name, options)
+ elif port_name.startswith('google-chrome-win'):
+ import chromium_win
+
+ class GoogleChromeWinPort(chromium_win.ChromiumWinPort):
+ def baseline_search_path(self):
+ paths = chromium_win.ChromiumWinPort.baseline_search_path(
+ self)
+ paths.insert(0, self._webkit_baseline_path(
+ 'google-chrome-win'))
+ return paths
+ return GoogleChromeWinPort(port_name, options)
+ raise NotImplementedError('unsupported port: %s' % port_name)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py
new file mode 100644
index 0000000..a2d7056
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+# 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.
+
+# 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.
+
+import os
+import unittest
+import google_chrome
+
+
+class GetGoogleChromePortTest(unittest.TestCase):
+ def test_get_google_chrome_port(self):
+ test_ports = ('google-chrome-linux32', 'google-chrome-linux64',
+ 'google-chrome-mac', 'google-chrome-win')
+ for port in test_ports:
+ self._verify_baseline_path(port, port)
+
+ self._verify_baseline_path('google-chrome-mac', 'google-chrome-mac-leopard')
+ self._verify_baseline_path('google-chrome-win', 'google-chrome-win-xp')
+ self._verify_baseline_path('google-chrome-win', 'google-chrome-win-vista')
+
+ def _verify_baseline_path(self, expected_path, port_name):
+ port = google_chrome.GetGoogleChromePort(port_name, None)
+ path = port.baseline_search_path()[0]
+ self.assertEqual(expected_path, os.path.split(path)[1])
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
index 6eef54e..9c9ab0a 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
@@ -124,6 +124,9 @@ class TestPort(base.Port):
def test_platform_names(self):
return self.test_base_platform_names()
+ def test_platform_name_to_name(self, test_platform_name):
+ return test_platform_name
+
def version():
return ''
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
index fa4df9b..92f1032 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
@@ -59,7 +59,6 @@ import webbrowser
import zipfile
from webkitpy.common.system.executive import run_command, ScriptError
-from webkitpy.common.checkout.scm import detect_scm_system
import webkitpy.common.checkout.scm as scm
import port
@@ -240,7 +239,7 @@ class Rebaseliner(object):
self._platform,
False,
False)
- self._scm = detect_scm_system(os.getcwd())
+ self._scm = scm.default_scm()
def run(self, backup):
"""Run rebaseline process."""
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py
index fa03238..121b64e 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py
@@ -84,5 +84,19 @@ class TestGetHostPortObject(unittest.TestCase):
port.get = old_get
+class TestRebaseliner(unittest.TestCase):
+
+ def test_noop(self):
+ # this method tests that was can at least instantiate an object, even
+ # if there is nothing to do.
+ options = MockOptions()
+ host_port_obj = port.get('test', options)
+ target_options = options
+ target_port_obj = port.get('test', target_options)
+ platform = 'test'
+ rebaseliner = rebaseline_chromium_webkit_tests.Rebaseliner(
+ host_port_obj, target_port_obj, platform, options)
+ self.assertNotEqual(rebaseliner, None)
+
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
index 490ac3c..b26bc6c 100755
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -53,6 +53,7 @@ import logging
import math
import optparse
import os
+import pdb
import platform
import Queue
import random
@@ -70,7 +71,6 @@ from layout_package import test_expectations
from layout_package import test_failures
from layout_package import test_files
from layout_package import test_results_uploader
-from test_types import fuzzy_image_diff
from test_types import image_diff
from test_types import text_diff
from test_types import test_type_base
@@ -578,8 +578,6 @@ class TestRunner:
test_args.new_baseline = self._options.new_baseline
test_args.reset_results = self._options.reset_results
- test_args.show_sources = self._options.sources
-
if self._options.startup_dialog:
shell_args.append('--testshell-startup-dialog')
@@ -629,35 +627,12 @@ class TestRunner:
"""Returns whether we should run all the tests in the main thread."""
return int(self._options.child_processes) == 1
- def _dump_thread_states(self):
- for thread_id, stack in sys._current_frames().items():
- # FIXME: Python 2.6 has thread.ident which we could
- # use to map from thread_id back to thread.name
- print "\n# Thread: %d" % thread_id
- for filename, lineno, name, line in traceback.extract_stack(stack):
- print 'File: "%s", line %d, in %s' % (filename, lineno, name)
- if line:
- print " %s" % (line.strip())
-
- def _dump_thread_states_if_necessary(self):
- # HACK: Dump thread states every minute to figure out what's
- # hanging on the bots.
- if not self._options.verbose:
- return
- dump_threads_every = 60 # Dump every minute
- if not self._last_thread_dump:
- self._last_thread_dump = time.time()
- time_since_last_dump = time.time() - self._last_thread_dump
- if time_since_last_dump > dump_threads_every:
- self._dump_thread_states()
- self._last_thread_dump = time.time()
-
def _run_tests(self, file_list, result_summary):
"""Runs the tests in the file_list.
- Return: A tuple (failures, thread_timings, test_timings,
+ Return: A tuple (keyboard_interrupted, thread_timings, test_timings,
individual_test_timings)
- failures is a map from test to list of failure types
+ keyboard_interrupted is whether someone typed Ctrl^C
thread_timings is a list of dicts with the total runtime
of each thread with 'name', 'num_tests', 'total_time' properties
test_timings is a list of timings for each sharded subdirectory
@@ -676,44 +651,55 @@ class TestRunner:
result_summary)
self._printer.print_update("Starting testing ...")
- # Wait for the threads to finish and collect test failures.
- failures = {}
- test_timings = {}
- individual_test_timings = []
- thread_timings = []
+ keyboard_interrupted = self._wait_for_threads_to_finish(threads,
+ result_summary)
+ (thread_timings, test_timings, individual_test_timings) = \
+ self._collect_timing_info(threads)
+
+ return (keyboard_interrupted, thread_timings, test_timings,
+ individual_test_timings)
+
+ def _wait_for_threads_to_finish(self, threads, result_summary):
keyboard_interrupted = False
try:
# Loop through all the threads waiting for them to finish.
- for thread in threads:
- # FIXME: We'll end up waiting on the first thread the whole
- # time. That means we won't notice exceptions on other
- # threads until the first one exits.
- # We should instead while True: in the outer loop
- # and then loop through threads joining and checking
- # isAlive and get_exception_info. Exiting on any exception.
- while thread.isAlive():
- # Wake the main thread every 0.1 seconds so we
- # can call update_summary in a timely fashion.
- thread.join(0.1)
- # HACK: Used for debugging threads on the bots.
- self._dump_thread_states_if_necessary()
- self.update_summary(result_summary)
+ some_thread_is_alive = True
+ while some_thread_is_alive:
+ some_thread_is_alive = False
+ t = time.time()
+ for thread in threads:
+ exception_info = thread.exception_info()
+ if exception_info is not None:
+ # Re-raise the thread's exception here to make it
+ # clear that testing was aborted. Otherwise,
+ # the tests that did not run would be assumed
+ # to have passed.
+ raise (exception_info[0], exception_info[1],
+ exception_info[2])
+
+ if thread.isAlive():
+ some_thread_is_alive = True
+ next_timeout = thread.next_timeout()
+ if (next_timeout and t > next_timeout):
+ _log_wedged_thread(thread)
+ thread.clear_next_timeout()
+
+ self.update_summary(result_summary)
+
+ if some_thread_is_alive:
+ time.sleep(0.1)
except KeyboardInterrupt:
keyboard_interrupted = True
for thread in threads:
thread.cancel()
- if not keyboard_interrupted:
- for thread in threads:
- # Check whether a thread died before normal completion.
- exception_info = thread.get_exception_info()
- if exception_info is not None:
- # Re-raise the thread's exception here to make it clear
- # something went wrong. Otherwise, the tests that did not
- # run would be assumed to have passed.
- raise (exception_info[0], exception_info[1],
- exception_info[2])
+ return keyboard_interrupted
+
+ def _collect_timing_info(self, threads):
+ test_timings = {}
+ individual_test_timings = []
+ thread_timings = []
for thread in threads:
thread_timings.append({'name': thread.getName(),
@@ -721,8 +707,8 @@ class TestRunner:
'total_time': thread.get_total_time()})
test_timings.update(thread.get_directory_timing_stats())
individual_test_timings.extend(thread.get_test_results())
- return (keyboard_interrupted, thread_timings, test_timings,
- individual_test_timings)
+
+ return (thread_timings, test_timings, individual_test_timings)
def needs_http(self):
"""Returns whether the test runner needs an HTTP server."""
@@ -890,7 +876,8 @@ class TestRunner:
self._options.build_number, self._options.results_directory,
BUILDER_BASE_URL, individual_test_timings,
self._expectations, result_summary, self._test_files_list,
- not self._options.upload_full_results)
+ not self._options.upload_full_results,
+ self._options.test_results_server)
_log.debug("Finished writing JSON files.")
@@ -1440,8 +1427,6 @@ def run(port_obj, options, args, regular_output=sys.stderr,
test_runner.add_test_type(text_diff.TestTextDiff)
if options.pixel_tests:
test_runner.add_test_type(image_diff.ImageDiff)
- if options.fuzzy_pixel_tests:
- test_runner.add_test_type(fuzzy_image_diff.FuzzyImageDiff)
num_unexpected_results = test_runner.run(result_summary)
@@ -1524,9 +1509,6 @@ def parse_args(args=None):
dest="pixel_tests", help="Enable pixel-to-pixel PNG comparisons"),
optparse.make_option("--no-pixel-tests", action="store_false",
dest="pixel_tests", help="Disable pixel-to-pixel PNG comparisons"),
- optparse.make_option("--fuzzy-pixel-tests", action="store_true",
- default=False,
- help="Also use fuzzy matching to compare pixel test outputs."),
# old-run-webkit-tests allows a specific tolerance: --tolerance t
# Ignore image differences less than this percentage (default: 0.1)
optparse.make_option("--results-directory",
@@ -1674,12 +1656,38 @@ def parse_args(args=None):
option_parser = optparse.OptionParser(option_list=option_list)
options, args = option_parser.parse_args(args)
- if options.sources:
- options.verbose = True
return options, args
+def _find_thread_stack(id):
+ """Returns a stack object that can be used to dump a stack trace for
+ the given thread id (or None if the id is not found)."""
+ for thread_id, stack in sys._current_frames().items():
+ if thread_id == id:
+ return stack
+ return None
+
+
+def _log_stack(stack):
+ """Log a stack trace to log.error()."""
+ for filename, lineno, name, line in traceback.extract_stack(stack):
+ _log.error('File: "%s", line %d, in %s' % (filename, lineno, name))
+ if line:
+ _log.error(' %s' % line.strip())
+
+
+def _log_wedged_thread(thread):
+ """Log information about the given thread state."""
+ id = thread.id()
+ stack = _find_thread_stack(id)
+ assert(stack is not None)
+ _log.error("")
+ _log.error("thread %s (%d) is wedged" % (thread.getName(), id))
+ _log_stack(stack)
+ _log.error("")
+
+
def main():
options, args = parse_args()
port_obj = port.get(options.platform, options)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
index 1c751d6..e1b3746 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
@@ -30,13 +30,20 @@
"""Unit tests for run_webkit_tests."""
import codecs
+import logging
import os
+import pdb
+import Queue
import sys
+import thread
+import time
+import threading
import unittest
from webkitpy.common import array_stream
from webkitpy.layout_tests import port
from webkitpy.layout_tests import run_webkit_tests
+from webkitpy.layout_tests.layout_package import dump_render_tree_thread
from webkitpy.thirdparty.mock import Mock
@@ -92,6 +99,7 @@ class MainTest(unittest.TestCase):
self.assertEqual(buildbot_output.get(), [])
+
def _mocked_open(original_open, file_list):
def _wrapper(name, mode, encoding):
if name.find("-expected.") != -1 and mode == "w":
@@ -191,5 +199,110 @@ class DryrunTest(unittest.TestCase):
'fast/html']))
+class TestThread(dump_render_tree_thread.WatchableThread):
+ def __init__(self, started_queue, stopping_queue):
+ dump_render_tree_thread.WatchableThread.__init__(self)
+ self._started_queue = started_queue
+ self._stopping_queue = stopping_queue
+ self._timeout = False
+ self._timeout_queue = Queue.Queue()
+
+ def run(self):
+ self._thread_id = thread.get_ident()
+ try:
+ self._started_queue.put('')
+ msg = self._stopping_queue.get()
+ if msg == 'KeyboardInterrupt':
+ raise KeyboardInterrupt
+ elif msg == 'Exception':
+ raise ValueError()
+ elif msg == 'Timeout':
+ self._timeout = True
+ self._timeout_queue.get()
+ except:
+ self._exception_info = sys.exc_info()
+
+ def next_timeout(self):
+ if self._timeout:
+ self._timeout_queue.put('done')
+ return time.time() - 10
+ return time.time()
+
+
+class TestHandler(logging.Handler):
+ def __init__(self, astream):
+ logging.Handler.__init__(self)
+ self._stream = astream
+
+ def emit(self, record):
+ self._stream.write(self.format(record))
+
+
+class WaitForThreadsToFinishTest(unittest.TestCase):
+ class MockTestRunner(run_webkit_tests.TestRunner):
+ def __init__(self):
+ pass
+
+ def __del__(self):
+ pass
+
+ def update_summary(self, result_summary):
+ pass
+
+ def run_one_thread(self, msg):
+ runner = self.MockTestRunner()
+ starting_queue = Queue.Queue()
+ stopping_queue = Queue.Queue()
+ child_thread = TestThread(starting_queue, stopping_queue)
+ child_thread.start()
+ started_msg = starting_queue.get()
+ stopping_queue.put(msg)
+ threads = [child_thread]
+ return runner._wait_for_threads_to_finish(threads, None)
+
+ def test_basic(self):
+ interrupted = self.run_one_thread('')
+ self.assertFalse(interrupted)
+
+ def test_interrupt(self):
+ interrupted = self.run_one_thread('KeyboardInterrupt')
+ self.assertTrue(interrupted)
+
+ def test_timeout(self):
+ interrupted = self.run_one_thread('Timeout')
+ self.assertFalse(interrupted)
+
+ def test_exception(self):
+ self.assertRaises(ValueError, self.run_one_thread, 'Exception')
+
+
+class StandaloneFunctionsTest(unittest.TestCase):
+ def test_log_wedged_thread(self):
+ logger = run_webkit_tests._log
+ astream = array_stream.ArrayStream()
+ handler = TestHandler(astream)
+ logger.addHandler(handler)
+
+ starting_queue = Queue.Queue()
+ stopping_queue = Queue.Queue()
+ child_thread = TestThread(starting_queue, stopping_queue)
+ child_thread.start()
+ msg = starting_queue.get()
+
+ run_webkit_tests._log_wedged_thread(child_thread)
+ stopping_queue.put('')
+ child_thread.join(timeout=1.0)
+
+ self.assertFalse(astream.empty())
+ self.assertFalse(child_thread.isAlive())
+
+ def test_find_thread_stack(self):
+ id, stack = sys._current_frames().items()[0]
+ found_stack = run_webkit_tests._find_thread_stack(id)
+ self.assertNotEqual(found_stack, None)
+
+ found_stack = run_webkit_tests._find_thread_stack(0)
+ self.assertEqual(found_stack, None)
+
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py
deleted file mode 100644
index 64dfb20..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-"""Compares the image output of a test to the expected image output using
-fuzzy matching.
-"""
-
-import errno
-import logging
-import os
-import shutil
-
-from webkitpy.layout_tests.layout_package import test_failures
-from webkitpy.layout_tests.test_types import test_type_base
-
-_log = logging.getLogger("webkitpy.layout_tests.test_types.fuzzy_image_diff")
-
-
-class FuzzyImageDiff(test_type_base.TestTypeBase):
-
- def compare_output(self, filename, output, test_args, configuration):
- """Implementation of CompareOutput that checks the output image and
- checksum against the expected files from the LayoutTest directory.
- """
- failures = []
-
- # If we didn't produce a hash file, this test must be text-only.
- if test_args.hash is None:
- return failures
-
- expected_png_file = self._port.expected_filename(filename, '.png')
-
- if test_args.show_sources:
- _log.debug('Using %s' % expected_png_file)
-
- # Also report a missing expected PNG file.
- if not os.path.isfile(expected_png_file):
- failures.append(test_failures.FailureMissingImage(self))
-
- # Run the fuzzymatcher
- r = self._port.fuzzy_diff(test_args.png_path, expected_png_file)
- if r != 0:
- failures.append(test_failures.FailureFuzzyFailure(self))
-
- return failures
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
index 65f8f3a..c9f4107 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
@@ -136,7 +136,7 @@ class ImageDiff(test_type_base.TestTypeBase):
# If we're generating a new baseline, we pass.
if test_args.new_baseline or test_args.reset_results:
self._save_baseline_files(filename, test_args.png_path,
- test_args.hash, test_args.new_baseline)
+ test_args.hash, test_args.new_baseline)
return failures
# Compare hashes.
@@ -144,10 +144,6 @@ class ImageDiff(test_type_base.TestTypeBase):
'.checksum')
expected_png_file = self._port.expected_filename(filename, '.png')
- if test_args.show_sources:
- _log.debug('Using %s' % expected_hash_file)
- _log.debug('Using %s' % expected_png_file)
-
# FIXME: We repeat this pattern often, we should share code.
try:
with codecs.open(expected_hash_file, "r", "ascii") as file:
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
index 8db2e3d..dd44642 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
@@ -58,9 +58,6 @@ class TestArguments(object):
# Whether to use wdiff to generate by-word diffs.
wdiff = False
- # Whether to report the locations of the expected result files used.
- show_sources = False
-
# Python bug workaround. See the wdiff code in WriteOutputFiles for an
# explanation.
_wdiff_available = True
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
index 18f74b8..d06ec8d 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
@@ -48,25 +48,22 @@ _log = logging.getLogger("webkitpy.layout_tests.test_types.text_diff")
class TestTextDiff(test_type_base.TestTypeBase):
- def get_normalized_output_text(self, output):
+ def _get_normalized_output_text(self, output):
# Some tests produce "\r\n" explicitly. Our system (Python/Cygwin)
# helpfully changes the "\n" to "\r\n", resulting in "\r\r\n".
norm = output.replace("\r\r\n", "\r\n").strip("\r\n").replace(
"\r\n", "\n")
return norm + "\n"
- def get_normalized_expected_text(self, filename, show_sources):
+ def _get_normalized_expected_text(self, filename):
"""Given the filename of the test, read the expected output from a file
and normalize the text. Returns a string with the expected text, or ''
if the expected output file was not found."""
# Read the port-specific expected text.
expected_filename = self._port.expected_filename(filename, '.txt')
- if show_sources:
- _log.debug('Using %s' % expected_filename)
+ return self._get_normalized_text(expected_filename)
- return self.get_normalized_text(expected_filename)
-
- def get_normalized_text(self, filename):
+ def _get_normalized_text(self, filename):
# FIXME: We repeat this pattern often, we should share code.
try:
# NOTE: -expected.txt files are ALWAYS utf-8. However,
@@ -94,13 +91,12 @@ class TestTextDiff(test_type_base.TestTypeBase):
# we do not ever decode it inside run-webkit-tests. For some tests
# DumpRenderTree may not output utf-8 text (e.g. webarchives).
self._save_baseline_data(filename, output, ".txt", encoding=None,
- generate_new_baseline=test_args.new_baseline)
+ generate_new_baseline=test_args.new_baseline)
return failures
# Normalize text to diff
- output = self.get_normalized_output_text(output)
- expected = self.get_normalized_expected_text(filename,
- test_args.show_sources)
+ output = self._get_normalized_output_text(output)
+ expected = self._get_normalized_expected_text(filename)
# Write output files for new tests, too.
if port.compare_text(output, expected):
@@ -127,5 +123,5 @@ class TestTextDiff(test_type_base.TestTypeBase):
False otherwise.
"""
- return port.compare_text(self.get_normalized_text(file1),
- self.get_normalized_text(file2))
+ return port.compare_text(self._get_normalized_text(file1),
+ self._get_normalized_text(file2))
diff --git a/WebKitTools/Scripts/webkitpy/style/checker.py b/WebKitTools/Scripts/webkitpy/style/checker.py
index e3c56c5..ee33003 100644
--- a/WebKitTools/Scripts/webkitpy/style/checker.py
+++ b/WebKitTools/Scripts/webkitpy/style/checker.py
@@ -38,6 +38,7 @@ from checkers.common import categories as CommonCategories
from checkers.common import CarriageReturnChecker
from checkers.cpp import CppChecker
from checkers.python import PythonChecker
+from checkers.test_expectations import TestExpectationsChecker
from checkers.text import TextChecker
from error_handlers import DefaultStyleErrorHandler
from filter import FilterConfiguration
@@ -234,6 +235,7 @@ def _all_categories():
"""Return the set of all categories used by check-webkit-style."""
# Take the union across all checkers.
categories = CommonCategories.union(CppChecker.categories)
+ categories = categories.union(TestExpectationsChecker.categories)
# FIXME: Consider adding all of the pep8 categories. Since they
# are not too meaningful for documentation purposes, for
@@ -399,10 +401,15 @@ class CheckerDispatcher(object):
# Since "LayoutTests" is in _SKIPPED_FILES_WITHOUT_WARNING, make
# an exception to prevent files like "LayoutTests/ChangeLog" and
# "LayoutTests/ChangeLog-2009-06-16" from being skipped.
+ # Files like 'test_expectations.txt' and 'drt_expectations.txt'
+ # are also should not be skipped.
#
# FIXME: Figure out a good way to avoid having to add special logic
# for this special case.
- if os.path.basename(file_path).startswith('ChangeLog'):
+ basename = os.path.basename(file_path)
+ if basename.startswith('ChangeLog'):
+ return False
+ elif basename == 'test_expectations.txt' or basename == 'drt_expectations.txt':
return False
for skipped_file in _SKIPPED_FILES_WITHOUT_WARNING:
if file_path.find(skipped_file) >= 0:
@@ -442,7 +449,11 @@ class CheckerDispatcher(object):
elif file_type == FileType.PYTHON:
checker = PythonChecker(file_path, handle_style_error)
elif file_type == FileType.TEXT:
- checker = TextChecker(file_path, handle_style_error)
+ basename = os.path.basename(file_path)
+ if basename == 'test_expectations.txt' or basename == 'drt_expectations.txt':
+ checker = TestExpectationsChecker(file_path, handle_style_error)
+ else:
+ checker = TextChecker(file_path, handle_style_error)
else:
raise ValueError('Invalid file type "%(file_type)s": the only valid file types '
"are %(NONE)s, %(CPP)s, and %(TEXT)s."
diff --git a/WebKitTools/Scripts/webkitpy/style/checkers/common.py b/WebKitTools/Scripts/webkitpy/style/checkers/common.py
index a2d933f..76aa956 100644
--- a/WebKitTools/Scripts/webkitpy/style/checkers/common.py
+++ b/WebKitTools/Scripts/webkitpy/style/checkers/common.py
@@ -30,7 +30,7 @@
# into a shared location and refactoring appropriately.
categories = set([
"whitespace/carriage_return",
-])
+ "whitespace/tab"])
class CarriageReturnChecker(object):
@@ -55,3 +55,20 @@ class CarriageReturnChecker(object):
lines[line_number] = lines[line_number].rstrip("\r")
return lines
+
+
+class TabChecker(object):
+
+ """Supports checking for and handling tabs."""
+
+ def __init__(self, file_path, handle_style_error):
+ self.file_path = file_path
+ self.handle_style_error = handle_style_error
+
+ def check(self, lines):
+ # FIXME: share with cpp_style.
+ for line_number, line in enumerate(lines):
+ if "\t" in line:
+ self.handle_style_error(line_number + 1,
+ "whitespace/tab", 5,
+ "Line contains tab character.")
diff --git a/WebKitTools/Scripts/webkitpy/style/checkers/common_unittest.py b/WebKitTools/Scripts/webkitpy/style/checkers/common_unittest.py
index b67b7b0..1fe1263 100644
--- a/WebKitTools/Scripts/webkitpy/style/checkers/common_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/style/checkers/common_unittest.py
@@ -25,7 +25,7 @@
import unittest
from common import CarriageReturnChecker
-
+from common import TabChecker
# FIXME: The unit tests for the cpp, text, and common checkers should
# share supporting test code. This can include, for example, the
@@ -92,3 +92,33 @@ class CarriageReturnCheckerTest(unittest.TestCase):
self.assert_carriage_return(["line1", "line2\r", "line3\r"],
["line1", "line2", "line3"],
[2, 3])
+
+
+class TabCheckerTest(unittest.TestCase):
+
+ """Tests for TabChecker."""
+
+ def assert_tab(self, input_lines, error_lines):
+ """Assert when the given lines contain tabs."""
+ self._error_lines = []
+
+ def style_error_handler(line_number, category, confidence, message):
+ self.assertEqual(category, 'whitespace/tab')
+ self.assertEqual(confidence, 5)
+ self.assertEqual(message, 'Line contains tab character.')
+ self._error_lines.append(line_number)
+
+ checker = TabChecker('', style_error_handler)
+ checker.check(input_lines)
+ self.assertEquals(self._error_lines, error_lines)
+
+ def test_notab(self):
+ self.assert_tab([''], [])
+ self.assert_tab(['foo', 'bar'], [])
+
+ def test_tab(self):
+ self.assert_tab(['\tfoo'], [1])
+ self.assert_tab(['line1', '\tline2', 'line3\t'], [2, 3])
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations.py b/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations.py
new file mode 100644
index 0000000..ddc3983
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations.py
@@ -0,0 +1,124 @@
+# 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.
+
+"""Checks WebKit style for test_expectations files."""
+
+import logging
+import os
+import re
+import sys
+
+from common import TabChecker
+from webkitpy.style_references import port
+from webkitpy.style_references import test_expectations
+
+_log = logging.getLogger("webkitpy.style.checkers.test_expectations")
+
+
+class ChromiumOptions(object):
+ """A mock object for creating chromium port object.
+
+ port.get() requires an options object which has 'chromium' attribute to create
+ chromium port object for each platform. This class mocks such object.
+ """
+ def __init__(self):
+ self.chromium = True
+ self.use_drt = True
+
+
+class TestExpectationsChecker(object):
+ """Processes test_expectations.txt lines for validating the syntax."""
+
+ categories = set(['test/expectations'])
+
+ def __init__(self, file_path, handle_style_error):
+ self._file_path = file_path
+ self._handle_style_error = handle_style_error
+ self._tab_checker = TabChecker(file_path, handle_style_error)
+ self._output_regex = re.compile('Line:(?P<line>\d+)\s*(?P<message>.+)')
+ # Determining the port of this expectations.
+ try:
+ port_name = self._file_path.split(os.sep)[-2]
+ if port_name == "chromium":
+ options = ChromiumOptions()
+ self._port_obj = port.get(port_name=None, options=options)
+ else:
+ self._port_obj = port.get(port_name=port_name)
+ except:
+ # Using 'test' port when we couldn't determine the port for this
+ # expectations.
+ _log.warn("Could not determine the port for %s. "
+ "Using 'test' port, but platform-specific expectations "
+ "will fail the check." % self._file_path)
+ self._port_obj = port.get('test')
+ self._port_to_check = self._port_obj.test_platform_name()
+ # Suppress error messages of test_expectations module since they will be
+ # reported later.
+ log = logging.getLogger("webkitpy.layout_tests.layout_package."
+ "test_expectations")
+ log.setLevel(logging.CRITICAL)
+
+ def _handle_error_message(self, lineno, message, confidence):
+ pass
+
+ def check_test_expectations(self, expectations_str, tests=None, overrides=None):
+ errors = []
+ expectations = None
+ try:
+ expectations = test_expectations.TestExpectationsFile(
+ port=self._port_obj, expectations=expectations_str, full_test_list=tests,
+ test_platform_name=self._port_to_check, is_debug_mode=False,
+ is_lint_mode=True, suppress_errors=False, tests_are_present=True,
+ overrides=overrides)
+ except SyntaxError, error:
+ errors = str(error).splitlines()
+
+ for error in errors:
+ matched = self._output_regex.match(error)
+ if matched:
+ lineno, message = matched.group('line', 'message')
+ self._handle_style_error(int(lineno), 'test/expectations', 5, message)
+
+ if expectations:
+ for error in expectations.get_non_fatal_errors():
+ matched = self._output_regex.match(error)
+ if matched:
+ lineno, message = matched.group('line', 'message')
+ self._handle_style_error(int(lineno), 'test/expectations', 2, message)
+
+ def check_tabs(self, lines):
+ self._tab_checker.check(lines)
+
+ def check(self, lines):
+ overrides = self._port_obj.test_expectations_overrides()
+ expectations = '\n'.join(lines)
+ self.check_test_expectations(expectations_str=expectations,
+ tests=None,
+ overrides=overrides)
+ # Warn tabs in lines as well
+ self.check_tabs(lines)
diff --git a/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py b/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py
new file mode 100644
index 0000000..aa219b2
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py
@@ -0,0 +1,172 @@
+#!/usr/bin/python
+# 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.
+
+"""Unit tests for test_expectations.py."""
+
+import os
+import sys
+import unittest
+
+# We need following workaround hack to run this unit tests in stand-alone.
+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, '../../../')))
+
+from test_expectations import TestExpectationsChecker
+from webkitpy.style_references import port
+from webkitpy.style_references import test_expectations as test_expectations_style
+
+
+class ErrorCollector(object):
+ """An error handler class for unit tests."""
+
+ def __init__(self):
+ self._errors = []
+
+ def __call__(self, lineno, category, confidence, message):
+ self._errors.append('%s [%s] [%d]' % (message, category, confidence))
+
+ def get_errors(self):
+ return ''.join(self._errors)
+
+ def reset_errors(self):
+ self._errors = []
+
+
+class TestExpectationsTestCase(unittest.TestCase):
+ """TestCase for test_expectations.py"""
+
+ def setUp(self):
+ self._error_collector = ErrorCollector()
+ port_obj = port.get('test')
+ self._test_file = os.path.join(port_obj.layout_tests_dir(), 'misc/passing.html')
+
+ def process_expectations(self, expectations, overrides=None):
+ self._checker = TestExpectationsChecker()
+
+ def assert_lines_lint(self, lines, expected):
+ self._error_collector.reset_errors()
+ checker = TestExpectationsChecker('test/test_expectations.txt',
+ self._error_collector)
+ checker.check_test_expectations(expectations_str='\n'.join(lines),
+ tests=[self._test_file],
+ overrides=None)
+ checker.check_tabs(lines)
+ self.assertEqual(expected, self._error_collector.get_errors())
+
+ def test_valid_expectations(self):
+ self.assert_lines_lint(
+ ["misc/passing.html = PASS"],
+ "")
+ self.assert_lines_lint(
+ ["misc/passing.html = FAIL PASS"],
+ "")
+ self.assert_lines_lint(
+ ["misc/passing.html = CRASH TIMEOUT FAIL PASS"],
+ "")
+ self.assert_lines_lint(
+ ["BUG1234 TEST : misc/passing.html = PASS FAIL"],
+ "")
+ self.assert_lines_lint(
+ ["SKIP BUG1234 : misc/passing.html = TIMEOUT PASS"],
+ "")
+ self.assert_lines_lint(
+ ["BUG1234 DEBUG : misc/passing.html = TIMEOUT PASS"],
+ "")
+ self.assert_lines_lint(
+ ["BUG1234 DEBUG SKIP : misc/passing.html = TIMEOUT PASS"],
+ "")
+ self.assert_lines_lint(
+ ["BUG1234 TEST DEBUG SKIP : misc/passing.html = TIMEOUT PASS"],
+ "")
+ self.assert_lines_lint(
+ ["BUG1234 DEBUG TEST : misc/passing.html = TIMEOUT PASS"],
+ "")
+ self.assert_lines_lint(
+ ["SLOW DEFER BUG1234 : misc/passing.html = PASS"],
+ "")
+ self.assert_lines_lint(
+ ["WONTFIX SKIP : misc/passing.html = TIMEOUT"],
+ "")
+
+ def test_valid_modifiers(self):
+ self.assert_lines_lint(
+ ["INVALID-MODIFIER : misc/passing.html = PASS"],
+ "Invalid modifier for test: invalid-modifier "
+ "misc/passing.html [test/expectations] [5]")
+ self.assert_lines_lint(
+ ["SKIP : misc/passing.html = PASS"],
+ "Test lacks BUG modifier. "
+ "misc/passing.html [test/expectations] [2]")
+ self.assert_lines_lint(
+ ["WONTFIX DEFER : misc/passing.html = PASS"],
+ "Test cannot be both DEFER and WONTFIX. "
+ "misc/passing.html [test/expectations] [5]")
+
+ def test_expectation_errors(self):
+ self.assert_lines_lint(
+ ["missing expectations"],
+ "Missing expectations. ['missing expectations'] [test/expectations] [5]")
+ self.assert_lines_lint(
+ ["SLOW : misc/passing.html = TIMEOUT"],
+ "A test can not be both slow and timeout. "
+ "If it times out indefinitely, then it should be just timeout. "
+ "misc/passing.html [test/expectations] [5]")
+ self.assert_lines_lint(
+ ["does/not/exist.html = FAIL"],
+ "Path does not exist. does/not/exist.html [test/expectations] [2]")
+
+ def test_parse_expectations(self):
+ self.assert_lines_lint(
+ ["misc/passing.html = PASS"],
+ "")
+ self.assert_lines_lint(
+ ["misc/passing.html = UNSUPPORTED"],
+ "Unsupported expectation: unsupported "
+ "misc/passing.html [test/expectations] [5]")
+ self.assert_lines_lint(
+ ["misc/passing.html = PASS UNSUPPORTED"],
+ "Unsupported expectation: unsupported "
+ "misc/passing.html [test/expectations] [5]")
+
+ def test_already_seen_test(self):
+ self.assert_lines_lint(
+ ["misc/passing.html = PASS",
+ "misc/passing.html = TIMEOUT"],
+ "Duplicate expectation. %s [test/expectations] [5]" % self._test_file)
+
+ def test_tab(self):
+ self.assert_lines_lint(
+ ["\tmisc/passing.html = PASS"],
+ "Line contains tab character. [whitespace/tab] [5]")
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/style/checkers/text.py b/WebKitTools/Scripts/webkitpy/style/checkers/text.py
index 0d03938..1147658 100644
--- a/WebKitTools/Scripts/webkitpy/style/checkers/text.py
+++ b/WebKitTools/Scripts/webkitpy/style/checkers/text.py
@@ -29,6 +29,7 @@
"""Checks WebKit style for text files."""
+from common import TabChecker
class TextChecker(object):
@@ -37,16 +38,10 @@ class TextChecker(object):
def __init__(self, file_path, handle_style_error):
self.file_path = file_path
self.handle_style_error = handle_style_error
+ self._tab_checker = TabChecker(file_path, handle_style_error)
def check(self, lines):
- lines = (["// adjust line numbers to make the first line 1."] + lines)
-
- # FIXME: share with cpp_style.
- for line_number, line in enumerate(lines):
- if "\t" in line:
- self.handle_style_error(line_number,
- "whitespace/tab", 5,
- "Line contains tab character.")
+ self._tab_checker.check(lines)
# FIXME: Remove this function (requires refactoring unit tests).
diff --git a/WebKitTools/Scripts/webkitpy/style_references.py b/WebKitTools/Scripts/webkitpy/style_references.py
index a42b69d..34f3bff 100644
--- a/WebKitTools/Scripts/webkitpy/style_references.py
+++ b/WebKitTools/Scripts/webkitpy/style_references.py
@@ -45,6 +45,8 @@ from webkitpy.common.system.logtesting import LogTesting
from webkitpy.common.system.logtesting import TestLogStream
from webkitpy.common.system.logutils import configure_logging
from webkitpy.common.checkout.scm import detect_scm_system
+from webkitpy.layout_tests import port
+from webkitpy.layout_tests.layout_package import test_expectations
from webkitpy.thirdparty.autoinstalled import pep8
diff --git a/WebKitTools/Scripts/webkitpy/thirdparty/simplejson/decoder.py b/WebKitTools/Scripts/webkitpy/thirdparty/simplejson/decoder.py
index b887b58..63f70cb 100644
--- a/WebKitTools/Scripts/webkitpy/thirdparty/simplejson/decoder.py
+++ b/WebKitTools/Scripts/webkitpy/thirdparty/simplejson/decoder.py
@@ -3,7 +3,7 @@ Implementation of JSONDecoder
"""
import re
-from .scanner import Scanner, pattern
+from scanner import Scanner, pattern
FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL
diff --git a/WebKitTools/Scripts/webkitpy/tool/main.py b/WebKitTools/Scripts/webkitpy/tool/main.py
index 1f43145..0dd5017 100755
--- a/WebKitTools/Scripts/webkitpy/tool/main.py
+++ b/WebKitTools/Scripts/webkitpy/tool/main.py
@@ -33,7 +33,7 @@ import os
import threading
from webkitpy.common.checkout.api import Checkout
-from webkitpy.common.checkout.scm import detect_scm_system
+from webkitpy.common.checkout.scm import default_scm
from webkitpy.common.net.bugzilla import Bugzilla
from webkitpy.common.net.buildbot import BuildBot
from webkitpy.common.net.rietveld import Rietveld
@@ -79,18 +79,8 @@ class WebKitPatch(MultiCommandTool):
def scm(self):
# Lazily initialize SCM to not error-out before command line parsing (or when running non-scm commands).
- original_cwd = os.path.abspath(".")
if not self._scm:
- self._scm = detect_scm_system(original_cwd)
-
- if not self._scm:
- script_directory = os.path.abspath(sys.path[0])
- self._scm = detect_scm_system(script_directory)
- if self._scm:
- log("The current directory (%s) is not a WebKit checkout, using %s" % (original_cwd, self._scm.checkout_root))
- else:
- error("FATAL: Failed to determine the SCM system for either %s or %s" % (original_cwd, script_directory))
-
+ self._scm = default_scm()
return self._scm
def checkout(self):
diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py b/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py
index 22b9452..0f57439 100644
--- a/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py
+++ b/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py
@@ -57,6 +57,7 @@ class RunTests(AbstractStep):
if self._options.non_interactive:
args.append("--no-launch-safari")
args.append("--exit-after-n-failures=1")
+ args.append("--wait-for-httpd")
# FIXME: Hack to work around https://bugs.webkit.org/show_bug.cgi?id=38912
# when running the commit-queue on a mac leopard machine since compositing
# does not work reliably on Leopard due to various graphics driver/system bugs.
diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py b/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py
index 766801b..f4c955d 100644
--- a/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py
@@ -77,6 +77,6 @@ MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/test-webkitperl']
Running JavaScriptCore tests
MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/run-javascriptcore-tests']
Running run-webkit-tests
-MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/run-webkit-tests', '--no-launch-safari', '--exit-after-n-failures=1', '--ignore-tests', 'compositing', '--quiet']
+MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/run-webkit-tests', '--no-launch-safari', '--exit-after-n-failures=1', '--wait-for-httpd', '--ignore-tests', 'compositing', '--quiet']
"""
OutputCapture().assert_outputs(self, step.run, [{}], expected_stderr=expected_stderr)
diff --git a/WebKitTools/TestResultServer/handlers/testfilehandler.py b/WebKitTools/TestResultServer/handlers/testfilehandler.py
index 97953e7..4d1320f 100644
--- a/WebKitTools/TestResultServer/handlers/testfilehandler.py
+++ b/WebKitTools/TestResultServer/handlers/testfilehandler.py
@@ -43,6 +43,7 @@ PARAM_NAME = "name"
PARAM_KEY = "key"
PARAM_TEST_TYPE = "testtype"
PARAM_INCREMENTAL = "incremental"
+PARAM_TEST_LIST_JSON = "testlistjson"
class DeleteFile(webapp.RequestHandler):
@@ -109,16 +110,31 @@ class GetFile(webapp.RequestHandler):
if not files:
logging.info("File not found, builder: %s, test_type: %s, name: %s.",
builder, test_type, name)
- return
+ return None
+
+ return files[0].data
+
+ def _get_test_list_json(self, builder, test_type):
+ """Return json file with test name list only, do not include test
+ results and other non-test-data .
- self.response.headers["Content-Type"] = "text/plain; charset=utf-8"
- self.response.out.write(files[0].data)
+ Args:
+ builder: builder name.
+ test_type: type of test results.
+ """
+
+ json = self._get_file_content(builder, test_type, "results.json")
+ if not json:
+ return None
+
+ return JsonResults.get_test_list(builder, json)
def get(self):
builder = self.request.get(PARAM_BUILDER)
test_type = self.request.get(PARAM_TEST_TYPE)
name = self.request.get(PARAM_NAME)
dir = self.request.get(PARAM_DIR)
+ test_list_json = self.request.get(PARAM_TEST_LIST_JSON)
logging.debug(
"Getting files, builder: %s, test_type: %s, name: %s.",
@@ -129,8 +145,15 @@ class GetFile(webapp.RequestHandler):
# file content.
if dir or not builder or not name:
return self._get_file_list(builder, test_type, name)
+
+ if name == "results.json" and test_list_json:
+ json = self._get_test_list_json(builder, test_type)
else:
- return self._get_file_content(builder, test_type, name)
+ json = self._get_file_content(builder, test_type, name)
+
+ if json:
+ self.response.headers["Content-Type"] = "text/plain; charset=utf-8"
+ self.response.out.write(json)
class Upload(webapp.RequestHandler):
diff --git a/WebKitTools/TestResultServer/model/jsonresults.py b/WebKitTools/TestResultServer/model/jsonresults.py
index d86fbcd..e5eb7f7 100755
--- a/WebKitTools/TestResultServer/model/jsonresults.py
+++ b/WebKitTools/TestResultServer/model/jsonresults.py
@@ -40,8 +40,11 @@ JSON_RESULTS_BUILD_NUMBERS = "buildNumbers"
JSON_RESULTS_TESTS = "tests"
JSON_RESULTS_RESULTS = "results"
JSON_RESULTS_TIMES = "times"
+JSON_RESULTS_PASS = "P"
+JSON_RESULTS_NO_DATA = "N"
+JSON_RESULTS_MIN_TIME = 1
JSON_RESULTS_VERSION = 3
-JSON_RESULTS_MAX_BUILDS = 750
+JSON_RESULTS_MAX_BUILDS = 1500
class JsonResults(object):
@@ -171,8 +174,6 @@ class JsonResults(object):
# Merge this build into aggreagated results.
cls._merge_one_build(aggregated_json, incremental_json, index)
- logging.debug("Merged build %s, merged json: %s.",
- build_number, aggregated_json)
return True
@@ -210,18 +211,26 @@ class JsonResults(object):
incremental_json: incremental json object.
"""
- for test_name in incremental_json:
- incremental_test = incremental_json[test_name]
+ all_tests = (set(aggregated_json.iterkeys()) |
+ set(incremental_json.iterkeys()))
+ for test_name in all_tests:
if test_name in aggregated_json:
aggregated_test = aggregated_json[test_name]
+ if test_name in incremental_json:
+ incremental_test = incremental_json[test_name]
+ results = incremental_test[JSON_RESULTS_RESULTS]
+ times = incremental_test[JSON_RESULTS_TIMES]
+ else:
+ results = [[1, JSON_RESULTS_NO_DATA]]
+ times = [[1, 0]]
+
cls._insert_item_run_length_encoded(
- incremental_test[JSON_RESULTS_RESULTS],
- aggregated_test[JSON_RESULTS_RESULTS])
+ results, aggregated_test[JSON_RESULTS_RESULTS])
cls._insert_item_run_length_encoded(
- incremental_test[JSON_RESULTS_TIMES],
- aggregated_test[JSON_RESULTS_TIMES])
+ times, aggregated_test[JSON_RESULTS_TIMES])
+ cls._normalize_results_json(test_name, aggregated_json)
else:
- aggregated_json[test_name] = incremental_test
+ aggregated_json[test_name] = incremental_json[test_name]
@classmethod
def _insert_item_run_length_encoded(cls, incremental_item, aggregated_item):
@@ -238,17 +247,69 @@ class JsonResults(object):
aggregated_item[0][0] = min(
aggregated_item[0][0] + item[0], JSON_RESULTS_MAX_BUILDS)
else:
- # The test item values need to be summed from continuous runs.
- # If there is an older item (not most recent one) whose value is
- # same as the one to insert, then we should remove the old item
- # from aggregated list.
- for i in reversed(range(1, len(aggregated_item))):
- if item[1] == aggregated_item[i][1]:
- aggregated_item.pop(i)
-
aggregated_item.insert(0, item)
@classmethod
+ def _normalize_results_json(cls, test_name, aggregated_json):
+ """ Prune tests where all runs pass or tests that no longer exist and
+ truncate all results to JSON_RESULTS_MAX_BUILDS.
+
+ Args:
+ test_name: Name of the test.
+ aggregated_json: The JSON object with all the test results for
+ this builder.
+ """
+
+ aggregated_test = aggregated_json[test_name]
+ aggregated_test[JSON_RESULTS_RESULTS] = \
+ cls._remove_items_over_max_number_of_builds(
+ aggregated_test[JSON_RESULTS_RESULTS])
+ aggregated_test[JSON_RESULTS_TIMES] = \
+ cls._remove_items_over_max_number_of_builds(
+ aggregated_test[JSON_RESULTS_TIMES])
+
+ is_all_pass = cls._is_results_all_of_type(
+ aggregated_test[JSON_RESULTS_RESULTS], JSON_RESULTS_PASS)
+ is_all_no_data = cls._is_results_all_of_type(
+ aggregated_test[JSON_RESULTS_RESULTS], JSON_RESULTS_NO_DATA)
+
+ max_time = max(
+ [time[1] for time in aggregated_test[JSON_RESULTS_TIMES]])
+ # Remove all passes/no-data from the results to reduce noise and
+ # filesize. If a test passes every run, but
+ # takes >= JSON_RESULTS_MIN_TIME to run, don't throw away the data.
+ if (is_all_no_data or
+ (is_all_pass and max_time < JSON_RESULTS_MIN_TIME)):
+ del aggregated_json[test_name]
+
+ @classmethod
+ def _remove_items_over_max_number_of_builds(cls, encoded_list):
+ """Removes items from the run-length encoded list after the final
+ item that exceeds the max number of builds to track.
+
+ Args:
+ encoded_results: run-length encoded results. An array of arrays, e.g.
+ [[3,'A'],[1,'Q']] encodes AAAQ.
+ """
+ num_builds = 0
+ index = 0
+ for result in encoded_list:
+ num_builds = num_builds + result[0]
+ index = index + 1
+ if num_builds > JSON_RESULTS_MAX_BUILDS:
+ return encoded_list[:index]
+
+ return encoded_list
+
+ @classmethod
+ def _is_results_all_of_type(cls, results, type):
+ """Returns whether all the results are of the given type
+ (e.g. all passes).
+ """
+
+ return len(results) == 1 and results[0][1] == type
+
+ @classmethod
def _check_json(cls, builder, json):
"""Check whether the given json is valid.
@@ -363,3 +424,33 @@ class JsonResults(object):
return None
return file
+
+ @classmethod
+ def get_test_list(cls, builder, json_file_data):
+ """Get list of test names from aggregated json file data.
+
+ Args:
+ json_file_data: json file data that has all test-data and
+ non-test-data.
+
+ Returns:
+ json file with test name list only. The json format is the same
+ as the one saved in datastore, but all non-test-data and test detail
+ results are removed.
+ """
+
+ logging.debug("Loading test results json...")
+ json = cls._load_json(json_file_data)
+ if not json:
+ return None
+
+ logging.debug("Checking test results json...")
+ if not cls._check_json(builder, json):
+ return None
+
+ test_list_json = {}
+ tests = json[builder][JSON_RESULTS_TESTS]
+ test_list_json[builder] = {
+ "tests": dict.fromkeys(tests, {})}
+
+ return cls._generate_file_data(test_list_json)
diff --git a/WebKitTools/TestResultServer/model/jsonresults_unittest.py b/WebKitTools/TestResultServer/model/jsonresults_unittest.py
index fd646c8..15b659b 100755
--- a/WebKitTools/TestResultServer/model/jsonresults_unittest.py
+++ b/WebKitTools/TestResultServer/model/jsonresults_unittest.py
@@ -26,6 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import jsonresults
import unittest
from jsonresults import JsonResults
@@ -65,6 +66,9 @@ JSON_RESULTS_TESTS_TEMPLATE = (
JSON_RESULTS_PREFIX = "ADD_RESULTS("
JSON_RESULTS_SUFFIX = ");"
+JSON_RESULTS_TEST_LIST_TEMPLATE = (
+ '{"Webkit":{"tests":{[TESTDATA_TESTS]}}}')
+
class JsonResultsTest(unittest.TestCase):
def setUp(self):
@@ -122,12 +126,27 @@ class JsonResultsTest(unittest.TestCase):
else:
self.assertFalse(merged_results)
+ def _test_get_test_list(self, input_data, expected_data):
+ input_results = self._make_test_json(input_data)
+
+ json_tests = []
+ for test in expected_data:
+ json_tests.append("\"" + test + "\":{}")
+
+ expected_results = JSON_RESULTS_PREFIX + \
+ JSON_RESULTS_TEST_LIST_TEMPLATE.replace(
+ "[TESTDATA_TESTS]", ",".join(json_tests)) + \
+ JSON_RESULTS_SUFFIX
+
+ actual_results = JsonResults.get_test_list(self._builder, input_results)
+ self.assertEquals(actual_results, expected_results)
+
def test(self):
# Empty incremental results json.
# Nothing to merge.
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"]]),
# Incremental results
None,
# Expect no merge happens.
@@ -137,7 +156,7 @@ class JsonResultsTest(unittest.TestCase):
# Nothing to merge.
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"]]),
# Incremental results
([], []),
# Expected no merge happens.
@@ -149,9 +168,9 @@ class JsonResultsTest(unittest.TestCase):
# Aggregated results
None,
# Incremental results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"]]),
# Expected results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"]]))
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"]]))
# Single test for single run.
# Incremental results has the latest build and same test results for
@@ -160,11 +179,11 @@ class JsonResultsTest(unittest.TestCase):
# of runs for "P" (200 + 1) to get merged results.
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"]]),
# Incremental results
- (["3"], [["001.html", "[1,\"P\"]", "[1,\"0\"]"]]),
+ (["3"], [["001.html", "[1,\"F\"]", "[1,0]"]]),
# Expected results
- (["3", "2", "1"], [["001.html", "[201,\"P\"]", "[201,\"0\"]"]]))
+ (["3", "2", "1"], [["001.html", "[201,\"F\"]", "[201,0]"]]))
# Single test for single run.
# Incremental results has the latest build but different test results
@@ -172,72 +191,68 @@ class JsonResultsTest(unittest.TestCase):
# Insert the incremental results at the first place.
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"]]),
# Incremental results
- (["3"], [["001.html", "[1, \"I\"]", "[1,\"1\"]"]]),
+ (["3"], [["001.html", "[1, \"I\"]", "[1,1]"]]),
# Expected results
- (["3", "2", "1"], [["001.html", "[1,\"I\"],[200,\"P\"]", "[1,\"1\"],[200,\"0\"]"]]))
+ (["3", "2", "1"], [["001.html", "[1,\"I\"],[200,\"F\"]", "[1,1],[200,0]"]]))
# Single test for single run.
# Incremental results has the latest build but different test results
# for that run.
- # The test "results" and "times" need to be continuous, so the old
- # [10,"I"] result should be dropped because a new result of same type [1,"I"]
- # is inserted in front of [200,"P"].
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"],[10,\"I\"]", "[200,\"0\"],[10,\"1\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"],[10,\"I\"]", "[200,0],[10,1]"]]),
# Incremental results
- (["3"], [["001.html", "[1,\"I\"]", "[1,\"1\"]"]]),
+ (["3"], [["001.html", "[1,\"I\"]", "[1,1]"]]),
# Expected results
- (["3", "2", "1"], [["001.html", "[1,\"I\"],[200,\"P\"]", "[1,\"1\"],[200,\"0\"]"]]))
+ (["3", "2", "1"], [["001.html", "[1,\"I\"],[200,\"F\"],[10,\"I\"]", "[1,1],[200,0],[10,1]"]]))
# Multiple tests for single run.
# All tests have incremental updates.
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"], ["002.html", "[100,\"I\"]", "[100,\"1\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"], ["002.html", "[100,\"I\"]", "[100,1]"]]),
# Incremental results
- (["3"], [["001.html", "[1,\"P\"]", "[1,\"0\"]"], ["002.html", "[1,\"I\"]", "[1,\"1\"]"]]),
+ (["3"], [["001.html", "[1,\"F\"]", "[1,0]"], ["002.html", "[1,\"I\"]", "[1,1]"]]),
# Expected results
- (["3", "2", "1"], [["001.html", "[201,\"P\"]", "[201,\"0\"]"], ["002.html", "[101,\"I\"]", "[101,\"1\"]"]]))
+ (["3", "2", "1"], [["001.html", "[201,\"F\"]", "[201,0]"], ["002.html", "[101,\"I\"]", "[101,1]"]]))
# Multiple tests for single run.
- # Not all tests have update.
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"], ["002.html", "[100,\"I\"]", "[100,\"1\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"], ["002.html", "[100,\"I\"]", "[100,1]"]]),
# Incremental results
- (["3"], [["002.html", "[1,\"I\"]", "[1,\"1\"]"]]),
+ (["3"], [["002.html", "[1,\"I\"]", "[1,1]"]]),
# Expected results
- (["3", "2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"], ["002.html", "[101,\"I\"]", "[101,\"1\"]"]]))
+ (["3", "2", "1"], [["001.html", "[1,\"N\"],[200,\"F\"]", "[201,0]"], ["002.html", "[101,\"I\"]", "[101,1]"]]))
# Single test for multiple runs.
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"]]),
# Incremental results
- (["4", "3"], [["001.html", "[2, \"I\"]", "[2,\"2\"]"]]),
+ (["4", "3"], [["001.html", "[2, \"I\"]", "[2,2]"]]),
# Expected results
- (["4", "3", "2", "1"], [["001.html", "[2,\"I\"],[200,\"P\"]", "[2,\"2\"],[200,\"0\"]"]]))
+ (["4", "3", "2", "1"], [["001.html", "[2,\"I\"],[200,\"F\"]", "[2,2],[200,0]"]]))
# Multiple tests for multiple runs.
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"], ["002.html", "[10,\"Z\"]", "[10,\"0\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"], ["002.html", "[10,\"Z\"]", "[10,0]"]]),
# Incremental results
- (["4", "3"], [["001.html", "[2, \"I\"]", "[2,\"2\"]"], ["002.html", "[1,\"C\"]", "[1,\"1\"]"]]),
+ (["4", "3"], [["001.html", "[2, \"I\"]", "[2,2]"], ["002.html", "[1,\"C\"]", "[1,1]"]]),
# Expected results
- (["4", "3", "2", "1"], [["001.html", "[2,\"I\"],[200,\"P\"]", "[2,\"2\"],[200,\"0\"]"], ["002.html", "[1,\"C\"],[10,\"Z\"]", "[1,\"1\"],[10,\"0\"]"]]))
+ (["4", "3", "2", "1"], [["001.html", "[2,\"I\"],[200,\"F\"]", "[2,2],[200,0]"], ["002.html", "[1,\"C\"],[10,\"Z\"]", "[1,1],[10,0]"]]))
# Test the build in incremental results is older than the most recent
# build in aggregated results.
# The incremental results should be dropped and no merge happens.
self._test_merge(
# Aggregated results
- (["3", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"]]),
+ (["3", "1"], [["001.html", "[200,\"F\"]", "[200,0]"]]),
# Incremental results
- (["2"], [["001.html", "[1, \"P\"]", "[1,\"0\"]"]]),
+ (["2"], [["001.html", "[1, \"F\"]", "[1,0]"]]),
# Expected no merge happens.
None)
@@ -246,11 +261,57 @@ class JsonResultsTest(unittest.TestCase):
# The incremental results should be dropped and no merge happens.
self._test_merge(
# Aggregated results
- (["2", "1"], [["001.html", "[200,\"P\"]", "[200,\"0\"]"]]),
+ (["2", "1"], [["001.html", "[200,\"F\"]", "[200,0]"]]),
# Incremental results
- (["3", "2"], [["001.html", "[2, \"P\"]", "[2,\"0\"]"]]),
+ (["3", "2"], [["001.html", "[2, \"F\"]", "[2,0]"]]),
# Expected no merge happens.
None)
+ # Remove test where there is no data in all runs.
+ self._test_merge(
+ # Aggregated results
+ (["2", "1"], [["001.html", "[200,\"N\"]", "[200,0]"], ["002.html", "[10,\"F\"]", "[10,0]"]]),
+ # Incremental results
+ (["3"], [["001.html", "[1,\"N\"]", "[1,0]"], ["002.html", "[1,\"P\"]", "[1,0]"]]),
+ # Expected results
+ (["3", "2", "1"], [["002.html", "[1,\"P\"],[10,\"F\"]", "[11,0]"]]))
+
+ # Remove test where all run pass and max running time < 1 seconds
+ self._test_merge(
+ # Aggregated results
+ (["2", "1"], [["001.html", "[200,\"P\"]", "[200,0]"], ["002.html", "[10,\"F\"]", "[10,0]"]]),
+ # Incremental results
+ (["3"], [["001.html", "[1,\"P\"]", "[1,0]"], ["002.html", "[1,\"P\"]", "[1,0]"]]),
+ # Expected results
+ (["3", "2", "1"], [["002.html", "[1,\"P\"],[10,\"F\"]", "[11,0]"]]))
+
+ # Do not remove test where all run pass but max running time >= 1 seconds
+ self._test_merge(
+ # Aggregated results
+ (["2", "1"], [["001.html", "[200,\"P\"]", "[200,0]"], ["002.html", "[10,\"F\"]", "[10,0]"]]),
+ # Incremental results
+ (["3"], [["001.html", "[1,\"P\"]", "[1,1]"], ["002.html", "[1,\"P\"]", "[1,0]"]]),
+ # Expected results
+ (["3", "2", "1"], [["001.html", "[201,\"P\"]", "[1,1],[200,0]"], ["002.html", "[1,\"P\"],[10,\"F\"]", "[11,0]"]]))
+
+ # Remove items from test results and times that exceeds the max number
+ # of builds to track.
+ max_builds = str(jsonresults.JSON_RESULTS_MAX_BUILDS)
+ self._test_merge(
+ # Aggregated results
+ (["2", "1"], [["001.html", "[" + max_builds + ",\"F\"],[1,\"I\"]", "[" + max_builds + ",0],[1,1]"]]),
+ # Incremental results
+ (["3"], [["001.html", "[1,\"T\"]", "[1,1]"]]),
+ # Expected results
+ (["3", "2", "1"], [["001.html", "[1,\"T\"],[" + max_builds + ",\"F\"]", "[1,1],[" + max_builds + ",0]"]]))
+
+ # Get test name list only. Don't include non-test-list data and
+ # of test result details.
+ self._test_get_test_list(
+ # Input results
+ (["3", "2", "1"], [["001.html", "[200,\"P\"]", "[200,0]"], ["002.html", "[10,\"F\"]", "[10,0]"]]),
+ # Expected results
+ ["001.html", "002.html"])
+
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
index 02dfeb1..b2aa836 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
@@ -49,6 +49,7 @@ InjectedBundle& InjectedBundle::shared()
InjectedBundle::InjectedBundle()
: m_bundle(0)
, m_mainPage(0)
+ , m_state(Idle)
{
}
@@ -84,17 +85,6 @@ void InjectedBundle::initialize(WKBundleRef bundle)
WKBundleActivateMacFontAscentHack(m_bundle);
}
-void InjectedBundle::done()
-{
- WKRetainPtr<WKStringRef> doneMessageName(AdoptWK, WKStringCreateWithCFString(CFSTR("Done")));
-
- std::string output = m_outputStream.str();
- RetainPtr<CFStringRef> outputCFString(AdoptCF, CFStringCreateWithCString(0, output.c_str(), kCFStringEncodingUTF8));
- WKRetainPtr<WKStringRef> doneMessageBody(AdoptWK, WKStringCreateWithCFString(outputCFString.get()));
-
- WKBundlePostMessage(m_bundle, doneMessageName.get(), doneMessageBody.get());
-}
-
void InjectedBundle::didCreatePage(WKBundlePageRef page)
{
// FIXME: we really need the main page ref to be sent over from the ui process
@@ -121,7 +111,7 @@ void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messag
WKRetainPtr<WKStringRef> ackMessageBody(AdoptWK, WKStringCreateWithCFString(CFSTR("BeginTest")));
WKBundlePostMessage(m_bundle, ackMessageName.get(), ackMessageBody.get());
- reset();
+ beginTesting();
return;
}
@@ -130,8 +120,10 @@ void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messag
WKBundlePostMessage(m_bundle, errorMessageName.get(), errorMessageBody.get());
}
-void InjectedBundle::reset()
+void InjectedBundle::beginTesting()
{
+ m_state = Testing;
+
m_outputStream.str("");
m_layoutTestController = LayoutTestController::create();
@@ -144,6 +136,21 @@ void InjectedBundle::reset()
m_mainPage->reset();
}
+void InjectedBundle::done()
+{
+ m_mainPage->stopLoading();
+
+ WKRetainPtr<WKStringRef> doneMessageName(AdoptWK, WKStringCreateWithCFString(CFSTR("Done")));
+
+ std::string output = m_outputStream.str();
+ RetainPtr<CFStringRef> outputCFString(AdoptCF, CFStringCreateWithCString(0, output.c_str(), kCFStringEncodingUTF8));
+ WKRetainPtr<WKStringRef> doneMessageBody(AdoptWK, WKStringCreateWithCFString(outputCFString.get()));
+
+ WKBundlePostMessage(m_bundle, doneMessageName.get(), doneMessageBody.get());
+
+ m_state = Idle;
+}
+
void InjectedBundle::closeOtherPages()
{
Vector<WKBundlePageRef> pages;
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
index ba021b1..d094f42 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
@@ -61,6 +61,8 @@ public:
void done();
std::ostringstream& os() { return m_outputStream; }
+ bool isTestRunning() { return m_state == Testing; }
+
private:
InjectedBundle();
~InjectedBundle();
@@ -73,7 +75,7 @@ private:
void willDestroyPage(WKBundlePageRef page);
void didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody);
- void reset();
+ void beginTesting();
WKBundleRef m_bundle;
HashMap<WKBundlePageRef, InjectedBundlePage*> m_otherPages;
@@ -84,6 +86,12 @@ private:
RefPtr<EventSendingController> m_eventSendingController;
std::ostringstream m_outputStream;
+
+ enum State {
+ Idle,
+ Testing
+ };
+ State m_state;
};
} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
index 40a098e..424f7ab 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
@@ -147,6 +147,12 @@ InjectedBundlePage::~InjectedBundlePage()
{
}
+void InjectedBundlePage::stopLoading()
+{
+ WKBundlePageStopLoading(m_page);
+ m_isLoading = false;
+}
+
void InjectedBundlePage::reset()
{
WKBundlePageClearMainFrameName(m_page);
@@ -235,6 +241,9 @@ void InjectedBundlePage::didRunInsecureContentForFrame(WKBundlePageRef page, WKB
void InjectedBundlePage::didStartProvisionalLoadForFrame(WKBundleFrameRef frame)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
if (frame == WKBundlePageGetMainFrame(m_page))
m_isLoading = true;
}
@@ -331,6 +340,8 @@ void InjectedBundlePage::dumpAllFramesText()
void InjectedBundlePage::dump()
{
+ ASSERT(InjectedBundle::shared().isTestRunning());
+
InjectedBundle::shared().layoutTestController()->invalidateWaitToDumpWatchdog();
switch (InjectedBundle::shared().layoutTestController()->whatToDump()) {
@@ -357,6 +368,9 @@ void InjectedBundlePage::dump()
void InjectedBundlePage::didFinishLoadForFrame(WKBundleFrameRef frame)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
if (!WKBundleFrameIsMainFrame(frame))
return;
@@ -373,6 +387,9 @@ void InjectedBundlePage::didFinishLoadForFrame(WKBundleFrameRef frame)
void InjectedBundlePage::didFailLoadWithErrorForFrame(WKBundleFrameRef frame)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
if (!WKBundleFrameIsMainFrame(frame))
return;
@@ -386,6 +403,9 @@ void InjectedBundlePage::didFailLoadWithErrorForFrame(WKBundleFrameRef frame)
void InjectedBundlePage::didReceiveTitleForFrame(WKStringRef title, WKBundleFrameRef frame)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
if (!InjectedBundle::shared().layoutTestController()->shouldDumpTitleChanges())
return;
@@ -394,6 +414,9 @@ void InjectedBundlePage::didReceiveTitleForFrame(WKStringRef title, WKBundleFram
void InjectedBundlePage::didClearWindowForFrame(WKBundleFrameRef frame, JSGlobalContextRef context, JSObjectRef window)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
JSValueRef exception = 0;
InjectedBundle::shared().layoutTestController()->makeWindowObject(context, window, &exception);
InjectedBundle::shared().gcController()->makeWindowObject(context, window, &exception);
@@ -414,6 +437,9 @@ void InjectedBundlePage::didChangeLocationWithinPageForFrame(WKBundleFrameRef fr
void InjectedBundlePage::didFinishDocumentLoadForFrame(WKBundleFrameRef frame)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
unsigned pendingFrameUnloadEvents = WKBundleFrameGetPendingUnloadCount(frame);
if (pendingFrameUnloadEvents)
InjectedBundle::shared().os() << frame << " - has " << pendingFrameUnloadEvents << " onunload handler(s)\n";
@@ -460,12 +486,18 @@ void InjectedBundlePage::willRunJavaScriptPrompt(WKBundlePageRef page, WKStringR
void InjectedBundlePage::willAddMessageToConsole(WKStringRef message, uint32_t lineNumber)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
// FIXME: Strip file: urls.
InjectedBundle::shared().os() << "CONSOLE MESSAGE: line " << lineNumber << ": " << message << "\n";
}
void InjectedBundlePage::willSetStatusbarText(WKStringRef statusbarText)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
if (!InjectedBundle::shared().layoutTestController()->shouldDumpStatusCallbacks())
return;
@@ -474,11 +506,17 @@ void InjectedBundlePage::willSetStatusbarText(WKStringRef statusbarText)
void InjectedBundlePage::willRunJavaScriptAlert(WKStringRef message, WKBundleFrameRef)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
InjectedBundle::shared().os() << "ALERT: " << message << "\n";
}
void InjectedBundlePage::willRunJavaScriptConfirm(WKStringRef message, WKBundleFrameRef)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
InjectedBundle::shared().os() << "CONFIRM: " << message << "\n";
}
@@ -546,6 +584,9 @@ void InjectedBundlePage::didChangeSelection(WKBundlePageRef page, WKStringRef no
bool InjectedBundlePage::shouldBeginEditing(WKBundleRangeRef range)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return true;
+
if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
InjectedBundle::shared().os() << "EDITING DELEGATE: shouldBeginEditingInDOMRange:" << range << "\n";
return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
@@ -553,6 +594,9 @@ bool InjectedBundlePage::shouldBeginEditing(WKBundleRangeRef range)
bool InjectedBundlePage::shouldEndEditing(WKBundleRangeRef range)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return true;
+
if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
InjectedBundle::shared().os() << "EDITING DELEGATE: shouldEndEditingInDOMRange:" << range << "\n";
return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
@@ -560,6 +604,9 @@ bool InjectedBundlePage::shouldEndEditing(WKBundleRangeRef range)
bool InjectedBundlePage::shouldInsertNode(WKBundleNodeRef node, WKBundleRangeRef rangeToReplace, WKInsertActionType action)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return true;
+
static const char* insertactionstring[] = {
"WebViewInsertActionTyped",
"WebViewInsertActionPasted",
@@ -573,6 +620,9 @@ bool InjectedBundlePage::shouldInsertNode(WKBundleNodeRef node, WKBundleRangeRef
bool InjectedBundlePage::shouldInsertText(WKStringRef text, WKBundleRangeRef rangeToReplace, WKInsertActionType action)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return true;
+
static const char *insertactionstring[] = {
"WebViewInsertActionTyped",
"WebViewInsertActionPasted",
@@ -586,6 +636,9 @@ bool InjectedBundlePage::shouldInsertText(WKStringRef text, WKBundleRangeRef ran
bool InjectedBundlePage::shouldDeleteRange(WKBundleRangeRef range)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return true;
+
if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
InjectedBundle::shared().os() << "EDITING DELEGATE: shouldDeleteDOMRange:" << range << "\n";
return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
@@ -593,6 +646,9 @@ bool InjectedBundlePage::shouldDeleteRange(WKBundleRangeRef range)
bool InjectedBundlePage::shouldChangeSelectedRange(WKBundleRangeRef fromRange, WKBundleRangeRef toRange, WKAffinityType affinity, bool stillSelecting)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return true;
+
static const char *affinitystring[] = {
"NSSelectionAffinityUpstream",
"NSSelectionAffinityDownstream"
@@ -609,6 +665,9 @@ bool InjectedBundlePage::shouldChangeSelectedRange(WKBundleRangeRef fromRange, W
bool InjectedBundlePage::shouldApplyStyle(WKBundleCSSStyleDeclarationRef style, WKBundleRangeRef range)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return true;
+
if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
InjectedBundle::shared().os() << "EDITING DELEGATE: shouldApplyStyle:" << style << " toElementsInDOMRange:" << range << "\n";
return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
@@ -616,27 +675,38 @@ bool InjectedBundlePage::shouldApplyStyle(WKBundleCSSStyleDeclarationRef style,
void InjectedBundlePage::didBeginEditing(WKStringRef notificationName)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
InjectedBundle::shared().os() << "EDITING DELEGATE: webViewDidBeginEditing:" << notificationName << "\n";
}
void InjectedBundlePage::didEndEditing(WKStringRef notificationName)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
InjectedBundle::shared().os() << "EDITING DELEGATE: webViewDidEndEditing:" << notificationName << "\n";
}
void InjectedBundlePage::didChange(WKStringRef notificationName)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
InjectedBundle::shared().os() << "EDITING DELEGATE: webViewDidChange:" << notificationName << "\n";
}
void InjectedBundlePage::didChangeSelection(WKStringRef notificationName)
{
+ if (!InjectedBundle::shared().isTestRunning())
+ return;
+
if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
InjectedBundle::shared().os() << "EDITING DELEGATE: webViewDidChangeSelection:" << notificationName << "\n";
}
-
} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
index 8909883..3f63bf3 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
@@ -38,6 +38,7 @@ public:
WKBundlePageRef page() const { return m_page; }
void dump();
+ void stopLoading();
bool isLoading() { return m_isLoading; }
void reset();
diff --git a/WebKitTools/WebKitTestRunner/PlatformWebView.h b/WebKitTools/WebKitTestRunner/PlatformWebView.h
index 6fc4509..29c63ae 100644
--- a/WebKitTools/WebKitTestRunner/PlatformWebView.h
+++ b/WebKitTools/WebKitTestRunner/PlatformWebView.h
@@ -51,6 +51,7 @@ public:
WKPageRef page();
PlatformWKView platformView() { return m_view; }
void resizeTo(unsigned width, unsigned height);
+ void focus();
private:
PlatformWKView m_view;
diff --git a/WebKitTools/WebKitTestRunner/StringFunctions.h b/WebKitTools/WebKitTestRunner/StringFunctions.h
index 4f8fe93..8195606 100644
--- a/WebKitTools/WebKitTestRunner/StringFunctions.h
+++ b/WebKitTools/WebKitTestRunner/StringFunctions.h
@@ -52,6 +52,16 @@ inline RetainPtr<CFStringRef> toCF(WKStringRef string)
return RetainPtr<CFStringRef>(AdoptCF, WKStringCopyCFString(0, string));
}
+inline RetainPtr<CFURLRef> toCF(WKURLRef url)
+{
+ return RetainPtr<CFURLRef>(AdoptCF, WKURLCopyCFURL(0, url));
+}
+
+inline RetainPtr<CFURLRef> toCF(const WKRetainPtr<WKURLRef>& url)
+{
+ return toCF(url.get());
+}
+
inline WKRetainPtr<WKStringRef> toWK(JSStringRef string)
{
return WKRetainPtr<WKStringRef>(AdoptWK, WKStringCreateWithCFString(toCF(string).get()));
diff --git a/WebKitTools/WebKitTestRunner/TestController.cpp b/WebKitTools/WebKitTestRunner/TestController.cpp
index 93857a7..c8a78d5 100644
--- a/WebKitTools/WebKitTestRunner/TestController.cpp
+++ b/WebKitTools/WebKitTestRunner/TestController.cpp
@@ -26,8 +26,10 @@
#include "TestController.h"
#include "PlatformWebView.h"
+#include "StringFunctions.h"
#include "TestInvocation.h"
#include <WebKit2/WKContextPrivate.h>
+#include <WebKit2/WKPreferencesPrivate.h>
#include <wtf/PassOwnPtr.h>
namespace WTR {
@@ -45,6 +47,8 @@ TestController::TestController(int argc, const char* argv[])
, m_verbose(false)
, m_printSeparators(false)
, m_usingServerMode(false)
+ , m_state(Initial)
+ , m_doneResetting(false)
{
initialize(argc, argv);
controller = this;
@@ -78,6 +82,7 @@ static WKPageRef createOtherPage(WKPageRef oldPage, const void*)
closeOtherPage,
0,
0,
+ 0,
0
};
WKPageSetPageUIClient(newPage, &otherPageUIClient);
@@ -119,6 +124,7 @@ void TestController::initialize(int argc, const char* argv[])
initializeTestPluginDirectory();
m_context.adopt(WKContextCreateWithInjectedBundlePath(injectedBundlePath()));
+ platformInitializeContext();
WKContextInjectedBundleClient injectedBundleClient = {
0,
@@ -128,7 +134,7 @@ void TestController::initialize(int argc, const char* argv[])
WKContextSetInjectedBundleClient(m_context.get(), &injectedBundleClient);
_WKContextSetAdditionalPluginsDirectory(m_context.get(), testPluginDirectory());
-
+
m_pageNamespace.adopt(WKPageNamespaceCreate(m_context.get()));
m_mainWebView = adoptPtr(new PlatformWebView(m_pageNamespace.get()));
@@ -140,13 +146,60 @@ void TestController::initialize(int argc, const char* argv[])
0,
0,
0,
+ 0,
0
};
WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient);
+
+ WKPageLoaderClient pageLoaderClient = {
+ 0,
+ this,
+ 0,
+ 0,
+ 0,
+ 0,
+ didFinishLoadForFrame,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ };
+ WKPageSetPageLoaderClient(m_mainWebView->page(), &pageLoaderClient);
+}
+
+void TestController::resetStateToConsistentValues()
+{
+ m_state = Resetting;
+
+ // FIXME: This function should also ensure that there is only one page open.
+
+ // Reset preferences
+ WKPreferencesRef preferences = WKContextGetPreferences(m_context.get());
+ WKPreferencesSetOfflineWebApplicationCacheEnabled(preferences, true);
+ WKPreferencesSetFontSmoothingLevel(preferences, kWKFontSmoothingLevelNoSubpixelAntiAliasing);
+
+ m_mainWebView->focus();
+
+ // Reset main page back to about:blank
+ m_doneResetting = false;
+
+ WKRetainPtr<WKURLRef> url(AdoptWK, createWKURL("about:blank"));
+ WKPageLoadURL(m_mainWebView->page(), url.get());
+ TestController::runUntil(m_doneResetting);
}
void TestController::runTest(const char* test)
{
+ resetStateToConsistentValues();
+
+ m_state = RunningTest;
m_currentInvocation.set(new TestInvocation(test));
m_currentInvocation->invoke();
m_currentInvocation.clear();
@@ -177,6 +230,8 @@ void TestController::run()
}
}
+// WKContextInjectedBundleClient
+
void TestController::didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo)
{
static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveMessageFromInjectedBundle(messageName, messageBody);
@@ -187,4 +242,28 @@ void TestController::didReceiveMessageFromInjectedBundle(WKStringRef messageName
m_currentInvocation->didReceiveMessageFromInjectedBundle(messageName, messageBody);
}
+// WKPageLoaderClient
+
+void TestController::didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, const void* clientInfo)
+{
+ static_cast<TestController*>(const_cast<void*>(clientInfo))->didFinishLoadForFrame(page, frame);
+}
+
+void TestController::didFinishLoadForFrame(WKPageRef page, WKFrameRef frame)
+{
+ if (m_state != Resetting)
+ return;
+
+ if (!WKFrameIsMainFrame(frame))
+ return;
+
+ WKRetainPtr<WKURLRef> wkURL(AdoptWK, WKFrameCopyURL(frame));
+ RetainPtr<CFURLRef> cfURL= toCF(wkURL);
+ CFStringRef cfURLString = CFURLGetString(cfURL.get());
+ if (!CFEqual(cfURLString, CFSTR("about:blank")))
+ return;
+
+ m_doneResetting = true;
+}
+
} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/TestController.h b/WebKitTools/WebKitTestRunner/TestController.h
index 5754728..5f6d99d 100644
--- a/WebKitTools/WebKitTestRunner/TestController.h
+++ b/WebKitTools/WebKitTestRunner/TestController.h
@@ -53,6 +53,9 @@ public:
WKPageNamespaceRef pageNamespace() { return m_pageNamespace.get(); }
WKContextRef context() { return m_context.get(); }
+ // Helper
+ static void runUntil(bool& done);
+
private:
void initialize(int argc, const char* argv[]);
void run();
@@ -61,13 +64,21 @@ private:
void runTest(const char* pathOrURL);
void platformInitialize();
+ void platformInitializeContext();
void initializeInjectedBundlePath();
void initializeTestPluginDirectory();
+ void resetStateToConsistentValues();
+
// WKContextInjectedBundleClient
static void didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void*);
void didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody);
+ // WKPageLoaderClient
+ static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, const void*);
+ void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame);
+
+
OwnPtr<TestInvocation> m_currentInvocation;
bool m_dumpPixels;
@@ -81,6 +92,14 @@ private:
OwnPtr<PlatformWebView> m_mainWebView;
WKRetainPtr<WKContextRef> m_context;
WKRetainPtr<WKPageNamespaceRef> m_pageNamespace;
+
+ enum State {
+ Initial,
+ Resetting,
+ RunningTest
+ };
+ State m_state;
+ bool m_doneResetting;
};
} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/TestInvocation.cpp b/WebKitTools/WebKitTestRunner/TestInvocation.cpp
index 9a0f0aa..47df66b 100644
--- a/WebKitTools/WebKitTestRunner/TestInvocation.cpp
+++ b/WebKitTools/WebKitTestRunner/TestInvocation.cpp
@@ -29,7 +29,6 @@
#include "StringFunctions.h"
#include "TestController.h"
#include <WebKit2/WKContextPrivate.h>
-#include <WebKit2/WKPreferencesPrivate.h>
#include <WebKit2/WKRetainPtr.h>
#include <wtf/RetainPtr.h>
@@ -59,7 +58,7 @@ static const unsigned normalHeight = 600;
static void sizeWebViewForCurrentTest(char* pathOrURL)
{
- bool isSVGW3CTest = strstr(pathOrURL, "svg/W3C-SVG-1.1");
+ bool isSVGW3CTest = strstr(pathOrURL, "svg/W3C-SVG-1.1") || strstr(pathOrURL, "svg\\W3C-SVG-1.1");
if (isSVGW3CTest)
TestController::shared().mainWebView()->resizeTo(w3cSVGWidth, w3cSVGHeight);
@@ -67,23 +66,15 @@ static void sizeWebViewForCurrentTest(char* pathOrURL)
TestController::shared().mainWebView()->resizeTo(normalWidth, normalHeight);
}
-void TestInvocation::resetPreferencesToConsistentValues()
-{
- WKPreferencesRef preferences = WKContextGetPreferences(TestController::shared().context());
- WKPreferencesSetOfflineWebApplicationCacheEnabled(preferences, true);
- WKPreferencesSetFontSmoothingLevel(preferences, kWKFontSmoothingLevelNoSubpixelAntiAliasing);
-}
-
void TestInvocation::invoke()
{
sizeWebViewForCurrentTest(m_pathOrURL);
- resetPreferencesToConsistentValues();
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithCFString(CFSTR("BeginTest")));
WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithCFString(CFSTR("")));
WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), messageBody.get());
- runUntil(m_gotInitialResponse);
+ TestController::runUntil(m_gotInitialResponse);
if (m_error) {
dump("FAIL\n");
return;
@@ -91,7 +82,7 @@ void TestInvocation::invoke()
WKPageLoadURL(TestController::shared().mainWebView()->page(), m_url.get());
- runUntil(m_gotFinalMessage);
+ TestController::runUntil(m_gotFinalMessage);
if (m_error) {
dump("FAIL\n");
return;
diff --git a/WebKitTools/WebKitTestRunner/TestInvocation.h b/WebKitTools/WebKitTestRunner/TestInvocation.h
index 484e61d..1b33e49 100644
--- a/WebKitTools/WebKitTestRunner/TestInvocation.h
+++ b/WebKitTools/WebKitTestRunner/TestInvocation.h
@@ -42,11 +42,6 @@ public:
private:
void dump(const char*);
- void resetPreferencesToConsistentValues();
-
- // Helper
- static void runUntil(bool& done);
-
WKRetainPtr<WKURLRef> m_url;
char* m_pathOrURL;
diff --git a/WebKitTools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj b/WebKitTools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj
index 6f78289..f5ee6d5 100644
--- a/WebKitTools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj
+++ b/WebKitTools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj
@@ -53,7 +53,6 @@
BCC997A511D3C8F60017BCA2 /* InjectedBundlePage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC997A211D3C8F60017BCA2 /* InjectedBundlePage.cpp */; };
BCC9981811D3F51E0017BCA2 /* LayoutTestController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC9981711D3F51E0017BCA2 /* LayoutTestController.cpp */; };
BCD7D2F811921278006DB7EE /* TestInvocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD7D2F711921278006DB7EE /* TestInvocation.cpp */; };
- BCDA2ABF1190B51A00C3BC47 /* TestInvocationMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCDA2ABE1190B51A00C3BC47 /* TestInvocationMac.mm */; };
BCDA2B9A1191051F00C3BC47 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCDA2B991191051F00C3BC47 /* JavaScriptCore.framework */; };
/* End PBXBuildFile section */
@@ -132,7 +131,6 @@
BCC9981711D3F51E0017BCA2 /* LayoutTestController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutTestController.cpp; sourceTree = "<group>"; };
BCD7D2F611921278006DB7EE /* TestInvocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestInvocation.h; sourceTree = "<group>"; };
BCD7D2F711921278006DB7EE /* TestInvocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestInvocation.cpp; sourceTree = "<group>"; };
- BCDA2ABE1190B51A00C3BC47 /* TestInvocationMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestInvocationMac.mm; sourceTree = "<group>"; };
BCDA2B991191051F00C3BC47 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = JavaScriptCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -270,7 +268,6 @@
children = (
BC7933FF118F7C84005EA8E2 /* main.mm */,
BC7934E711906846005EA8E2 /* PlatformWebViewMac.mm */,
- BCDA2ABE1190B51A00C3BC47 /* TestInvocationMac.mm */,
BC8C795B11D2785D004535A1 /* TestControllerMac.mm */,
);
path = mac;
@@ -426,7 +423,6 @@
BC793400118F7C84005EA8E2 /* main.mm in Sources */,
BC793431118F7F19005EA8E2 /* TestController.cpp in Sources */,
BC7934E811906846005EA8E2 /* PlatformWebViewMac.mm in Sources */,
- BCDA2ABF1190B51A00C3BC47 /* TestInvocationMac.mm in Sources */,
BCD7D2F811921278006DB7EE /* TestInvocation.cpp in Sources */,
BC8C795C11D2785D004535A1 /* TestControllerMac.mm in Sources */,
);
diff --git a/WebKitTools/WebKitTestRunner/mac/PlatformWebViewMac.mm b/WebKitTools/WebKitTestRunner/mac/PlatformWebViewMac.mm
index 4e2a60c..96e6526 100644
--- a/WebKitTools/WebKitTestRunner/mac/PlatformWebViewMac.mm
+++ b/WebKitTools/WebKitTestRunner/mac/PlatformWebViewMac.mm
@@ -58,4 +58,9 @@ WKPageRef PlatformWebView::page()
return [m_view pageRef];
}
+void PlatformWebView::focus()
+{
+ // Implement.
+}
+
} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm b/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm
index 1a71b5d..dbe35e2 100644
--- a/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm
+++ b/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm
@@ -45,4 +45,14 @@ void TestController::initializeTestPluginDirectory()
m_testPluginDirectory.adopt(WKStringCreateWithCFString((CFStringRef)[[NSBundle mainBundle] bundlePath]));
}
+void TestController::runUntil(bool& done)
+{
+ while (!done)
+ [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+}
+
+void TestController::platformInitializeContext()
+{
+}
+
} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/mac/TestInvocationMac.mm b/WebKitTools/WebKitTestRunner/mac/TestInvocationMac.mm
deleted file mode 100644
index bd01029..0000000
--- a/WebKitTools/WebKitTestRunner/mac/TestInvocationMac.mm
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2010 Apple 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:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
- */
-
-#include "TestInvocation.h"
-
-namespace WTR {
-
-void TestInvocation::runUntil(bool& done)
-{
- while (!done)
- [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
-}
-
-} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/win/PlatformWebViewWin.cpp b/WebKitTools/WebKitTestRunner/win/PlatformWebViewWin.cpp
index e602d0e..deed4ab 100644
--- a/WebKitTools/WebKitTestRunner/win/PlatformWebViewWin.cpp
+++ b/WebKitTools/WebKitTestRunner/win/PlatformWebViewWin.cpp
@@ -65,7 +65,7 @@ PlatformWebView::~PlatformWebView()
void PlatformWebView::resizeTo(unsigned width, unsigned height)
{
- // Implement
+ ::SetWindowPos(WKViewGetWindow(m_view), 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS);
}
WKPageRef PlatformWebView::page()
@@ -73,4 +73,9 @@ WKPageRef PlatformWebView::page()
return WKViewGetPage(m_view);
}
+void PlatformWebView::focus()
+{
+ ::SetFocus(::WKViewGetWindow(m_view));
+}
+
} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp b/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp
index f650d7f..e35ee22 100644
--- a/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp
+++ b/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp
@@ -29,6 +29,7 @@
#include <io.h>
#include <shlwapi.h>
#include <string>
+#include <WebKit2/WKContextPrivateWin.h>
#include <WebKit2/WKStringCF.h>
#include <wtf/RetainPtr.h>
#include <wtf/Vector.h>
@@ -80,8 +81,17 @@ static void addQTDirToPATH()
::SetEnvironmentVariableW(pathEnvironmentVariable, newPath.data());
}
+static LONG WINAPI exceptionFilter(EXCEPTION_POINTERS*)
+{
+ fputs("#CRASHED\n", stderr);
+ fflush(stderr);
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
void TestController::platformInitialize()
{
+ ::SetUnhandledExceptionFilter(exceptionFilter);
+
_setmode(1, _O_BINARY);
_setmode(2, _O_BINARY);
@@ -113,4 +123,22 @@ void TestController::initializeTestPluginDirectory()
m_testPluginDirectory.adopt(WKStringCreateWithCFString(testPluginDirectoryPath.get()));
}
+void TestController::runUntil(bool& done)
+{
+ while (!done) {
+ MSG msg;
+ BOOL result = GetMessage(&msg, 0, 0, 0);
+ if (result == -1)
+ return;
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+}
+
+void TestController::platformInitializeContext()
+{
+ // FIXME: Make DRT pass with Windows native controls. <http://webkit.org/b/25592>
+ WKContextSetShouldPaintNativeControls(m_context.get(), false);
+}
+
} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/win/TestInvocationWin.cpp b/WebKitTools/WebKitTestRunner/win/TestInvocationWin.cpp
deleted file mode 100644
index cfeebcc..0000000
--- a/WebKitTools/WebKitTestRunner/win/TestInvocationWin.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2010 Apple 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:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
- */
-
-#include "TestInvocation.h"
-
-namespace WTR {
-
-void TestInvocation::runUntil(bool& done)
-{
- while (!done) {
- MSG msg;
- BOOL result = GetMessage(&msg, 0, 0, 0);
- if (result == -1)
- return;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-}
-
-} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj b/WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj
index 7375bd4..d7ddd5c 100644
--- a/WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj
+++ b/WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj
@@ -317,10 +317,6 @@
RelativePath=".\TestControllerWin.cpp"
>
</File>
- <File
- RelativePath=".\TestInvocationWin.cpp"
- >
- </File>
</Filter>
<File
RelativePath="..\PlatformWebView.h"
diff --git a/WebKitTools/gdb/webcore.py b/WebKitTools/gdb/webcore.py
index 83886f8..8dc4d8e 100644
--- a/WebKitTools/gdb/webcore.py
+++ b/WebKitTools/gdb/webcore.py
@@ -26,170 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""GDB support for WebKit types.
-
-Add this to your gdb by amending your ~/.gdbinit as follows:
- python
- import sys
- sys.path.insert(0, "/path/to/tools/gdb/")
- import webcore
-"""
-
-import gdb
-import struct
-
-def ustring_to_string(ptr, length=None):
- """Convert a pointer to UTF-16 data into a Python Unicode string.
-
- ptr and length are both gdb.Value objects.
- If length is unspecified, will guess at the length."""
- extra = ''
- if length is None:
- # Try to guess at the length.
- for i in xrange(0, 2048):
- if int((ptr + i).dereference()) == 0:
- length = i
- break
- if length is None:
- length = 256
- extra = u' (no trailing NUL found)'
- else:
- length = int(length)
-
- char_vals = [int((ptr + i).dereference()) for i in xrange(length)]
- string = struct.pack('H' * length, *char_vals).decode('utf-16', 'replace')
-
- return string + extra
-
-
-class StringPrinter(object):
- "Shared code between different string-printing classes"
- def __init__(self, val):
- self.val = val
-
- def display_hint(self):
- return 'string'
-
-
-class UCharStringPrinter(StringPrinter):
- "Print a UChar*; we must guess at the length"
- def to_string(self):
- return ustring_to_string(self.val)
-
-
-class WebCoreAtomicStringPrinter(StringPrinter):
- "Print a WebCore::AtomicString"
- def to_string(self):
- return self.val['m_string']
-
-
-class WebCoreStringPrinter(StringPrinter):
- "Print a WebCore::String"
- def get_length(self):
- if not self.val['m_impl']['m_ptr']:
- return 0
- return self.val['m_impl']['m_ptr']['m_length']
-
- def to_string(self):
- if self.get_length() == 0:
- return '(null)'
-
- return ustring_to_string(self.val['m_impl']['m_ptr']['m_data'],
- self.get_length())
-
-
-class WebCoreQualifiedNamePrinter(StringPrinter):
- "Print a WebCore::QualifiedName"
-
- def __init__(self, val):
- super(WebCoreQualifiedNamePrinter, self).__init__(val)
- self.prefix_length = 0
- self.length = 0
- if self.val['m_impl']:
- self.prefix_printer = WebCoreStringPrinter(
- self.val['m_impl']['m_prefix']['m_string'])
- self.local_name_printer = WebCoreStringPrinter(
- self.val['m_impl']['m_localName']['m_string'])
- self.prefix_length = self.prefix_printer.get_length()
- if self.prefix_length > 0:
- self.length = (self.prefix_length + 1 +
- self.local_name_printer.get_length())
- else:
- self.length = self.local_name_printer.get_length()
-
- def get_length(self):
- return self.length
-
- def to_string(self):
- if self.get_length() == 0:
- return "(null)"
- else:
- if self.prefix_length > 0:
- return (self.prefix_printer.to_string() + ":" +
- self.local_name_printer.to_string())
- else:
- return self.local_name_printer.to_string()
-
-
-
-def lookup_function(val):
- """Function used to load pretty printers; will be passed to GDB."""
- lookup_tag = val.type.tag
- printers = {
- "WebCore::AtomicString": WebCoreAtomicStringPrinter,
- "WebCore::String": WebCoreStringPrinter,
- "WebCore::QualifiedName": WebCoreQualifiedNamePrinter,
- }
- name = val.type.tag
- if name in printers:
- return printers[name](val)
-
- if val.type.code == gdb.TYPE_CODE_PTR:
- name = str(val.type.target().unqualified())
- if name == 'UChar':
- return UCharStringPrinter(val)
-
- return None
-
-
-gdb.pretty_printers.append(lookup_function)
-
-
-
-class PrintPathToRootCommand(gdb.Command):
- """Command for printing WebKit Node trees.
-Usage: printpathtoroot variable_name
-"""
-
- def __init__(self):
- super(PrintPathToRootCommand, self).__init__("printpathtoroot",
- gdb.COMMAND_SUPPORT,
- gdb.COMPLETE_NONE)
-
- def invoke(self, arg, from_tty):
- element_type = gdb.lookup_type('WebCore::Element')
- node_type = gdb.lookup_type('WebCore::Node')
- frame = gdb.selected_frame()
- try:
- val = gdb.Frame.read_var(frame, arg)
- except:
- print "No such variable, or invalid type"
- return
-
- target_type = str(val.type.target().strip_typedefs())
- if target_type == str(node_type):
- stack = []
- while val:
- stack.append([val,
- val.cast(element_type.pointer()).dereference()['m_tagName']])
- val = val.dereference()['m_parent']
-
- padding = ''
- while len(stack) > 0:
- pair = stack.pop()
- print padding, pair[1], pair[0]
- padding = padding + ' '
- else:
- print 'Sorry: I don\'t know how to deal with %s yet.' % target_type
-
-PrintPathToRootCommand()
+# For backward compatibility.
+import webkit
+print ("webcore.py is deprecated. Please use 'import webkit' instead of "
+ "'import webcore' in your ~/.gdbinit.")
diff --git a/WebKitTools/gdb/webkit.py b/WebKitTools/gdb/webkit.py
new file mode 100644
index 0000000..2d3b47a
--- /dev/null
+++ b/WebKitTools/gdb/webkit.py
@@ -0,0 +1,272 @@
+# 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.
+
+"""GDB support for WebKit types.
+
+Add this to your gdb by amending your ~/.gdbinit as follows:
+ python
+ import sys
+ sys.path.insert(0, "/path/to/tools/gdb/")
+ import webkit
+"""
+
+import gdb
+import re
+import struct
+
+
+def ustring_to_string(ptr, length=None):
+ """Convert a pointer to UTF-16 data into a Python Unicode string.
+
+ ptr and length are both gdb.Value objects.
+ If length is unspecified, will guess at the length."""
+ extra = ''
+ if length is None:
+ # Try to guess at the length.
+ for i in xrange(0, 2048):
+ if int((ptr + i).dereference()) == 0:
+ length = i
+ break
+ if length is None:
+ length = 256
+ extra = u' (no trailing NUL found)'
+ else:
+ length = int(length)
+
+ char_vals = [int((ptr + i).dereference()) for i in xrange(length)]
+ string = struct.pack('H' * length, *char_vals).decode('utf-16', 'replace')
+
+ return string + extra
+
+
+class StringPrinter(object):
+ "Shared code between different string-printing classes"
+ def __init__(self, val):
+ self.val = val
+
+ def display_hint(self):
+ return 'string'
+
+
+class UCharStringPrinter(StringPrinter):
+ "Print a UChar*; we must guess at the length"
+ def to_string(self):
+ return ustring_to_string(self.val)
+
+
+class WTFAtomicStringPrinter(StringPrinter):
+ "Print a WTF::AtomicString"
+ def to_string(self):
+ return self.val['m_string']
+
+
+class WTFStringPrinter(StringPrinter):
+ "Print a WTF::String"
+ def get_length(self):
+ if not self.val['m_impl']['m_ptr']:
+ return 0
+ return self.val['m_impl']['m_ptr']['m_length']
+
+ def to_string(self):
+ if self.get_length() == 0:
+ return '(null)'
+
+ return ustring_to_string(self.val['m_impl']['m_ptr']['m_data'],
+ self.get_length())
+
+
+class WebCoreQualifiedNamePrinter(StringPrinter):
+ "Print a WebCore::QualifiedName"
+
+ def __init__(self, val):
+ super(WebCoreQualifiedNamePrinter, self).__init__(val)
+ self.prefix_length = 0
+ self.length = 0
+ if self.val['m_impl']:
+ self.prefix_printer = WTFStringPrinter(
+ self.val['m_impl']['m_prefix']['m_string'])
+ self.local_name_printer = WTFStringPrinter(
+ self.val['m_impl']['m_localName']['m_string'])
+ self.prefix_length = self.prefix_printer.get_length()
+ if self.prefix_length > 0:
+ self.length = (self.prefix_length + 1 +
+ self.local_name_printer.get_length())
+ else:
+ self.length = self.local_name_printer.get_length()
+
+ def get_length(self):
+ return self.length
+
+ def to_string(self):
+ if self.get_length() == 0:
+ return "(null)"
+ else:
+ if self.prefix_length > 0:
+ return (self.prefix_printer.to_string() + ":" +
+ self.local_name_printer.to_string())
+ else:
+ return self.local_name_printer.to_string()
+
+
+class WTFVectorPrinter:
+ """Pretty Printer for a WTF::Vector.
+
+ The output of this pretty printer is similar to the output of std::vector's
+ pretty printer, which is bundled in gcc.
+
+ Example gdb session should look like:
+ (gdb) p v
+ $3 = WTF::Vector of length 7, capacity 16 = {7, 17, 27, 37, 47, 57, 67}
+ (gdb) set print elements 3
+ (gdb) p v
+ $6 = WTF::Vector of length 7, capacity 16 = {7, 17, 27...}
+ (gdb) set print array
+ (gdb) p v
+ $7 = WTF::Vector of length 7, capacity 16 = {
+ 7,
+ 17,
+ 27
+ ...
+ }
+ (gdb) set print elements 200
+ (gdb) p v
+ $8 = WTF::Vector of length 7, capacity 16 = {
+ 7,
+ 17,
+ 27,
+ 37,
+ 47,
+ 57,
+ 67
+ }
+ """
+
+ class Iterator:
+ def __init__(self, start, finish):
+ self.item = start
+ self.finish = finish
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.item == self.finish:
+ raise StopIteration
+ count = self.count
+ self.count += 1
+ element = self.item.dereference()
+ self.item += 1
+ return ('[%d]' % count, element)
+
+ def __init__(self, val):
+ self.val = val
+
+ def children(self):
+ start = self.val['m_buffer']['m_buffer']
+ return self.Iterator(start, start + self.val['m_size'])
+
+ def to_string(self):
+ return ('%s of length %d, capacity %d'
+ % ('WTF::Vector', self.val['m_size'], self.val['m_buffer']['m_capacity']))
+
+ def display_hint(self):
+ return 'array'
+
+
+def add_pretty_printers():
+ pretty_printers_dict = {
+ re.compile("^WTF::Vector<.*>$"): WTFVectorPrinter,
+ re.compile("^WTF::AtomicString$"): WTFAtomicStringPrinter,
+ re.compile("^WTF::String$"): WTFStringPrinter,
+ re.compile("^WebCore::QualifiedName$"): WebCoreQualifiedNamePrinter,
+ }
+
+ def lookup_function(val):
+ """Function used to load pretty printers; will be passed to GDB."""
+ type = val.type
+ if type.code == gdb.TYPE_CODE_REF:
+ type = type.target()
+ type = type.unqualified().strip_typedefs()
+ typename = type.tag
+ if not typename:
+ return None
+ for function, pretty_printer in pretty_printers_dict.items():
+ if function.search(typename):
+ return pretty_printer(val)
+
+ if type.code == gdb.TYPE_CODE_PTR:
+ name = str(type.target().unqualified())
+ if name == 'UChar':
+ return UCharStringPrinter(val)
+ return None
+
+ gdb.pretty_printers.append(lookup_function)
+
+
+add_pretty_printers()
+
+
+class PrintPathToRootCommand(gdb.Command):
+ """Command for printing WebKit Node trees.
+
+ Usage: printpathtoroot variable_name"""
+
+ def __init__(self):
+ super(PrintPathToRootCommand, self).__init__("printpathtoroot",
+ gdb.COMMAND_SUPPORT,
+ gdb.COMPLETE_NONE)
+
+ def invoke(self, arg, from_tty):
+ element_type = gdb.lookup_type('WebCore::Element')
+ node_type = gdb.lookup_type('WebCore::Node')
+ frame = gdb.selected_frame()
+ try:
+ val = gdb.Frame.read_var(frame, arg)
+ except:
+ print "No such variable, or invalid type"
+ return
+
+ target_type = str(val.type.target().strip_typedefs())
+ if target_type == str(node_type):
+ stack = []
+ while val:
+ stack.append([val,
+ val.cast(element_type.pointer()).dereference()['m_tagName']])
+ val = val.dereference()['m_parent']
+
+ padding = ''
+ while len(stack) > 0:
+ pair = stack.pop()
+ print padding, pair[1], pair[0]
+ padding = padding + ' '
+ else:
+ print 'Sorry: I don\'t know how to deal with %s yet.' % target_type
+
+
+PrintPathToRootCommand()
diff --git a/WebKitTools/gdb/wtf.py b/WebKitTools/gdb/wtf.py
deleted file mode 100644
index cf4b59b..0000000
--- a/WebKitTools/gdb/wtf.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# 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.
-
-"""GDB support for WebKit WTF types.
-
-Add this to your gdb by amending your ~/.gdbinit as follows:
- python
- import sys
- sys.path.insert(0, "/path/to/tools/gdb/")
- import wtf
-
-See http://sourceware.org/gdb/current/onlinedocs/gdb/Python.html for GDB's
-Python API.
-"""
-
-import gdb
-import re
-
-
-class WTFVectorPrinter:
- """Pretty Printer for a WTF::Vector.
-
- The output of this pretty printer is similar to the output of std::vector's
- pretty printer, which is bundled in gcc.
-
- Example gdb session should look like:
- (gdb) p v
- $3 = WTF::Vector of length 7, capacity 16 = {7, 17, 27, 37, 47, 57, 67}
- (gdb) set print elements 3
- (gdb) p v
- $6 = WTF::Vector of length 7, capacity 16 = {7, 17, 27...}
- (gdb) set print array
- (gdb) p v
- $7 = WTF::Vector of length 7, capacity 16 = {
- 7,
- 17,
- 27
- ...
- }
- (gdb) set print elements 200
- (gdb) p v
- $8 = WTF::Vector of length 7, capacity 16 = {
- 7,
- 17,
- 27,
- 37,
- 47,
- 57,
- 67
- }
- """
-
- class Iterator:
- def __init__(self, start, finish):
- self.item = start
- self.finish = finish
- self.count = 0
-
- def __iter__(self):
- return self
-
- def next(self):
- if self.item == self.finish:
- raise StopIteration
- count = self.count
- self.count += 1
- element = self.item.dereference()
- self.item += 1
- return ('[%d]' % count, element)
-
- def __init__(self, val):
- self.val = val
-
- def children(self):
- start = self.val['m_buffer']['m_buffer']
- return self.Iterator(start, start + self.val['m_size'])
-
- def to_string(self):
- return ('%s of length %d, capacity %d'
- % ('WTF::Vector', self.val['m_size'], self.val['m_buffer']['m_capacity']))
-
- def display_hint(self):
- return 'array'
-
-
-def lookup_function(val):
- type = val.type
- if type.code == gdb.TYPE_CODE_REF:
- type = type.target()
- type = type.unqualified().strip_typedefs()
- typename = type.tag
- if not typename:
- return None
- for function, pretty_printer in pretty_printers_dict.items():
- if function.search(typename):
- return pretty_printer(val)
- return None
-
-
-def build_pretty_printers_dict():
- pretty_printers_dict[re.compile('^WTF::Vector<.*>$')] = WTFVectorPrinter
-
-
-pretty_printers_dict = {}
-
-build_pretty_printers_dict()
-
-gdb.pretty_printers.append(lookup_function)
diff --git a/WebKitTools/wx/browser/wscript b/WebKitTools/wx/browser/wscript
index bd2640c..8c22cf6 100644
--- a/WebKitTools/wx/browser/wscript
+++ b/WebKitTools/wx/browser/wscript
@@ -46,9 +46,9 @@ def build(bld):
includes = ' '.join(include_paths),
source = 'browser.cpp',
target = 'wxBrowser',
- uselib = 'WX CURL ICU XSLT XML WXWEBKIT ' + get_config(),
+ uselib = 'WX CURL ICU XSLT XML ' + get_config(),
libpath = [output_dir],
- uselib_local = '',
+ uselib_local = 'wxwebkit',
install_path = output_dir)
if sys.platform.startswith('darwin'):
diff --git a/WebKitTools/wx/build/settings.py b/WebKitTools/wx/build/settings.py
index be43873..74d9789 100644
--- a/WebKitTools/wx/build/settings.py
+++ b/WebKitTools/wx/build/settings.py
@@ -97,56 +97,56 @@ jscore_dirs = [
]
webcore_dirs = [
- 'accessibility',
- 'bindings',
- 'bindings/cpp',
- 'bindings/generic',
- 'bindings/js',
- 'bridge',
- 'bridge/c',
- 'bridge/jsc',
- 'css',
- 'DerivedSources',
- 'dom',
- 'dom/default',
- 'editing',
- 'history',
- 'html',
- 'html/canvas',
- 'inspector',
- 'loader',
- 'loader/appcache',
- 'loader/archive',
- 'loader/icon',
- 'notifications',
- 'page',
- 'page/animation',
- 'platform',
- 'platform/animation',
- 'platform/graphics',
- 'platform/graphics/filters',
- 'platform/graphics/transforms',
- 'platform/image-decoders',
- 'platform/image-decoders/bmp',
- 'platform/image-decoders/gif',
- 'platform/image-decoders/ico',
- 'platform/image-decoders/jpeg',
- 'platform/image-decoders/png',
- 'platform/mock',
- 'platform/network',
- 'platform/sql',
- 'platform/text',
- 'platform/text/transcoder',
- 'plugins',
- 'rendering',
- 'rendering/style',
- 'storage',
- 'svg',
- 'svg/animation',
- 'svg/graphics',
- 'svg/graphics/filters',
- 'websockets',
- 'xml'
+ 'WebCore/accessibility',
+ 'WebCore/bindings',
+ 'WebCore/bindings/cpp',
+ 'WebCore/bindings/generic',
+ 'WebCore/bindings/js',
+ 'WebCore/bridge',
+ 'WebCore/bridge/c',
+ 'WebCore/bridge/jsc',
+ 'WebCore/css',
+ 'WebCore/DerivedSources',
+ 'WebCore/dom',
+ 'WebCore/dom/default',
+ 'WebCore/editing',
+ 'WebCore/history',
+ 'WebCore/html',
+ 'WebCore/html/canvas',
+ 'WebCore/inspector',
+ 'WebCore/loader',
+ 'WebCore/loader/appcache',
+ 'WebCore/loader/archive',
+ 'WebCore/loader/icon',
+ 'WebCore/notifications',
+ 'WebCore/page',
+ 'WebCore/page/animation',
+ 'WebCore/platform',
+ 'WebCore/platform/animation',
+ 'WebCore/platform/graphics',
+ 'WebCore/platform/graphics/filters',
+ 'WebCore/platform/graphics/transforms',
+ 'WebCore/platform/image-decoders',
+ 'WebCore/platform/image-decoders/bmp',
+ 'WebCore/platform/image-decoders/gif',
+ 'WebCore/platform/image-decoders/ico',
+ 'WebCore/platform/image-decoders/jpeg',
+ 'WebCore/platform/image-decoders/png',
+ 'WebCore/platform/mock',
+ 'WebCore/platform/network',
+ 'WebCore/platform/sql',
+ 'WebCore/platform/text',
+ 'WebCore/platform/text/transcoder',
+ 'WebCore/plugins',
+ 'WebCore/rendering',
+ 'WebCore/rendering/style',
+ 'WebCore/storage',
+ 'WebCore/svg',
+ 'WebCore/svg/animation',
+ 'WebCore/svg/graphics',
+ 'WebCore/svg/graphics/filters',
+ 'WebCore/websockets',
+ 'WebCore/xml'
]
config = get_config(wk_root)
@@ -180,7 +180,7 @@ os.environ['CREATE_HASH_TABLE'] = create_hash_table
feature_defines = ['ENABLE_DATABASE', 'ENABLE_XSLT', 'ENABLE_JAVASCRIPT_DEBUGGER',
'ENABLE_SVG', 'ENABLE_SVG_USE', 'ENABLE_FILTERS', 'ENABLE_SVG_FONTS',
'ENABLE_SVG_ANIMATION', 'ENABLE_SVG_AS_IMAGE', 'ENABLE_SVG_FOREIGN_OBJECT',
- 'ENABLE_JIT', 'ENABLE_EXECUTABLE_ALLOCATOR_DEMAND', 'BUILDING_%s' % build_port.upper()]
+ 'ENABLE_JIT', 'BUILDING_%s' % build_port.upper()]
msvc_version = 'msvc2008'
@@ -289,9 +289,6 @@ def common_configure(conf):
conf.env.append_value('CXXDEFINES', ['BUILDING_WX__=1', 'JS_NO_EXPORT'])
- conf.env['LIB_WXWEBKIT'] = ['wxwebkit']
- conf.env['CXXDEFINES_WXWEBKIT'] = ['WXUSINGDLL_WEBKIT']
-
if building_on_win32:
conf.env.append_value('LIBPATH', os.path.join(msvclibs_dir, 'lib'))
# wx settings
@@ -303,22 +300,8 @@ def common_configure(conf):
conf.env['LIB_WX'] = wxlibs
conf.env['LIBPATH_WX'] = wxlibpaths
- if building_on_win32:
- conf.env['LIB_JSCORE'] = [libprefix + 'jscore']
- conf.env['LIB_WEBCORE'] = [libprefix + 'webcore']
- elif sys.platform.startswith('darwin'):
- conf.env['LINKFLAGS_JSCORE'] = ['-Wl,-force_load,%s' % os.path.join(output_dir, 'libjscore.a')]
- conf.env['LINKFLAGS_WEBCORE'] = ['-Wl,-force_load,%s' % os.path.join(output_dir, 'libwebcore.a')]
- else:
- conf.env['LINKFLAGS_JSCORE'] = ['-Wl,-whole-archive', '-ljscore', '-Wl,-no-whole-archive']
- conf.env['LINKFLAGS_WEBCORE'] = ['-Wl,-whole-archive', '-lwebcore', '-Wl,-no-whole-archive']
-
if sys.platform.startswith('darwin'):
conf.env['LIB_ICU'] = ['icucore']
- # Apple does not ship the ICU headers with Mac OS X, so WebKit includes a copy of 3.2 headers
- conf.env.append_value('CPPPATH_JSCORE', os.path.join(jscore_dir, 'icu'))
-
- conf.env.append_value('CPPPATH_WEBCORE', os.path.join(webcore_dir, 'icu'))
conf.env.append_value('CPPPATH', wklibs_dir)
conf.env.append_value('LIBPATH', wklibs_dir)
@@ -340,12 +323,12 @@ def common_configure(conf):
sdk_version = min_version
if min_version == "10.4":
sdk_version += "u"
- conf.env.append_value('LIB_WEBCORE', ['WebKitSystemInterfaceTiger'])
+ conf.env.append_value('LIB_WKINTERFACE', ['WebKitSystemInterfaceTiger'])
else:
# NOTE: There is a WebKitSystemInterfaceSnowLeopard, but when we use that
# on 10.6, we get a strange missing symbol error, and this library seems to
# work fine for wx's purposes.
- conf.env.append_value('LIB_WEBCORE', ['WebKitSystemInterfaceLeopard'])
+ conf.env.append_value('LIB_WKINTERFACE', ['WebKitSystemInterfaceLeopard'])
sdkroot = '/Developer/SDKs/MacOSX%s.sdk' % sdk_version
sdkflags = ['-arch', 'i386', '-isysroot', sdkroot]
diff --git a/WebKitTools/wx/build/waf_extensions.py b/WebKitTools/wx/build/waf_extensions.py
index 6816441..f50f264 100644
--- a/WebKitTools/wx/build/waf_extensions.py
+++ b/WebKitTools/wx/build/waf_extensions.py
@@ -35,7 +35,12 @@ def exec_command(s, **kw):
if sys.platform.startswith('win') and len(' '.join(s)) > 32000:
import tempfile
(fd, filename) = tempfile.mkstemp()
- os.write(fd, ' '.join(s[1:]))
+ t = []
+ for i in s:
+ if i.find(" ") != -1:
+ i = '"%s"' % i
+ t.append(i)
+ os.write(fd, ' '.join(t[1:]))
os.close(fd)
s = [s[0], '@' + filename]