summaryrefslogtreecommitdiffstats
path: root/WebKitTools
diff options
context:
space:
mode:
Diffstat (limited to 'WebKitTools')
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json8
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg47
-rw-r--r--WebKitTools/ChangeLog1238
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj4
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp186
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h4
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp10
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h2
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/TestObject.cpp50
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp64
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/DrawsGradient.cpp118
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp49
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowRegionIsSetToClipRect.cpp114
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp54
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj39
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.cpp71
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.h50
-rw-r--r--WebKitTools/DumpRenderTree/chromium/EventSender.cpp1
-rw-r--r--WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp5
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShell.h2
-rw-r--r--WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp13
-rw-r--r--WebKitTools/DumpRenderTree/chromium/WebViewHost.h1
-rw-r--r--WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp7
-rw-r--r--WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp4
-rw-r--r--WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf27
-rw-r--r--WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm4
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp5
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h2
-rw-r--r--WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro1
-rw-r--r--WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp4
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp7
-rw-r--r--WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp4
-rw-r--r--WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp4
-rw-r--r--WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp44
-rw-r--r--WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h20
-rw-r--r--WebKitTools/GNUmakefile.am1
-rw-r--r--WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m2
-rw-r--r--WebKitTools/QtTestBrowser/QtTestBrowser.pro1
-rw-r--r--WebKitTools/QtTestBrowser/launcherwindow.cpp4
-rw-r--r--WebKitTools/QtTestBrowser/useragentlist.txt1
-rw-r--r--WebKitTools/QtTestBrowser/webinspector.h2
-rw-r--r--WebKitTools/QtTestBrowser/webview.cpp17
-rw-r--r--WebKitTools/QtTestBrowser/webview.h1
-rw-r--r--WebKitTools/QueueStatusServer/__init__.py29
-rw-r--r--WebKitTools/QueueStatusServer/handlers/queuestatus.py25
-rw-r--r--WebKitTools/QueueStatusServer/handlers/queuestatus_unittest.py62
-rw-r--r--WebKitTools/QueueStatusServer/model/workitems.py2
-rw-r--r--WebKitTools/QueueStatusServer/model/workitems_unittest.py8
-rw-r--r--WebKitTools/QueueStatusServer/templates/includes/singlequeuestatus.html6
-rwxr-xr-xWebKitTools/Scripts/check-webkit-style5
-rwxr-xr-xWebKitTools/Scripts/old-run-webkit-tests9
-rw-r--r--WebKitTools/Scripts/webkitpy/common/checkout/scm.py2
-rw-r--r--WebKitTools/Scripts/webkitpy/common/config/committers.py4
-rw-r--r--WebKitTools/Scripts/webkitpy/common/net/bugzilla.py4
-rw-r--r--WebKitTools/Scripts/webkitpy/common/system/executive.py109
-rw-r--r--WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py77
-rw-r--r--WebKitTools/Scripts/webkitpy/common/system/filesystem.py117
-rw-r--r--WebKitTools/Scripts/webkitpy/common/system/filesystem_unittest.py157
-rw-r--r--WebKitTools/Scripts/webkitpy/common/system/fileutils.py33
-rw-r--r--WebKitTools/Scripts/webkitpy/common/system/path.py8
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py39
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/base.py21
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py11
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py6
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/config.py154
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py176
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py47
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py9
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py31
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py9
-rwxr-xr-xWebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py57
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py146
-rw-r--r--WebKitTools/Scripts/webkitpy/style/checker.py8
-rw-r--r--WebKitTools/Scripts/webkitpy/style/optparser.py15
-rw-r--r--WebKitTools/Scripts/webkitpy/style/optparser_unittest.py8
-rw-r--r--WebKitTools/Scripts/webkitpy/style_references.py6
-rw-r--r--WebKitTools/Scripts/webkitpy/test/cat.py42
-rw-r--r--WebKitTools/Scripts/webkitpy/test/cat_unittest.py52
-rw-r--r--WebKitTools/Scripts/webkitpy/test/echo.py52
-rw-r--r--WebKitTools/Scripts/webkitpy/test/echo_unittest.py64
-rw-r--r--WebKitTools/Scripts/webkitpy/test/skip.py52
-rw-r--r--WebKitTools/Scripts/webkitpy/test/skip_unittest.py77
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/__init__.py1
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html40
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css56
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js36
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py157
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/upload.py26
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/mocktool.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/steps/checkstyle.py3
-rw-r--r--WebKitTools/TestWebKitAPI/InjectedBundleController.cpp18
-rw-r--r--WebKitTools/TestWebKitAPI/InjectedBundleController.h2
-rw-r--r--WebKitTools/TestWebKitAPI/InjectedBundleMain.cpp4
-rw-r--r--WebKitTools/TestWebKitAPI/PlatformUtilities.cpp9
-rw-r--r--WebKitTools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp5
-rw-r--r--WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj7
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl2
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp2
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp12
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h4
-rw-r--r--WebKitTools/WebKitTestRunner/TestController.cpp37
-rw-r--r--WebKitTools/WebKitTestRunner/TestController.h13
-rw-r--r--WebKitTools/WebKitTestRunner/TestInvocation.cpp12
-rw-r--r--WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm7
-rw-r--r--WebKitTools/WebKitTestRunner/qt/TestControllerQt.cpp5
-rw-r--r--WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp22
-rw-r--r--WebKitTools/iExploder/htdocs/cssproperties.in2
107 files changed, 4076 insertions, 440 deletions
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json
index 71c20f0..f39e10c 100644
--- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json
@@ -91,7 +91,7 @@
{
"name": "Windows Release (Build)", "type": "Build", "builddir": "win-release",
"platform": "win", "configuration": "release", "architectures": ["i386"],
- "triggers": ["win-release-tests"],
+ "triggers": ["win-release-tests", "win-release-tests-wk2"],
"slavenames": ["apple-windows-2", "test-slave"]
},
{
@@ -102,7 +102,7 @@
{
"name": "Windows Debug (Build)", "type": "Build", "builddir": "win-debug",
"platform": "win", "configuration": "debug", "architectures": ["i386"],
- "triggers": ["win-debug-tests", "win-debug-tests-wk2"],
+ "triggers": ["win-debug-tests"],
"slavenames": ["apple-windows-1", "test-slave"]
},
{
@@ -240,8 +240,8 @@
{ "type": "Triggerable", "name": "win-debug-tests",
"builderNames": ["Windows Debug (Tests)"]
},
- { "type": "Triggerable", "name": "win-debug-tests-wk2",
- "builderNames": ["Windows Debug (WebKit2 Tests)"]
+ { "type": "Triggerable", "name": "win-release-tests-wk2",
+ "builderNames": ["Windows Release (WebKit2 Tests)"]
}
]
}
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
index 5c44525..97641bf 100644
--- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
@@ -305,6 +305,51 @@ class RunGtkAPITests(shell.Test):
return [self.name]
+class RunQtAPITests(shell.Test):
+ name = "API tests"
+ description = ["API tests running"]
+ descriptionDone = ["API tests"]
+ command = ["python", "./WebKitTools/Scripts/run-qtwebkit-tests",
+ "--output-file=qt-unit-tests.html", "--do-not-open-results",
+ WithProperties("WebKitBuild/%(configuration_pretty)s/WebKit/qt/tests/")]
+
+ def start(self):
+ self.setProperty("configuration_pretty", self.getProperty("configuration").title())
+ return shell.Test.start(self)
+
+ def commandComplete(self, cmd):
+ shell.Test.commandComplete(self, cmd)
+
+ logText = cmd.logs['stdio'].getText()
+ foundItems = re.findall("TOTALS: (?P<passed>\d+) passed, (?P<failed>\d+) failed, (?P<skipped>\d+) skipped", logText)
+
+ self.incorrectTests = 0
+ self.statusLine = []
+
+ if foundItems:
+ self.incorrectTests = int(foundItems[0][1])
+ if self.incorrectTests > 0:
+ self.statusLine = [
+ "%s passed, %s failed, %s skipped" % (foundItems[0][0], foundItems[0][1], foundItems[0][2])
+ ]
+
+ def evaluateCommand(self, cmd):
+ if self.incorrectTests:
+ return WARNINGS
+
+ if cmd.rc != 0:
+ return FAILURE
+
+ return SUCCESS
+
+ def getText(self, cmd, results):
+ return self.getText2(cmd, results)
+
+ def getText2(self, cmd, results):
+ if results != SUCCESS and self.incorrectTests:
+ return self.statusLine
+
+ return [self.name]
class RunWebKitLeakTests(RunWebKitTests):
def start(self):
@@ -421,6 +466,8 @@ class BuildAndTestFactory(Factory):
self.addStep(ExtractTestResults)
if platform == "gtk":
self.addStep(RunGtkAPITests)
+ if platform == "qt":
+ self.addStep(RunQtAPITests)
class BuildAndTestLeaksFactory(BuildAndTestFactory):
TestClass = RunWebKitLeakTests
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 1c7d1bf..a5e6893 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,1241 @@
+2010-11-05 Adam Roben <aroben@apple.com>
+
+ Make webkitpy.common.system.executive_unittest pass when running under
+ Win32 Python
+
+ Fixes <http://webkit.org/b/49033>.
+
+ Reviewed by Dave Levin and Eric Seidel.
+
+ * Scripts/webkitpy/common/system/executive.py:
+ (Executive._run_command_with_teed_output): Pass the arguments through
+ encode_argument_if_needed rather than using Cygwin-specific code here.
+ (Executive.run_and_throw_if_fail): Use child_process_encoding to decode
+ the output.
+ (Executive.run_command): Use encode_argument_if_needed to encode the
+ arguments and child_process_encoding to decode the output.
+ (Executive._child_process_encoding): Returns the encoding that should be
+ used when communicating with child processes. On Windows we use mbcs,
+ which maps to the current code page. On all other platforms we use
+ UTF-8.
+ (Executive._should_encode_child_process_arguments): Returns True if
+ arguments to child processes need to be encoded. This is currently
+ only needed on Cygwin and Win32 Python 2.x.
+ (Executive._encode_argument_if_needed): Encode the argument using
+ child_process_encoding if we need to encode arguments to child
+ processes on this platform.
+
+ * Scripts/webkitpy/common/system/executive_unittest.py:
+ (never_ending_command): Added. Returns arguments to run a command that
+ will not quit until we kill it. On Windows we use wmic, on other
+ platforms we use yes.
+ (ExecutiveTest.test_run_command_with_unicode): Changed to expect the
+ mbcs encoding to be used and for output from the child processes to
+ have been roundtripped through encode/decode on Win32 Python. When
+ UTF-8 is the encoding the roundtripping is undetectable, but with mbcs
+ it's possible that some characters will not be able to be converted
+ and will be replaced by question marks; the round-tripping allows us
+ to expect this result.
+
+ (ExecutiveTest.test_kill_process):
+ (ExecutiveTest.test_kill_all):
+ Use never_ending_command instead of invoking "yes" directly. Expect an
+ exit code of 1 when using Win32 Python, as that's what seems to happen.
+
+2010-11-08 Adam Roben <aroben@apple.com>
+
+ Roll out r71532
+
+ It broke the build for Cygwin 1.7 installs. Cygwin 1.7's default
+ .bashrc unsets %TEMP%, which broke copy-tools.cmd.
+
+ * Scripts/webkitdirs.pm:
+
+2010-11-08 Tony Chang <tony@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ run platform/chromium/plugins/nested-plugin-objects.html on all platforms
+ https://bugs.webkit.org/show_bug.cgi?id=49094
+
+ This tests that objects created by plugins are proplery cleaned up.
+
+ * DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp:
+ (testPassTestObject):
+ (pluginInvoke):
+ * DumpRenderTree/TestNetscapePlugIn/TestObject.cpp:
+ (testAllocate):
+ (testDeallocate):
+ (testGetProperty):
+ (testConstruct):
+
+2010-11-08 Adam Roben <aroben@apple.com>
+
+ Mark Windows builds triggered from Perl as being non-interactive
+
+ This affects whether some of our scripts will show alerts vs. printing
+ to the build log.
+
+ Fixes <http://webkit.org/b/49181> Windows build fail mysteriously when
+ .vsprops files are updated
+
+ Reviewed by Steve Falkenburg.
+
+ * Scripts/webkitdirs.pm:
+ (buildVisualStudioProject): Set WEBKIT_NONINTERACTIVE_BUILD to 1.
+
+2010-11-08 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>
+
+ Reviewed by Ojan Vafai.
+
+ Make http locking default in NRWT.
+ https://bugs.webkit.org/show_bug.cgi?id=48053
+
+ * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+
+2010-11-08 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>
+
+ Reviewed by Csaba Osztrogonác.
+
+ [NRWT] If the http lock fails we shouldn't do any locking
+ https://bugs.webkit.org/show_bug.cgi?id=49164
+
+ If something goes wrong with the locking, the test should keep going.
+
+ * Scripts/webkitpy/layout_tests/port/http_lock.py:
+
+2010-11-08 Adam Roben <aroben@apple.com>
+
+ Switch back to using kCGImageAlphaPremultipliedFirst when generating
+ pixel dumps on Windows
+
+ I changed this behavior in r71418 thinking that it was required for
+ getting plugins to show up in pixel dumps. But it doesn't seem to be
+ necessary, and was making it impossible to compare new Windows pixel
+ dumps with existing Windows or Mac pixel dumps (because ImageDiff won't
+ compare an image with alpha to an image without alpha).
+
+ Fixes <http://webkit.org/b/49172> REGRESION (r71418): Can't compare
+ new Windows pixel results to existing Windows or Mac results
+
+ Reviewed by Antti Koivisto.
+
+ * DumpRenderTree/win/PixelDumpSupportWin.cpp:
+ (createBitmapContextFromWebView): Replaced kCGImageAlphaNoneSkipFirst
+ with kCGImageAlphaPremultipliedFirst.
+
+2010-11-08 Csaba Osztrogonac <ossy@webkit.org>
+
+ Unreviewed, rolling out r71466.
+ http://trac.webkit.org/changeset/71466
+ https://bugs.webkit.org/show_bug.cgi?id=48865
+
+ It broke layout tests on GTK bots.
+
+ * DumpRenderTree/gtk/DumpRenderTree.cpp:
+ (createWebView):
+
+2010-11-08 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>
+
+ Reviewed by Csaba Osztrogonác.
+
+ Enable running of Qt API tests on BuildBot
+ https://bugs.webkit.org/show_bug.cgi?id=49004
+
+ * BuildSlaveSupport/build.webkit.org-config/master.cfg:
+
+2010-11-08 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Add clean-review-queue command to remove closed bugs from the webkit.org/pending-review
+ https://bugs.webkit.org/show_bug.cgi?id=49160
+
+ Bugzilla doesn't automatically remove r? when a bug gets closed.
+ This script takes care of that for webkit.org.
+
+ * Scripts/webkitpy/common/net/bugzilla.py:
+ * Scripts/webkitpy/tool/commands/upload.py:
+
+2010-11-07 Fumitoshi Ukai <ukai@chromium.org>
+
+ Unreviewed, rolling out r71474.
+ http://trac.webkit.org/changeset/71474
+ https://bugs.webkit.org/show_bug.cgi?id=48280
+
+ breaks chromium webkit tests
+ https://bugs.webkit.org/show_bug.cgi?id=49151
+
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ * Scripts/webkitpy/layout_tests/port/base_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/config.py:
+ * Scripts/webkitpy/layout_tests/port/config_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py:
+ * Scripts/webkitpy/tool/mocktool.py:
+
+2010-11-07 Fumitoshi Ukai <ukai@chromium.org>
+
+ Unreviewed, rolling out r71475.
+ http://trac.webkit.org/changeset/71475
+
+ breaks chromium webkit tests
+ https://bugs.webkit.org/show_bug.cgi?id=49151
+
+ * Scripts/webkitpy/common/newstringio.py: Removed.
+ * Scripts/webkitpy/common/newstringio_unittest.py: Removed.
+ * Scripts/webkitpy/common/system/executive_mock.py: Removed.
+ * Scripts/webkitpy/common/system/filesystem_mock.py: Removed.
+ * Scripts/webkitpy/layout_tests/port/config_mock.py: Removed.
+
+2010-11-06 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, build fix.
+
+ Add files inexplicably not committed in r71474 as part of the
+ fix for bug 48280.
+
+ * Scripts/webkitpy/common/newstringio.py: Added.
+ * Scripts/webkitpy/common/newstringio_unittest.py: Added.
+ * Scripts/webkitpy/common/system/executive_mock.py: Added.
+ * Scripts/webkitpy/common/system/filesystem_mock.py: Added.
+ * Scripts/webkitpy/layout_tests/port/config_mock.py: Added.
+
+2010-11-06 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Eric Siedel.
+
+ new-run-webkit-tests: update port/base and port/webkit to use the
+ new FileSystem and Config abstractions, pulling more logic out of
+ the base Port classes into separate, mockable objects.
+
+ Also create a MockFileSystem object, a MockConfig object, move
+ MockExecutive into common/system to be next to executive, and
+ update the config object to use a FileSystem.
+
+ https://bugs.webkit.org/show_bug.cgi?id=48280
+
+ * Scripts/webkitpy/common/newstringio.py: Added.
+ * Scripts/webkitpy/common/newstringio_unittest.py: Added.
+ * Scripts/webkitpy/common/system/executive_mock.py: Added.
+ * Scripts/webkitpy/common/system/filesystem_mock.py: Added.
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ * Scripts/webkitpy/layout_tests/port/base_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/config.py:
+ * Scripts/webkitpy/layout_tests/port/config_mock.py:
+ * Scripts/webkitpy/layout_tests/port/config_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py:
+ * Scripts/webkitpy/tool/mocktool.py:
+
+2010-11-06 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, build breakage.
+
+ Apparently I uploaded the wrong version of the file to fix 49122
+ and neither Eric or I noticed - it was missing a dirname() call.
+ Fixing ...
+
+ https://bugs.webkit.org/show_bug.cgi?id=49122
+
+ * Scripts/webkitpy/common/checkout/scm.py:
+
+2010-11-06 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ webkitpy/tool/* unittests change cwd and don't clean up properly
+
+ https://bugs.webkit.org/show_bug.cgi?id=49122
+
+ * Scripts/webkitpy/common/checkout/scm.py:
+
+2010-11-05 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ suspendAnimations/resumeAnimations not present in WebKit2
+ https://bugs.webkit.org/show_bug.cgi?id=49109
+
+ * WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl:
+ * WebKitTestRunner/InjectedBundle/LayoutTestController.cpp:
+ (WTR::LayoutTestController::suspendAnimations):
+ (WTR::LayoutTestController::resumeAnimations):
+ * WebKitTestRunner/InjectedBundle/LayoutTestController.h:
+
+2010-11-05 Tony Chang <tony@chromium.org>
+
+ Reviewed by David Levin.
+
+ cleanup style in TestNetscapePlugIn/PluginObject.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=49044
+
+ * DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp:
+ (getPluginClass):
+ (pluginGetProperty):
+ (pluginSetProperty):
+ (variantToIdentifier):
+ (testCallback):
+ (getURL):
+ (getURLNotify):
+ (testInvokeDefault):
+ (testGetProperty):
+ (testDocumentOpen):
+ (testWindowOpen):
+ (pluginInvoke):
+ (handleCallback):
+ (notifyStream):
+ * DumpRenderTree/TestNetscapePlugIn/PluginObject.h:
+
+2010-11-05 Eric Seidel <eric@webkit.org>
+
+ Reviewed by David Levin.
+
+ Add QueueStatusServer/__init__.py so others can run the QueueStatusServer tests
+ https://bugs.webkit.org/show_bug.cgi?id=49032
+
+ I wrote this file as part of bug 47847, but I forgot to commit it.
+ No one else noticed it missing because test-webkitpy knows how
+ to recover in the case where it can't import QueueStatusServer
+ (which generally occurs due to not having installed the AppEngine SDK).
+
+ * QueueStatusServer/__init__.py: Added.
+ * QueueStatusServer/model/workitems_unittest.py:
+ - Remove a test which fails. This was probably landed (by me)
+ from my other machine, which since this __init__.py was missing
+ I never noticed the failure and landed this invalid test.
+ Sadly we can't really test remove_work_item as it depends
+ on .key() working. .key() will throw unless the object
+ has already been saved it seems.
+ This may be a mis-design in our remove_work_item implementation,
+ but for now, just removing the test.
+
+2010-11-04 Adam Roben <aroben@apple.com>
+
+ Teach check-webkit-style about TestNetscapePlugIn
+
+ Fixes <http://webkit.org/b/49030> check-webkit-style is ignorant of
+ TestNetscapePlugIn's coding conventions
+
+ Reviewed by John Sullivan.
+
+ * Scripts/webkitpy/style/checker.py: Lump TestNetscapePlugIn in with
+ WebKitAPITest and TestWebKitAPI in having different include order and
+ naming conventions than WebCore. Added some comments about why the
+ exceptions exist.
+
+2010-11-04 Adam Roben <aroben@apple.com>
+
+ Add a test that shows that windowed plugins are able to paint
+
+ Somehow we never had a test for this before.
+
+ Fixes <http://webkit.org/b/49029> Should add a test that shows
+ windowed plugins can paint
+
+ Reviewed by Jon Honeycutt.
+
+ * DumpRenderTree/TestNetscapePlugIn/Tests/win/DrawsGradient.cpp: Added.
+ (DrawsGradient::DrawsGradient):
+ (DrawsGradient::wndProc): We handle the WM_PAINT and WM_PRINTCLIENT messages.
+
+ (DrawsGradient::onPaint):
+ (DrawsGradient::onPrintClient):
+ These both just call through to paint.
+
+ (DrawsGradient::paint): Fills our client area with some gradients.
+
+ * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj: Link
+ against Msimg32.lib for ::GradientFill and added DrawsGradient.
+
+ * DumpRenderTree/win/PixelDumpSupportWin.cpp:
+ (createBitmapContextFromWebView): Use WM_PRINT instead of
+ WM_PRINTCLIENT so that ::DefWindowProc will send
+ WM_PRINT/WM_PRINTCLIENT messages to the WebView's child windows.
+ Replaced kCGImageAlphaPremultipledFirst with kCGImageAlphaNoneSkipFirst
+ because GDI doesn't support alpha and kCGImageBitmapOrder32Little with
+ kCGImageBitmapOrder32Host because, who knows, maybe someday Windows
+ will run on a big-endian platform.
+
+2010-11-04 Adam Roben <aroben@apple.com>
+
+ Extract much of NPNInvalidateRectInvalidatesWindow's code into a
+ WindowedPluginTest base class
+
+ The base class takes care of subclassing the plugin's window so that a
+ custom WNDPROC is called. This will make it easier to write tests that
+ need to handle window messages.
+
+ Fixes <http://webkit.org/b/49028> It's hard to write a PluginTest with
+ a custom WNDPROC
+
+ Reviewed by Jon Honeycutt.
+
+ * DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp:
+ (NPNInvalidateRectInvalidatesWindow::NPNInvalidateRectInvalidatesWindow):
+ (NPNInvalidateRectInvalidatesWindow::NPP_SetWindow):
+ (NPNInvalidateRectInvalidatesWindow::wndProc):
+ (NPNInvalidateRectInvalidatesWindow::testInvalidateRect):
+ Moved code from here to WindowedPluginTest. Changed to use window()
+ instead of m_window.
+
+ * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj:
+ Added WindowedPluginTest and added TestNetscapePlugIn/win to the
+ include path. Also reordered the include path to make a little more
+ sense and simplified the entry that added TestNetscapePlugIn itself to
+ the include path.
+
+ * DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.cpp: Added.
+ (WindowedPluginTest::WindowedPluginTest):
+ (WindowedPluginTest::NPP_SetWindow):
+ (WindowedPluginTest::staticWndProc):
+ * DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.h: Added.
+ (WindowedPluginTest::window):
+ Code came from NPNInvalidateRectInvalidatesWindow.
+
+2010-11-04 Adam Roben <aroben@apple.com>
+
+ Add a plugin test to show that windowed plugins are clipped correctly
+
+ Fixes <http://webkit.org/b/49024> <rdar://problem/8487847> Windowed
+ plugins aren't clipped in WebKit2 on Windows
+
+ Reviewed by Jon Honeycutt.
+
+ * DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowRegionIsSetToClipRect.cpp: Added.
+ (WindowRegionIsSetToClipRect::WindowRegionIsSetToClipRect): Initialize members.
+ (WindowRegionIsSetToClipRect::NPP_SetWindow): Check that our window
+ region matches the clip rect we know we should have based on
+ window-region-is-set-to-clip-rect.html, and check that our window class
+ doesn't have the CS_PARENTDC style.
+
+ * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj:
+ Added WindowRegionIsSetToClipRect.
+
+2010-11-05 Alejandro G. Castro <alex@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ [GTK] Avoid font hinting in the DRT
+ https://bugs.webkit.org/show_bug.cgi?id=48548
+
+ Change the settings to avoid font hinting, it was causing
+ different results depending on the distribution.
+
+ * DumpRenderTree/gtk/DumpRenderTree.cpp:
+ (initializeGtkFontSettings):
+ * DumpRenderTree/gtk/fonts/fonts.conf:
+
+2010-11-05 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ build-webkit spams system.log by repeatedly checking for PBXProductDirectory in com.apple.Xcode
+ https://bugs.webkit.org/show_bug.cgi?id=49051
+
+ This is a speculative fix. The unit tests cover these methods, however
+ I don't know if this will fully stop the system.log spam.
+
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+
+2010-11-05 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Add basic support for showing bot id on /queue-status/ pages
+ https://bugs.webkit.org/show_bug.cgi?id=49037
+
+ This support is really simple. Eventually we'll want to
+ show the bot id in the lock table too, but we don't have
+ that information stored in the server yet.
+
+ * QueueStatusServer/handlers/queuestatus.py:
+ * QueueStatusServer/handlers/queuestatus_unittest.py: Added.
+ * QueueStatusServer/templates/includes/singlequeuestatus.html:
+
+2010-11-04 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Create a filesystem wrapper that we can use to enforce
+ particular conventions and use for mocking and dependency
+ injection down the line.
+
+ https://bugs.webkit.org/show_bug.cgi?id=48144
+
+ * Scripts/webkitpy/common/system/filesystem.py: Added.
+ * Scripts/webkitpy/common/system/filesystem_unittest.py: Added.
+
+2010-11-04 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ run_webkit_tests_unittest fails under Python 2.5
+ https://bugs.webkit.org/show_bug.cgi?id=49043
+
+ Switch from itertools.chain.from_iterable (which was added in 2.6)
+ to using itertools.chain directly.
+
+ * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py:
+
+2010-11-04 Mihai Parparita <mihaip@chromium.org>
+
+ Unreviewed fix to webkit-patch rebaseline-server so that it runs under
+ Python 2.5 (it needs an import to use the with statement).
+
+ * Scripts/webkitpy/tool/commands/rebaselineserver.py:
+
+2010-11-04 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ new-run-webkit-tests: split out webkit-specific configuration stuff into a new module
+
+ The current NRWT code has webkit-specific configuration code (like
+ _script_path, default configuration, etc.) mixed in with
+ layout-test-specific stuff in port/base. The configuration code
+ should be split out into a separate module for easier mocking,
+ testing, and isolation.
+
+ https://bugs.webkit.org/show_bug.cgi?id=48264
+
+ * Scripts/webkitpy/layout_tests/port/config.py: Added.
+ * Scripts/webkitpy/layout_tests/port/config_unittest.py: Added.
+
+2010-11-04 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ Rebaseline server: initial framework
+ https://bugs.webkit.org/show_bug.cgi?id=48892
+
+ Adds the basic framework for the rebaseline server (details at
+ http://webkit.org/b/47761). Includes the rebaseline-server webkit-patch
+ command, which starts an HTTP server that can serve static files or
+ invoke handler methods on a class.
+
+ * Scripts/webkitpy/tool/commands/__init__.py:
+ * Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html: Added.
+ * Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css: Added.
+ * Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js: Added.
+ * Scripts/webkitpy/tool/commands/rebaselineserver.py: Added.
+
+2010-11-04 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by James Robinson.
+
+ new-run-webkit-tests wasn't using DRT by default for
+ --platform chromium-gpu
+
+ The default value was set to False instead of None, which meant
+ that the platform specific logic wasn't firing to change the
+ value to True (b/c we were afraid we'd be overriding the user
+ preference).
+
+ https://bugs.webkit.org/show_bug.cgi?id=49038
+
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+
+2010-11-04 Tony Chang <tony@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ make platform/chromium/plugins/multiple-plugins.html pass on all platforms
+ https://bugs.webkit.org/show_bug.cgi?id=49026
+
+ Have the testObject.bar property return the string "bar". This lets
+ us run and pass platform/chromium/plugins/multiple-plugins.html on all
+ platforms.
+
+ * DumpRenderTree/TestNetscapePlugIn/TestObject.cpp:
+ (testGetProperty):
+
+2010-11-04 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ NRWT doesn't have good test coverage for --run-chunk, --batch-size, --run-part, etc.
+ https://bugs.webkit.org/show_bug.cgi?id=48878
+
+ Add get_tests_run so that it's easy to see which tests get run (and with
+ what batching) for a given flag combination. Flesh out the various
+ test cases that have FIXMEs.
+
+ Also fixes an off-by-one error (batch sizes were one larger than
+ expected) and makes --run-part also have wraparound behavior, like
+ --run-chunk.
+
+ * 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-11-04 Erik Arvidsson <arv@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Support box-sizing without the vendor prefix
+ https://bugs.webkit.org/show_bug.cgi?id=36713
+
+ Based on patch by Peter Beverloo <peter@lvp-media.com>
+
+ * iExploder/htdocs/cssproperties.in: Change -webkit-box-sizing to box-sizing.
+
+2010-11-04 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviewed rollout r71340, because it broke Chromium Windows bot.
+
+ * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+
+2010-11-04 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>
+
+ Reviewed by Ojan Vafai.
+
+ Make http locking default in NRWT.
+ https://bugs.webkit.org/show_bug.cgi?id=48053
+
+ * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+
+2010-11-04 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>
+
+ Reviewed by Eric Seidel.
+
+ [NRWT] Clear invalid http locks on Windows platform as well
+ https://bugs.webkit.org/show_bug.cgi?id=48515
+
+ * Scripts/webkitpy/common/system/executive.py:
+ * Scripts/webkitpy/common/system/executive_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/http_lock.py:
+
+2010-11-02 Adam Roben <aroben@apple.com>
+
+ Reduce our dependence on coreutils when running Python tests
+
+ This patch introduces versions of the standard echo and cat utilities
+ implemented in Python. They are probably missing features of their
+ coreutils equivalents, but they can do what's necessary for our Python
+ tests. This is useful on Windows, where these utilities typically
+ aren't available.
+
+ Fixes <http://webkit.org/b/48883> executive_unittest relies on echo
+ and cat utilities from coreutils, which are not present on Windows
+
+ Reviewed by Eric Seidel.
+
+ * Scripts/webkitpy/common/system/executive_unittest.py: Changed to use
+ our Python-based echo and cat.
+
+ * Scripts/webkitpy/common/system/fileutils.py: Added.
+ (make_stdout_binary): On Windows, puts sys.stdout into binary mode so
+ that \n won't be translated into \r\n. I couldn't think of a good way
+ to test this directly without touching the filesystem, but it is tested
+ indirectly by echo_unittest.
+
+ * Scripts/webkitpy/test/cat.py: Added.
+ (command_arguments): Returns a list for invoking cat with the given arguments.
+ (main): Acts like a simplified version of the coreutils cat utility.
+
+ * Scripts/webkitpy/test/cat_unittest.py: Added.
+ (CatTest.assert_cat): Runs cat with the given input and ensures the
+ output matches the input.
+ (CatTest.test_basic): Performs a simple test of cat.
+ (CatTest.test_no_newline): Tests what happens when the input string
+ doesn't have a trailing newline.
+ (CatTest.test_unicode): Tests passing a unicode string to cat.
+ (CatTest.test_as_command): Tests running cat as a separate command.
+
+ * Scripts/webkitpy/test/echo.py: Added.
+ (command_arguments): Returns a list for invoking echo with the given arguments.
+ (main): Acts like a simplified version of the coreutils echo utility.
+
+ * Scripts/webkitpy/test/echo_unittest.py: Added.
+ (EchoTest.test_basic): Performs a simple test of echo.
+ (EchoTest.test_no_newline): Tests passing -n to echo to suppress the
+ trailing newline.
+ (EchoTest.test_unicode): Tests passing unicode and non-unicode strings
+ to echo.
+ (EchoTest.test_argument_order): Tests what happens when -n is not the
+ first argument.
+ (EchoTest.test_empty_arguments): Tests what happens when you pass [] to
+ echo.main.
+ (EchoTest.test_no_arguments): Tests what happens when you call
+ echo.main with no arguments.
+ (EchoTest.test_as_command): Tests running echo as a separate command.
+
+2010-11-04 Renata Hodovan <reni@inf.u-szeged.hu>
+
+ Unreviewed: Add myself to the list of Committers.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-11-04 Andreas Kling <kling@webkit.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Hook into QWebPage::scrollRequested for resizes-to-contents mode
+
+ In RTC mode the QGraphicsWebView item is the size of the contents,
+ scrolling works a bit differently (we need to react to scrollRequested.)
+
+ Normally QGraphicsView will replay the last mouse event when scrolling,
+ so to prevent WebKit from getting confused by this we temporarily make
+ the QGraphicsView non-interactive.
+
+ * QtTestBrowser/webview.cpp:
+ (WebViewGraphicsBased::setPage):
+ (WebViewGraphicsBased::scrollRequested):
+ * QtTestBrowser/webview.h:
+
+2010-11-04 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ Use OS(MAC_OS_X) rather than PLATFORM(MAC) in TestControllerQt
+
+ PLATFORM(MAC) is not defined for the Qt port, as it refers to
+ the Mac-port, not the Mac OS X operating system.
+
+ * WebKitTestRunner/qt/TestControllerQt.cpp:
+ (WTR::isExistingLibrary):
+
+2010-11-04 Leonid Ebril <leonid.ebril@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] Adding iphone user agent string the user agent list for QtTestBrowser
+ https://bugs.webkit.org/show_bug.cgi?id=48869
+
+ * QtTestBrowser/useragentlist.txt:
+
+2010-11-03 Adam Roben <aroben@apple.com>
+
+ Always use uppercase drive names in strings returned by abspath_to_uri
+
+ Some versions of cygpath use lowercase drive letters while others use
+ uppercase, which makes it hard to test the output of code that uses
+ cygpath.
+
+ Fixes <http://webkit.org/b/48914> webkitpy.common.system.path_unittest
+ fails with Cygwin 1.5
+
+ Reviewed by Eric Seidel.
+
+ * Scripts/webkitpy/common/system/path.py:
+ (cygpath): Updated the docstring to indicate that only absolute paths
+ should be passed for now (though relative paths will work fine).
+ (_Cygpath.convert): Upper-case the first letter of the converted Windows path.
+
+2010-11-03 George Guo <George.Guo@Nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] QtTestBrowser : set mmp rule pageddata in Symbian
+ https://bugs.webkit.org/show_bug.cgi?id=48767
+
+ Paging is needd on Symbian devices to support benchmarks tests like
+ dromaeo.com and Celtic Kane that need a lot of memory to run
+
+ * QtTestBrowser/QtTestBrowser.pro:
+
+2010-11-03 Jenn Braithwaite <jennb@chromium.org>
+
+ Reviewed by Dmitry Titov.
+
+ Chromium: Update resource tracking when moving a frame between documents
+ https://bugs.webkit.org/show_bug.cgi?id=48363
+
+ * DumpRenderTree/chromium/WebViewHost.cpp:
+ (WebViewHost::assignIdentifierToRequest):
+ Always put resource id in map so we can make assumptions about its
+ presence.
+ (WebViewHost::removeIdentifierForRequest):
+ Added.
+ (WebViewHost::didFinishResourceLoad):
+ (WebViewHost::didFailResourceLoad):
+ Check existence of resource id before removing from map.
+ * DumpRenderTree/chromium/WebViewHost.h:
+
+2010-11-03 Victor Wang <victorw@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ [Chromium] update buildbot names in chromium rebaseline tool.
+
+ https://bugs.webkit.org/show_bug.cgi?id=48881
+
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py:
+
+2010-11-03 Darin Adler <darin@apple.com>
+
+ Updated Xcode projects by opening them with Xcode 3.2.4.
+ Updated svn:ignore for Xcode projects.
+
+ * MiniBrowser/MiniBrowser.xcodeproj: Added property svn:ignore.
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj: Added property svn:ignore.
+ * WebKitLauncher/WebKitLauncher.xcodeproj: Modified property svn:ignore.
+ * WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj: Updated with Xcode 3.2.4.
+
+2010-11-03 Adam Roben <aroben@apple.com>
+
+ Stop waiting for messages from the web process after a timeout elapses
+
+ TestController::runUntil now takes a timeout parameter that specifies
+ how long to wait for the condition to become true. WebKitTestRunner
+ takes a --timeout flag that specifies how long the timeout should be.
+ run-webkit-tests passes this flag to WebKitTestRunner so its timeout
+ will be similar to run-webkit-tests.
+
+ Fixes <http://webkit.org/b/43047> <rdar://problem/8365833>
+ WebKitTestRunner waits forever if the web process crashes
+
+ Reviewed by Darin Adler and Anders Carlsson.
+
+ * Scripts/old-run-webkit-tests:
+ (top level): Moved the GuardMalloc timeout adjustment here from
+ readFromDumpToolWithTimer.
+ (openDumpTool): Make WTR use a timeout similar to but slightly shorter
+ than the one that was specified on the command line.
+
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::TestController): Initialize our timeout values.
+ (WTR::TestController::initialize): Parse the --timeout flag and use it
+ to modify our timeout values.
+ (WTR::TestController::resetStateToConsistentValues): Changed to use a
+ short timeout while waiting for the web process to reset and to return
+ a boolean indicating whether we were able to reset the web process.
+ Uses a 5-second timeout while waiting for the process to be reset.
+ (WTR::TestController::runTest): Changed to return a boolean indicating
+ whether we were able to reset the web process (and thus run the test).
+ (WTR::TestController::runUntil): Call through to platformRunUntil.
+
+ (WTR::TestController::runTestingServerLoop):
+ (WTR::TestController::run):
+ Changed to bail if any test can't be run. This will cause the process
+ to exit. (Unfortunately this will make run-webkit-tests think we
+ crashed; see <http://webkit.org/b/48943>.)
+
+ * WebKitTestRunner/TestController.h: Added platformRunUntil,
+ m_longTimeout, and m_shortTimeout.
+
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::invoke): Use a short timeout when waiting for the
+ initial response and a long timeout when waiting for the test to
+ complete. Check whether runUntil timed out and print an error message
+ if so.
+
+ * WebKitTestRunner/mac/TestControllerMac.mm:
+ (WTR::TestController::platformRunUntil): Renamed from runUntil. Pass
+ [NSDate distantPast] to -[NSRunLoop runMode:beforeDate:] so that we
+ won't block waiting for the run loop. Only loop until the timeout
+ elapses.
+
+ * WebKitTestRunner/qt/TestControllerQt.cpp:
+ (WTR::TestController::platformRunUntil): Renamed from runUntil. Added a
+ FIXME about honoring the timeout.
+
+ * WebKitTestRunner/win/TestControllerWin.cpp:
+ (WTR::TestController::platformRunUntil): Renamed from runUntil. Use
+ ::MsgWaitForMultipleObjectsEx to implement the timeout. Changed to use
+ ::PeekMessageW so that we don't block waiting for messages to become
+ available.
+
+2010-11-03 Adam Roben <aroben@apple.com>
+
+ Add a plugin test that evaluates JS after removing the plugin element
+ from the document
+
+ This test replaces platform/win/plugins/plugin-delayed-destroy.html.
+ That test was made to prevent a crash very similar to this one, but
+ unfortunately tested only the mechanism that prevented the crash and
+ not whether the crash itself was prevented. Since WebKit2 uses a
+ different mechanism to prevent the crash, the test was failing even
+ though WebKit2 was not vulnerable to the crash. This new test crashes
+ if there is no mechanism in place to prevent it and passes in both
+ WebKit1 and WebKit2.
+
+ Fixes <http://webkit.org/b/46711> <rdar://problem/8485903>
+ platform/win/plugins/plugin-delayed-destroy.html fails in WebKit2
+
+ Reviewed by Anders Carlsson.
+
+ * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+ * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj:
+ * DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro:
+ * GNUmakefile.am:
+ Added new file.
+
+ * DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp:
+ (pluginDeallocate): Make sure we delete the PluginTest object. This
+ prevents a leak and also allows us to test the crash.
+
+ * DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp:
+ (PluginTest::executeScript): Made this into a non-static member
+ function.
+
+ (PluginTest::waitUntilDone):
+ (PluginTest::notifyDone):
+ Updated for changes to executeScript.
+
+ * DumpRenderTree/TestNetscapePlugIn/PluginTest.h: Added executeScript.
+
+ * DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp: Added.
+ (EvaluateJSAfterRemovingPluginElement::EvaluateJSAfterRemovingPluginElement):
+ Initialize ourselves and tell the test harness to wait.
+ (EvaluateJSAfterRemovingPluginElement::NPP_DestroyStream): Remove our
+ plugin element from the document, then execute some JavaScript. If
+ WebKit does not have appropriate mechanisms in place, we'll be
+ destroyed inside the first call to executeScript and crash on the
+ second call.
+
+2010-11-02 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ [chromium] Fix LayoutTestController UMRs.
+ https://bugs.webkit.org/show_bug.cgi?id=48872
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::LayoutTestController):
+
+2010-11-03 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ REGRESSION: rebaseline-chromium-webkit-tests uses non-zero tolerance for
+ image dup detection
+ https://bugs.webkit.org/show_bug.cgi?id=48744
+
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py:
+ - Make a function for option parsing for ease of test
+ - Set 0 to options.tolerance
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py:
+ - Add a test for this change
+
+2010-11-02 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ Unreviewed: Add myself to the list of Committers.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-11-02 Anders Carlsson <andersca@apple.com>
+
+ Fix build.
+
+ * TestWebKitAPI/PlatformUtilities.cpp:
+ (TestWebKitAPI::Util::createContextForInjectedBundleTest):
+
+2010-11-02 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Anders Carlsson.
+
+ Add a way to send startup messages on the context which can be posted when a process launches
+ <rdar://problem/8617928>
+ https://bugs.webkit.org/show_bug.cgi?id=48838
+
+ * MiniBrowser/mac/WebBundle/WebBundleMain.m:
+ (WKBundleInitialize):
+ * TestWebKitAPI/InjectedBundleController.cpp:
+ (TestWebKitAPI::InjectedBundleController::initialize):
+ (TestWebKitAPI::InjectedBundleController::didReceiveMessage):
+ * TestWebKitAPI/InjectedBundleController.h:
+ * TestWebKitAPI/InjectedBundleMain.cpp:
+ (WKBundleInitialize):
+ * TestWebKitAPI/PlatformUtilities.cpp:
+ (TestWebKitAPI::Util::createContextForInjectedBundleTest):
+ * WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp:
+ (WKBundleInitialize):
+ Update implementations of WKBundleInitialize to take an initial userData
+ argument. Change TestWebKitAPI to use the new initial userData to initialize
+ each test's bundle.
+
+2010-11-02 Benjamin Kalman <kalman@google.com>
+
+ Reviewed by Ojan Vafai.
+
+ new-run-webkit-tests doesn't strip "LayoutTests/" from prefix, unlike old-run-webkit-tests
+ https://bugs.webkit.org/show_bug.cgi?id=48794
+
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py: Strip the "LayoutTests/" prefix from test argument paths.
+
+2010-11-02 Adam Roben <aroben@apple.com>
+
+ Skip webkitpy.layout_tests.run_webkit_tests_unittest.MainTest on Cygwin
+ Python 2.5.x
+
+ It is known to hang on that version of Python. See
+ <http://webkit.org/b/48614>.
+
+ Reviewed by Adam Barth.
+
+ * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py: Use
+ skip_if to skip MainTest on Cygwin Python 2.5.x.
+
+ * Scripts/webkitpy/test/skip.py: Added.
+ (skip_if): If the passed-in condition is false, find all the test_*
+ methods of the given class and replace them with a function that just
+ logs that we're skipping these tests. This is loosely based on the
+ unittest.skip_if decorator added in Python 3.1.
+ (_skipped_method): Returns a function that just logs that the tests are
+ being skipped. This is used in place of the actual test_* functions.
+
+ * Scripts/webkitpy/test/skip_unittest.py: Added.
+ (SkipTest.setUp): Create a logger for ourselves and give it a handler
+ that logs to a private stream.
+ (SkipTest.tearDown): Reset the logger.
+ (SkipTest.create_fixture_class): Returns a class that we use to test
+ skip_if. It has a single test_* method, test_foo, that just calls
+ through to a callback.
+ (SkipTest.foo_callback): Record that test_foo was called.
+ (SkipTest.test_skip_if_false): Pass skip_if a False condition and test
+ that test_foo does get called.
+ (SkipTest.test_skip_if_true): Pass skip_if a True condition and test
+ that test_foo does not get called and the appropriate message gets
+ logged.
+
+2010-11-02 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ webkit-patch should tell check-webkit-style which files were changed so
+ check-webkit-style doesn't have to stat the whole working copy again
+ https://bugs.webkit.org/show_bug.cgi?id=48792
+
+ * Scripts/webkitpy/tool/mocktool.py:
+ * Scripts/webkitpy/tool/steps/checkstyle.py:
+
+2010-11-02 Robert Kroeger <rjkroege@chromium.org>
+
+ Reviewed by James Robinson.
+
+ [Chromium/DRT] Make EventSendingController honour leapForward for touch events.
+ https://bugs.webkit.org/show_bug.cgi?id=48777
+
+ * DumpRenderTree/chromium/EventSender.cpp:
+ (EventSender::sendCurrentTouchEvent):
+
+2010-11-02 Adam Roben <aroben@apple.com>
+
+ Only track resource identifiers in DRT when dumpResourceLoadCallbacks
+ is on
+
+ This reverts Windows to our pre-r71097 behavior. That patch made us
+ track all resource identifiers, including the main resource, so the
+ main resource's URL started appearing in test output instead of
+ "<unknown>". Arguably having the main resource's URL is better, but all
+ other platforms print "<unknown>" and we want to match.
+
+ Fixes <http://webkit.org/b/48837> <rdar://problem/8620351> REGRESSION
+ (r71097): Many http tests failing on Windows
+
+ Reviewed by Anders Carlsson.
+
+ * DumpRenderTree/win/ResourceLoadDelegate.cpp:
+ (ResourceLoadDelegate::identifierForInitialRequest): Don't add the
+ identifier to the URL map if we're not supposed to dump resource load
+ callbacks.
+ (ResourceLoadDelegate::removeIdentifierForRequest): Always remove the
+ identifier from the URL map even if we're already "done". There's no
+ point in keeping out-of-date identifiers around.
+
+2010-11-01 Jenn Braithwaite <jennb@chromium.org>
+
+ Reviewed by Adam Roben.
+
+ Windows: Update resource tracking when moving a frame between documents
+ https://bugs.webkit.org/show_bug.cgi?id=48364
+
+ * DumpRenderTree/win/DumpRenderTree.cpp:
+ (createWebViewAndOffscreenWindow):
+ (main):
+ Give each WebView its own ResourceLoadDelegate instance in order to
+ make assertions about resource ids on a particular WebView.
+ * DumpRenderTree/win/ResourceLoadDelegate.cpp:
+ (ResourceLoadDelegate::identifierForInitialRequest):
+ Always add id to the map.
+ (ResourceLoadDelegate::removeIdentifierForRequest):
+ Added.
+ (ResourceLoadDelegate::willSendRequest):
+ (ResourceLoadDelegate::didReceiveAuthenticationChallenge):
+ (ResourceLoadDelegate::didReceiveResponse):
+ (ResourceLoadDelegate::didFinishLoadingFromDataSource):
+ (ResourceLoadDelegate::didFailLoadingWithError):
+ (ResourceLoadDelegate::descriptionSuitableForTestResult):
+ Replace static descriptionSuitableForTestResult with static member function to access identifier map.
+ * DumpRenderTree/win/ResourceLoadDelegate.h:
+ (ResourceLoadDelegate::urlMap):
+ Moved within class so that each WebView has its own id map.
+
+2010-11-01 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ remove debug code from run_webkit_tests.py
+ https://bugs.webkit.org/show_bug.cgi?id=48800
+
+ Remove temporary debug code and make --master-name required
+ if --test-results-server is set now that all clients set
+ --master-name.
+
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+
+2010-11-01 Tony Chang <tony@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ add plugin event logging for linux
+ https://bugs.webkit.org/show_bug.cgi?id=48779
+
+ This is taken from Chromium's fork of the layout test plugin:
+ http://git.chromium.org/gitweb/?p=chromium.git/.git;a=blob;f=webkit/tools/npapi_layout_test_plugin/main.cpp;h=3ebdada2f049b3624756438cff852364f86a2ede;hb=HEAD#l348
+
+ * DumpRenderTree/TestNetscapePlugIn/main.cpp:
+ (handleEventX11):
+ (NPP_HandleEvent):
+
+2010-11-01 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by James Robinson.
+
+ new-run-webkit-tests: use DRT, child-processes=1 for GPU tests by default
+ https://bugs.webkit.org/show_bug.cgi?id=48790
+
+ * Scripts/webkitpy/layout_tests/port/chromium_gpu.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py:
+
+2010-11-01 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Teach check-webkit-style how to accept a list of files to diff on the
+ command line
+ https://bugs.webkit.org/show_bug.cgi?id=48784
+
+ In a future patch, webkit-patch will use this option to improve
+ performance. I'm landing this in two pieces to avoid causing a version
+ skew problem for the style-bot.
+
+ * Scripts/check-webkit-style:
+ * Scripts/webkitpy/style/optparser.py:
+ * Scripts/webkitpy/style/optparser_unittest.py:
+ * Scripts/webkitpy/style_references.py:
+
+2010-11-01 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by John Sullivan.
+
+ Tear down the related WebProcessProxy when a WebContext is deallocated
+ https://bugs.webkit.org/show_bug.cgi?id=48769
+
+ * TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp:
+ (TestWebKitAPI::didFailProvisionalLoadWithErrorForFrame):
+ We don't support empty URLs anymore, update test to expect a null URL instead.
+
+2010-11-01 Søren Gjesse <sgjesse@chromium.org>
+
+ Reviewed by Andreas Kling.
+
+ Fix warning when compiling the chromium port of DumpRenderShell
+ with clang.
+ https://bugs.webkit.org/show_bug.cgi?id=48414
+
+ * DumpRenderTree/chromium/TestShell.h:
+ (TestShell::javaScriptFlagsForLoad):
+
+2010-11-01 Adam Roben <aroben@apple.com>
+
+ Fix typo from r71022
+
+ * BuildSlaveSupport/build.webkit.org-config/config.json:
+
+2010-11-01 Adam Roben <aroben@apple.com>
+
+ Trigger the Windows Release WebKit2 tests when a Release build
+ finishes, not when a Debug build finishes
+
+ Fixes <http://webkit.org/b/48754> Windows Release WebKit2 tests are
+ triggered at the wrong time
+
+ Reviewed by Sam Weinig.
+
+ * BuildSlaveSupport/build.webkit.org-config/config.json: Fixed
+ triggerable name and trigger.
+
+2010-11-01 Mario Sanchez Prada <msanchez@igalia.com>
+
+ Unreviewed. Adding my IRC nickname to the list of committers.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-10-31 Robert Hogan <robert@webkit.org>
+
+ Reviewed by Antonio Gomes.
+
+ [Qt] [Gtk] Plug-ins having upper case in mime type are failing to load
+
+ Qt and Gtk are case-sensitive when storing the declared mime-type
+ of plugins. Since plugin mime-types are lowercased prior to searching
+ for them in the plugin database, ensure they are loaded with the
+ mime-type in lower case too.
+
+ Change the test netscape plugin to declare its mimetype in sentence
+ case so that the correct behaviour is enforced.
+
+ https://bugs.webkit.org/show_bug.cgi?id=36815
+
+ * DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp:
+ (NP_GetMIMEDescription):
+
+2010-10-31 Robert Hogan <robert@webkit.org>
+
+ Reviewed by Antonio Gomes.
+
+ [Qt] Support nodesFromRect in DRT
+
+ https://bugs.webkit.org/show_bug.cgi?id=48716
+
+ * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+ (LayoutTestController::nodesFromRect):
+ * DumpRenderTree/qt/LayoutTestControllerQt.h:
+
+2010-10-30 Andreas Kling <kling@webkit.org>
+
+ Reviewed by Antonio Gomes.
+
+ [Qt] QtTestBrowser: Switching view type moves the embedded inspector
+ https://bugs.webkit.org/show_bug.cgi?id=48705
+
+ Reinsert the embedded inspector into the splitter after changing
+ between QWebView/QGraphicsWebView.
+
+ * QtTestBrowser/launcherwindow.cpp:
+ (LauncherWindow::init):
+ (LauncherWindow::initializeView):
+ * QtTestBrowser/webinspector.h:
+ (WebInspector::WebInspector):
+
+2010-10-28 Antonio Gomes <agomes@rim.com>
+
+ Reviewed by Ojan Vafai.
+
+ Needs a "LinuxEditingBehavior", perhaps with a better name
+ https://bugs.webkit.org/show_bug.cgi?id=36627
+
+ Adding support to Mac's, GTK+'s, Windows' and Chromium's LayoutTestController class to test the newly introduced Unix editing behavior.
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::setEditingBehavior):
+ * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+ (LayoutTestController::setEditingBehavior):
+ * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+ (LayoutTestController::setEditingBehavior):
+ * DumpRenderTree/win/LayoutTestControllerWin.cpp:
+ (LayoutTestController::setEditingBehavior):
+
2010-10-29 Andreas Kling <kling@webkit.org>
Reviewed by Kenneth Rohde Christiansen.
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
index bf0aebf..b2eb8e9 100644
--- a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
@@ -132,6 +132,7 @@
BCD08B710E1059D200A7D0C1 /* AccessibilityControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */; };
BCF6C6500C98E9C000AC063E /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF6C64F0C98E9C000AC063E /* GCController.cpp */; };
C06F9ABC1267A7060058E1F6 /* PassDifferentNPPStruct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C06F9ABB1267A7060058E1F6 /* PassDifferentNPPStruct.cpp */; };
+ C0E720751281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */; };
C0EC3C9C12787F0500939164 /* NullNPPGetValuePointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */; };
E1B7816511AF31B7007E1BC2 /* MockGeolocationProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */; };
E1B7816711AF31C3007E1BC2 /* MockGeolocationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = E1B7808511AF1643007E1BC2 /* MockGeolocationProvider.h */; };
@@ -307,6 +308,7 @@
BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityControllerMac.mm; path = mac/AccessibilityControllerMac.mm; sourceTree = "<group>"; };
BCF6C64F0C98E9C000AC063E /* GCController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GCController.cpp; sourceTree = "<group>"; };
C06F9ABB1267A7060058E1F6 /* PassDifferentNPPStruct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PassDifferentNPPStruct.cpp; sourceTree = "<group>"; };
+ C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EvaluateJSAfterRemovingPluginElement.cpp; sourceTree = "<group>"; };
C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullNPPGetValuePointer.cpp; sourceTree = "<group>"; };
E1B7808511AF1643007E1BC2 /* MockGeolocationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MockGeolocationProvider.h; path = mac/MockGeolocationProvider.h; sourceTree = "<group>"; };
E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MockGeolocationProvider.mm; path = mac/MockGeolocationProvider.mm; sourceTree = "<group>"; };
@@ -462,6 +464,7 @@
isa = PBXGroup;
children = (
1A215A7511F26072008AD0F5 /* DocumentOpenInDestroyStream.cpp */,
+ C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */,
1A24BAA8120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp */,
1AC77DCE120605B6005C19EF /* NPRuntimeRemoveProperty.cpp */,
C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */,
@@ -751,6 +754,7 @@
1A24BAA9120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp in Sources */,
C06F9ABC1267A7060058E1F6 /* PassDifferentNPPStruct.cpp in Sources */,
C0EC3C9C12787F0500939164 /* NullNPPGetValuePointer.cpp in Sources */,
+ C0E720751281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
index db73a9d..7f1c4b4 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
@@ -27,13 +27,13 @@
#include "PluginObject.h"
+#include "PluginTest.h"
#include "TestObject.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
-
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
// Helper function which takes in the plugin window object for logging to the console object.
static void pluginLogWithWindowObject(NPObject* windowObject, NPP instance, const char* message)
@@ -118,10 +118,10 @@ static NPClass pluginClass = {
pluginSetProperty,
0, // NPClass::removeProperty
0, // NPClass::enumerate
- 0 // NPClass::construct
+ 0, // NPClass::construct
};
-NPClass *getPluginClass(void)
+NPClass* getPluginClass(void)
{
return &pluginClass;
}
@@ -176,6 +176,7 @@ enum {
ID_TEST_GET_PROPERTY_RETURN_VALUE,
ID_TEST_IDENTIFIER_TO_STRING,
ID_TEST_IDENTIFIER_TO_INT,
+ ID_TEST_PASS_TEST_OBJECT,
ID_TEST_POSTURL_FILE,
ID_TEST_CONSTRUCT,
ID_TEST_THROW_EXCEPTION_METHOD,
@@ -212,6 +213,7 @@ static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
"testGetPropertyReturnValue",
"testIdentifierToString",
"testIdentifierToInt",
+ "testPassTestObject",
"testPostURLFile",
"testConstruct",
"testThrowException",
@@ -270,38 +272,48 @@ static bool pluginGetProperty(NPObject* obj, NPIdentifier name, NPVariant* resul
strcpy(buf, originalString);
STRINGZ_TO_NPVARIANT(buf, *result);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
BOOLEAN_TO_NPVARIANT(plugin->eventLogging, *result);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
BOOLEAN_TO_NPVARIANT(plugin->logDestroy, *result);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
- BOOLEAN_TO_NPVARIANT(plugin->stream != 0, *result);
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
+ BOOLEAN_TO_NPVARIANT(plugin->stream, *result);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
NPObject* testObject = plugin->testObject;
browser->retainobject(testObject);
OBJECT_TO_NPVARIANT(testObject, *result);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
BOOLEAN_TO_NPVARIANT(plugin->returnErrorFromNewStream, *result);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
BOOLEAN_TO_NPVARIANT(plugin->returnNegativeOneFromWrite, *result);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_PRIVATE_BROWSING_ENABLED]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_PRIVATE_BROWSING_ENABLED]) {
NPBool privateBrowsingEnabled = FALSE;
browser->getvalue(plugin->npp, NPNVprivateModeBool, &privateBrowsingEnabled);
BOOLEAN_TO_NPVARIANT(privateBrowsingEnabled, *result);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_CACHED_PRIVATE_BROWSING_ENABLED]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_CACHED_PRIVATE_BROWSING_ENABLED]) {
BOOLEAN_TO_NPVARIANT(plugin->cachedPrivateBrowsingMode, *result);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
browser->setexception(obj, "plugin object testThrowExceptionProperty SUCCESS");
return true;
- } else if (name == pluginPropertyIdentifiers[ID_LAST_SET_WINDOW_ARGUMENTS]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_LAST_SET_WINDOW_ARGUMENTS]) {
char* buf = static_cast<char*>(browser->memalloc(256));
snprintf(buf, 256, "x: %d, y: %d, width: %u, height: %u, clipRect: (%u, %u, %u, %u)", (int)plugin->lastWindow.x, (int)plugin->lastWindow.y, (unsigned)plugin->lastWindow.width, (unsigned)plugin->lastWindow.height,
plugin->lastWindow.clipRect.left, plugin->lastWindow.clipRect.top, plugin->lastWindow.clipRect.right - plugin->lastWindow.clipRect.left, plugin->lastWindow.clipRect.bottom - plugin->lastWindow.clipRect.top);
@@ -319,19 +331,24 @@ static bool pluginSetProperty(NPObject* obj, NPIdentifier name, const NPVariant*
if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
plugin->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
plugin->logDestroy = NPVARIANT_TO_BOOLEAN(*variant);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
plugin->returnErrorFromNewStream = NPVARIANT_TO_BOOLEAN(*variant);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
plugin->returnNegativeOneFromWrite = NPVARIANT_TO_BOOLEAN(*variant);
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
browser->setexception(obj, "plugin object testThrowExceptionProperty SUCCESS");
return true;
- } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_WINDOWED_PLUGIN]) {
+ }
+ if (name == pluginPropertyIdentifiers[ID_PROPERTY_WINDOWED_PLUGIN]) {
browser->setvalue(plugin->npp, NPPVpluginWindowBool, (void *)NPVARIANT_TO_BOOLEAN(*variant));
return true;
}
@@ -391,9 +408,9 @@ static NPIdentifier variantToIdentifier(NPVariant variant)
{
if (NPVARIANT_IS_STRING(variant))
return stringVariantToIdentifier(variant);
- else if (NPVARIANT_IS_INT32(variant))
+ if (NPVARIANT_IS_INT32(variant))
return int32VariantToIdentifier(variant);
- else if (NPVARIANT_IS_DOUBLE(variant))
+ if (NPVARIANT_IS_DOUBLE(variant))
return doubleVariantToIdentifier(variant);
return 0;
}
@@ -424,9 +441,29 @@ static bool testIdentifierToInt(PluginObject*, const NPVariant* args, uint32_t a
return true;
}
+static bool testPassTestObject(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (argCount != 2 || !NPVARIANT_IS_STRING(args[0]))
+ return false;
+
+ NPObject* windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
+ NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
+ free(callbackString);
+
+ NPVariant browserResult;
+ browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, &args[1], 1, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+}
+
static bool testCallback(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
- if (argCount == 0 || !NPVARIANT_IS_STRING(args[0]))
+ if (!argCount || !NPVARIANT_IS_STRING(args[0]))
return false;
NPObject* windowScriptObject;
@@ -457,7 +494,8 @@ static bool getURL(PluginObject* obj, const NPVariant* args, uint32_t argCount,
INT32_TO_NPVARIANT(npErr, *result);
return true;
- } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
+ }
+ if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
NPError npErr = browser->geturl(obj->npp, urlString, 0);
free(urlString);
@@ -476,7 +514,7 @@ static bool getURLNotify(PluginObject* obj, const NPVariant* args, uint32_t argC
return false;
NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
- NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : NULL);
+ NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : 0);
NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
@@ -495,7 +533,7 @@ static bool testInvokeDefault(PluginObject* obj, const NPVariant* args, uint32_t
if (!NPVARIANT_IS_OBJECT(args[0]))
return false;
- NPObject *callback = NPVARIANT_TO_OBJECT(args[0]);
+ NPObject* callback = NPVARIANT_TO_OBJECT(args[0]);
NPVariant invokeArgs[1];
NPVariant browserResult;
@@ -568,10 +606,10 @@ static bool testGetIntIdentifier(PluginObject*, const NPVariant* args, uint32_t
static bool testGetProperty(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
- if (argCount == 0)
+ if (!argCount)
return false;
- NPObject *object;
+ NPObject* object;
browser->getvalue(obj->npp, NPNVWindowNPObject, &object);
for (uint32_t i = 0; i < argCount; i++) {
@@ -730,7 +768,7 @@ bool testDocumentOpen(NPP npp)
NPIdentifier documentId = browser->getstringidentifier("document");
NPIdentifier openId = browser->getstringidentifier("open");
- NPObject *windowObject = NULL;
+ NPObject* windowObject = 0;
browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
if (!windowObject)
return false;
@@ -742,7 +780,7 @@ bool testDocumentOpen(NPP npp)
return false;
}
- NPObject *documentObject = NPVARIANT_TO_OBJECT(docVariant);
+ NPObject* documentObject = NPVARIANT_TO_OBJECT(docVariant);
NPVariant openArgs[2];
STRINGZ_TO_NPVARIANT("text/html", openArgs[0]);
@@ -774,7 +812,7 @@ bool testWindowOpen(NPP npp)
{
NPIdentifier openId = browser->getstringidentifier("open");
- NPObject *windowObject = NULL;
+ NPObject* windowObject = 0;
browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
if (!windowObject)
return false;
@@ -856,87 +894,100 @@ static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* a
PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD])
return testCallback(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_GETURL])
+ if (name == pluginMethodIdentifiers[ID_TEST_GETURL])
return getURL(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS])
+ if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS])
return testDOMAccess(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY])
+ if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY])
return getURLNotify(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT])
+ if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT])
return testInvokeDefault(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE])
+ if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE])
return testEnumerate(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM])
+ if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM])
return destroyStream(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER])
+ if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER])
return testGetIntIdentifier(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE])
+ if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE])
return testEvaluate(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY])
+ if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY])
return testGetProperty(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE])
+ if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE])
return testGetPropertyReturnValue(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_HAS_PROPERTY])
+ if (name == pluginMethodIdentifiers[ID_TEST_HAS_PROPERTY])
return testHasProperty(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_HAS_METHOD])
+ if (name == pluginMethodIdentifiers[ID_TEST_HAS_METHOD])
return testHasMethod(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING])
+ if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING])
return testIdentifierToString(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT])
+ if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT])
return testIdentifierToInt(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE])
+ if (name == pluginMethodIdentifiers[ID_TEST_PASS_TEST_OBJECT])
+ return testPassTestObject(plugin, args, argCount, result);
+ if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE])
return testPostURLFile(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT])
+ if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT])
return testConstruct(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_THROW_EXCEPTION_METHOD]) {
+ if (name == pluginMethodIdentifiers[ID_TEST_THROW_EXCEPTION_METHOD]) {
browser->setexception(header, "plugin object testThrowException SUCCESS");
return true;
- } else if (name == pluginMethodIdentifiers[ID_TEST_FAIL_METHOD]) {
+ }
+ if (name == pluginMethodIdentifiers[ID_TEST_FAIL_METHOD]) {
NPObject* windowScriptObject;
browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObject);
browser->invoke(plugin->npp, windowScriptObject, name, args, argCount, result);
- } else if (name == pluginMethodIdentifiers[ID_DESTROY_NULL_STREAM])
+ return false;
+ }
+ if (name == pluginMethodIdentifiers[ID_DESTROY_NULL_STREAM])
return destroyNullStream(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_NO_PAGES]) {
+ if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_NO_PAGES]) {
browser->reloadplugins(false);
return true;
- } else if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_AND_PAGES]) {
+ }
+ if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_AND_PAGES]) {
browser->reloadplugins(true);
return true;
- } else if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) {
+ }
+ if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) {
browser->getproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVariantToIdentifier(args[1]), result);
return true;
- } else if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) {
+ }
+ if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) {
browser->setproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVariantToIdentifier(args[1]), &args[2]);
return true;
- } else if (name == pluginMethodIdentifiers[ID_REMEMBER]) {
+ }
+ if (name == pluginMethodIdentifiers[ID_REMEMBER]) {
if (plugin->rememberedObject)
browser->releaseobject(plugin->rememberedObject);
plugin->rememberedObject = NPVARIANT_TO_OBJECT(args[0]);
browser->retainobject(plugin->rememberedObject);
VOID_TO_NPVARIANT(*result);
return true;
- } else if (name == pluginMethodIdentifiers[ID_GET_REMEMBERED_OBJECT]) {
+ }
+ if (name == pluginMethodIdentifiers[ID_GET_REMEMBERED_OBJECT]) {
assert(plugin->rememberedObject);
browser->retainobject(plugin->rememberedObject);
OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
return true;
- } else if (name == pluginMethodIdentifiers[ID_GET_AND_FORGET_REMEMBERED_OBJECT]) {
+ }
+ if (name == pluginMethodIdentifiers[ID_GET_AND_FORGET_REMEMBERED_OBJECT]) {
assert(plugin->rememberedObject);
OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
plugin->rememberedObject = 0;
return true;
- } else if (name == pluginMethodIdentifiers[ID_REF_COUNT]) {
+ }
+ if (name == pluginMethodIdentifiers[ID_REF_COUNT]) {
uint32_t refCount = NPVARIANT_TO_OBJECT(args[0])->referenceCount;
INT32_TO_NPVARIANT(refCount, *result);
return true;
- } else if (name == pluginMethodIdentifiers[ID_SET_STATUS])
+ }
+ if (name == pluginMethodIdentifiers[ID_SET_STATUS])
return testSetStatus(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_RESIZE_TO])
+ if (name == pluginMethodIdentifiers[ID_RESIZE_TO])
return testResizeTo(plugin, args, argCount, result);
- else if (name == pluginMethodIdentifiers[ID_NORMALIZE])
+ if (name == pluginMethodIdentifiers[ID_NORMALIZE])
return normalizeOverride(plugin, args, argCount, result);
-
+
return false;
}
@@ -990,6 +1041,7 @@ static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
static void pluginDeallocate(NPObject* header)
{
PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
+ delete plugin->pluginTest;
if (plugin->testObject)
browser->releaseobject(plugin->testObject);
if (plugin->rememberedObject)
@@ -1008,14 +1060,14 @@ void handleCallback(PluginObject* object, const char *url, NPReason reason, void
NPVariant args[2];
- NPObject *windowScriptObject;
+ NPObject* windowScriptObject;
browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
NPIdentifier callbackIdentifier = notifyData;
INT32_TO_NPVARIANT(reason, args[0]);
- char *strHdr = NULL;
+ char* strHdr = 0;
if (object->firstUrl && object->firstHeaders && object->lastUrl && object->lastHeaders) {
// Format expected by JavaScript validator: four fields separated by \n\n:
// First URL; first header block; last URL; last header block.
@@ -1040,7 +1092,7 @@ void handleCallback(PluginObject* object, const char *url, NPReason reason, void
void notifyStream(PluginObject* object, const char *url, const char *headers)
{
- if (object->firstUrl == NULL) {
+ if (!object->firstUrl) {
if (url)
object->firstUrl = strdup(url);
if (headers)
@@ -1048,8 +1100,8 @@ void notifyStream(PluginObject* object, const char *url, const char *headers)
} else {
free(object->lastUrl);
free(object->lastHeaders);
- object->lastUrl = (url ? strdup(url) : NULL);
- object->lastHeaders = (headers ? strdup(headers) : NULL);
+ object->lastUrl = (url ? strdup(url) : 0);
+ object->lastHeaders = (headers ? strdup(headers) : 0);
}
}
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h
index 99d5bf6..def8ad8 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h
@@ -23,6 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef PluginObject_h
+#define PluginObject_h
+
#include <WebKit/npfunctions.h>
#if defined(XP_MACOSX)
@@ -90,3 +93,4 @@ extern bool testWindowOpen(NPP npp);
extern void* createCoreAnimationLayer();
#endif
+#endif // PluginObject_h
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
index e41e6e5..06c9953 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
@@ -101,28 +101,28 @@ bool PluginTest::NPN_RemoveProperty(NPObject* npObject, NPIdentifier propertyNam
return browser->removeproperty(m_npp, npObject, propertyName);
}
-static void executeScript(NPP npp, const char* script)
+void PluginTest::executeScript(const char* script)
{
NPObject* windowScriptObject;
- browser->getvalue(npp, NPNVWindowNPObject, &windowScriptObject);
+ browser->getvalue(m_npp, NPNVWindowNPObject, &windowScriptObject);
NPString npScript;
npScript.UTF8Characters = script;
npScript.UTF8Length = strlen(script);
NPVariant browserResult;
- browser->evaluate(npp, windowScriptObject, &npScript, &browserResult);
+ browser->evaluate(m_npp, windowScriptObject, &npScript, &browserResult);
browser->releasevariantvalue(&browserResult);
}
void PluginTest::waitUntilDone()
{
- executeScript(m_npp, "layoutTestController.waitUntilDone()");
+ executeScript("layoutTestController.waitUntilDone()");
}
void PluginTest::notifyDone()
{
- executeScript(m_npp, "layoutTestController.notifyDone()");
+ executeScript("layoutTestController.notifyDone()");
}
void PluginTest::registerCreateTestFunction(const string& identifier, CreateTestFunction createTestFunction)
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
index 0497764..ae9bd82 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
@@ -68,6 +68,8 @@ public:
NPObject* NPN_CreateObject(NPClass*);
bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName);
+ void executeScript(const char*);
+
template<typename TestClassTy> class Register {
public:
Register(const std::string& identifier)
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/TestObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/TestObject.cpp
index 0b32191..8946c0e 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/TestObject.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/TestObject.cpp
@@ -59,18 +59,29 @@ NPClass *getTestClass(void)
return &testClass;
}
-static bool identifiersInitialized = false;
+typedef struct {
+ NPObject header;
+ NPObject* testObject;
+} TestObject;
-#define ID_OBJECT_POINTER 2
+static bool identifiersInitialized = false;
#define NUM_ENUMERATABLE_TEST_IDENTIFIERS 2
-#define NUM_TEST_IDENTIFIERS 3
+
+enum {
+ ID_PROPERTY_FOO = 0,
+ ID_PROPERTY_BAR,
+ ID_PROPERTY_OBJECT_POINTER,
+ ID_PROPERTY_TEST_OBJECT,
+ NUM_TEST_IDENTIFIERS,
+};
static NPIdentifier testIdentifiers[NUM_TEST_IDENTIFIERS];
static const NPUTF8 *testIdentifierNames[NUM_TEST_IDENTIFIERS] = {
"foo",
"bar",
"objectPointer",
+ "testObject",
};
#define ID_THROW_EXCEPTION_METHOD 0
@@ -87,20 +98,24 @@ static void initializeIdentifiers(void)
browser->getstringidentifiers(testMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, testMethodIdentifiers);
}
-static NPObject *testAllocate(NPP /*npp*/, NPClass* /*theClass*/)
+static NPObject* testAllocate(NPP /*npp*/, NPClass* /*theClass*/)
{
- NPObject *newInstance = static_cast<NPObject*>(malloc(sizeof(NPObject)));
-
+ TestObject* newInstance = static_cast<TestObject*>(malloc(sizeof(TestObject)));
+ newInstance->testObject = 0;
+
if (!identifiersInitialized) {
identifiersInitialized = true;
initializeIdentifiers();
}
-
- return newInstance;
+
+ return reinterpret_cast<NPObject*>(newInstance);
}
static void testDeallocate(NPObject *obj)
{
+ TestObject* testObject = reinterpret_cast<TestObject*>(obj);
+ if (testObject->testObject)
+ browser->releaseobject(testObject->testObject);
free(obj);
}
@@ -134,17 +149,30 @@ static bool testHasProperty(NPObject*, NPIdentifier name)
static bool testGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result)
{
- if (name == testIdentifiers[ID_OBJECT_POINTER]) {
+ if (name == testIdentifiers[ID_PROPERTY_FOO]) {
+ char* mem = static_cast<char*>(browser->memalloc(4));
+ strcpy(mem, "foo");
+ STRINGZ_TO_NPVARIANT(mem, *result);
+ return true;
+ }
+ if (name == testIdentifiers[ID_PROPERTY_OBJECT_POINTER]) {
int32_t objectPointer = static_cast<int32_t>(reinterpret_cast<long long>(npobj));
INT32_TO_NPVARIANT(objectPointer, *result);
return true;
}
+ if (name == testIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
+ TestObject* testObject = reinterpret_cast<TestObject*>(npobj);
+ if (!testObject->testObject)
+ testObject->testObject = browser->createobject(0, &testClass);
+ browser->retainobject(testObject->testObject);
+ OBJECT_TO_NPVARIANT(testObject->testObject, *result);
+ return true;
+ }
return false;
}
-
static bool testEnumerate(NPObject* /*npobj*/, NPIdentifier **value, uint32_t *count)
{
*count = NUM_ENUMERATABLE_TEST_IDENTIFIERS;
@@ -163,5 +191,3 @@ static bool testConstruct(NPObject* npobj, const NPVariant* /*args*/, uint32_t /
OBJECT_TO_NPVARIANT(npobj, *result);
return true;
}
-
-
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp
new file mode 100644
index 0000000..4b5d3e0
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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 "PluginTest.h"
+
+#include "PluginObject.h"
+
+using namespace std;
+
+// Executing JS after removing the plugin element from the document should not crash.
+
+class EvaluateJSAfterRemovingPluginElement : public PluginTest {
+public:
+ EvaluateJSAfterRemovingPluginElement(NPP, const string& identifier);
+
+private:
+ virtual NPError NPP_DestroyStream(NPStream*, NPReason);
+
+ bool m_didExecuteScript;
+};
+
+static PluginTest::Register<EvaluateJSAfterRemovingPluginElement> registrar("evaluate-js-after-removing-plugin-element");
+
+EvaluateJSAfterRemovingPluginElement::EvaluateJSAfterRemovingPluginElement(NPP npp, const string& identifier)
+ : PluginTest(npp, identifier)
+ , m_didExecuteScript(false)
+{
+ waitUntilDone();
+}
+
+NPError EvaluateJSAfterRemovingPluginElement::NPP_DestroyStream(NPStream*, NPReason)
+{
+ if (m_didExecuteScript)
+ return NPERR_NO_ERROR;
+ m_didExecuteScript = true;
+
+ executeScript("var plugin = document.getElementsByTagName('embed')[0]; plugin.parentElement.removeChild(plugin);");
+ executeScript("document.body.appendChild(document.createTextNode('Executing script after removing the plugin element from the document succeeded.'));");
+ notifyDone();
+
+ return NPERR_NO_ERROR;
+}
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/DrawsGradient.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/DrawsGradient.cpp
new file mode 100644
index 0000000..2b06198
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/DrawsGradient.cpp
@@ -0,0 +1,118 @@
+/* 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 "WindowedPluginTest.h"
+
+#include "PluginObject.h"
+
+using namespace std;
+
+// Just fills its window with some gradients
+
+class DrawsGradient : public WindowedPluginTest {
+public:
+ DrawsGradient(NPP, const string& identifier);
+
+private:
+ void paint(HDC) const;
+
+ LRESULT onPaint(WPARAM, LPARAM, bool& handled);
+ LRESULT onPrintClient(WPARAM, LPARAM, bool& handled);
+
+ virtual LRESULT wndProc(UINT message, WPARAM, LPARAM, bool& handled);
+};
+
+static PluginTest::Register<DrawsGradient> registrar("draws-gradient");
+
+DrawsGradient::DrawsGradient(NPP npp, const string& identifier)
+ : WindowedPluginTest(npp, identifier)
+{
+}
+
+LRESULT DrawsGradient::wndProc(UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
+{
+ LRESULT result = 0;
+
+ switch (message) {
+ case WM_PAINT:
+ result = onPaint(wParam, lParam, handled);
+ break;
+ case WM_PRINTCLIENT:
+ result = onPrintClient(wParam, lParam, handled);
+ break;
+ default:
+ handled = false;
+ }
+
+ return result;
+}
+
+LRESULT DrawsGradient::onPaint(WPARAM, LPARAM, bool& handled)
+{
+ PAINTSTRUCT paintStruct;
+ HDC dc = ::BeginPaint(window(), &paintStruct);
+ if (!dc)
+ return 0;
+
+ paint(dc);
+ ::EndPaint(window(), &paintStruct);
+
+ handled = true;
+ return 0;
+}
+
+LRESULT DrawsGradient::onPrintClient(WPARAM wParam, LPARAM, bool& handled)
+{
+ paint(reinterpret_cast<HDC>(wParam));
+
+ handled = true;
+ return 0;
+}
+
+void DrawsGradient::paint(HDC dc) const
+{
+ RECT clientRect;
+ if (!::GetClientRect(window(), &clientRect))
+ return;
+
+ TRIVERTEX vertices[] = {
+ // Upper-left: green
+ { clientRect.left, clientRect.top, 0, 0xff00, 0, 0 },
+ // Upper-right: blue
+ { clientRect.right, clientRect.top, 0, 0, 0xff00, 0 },
+ // Lower-left: yellow
+ { clientRect.left, clientRect.bottom, 0xff00, 0xff00, 0, 0 },
+ // Lower-right: red
+ { clientRect.right, clientRect.bottom, 0xff00, 0, 0, 0 },
+ };
+
+ GRADIENT_TRIANGLE mesh[] = {
+ // Upper-left triangle
+ { 0, 1, 2 },
+ // Lower-right triangle
+ { 1, 2, 3 },
+ };
+
+ ::GradientFill(dc, vertices, _countof(vertices), mesh, _countof(mesh), GRADIENT_FILL_TRIANGLE);
+}
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp
index 90ea54d..e598c49 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp
@@ -23,7 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "PluginTest.h"
+#include "WindowedPluginTest.h"
#include "PluginObject.h"
@@ -69,28 +69,24 @@ TemporaryWindowMover::~TemporaryWindowMover()
::SetWindowPos(m_window, 0, m_savedWindowRect.left, m_savedWindowRect.top, 0, 0, SWP_HIDEWINDOW | standardSetWindowPosFlags);
}
-class NPNInvalidateRectInvalidatesWindow : public PluginTest {
+class NPNInvalidateRectInvalidatesWindow : public WindowedPluginTest {
public:
NPNInvalidateRectInvalidatesWindow(NPP, const string& identifier);
~NPNInvalidateRectInvalidatesWindow();
private:
- static LRESULT CALLBACK wndProc(HWND, UINT message, WPARAM, LPARAM);
+ virtual LRESULT wndProc(UINT message, WPARAM, LPARAM, bool& handled);
void onPaint();
void testInvalidateRect();
virtual NPError NPP_SetWindow(NPP, NPWindow*);
- HWND m_window;
- WNDPROC m_originalWndProc;
TemporaryWindowMover* m_windowMover;
};
NPNInvalidateRectInvalidatesWindow::NPNInvalidateRectInvalidatesWindow(NPP npp, const string& identifier)
- : PluginTest(npp, identifier)
- , m_window(0)
- , m_originalWndProc(0)
+ : WindowedPluginTest(npp, identifier)
, m_windowMover(0)
{
}
@@ -100,30 +96,20 @@ NPNInvalidateRectInvalidatesWindow::~NPNInvalidateRectInvalidatesWindow()
delete m_windowMover;
}
-NPError NPNInvalidateRectInvalidatesWindow::NPP_SetWindow(NPP instance, NPWindow* window)
+NPError NPNInvalidateRectInvalidatesWindow::NPP_SetWindow(NPP instance, NPWindow* npWindow)
{
- HWND newWindow = reinterpret_cast<HWND>(window->window);
- if (newWindow == m_window)
- return NPERR_NO_ERROR;
-
- if (m_window) {
- ::RemovePropW(m_window, instancePointerProperty);
- ::SetWindowLongPtr(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_originalWndProc));
- m_originalWndProc = 0;
- }
+ NPError error = WindowedPluginTest::NPP_SetWindow(instance, npWindow);
+ if (error != NPERR_NO_ERROR)
+ return error;
- m_window = newWindow;
- if (!m_window)
+ if (!window())
return NPERR_NO_ERROR;
- m_originalWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtrW(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wndProc)));
- ::SetPropW(m_window, instancePointerProperty, this);
-
// The test harness's window (the one that contains the WebView) is off-screen and hidden.
// We need to move it on-screen and make it visible in order for the plugin's window to
// accumulate an update region when the DWM is disabled.
- HWND testHarnessWindow = ::GetAncestor(m_window, GA_ROOT);
+ HWND testHarnessWindow = ::GetAncestor(window(), GA_ROOT);
if (!testHarnessWindow) {
pluginLog(instance, "Failed to get test harness window");
return NPERR_GENERIC_ERROR;
@@ -141,14 +127,13 @@ NPError NPNInvalidateRectInvalidatesWindow::NPP_SetWindow(NPP instance, NPWindow
return NPERR_NO_ERROR;
}
-LRESULT NPNInvalidateRectInvalidatesWindow::wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+LRESULT NPNInvalidateRectInvalidatesWindow::wndProc(UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
- NPNInvalidateRectInvalidatesWindow* instance = reinterpret_cast<NPNInvalidateRectInvalidatesWindow*>(::GetPropW(hwnd, instancePointerProperty));
-
if (message == WM_PAINT)
- instance->onPaint();
+ onPaint();
- return ::CallWindowProcW(instance->m_originalWndProc, hwnd, message, wParam, lParam);
+ handled = false;
+ return 0;
}
void NPNInvalidateRectInvalidatesWindow::onPaint()
@@ -162,7 +147,7 @@ void NPNInvalidateRectInvalidatesWindow::onPaint()
void NPNInvalidateRectInvalidatesWindow::testInvalidateRect()
{
RECT clientRect;
- if (!::GetClientRect(m_window, &clientRect)) {
+ if (!::GetClientRect(window(), &clientRect)) {
pluginLog(m_npp, "::GetClientRect failed");
return;
}
@@ -173,7 +158,7 @@ void NPNInvalidateRectInvalidatesWindow::testInvalidateRect()
}
// Clear the invalid region.
- if (!::ValidateRect(m_window, 0)) {
+ if (!::ValidateRect(window(), 0)) {
pluginLog(m_npp, "::ValidateRect failed");
return;
}
@@ -187,7 +172,7 @@ void NPNInvalidateRectInvalidatesWindow::testInvalidateRect()
NPN_InvalidateRect(&rectToInvalidate);
RECT invalidRect;
- if (!::GetUpdateRect(m_window, &invalidRect, FALSE)) {
+ if (!::GetUpdateRect(window(), &invalidRect, FALSE)) {
pluginLog(m_npp, "::GetUpdateRect failed");
return;
}
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowRegionIsSetToClipRect.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowRegionIsSetToClipRect.cpp
new file mode 100644
index 0000000..975a598
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowRegionIsSetToClipRect.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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 "PluginTest.h"
+
+#include "PluginObject.h"
+
+using namespace std;
+
+// The plugin's window's window region should be set to the plugin's clip rect.
+
+class WindowRegionIsSetToClipRect : public PluginTest {
+public:
+ WindowRegionIsSetToClipRect(NPP, const string& identifier);
+
+private:
+ virtual NPError NPP_SetWindow(NPP, NPWindow*);
+
+ bool m_didReceiveInitialSetWindowCall;
+};
+
+static PluginTest::Register<WindowRegionIsSetToClipRect> registrar("window-region-is-set-to-clip-rect");
+
+WindowRegionIsSetToClipRect::WindowRegionIsSetToClipRect(NPP npp, const string& identifier)
+ : PluginTest(npp, identifier)
+ , m_didReceiveInitialSetWindowCall(false)
+{
+}
+
+NPError WindowRegionIsSetToClipRect::NPP_SetWindow(NPP instance, NPWindow* window)
+{
+ if (m_didReceiveInitialSetWindowCall)
+ return NPERR_NO_ERROR;
+ m_didReceiveInitialSetWindowCall = true;
+
+ if (window->type != NPWindowTypeWindow) {
+ pluginLog(instance, "window->type should be NPWindowTypeWindow but was %d", window->type);
+ return NPERR_GENERIC_ERROR;
+ }
+
+ HWND hwnd = reinterpret_cast<HWND>(window->window);
+
+ RECT regionRect;
+ if (::GetWindowRgnBox(hwnd, &regionRect) == ERROR) {
+ pluginLog(instance, "::GetWindowRgnBox failed with error %u", ::GetLastError());
+ return NPERR_GENERIC_ERROR;
+ }
+
+ // This expected rect is based on the layout of window-region-is-set-to-clip-rect.html.
+ RECT expectedRect = { 50, 50, 100, 100 };
+ if (!::EqualRect(&regionRect, &expectedRect)) {
+ pluginLog(instance, "Expected region rect {left=%u, top=%u, right=%u, bottom=%u}, but got {left=%d, top=%d, right=%d, bottom=%d}", expectedRect.left, expectedRect.top, expectedRect.right, expectedRect.bottom, regionRect.left, regionRect.top, regionRect.right, regionRect.bottom);
+ return NPERR_GENERIC_ERROR;
+ }
+
+ pluginLog(instance, "PASS: Plugin's window's window region has been set as expected");
+
+ // While we're here, check that our window class doesn't have the CS_PARENTDC style, which
+ // defeats clipping by ignoring the window region and always clipping to the parent window.
+ // FIXME: It would be nice to have a pixel test that shows that we're
+ // getting clipped correctly, but unfortunately window regions are ignored
+ // during WM_PRINT (see <http://webkit.org/b/49034>).
+ wchar_t className[512];
+ if (!::GetClassNameW(hwnd, className, _countof(className))) {
+ pluginLog(instance, "::GetClassName failed with error %u", ::GetLastError());
+ return NPERR_GENERIC_ERROR;
+ }
+
+#ifdef DEBUG_ALL
+ const wchar_t webKitDLLName[] = L"WebKit_debug.dll";
+#else
+ const wchar_t webKitDLLName[] = L"WebKit.dll";
+#endif
+ HMODULE webKitModule = ::GetModuleHandleW(webKitDLLName);
+ if (!webKitModule) {
+ pluginLog(instance, "::GetModuleHandleW failed with error %u", ::GetLastError());
+ return NPERR_GENERIC_ERROR;
+ }
+
+ WNDCLASSW wndClass;
+ if (!::GetClassInfoW(webKitModule, className, &wndClass)) {
+ pluginLog(instance, "::GetClassInfoW failed with error %u", ::GetLastError());
+ return NPERR_GENERIC_ERROR;
+ }
+
+ if (wndClass.style & CS_PARENTDC)
+ pluginLog(instance, "FAIL: Plugin's window's class has the CS_PARENTDC style, which will defeat clipping");
+ else
+ pluginLog(instance, "PASS: Plugin's window's class does not have the CS_PARENTDC style");
+
+ return NPERR_NO_ERROR;
+}
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp
index e5246c4..2110a8a 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp
@@ -29,6 +29,10 @@
#include <cstdlib>
#include <string>
+#ifdef XP_UNIX
+#include <X11/Xlib.h>
+#endif
+
#if !defined(NP_NO_CARBON) && defined(QD_HEADERS_ARE_PRIVATE) && QD_HEADERS_ARE_PRIVATE
extern "C" void GlobalToLocal(Point*);
#endif
@@ -565,6 +569,54 @@ static int16_t handleEventCocoa(NPP instance, PluginObject* obj, NPCocoaEvent* e
#endif // XP_MACOSX
+#ifdef XP_UNIX
+static int16_t handleEventX11(NPP instance, PluginObject* obj, XEvent* event)
+{
+ XButtonPressedEvent* buttonPressEvent = reinterpret_cast<XButtonPressedEvent*>(event);
+ XButtonReleasedEvent* buttonReleaseEvent = reinterpret_cast<XButtonReleasedEvent*>(event);
+ switch (event->type) {
+ case ButtonPress:
+ pluginLog(instance, "mouseDown at (%d, %d)", buttonPressEvent->x, buttonPressEvent->y);
+ if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript)
+ executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
+ break;
+ case ButtonRelease:
+ pluginLog(instance, "mouseUp at (%d, %d)", buttonReleaseEvent->x, buttonReleaseEvent->y);
+ break;
+ case KeyPress:
+ // FIXME: extract key code
+ pluginLog(instance, "NOTIMPLEMENTED: keyDown '%c'", ' ');
+ if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript)
+ executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
+ break;
+ case KeyRelease:
+ // FIXME: extract key code
+ pluginLog(instance, "NOTIMPLEMENTED: keyUp '%c'", ' ');
+ break;
+ case GraphicsExpose:
+ pluginLog(instance, "updateEvt");
+ break;
+ // NPAPI events
+ case FocusIn:
+ pluginLog(instance, "getFocusEvent");
+ break;
+ case FocusOut:
+ pluginLog(instance, "loseFocusEvent");
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ case MotionNotify:
+ pluginLog(instance, "adjustCursorEvent");
+ break;
+ default:
+ pluginLog(instance, "event %d", event->type);
+ }
+
+ fflush(stdout);
+ return 0;
+}
+#endif // XP_UNIX
+
int16_t NPP_HandleEvent(NPP instance, void *event)
{
PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
@@ -579,6 +631,8 @@ int16_t NPP_HandleEvent(NPP instance, void *event)
assert(obj->eventModel == NPEventModelCocoa);
return handleEventCocoa(instance, obj, static_cast<NPCocoaEvent*>(event));
+#elif defined(XP_UNIX)
+ return handleEventX11(instance, obj, static_cast<XEvent*>(event));
#else
// FIXME: Implement for other platforms.
return 0;
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj
index 74042bc..a2e6809 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj
@@ -39,7 +39,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
DisableSpecificWarnings="4819"
/>
@@ -55,6 +55,7 @@
/>
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -109,7 +110,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
DisableSpecificWarnings="4819"
/>
@@ -125,6 +126,7 @@
/>
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -178,7 +180,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
RuntimeLibrary="3"
DisableSpecificWarnings="4819"
@@ -195,6 +197,7 @@
/>
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -248,7 +251,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
DisableSpecificWarnings="4819"
/>
@@ -264,6 +267,7 @@
/>
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -317,7 +321,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(ProjectDir)..\..\TestNetscapePlugin&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
PreprocessorDefinitions="_USRDLL;TESTNETSCAPEPLUGIN_EXPORTS;snprintf=_snprintf"
RuntimeLibrary="3"
DisableSpecificWarnings="4819"
@@ -334,6 +338,7 @@
/>
<Tool
Name="VCLinkerTool"
+ AdditionalDependencies="Msimg32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix)\np$(ProjectName)$(WebKitConfigSuffix).dll"
ModuleDefinitionFile="TestNetscapePlugin$(WebKitConfigSuffix).def"
/>
@@ -375,6 +380,10 @@
>
</File>
<File
+ RelativePath="..\Tests\EvaluateJSAfterRemovingPluginElement.cpp"
+ >
+ </File>
+ <File
RelativePath="..\Tests\NPRuntimeObjectFromDestroyedPlugin.cpp"
>
</File>
@@ -398,6 +407,10 @@
Name="win"
>
<File
+ RelativePath="..\Tests\win\DrawsGradient.cpp"
+ >
+ </File>
+ <File
RelativePath="..\Tests\win\GetValueNetscapeWindow.cpp"
>
</File>
@@ -409,8 +422,24 @@
RelativePath="..\Tests\win\WindowGeometryInitializedBeforeSetWindow.cpp"
>
</File>
+ <File
+ RelativePath="..\Tests\win\WindowRegionIsSetToClipRect.cpp"
+ >
+ </File>
</Filter>
</Filter>
+ <Filter
+ Name="win"
+ >
+ <File
+ RelativePath=".\WindowedPluginTest.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\WindowedPluginTest.h"
+ >
+ </File>
+ </Filter>
<File
RelativePath="..\main.cpp"
>
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.cpp
new file mode 100644
index 0000000..96b51f8
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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 "WindowedPluginTest.h"
+
+using namespace std;
+
+static const wchar_t instancePointerProperty[] = L"org.webkit.TestNetscapePlugin.WindowedPluginTest.InstancePointer";
+
+WindowedPluginTest::WindowedPluginTest(NPP npp, const string& identifier)
+ : PluginTest(npp, identifier)
+ , m_window(0)
+ , m_originalWndProc(0)
+{
+}
+
+NPError WindowedPluginTest::NPP_SetWindow(NPP instance, NPWindow* window)
+{
+ HWND newWindow = reinterpret_cast<HWND>(window->window);
+ if (newWindow == m_window)
+ return NPERR_NO_ERROR;
+
+ if (m_window) {
+ ::RemovePropW(m_window, instancePointerProperty);
+ ::SetWindowLongPtr(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_originalWndProc));
+ m_originalWndProc = 0;
+ }
+
+ m_window = newWindow;
+ if (!m_window)
+ return NPERR_NO_ERROR;
+
+ m_originalWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtrW(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(staticWndProc)));
+ ::SetPropW(m_window, instancePointerProperty, this);
+
+ return NPERR_NO_ERROR;
+}
+
+LRESULT WindowedPluginTest::staticWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ WindowedPluginTest* instance = reinterpret_cast<WindowedPluginTest*>(::GetPropW(hwnd, instancePointerProperty));
+
+ bool handled = false;
+ LRESULT result = instance->wndProc(message, wParam, lParam, handled);
+ if (handled)
+ return result;
+
+ return ::CallWindowProcW(instance->m_originalWndProc, hwnd, message, wParam, lParam);
+}
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.h
new file mode 100644
index 0000000..7abc734
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/WindowedPluginTest.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#ifndef WindowedPluginTest_h
+#define WindowedPluginTest_h
+
+#include "PluginTest.h"
+
+class WindowedPluginTest : public PluginTest {
+protected:
+ WindowedPluginTest(NPP, const std::string& identifier);
+
+ HWND window() const { return m_window; }
+
+ // For derived classes to override
+ virtual LRESULT wndProc(UINT message, WPARAM, LPARAM, bool& handled) = 0;
+
+ // PluginTest
+ virtual NPError NPP_SetWindow(NPP, NPWindow*);
+
+private:
+ static LRESULT CALLBACK staticWndProc(HWND, UINT message, WPARAM, LPARAM);
+
+ HWND m_window;
+ WNDPROC m_originalWndProc;
+};
+
+#endif // WindowedPluginTest_h
diff --git a/WebKitTools/DumpRenderTree/chromium/EventSender.cpp b/WebKitTools/DumpRenderTree/chromium/EventSender.cpp
index e250dfc..ec16cf7 100644
--- a/WebKitTools/DumpRenderTree/chromium/EventSender.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/EventSender.cpp
@@ -873,6 +873,7 @@ void EventSender::sendCurrentTouchEvent(const WebInputEvent::Type type)
WebTouchEvent touchEvent;
touchEvent.type = type;
touchEvent.modifiers = touchModifiers;
+ touchEvent.timeStampSeconds = getCurrentEventTimeSec();
touchEvent.touchPointsLength = touchPoints.size();
for (unsigned i = 0; i < touchPoints.size(); ++i)
touchEvent.touchPoints[i] = touchPoints[i];
diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
index d713b04..5b0c844 100644
--- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
@@ -71,6 +71,8 @@ using namespace std;
LayoutTestController::LayoutTestController(TestShell* shell)
: m_shell(shell)
+ , m_closeRemainingWindows(false)
+ , m_deferMainResourceDataLoad(false)
, m_workQueue(this)
{
@@ -1486,6 +1488,9 @@ void LayoutTestController::setEditingBehavior(const CppArgumentList& arguments,
} else if (key == "win") {
m_shell->preferences()->editingBehavior = WebSettings::EditingBehaviorWin;
m_shell->applyPreferences();
+ } else if (key == "unix") {
+ m_shell->preferences()->editingBehavior = WebSettings::EditingBehaviorUnix;
+ m_shell->applyPreferences();
} else
logErrorToConsole("Passed invalid editing behavior. Should be 'mac' or 'win'.");
}
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.h b/WebKitTools/DumpRenderTree/chromium/TestShell.h
index ca06812..06e77cc 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShell.h
+++ b/WebKitTools/DumpRenderTree/chromium/TestShell.h
@@ -144,7 +144,7 @@ public:
// The JavaScript flags are specified as a vector of strings. Each element of the vector is full flags string
// which can contain multiple flags (e.g. "--xxx --yyy"). With multiple load testing it is possible to specify
// separate sets of flags to each load.
- std::string javaScriptFlagsForLoad(size_t load) { return (load >= 0 && load < m_javaScriptFlags.size()) ? m_javaScriptFlags[load] : ""; }
+ std::string javaScriptFlagsForLoad(size_t load) { return (load < m_javaScriptFlags.size()) ? m_javaScriptFlags[load] : ""; }
void setJavaScriptFlags(Vector<std::string> javaScriptFlags) { m_javaScriptFlags = javaScriptFlags; }
// Set whether to dump when the loaded page has finished processing. This is used with multiple load
diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp
index 847e7dc..2f9bdfb 100644
--- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp
@@ -940,11 +940,16 @@ void WebViewHost::didChangeLocationWithinPage(WebFrame* frame)
void WebViewHost::assignIdentifierToRequest(WebFrame*, unsigned identifier, const WebURLRequest& request)
{
- if (!m_shell->shouldDumpResourceLoadCallbacks())
- return;
+ ASSERT(!m_resourceIdentifierMap.contains(identifier));
m_resourceIdentifierMap.set(identifier, descriptionSuitableForTestResult(request.url().spec()));
}
+void WebViewHost::removeIdentifierForRequest(unsigned identifier)
+{
+ ASSERT(m_resourceIdentifierMap.contains(identifier));
+ m_resourceIdentifierMap.remove(identifier);
+}
+
void WebViewHost::willSendRequest(WebFrame*, unsigned identifier, WebURLRequest& request, const WebURLResponse& redirectResponse)
{
// Need to use GURL for host() and SchemeIs()
@@ -1022,7 +1027,7 @@ void WebViewHost::didFinishResourceLoad(WebFrame*, unsigned identifier)
printResourceDescription(identifier);
fputs(" - didFinishLoading\n", stdout);
}
- m_resourceIdentifierMap.remove(identifier);
+ removeIdentifierForRequest(identifier);
}
void WebViewHost::didFailResourceLoad(WebFrame*, unsigned identifier, const WebURLError& error)
@@ -1033,7 +1038,7 @@ void WebViewHost::didFailResourceLoad(WebFrame*, unsigned identifier, const WebU
fputs(webkit_support::MakeURLErrorDescription(error).c_str(), stdout);
fputs("\n", stdout);
}
- m_resourceIdentifierMap.remove(identifier);
+ removeIdentifierForRequest(identifier);
}
void WebViewHost::didDisplayInsecureContent(WebFrame*)
diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h
index 1380ebd..f21e663 100644
--- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h
+++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h
@@ -185,6 +185,7 @@ class WebViewHost : public WebKit::WebViewClient, public WebKit::WebFrameClient,
virtual void didNavigateWithinPage(WebKit::WebFrame*, bool isNewNavigation);
virtual void didChangeLocationWithinPage(WebKit::WebFrame*);
virtual void assignIdentifierToRequest(WebKit::WebFrame*, unsigned identifier, const WebKit::WebURLRequest&);
+ virtual void removeIdentifierForRequest(unsigned identifier);
virtual void willSendRequest(WebKit::WebFrame*, unsigned identifier, WebKit::WebURLRequest&, const WebKit::WebURLResponse&);
virtual void didReceiveResponse(WebKit::WebFrame*, unsigned identifier, const WebKit::WebURLResponse&);
virtual void didFinishResourceLoad(WebKit::WebFrame*, unsigned identifier);
diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
index 1c851d7..54acc49 100644
--- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
@@ -137,10 +137,9 @@ static void initializeGtkFontSettings(const char* testURL)
GtkSettings* settings = gtk_settings_get_default();
if (!settings)
return;
- g_object_set(settings, "gtk-xft-antialias", 1, NULL);
- g_object_set(settings, "gtk-xft-hinting", 1, NULL);
- g_object_set(settings, "gtk-xft-hintstyle", "hintfull", NULL);
- g_object_set(settings, "gtk-font-name", "Liberation Sans 16", NULL);
+ g_object_set(settings, "gtk-xft-antialias", 1,
+ "gtk-xft-hinting", 0,
+ "gtk-font-name", "Liberation Sans 16", NULL);
// One test needs subpixel anti-aliasing turned on, but generally we
// want all text in other tests to use to grayscale anti-aliasing.
diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
index 688b3f8..ab70a3e 100644
--- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
@@ -813,8 +813,10 @@ void LayoutTestController::setEditingBehavior(const char* editingBehavior)
if (!strcmp(editingBehavior, "win"))
g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_WINDOWS, NULL);
- if (!strcmp(editingBehavior, "mac"))
+ else if (!strcmp(editingBehavior, "mac"))
g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_MAC, NULL);
+ else if (!strcmp(editingBehavior, "unix"))
+ g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_UNIX, NULL);
}
void LayoutTestController::abortModal()
diff --git a/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf b/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf
index 6eb057e..2d9af17 100644
--- a/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf
+++ b/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf
@@ -2,6 +2,19 @@
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
+ <!-- Due to patent (http://freetype.sourceforge.net/patents.html)
+ issues hinting gives different results depending on the
+ freetype version of the linux distribution, avoiding hinting
+ gives more consistent results. When all the distributions
+ release freetype the 2.4, which enables by default the
+ hinting method that was patented, we could undo this change
+ and try the hinting again. -->
+ <match target="font">
+ <edit name="hinting" mode="assign">
+ <bool>false</bool>
+ </edit>
+ </match>
+
<!-- The sans-serif font should be Liberation Serif -->
<match target="pattern">
<test qual="any" name="family">
@@ -158,6 +171,9 @@
<edit name="family" mode="assign">
<string>Liberation Serif</string>
</edit>
+ <edit name="hinting" mode="assign">
+ <bool>true</bool>
+ </edit>
<edit name="hintstyle" mode="assign">
<const>hintslight</const>
</edit>
@@ -175,7 +191,7 @@
<edit name="hintstyle" mode="assign">
<const>hintfull</const>
</edit>
- <edit name="hinting" mode="assign">
+ <edit name="hinting" mode="assign">
<bool>false</bool>
</edit>
</match>
@@ -187,6 +203,9 @@
<edit name="family" mode="assign">
<string>Liberation Serif</string>
</edit>
+ <edit name="hinting" mode="assign">
+ <bool>true</bool>
+ </edit>
<edit name="autohint" mode="assign">
<bool>true</bool>
</edit>
@@ -202,6 +221,9 @@
<edit name="family" mode="assign">
<string>Liberation Serif</string>
</edit>
+ <edit name="hinting" mode="assign">
+ <bool>true</bool>
+ </edit>
<edit name="autohint" mode="assign">
<bool>false</bool>
</edit>
@@ -217,6 +239,9 @@
<edit name="family" mode="assign">
<string>Liberation Serif</string>
</edit>
+ <edit name="hinting" mode="assign">
+ <bool>true</bool>
+ </edit>
<edit name="autohint" mode="assign">
<bool>true</bool>
</edit>
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
index 150b6f9..431d4e9 100644
--- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -935,8 +935,10 @@ void LayoutTestController::setEditingBehavior(const char* editingBehavior)
NSString* editingBehaviorNS = [[NSString alloc] initWithUTF8String:editingBehavior];
if ([editingBehaviorNS isEqualToString:@"mac"])
[[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingMacBehavior];
- if ([editingBehaviorNS isEqualToString:@"win"])
+ else if ([editingBehaviorNS isEqualToString:@"win"])
[[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingWinBehavior];
+ else if ([editingBehaviorNS isEqualToString:@"unix"])
+ [[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingUnixBehavior];
[editingBehaviorNS release];
}
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
index f99ec4f..3e50e06 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
@@ -810,5 +810,10 @@ bool LayoutTestController::hasSpellingMarker(int, int)
return false;
}
+QVariantList LayoutTestController::nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
+{
+ return DumpRenderTreeSupportQt::nodesFromRect(document, x, y, top, right, bottom, left, ignoreClipping);
+}
+
const unsigned LayoutTestController::maxViewWidth = 800;
const unsigned LayoutTestController::maxViewHeight = 600;
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
index 11d72e4..dfb12fe 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
@@ -222,6 +222,8 @@ public slots:
void abortModal() {}
bool hasSpellingMarker(int from, int length);
+ QVariantList nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping);
+
/*
Policy values: 'on', 'auto' or 'off'.
Orientation values: 'vertical' or 'horizontal'.
diff --git a/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro b/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro
index b958025..1d460d7 100644
--- a/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro
+++ b/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro
@@ -29,6 +29,7 @@ SOURCES = PluginObject.cpp \
PluginTest.cpp \
TestObject.cpp \
Tests/DocumentOpenInDestroyStream.cpp \
+ Tests/EvaluateJSAfterRemovingPluginElement.cpp \
Tests/NPRuntimeObjectFromDestroyedPlugin.cpp \
Tests/NPRuntimeRemoveProperty.cpp \
Tests/NullNPPGetValuePointer.cpp \
diff --git a/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp b/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp
index 14bb8ef..2298ef1 100644
--- a/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp
+++ b/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp
@@ -372,7 +372,9 @@ webkit_test_plugin_set_value(NPP instance, NPNVariable variable, void* value)
char *
NP_GetMIMEDescription(void)
{
- return const_cast<char*>("application/x-webkit-test-netscape:testnetscape:test netscape content");
+ // We sentence-case the mime-type here to ensure that ports are not
+ // case-sensitive when loading plugins. See https://webkit.org/b/36815
+ return const_cast<char*>("application/x-Webkit-Test-Netscape:testnetscape:test netscape content");
}
NPError
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
index 5138562..7c3d9b3 100644
--- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
@@ -98,7 +98,6 @@ PolicyDelegate* policyDelegate;
COMPtr<FrameLoadDelegate> sharedFrameLoadDelegate;
COMPtr<UIDelegate> sharedUIDelegate;
COMPtr<EditingDelegate> sharedEditingDelegate;
-COMPtr<ResourceLoadDelegate> sharedResourceLoadDelegate;
COMPtr<HistoryDelegate> sharedHistoryDelegate;
IWebFrame* frame;
@@ -1201,7 +1200,10 @@ IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow)
if (FAILED(viewEditing->setEditingDelegate(sharedEditingDelegate.get())))
return 0;
- if (FAILED(webView->setResourceLoadDelegate(sharedResourceLoadDelegate.get())))
+ ResourceLoadDelegate* resourceLoadDelegate = new ResourceLoadDelegate();
+ HRESULT result = webView->setResourceLoadDelegate(resourceLoadDelegate);
+ resourceLoadDelegate->Release(); // The delegate is owned by the WebView, so release our reference to it.
+ if (FAILED(result))
return 0;
openWindows().append(hostWindow);
@@ -1285,7 +1287,6 @@ int main(int argc, char* argv[])
sharedFrameLoadDelegate.adoptRef(new FrameLoadDelegate);
sharedUIDelegate.adoptRef(new UIDelegate);
sharedEditingDelegate.adoptRef(new EditingDelegate);
- sharedResourceLoadDelegate.adoptRef(new ResourceLoadDelegate);
sharedHistoryDelegate.adoptRef(new HistoryDelegate);
// FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592>
diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
index d7c41e0..386f118 100644
--- a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
@@ -1383,8 +1383,10 @@ void LayoutTestController::setEditingBehavior(const char* editingBehavior)
string behaviorString(editingBehavior);
if (behaviorString == "mac")
preferences->setEditingBehavior(WebKitEditingMacBehavior);
- if (behaviorString == "win")
+ else if (behaviorString == "win")
preferences->setEditingBehavior(WebKitEditingWinBehavior);
+ else if (behaviorString == "unix")
+ preferences->setEditingBehavior(WebKitEditingUnixBehavior);
}
void LayoutTestController::abortModal()
diff --git a/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp b/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp
index b0c76d6..752cc39 100644
--- a/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/PixelDumpSupportWin.cpp
@@ -63,7 +63,7 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool onscreen, bool inc
HDC memoryDC = CreateCompatibleDC(0);
SelectObject(memoryDC, bitmap);
- SendMessage(webViewWindow, WM_PRINTCLIENT, reinterpret_cast<WPARAM>(memoryDC), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED);
+ SendMessage(webViewWindow, WM_PRINT, reinterpret_cast<WPARAM>(memoryDC), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED);
DeleteDC(memoryDC);
BITMAP info = {0};
@@ -73,7 +73,7 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool onscreen, bool inc
#if PLATFORM(CG)
RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
CGContextRef context = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
- info.bmWidthBytes, colorSpace.get(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
+ info.bmWidthBytes, colorSpace.get(), kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
#elif PLATFORM(CAIRO)
cairo_surface_t* image = cairo_image_surface_create_for_data((unsigned char*)info.bmBits, CAIRO_FORMAT_ARGB32,
info.bmWidth, info.bmHeight, info.bmWidthBytes);
diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp
index 825366a..09b07d6 100644
--- a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp
+++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.cpp
@@ -35,7 +35,6 @@
#include <comutil.h>
#include <sstream>
#include <tchar.h>
-#include <wtf/HashMap.h>
#include <wtf/Vector.h>
using namespace std;
@@ -60,26 +59,17 @@ static inline BSTR BSTRFromString(const string& str)
return result;
}
-typedef HashMap<unsigned long, wstring> IdentifierMap;
-
-IdentifierMap& urlMap()
-{
- static IdentifierMap urlMap;
-
- return urlMap;
-}
-
-static wstring descriptionSuitableForTestResult(unsigned long identifier)
+wstring ResourceLoadDelegate::descriptionSuitableForTestResult(unsigned long identifier) const
{
- IdentifierMap::iterator it = urlMap().find(identifier);
+ IdentifierMap::const_iterator it = m_urlMap.find(identifier);
- if (it == urlMap().end())
+ if (it == m_urlMap.end())
return L"<unknown>";
return urlSuitableForTestResult(it->second);
}
-static wstring descriptionSuitableForTestResult(IWebURLRequest* request)
+wstring ResourceLoadDelegate::descriptionSuitableForTestResult(IWebURLRequest* request)
{
if (!request)
return L"(null)";
@@ -108,7 +98,7 @@ static wstring descriptionSuitableForTestResult(IWebURLRequest* request)
return L"<NSURLRequest URL " + url + L", main document URL " + mainDocumentURL + L", http method " + httpMethod + L">";
}
-static wstring descriptionSuitableForTestResult(IWebURLResponse* response)
+wstring ResourceLoadDelegate::descriptionSuitableForTestResult(IWebURLResponse* response)
{
if (!response)
return L"(null)";
@@ -128,7 +118,7 @@ static wstring descriptionSuitableForTestResult(IWebURLResponse* response)
return L"<NSURLResponse " + url + L", http status code " + wstringFromInt(statusCode) + L">";
}
-static wstring descriptionSuitableForTestResult(IWebError* error, unsigned long identifier)
+wstring ResourceLoadDelegate::descriptionSuitableForTestResult(IWebError* error, unsigned long identifier) const
{
wstring result = L"<NSError ";
@@ -197,6 +187,8 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::QueryInterface(REFIID riid, void
*ppvObject = static_cast<IWebResourceLoadDelegate*>(this);
else if (IsEqualGUID(riid, IID_IWebResourceLoadDelegate))
*ppvObject = static_cast<IWebResourceLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebResourceLoadDelegatePrivate2))
+ *ppvObject = static_cast<IWebResourceLoadDelegatePrivate2*>(this);
else
return E_NOINTERFACE;
@@ -229,12 +221,22 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::identifierForInitialRequest(
if (FAILED(request->URL(&urlStr)))
return E_FAIL;
+ ASSERT(!urlMap().contains(identifier));
urlMap().set(identifier, wstringFromBSTR(urlStr));
}
return S_OK;
}
+HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::removeIdentifierForRequest(
+ /* [in] */ IWebView* webView,
+ /* [in] */ unsigned long identifier)
+{
+ urlMap().remove(identifier);
+
+ return S_OK;
+}
+
HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::willSendRequest(
/* [in] */ IWebView* webView,
/* [in] */ unsigned long identifier,
@@ -351,11 +353,12 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFinishLoadingFromDataSource(
{
if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
printf("%S - didFinishLoading\n",
- descriptionSuitableForTestResult(identifier).c_str()),
- urlMap().remove(identifier);
+ descriptionSuitableForTestResult(identifier).c_str());
}
- return S_OK;
+ removeIdentifierForRequest(webView, identifier);
+
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFailLoadingWithError(
@@ -368,8 +371,9 @@ HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFailLoadingWithError(
printf("%S - didFailLoadingWithError: %S\n",
descriptionSuitableForTestResult(identifier).c_str(),
descriptionSuitableForTestResult(error, identifier).c_str());
- urlMap().remove(identifier);
}
+ removeIdentifierForRequest(webView, identifier);
+
return S_OK;
}
diff --git a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h
index 924727b..3f20f47 100644
--- a/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h
+++ b/WebKitTools/DumpRenderTree/win/ResourceLoadDelegate.h
@@ -30,8 +30,10 @@
#define ResourceLoadDelegate_h
#include <WebKit/WebKit.h>
+#include <string>
+#include <wtf/HashMap.h>
-class ResourceLoadDelegate : public IWebResourceLoadDelegate {
+class ResourceLoadDelegate : public IWebResourceLoadDelegate, public IWebResourceLoadDelegatePrivate2 {
public:
ResourceLoadDelegate();
virtual ~ResourceLoadDelegate();
@@ -95,8 +97,22 @@ public:
/* [in] */ IWebView *webView,
/* [in] */ IWebError *error,
/* [in] */ IWebDataSource *dataSource) { return E_NOTIMPL; }
+
+ // IWebResourceLoadDelegatePrivate2
+ virtual HRESULT STDMETHODCALLTYPE removeIdentifierForRequest(
+ /* [in] */ IWebView *webView,
+ /* [in] */ unsigned long identifier);
-protected:
+private:
+ static std::wstring descriptionSuitableForTestResult(IWebURLRequest*);
+ static std::wstring descriptionSuitableForTestResult(IWebURLResponse*);
+ std::wstring descriptionSuitableForTestResult(unsigned long) const;
+ std::wstring descriptionSuitableForTestResult(IWebError*, unsigned long) const;
+
+ typedef HashMap<unsigned long, std::wstring> IdentifierMap;
+ IdentifierMap& urlMap() { return m_urlMap; }
+ IdentifierMap m_urlMap;
+
ULONG m_refCount;
};
diff --git a/WebKitTools/GNUmakefile.am b/WebKitTools/GNUmakefile.am
index 2700869..d20b3b5 100644
--- a/WebKitTools/GNUmakefile.am
+++ b/WebKitTools/GNUmakefile.am
@@ -167,6 +167,7 @@ TestNetscapePlugin_libtestnetscapeplugin_la_SOURCES = \
WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/ForwardingHeaders/WebKit/npruntime.h \
WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp \
WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/DocumentOpenInDestroyStream.cpp \
+ WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/EvaluateJSAfterRemovingPluginElement.cpp \
WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NPRuntimeObjectFromDestroyedPlugin.cpp \
WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NPRuntimeRemoveProperty.cpp \
WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp \
diff --git a/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m b/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m
index 1fffce6..f3d44a5 100644
--- a/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m
+++ b/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m
@@ -88,7 +88,7 @@ void didRecieveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef me
CFRelease(cfMessageName);
}
-void WKBundleInitialize(WKBundleRef bundle)
+void WKBundleInitialize(WKBundleRef bundle, WKTypeRef initializationUserData)
{
globalBundle = bundle;
diff --git a/WebKitTools/QtTestBrowser/QtTestBrowser.pro b/WebKitTools/QtTestBrowser/QtTestBrowser.pro
index 08e0fb8..62d2c02 100644
--- a/WebKitTools/QtTestBrowser/QtTestBrowser.pro
+++ b/WebKitTools/QtTestBrowser/QtTestBrowser.pro
@@ -49,6 +49,7 @@ linux-* {
symbian {
TARGET.UID3 = 0xA000E543
TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices Location
+ MMP_RULES *= pageddata
}
contains(QT_CONFIG, opengl) {
diff --git a/WebKitTools/QtTestBrowser/launcherwindow.cpp b/WebKitTools/QtTestBrowser/launcherwindow.cpp
index e5e49be..7608063 100644
--- a/WebKitTools/QtTestBrowser/launcherwindow.cpp
+++ b/WebKitTools/QtTestBrowser/launcherwindow.cpp
@@ -70,12 +70,11 @@ void LauncherWindow::init()
resize(800, 600);
#endif
- m_inspector = new WebInspector(splitter);
+ m_inspector = new WebInspector;
#ifndef QT_NO_PROPERTIES
if (!m_windowOptions.inspectorUrl.isEmpty())
m_inspector->setProperty("_q_inspectorUrl", m_windowOptions.inspectorUrl);
#endif
- m_inspector->hide();
connect(this, SIGNAL(destroyed()), m_inspector, SLOT(deleteLater()));
// the zoom values are chosen to be like in Mozilla Firefox 3
@@ -130,6 +129,7 @@ void LauncherWindow::initializeView()
applyPrefs();
+ splitter->addWidget(m_inspector);
m_inspector->setPage(page());
m_inspector->hide();
diff --git a/WebKitTools/QtTestBrowser/useragentlist.txt b/WebKitTools/QtTestBrowser/useragentlist.txt
index b4b00f6..1c424d9 100644
--- a/WebKitTools/QtTestBrowser/useragentlist.txt
+++ b/WebKitTools/QtTestBrowser/useragentlist.txt
@@ -3,6 +3,7 @@ Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0; en-GB) AppleWebKit/533.3 (KHTML, li
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/125.2 (KHTML, like Gecko) Safari/125.8
Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2
Mozilla/5.0 (iPhone; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10
+Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10
Opera/9.25 (Windows NT 6.0; U; en)
Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0 Nokia5800d-1b/20.2.014; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413
diff --git a/WebKitTools/QtTestBrowser/webinspector.h b/WebKitTools/QtTestBrowser/webinspector.h
index d251c5c..5cc7f8a 100644
--- a/WebKitTools/QtTestBrowser/webinspector.h
+++ b/WebKitTools/QtTestBrowser/webinspector.h
@@ -35,7 +35,7 @@ class WebInspector : public QWebInspector {
Q_OBJECT
public:
- WebInspector(QWidget* parent) : QWebInspector(parent) {}
+ WebInspector(QWidget* parent = 0) : QWebInspector(parent) {}
signals:
void visibleChanged(bool nowVisible);
diff --git a/WebKitTools/QtTestBrowser/webview.cpp b/WebKitTools/QtTestBrowser/webview.cpp
index 242daf6..fffaf9c 100644
--- a/WebKitTools/QtTestBrowser/webview.cpp
+++ b/WebKitTools/QtTestBrowser/webview.cpp
@@ -59,9 +59,26 @@ WebViewGraphicsBased::WebViewGraphicsBased(QWidget* parent)
void WebViewGraphicsBased::setPage(QWebPage* page)
{
connect(page->mainFrame(), SIGNAL(contentsSizeChanged(const QSize&)), SLOT(contentsSizeChanged(const QSize&)));
+ connect(page, SIGNAL(scrollRequested(int, int, const QRect&)), SLOT(scrollRequested(int, int)));
graphicsWebView()->setPage(page);
}
+void WebViewGraphicsBased::scrollRequested(int x, int y)
+{
+ if (!m_resizesToContents)
+ return;
+
+ // Turn off interactive mode while scrolling, or QGraphicsView will replay the
+ // last mouse event which may cause WebKit to initiate a drag operation.
+ bool interactive = isInteractive();
+ setInteractive(false);
+
+ verticalScrollBar()->setValue(-y);
+ horizontalScrollBar()->setValue(-x);
+
+ setInteractive(interactive);
+}
+
void WebViewGraphicsBased::contentsSizeChanged(const QSize& size)
{
if (m_resizesToContents)
diff --git a/WebKitTools/QtTestBrowser/webview.h b/WebKitTools/QtTestBrowser/webview.h
index e34d081..240ea89 100644
--- a/WebKitTools/QtTestBrowser/webview.h
+++ b/WebKitTools/QtTestBrowser/webview.h
@@ -97,6 +97,7 @@ public slots:
void animatedFlip();
void animatedYFlip();
void contentsSizeChanged(const QSize&);
+ void scrollRequested(int, int);
signals:
void currentFPSUpdated(int fps);
diff --git a/WebKitTools/QueueStatusServer/__init__.py b/WebKitTools/QueueStatusServer/__init__.py
new file mode 100644
index 0000000..2346c23
--- /dev/null
+++ b/WebKitTools/QueueStatusServer/__init__.py
@@ -0,0 +1,29 @@
+# Required for Python to search this directory for module files
+
+# This __init__.py makes unit testing easier by allowing us to treat the entire server as one big module.
+# This file is only accessed when not on AppEngine itself.
+
+# Make sure that this module will load in that case by including paths to
+# the default Google AppEngine install.
+
+
+def fix_sys_path():
+ import sys
+ import os
+
+ # AppEngine imports a bunch of google-specific modules. Thankfully the dev_appserver
+ # knows how to do the same. Re-use the dev_appserver fix_sys_path logic to import
+ # all the google.appengine.* stuff so we can run under test-webkitpy
+ sys.path.append("/usr/local/google_appengine")
+ import dev_appserver
+ dev_appserver.fix_sys_path()
+
+ # test-webkitpy adds $WEBKIT/WebKitTools to the sys.path and imports
+ # QueueStatusServer to run all the tests. However, when AppEngine runs
+ # our code QueueStatusServer is the root (and thus in the path).
+ # Emulate that here for test-webkitpy so that we can import "model."
+ # not "QueueStatusServer.model.", etc.
+ sys.path.append(os.path.dirname(__file__))
+
+
+fix_sys_path()
diff --git a/WebKitTools/QueueStatusServer/handlers/queuestatus.py b/WebKitTools/QueueStatusServer/handlers/queuestatus.py
index 5c31537..54c0fdd 100644
--- a/WebKitTools/QueueStatusServer/handlers/queuestatus.py
+++ b/WebKitTools/QueueStatusServer/handlers/queuestatus.py
@@ -26,11 +26,12 @@
# (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 itertools
+
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from model.queues import Queue
-
from model import queuestatus
@@ -49,6 +50,12 @@ class QueueStatus(webapp.RequestHandler):
})
return rows
+ def _grouping_key_for_status(self, status):
+ return "%s-%s" % (status.active_patch_id, status.bot_id)
+
+ def _build_status_groups(self, statuses):
+ return [list(group) for key, group in itertools.groupby(statuses, self._grouping_key_for_status)]
+
def get(self, queue_name):
queue_name = queue_name.lower()
queue = Queue.queue_with_name(queue_name)
@@ -56,24 +63,10 @@ class QueueStatus(webapp.RequestHandler):
self.error(404)
return
- status_groups = []
- last_patch_id = None
- synthetic_patch_id_counter = 0
-
statuses = queuestatus.QueueStatus.all().filter("queue_name =", queue.name()).order("-date").fetch(15)
- for status in statuses:
- patch_id = status.active_patch_id
- if not patch_id or last_patch_id != patch_id:
- status_group = []
- status_groups.append(status_group)
- else:
- status_group = status_groups[-1]
- status_group.append(status)
- last_patch_id = patch_id
-
template_values = {
"display_queue_name": queue.display_name(),
"work_item_rows": self._rows_for_work_items(queue),
- "status_groups": status_groups,
+ "status_groups": self._build_status_groups(statuses),
}
self.response.out.write(template.render("templates/queuestatus.html", template_values))
diff --git a/WebKitTools/QueueStatusServer/handlers/queuestatus_unittest.py b/WebKitTools/QueueStatusServer/handlers/queuestatus_unittest.py
new file mode 100644
index 0000000..a5ae844
--- /dev/null
+++ b/WebKitTools/QueueStatusServer/handlers/queuestatus_unittest.py
@@ -0,0 +1,62 @@
+# 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 Research in Motion Ltd. 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 unittest
+
+from handlers.queuestatus import QueueStatus
+from model.queues import Queue
+
+
+class MockStatus(object):
+ def __init__(self, patch_id, bot_id):
+ self.active_patch_id = patch_id
+ self.bot_id = bot_id
+
+
+class QueueStatusTest(unittest.TestCase):
+ def test_build_status_groups(self):
+ queue_status = QueueStatus()
+ statuses = [
+ MockStatus(1, "foo"),
+ MockStatus(1, "foo"),
+ MockStatus(2, "foo"),
+ MockStatus(1, "foo"),
+ MockStatus(1, "bar"),
+ MockStatus(1, "foo"),
+ ]
+ groups = queue_status._build_status_groups(statuses)
+ self.assertEqual(len(groups), 5)
+ self.assertEqual(groups[0], statuses[0:2])
+ self.assertEqual(groups[1], statuses[2:3])
+ self.assertEqual(groups[2], statuses[3:4])
+ self.assertEqual(groups[3], statuses[4:5])
+ self.assertEqual(groups[4], statuses[5:6])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/QueueStatusServer/model/workitems.py b/WebKitTools/QueueStatusServer/model/workitems.py
index fae6830..772fc39 100644
--- a/WebKitTools/QueueStatusServer/model/workitems.py
+++ b/WebKitTools/QueueStatusServer/model/workitems.py
@@ -52,6 +52,7 @@ class WorkItems(db.Model, QueuePropertyMixin):
work_items.item_ids.append(attachment_id)
work_items.put()
+ # Because this uses .key() self.is_saved() must be True or this will throw NotSavedError.
def add_work_item(self, attachment_id):
db.run_in_transaction(self._unguarded_add, self.key(), attachment_id)
@@ -63,5 +64,6 @@ class WorkItems(db.Model, QueuePropertyMixin):
work_items.item_ids.remove(attachment_id)
work_items.put()
+ # Because this uses .key() self.is_saved() must be True or this will throw NotSavedError.
def remove_work_item(self, attachment_id):
db.run_in_transaction(self._unguarded_remove, self.key(), attachment_id)
diff --git a/WebKitTools/QueueStatusServer/model/workitems_unittest.py b/WebKitTools/QueueStatusServer/model/workitems_unittest.py
index d53302e..b1ff1d3 100644
--- a/WebKitTools/QueueStatusServer/model/workitems_unittest.py
+++ b/WebKitTools/QueueStatusServer/model/workitems_unittest.py
@@ -40,14 +40,6 @@ class WorkItemsTest(unittest.TestCase):
self.assertEquals(items.display_position_for_attachment(1), 2)
self.assertEquals(items.display_position_for_attachment(3), None)
- def test_remove_work_item(self):
- items = WorkItems()
- items.item_ids = [0, 1, 2]
- items.remove_work_item(0)
- self.assertEqual(items.item_ids, [1, 2])
- items.remove_work_item(4) # Should not throw
- self.assertEqual(items.item_ids, [1, 2])
-
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/QueueStatusServer/templates/includes/singlequeuestatus.html b/WebKitTools/QueueStatusServer/templates/includes/singlequeuestatus.html
index 075cd39..0adbfbd 100644
--- a/WebKitTools/QueueStatusServer/templates/includes/singlequeuestatus.html
+++ b/WebKitTools/QueueStatusServer/templates/includes/singlequeuestatus.html
@@ -1,4 +1,8 @@
-<span class="status-date">{{ status.date|timesince }} ago</span>
+<span class="status-date">{{ status.date|timesince }} ago
+{% if status.bot_id %}
+({{ status.bot_id }})
+{% endif %}
+</span>
<span class="status-message">{{ status.message|force_escape|urlize|webkit_linkify|safe }}</span>
{% if status.results_file %}
<span class="status-results">[{{ status.key.id|results_link|safe }}]</span>
diff --git a/WebKitTools/Scripts/check-webkit-style b/WebKitTools/Scripts/check-webkit-style
index e29d4b1..076c712 100755
--- a/WebKitTools/Scripts/check-webkit-style
+++ b/WebKitTools/Scripts/check-webkit-style
@@ -112,10 +112,11 @@ def main():
file_reader = TextFileReader(style_processor)
- if paths:
+ if paths and not options.diff_files:
file_reader.process_paths(paths)
else:
- patch = checkout.create_patch(options.git_commit)
+ changed_files = paths if options.diff_files else None
+ patch = checkout.create_patch(options.git_commit, changed_files=changed_files)
patch_checker = PatchReader(file_reader)
patch_checker.check(patch)
diff --git a/WebKitTools/Scripts/old-run-webkit-tests b/WebKitTools/Scripts/old-run-webkit-tests
index e40b3ad..2cef18b 100755
--- a/WebKitTools/Scripts/old-run-webkit-tests
+++ b/WebKitTools/Scripts/old-run-webkit-tests
@@ -373,6 +373,8 @@ if ($useWebKitTestRunner) {
}
}
+$timeoutSeconds *= 10 if $guardMalloc;
+
$stripEditingCallbacks = isCygwin() unless defined $stripEditingCallbacks;
my $ignoreSkipped = $treatSkipped eq "ignore";
@@ -1483,6 +1485,12 @@ sub openDumpTool()
unshift @args, "valgrind", "--suppressions=$platformBaseDirectory/qt/SuppressedValgrindErrors";
}
+ if ($useWebKitTestRunner) {
+ # Make WebKitTestRunner use a similar timeout. We don't use the exact same timeout to avoid
+ # race conditions.
+ push @args, "--timeout", $timeoutSeconds - 5;
+ }
+
$CLEAN_ENV{MallocStackLogging} = 1 if $shouldCheckLeaks;
$dumpToolPID = open3(\*OUT, \*IN, \*ERROR, launchWithEnv(@args, %CLEAN_ENV)) or die "Failed to start tool: $dumpTool\n";
@@ -2089,7 +2097,6 @@ sub readFromDumpToolWithTimer(**)
setFileHandleNonBlocking($fhError, 1);
my $maximumSecondsWithoutOutput = $timeoutSeconds;
- $maximumSecondsWithoutOutput *= 10 if $guardMalloc;
my $microsecondsToWaitBeforeReadingAgain = 1000;
my $timeOfLastSuccessfulRead = time;
diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
index 9b602c3..8aadcb8 100644
--- a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
+++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
@@ -64,7 +64,7 @@ def default_scm():
cwd = os.getcwd()
scm_system = detect_scm_system(cwd)
if not scm_system:
- script_directory = os.path.abspath(sys.path[0])
+ script_directory = os.path.dirname(os.path.abspath(__file__))
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))
diff --git a/WebKitTools/Scripts/webkitpy/common/config/committers.py b/WebKitTools/Scripts/webkitpy/common/config/committers.py
index 71d764c..446c2b1 100644
--- a/WebKitTools/Scripts/webkitpy/common/config/committers.py
+++ b/WebKitTools/Scripts/webkitpy/common/config/committers.py
@@ -112,6 +112,7 @@ committers_unable_to_review = [
Committer("Girish Ramakrishnan", ["girish@forwardbias.in", "ramakrishnan.girish@gmail.com"]),
Committer("Graham Dennis", ["Graham.Dennis@gmail.com", "gdennis@webkit.org"]),
Committer("Greg Bolsinga", "bolsinga@apple.com"),
+ Committer("Gyuyoung Kim", ["gyuyoung.kim@samsung.com", "gyuyoung@gmail.com", "gyuyoung@webkit.org"], "gyuyoung"),
Committer("Hans Wennborg", "hans@chromium.org", "hwennborg"),
Committer("Hayato Ito", "hayato@chromium.org", "hayato"),
Committer("Hin-Chung Lam", ["hclam@google.com", "hclam@chromium.org"]),
@@ -147,7 +148,7 @@ committers_unable_to_review = [
Committer("Luiz Agostini", ["luiz@webkit.org", "luiz.agostini@openbossa.org"], "lca"),
Committer("Mads Ager", "ager@chromium.org"),
Committer("Marcus Voltis Bulach", "bulach@chromium.org"),
- Committer("Mario Sanchez Prada", ["msanchez@igalia.com", "mario@webkit.org"]),
+ Committer("Mario Sanchez Prada", ["msanchez@igalia.com", "mario@webkit.org"], "msanchez"),
Committer("Matt Delaney", "mdelaney@apple.com"),
Committer("Matt Lilek", ["webkit@mattlilek.com", "pewtermoose@webkit.org"]),
Committer("Matt Perry", "mpcomplete@chromium.org"),
@@ -171,6 +172,7 @@ committers_unable_to_review = [
Committer("Philippe Normand", ["pnormand@igalia.com", "philn@webkit.org"], "philn-tp"),
Committer("Pierre d'Herbemont", ["pdherbemont@free.fr", "pdherbemont@apple.com"], "pdherbemont"),
Committer("Pierre-Olivier Latour", "pol@apple.com", "pol"),
+ Committer("Renata Hodovan", "reni@webkit.org", "reni"),
Committer("Robert Hogan", ["robert@webkit.org", "robert@roberthogan.net", "lists@roberthogan.net"], "mwenge"),
Committer("Roland Steiner", "rolandsteiner@chromium.org"),
Committer("Ryosuke Niwa", "rniwa@webkit.org", "rniwa"),
diff --git a/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py b/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py
index 1cc8e2e..a7dc1b7 100644
--- a/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py
+++ b/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py
@@ -281,7 +281,7 @@ class BugzillaQueries(object):
return sum([self._fetch_bug(bug_id).commit_queued_patches()
for bug_id in self.fetch_bug_ids_from_commit_queue()], [])
- def _fetch_bug_ids_from_review_queue(self):
+ def fetch_bug_ids_from_review_queue(self):
review_queue_url = "buglist.cgi?query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&field0-0-0=flagtypes.name&type0-0-0=equals&value0-0-0=review?"
return self._fetch_bug_ids_advanced_query(review_queue_url)
@@ -289,7 +289,7 @@ class BugzillaQueries(object):
def fetch_patches_from_review_queue(self, limit=None):
# [:None] returns the whole array.
return sum([self._fetch_bug(bug_id).unreviewed_patches()
- for bug_id in self._fetch_bug_ids_from_review_queue()[:limit]], [])
+ for bug_id in self.fetch_bug_ids_from_review_queue()[:limit]], [])
# NOTE: This is the only client of _fetch_attachment_ids_request_query
# This method only makes one request to bugzilla.
diff --git a/WebKitTools/Scripts/webkitpy/common/system/executive.py b/WebKitTools/Scripts/webkitpy/common/system/executive.py
index 216cf58..37f4e53 100644
--- a/WebKitTools/Scripts/webkitpy/common/system/executive.py
+++ b/WebKitTools/Scripts/webkitpy/common/system/executive.py
@@ -33,6 +33,7 @@ try:
except ImportError:
multiprocessing = None
+import ctypes
import errno
import logging
import os
@@ -44,6 +45,7 @@ import sys
import time
from webkitpy.common.system.deprecated_logging import tee
+from webkitpy.python24 import versioning
_log = logging.getLogger("webkitpy.common.system")
@@ -103,13 +105,8 @@ class Executive(object):
def _run_command_with_teed_output(self, args, teed_output):
args = map(unicode, args) # Popen will throw an exception if args are non-strings (like int())
- if sys.platform == 'cygwin':
- # Cygwin's Python's os.execv doesn't support unicode command
- # arguments, and neither does Cygwin's execv itself.
- # FIXME: Using UTF-8 here will confuse Windows-native commands
- # which will expect arguments to be encoded using the current code
- # page.
- args = [arg.encode('utf-8') for arg in args]
+ args = map(self._encode_argument_if_needed, args)
+
child_process = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
@@ -148,9 +145,8 @@ class Executive(object):
child_output = child_out_file.getvalue()
child_out_file.close()
- # We assume the child process output utf-8
if decode_output:
- child_output = child_output.decode("utf-8")
+ child_output = child_output.decode(self._child_process_encoding())
if exit_code:
raise ScriptError(script_args=args,
@@ -205,6 +201,55 @@ class Executive(object):
return
raise
+ def _win32_check_running_pid(self):
+
+ class PROCESSENTRY32(ctypes.Structure):
+ _fields_ = [("dwSize", ctypes.c_ulong),
+ ("cntUsage", ctypes.c_ulong),
+ ("th32ProcessID", ctypes.c_ulong),
+ ("th32DefaultHeapID", ctypes.c_ulong),
+ ("th32ModuleID", ctypes.c_ulong),
+ ("cntThreads", ctypes.c_ulong),
+ ("th32ParentProcessID", ctypes.c_ulong),
+ ("pcPriClassBase", ctypes.c_ulong),
+ ("dwFlags", ctypes.c_ulong),
+ ("szExeFile", ctypes.c_char * 260)]
+
+ CreateToolhelp32Snapshot = ctypes.windll.kernel32.CreateToolhelp32Snapshot
+ Process32First = ctypes.windll.kernel32.Process32First
+ Process32Next = ctypes.windll.kernel32.Process32Next
+ CloseHandle = ctypes.windll.kernel32.CloseHandle
+ TH32CS_SNAPPROCESS = 0x00000002 # win32 magic number
+ hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
+ pe32 = PROCESSENTRY32()
+ pe32.dwSize = ctypes.sizeof(PROCESSENTRY32)
+ result = False
+ if not Process32First(hProcessSnap, ctypes.byref(pe32)):
+ _log.debug("Failed getting first process.")
+ CloseHandle(hProcessSnap)
+ return result
+ while True:
+ if pe32.th32ProcessID == pid:
+ result = True
+ break
+ if not Process32Next(hProcessSnap, ctypes.byref(pe32)):
+ break
+ CloseHandle(hProcessSnap)
+ return result
+
+ def check_running_pid(self, pid):
+ """Return True if pid is alive, otherwise return False."""
+ if sys.platform in ('darwin', 'linux2', 'cygwin'):
+ try:
+ os.kill(pid, 0)
+ return True
+ except OSError:
+ return False
+ elif sys.platform == 'win32':
+ return self._win32_check_running_pid()
+
+ assert(False)
+
def _windows_image_name(self, process_name):
name, extension = os.path.splitext(process_name)
if not extension:
@@ -260,7 +305,7 @@ class Executive(object):
# for an example of a regresion caused by passing a unicode string directly.
# FIXME: We may need to encode differently on different platforms.
if isinstance(input, unicode):
- input = input.encode("utf-8")
+ input = input.encode(self._child_process_encoding())
return (subprocess.PIPE, input)
def _command_for_printing(self, args):
@@ -288,13 +333,8 @@ class Executive(object):
assert(isinstance(args, list) or isinstance(args, tuple))
start_time = time.time()
args = map(unicode, args) # Popen will throw an exception if args are non-strings (like int())
- if sys.platform == 'cygwin':
- # Cygwin's Python's os.execv doesn't support unicode command
- # arguments, and neither does Cygwin's execv itself.
- # FIXME: Using UTF-8 here will confuse Windows-native commands
- # which will expect arguments to be encoded using the current code
- # page.
- args = [arg.encode('utf-8') for arg in args]
+ args = map(self._encode_argument_if_needed, args)
+
stdin, string_to_communicate = self._compute_stdin(input)
stderr = subprocess.STDOUT if return_stderr else None
@@ -305,9 +345,11 @@ class Executive(object):
cwd=cwd,
close_fds=self._should_close_fds())
output = process.communicate(string_to_communicate)[0]
+
# run_command automatically decodes to unicode() unless explicitly told not to.
if decode_output:
- output = output.decode("utf-8")
+ output = output.decode(self._child_process_encoding())
+
# wait() is not threadsafe and can throw OSError due to:
# http://bugs.python.org/issue1731717
exit_code = process.wait()
@@ -324,3 +366,34 @@ class Executive(object):
cwd=cwd)
(error_handler or self.default_error_handler)(script_error)
return output
+
+ def _child_process_encoding(self):
+ # Win32 Python 2.x uses CreateProcessA rather than CreateProcessW
+ # to launch subprocesses, so we have to encode arguments using the
+ # current code page.
+ if sys.platform == 'win32' and versioning.compare_version(sys, '3.0')[0] < 0:
+ return 'mbcs'
+ # All other platforms use UTF-8.
+ # FIXME: Using UTF-8 on Cygwin will confuse Windows-native commands
+ # which will expect arguments to be encoded using the current code
+ # page.
+ return 'utf-8'
+
+ def _should_encode_child_process_arguments(self):
+ # Cygwin's Python's os.execv doesn't support unicode command
+ # arguments, and neither does Cygwin's execv itself.
+ if sys.platform == 'cygwin':
+ return True
+
+ # Win32 Python 2.x uses CreateProcessA rather than CreateProcessW
+ # to launch subprocesses, so we have to encode arguments using the
+ # current code page.
+ if sys.platform == 'win32' and versioning.compare_version(sys, '3.0')[0] < 0:
+ return True
+
+ return False
+
+ def _encode_argument_if_needed(self, argument):
+ if not self._should_encode_child_process_arguments():
+ return argument
+ return argument.encode(self._child_process_encoding())
diff --git a/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py b/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py
index 32f8f51..b8fd82e 100644
--- a/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py
@@ -27,12 +27,23 @@
# (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 signal
import subprocess
import sys
import unittest
from webkitpy.common.system.executive import Executive, run_command, ScriptError
+from webkitpy.test import cat, echo
+
+
+def never_ending_command():
+ """Arguments for a command that will never end (useful for testing process
+ killing). It should be a process that is unlikely to already be running
+ because all instances will be killed."""
+ if sys.platform == 'win32':
+ return ['wmic']
+ return ['yes']
class ExecutiveTest(unittest.TestCase):
@@ -46,46 +57,56 @@ class ExecutiveTest(unittest.TestCase):
executive = Executive()
self.assertRaises(AssertionError, executive.run_command, "echo")
self.assertRaises(AssertionError, executive.run_command, u"echo")
- executive.run_command(["echo", "foo"])
- executive.run_command(("echo", "foo"))
+ executive.run_command(echo.command_arguments('foo'))
+ executive.run_command(tuple(echo.command_arguments('foo')))
def test_run_command_with_unicode(self):
"""Validate that it is safe to pass unicode() objects
to Executive.run* methods, and they will return unicode()
objects by default unless decode_output=False"""
+ unicode_tor_input = u"WebKit \u2661 Tor Arne Vestb\u00F8!"
+ if sys.platform == 'win32':
+ encoding = 'mbcs'
+ else:
+ encoding = 'utf-8'
+ encoded_tor = unicode_tor_input.encode(encoding)
+ # On Windows, we expect the unicode->mbcs->unicode roundtrip to be
+ # lossy. On other platforms, we expect a lossless roundtrip.
+ if sys.platform == 'win32':
+ unicode_tor_output = encoded_tor.decode(encoding)
+ else:
+ unicode_tor_output = unicode_tor_input
+
executive = Executive()
- unicode_tor = u"WebKit \u2661 Tor Arne Vestb\u00F8!"
- utf8_tor = unicode_tor.encode("utf-8")
- output = executive.run_command(["cat"], input=unicode_tor)
- self.assertEquals(output, unicode_tor)
+ output = executive.run_command(cat.command_arguments(), input=unicode_tor_input)
+ self.assertEquals(output, unicode_tor_output)
- output = executive.run_command(["echo", "-n", unicode_tor])
- self.assertEquals(output, unicode_tor)
+ output = executive.run_command(echo.command_arguments("-n", unicode_tor_input))
+ self.assertEquals(output, unicode_tor_output)
- output = executive.run_command(["echo", "-n", unicode_tor], decode_output=False)
- self.assertEquals(output, utf8_tor)
+ output = executive.run_command(echo.command_arguments("-n", unicode_tor_input), decode_output=False)
+ self.assertEquals(output, encoded_tor)
# Make sure that str() input also works.
- output = executive.run_command(["cat"], input=utf8_tor, decode_output=False)
- self.assertEquals(output, utf8_tor)
+ output = executive.run_command(cat.command_arguments(), input=encoded_tor, decode_output=False)
+ self.assertEquals(output, encoded_tor)
# FIXME: We should only have one run* method to test
- output = executive.run_and_throw_if_fail(["echo", "-n", unicode_tor], quiet=True)
- self.assertEquals(output, unicode_tor)
+ output = executive.run_and_throw_if_fail(echo.command_arguments("-n", unicode_tor_input), quiet=True)
+ self.assertEquals(output, unicode_tor_output)
- output = executive.run_and_throw_if_fail(["echo", "-n", unicode_tor], quiet=True, decode_output=False)
- self.assertEquals(output, utf8_tor)
+ output = executive.run_and_throw_if_fail(echo.command_arguments("-n", unicode_tor_input), quiet=True, decode_output=False)
+ self.assertEquals(output, encoded_tor)
def test_kill_process(self):
executive = Executive()
- # We use "yes" because it loops forever.
- process = subprocess.Popen(["yes"], stdout=subprocess.PIPE)
+ process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE)
self.assertEqual(process.poll(), None) # Process is running
executive.kill_process(process.pid)
# Note: Can't use a ternary since signal.SIGKILL is undefined for sys.platform == "win32"
if sys.platform == "win32":
- expected_exit_code = 0 # taskkill.exe results in exit(0)
+ expected_exit_code = 1
else:
expected_exit_code = -signal.SIGKILL
self.assertEqual(process.wait(), expected_exit_code)
@@ -109,14 +130,22 @@ class ExecutiveTest(unittest.TestCase):
def test_kill_all(self):
executive = Executive()
# We use "yes" because it loops forever.
- process = subprocess.Popen(["yes"], stdout=subprocess.PIPE)
+ process = subprocess.Popen(never_ending_command(), stdout=subprocess.PIPE)
self.assertEqual(process.poll(), None) # Process is running
- executive.kill_all("yes")
+ executive.kill_all(never_ending_command()[0])
# Note: Can't use a ternary since signal.SIGTERM is undefined for sys.platform == "win32"
- if sys.platform in ("win32", "cygwin"):
- expected_exit_code = 0 # taskkill.exe results in exit(0)
+ if sys.platform == "cygwin":
+ expected_exit_code = 0 # os.kill results in exit(0) for this process.
+ elif sys.platform == "win32":
+ expected_exit_code = 1
else:
expected_exit_code = -signal.SIGTERM
self.assertEqual(process.wait(), expected_exit_code)
# Killing again should fail silently.
- executive.kill_all("yes")
+ executive.kill_all(never_ending_command()[0])
+
+ def test_check_running_pid(self):
+ executive = Executive()
+ self.assertTrue(executive.check_running_pid(os.getpid()))
+ # Maximum pid number on Linux is 32768 by default
+ self.assertFalse(executive.check_running_pid(100000))
diff --git a/WebKitTools/Scripts/webkitpy/common/system/filesystem.py b/WebKitTools/Scripts/webkitpy/common/system/filesystem.py
new file mode 100644
index 0000000..c7efde3
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/common/system/filesystem.py
@@ -0,0 +1,117 @@
+# 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.
+
+"""Wrapper object for the file system / source tree."""
+
+from __future__ import with_statement
+
+import codecs
+import errno
+import os
+import tempfile
+
+
+class FileSystem(object):
+ """FileSystem interface for webkitpy.
+
+ Unless otherwise noted, all paths are allowed to be either absolute
+ or relative."""
+
+ def exists(self, path):
+ """Return whether the path exists in the filesystem."""
+ return os.path.exists(path)
+
+ def isdir(self, path):
+ """Return whether the path refers to a directory."""
+ return os.path.isdir(path)
+
+ def join(self, *comps):
+ """Return the path formed by joining the components."""
+ return os.path.join(*comps)
+
+ def listdir(self, path):
+ """Return the contents of the directory pointed to by path."""
+ return os.listdir(path)
+
+ def mkdtemp(self, **kwargs):
+ """Create and return a uniquely named directory.
+
+ This is like tempfile.mkdtemp, but if used in a with statement
+ the directory will self-delete at the end of the block (if the
+ directory is empty; non-empty directories raise errors). The
+ directory can be safely deleted inside the block as well, if so
+ desired."""
+ class TemporaryDirectory(object):
+ def __init__(self, **kwargs):
+ self._kwargs = kwargs
+ self._directory_path = None
+
+ def __enter__(self):
+ self._directory_path = tempfile.mkdtemp(**self._kwargs)
+ return self._directory_path
+
+ def __exit__(self, type, value, traceback):
+ # Only self-delete if necessary.
+
+ # FIXME: Should we delete non-empty directories?
+ if os.path.exists(self._directory_path):
+ os.rmdir(self._directory_path)
+
+ return TemporaryDirectory(**kwargs)
+
+ def maybe_make_directory(self, *path):
+ """Create the specified directory if it doesn't already exist."""
+ try:
+ os.makedirs(os.path.join(*path))
+ except OSError, e:
+ if e.errno != errno.EEXIST:
+ raise
+
+ def read_binary_file(self, path):
+ """Return the contents of the file at the given path as a byte string."""
+ with file(path, 'rb') as f:
+ return f.read()
+
+ def read_text_file(self, path):
+ """Return the contents of the file at the given path as a Unicode string.
+
+ The file is read assuming it is a UTF-8 encoded file with no BOM."""
+ with codecs.open(path, 'r', 'utf8') as f:
+ return f.read()
+
+ def write_binary_file(self, path, contents):
+ """Write the contents to the file at the given location."""
+ with file(path, 'wb') as f:
+ f.write(contents)
+
+ def write_text_file(self, path, contents):
+ """Write the contents to the file at the given location.
+
+ The file is written encoded as UTF-8 with no BOM."""
+ with codecs.open(path, 'w', 'utf8') as f:
+ f.write(contents)
diff --git a/WebKitTools/Scripts/webkitpy/common/system/filesystem_unittest.py b/WebKitTools/Scripts/webkitpy/common/system/filesystem_unittest.py
new file mode 100644
index 0000000..95684b7
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/common/system/filesystem_unittest.py
@@ -0,0 +1,157 @@
+# vim: set fileencoding=utf-8 :
+# 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.
+
+# NOTE: The fileencoding comment on the first line of the file is
+# important; without it, Python will choke while trying to parse the file,
+# since it includes non-ASCII characters.
+
+from __future__ import with_statement
+
+import os
+import stat
+import sys
+import tempfile
+import unittest
+
+from filesystem import FileSystem
+
+
+class FileSystemTest(unittest.TestCase):
+ def setUp(self):
+ self._this_dir = os.path.dirname(os.path.abspath(__file__))
+ self._missing_file = os.path.join(self._this_dir, 'missing_file.py')
+ self._this_file = os.path.join(self._this_dir, 'filesystem_unittest.py')
+
+ def test_exists__true(self):
+ fs = FileSystem()
+ self.assertTrue(fs.exists(self._this_file))
+
+ def test_exists__false(self):
+ fs = FileSystem()
+ self.assertFalse(fs.exists(self._missing_file))
+
+ def test_isdir__true(self):
+ fs = FileSystem()
+ self.assertTrue(fs.isdir(self._this_dir))
+
+ def test_isdir__false(self):
+ fs = FileSystem()
+ self.assertFalse(fs.isdir(self._this_file))
+
+ def test_join(self):
+ fs = FileSystem()
+ self.assertEqual(fs.join('foo', 'bar'),
+ os.path.join('foo', 'bar'))
+
+ def test_listdir(self):
+ fs = FileSystem()
+ with fs.mkdtemp(prefix='filesystem_unittest_') as d:
+ self.assertEqual(fs.listdir(d), [])
+ new_file = os.path.join(d, 'foo')
+ fs.write_text_file(new_file, u'foo')
+ self.assertEqual(fs.listdir(d), ['foo'])
+ os.remove(new_file)
+
+ def test_maybe_make_directory__success(self):
+ fs = FileSystem()
+
+ with fs.mkdtemp(prefix='filesystem_unittest_') as base_path:
+ sub_path = os.path.join(base_path, "newdir")
+ self.assertFalse(os.path.exists(sub_path))
+ self.assertFalse(fs.isdir(sub_path))
+
+ fs.maybe_make_directory(sub_path)
+ self.assertTrue(os.path.exists(sub_path))
+ self.assertTrue(fs.isdir(sub_path))
+
+ # Make sure we can re-create it.
+ fs.maybe_make_directory(sub_path)
+ self.assertTrue(os.path.exists(sub_path))
+ self.assertTrue(fs.isdir(sub_path))
+
+ # Clean up.
+ os.rmdir(sub_path)
+
+ self.assertFalse(os.path.exists(base_path))
+ self.assertFalse(fs.isdir(base_path))
+
+ def test_maybe_make_directory__failure(self):
+ # FIXME: os.chmod() doesn't work on Windows to set directories
+ # as readonly, so we skip this test for now.
+ if sys.platform in ('win32', 'cygwin'):
+ return
+
+ fs = FileSystem()
+ with fs.mkdtemp(prefix='filesystem_unittest_') as d:
+ # Remove write permissions on the parent directory.
+ os.chmod(d, stat.S_IRUSR)
+
+ # Now try to create a sub directory - should fail.
+ sub_dir = fs.join(d, 'subdir')
+ self.assertRaises(OSError, fs.maybe_make_directory, sub_dir)
+
+ # Clean up in case the test failed and we did create the
+ # directory.
+ if os.path.exists(sub_dir):
+ os.rmdir(sub_dir)
+
+ def test_read_and_write_file(self):
+ fs = FileSystem()
+ text_path = None
+ binary_path = None
+
+ unicode_text_string = u'Ūnĭcōde̽'
+ hex_equivalent = '\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD'
+ try:
+ text_path = tempfile.mktemp(prefix='tree_unittest_')
+ binary_path = tempfile.mktemp(prefix='tree_unittest_')
+ fs.write_text_file(text_path, unicode_text_string)
+ contents = fs.read_binary_file(text_path)
+ self.assertEqual(contents, hex_equivalent)
+
+ fs.write_text_file(binary_path, hex_equivalent)
+ text_contents = fs.read_text_file(binary_path)
+ self.assertEqual(text_contents, unicode_text_string)
+ except:
+ if text_path:
+ os.remove(text_path)
+ if binary_path:
+ os.remove(binary_path)
+
+ def test_read_binary_file__missing(self):
+ fs = FileSystem()
+ self.assertRaises(IOError, fs.read_binary_file, self._missing_file)
+
+ def test_read_text_file__missing(self):
+ fs = FileSystem()
+ self.assertRaises(IOError, fs.read_text_file, self._missing_file)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/common/system/fileutils.py b/WebKitTools/Scripts/webkitpy/common/system/fileutils.py
new file mode 100644
index 0000000..55821f8
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/common/system/fileutils.py
@@ -0,0 +1,33 @@
+# 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.
+
+import sys
+
+
+def make_stdout_binary():
+ """Puts sys.stdout into binary mode (on platforms that have a distinction
+ between text and binary mode)."""
+ if sys.platform != 'win32' or not hasattr(sys.stdout, 'fileno'):
+ return
+ import msvcrt
+ import os
+ msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
diff --git a/WebKitTools/Scripts/webkitpy/common/system/path.py b/WebKitTools/Scripts/webkitpy/common/system/path.py
index 43c6410..09787d7 100644
--- a/WebKitTools/Scripts/webkitpy/common/system/path.py
+++ b/WebKitTools/Scripts/webkitpy/common/system/path.py
@@ -44,7 +44,7 @@ def abspath_to_uri(path, platform=None):
def cygpath(path):
- """Converts a cygwin path to Windows path."""
+ """Converts an absolute cygwin path to an absolute Windows path."""
return _CygPath.convert_using_singleton(path)
@@ -103,7 +103,11 @@ class _CygPath(object):
self.start()
self._child_process.stdin.write("%s\r\n" % path)
self._child_process.stdin.flush()
- return self._child_process.stdout.readline().rstrip()
+ windows_path = self._child_process.stdout.readline().rstrip()
+ # Some versions of cygpath use lowercase drive letters while others
+ # use uppercase. We always convert to uppercase for consistency.
+ windows_path = '%s%s' % (windows_path[0].upper(), windows_path[1:])
+ return windows_path
def _escape(path):
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 3e3ba0b..9f2de7e 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
@@ -341,7 +341,7 @@ class TestShellThread(WatchableThread):
def cancel(self):
"""Clean up http lock and set a flag telling this thread to quit."""
- self._stop_http_lock()
+ self._stop_servers_with_lock()
WatchableThread.cancel(self)
def next_timeout(self):
@@ -389,23 +389,15 @@ class TestShellThread(WatchableThread):
self._current_group, self._filename_list = \
self._filename_list_queue.get_nowait()
except Queue.Empty:
- self._stop_http_lock()
+ self._stop_servers_with_lock()
self._kill_dump_render_tree()
tests_run_file.close()
return
- if self._options.wait_for_httpd:
- if self._current_group == "tests_to_http_lock":
- self._http_lock_wait_begin = time.time()
- self._port.acquire_http_lock()
-
- self._port.start_http_server()
- self._port.start_websocket_server()
-
- self._have_http_lock = True
- self._http_lock_wait_end = time.time()
- elif self._have_http_lock:
- self._stop_http_lock()
+ if self._current_group == "tests_to_http_lock":
+ self._start_servers_with_lock()
+ elif self._have_http_lock:
+ self._stop_servers_with_lock()
self._num_tests_in_current_group = len(self._filename_list)
self._current_group_start_time = time.time()
@@ -440,7 +432,7 @@ class TestShellThread(WatchableThread):
self._port.relative_test_filename(filename)))
self._result_queue.put(result.dumps())
- if batch_size > 0 and batch_count > batch_size:
+ if batch_size > 0 and batch_count >= batch_size:
# Bounce the shell and reset count.
self._kill_dump_render_tree()
batch_count = 0
@@ -545,11 +537,26 @@ class TestShellThread(WatchableThread):
self._options)
self._driver.start()
- def _stop_http_lock(self):
+ def _start_servers_with_lock(self):
+ """Acquire http lock and start the servers."""
+ self._http_lock_wait_begin = time.time()
+ _log.debug('Acquire http lock ...')
+ self._port.acquire_http_lock()
+ _log.debug('Starting HTTP server ...')
+ self._port.start_http_server()
+ _log.debug('Starting WebSocket server ...')
+ self._port.start_websocket_server()
+ self._http_lock_wait_end = time.time()
+ self._have_http_lock = True
+
+ def _stop_servers_with_lock(self):
"""Stop the servers and release http lock."""
if self._have_http_lock:
+ _log.debug('Stopping HTTP server ...')
self._port.stop_http_server()
+ _log.debug('Stopping WebSocket server ...')
self._port.stop_websocket_server()
+ _log.debug('Release http lock ...')
self._port.release_http_lock()
self._have_http_lock = False
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
index cd7d663..a98b858 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
@@ -47,6 +47,7 @@ import http_server
import test_files
import websocket_server
+from webkitpy.common.memoized import memoized
from webkitpy.common.system import logutils
from webkitpy.common.system.executive import Executive, ScriptError
from webkitpy.common.system.path import abspath_to_uri
@@ -725,13 +726,25 @@ class Port(object):
e.message_with_output()))
return self._pretty_patch_error_html
- def _webkit_build_directory(self, args):
- args = ["perl", self.script_path("webkit-build-directory")] + args
+ def _webkit_build_directory_command(self, args):
+ return ["perl", self.script_path("webkit-build-directory")] + args
+
+ @memoized
+ def _webkit_top_level_build_directory(self, top_level=True):
+ """This directory is above where products are built to and contains things like the Configuration file."""
+ args = self._webkit_build_directory_command(["--top-level"])
+ return self._executive.run_command(args).rstrip()
+
+ @memoized
+ def _webkit_configuration_build_directory(self, configuration=None):
+ """This is where products are normally built to."""
+ if not configuration:
+ configuration = self.flag_from_configuration(self.get_option('configuration'))
+ args = self._webkit_build_directory_command(["--configuration", configuration])
return self._executive.run_command(args).rstrip()
def _configuration_file_path(self):
- build_root = self._webkit_build_directory(["--top-level"])
- return os.path.join(build_root, "Configuration")
+ return os.path.join(self._webkit_top_level_build_directory(), "Configuration")
# Easy override for unit tests
def _open_configuration_file(self):
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py
index 5d28fae..57b6989 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py
@@ -71,6 +71,8 @@ def _set_gpu_options(options):
options.accelerated_2d_canvas = True
if options.builder_name is not None:
options.builder_name = options.builder_name + ' - GPU'
+ if options.use_drt is None:
+ options.use_drt = True
def _gpu_overrides(port):
@@ -96,6 +98,9 @@ class ChromiumGpuLinuxPort(chromium_linux.ChromiumLinuxPort):
return (map(self._webkit_baseline_path, ['chromium-gpu-linux', 'chromium-gpu-win', 'chromium-gpu']) +
chromium_linux.ChromiumLinuxPort.baseline_search_path(self))
+ def default_child_processes(self):
+ return 1
+
def path_to_test_expectations_file(self):
return self.path_from_webkit_base('LayoutTests', 'platform',
'chromium-gpu', 'test_expectations.txt')
@@ -114,6 +119,9 @@ class ChromiumGpuMacPort(chromium_mac.ChromiumMacPort):
return (map(self._webkit_baseline_path, ['chromium-gpu-mac', 'chromium-gpu']) +
chromium_mac.ChromiumMacPort.baseline_search_path(self))
+ def default_child_processes(self):
+ return 1
+
def path_to_test_expectations_file(self):
return self.path_from_webkit_base('LayoutTests', 'platform',
'chromium-gpu', 'test_expectations.txt')
@@ -132,6 +140,9 @@ class ChromiumGpuWinPort(chromium_win.ChromiumWinPort):
return (map(self._webkit_baseline_path, ['chromium-gpu-win', 'chromium-gpu']) +
chromium_win.ChromiumWinPort.baseline_search_path(self))
+ def default_child_processes(self):
+ return 1
+
def path_to_test_expectations_file(self):
return self.path_from_webkit_base('LayoutTests', 'platform',
'chromium-gpu', 'test_expectations.txt')
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py
index 88524fc..03bc98a 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py
@@ -45,10 +45,14 @@ class ChromiumGpuTest(unittest.TestCase):
# test that we got the right port
mock_options = mocktool.MockOptions(accelerated_compositing=None,
accelerated_2d_canvas=None,
- builder_name='foo')
+ builder_name='foo',
+ use_drt=None,
+ child_processes=None)
port = chromium_gpu.get(port_name=port_name, options=mock_options)
self.assertTrue(port._options.accelerated_compositing)
self.assertTrue(port._options.accelerated_2d_canvas)
+ self.assertTrue(port._options.use_drt)
+ self.assertEqual(port.default_child_processes(), 1)
self.assertEqual(port._options.builder_name, 'foo - GPU')
# we use startswith() instead of Equal to gloss over platform versions.
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/config.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/config.py
new file mode 100644
index 0000000..2364098
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/config.py
@@ -0,0 +1,154 @@
+#!/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.
+
+"""Wrapper objects for WebKit-specific utility routines."""
+
+# FIXME: This file needs to be unified with common/checkout/scm.py and
+# common/config/ports.py .
+
+from __future__ import with_statement
+
+import codecs
+import os
+
+from webkitpy.common.checkout import scm
+from webkitpy.common.system import logutils
+
+
+_log = logutils.get_logger(__file__)
+
+#
+# This is used to record if we've already hit the filesystem to look
+# for a default configuration. We cache this to speed up the unit tests,
+# but this can be reset with clear_cached_configuration().
+#
+_determined_configuration = None
+
+
+def clear_cached_configuration():
+ global _determined_configuration
+ _determined_configuration = -1
+
+
+class Config(object):
+ _FLAGS_FROM_CONFIGURATIONS = {
+ "Debug": "--debug",
+ "Release": "--release",
+ }
+
+ def __init__(self, executive):
+ self._executive = executive
+ self._webkit_base_dir = None
+ self._default_configuration = None
+ self._build_directories = {}
+
+ def build_directory(self, configuration):
+ """Returns the path to the build directory for the configuration."""
+ if configuration:
+ flags = ["--configuration",
+ self._FLAGS_FROM_CONFIGURATIONS[configuration]]
+ configuration = ""
+ else:
+ configuration = ""
+ flags = ["--top-level"]
+
+ if not self._build_directories.get(configuration):
+ args = ["perl", self._script_path("webkit-build-directory")] + flags
+ self._build_directories[configuration] = (
+ self._executive.run_command(args).rstrip())
+
+ return self._build_directories[configuration]
+
+ def build_dumprendertree(self, configuration):
+ """Builds DRT in the given configuration.
+
+ Returns True if the build was successful and up-to-date."""
+ flag = self._FLAGS_FROM_CONFIGURATIONS[configuration]
+ exit_code = self._executive.run_command([
+ self._script_path("build-dumprendertree"), flag],
+ return_exit_code=True)
+ if exit_code != 0:
+ _log.error("Failed to build DumpRenderTree")
+ return False
+ return True
+
+ def default_configuration(self):
+ """Returns the default configuration for the user.
+
+ Returns the value set by 'set-webkit-configuration', or "Release"
+ if that has not been set. This mirrors the logic in webkitdirs.pm."""
+ if not self._default_configuration:
+ self._default_configuration = self._determine_configuration()
+ if not self._default_configuration:
+ self._default_configuration = 'Release'
+ if self._default_configuration not in self._FLAGS_FROM_CONFIGURATIONS:
+ _log.warn("Configuration \"%s\" is not a recognized value.\n" %
+ self._default_configuration)
+ _log.warn("Scripts may fail. "
+ "See 'set-webkit-configuration --help'.")
+ return self._default_configuration
+
+ def path_from_webkit_base(self, *comps):
+ return os.path.join(self.webkit_base_dir(), *comps)
+
+ def webkit_base_dir(self):
+ """Returns the absolute path to the top of the WebKit tree.
+
+ Raises an AssertionError if the top dir can't be determined."""
+ # FIXME: Consider determining this independently of scm in order
+ # to be able to run in a bare tree.
+ if not self._webkit_base_dir:
+ self._webkit_base_dir = scm.find_checkout_root()
+ assert self._webkit_base_dir, "Could not determine the top of the WebKit checkout"
+ return self._webkit_base_dir
+
+ def _script_path(self, script_name):
+ return os.path.join(self.webkit_base_dir(), "WebKitTools",
+ "Scripts", script_name)
+
+ def _determine_configuration(self):
+ # This mirrors the logic in webkitdirs.pm:determineConfiguration().
+ global _determined_configuration
+ if _determined_configuration == -1:
+ contents = self._read_configuration()
+ if contents == "Deployment":
+ contents = "Release"
+ if contents == "Development":
+ contents = "Debug"
+ _determined_configuration = contents
+ return _determined_configuration
+
+ def _read_configuration(self):
+ configuration_path = os.path.join(self.build_directory(None),
+ "Configuration")
+ if not os.path.exists(configuration_path):
+ return None
+
+ with codecs.open(configuration_path, "r", "utf-8") as fh:
+ return fh.read().rstrip()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py
new file mode 100644
index 0000000..4674cba
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py
@@ -0,0 +1,176 @@
+# 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 codecs
+import os
+import StringIO
+import unittest
+
+from webkitpy.common.system import outputcapture
+
+import config
+
+
+# FIXME: This makes StringIO objects work with "with". Remove
+# when we upgrade to 2.6.
+class NewStringIO(StringIO.StringIO):
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ pass
+
+
+class MockExecutive(object):
+ def __init__(self, output='', exit_code=0):
+ self._output = output
+ self._exit_code = exit_code
+
+ def run_command(self, arg_list, return_exit_code=False,
+ decode_output=False):
+ if return_exit_code:
+ return self._exit_code
+ return self._output
+
+
+class ConfigTest(unittest.TestCase):
+ def tearDown(self):
+ config.clear_cached_configuration()
+
+ def assertConfiguration(self, contents, expected):
+ # This tests that a configuration file containing
+ # _contents_ endsd up being interpreted as _expected_.
+ #
+ # FIXME: rewrite this when we have a filesystem abstraction we
+ # can mock out more easily.
+ config.clear_cached_configuration()
+ orig_open = codecs.open
+
+ def wrap_open(contents):
+ def open_wrapper(path, mode, encoding):
+ return NewStringIO(contents)
+ return open_wrapper
+
+ try:
+ orig_exists = os.path.exists
+ os.path.exists = lambda p: True
+ codecs.open = wrap_open(contents)
+
+ e = MockExecutive(output='foo')
+ c = config.Config(e)
+ self.assertEqual(c.default_configuration(), expected)
+ finally:
+ os.path.exists = orig_exists
+ codecs.open = orig_open
+
+ def test_build_directory_toplevel(self):
+ e = MockExecutive(output="toplevel")
+ c = config.Config(e)
+ self.assertEqual(c.build_directory(None), 'toplevel')
+
+ # Test again to check caching
+ self.assertEqual(c.build_directory(None), 'toplevel')
+
+ def test_build_directory__release(self):
+ e = MockExecutive(output="release")
+ c = config.Config(e)
+ self.assertEqual(c.build_directory('Release'), 'release')
+
+ def test_build_directory__debug(self):
+ e = MockExecutive(output="debug")
+ c = config.Config(e)
+ self.assertEqual(c.build_directory('Debug'), 'debug')
+
+ def test_build_directory__unknown(self):
+ e = MockExecutive(output="unknown")
+ c = config.Config(e)
+ self.assertRaises(KeyError, c.build_directory, 'Unknown')
+
+ def test_build_dumprendertree__success(self):
+ e = MockExecutive(exit_code=0)
+ c = config.Config(e)
+ self.assertTrue(c.build_dumprendertree("Debug"))
+ self.assertTrue(c.build_dumprendertree("Release"))
+ self.assertRaises(KeyError, c.build_dumprendertree, "Unknown")
+
+ def test_build_dumprendertree__failure(self):
+ e = MockExecutive(exit_code=-1)
+ c = config.Config(e)
+
+ oc = outputcapture.OutputCapture()
+ oc.capture_output()
+ self.assertFalse(c.build_dumprendertree('Debug'))
+ (out, err) = oc.restore_output()
+
+ oc.capture_output()
+ self.assertFalse(c.build_dumprendertree('Release'))
+ oc.restore_output()
+
+ def test_default_configuration__release(self):
+ self.assertConfiguration('Release', 'Release')
+
+ def test_default_configuration__debug(self):
+ self.assertConfiguration('Debug', 'Debug')
+
+ def test_default_configuration__deployment(self):
+ self.assertConfiguration('Deployment', 'Release')
+
+ def test_default_configuration__development(self):
+ self.assertConfiguration('Development', 'Debug')
+
+ def test_default_configuration__notfound(self):
+ # This tests what happens if the default configuration file
+ # doesn't exist.
+ config.clear_cached_configuration()
+ try:
+ orig_exists = os.path.exists
+ os.path.exists = lambda p: False
+ e = MockExecutive(output="foo")
+ c = config.Config(e)
+ self.assertEqual(c.default_configuration(), "Release")
+ finally:
+ os.path.exists = orig_exists
+
+ def test_default_configuration__unknown(self):
+ # Ignore the warning about an unknown configuration value.
+ oc = outputcapture.OutputCapture()
+ oc.capture_output()
+ self.assertConfiguration('Unknown', 'Unknown')
+ oc.restore_output()
+
+ def test_path_from_webkit_base(self, *comps):
+ c = config.Config(None)
+ self.assertTrue(c.path_from_webkit_base('foo'))
+
+ def test_webkit_base_dir(self):
+ c = config.Config(None)
+ self.assertTrue(c.webkit_base_dir())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py
index b2615a3..d65801d 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py
@@ -29,27 +29,38 @@
http and websocket tests in a same time."""
import glob
+import logging
import os
import sys
import tempfile
import time
+from webkitpy.common.system.executive import Executive
+
+
+_log = logging.getLogger("webkitpy.layout_tests.port.http_lock")
+
class HttpLock(object):
def __init__(self, lock_path, lock_file_prefix="WebKitHttpd.lock.",
guard_lock="WebKit.lock"):
- if not lock_path:
+ self._lock_path = lock_path
+ if not self._lock_path:
self._lock_path = tempfile.gettempdir()
self._lock_file_prefix = lock_file_prefix
self._lock_file_path_prefix = os.path.join(self._lock_path,
self._lock_file_prefix)
self._guard_lock_file = os.path.join(self._lock_path, guard_lock)
self._process_lock_file_name = ""
+ self._executive = Executive()
+ # maximum wait time for the lock creation
+ self._guard_lock_max_wait = 1 * 60
def cleanup_http_lock(self):
"""Delete the lock file if exists."""
if os.path.exists(self._process_lock_file_name):
+ _log.debug("Removing lock file: %s" % self._process_lock_file_name)
os.unlink(self._process_lock_file_name)
def _extract_lock_number(self, lock_file_name):
@@ -70,17 +81,6 @@ class HttpLock(object):
return 0
return self._extract_lock_number(lock_list[-1]) + 1
- def _check_pid(self, current_pid):
- """Return True if pid is alive, otherwise return False.
- FIXME: os.kill() doesn't work on Windows for checking if
- a pid is alive, so always return True"""
- if sys.platform in ('darwin', 'linux2'):
- try:
- os.kill(current_pid, 0)
- except OSError:
- return False
- return True
-
def _curent_lock_pid(self):
"""Return with the current lock pid. If the lock is not valid
it deletes the lock file."""
@@ -91,7 +91,8 @@ class HttpLock(object):
current_lock_file = open(lock_list[0], 'r')
current_pid = current_lock_file.readline()
current_lock_file.close()
- if not (current_pid and self._check_pid(int(current_pid))):
+ if not (current_pid and self._executive.check_running_pid(int(current_pid))):
+ _log.debug("Removing stuck lock file: %s" % lock_list[0])
os.unlink(lock_list[0])
return
except IOError, OSError:
@@ -102,22 +103,34 @@ class HttpLock(object):
"""The lock files are used to schedule the running test sessions in first
come first served order. The sequential guard lock ensures that the lock
numbers are sequential."""
+ if not os.path.exists(self._lock_path):
+ _log.debug("Lock directory does not exist: %s" % self._lock_path)
+ return False
+
+ start_time = time.time()
while(True):
try:
sequential_guard_lock = os.open(self._guard_lock_file, os.O_CREAT | os.O_EXCL)
self._process_lock_file_name = (self._lock_file_path_prefix +
str(self._next_lock_number()))
lock_file = open(self._process_lock_file_name, 'w')
+ _log.debug("Creating lock file: %s" % self._process_lock_file_name)
lock_file.write(str(os.getpid()))
lock_file.close()
os.close(sequential_guard_lock)
os.unlink(self._guard_lock_file)
- break
+ return True
except OSError:
- pass
+ if time.time() - start_time > self._guard_lock_max_wait:
+ _log.debug("Lock does not created: %s" % str(sys.exc_info()))
+ return False
def wait_for_httpd_lock(self):
- """Create a lock file and wait until it's turn comes."""
- self._create_lock_file()
+ """Create a lock file and wait until it's turn comes. If something goes wrong
+ it wont do any locking."""
+ if not self._create_lock_file():
+ _log.debug("Warning, http locking failed!")
+ return
+
while self._curent_lock_pid() != os.getpid():
time.sleep(1)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py
index 0d0d3e0..0b324f5 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py
@@ -60,7 +60,6 @@ class WebKitPort(base.Port):
def __init__(self, **kwargs):
base.Port.__init__(self, **kwargs)
- self._cached_build_root = None
self._cached_apache_path = None
# FIXME: disable pixel tests until they are run by default on the
@@ -358,12 +357,8 @@ class WebKitPort(base.Port):
'mac-tiger', 'mac-leopard', 'mac-snowleopard')
def _build_path(self, *comps):
- if not self._cached_build_root:
- self._cached_build_root = self._webkit_build_directory([
- "--configuration",
- self.flag_from_configuration(self.get_option('configuration')),
- ])
- return os.path.join(self._cached_build_root, *comps)
+ build_root = self._webkit_configuration_build_directory()
+ return os.path.join(build_root, *comps)
def _path_to_driver(self):
return self._build_path('DumpRenderTree')
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 434058e..55c4558 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
@@ -70,11 +70,11 @@ _log = logging.getLogger("webkitpy.layout_tests."
BASELINE_SUFFIXES = ['.txt', '.png', '.checksum']
REBASELINE_PLATFORM_ORDER = ['mac', 'win', 'win-xp', 'win-vista', 'linux']
-ARCHIVE_DIR_NAME_DICT = {'win': 'webkit-rel',
+ARCHIVE_DIR_NAME_DICT = {'win': 'Webkit_Win',
'win-vista': 'webkit-dbg-vista',
- 'win-xp': 'webkit-rel',
- 'mac': 'webkit-rel-mac5',
- 'linux': 'webkit-rel-linux',
+ 'win-xp': 'Webkit_Win',
+ 'mac': 'Webkit_Mac10_5',
+ 'linux': 'webkit-rel-linux64',
'win-canary': 'webkit-rel-webkit-org',
'win-vista-canary': 'webkit-dbg-vista',
'win-xp-canary': 'webkit-rel-webkit-org',
@@ -819,9 +819,8 @@ def get_host_port_object(options):
return port_obj
-def main(executive=Executive()):
- """Main function to produce new baselines."""
-
+def parse_options(args):
+ """Parse options and return a pair of host options and target options."""
option_parser = optparse.OptionParser()
option_parser.add_option('-v', '--verbose',
action='store_true',
@@ -874,7 +873,20 @@ def main(executive=Executive()):
help=('The target platform to rebaseline '
'("mac", "chromium", "qt", etc.). Defaults '
'to "chromium".'))
- options = option_parser.parse_args()[0]
+ options = option_parser.parse_args(args)[0]
+
+ target_options = copy.copy(options)
+ if options.target_platform == 'chromium':
+ target_options.chromium = True
+ options.tolerance = 0
+
+ return (options, target_options)
+
+
+def main(executive=Executive()):
+ """Main function to produce new baselines."""
+
+ (options, target_options) = parse_options(sys.argv[1:])
# We need to create three different Port objects over the life of this
# script. |target_port_obj| is used to determine configuration information:
@@ -882,9 +894,6 @@ def main(executive=Executive()):
# |port_obj| is used for runtime functionality like actually diffing
# Then we create a rebaselining port to actual find and manage the
# baselines.
- target_options = copy.copy(options)
- if options.target_platform == 'chromium':
- target_options.chromium = True
target_port_obj = port.get(None, target_options)
# Set up our logging format.
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 8db31a6..7c55b94 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
@@ -95,6 +95,15 @@ class TestRebaseliner(unittest.TestCase):
return rebaseline_chromium_webkit_tests.Rebaseliner(
host_port_obj, target_port_obj, platform, options)
+ def test_parse_options(self):
+ (options, target_options) = rebaseline_chromium_webkit_tests.parse_options([])
+ self.assertTrue(target_options.chromium)
+ self.assertEqual(options.tolerance, 0)
+
+ (options, target_options) = rebaseline_chromium_webkit_tests.parse_options(['--target-platform', 'qt'])
+ self.assertFalse(hasattr(target_options, 'chromium'))
+ self.assertEqual(options.tolerance, 0)
+
def test_noop(self):
# this method tests that was can at least instantiate an object, even
# if there is nothing to do.
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
index 704180c..f360adc 100755
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -85,6 +85,8 @@ _log = logging.getLogger("webkitpy.layout_tests.run_webkit_tests")
# Builder base URL where we have the archived test results.
BUILDER_BASE_URL = "http://build.chromium.org/buildbot/layout_test_results/"
+LAYOUT_TESTS_DIRECTORY = "LayoutTests" + os.sep
+
TestExpectationsFile = test_expectations.TestExpectationsFile
@@ -283,12 +285,17 @@ class TestRunner:
last_unexpected_results: list of unexpected results to retest, if any
"""
- paths = [arg for arg in args if arg and arg != '']
+ paths = [self._strip_test_dir_prefix(arg) for arg in args if arg and arg != '']
paths += last_unexpected_results
if self._options.test_list:
paths += read_test_files(self._options.test_list)
self._test_files = self._port.tests(paths)
+ def _strip_test_dir_prefix(self, path):
+ if path.startswith(LAYOUT_TESTS_DIRECTORY):
+ return path[len(LAYOUT_TESTS_DIRECTORY):]
+ return path
+
def lint(self):
# Creating the expecations for each platform/configuration pair does
# all the test list parsing and ensures it's correct syntax (e.g. no
@@ -404,9 +411,8 @@ class TestRunner:
# If we reached the end and we don't have enough tests, we run some
# from the beginning.
- if (self._options.run_chunk and
- (slice_end - slice_start < chunk_len)):
- extra = 1 + chunk_len - (slice_end - slice_start)
+ if slice_end - slice_start < chunk_len:
+ extra = chunk_len - (slice_end - slice_start)
extra_msg = (' last chunk is partial, appending [0:%d]' %
extra)
self._printer.print_expected(extra_msg)
@@ -470,9 +476,9 @@ class TestRunner:
def _get_dir_for_test_file(self, test_file):
"""Returns the highest-level directory by which to shard the given
test file."""
- index = test_file.rfind(os.sep + 'LayoutTests' + os.sep)
+ index = test_file.rfind(os.sep + LAYOUT_TESTS_DIRECTORY)
- test_file = test_file[index + len('LayoutTests/'):]
+ test_file = test_file[index + len(LAYOUT_TESTS_DIRECTORY):]
test_file_parts = test_file.split(os.sep, 1)
directory = test_file_parts[0]
test_file = test_file_parts[1]
@@ -741,17 +747,6 @@ class TestRunner:
if not result_summary:
return None
- # Do not start when http locking is enabled.
- if not self._options.wait_for_httpd:
- if self.needs_http():
- self._printer.print_update('Starting HTTP server ...')
- self._port.start_http_server()
-
- if self.needs_websocket():
- self._printer.print_update('Starting WebSocket server ...')
- self._port.start_websocket_server()
- # self._websocket_secure_server.Start()
-
return result_summary
def run(self, result_summary):
@@ -841,11 +836,6 @@ class TestRunner:
sys.stdout.flush()
_log.debug("flushing stderr")
sys.stderr.flush()
- if not self._options.wait_for_httpd:
- _log.debug("stopping http server")
- self._port.stop_http_server()
- _log.debug("stopping websocket server")
- self._port.stop_websocket_server()
_log.debug("stopping helper")
self._port.stop_helper()
@@ -948,14 +938,15 @@ class TestRunner:
if not self._options.test_results_server:
return
+ if not self._options.master_name:
+ _log.error("--test-results-server was set, but --master-name was not. Not uploading JSON files.")
+ return
+
_log.info("Uploading JSON files for builder: %s",
self._options.builder_name)
- attrs = [("builder", self._options.builder_name), ("testtype", "layout-tests")]
- # FIXME: master_name should be required if test_results_server is set.
- # Throw an error if master_name isn't set.
- if self._options.master_name:
- attrs.append(("master", self._options.master_name))
+ attrs = [("builder", self._options.builder_name), ("testtype", "layout-tests"),
+ ("master", self._options.master_name)]
json_files = ["expectations.json"]
if self._options.upload_full_results:
@@ -966,13 +957,6 @@ class TestRunner:
files = [(file, os.path.join(self._options.results_directory, file))
for file in json_files]
- # FIXME: Remove this. This is temporary debug logging.
- if self._options.builder_name.startswith("Webkit Linux"):
- for filename in files:
- _log.debug(filename[1])
- with codecs.open(filename[1], "r") as results_file:
- _log.debug("%s:\n%s" % (filename[0], results_file.read()))
-
uploader = test_results_uploader.TestResultsUploader(
self._options.test_results_server)
try:
@@ -1530,7 +1514,7 @@ def parse_args(args=None):
default=False,
help="Don't check the system dependencies (themes)"),
optparse.make_option("--use-drt", action="store_true",
- default=False,
+ default=None,
help="Use DumpRenderTree instead of test_shell"),
optparse.make_option("--accelerated-compositing",
action="store_true",
@@ -1612,9 +1596,6 @@ def parse_args(args=None):
optparse.make_option("--no-record-results", action="store_false",
default=True, dest="record_results",
help="Don't record the results."),
- optparse.make_option("--wait-for-httpd", action="store_true",
- default=False, dest="wait_for_httpd",
- help="Wait for http locks."),
# old-run-webkit-tests also has HTTP toggle options:
# --[no-]http Run (or do not run) http tests
# (default: run)
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 0f09ffa..f21e7a5 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
@@ -31,6 +31,7 @@
"""Unit tests for run_webkit_tests."""
import codecs
+import itertools
import logging
import os
import Queue
@@ -48,7 +49,9 @@ from webkitpy.common.system import user
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.layout_tests.port.test import TestPort
+from webkitpy.layout_tests.port.test import TestPort, TestDriver
+from webkitpy.python24.versioning import compare_version
+from webkitpy.test.skip import skip_if
from webkitpy.thirdparty.mock import Mock
@@ -61,41 +64,44 @@ class MockUser():
self.url = url
-def passing_run(args=[], port_obj=None, record_results=False,
+def passing_run(extra_args=None, port_obj=None, record_results=False,
tests_included=False):
- new_args = ['--print', 'nothing']
- if not '--platform' in args:
- new_args.extend(['--platform', 'test'])
+ extra_args = extra_args or []
+ args = ['--print', 'nothing']
+ if not '--platform' in extra_args:
+ args.extend(['--platform', 'test'])
if not record_results:
- new_args.append('--no-record-results')
- new_args.extend(args)
+ args.append('--no-record-results')
+ args.extend(extra_args)
if not tests_included:
# We use the glob to test that globbing works.
- new_args.extend(['passes',
- 'http/tests',
- 'http/tests/websocket/tests',
- 'failures/expected/*'])
- options, parsed_args = run_webkit_tests.parse_args(new_args)
- if port_obj is None:
+ args.extend(['passes',
+ 'http/tests',
+ 'http/tests/websocket/tests',
+ 'failures/expected/*'])
+ options, parsed_args = run_webkit_tests.parse_args(args)
+ if not port_obj:
port_obj = port.get(port_name=options.platform, options=options,
user=MockUser())
res = run_webkit_tests.run(port_obj, options, parsed_args)
return res == 0
-def logging_run(args=[], tests_included=False):
- new_args = ['--no-record-results']
- if not '--platform' in args:
- new_args.extend(['--platform', 'test'])
- new_args.extend(args)
+def logging_run(extra_args=None, port_obj=None, tests_included=False):
+ extra_args = extra_args or []
+ args = ['--no-record-results']
+ if not '--platform' in extra_args:
+ args.extend(['--platform', 'test'])
+ args.extend(extra_args)
if not tests_included:
- new_args.extend(['passes',
- 'http/tests',
- 'http/tests/websocket/tests',
- 'failures/expected/*'])
- options, parsed_args = run_webkit_tests.parse_args(new_args)
+ args.extend(['passes',
+ 'http/tests',
+ 'http/tests/websocket/tests',
+ 'failures/expected/*'])
+ options, parsed_args = run_webkit_tests.parse_args(args)
user = MockUser()
- port_obj = port.get(port_name=options.platform, options=options, user=user)
+ if not port_obj:
+ port_obj = port.get(port_name=options.platform, options=options, user=user)
buildbot_output = array_stream.ArrayStream()
regular_output = array_stream.ArrayStream()
res = run_webkit_tests.run(port_obj, options, parsed_args,
@@ -104,6 +110,54 @@ def logging_run(args=[], tests_included=False):
return (res, buildbot_output, regular_output, user)
+def get_tests_run(extra_args=None, tests_included=False, flatten_batches=False):
+ extra_args = extra_args or []
+ args = [
+ '--print', 'nothing',
+ '--platform', 'test',
+ '--no-record-results',
+ '--child-processes', '1']
+ args.extend(extra_args)
+ if not tests_included:
+ # Not including http tests since they get run out of order (that
+ # behavior has its own test, see test_get_test_file_queue)
+ args.extend(['passes', 'failures'])
+ options, parsed_args = run_webkit_tests.parse_args(args)
+ user = MockUser()
+
+ test_batches = []
+
+ class RecordingTestDriver(TestDriver):
+ def __init__(self, port, image_path, options):
+ TestDriver.__init__(self, port, image_path, options, executive=None)
+ self._current_test_batch = None
+
+ def poll(self):
+ # So that we don't create a new driver for every test
+ return None
+
+ def stop(self):
+ self._current_test_batch = None
+
+ def run_test(self, uri, timeoutms, image_hash):
+ if self._current_test_batch is None:
+ self._current_test_batch = []
+ test_batches.append(self._current_test_batch)
+ self._current_test_batch.append(self._port.uri_to_test_name(uri))
+ return TestDriver.run_test(self, uri, timeoutms, image_hash)
+
+ class RecordingTestPort(TestPort):
+ def create_driver(self, image_path, options):
+ return RecordingTestDriver(self, image_path, options)
+
+ recording_port = RecordingTestPort(options=options, user=user)
+ logging_run(extra_args=args, port_obj=recording_port, tests_included=True)
+
+ if flatten_batches:
+ return list(itertools.chain(*test_batches))
+
+ return test_batches
+
class MainTest(unittest.TestCase):
def test_accelerated_compositing(self):
# This just tests that we recognize the command line args
@@ -119,8 +173,9 @@ class MainTest(unittest.TestCase):
self.assertTrue(passing_run())
def test_batch_size(self):
- # FIXME: verify # of tests run
- self.assertTrue(passing_run(['--batch-size', '2']))
+ batch_tests_run = get_tests_run(['--batch-size', '2'])
+ for batch in batch_tests_run:
+ self.assertTrue(len(batch) <= 2, '%s had too many tests' % ', '.join(batch))
def test_child_process_1(self):
(res, buildbot_output, regular_output, user) = logging_run(
@@ -194,8 +249,15 @@ class MainTest(unittest.TestCase):
self.assertTrue(passing_run(['--randomize-order']))
def test_run_chunk(self):
- # FIXME: verify # of tests run
- self.assertTrue(passing_run(['--run-chunk', '1:4']))
+ # Test that we actually select the right chunk
+ all_tests_run = get_tests_run(flatten_batches=True)
+ chunk_tests_run = get_tests_run(['--run-chunk', '1:4'], flatten_batches=True)
+ self.assertEquals(all_tests_run[4:8], chunk_tests_run)
+
+ # Test that we wrap around if the number of tests is not evenly divisible by the chunk size
+ tests_to_run = ['passes/error.html', 'passes/image.html', 'passes/platform_image.html', 'passes/text.html']
+ chunk_tests_run = get_tests_run(['--run-chunk', '1:3'] + tests_to_run, tests_included=True, flatten_batches=True)
+ self.assertEquals(['passes/text.html', 'passes/error.html', 'passes/image.html'], chunk_tests_run)
def test_run_force(self):
# This raises an exception because we run
@@ -203,23 +265,33 @@ class MainTest(unittest.TestCase):
self.assertRaises(ValueError, logging_run, ['--force'])
def test_run_part(self):
- # FIXME: verify # of tests run
- self.assertTrue(passing_run(['--run-part', '1:2']))
+ # Test that we actually select the right part
+ tests_to_run = ['passes/error.html', 'passes/image.html', 'passes/platform_image.html', 'passes/text.html']
+ tests_run = get_tests_run(['--run-part', '1:2'] + tests_to_run, tests_included=True, flatten_batches=True)
+ self.assertEquals(['passes/error.html', 'passes/image.html'], tests_run)
+
+ # Test that we wrap around if the number of tests is not evenly divisible by the chunk size
+ # (here we end up with 3 parts, each with 2 tests, and we only have 4 tests total, so the
+ # last part repeats the first two tests).
+ chunk_tests_run = get_tests_run(['--run-part', '3:3'] + tests_to_run, tests_included=True, flatten_batches=True)
+ self.assertEquals(['passes/error.html', 'passes/image.html'], chunk_tests_run)
def test_run_singly(self):
- self.assertTrue(passing_run(['--run-singly']))
+ batch_tests_run = get_tests_run(['--run-singly'])
+ for batch in batch_tests_run:
+ self.assertEquals(len(batch), 1, '%s had too many tests' % ', '.join(batch))
def test_single_file(self):
- # FIXME: verify # of tests run
- self.assertTrue(passing_run(['passes/text.html'], tests_included=True))
+ tests_run = get_tests_run(['passes/text.html'], tests_included=True, flatten_batches=True)
+ self.assertEquals(['passes/text.html'], tests_run)
def test_test_list(self):
filename = tempfile.mktemp()
tmpfile = file(filename, mode='w+')
tmpfile.write('passes/text.html')
tmpfile.close()
- self.assertTrue(passing_run(['--test-list=%s' % filename],
- tests_included=True))
+ tests_run = get_tests_run(['--test-list=%s' % filename], tests_included=True, flatten_batches=True)
+ self.assertEquals(['passes/text.html'], tests_run)
os.remove(filename)
res, out, err, user = logging_run(['--test-list=%s' % filename],
tests_included=True)
@@ -271,7 +343,7 @@ class MainTest(unittest.TestCase):
def get_port_for_run(args):
options, parsed_args = run_webkit_tests.parse_args(args)
test_port = ImageDiffTestPort(options=options, user=MockUser())
- passing_run(args=args, port_obj=test_port, tests_included=True)
+ passing_run(args, port_obj=test_port, tests_included=True)
return test_port
base_args = ['--pixel-tests', 'failures/expected/*']
@@ -287,6 +359,8 @@ class MainTest(unittest.TestCase):
test_port = get_port_for_run(base_args)
self.assertEqual(None, test_port.tolerance_used_for_diff_image)
+MainTest = skip_if(MainTest, sys.platform == 'cygwin' and compare_version(sys, '2.6')[0] < 0, 'new-run-webkit-tests tests hang on Cygwin Python 2.5.2')
+
def _mocked_open(original_open, file_list):
def _wrapper(name, mode, encoding):
diff --git a/WebKitTools/Scripts/webkitpy/style/checker.py b/WebKitTools/Scripts/webkitpy/style/checker.py
index 11e3e33..fb93eb9 100644
--- a/WebKitTools/Scripts/webkitpy/style/checker.py
+++ b/WebKitTools/Scripts/webkitpy/style/checker.py
@@ -115,7 +115,13 @@ _PATH_RULES_SPECIFIER = [
# Files in these directories are consumers of the WebKit
# API and therefore do not follow the same header including
# discipline as WebCore.
- (["WebKitTools/WebKitAPITest/",
+
+ ([# TestNetscapePlugIn has no config.h and uses funny names like
+ # NPP_SetWindow.
+ "WebKitTools/DumpRenderTree/TestNetscapePlugIn/",
+ # The API test harnesses have no config.h and use funny macros like
+ # TEST_CLASS_NAME.
+ "WebKitTools/WebKitAPITest/",
"WebKitTools/TestWebKitAPI/"],
["-build/include",
"-readability/naming"]),
diff --git a/WebKitTools/Scripts/webkitpy/style/optparser.py b/WebKitTools/Scripts/webkitpy/style/optparser.py
index 3ba0fae..f4e9923 100644
--- a/WebKitTools/Scripts/webkitpy/style/optparser.py
+++ b/WebKitTools/Scripts/webkitpy/style/optparser.py
@@ -145,6 +145,7 @@ class CommandOptionValues(object):
def __init__(self,
filter_rules=None,
git_commit=None,
+ diff_files=None,
is_verbose=False,
min_confidence=1,
output_format="emacs"):
@@ -163,6 +164,7 @@ class CommandOptionValues(object):
self.filter_rules = filter_rules
self.git_commit = git_commit
+ self.diff_files = diff_files
self.is_verbose = is_verbose
self.min_confidence = min_confidence
self.output_format = output_format
@@ -174,6 +176,8 @@ class CommandOptionValues(object):
return False
if self.git_commit != other.git_commit:
return False
+ if self.diff_files != other.diff_files:
+ return False
if self.is_verbose != other.is_verbose:
return False
if self.min_confidence != other.min_confidence:
@@ -214,6 +218,8 @@ class ArgumentPrinter(object):
flags['filter'] = ",".join(filter_rules)
if options.git_commit:
flags['git-commit'] = options.git_commit
+ if options.diff_files:
+ flags['diff_files'] = options.diff_files
flag_string = ''
# Alphabetizing lets us unit test this method.
@@ -308,6 +314,9 @@ class ArgumentParser(object):
parser.add_option("-g", "--git-diff", "--git-commit",
metavar="COMMIT", dest="git_commit", help=git_commit_help,)
+ diff_files_help = "diff the files passed on the command line rather than checking the style of every line"
+ parser.add_option("--diff-files", action="store_true", dest="diff_files", default=False, help=diff_files_help)
+
min_confidence_help = ("set the minimum confidence of style errors "
"to report. Can be an integer 1-5, with 1 "
"displaying all errors. Defaults to %default.")
@@ -409,6 +418,7 @@ class ArgumentParser(object):
filter_value = options.filter_value
git_commit = options.git_commit
+ diff_files = options.diff_files
is_verbose = options.is_verbose
min_confidence = options.min_confidence
output_format = options.output_format
@@ -420,10 +430,6 @@ class ArgumentParser(object):
# Validate user-provided values.
- if paths and git_commit:
- self._parse_error('You cannot provide both paths and a git '
- 'commit at the same time.')
-
min_confidence = int(min_confidence)
if (min_confidence < 1) or (min_confidence > 5):
self._parse_error('option --min-confidence: invalid integer: '
@@ -442,6 +448,7 @@ class ArgumentParser(object):
options = CommandOptionValues(filter_rules=filter_rules,
git_commit=git_commit,
+ diff_files=diff_files,
is_verbose=is_verbose,
min_confidence=min_confidence,
output_format=output_format)
diff --git a/WebKitTools/Scripts/webkitpy/style/optparser_unittest.py b/WebKitTools/Scripts/webkitpy/style/optparser_unittest.py
index b7e3eda..a6b64da 100644
--- a/WebKitTools/Scripts/webkitpy/style/optparser_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/style/optparser_unittest.py
@@ -136,11 +136,6 @@ class ArgumentParserTest(LoggingTestCase):
self.assertLog(['ERROR: Invalid filter rule "build": '
'every rule must start with + or -.\n'])
parse(['--filter=+build']) # works
- # Pass files and git-commit at the same time.
- self.assertRaises(SystemExit, parse, ['--git-commit=committish',
- 'file.txt'])
- self.assertLog(['ERROR: You cannot provide both paths and '
- 'a git commit at the same time.\n'])
def test_parse_default_arguments(self):
parse = self._parse
@@ -151,6 +146,7 @@ class ArgumentParserTest(LoggingTestCase):
self.assertEquals(options.filter_rules, [])
self.assertEquals(options.git_commit, None)
+ self.assertEquals(options.diff_files, False)
self.assertEquals(options.is_verbose, False)
self.assertEquals(options.min_confidence, 3)
self.assertEquals(options.output_format, 'vs7')
@@ -171,6 +167,8 @@ class ArgumentParserTest(LoggingTestCase):
self.assertEquals(options.git_commit, 'commit')
(files, options) = parse(['--verbose'])
self.assertEquals(options.is_verbose, True)
+ (files, options) = parse(['--diff-files', 'file.txt'])
+ self.assertEquals(options.diff_files, True)
# Pass user_rules.
(files, options) = parse(['--filter=+build,-whitespace'])
diff --git a/WebKitTools/Scripts/webkitpy/style_references.py b/WebKitTools/Scripts/webkitpy/style_references.py
index 34f3bff..a21e931 100644
--- a/WebKitTools/Scripts/webkitpy/style_references.py
+++ b/WebKitTools/Scripts/webkitpy/style_references.py
@@ -69,6 +69,6 @@ class WebKitCheckout(object):
"""Return the checkout root as an absolute path."""
return self._scm.checkout_root
- def create_patch(self, git_commit):
- return self._scm.create_patch(git_commit)
-
+ def create_patch(self, git_commit, changed_files=None):
+ # FIXME: SCM.create_patch should understand how to handle None.
+ return self._scm.create_patch(git_commit, changed_files=changed_files or [])
diff --git a/WebKitTools/Scripts/webkitpy/test/cat.py b/WebKitTools/Scripts/webkitpy/test/cat.py
new file mode 100644
index 0000000..ae1e143
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/test/cat.py
@@ -0,0 +1,42 @@
+# 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.
+
+import os.path
+import sys
+
+# Add WebKitTools/Scripts to the path to ensure we can find webkitpy.
+sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
+
+from webkitpy.common.system import fileutils
+
+
+def command_arguments(*args):
+ return ['python', __file__] + list(args)
+
+
+def main():
+ fileutils.make_stdout_binary()
+ sys.stdout.write(sys.stdin.read())
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/WebKitTools/Scripts/webkitpy/test/cat_unittest.py b/WebKitTools/Scripts/webkitpy/test/cat_unittest.py
new file mode 100644
index 0000000..4ed1f67
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/test/cat_unittest.py
@@ -0,0 +1,52 @@
+# 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.
+
+import StringIO
+import os.path
+import sys
+import unittest
+
+from webkitpy.common.system import executive, outputcapture
+from webkitpy.test import cat
+
+
+class CatTest(outputcapture.OutputCaptureTestCaseBase):
+ def assert_cat(self, input):
+ saved_stdin = sys.stdin
+ sys.stdin = StringIO.StringIO(input)
+ cat.main()
+ self.assertStdout(input)
+ sys.stdin = saved_stdin
+
+ def test_basic(self):
+ self.assert_cat('foo bar baz\n')
+
+ def test_no_newline(self):
+ self.assert_cat('foo bar baz')
+
+ def test_unicode(self):
+ self.assert_cat(u'WebKit \u2661 Tor Arne Vestb\u00F8!')
+
+ def test_as_command(self):
+ input = 'foo bar baz\n'
+ output = executive.Executive().run_command(cat.command_arguments(), input=input)
+ self.assertEqual(input, output)
diff --git a/WebKitTools/Scripts/webkitpy/test/echo.py b/WebKitTools/Scripts/webkitpy/test/echo.py
new file mode 100644
index 0000000..f7468f7
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/test/echo.py
@@ -0,0 +1,52 @@
+# 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.
+
+import os.path
+import sys
+
+# Add WebKitTools/Scripts to the path to ensure we can find webkitpy.
+sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
+
+from webkitpy.common.system import fileutils
+
+
+def command_arguments(*args):
+ return ['python', __file__] + list(args)
+
+
+def main(args=None):
+ if args is None:
+ args = sys.argv[1:]
+
+ fileutils.make_stdout_binary()
+
+ print_newline = True
+ if len(args) and args[0] == '-n':
+ print_newline = False
+ del args[0]
+ sys.stdout.write(' '.join(args))
+ if print_newline:
+ sys.stdout.write('\n')
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/WebKitTools/Scripts/webkitpy/test/echo_unittest.py b/WebKitTools/Scripts/webkitpy/test/echo_unittest.py
new file mode 100644
index 0000000..bc13b5e
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/test/echo_unittest.py
@@ -0,0 +1,64 @@
+# 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.
+
+import os.path
+import sys
+import unittest
+
+from webkitpy.common.system import executive, outputcapture
+from webkitpy.test import echo
+
+
+class EchoTest(outputcapture.OutputCaptureTestCaseBase):
+ def test_basic(self):
+ echo.main(['foo', 'bar', 'baz'])
+ self.assertStdout('foo bar baz\n')
+
+ def test_no_newline(self):
+ echo.main(['-n', 'foo', 'bar', 'baz'])
+ self.assertStdout('foo bar baz')
+
+ def test_unicode(self):
+ echo.main([u'WebKit \u2661', 'Tor Arne', u'Vestb\u00F8!'])
+ self.assertStdout(u'WebKit \u2661 Tor Arne Vestb\u00F8!\n')
+
+ def test_argument_order(self):
+ echo.main(['foo', '-n', 'bar'])
+ self.assertStdout('foo -n bar\n')
+
+ def test_empty_arguments(self):
+ old_argv = sys.argv
+ sys.argv = ['echo.py', 'foo', 'bar', 'baz']
+ echo.main([])
+ self.assertStdout('\n')
+ sys.argv = old_argv
+
+ def test_no_arguments(self):
+ old_argv = sys.argv
+ sys.argv = ['echo.py', 'foo', 'bar', 'baz']
+ echo.main()
+ self.assertStdout('foo bar baz\n')
+ sys.argv = old_argv
+
+ def test_as_command(self):
+ output = executive.Executive().run_command(echo.command_arguments('foo', 'bar', 'baz'))
+ self.assertEqual(output, 'foo bar baz\n')
diff --git a/WebKitTools/Scripts/webkitpy/test/skip.py b/WebKitTools/Scripts/webkitpy/test/skip.py
new file mode 100644
index 0000000..8587d56
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/test/skip.py
@@ -0,0 +1,52 @@
+# 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.
+
+import logging
+
+_log = logging.getLogger(__name__)
+
+
+def skip_if(klass, condition, message=None, logger=None):
+ """Makes all test_* methods in a given class no-ops if the given condition
+ is False. Backported from Python 3.1+'s unittest.skipIf decorator."""
+ if not logger:
+ logger = _log
+ if not condition:
+ return klass
+ for name in dir(klass):
+ attr = getattr(klass, name)
+ if not callable(attr):
+ continue
+ if not name.startswith('test_'):
+ continue
+ setattr(klass, name, _skipped_method(attr, message, logger))
+ klass._printed_skipped_message = False
+ return klass
+
+
+def _skipped_method(method, message, logger):
+ def _skip(*args):
+ if method.im_class._printed_skipped_message:
+ return
+ method.im_class._printed_skipped_message = True
+ logger.info('Skipping %s.%s: %s' % (method.__module__, method.im_class.__name__, message))
+ return _skip
diff --git a/WebKitTools/Scripts/webkitpy/test/skip_unittest.py b/WebKitTools/Scripts/webkitpy/test/skip_unittest.py
new file mode 100644
index 0000000..f61a1bb
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/test/skip_unittest.py
@@ -0,0 +1,77 @@
+# 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.
+
+import StringIO
+import logging
+import unittest
+
+from webkitpy.test.skip import skip_if
+
+
+class SkipTest(unittest.TestCase):
+ def setUp(self):
+ self.logger = logging.getLogger(__name__)
+
+ self.old_level = self.logger.level
+ self.logger.setLevel(logging.INFO)
+
+ self.old_propagate = self.logger.propagate
+ self.logger.propagate = False
+
+ self.log_stream = StringIO.StringIO()
+ self.handler = logging.StreamHandler(self.log_stream)
+ self.logger.addHandler(self.handler)
+
+ self.foo_was_called = False
+
+ def tearDown(self):
+ self.logger.removeHandler(self.handler)
+ self.propagate = self.old_propagate
+ self.logger.setLevel(self.old_level)
+
+ def create_fixture_class(self):
+ class TestSkipFixture(object):
+ def __init__(self, callback):
+ self.callback = callback
+
+ def test_foo(self):
+ self.callback()
+
+ return TestSkipFixture
+
+ def foo_callback(self):
+ self.foo_was_called = True
+
+ def test_skip_if_false(self):
+ klass = skip_if(self.create_fixture_class(), False, 'Should not see this message.', logger=self.logger)
+ klass(self.foo_callback).test_foo()
+ self.assertEqual(self.log_stream.getvalue(), '')
+ self.assertTrue(self.foo_was_called)
+
+ def test_skip_if_true(self):
+ klass = skip_if(self.create_fixture_class(), True, 'Should see this message.', logger=self.logger)
+ klass(self.foo_callback).test_foo()
+ self.assertEqual(self.log_stream.getvalue(), 'Skipping webkitpy.test.skip_unittest.TestSkipFixture: Should see this message.\n')
+ self.assertFalse(self.foo_was_called)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py b/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py
index 9bdec8f..a070324 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/__init__.py
@@ -2,4 +2,5 @@
from webkitpy.tool.commands.prettydiff import PrettyDiff
from webkitpy.tool.commands.rebaseline import Rebaseline
+from webkitpy.tool.commands.rebaselineserver import RebaselineServer
# FIXME: Add the rest of the commands here.
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html
new file mode 100644
index 0000000..5667cd2
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!--
+ 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.
+-->
+<html>
+<head>
+ <title>Layout Test Rebaseline Server</title>
+ <link rel="stylesheet" href="/main.css" type="text/css">
+ <script src="/main.js"></script>
+</head>
+<body class="loading">
+ <a href="/quitquitquit">Exit</a>
+</body>
+</html>
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css
new file mode 100644
index 0000000..35bd6a5
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+body {
+ font-size: 12px;
+ font-family: Helvetica, Arial, sans-serif;
+ padding: 0;
+ margin: 0;
+}
+
+.loading {
+ opacity: 0.5;
+}
+
+div {
+ margin: 0;
+}
+
+a, .link {
+ color: #aaf;
+ text-decoration: underline;
+ cursor: pointer;
+}
+
+.link.selected {
+ color: #fff;
+ font-weight: bold;
+ text-decoration: none;
+}
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js
new file mode 100644
index 0000000..55f19a4
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+function main()
+{
+ document.body.classList.remove('loading');
+}
+
+window.addEventListener('DOMContentLoaded', main);
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py b/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py
new file mode 100644
index 0000000..0a37677
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py
@@ -0,0 +1,157 @@
+# 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.
+
+"""Starts a local HTTP server which displays layout test failures (given a test
+results directory), provides comparisons of expected and actual results (both
+images and text) and allows one-click rebaselining of tests."""
+from __future__ import with_statement
+
+import codecs
+import datetime
+import mimetypes
+import os
+import os.path
+import shutil
+import threading
+import time
+import urlparse
+import BaseHTTPServer
+
+from optparse import make_option
+from wsgiref.handlers import format_date_time
+
+from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand
+
+
+class RebaselineHTTPServer(BaseHTTPServer.HTTPServer):
+ def __init__(self, httpd_port, results_directory):
+ BaseHTTPServer.HTTPServer.__init__(self, ("", httpd_port), RebaselineHTTPRequestHandler)
+ self.results_directory = results_directory
+
+
+class RebaselineHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ STATIC_FILE_NAMES = frozenset([
+ "index.html",
+ "main.js",
+ "main.css",
+ ])
+
+ STATIC_FILE_DIRECTORY = os.path.join(
+ os.path.dirname(__file__), "data", "rebaselineserver")
+
+ def do_GET(self):
+ self._handle_request()
+
+ def do_POST(self):
+ self._handle_request()
+
+ def _handle_request(self):
+ # Parse input.
+ if "?" in self.path:
+ path, query_string = self.path.split("?", 1)
+ self.query = urlparse.parse_qs(query_string)
+ else:
+ path = self.path
+ self.query = {}
+ function_or_file_name = path[1:] or "index.html"
+
+ # See if a static file matches.
+ if function_or_file_name in RebaselineHTTPRequestHandler.STATIC_FILE_NAMES:
+ self._serve_static_file(function_or_file_name)
+ return
+
+ # See if a class method matches.
+ function_name = function_or_file_name.replace(".", "_")
+ if not hasattr(self, function_name):
+ self.send_error(404, "Unknown function %s" % function_name)
+ return
+ if function_name[0] == "_":
+ self.send_error(
+ 401, "Not allowed to invoke private or protected methods")
+ return
+ function = getattr(self, function_name)
+ function()
+
+ def _serve_static_file(self, static_path):
+ self._serve_file(os.path.join(
+ RebaselineHTTPRequestHandler.STATIC_FILE_DIRECTORY, static_path))
+
+ def quitquitquit(self):
+ self.send_response(200)
+ self.send_header("Content-type", "text/plain")
+ self.end_headers()
+ self.wfile.write("Quit.\n")
+
+ # Shutdown has to happen on another thread from the server's thread,
+ # otherwise there's a deadlock
+ threading.Thread(target=lambda: self.server.shutdown()).start()
+
+ def _serve_file(self, file_path, cacheable_seconds=0):
+ if not os.path.exists(file_path):
+ self.send_error(404, "File not found")
+ return
+ with codecs.open(file_path, "rb") as static_file:
+ self.send_response(200)
+ self.send_header("Content-Length", os.path.getsize(file_path))
+ mime_type, encoding = mimetypes.guess_type(file_path)
+ if mime_type:
+ self.send_header("Content-type", mime_type)
+
+ if cacheable_seconds:
+ expires_time = (datetime.datetime.now() +
+ datetime.timedelta(0, cacheable_seconds))
+ expires_formatted = format_date_time(
+ time.mktime(expires_time.timetuple()))
+ self.send_header("Expires", expires_formatted)
+ self.end_headers()
+
+ shutil.copyfileobj(static_file, self.wfile)
+
+
+class RebaselineServer(AbstractDeclarativeCommand):
+ name = "rebaseline-server"
+ help_text = __doc__
+ argument_names = "/path/to/results/directory"
+
+ def __init__(self):
+ options = [
+ make_option("--httpd-port", action="store", type="int", default=8127, help="Port to use for the the rebaseline HTTP server"),
+ ]
+ AbstractDeclarativeCommand.__init__(self, options=options)
+
+ def execute(self, options, args, tool):
+ results_directory = args[0]
+
+ print "Starting server at http://localhost:%d/" % options.httpd_port
+ print ("Use the 'Exit' link in the UI, http://localhost:%d/"
+ "quitquitquit or Ctrl-C to stop") % options.httpd_port
+
+ httpd = RebaselineHTTPServer(
+ httpd_port=options.httpd_port,
+ results_directory=results_directory)
+ httpd.serve_forever()
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py
index ed91f5a..e12c8e2 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py
@@ -92,6 +92,32 @@ class CleanPendingCommit(AbstractDeclarativeCommand):
self._tool.bugs.obsolete_attachment(patch.id(), message)
+# FIXME: This should be share more logic with AssignToCommitter and CleanPendingCommit
+class CleanReviewQueue(AbstractDeclarativeCommand):
+ name = "clean-review-queue"
+ help_text = "Clear r? on obsolete patches so they do not appear in the pending-commit list."
+
+ def execute(self, options, args, tool):
+ queue_url = "http://webkit.org/pending-review"
+ # We do this inefficient dance to be more like webkit.org/pending-review
+ # bugs.queries.fetch_bug_ids_from_review_queue() doesn't return
+ # closed bugs, but folks using /pending-review will see them. :(
+ for patch_id in tool.bugs.queries.fetch_attachment_ids_from_review_queue():
+ patch = self._tool.bugs.fetch_attachment(patch_id)
+ if not patch.review() == "?":
+ continue
+ attachment_obsolete_modifier = ""
+ if patch.is_obsolete():
+ attachment_obsolete_modifier = "obsolete "
+ elif patch.bug().is_closed():
+ bug_closed_explanation = " If you would like this patch reviewed, please attach it to a new bug (or re-open this bug before marking it for review again)."
+ else:
+ # Neither the patch was obsolete or the bug was closed, next patch...
+ continue
+ message = "Cleared review? from %sattachment %s so that this bug does not appear in %s.%s" % (attachment_obsolete_modifier, patch.id(), queue_url, bug_closed_explanation)
+ self._tool.bugs.obsolete_attachment(patch.id(), message)
+
+
class AssignToCommitter(AbstractDeclarativeCommand):
name = "assign-to-committer"
help_text = "Assign bug to whoever attached the most recent r+'d patch"
diff --git a/WebKitTools/Scripts/webkitpy/tool/mocktool.py b/WebKitTools/Scripts/webkitpy/tool/mocktool.py
index af232d9..b6ee95f 100644
--- a/WebKitTools/Scripts/webkitpy/tool/mocktool.py
+++ b/WebKitTools/Scripts/webkitpy/tool/mocktool.py
@@ -424,6 +424,9 @@ class MockSCM(Mock):
# will actually be the root. Since getcwd() is wrong, use a globally fake root for now.
self.checkout_root = self.fake_checkout_root
+ def changed_files(self, git_commit=None):
+ return ["MockFile1"]
+
def create_patch(self, git_commit, changed_files=None):
return "Patch1"
diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/checkstyle.py b/WebKitTools/Scripts/webkitpy/tool/steps/checkstyle.py
index af38214..af66c50 100644
--- a/WebKitTools/Scripts/webkitpy/tool/steps/checkstyle.py
+++ b/WebKitTools/Scripts/webkitpy/tool/steps/checkstyle.py
@@ -52,6 +52,9 @@ class CheckStyle(AbstractStep):
args.append("--git-commit")
args.append(self._options.git_commit)
+ args.append("--diff-files")
+ args.extend(self._changed_files(state))
+
try:
self._run_script("check-webkit-style", args)
except ScriptError, e:
diff --git a/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp b/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp
index 2674801..5942ec8 100644
--- a/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp
+++ b/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp
@@ -45,7 +45,7 @@ InjectedBundleController::InjectedBundleController()
{
}
-void InjectedBundleController::initialize(WKBundleRef bundle)
+void InjectedBundleController::initialize(WKBundleRef bundle, WKTypeRef initializationUserData)
{
m_bundle = bundle;
@@ -57,6 +57,12 @@ void InjectedBundleController::initialize(WKBundleRef bundle)
didReceiveMessage
};
WKBundleSetClient(m_bundle, &client);
+
+ // Initialize the test from the "initializationUserData".
+ assert(WKGetTypeID(initializationUserData) == WKStringGetTypeID());
+ WKStringRef testName = static_cast<WKStringRef>(initializationUserData);
+
+ initializeTestNamed(bundle, Util::toSTD(testName));
}
void InjectedBundleController::didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
@@ -76,16 +82,6 @@ void InjectedBundleController::willDestroyPage(WKBundleRef bundle, WKBundlePageR
void InjectedBundleController::didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
{
InjectedBundleController* self = static_cast<InjectedBundleController*>(const_cast<void*>(clientInfo));
-
- if (WKStringIsEqualToUTF8CString(messageName, "BundleTestInstantiator")) {
- assert(WKGetTypeID(messageBody) == WKStringGetTypeID());
- WKStringRef messageBodyString = static_cast<WKStringRef>(messageBody);
-
- self->initializeTestNamed(bundle, Util::toSTD(messageBodyString));
-
- return;
- }
-
assert(self->m_currentTest);
self->m_currentTest->didReceiveMessage(bundle, messageName, messageBody);
}
diff --git a/WebKitTools/TestWebKitAPI/InjectedBundleController.h b/WebKitTools/TestWebKitAPI/InjectedBundleController.h
index 8b45fff..91c571e 100644
--- a/WebKitTools/TestWebKitAPI/InjectedBundleController.h
+++ b/WebKitTools/TestWebKitAPI/InjectedBundleController.h
@@ -38,7 +38,7 @@ class InjectedBundleController {
public:
static InjectedBundleController& shared();
- void initialize(WKBundleRef);
+ void initialize(WKBundleRef, WKTypeRef);
void dumpTestNames();
void initializeTestNamed(WKBundleRef bundle, const std::string&);
diff --git a/WebKitTools/TestWebKitAPI/InjectedBundleMain.cpp b/WebKitTools/TestWebKitAPI/InjectedBundleMain.cpp
index 8f9e8ad..355c35b 100644
--- a/WebKitTools/TestWebKitAPI/InjectedBundleMain.cpp
+++ b/WebKitTools/TestWebKitAPI/InjectedBundleMain.cpp
@@ -31,7 +31,7 @@ extern "C" __declspec(dllexport)
#else
extern "C"
#endif
-void WKBundleInitialize(WKBundleRef bundle)
+void WKBundleInitialize(WKBundleRef bundle, WKTypeRef initializationUserData)
{
- TestWebKitAPI::InjectedBundleController::shared().initialize(bundle);
+ TestWebKitAPI::InjectedBundleController::shared().initialize(bundle, initializationUserData);
}
diff --git a/WebKitTools/TestWebKitAPI/PlatformUtilities.cpp b/WebKitTools/TestWebKitAPI/PlatformUtilities.cpp
index 2fadf3a..281fb13 100644
--- a/WebKitTools/TestWebKitAPI/PlatformUtilities.cpp
+++ b/WebKitTools/TestWebKitAPI/PlatformUtilities.cpp
@@ -37,13 +37,10 @@ WKContextRef createContextForInjectedBundleTest(const std::string& testName)
{
WKRetainPtr<WKStringRef> injectedBundlePath(AdoptWK, createInjectedBundlePath());
WKContextRef context = WKContextCreateWithInjectedBundlePath(injectedBundlePath.get());
-
- WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("BundleTestInstantiator"));
- WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithUTF8CString(testName.c_str()));
- // Enqueue message to instantiate the bundle test.
- WKContextPostMessageToInjectedBundle(context, messageName.get(), messageBody.get());
-
+ WKRetainPtr<WKStringRef> testNameString(AdoptWK, WKStringCreateWithUTF8CString(testName.c_str()));
+ WKContextSetInitializationUserDataForInjectedBundle(context, testNameString.get());
+
return context;
}
diff --git a/WebKitTools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp b/WebKitTools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp
index b7db746..0ccee5a 100644
--- a/WebKitTools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp
+++ b/WebKitTools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp
@@ -41,10 +41,7 @@ static void didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef f
TEST_ASSERT(WKFrameGetFrameLoadState(frame) == kWKFrameLoadStateFinished);
WKURLRef url = WKFrameCopyProvisionalURL(frame);
- WKURLRef emptyURL = WKURLCreateWithUTF8CString("");
- TEST_ASSERT(WKURLIsEqual(url, emptyURL));
- WKRelease(url);
- WKRelease(emptyURL);
+ TEST_ASSERT(!url);
testDone = true;
}
diff --git a/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj b/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj
index 36eacc5..c130f45 100644
--- a/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj
+++ b/WebKitTools/WebKitLauncher/WebKitLauncher.xcodeproj/project.pbxproj
@@ -239,7 +239,14 @@
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "WebKitLauncher" */;
compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
mainGroup = 29B97314FDCFA39411CA2CEA /* WebKit */;
projectDirPath = "";
projectRoot = "";
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl b/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl
index a0e36ad..583eb0a 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl
@@ -64,6 +64,8 @@ module WTR {
// Animation testing.
int numberOfActiveAnimations();
boolean pauseAnimationAtTimeOnElementWithId(in DOMString animationName, in double time, in DOMString elementId);
+ void suspendAnimations();
+ void resumeAnimations();
// UserContent testing.
void addUserScript(in DOMString source, in boolean runAtStart, in boolean allFrames);
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp
index b1bc89d..c4cf892 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp
@@ -31,7 +31,7 @@ extern "C" __declspec(dllexport)
#else
extern "C"
#endif
-void WKBundleInitialize(WKBundleRef bundle)
+void WKBundleInitialize(WKBundleRef bundle, WKTypeRef initializationUserData)
{
WTR::InjectedBundle::shared().initialize(bundle);
}
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp
index e828c46..de37383 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp
@@ -150,6 +150,18 @@ bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef anima
return WKBundleFramePauseAnimationOnElementWithId(mainFrame, toWK(animationName).get(), toWK(elementId).get(), time);
}
+void LayoutTestController::suspendAnimations()
+{
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ WKBundleFrameSuspendAnimations(mainFrame);
+}
+
+void LayoutTestController::resumeAnimations()
+{
+ WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+ WKBundleFrameResumeAnimations(mainFrame);
+}
+
JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
{
WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h
index dfafb55..427d05e 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h
@@ -91,7 +91,9 @@ public:
// Animation testing.
unsigned numberOfActiveAnimations() const;
bool pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId);
-
+ void suspendAnimations();
+ void resumeAnimations();
+
// Compositing testing.
JSRetainPtr<JSStringRef> layerTreeAsText() const;
diff --git a/WebKitTools/WebKitTestRunner/TestController.cpp b/WebKitTools/WebKitTestRunner/TestController.cpp
index c88062a..8ca0529 100644
--- a/WebKitTools/WebKitTestRunner/TestController.cpp
+++ b/WebKitTools/WebKitTestRunner/TestController.cpp
@@ -35,6 +35,9 @@
namespace WTR {
+static const double defaultLongTimeout = 30;
+static const double defaultShortTimeout = 5;
+
static WKURLRef blankURL()
{
static WKURLRef staticBlankURL = WKURLCreateWithUTF8CString("about:blank");
@@ -56,6 +59,8 @@ TestController::TestController(int argc, const char* argv[])
, m_usingServerMode(false)
, m_state(Initial)
, m_doneResetting(false)
+ , m_longTimeout(defaultLongTimeout)
+ , m_shortTimeout(defaultShortTimeout)
{
initialize(argc, argv);
controller = this;
@@ -146,6 +151,12 @@ void TestController::initialize(int argc, const char* argv[])
for (int i = 1; i < argc; ++i) {
std::string argument(argv[i]);
+ if (argument == "--timeout" && i + 1 < argc) {
+ m_longTimeout = atoi(argv[++i]);
+ // Scale up the short timeout to match.
+ m_shortTimeout = defaultShortTimeout * m_longTimeout / defaultLongTimeout;
+ continue;
+ }
if (argument == "--pixel-tests") {
m_dumpPixels = true;
continue;
@@ -253,7 +264,7 @@ void TestController::initialize(int argc, const char* argv[])
WKPageSetPageLoaderClient(m_mainWebView->page(), &pageLoaderClient);
}
-void TestController::resetStateToConsistentValues()
+bool TestController::resetStateToConsistentValues()
{
m_state = Resetting;
@@ -285,17 +296,21 @@ void TestController::resetStateToConsistentValues()
m_doneResetting = false;
WKPageLoadURL(m_mainWebView->page(), blankURL());
- TestController::runUntil(m_doneResetting);
+ runUntil(m_doneResetting, ShortTimeout);
+ return m_doneResetting;
}
-void TestController::runTest(const char* test)
+bool TestController::runTest(const char* test)
{
- resetStateToConsistentValues();
+ if (!resetStateToConsistentValues())
+ return false;
m_state = RunningTest;
m_currentInvocation.set(new TestInvocation(test));
m_currentInvocation->invoke();
m_currentInvocation.clear();
+
+ return true;
}
void TestController::runTestingServerLoop()
@@ -309,7 +324,8 @@ void TestController::runTestingServerLoop()
if (strlen(filenameBuffer) == 0)
continue;
- runTest(filenameBuffer);
+ if (!runTest(filenameBuffer))
+ break;
}
}
@@ -318,11 +334,18 @@ void TestController::run()
if (m_usingServerMode)
runTestingServerLoop();
else {
- for (size_t i = 0; i < m_paths.size(); ++i)
- runTest(m_paths[i].c_str());
+ for (size_t i = 0; i < m_paths.size(); ++i) {
+ if (!runTest(m_paths[i].c_str()))
+ break;
+ }
}
}
+void TestController::runUntil(bool& done, TimeoutDuration timeoutDuration)
+{
+ platformRunUntil(done, timeoutDuration == ShortTimeout ? m_shortTimeout : m_longTimeout);
+}
+
// WKContextInjectedBundleClient
void TestController::didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
diff --git a/WebKitTools/WebKitTestRunner/TestController.h b/WebKitTools/WebKitTestRunner/TestController.h
index b12f1b2..1396c94 100644
--- a/WebKitTools/WebKitTestRunner/TestController.h
+++ b/WebKitTools/WebKitTestRunner/TestController.h
@@ -53,22 +53,24 @@ public:
WKPageNamespaceRef pageNamespace() { return m_pageNamespace.get(); }
WKContextRef context() { return m_context.get(); }
- // Helper
- static void runUntil(bool& done);
+ // Runs the run loop until `done` is true or the timeout elapses.
+ enum TimeoutDuration { ShortTimeout, LongTimeout };
+ void runUntil(bool& done, TimeoutDuration);
private:
void initialize(int argc, const char* argv[]);
void run();
void runTestingServerLoop();
- void runTest(const char* pathOrURL);
+ bool runTest(const char* pathOrURL);
void platformInitialize();
void platformInitializeContext();
+ void platformRunUntil(bool& done, double timeout);
void initializeInjectedBundlePath();
void initializeTestPluginDirectory();
- void resetStateToConsistentValues();
+ bool resetStateToConsistentValues();
// WKContextInjectedBundleClient
static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*);
@@ -102,6 +104,9 @@ private:
};
State m_state;
bool m_doneResetting;
+
+ double m_longTimeout;
+ double m_shortTimeout;
};
} // namespace WTR
diff --git a/WebKitTools/WebKitTestRunner/TestInvocation.cpp b/WebKitTools/WebKitTestRunner/TestInvocation.cpp
index 04a56f1..e88de53 100644
--- a/WebKitTools/WebKitTestRunner/TestInvocation.cpp
+++ b/WebKitTools/WebKitTestRunner/TestInvocation.cpp
@@ -120,7 +120,11 @@ void TestInvocation::invoke()
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("BeginTest"));
WKContextPostMessageToInjectedBundle(TestController::shared().context(), messageName.get(), 0);
- TestController::runUntil(m_gotInitialResponse);
+ TestController::shared().runUntil(m_gotInitialResponse, TestController::ShortTimeout);
+ if (!m_gotInitialResponse) {
+ dump("Timed out waiting for initial response from web process\n");
+ return;
+ }
if (m_error) {
dump("FAIL\n");
return;
@@ -128,7 +132,11 @@ void TestInvocation::invoke()
WKPageLoadURL(TestController::shared().mainWebView()->page(), m_url.get());
- TestController::runUntil(m_gotFinalMessage);
+ TestController::shared().runUntil(m_gotFinalMessage, TestController::LongTimeout);
+ if (!m_gotFinalMessage) {
+ dump("Timed out waiting for final message from web process\n");
+ return;
+ }
if (m_error) {
dump("FAIL\n");
return;
diff --git a/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm b/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm
index be9aa33..268f718 100644
--- a/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm
+++ b/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm
@@ -45,10 +45,11 @@ void TestController::initializeTestPluginDirectory()
m_testPluginDirectory.adopt(WKStringCreateWithCFString((CFStringRef)[[NSBundle mainBundle] bundlePath]));
}
-void TestController::runUntil(bool& done)
+void TestController::platformRunUntil(bool& done, double timeout)
{
- while (!done)
- [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+ CFAbsoluteTime end = CFAbsoluteTimeGetCurrent() + timeout;
+ while (!done && CFAbsoluteTimeGetCurrent() < end)
+ [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
}
void TestController::platformInitializeContext()
diff --git a/WebKitTools/WebKitTestRunner/qt/TestControllerQt.cpp b/WebKitTools/WebKitTestRunner/qt/TestControllerQt.cpp
index d3aee4a..d4de1ba 100644
--- a/WebKitTools/WebKitTestRunner/qt/TestControllerQt.cpp
+++ b/WebKitTools/WebKitTestRunner/qt/TestControllerQt.cpp
@@ -83,8 +83,9 @@ void TestController::platformInitialize()
{
}
-void TestController::runUntil(bool& done)
+void TestController::platformRunUntil(bool& done, double)
{
+ // FIXME: Honor the timeout parameter <http://webkit.org/b/48941>.
RunUntilConditionLoop::start(done);
ASSERT(done);
}
@@ -93,7 +94,7 @@ static bool isExistingLibrary(const QString& path)
{
#if OS(WINDOWS) || OS(SYMBIAN)
const char* librarySuffixes[] = { ".dll" };
-#elif PLATFORM(MAC)
+#elif OS(MAC_OS_X)
const char* librarySuffixes[] = { ".bundle", ".dylib", ".so" };
#elif OS(UNIX)
const char* librarySuffixes[] = { ".so" };
diff --git a/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp b/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp
index 9643c40..3fd853f 100644
--- a/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp
+++ b/WebKitTools/WebKitTestRunner/win/TestControllerWin.cpp
@@ -120,15 +120,25 @@ void TestController::initializeTestPluginDirectory()
m_testPluginDirectory.adopt(WKStringCreateWithCFString(testPluginDirectoryPath.get()));
}
-void TestController::runUntil(bool& done)
+void TestController::platformRunUntil(bool& done, double timeout)
{
+ DWORD end = ::GetTickCount() + timeout * 1000;
while (!done) {
- MSG msg;
- BOOL result = GetMessage(&msg, 0, 0, 0);
- if (result == -1)
+ DWORD now = ::GetTickCount();
+ if (now > end)
+ return;
+
+ DWORD result = ::MsgWaitForMultipleObjectsEx(0, 0, end - now, QS_ALLINPUT, 0);
+ if (result == WAIT_TIMEOUT)
return;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
+
+ ASSERT(result == WAIT_OBJECT_0);
+ // There are messages in the queue. Process them.
+ MSG msg;
+ while (::PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) {
+ ::TranslateMessage(&msg);
+ ::DispatchMessageW(&msg);
+ }
}
}
diff --git a/WebKitTools/iExploder/htdocs/cssproperties.in b/WebKitTools/iExploder/htdocs/cssproperties.in
index 9ced1c3..d49eb8e 100644
--- a/WebKitTools/iExploder/htdocs/cssproperties.in
+++ b/WebKitTools/iExploder/htdocs/cssproperties.in
@@ -37,7 +37,6 @@
-webkit-box-pack
-webkit-box-reflect
-webkit-box-shadow
--webkit-box-sizing
-webkit-color-correction
-webkit-column-break-after
-webkit-column-break-before
@@ -156,6 +155,7 @@ border-top-style
border-top-width
border-width
bottom
+box-sizing
caption-side
clear
clip