summaryrefslogtreecommitdiffstats
path: root/WebKitTools
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-09-30 15:42:16 +0100
committerSteve Block <steveblock@google.com>2010-10-07 10:59:29 +0100
commitbec39347bb3bb5bf1187ccaf471d26247f28b585 (patch)
tree56bdc4c2978fbfd3d79d0d36d5d6c640ecc09cc8 /WebKitTools
parent90b7966e7815b262cd19ac25f03aaad9b21fdc06 (diff)
downloadexternal_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.zip
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.gz
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.bz2
Merge WebKit at r68651 : Initial merge by git.
Change-Id: I3d6bff59f17eedd6722723354f386fec9be8ad12
Diffstat (limited to 'WebKitTools')
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json3
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg10
-rw-r--r--WebKitTools/CMakeListsEfl.txt5
-rw-r--r--WebKitTools/CSSTestSuiteHarness/harness/harness.css220
-rw-r--r--WebKitTools/CSSTestSuiteHarness/harness/harness.html206
-rw-r--r--WebKitTools/CSSTestSuiteHarness/harness/harness.js1314
-rw-r--r--WebKitTools/ChangeLog1497
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.cpp19
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.h1
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp11
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h2
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp5
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h1
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowGeometryInitializedBeforeSetWindow.cpp83
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp24
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj48
-rw-r--r--WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp5
-rw-r--r--WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp23
-rw-r--r--WebKitTools/DumpRenderTree/chromium/LayoutTestController.h1
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestEventPrinter.cpp3
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShell.cpp2
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShell.h3
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp17
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TextInputController.cpp22
-rw-r--r--WebKitTools/DumpRenderTree/chromium/WebPreferences.cpp7
-rw-r--r--WebKitTools/DumpRenderTree/chromium/WebPreferences.h3
-rw-r--r--WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp90
-rw-r--r--WebKitTools/DumpRenderTree/gtk/EventSender.cpp60
-rw-r--r--WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp103
-rw-r--r--WebKitTools/DumpRenderTree/gtk/fonts.conf258
-rw-r--r--WebKitTools/DumpRenderTree/gtk/fonts/AHEM____.TTFbin0 -> 12480 bytes
-rw-r--r--WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf282
-rw-r--r--WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm5
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro5
-rw-r--r--WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp3
-rw-r--r--WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp18
-rw-r--r--WebKitTools/DumpRenderTree/qt/EventSenderQt.h6
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp2
-rw-r--r--WebKitTools/DumpRenderTree/qt/TextInputControllerQt.cpp2
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj46
-rw-r--r--WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp6
-rw-r--r--WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp6
-rwxr-xr-xWebKitTools/EWSTools/start-commit-queue.sh3
-rw-r--r--WebKitTools/EWebLauncher/main.c53
-rw-r--r--WebKitTools/GNUmakefile.am8
-rw-r--r--WebKitTools/MiniBrowser/Configurations/MiniBrowserCFLite.vsprops15
-rw-r--r--WebKitTools/MiniBrowser/Configurations/MiniBrowserCommon.vsprops8
-rw-r--r--WebKitTools/MiniBrowser/Configurations/MiniBrowserCoreFoundation.vsprops15
-rw-r--r--WebKitTools/MiniBrowser/MiniBrowser.vcproj153
-rw-r--r--WebKitTools/MiniBrowser/mac/BrowserWindowController.m15
-rw-r--r--WebKitTools/MiniBrowser/mac/MiniBrowser_Prefix.pch2
-rw-r--r--WebKitTools/MiniBrowser/win/BrowserView.cpp8
-rw-r--r--WebKitTools/QtTestBrowser/launcherwindow.cpp17
-rw-r--r--WebKitTools/QtTestBrowser/launcherwindow.h5
-rw-r--r--WebKitTools/QtTestBrowser/main.cpp35
-rw-r--r--WebKitTools/QtTestBrowser/urlloader.cpp21
-rw-r--r--WebKitTools/QtTestBrowser/urlloader.h7
-rw-r--r--WebKitTools/QtTestBrowser/utils.cpp4
-rw-r--r--WebKitTools/QtTestBrowser/webview.cpp4
-rw-r--r--WebKitTools/QtTestBrowser/webview.h2
-rw-r--r--WebKitTools/QueueStatusServer/handlers/queuestatus.py13
-rw-r--r--WebKitTools/QueueStatusServer/handlers/updatestatus.py17
-rw-r--r--WebKitTools/QueueStatusServer/model/activeworkitems.py42
-rw-r--r--WebKitTools/QueueStatusServer/templates/queuestatus.html7
-rwxr-xr-xWebKitTools/Scripts/build-webkit21
-rwxr-xr-xWebKitTools/Scripts/old-run-webkit-tests3
-rwxr-xr-xWebKitTools/Scripts/prepare-ChangeLog2
-rwxr-xr-xWebKitTools/Scripts/run-chromium-webkit-unit-tests51
-rwxr-xr-xWebKitTools/Scripts/test-webkitpy19
-rw-r--r--WebKitTools/Scripts/webkitdirs.pm79
-rw-r--r--WebKitTools/Scripts/webkitpy/common/config/committers.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/common/net/buildbot.py64
-rw-r--r--WebKitTools/Scripts/webkitpy/common/net/buildbot_unittest.py73
-rw-r--r--WebKitTools/Scripts/webkitpy/common/net/credentials.py20
-rw-r--r--WebKitTools/Scripts/webkitpy/common/net/credentials_unittest.py23
-rw-r--r--WebKitTools/Scripts/webkitpy/common/net/failuremap.py48
-rw-r--r--WebKitTools/Scripts/webkitpy/common/net/regressionwindow.py48
-rw-r--r--WebKitTools/Scripts/webkitpy/common/system/user.py35
-rw-r--r--WebKitTools/Scripts/webkitpy/common/system/user_unittest.py47
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.checksum1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.png1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/crash.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/exception.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/hang.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.checksum1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.png1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.checksum1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.png1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/keyboard.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check-expected.png1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_image.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_text.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/text-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/text.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/timeout.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.checksum1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.png1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/error-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/error.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.checksum1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.png1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.checksum1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.png1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.checksum1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.png1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt13
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/resources/README.txt2
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py17
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py12
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py39
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py7
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/base.py115
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py16
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py48
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py137
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py58
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py9
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py9
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py53
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py9
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py95
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py43
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py10
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py12
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/gtk.py7
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py7
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py12
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py7
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py2
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/test.py262
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/test_files.py (renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py)14
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/test_files_unittest.py68
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py59
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py2
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/win.py7
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py39
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py17
-rwxr-xr-xWebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py46
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py66
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py31
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py10
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py21
-rw-r--r--WebKitTools/Scripts/webkitpy/style/checkers/test_expectations.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/test/main.py12
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask.py158
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py194
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/bot/feeders.py73
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/bot/feeders_unittest.py70
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/bot/queueengine.py2
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/download.py2
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/openbugs.py4
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/queries.py47
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/queues.py253
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py160
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/queuestest.py5
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/rebaseline.py9
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot.py14
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/upload.py8
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/mocktool.py20
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/multicommandtool.py14
-rw-r--r--WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCFLite.vsprops12
-rw-r--r--WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCommon.vsprops5
-rw-r--r--WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCoreFoundation.vsprops12
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h1
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp4
-rw-r--r--WebKitTools/WebKitTestRunner/TestController.cpp5
-rw-r--r--WebKitTools/WebKitTestRunner/win/InjectedBundle.vcproj135
-rw-r--r--WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj147
-rw-r--r--WebKitTools/wx/packaging/build-mac-installer.py7
-rw-r--r--WebKitTools/wx/packaging/build-win-installer.py5
194 files changed, 6794 insertions, 1437 deletions
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json
index 54a0dfe..2a4a351 100644
--- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json
@@ -16,6 +16,7 @@
{ "name": "apple-macpro-2", "platform": "mac-snowleopard" },
{ "name": "apple-macpro-3", "platform": "mac-snowleopard" },
{ "name": "apple-macpro-4", "platform": "mac-leopard" },
+ { "name": "apple-macpro-5", "platform": "mac-leopard" },
{ "name": "apple-windows-1", "platform": "win"},
{ "name": "apple-windows-2", "platform": "win"},
@@ -64,7 +65,7 @@
},
{ "name": "Leopard Intel Debug (Tests)", "type": "Test", "builddir": "leopard-intel-debug-tests",
"platform": "mac-leopard", "configuration": "debug", "architectures": ["i386"],
- "slavenames": ["apple-xserve-3", "test-slave"]
+ "slavenames": ["apple-xserve-3", "test-slave", "apple-macpro-5"]
},
{ "name": "SnowLeopard Intel Release (Build)", "type": "Build", "builddir": "snowleopard-intel-release",
"platform": "mac-snowleopard", "configuration": "release", "architectures": ["x86_64"],
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
index aca3c65..d5cd6fb 100644
--- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
@@ -317,6 +317,14 @@ class RunWebKit2Tests(RunWebKitTests):
return RunWebKitTests.start(self)
+class RunChromiumWebKitUnitTests(shell.Test):
+ name = "webkit-unit-tests"
+ description = ["webkit-unit-tests running"]
+ descriptionDone = ["webkit-unit-tests"]
+ command = ["perl", "./WebKitTools/Scripts/run-chromium-webkit-unit-tests",
+ WithProperties("--%(configuration)s")]
+
+
class ArchiveTestResults(shell.ShellCommand):
command = ["python", "./WebKitTools/BuildSlaveSupport/test-result-archive",
WithProperties("--platform=%(platform)s"), WithProperties("--%(configuration)s"), "archive"]
@@ -399,6 +407,8 @@ class BuildAndTestFactory(Factory):
self.addStep(CompileWebKit)
if not platform.startswith("chromium"):
self.addStep(RunJavaScriptCoreTests)
+ if platform.startswith("chromium"):
+ self.addStep(RunChromiumWebKitUnitTests)
self.addStep(self.TestClass)
# Tiger's Python 2.3 is too old. WebKit Python requires 2.5+.
# Sadly we have no way to detect the version on the slave from here.
diff --git a/WebKitTools/CMakeListsEfl.txt b/WebKitTools/CMakeListsEfl.txt
index b9086ac..732b4b3 100644
--- a/WebKitTools/CMakeListsEfl.txt
+++ b/WebKitTools/CMakeListsEfl.txt
@@ -1,5 +1,4 @@
SET(EWebLauncher_SOURCES
- ${WebKit_THEME}
${WEBKITTOOLS_DIR}/EWebLauncher/main.c
)
@@ -50,6 +49,10 @@ IF (WTF_USE_CURL)
LIST(APPEND EWebLauncher_LINK_FLAGS ${CURL_LDFLAGS})
ENDIF ()
+# Override data directory. We always want to get a fresh theme.
+REMOVE_DEFINITIONS(-DDATA_DIR=\"${DATA_DIR}\")
+ADD_DEFINITIONS(-DDATA_DIR=\"${BUILD_DATA_DIR}\")
+
INCLUDE_DIRECTORIES(${EWebLauncher_INCLUDE_DIRECTORIES})
ADD_EXECUTABLE(Programs/EWebLauncher ${EWebLauncher_SOURCES})
TARGET_LINK_LIBRARIES(Programs/EWebLauncher ${EWebLauncher_LIBRARIES})
diff --git a/WebKitTools/CSSTestSuiteHarness/harness/harness.css b/WebKitTools/CSSTestSuiteHarness/harness/harness.css
new file mode 100644
index 0000000..8c0e7d1
--- /dev/null
+++ b/WebKitTools/CSSTestSuiteHarness/harness/harness.css
@@ -0,0 +1,220 @@
+/*
+ * 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.
+ */
+
+body {
+ font-family: Helvetica, sans-serif;
+ background-color: #DDD;
+}
+
+.controls {
+ border: 1px solid black;
+ width: 300px;
+ height: 660px;
+ float: left;
+ font-size: smaller;
+ padding: 4px;
+}
+
+.controls div {
+ margin: 4px;
+}
+
+.controls select {
+ width: 100%;
+}
+
+.details > div {
+ margin: 4px 0;
+}
+
+.actions {
+ margin-left: 320px;
+ border: 1px solid black;
+ font-size: smaller;
+ height: 30px;
+ padding: 4px;
+ margin-bottom: 8px;
+}
+
+.actions button {
+ font-size: 13px;
+ width: 5em;
+}
+
+.note {
+ font-size: 10px;
+ color: gray;
+}
+.action-buttons {
+ float: right;
+}
+
+#test-content {
+ margin-left: 320px;
+ height: 612px;
+ border: 1px solid black;
+ padding: 4px;
+ background-color: white;
+}
+
+.info > div {
+ margin: 6px 0;
+}
+
+.info .title {
+ font-size: larger;
+ font-weight: bold;
+}
+
+.info .url {
+ font-family: monospace;
+}
+
+.info .assertion, .info .flags {
+ font-size: smaller;
+}
+
+#test-content iframe {
+ border: 1px solid gray;
+ margin: 2px;
+}
+
+#test-content h2 {
+ font-size: 11pt;
+ margin: 2px 0 2px 0;
+ color: darkgray;
+}
+
+#test-list > option.untested {
+
+}
+
+#test-list > option.completed {
+ color: gray;
+}
+
+#test-content.with-ref {
+}
+
+.frame-wrapper {
+
+}
+
+.frame-wrapper iframe {
+ width: 98%;
+ height: 460px;
+}
+
+.frame-wrapper {
+ height: 500px;
+ width: 99%;
+ display: inline-block;
+}
+
+.with-ref > .frame-wrapper {
+ width: 49%;
+}
+
+#ref-wrapper {
+ height: 500px;
+ width: 49%;
+ display: none;
+}
+
+.with-ref > #ref-wrapper {
+ display: inline-block;
+}
+
+.results {
+ border: 1px solid black;
+ padding: 4px;
+ margin-top: 6px;
+}
+
+#output {
+ border: 1px solid black;
+ font-size: smaller;
+ height: 220px;
+ margin: 4px;
+ padding: 4px;
+ overflow-y: auto;
+ background-color: white;
+}
+
+#output > p {
+ margin: 0;
+}
+#output .pass {
+ color: green;
+}
+
+#output .fail {
+ color: red;
+}
+
+#output .skipped {
+ color: orange;
+}
+
+#output .invalid {
+ background: red;
+}
+
+.output-options {
+ float: right;
+ border: 1px solid black;
+ width: 200px;
+ height: 220px;
+ margin: 4px;
+ padding: 4px;
+ font-size: smaller;
+}
+
+.output-options select {
+ width: 90%;
+}
+
+.summary {
+ font-size: smaller;
+ margin: 4px;
+}
+
+.summary .label {
+ display: inline-block;
+ min-width: 5em;
+ margin: 0;
+}
+
+.summary span {
+ display: inline-block;
+ min-width: 3em;
+ text-align: right;
+ margin: 0;
+}
+
+.summary td {
+ text-align: right;
+ padding: 4px;
+}
diff --git a/WebKitTools/CSSTestSuiteHarness/harness/harness.html b/WebKitTools/CSSTestSuiteHarness/harness/harness.html
new file mode 100644
index 0000000..6bd47e5
--- /dev/null
+++ b/WebKitTools/CSSTestSuiteHarness/harness/harness.html
@@ -0,0 +1,206 @@
+<!--
+/*
+ * 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.
+ */
+-->
+
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <title>CSS 2.1 Test Harness</title>
+ <link rel="stylesheet" href="harness.css" type="text/css" media="screen" charset="utf-8">
+
+ <script src="http://code.jquery.com/jquery-1.4.2.min.js" type="text/javascript" charset="utf-8"></script>
+ <script src="harness.js" type="text/javascript" charset="utf-8"></script>
+
+ <script type="text/javascript" charset="utf-8">
+ var gTestSuite;
+ function setupTests()
+ {
+ gTestSuite = new TestSuite();
+ }
+
+ window.addEventListener('load', setupTests, false);
+
+ function skipTest()
+ {
+ gTestSuite.skipTest(document.getElementById('skip-reason').value);
+ }
+
+ function invalidTest()
+ {
+ gTestSuite.invalidTest();
+ }
+
+ function failTest()
+ {
+ gTestSuite.failTest();
+ }
+
+ function passTest()
+ {
+ gTestSuite.passTest();
+ }
+
+ function formatChanged()
+ {
+ var newFormat;
+ if (document.harness.format.html4.checked)
+ newFormat = 'html4';
+ else
+ newFormat = 'xhtml1';
+ gTestSuite.formatChanged(newFormat);
+ }
+
+ function testSelected()
+ {
+ var list = document.getElementById('test-list')
+ if (list.selectedIndex >= 0)
+ gTestSuite.goToTestIndex(list.selectedIndex);
+ else
+ gTestSuite.clearTest();
+ }
+
+ function resultsPopupChanged(popup)
+ {
+ gTestSuite.resultsPopupChanged(popup.selectedIndex);
+ }
+
+ function doExport()
+ {
+ gTestSuite.exportResults(document.getElementById('results-popup').selectedIndex);
+ }
+
+ /*
+ This conflicts badly with key handling in selects.
+ function keyHandler(event)
+ {
+ var charCode = String.fromCharCode(event.keyCode);
+ window.console.log('keyHandler')
+ switch (charCode) {
+ case 'P':
+ passTest();
+ break;
+
+ case 'F':
+ failTest();
+ break;
+
+ case 'I':
+ invalidTest();
+ break;
+
+ case 'S':
+ skipTest();
+ break;
+ }
+
+ event.stopPropagation();
+ event.preventDefault();
+ }
+
+ document.addEventListener('keyup', keyHandler, false);
+ */
+ </script>
+
+</head>
+<body>
+
+ <div class="controls">
+ <form name="harness" onsubmit="return false;">
+ <select id="chapters">
+ <option>Test category</option>
+ </select>
+ <div class="progress">
+ <div><span id="test-index">1</span> of <span id="chapter-test-count">200</span> unique tests</div>
+ </div>
+ <div class="details">
+ <div class="name">
+ <div class="test-type">
+ <input type="radio" name="format" id="html4" onchange="formatChanged()" checked><label for="html4">HTML4</label><br>
+ <input type="radio" name="format" id="xhtml1" onchange="formatChanged()"><label for="xhtml1">XHTML1</label>
+ </div>
+ </div>
+ </div>
+
+ <div>
+ <select id="test-list" size="40" onchange="testSelected()"></select>
+ </div>
+ </form>
+ </div>
+
+ <div class="actions">
+ <span>Skip reason:</span> <input type="text" id="skip-reason" size="50">
+ <button onclick="skipTest()" accesskey="s">Skip</button>
+ <span class="note">Use <i>Control-Option-letter</i> to trigger buttons via the keyboard.</span>
+ <div class="action-buttons">
+ <button onclick="invalidTest()" accesskey="i">Invalid</button>
+ <button onclick="failTest()" accesskey="f">Fail</button>
+ <button onclick="passTest()" accesskey="p">Pass</button>
+ </div>
+ </div>
+ <div id="test-content">
+ <div class="info">
+ <div class="title">Title: <span id="test-title"></span></div>
+ <div class="url">URL: <span id="test-url"></span></div>
+ <div class="assertion">Assertion: <span id="test-assertion"></span></div>
+ <div class="flags">Flags: <span id="test-flags"></span></div>
+ </div>
+
+ <div id="test-wrapper" class="frame-wrapper">
+ <h2>Test</h2>
+ <iframe id="test-frame"></iframe>
+ </div>
+ <div id="ref-wrapper" class="frame-wrapper">
+ <h2>Reference</h2>
+ <iframe id="ref-frame"></iframe>
+ </div>
+ </div>
+
+ <div class="results">
+ <div class="output-options">
+ <p>Show results for:</p>
+ <select id="results-popup" onchange="resultsPopupChanged(this)">
+ </select>
+ <button id="export-button" onclick="doExport()">Export...</button>
+ </div>
+ <div id="output"></div>
+ <div class="summary">
+ <table>
+ <tr>
+ <th></th><th>Passed</th><th>Failed</th><th>Skipped</th><th>Invalid</th><th>Tested</th><th>Total</th><th>% done</th>
+ </tr>
+ <tr>
+ <td class="label">HTML4:</td><td id="h-passed"></td><td id="h-failed"></td><td id="h-skipped"></td><td id="h-invalid"></td><td id="h-tested"></td><td id="h-total"></td><td id="h-percent"></td>
+ </tr>
+ <tr>
+ <td class="label">XHTML1:</td><td id="x-passed"></td><td id="x-failed"></td><td id="x-skipped"></td><td id="x-invalid"></td><td id="x-tested"></td><td id="x-total"></td><td id="x-percent"></td>
+ </tr>
+ </table>
+ </div>
+ </div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/WebKitTools/CSSTestSuiteHarness/harness/harness.js b/WebKitTools/CSSTestSuiteHarness/harness/harness.js
new file mode 100644
index 0000000..95262af
--- /dev/null
+++ b/WebKitTools/CSSTestSuiteHarness/harness/harness.js
@@ -0,0 +1,1314 @@
+/*
+ * 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.
+ */
+
+// requires jQuery
+
+const kTestSuiteVersion = '20100917';
+const kTestSuiteHome = '../' + kTestSuiteVersion + '/';
+const kTestInfoDataFile = 'testinfo.data';
+
+const kChapterData = [
+ {
+ 'file' : 'about.html',
+ 'title' : 'About the CSS 2.1 Specification',
+ },
+ {
+ 'file' : 'intro.html',
+ 'title' : 'Introduction to CSS 2.1',
+ },
+ {
+ 'file' : 'conform.html',
+ 'title' : 'Conformance: Requirements and Recommendations',
+ },
+ {
+ 'file' : "syndata.html",
+ 'title' : 'Syntax and basic data types',
+ },
+ {
+ 'file' : 'selector.html' ,
+ 'title' : 'Selectors',
+ },
+ {
+ 'file' : 'cascade.html',
+ 'title' : 'Assigning property values, Cascading, and Inheritance',
+ },
+ {
+ 'file' : 'media.html',
+ 'title' : 'Media types',
+ },
+ {
+ 'file' : 'box.html' ,
+ 'title' : 'Box model',
+ },
+ {
+ 'file' : 'visuren.html',
+ 'title' : 'Visual formatting model',
+ },
+ {
+ 'file' :'visudet.html',
+ 'title' : 'Visual formatting model details',
+ },
+ {
+ 'file' : 'visufx.html',
+ 'title' : 'Visual effects',
+ },
+ {
+ 'file' : 'generate.html',
+ 'title' : 'Generated content, automatic numbering, and lists',
+ },
+ {
+ 'file' : 'page.html',
+ 'title' : 'Paged media',
+ },
+ {
+ 'file' : 'colors.html',
+ 'title' : 'Colors and Backgrounds',
+ },
+ {
+ 'file' : 'fonts.html',
+ 'title' : 'Fonts',
+ },
+ {
+ 'file' : 'text.html',
+ 'title' : 'Text',
+ },
+ {
+ 'file' : 'tables.html',
+ 'title' : 'Tables',
+ },
+ {
+ 'file' : 'ui.html',
+ 'title' : 'User interface',
+ },
+ {
+ 'file' : 'aural.html',
+ 'title' : 'Appendix A. Aural style sheets',
+ },
+ {
+ 'file' : 'refs.html',
+ 'title' : 'Appendix B. Bibliography',
+ },
+ {
+ 'file' : 'changes.html',
+ 'title' : 'Appendix C. Changes',
+ },
+ {
+ 'file' : 'sample.html',
+ 'title' : 'Appendix D. Default style sheet for HTML 4',
+ },
+ {
+ 'file' : 'zindex.html',
+ 'title' : 'Appendix E. Elaborate description of Stacking Contexts',
+ },
+ {
+ 'file' : 'propidx.html',
+ 'title' : 'Appendix F. Full property table',
+ },
+ {
+ 'file' : 'grammar.html',
+ 'title' : 'Appendix G. Grammar of CSS',
+ },
+ {
+ 'file' : 'other.html',
+ 'title' : 'Other',
+ },
+];
+
+
+const kHTML4Data = {
+ 'path' : 'html4',
+ 'suffix' : '.htm'
+};
+
+const kXHTML1Data = {
+ 'path' : 'xhtml1',
+ 'suffix' : '.xht'
+};
+
+// Results popup
+const kResultsSelector = [
+ {
+ 'name': 'All Tests',
+ 'handler' : function(self) { self.showResultsForAllTests(); },
+ 'exporter' : function(self) { self.exportResultsForAllTests(); }
+ },
+ {
+ 'name': 'Completed Tests',
+ 'handler' : function(self) { self.showResultsForCompletedTests(); },
+ 'exporter' : function(self) { self.exportResultsForCompletedTests(); }
+ },
+ {
+ 'name': 'Passing Tests',
+ 'handler' : function(self) { self.showResultsForTestsWithStatus('pass'); },
+ 'exporter' : function(self) { self.exportResultsForTestsWithStatus('pass'); }
+ },
+ {
+ 'name': 'Failing Tests',
+ 'handler' : function(self) { self.showResultsForTestsWithStatus('fail'); },
+ 'exporter' : function(self) { self.exportResultsForTestsWithStatus('fail'); }
+ },
+ {
+ 'name': 'Skipped Tests',
+ 'handler' : function(self) { self.showResultsForTestsWithStatus('skipped'); },
+ 'exporter' : function(self) { self.exportResultsForTestsWithStatus('skipped'); }
+ },
+ {
+ 'name': 'Invalid Tests',
+ 'handler' : function(self) { self.showResultsForTestsWithStatus('invalid'); },
+ 'exporter' : function(self) { self.exportResultsForTestsWithStatus('invalid'); }
+ },
+ {
+ 'name': 'Tests where HTML4 and XHTML1 results differ',
+ 'handler' : function(self) { self.showResultsForTestsWithMismatchedResults(); },
+ 'exporter' : function(self) { self.exportResultsForTestsWithMismatchedResults(); }
+ },
+ {
+ 'name': 'Tests Not Run',
+ 'handler' : function(self) { self.showResultsForTestsNotRun(); },
+ 'exporter' : function(self) { self.exportResultsForTestsNotRun(); }
+ }
+];
+
+function Test(testInfoLine)
+{
+ var fields = testInfoLine.split('\t');
+
+ this.id = fields[0];
+ this.reference = fields[1];
+ this.title = fields[2];
+ this.flags = fields[3];
+ this.links = fields[4];
+ this.assertion = fields[5];
+
+ this.completed = false; // true if this test has a result (pass, fail or skip)
+
+ if (!this.links)
+ this.links = "other.html"
+}
+
+function ChapterSection(link)
+{
+ var result= link.match(/^([.\w]+)(#.+)?$/);
+ if (result != null) {
+ this.file = result[1];
+ this.anchor = result[2];
+ }
+
+ this.tests = [];
+}
+
+function Chapter(chapterInfo)
+{
+ this.file = chapterInfo.file;
+ this.title = chapterInfo.title;
+ this.testCount = 0;
+ this.sections = []; // array of ChapterSection
+}
+
+Chapter.prototype.description = function()
+{
+ return this.title + ' (' + this.testCount + ' tests)';
+}
+
+// Utils
+String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }
+
+function TestSuite()
+{
+ this.chapterSections = {}; // map of links to ChapterSections
+ this.tests = {}; // map of test id to test info
+
+ this.chapters = {}; // map of file name to chapter
+ this.currentChapter = null;
+
+ this.currentChapterTests = []; // array of tests for the current chapter.
+ this.currChapterTestIndex = -1; // index of test in the current chapter
+
+ this.format = '';
+ this.formatChanged('html4');
+
+ this.testInfoLoaded = false;
+
+ this.populatingDatabase = false;
+
+ var testInfoPath = kTestSuiteHome + kTestInfoDataFile;
+ this.loadTestInfo(testInfoPath);
+}
+
+TestSuite.prototype.loadTestInfo = function(testInfoPath)
+{
+ var _self = this;
+ this.asyncLoad(testInfoPath, 'data', function(data, status) {
+ _self.testInfoDataLoaded(data, status);
+ });
+}
+
+TestSuite.prototype.testInfoDataLoaded = function(data, status)
+{
+ if (status != 'success') {
+ alert("Failed to load testinfo.data. Database of tests will not be initialized.");
+ return;
+ }
+
+ this.parseTests(data);
+ this.buildChapters();
+
+ this.testInfoLoaded = true;
+
+ this.fillChapterPopup(document.getElementById('chapters'));
+
+ this.initializeControls();
+
+ this.openDatabase();
+}
+
+TestSuite.prototype.parseTests = function(data)
+{
+ var lines = data.split('\n');
+
+ // First line is column labels
+ for (var i = 1; i < lines.length; ++i) {
+ var test = new Test(lines[i]);
+ if (test.id.length > 0)
+ this.tests[test.id] = test;
+ }
+}
+
+TestSuite.prototype.buildChapters = function()
+{
+ for (var testID in this.tests) {
+ var currTest = this.tests[testID];
+
+ // FIXME: tests with more than one link will be presented to the user
+ // twice. Be smarter about avoiding this.
+ var testLinks = currTest.links.split(',');
+ for (var i = 0; i < testLinks.length; ++i) {
+ var link = testLinks[i];
+ var section = this.chapterSections[link];
+ if (!section) {
+ section = new ChapterSection(link);
+ this.chapterSections[link] = section;
+ }
+
+ section.tests.push(currTest);
+ }
+ }
+
+ for (var i = 0; i < kChapterData.length; ++i) {
+ var chapter = new Chapter(kChapterData[i]);
+ chapter.index = i;
+ this.chapters[chapter.file] = chapter;
+ }
+
+ for (var sectionName in this.chapterSections) {
+ var section = this.chapterSections[sectionName];
+
+ var file = section.file;
+ var chapter = this.chapters[file];
+ if (!chapter)
+ window.console.log('failed to find chapter ' + file + ' in chapter data.');
+ chapter.sections.push(section);
+ }
+
+ for (var chapterName in this.chapters) {
+ var currChapter = this.chapters[chapterName];
+ currChapter.sections.sort();
+
+ var testCount = 0;
+ for (var s = 0; s < currChapter.sections.length; ++s)
+ testCount += currChapter.sections[s].tests.length;
+
+ currChapter.testCount = testCount;
+ }
+}
+
+TestSuite.prototype.indexOfChapter = function(chapter)
+{
+ for (var i = 0; i < kChapterData.length; ++i) {
+ if (kChapterData[i].file == chapter.file)
+ return i;
+ }
+
+ window.console.log('indexOfChapter for ' + chapter.file + ' failed');
+ return -1;
+}
+
+TestSuite.prototype.chapterAtIndex = function(index)
+{
+ if (index < 0 || index >= kChapterData.length)
+ return null;
+
+ return this.chapters[kChapterData[index].file];
+}
+
+TestSuite.prototype.fillChapterPopup = function(select)
+{
+ select.innerHTML = ''; // Remove all children.
+
+ for (var i = 0; i < kChapterData.length; ++i) {
+ var chapterData = kChapterData[i];
+ var chapter = this.chapters[chapterData.file];
+
+ var option = document.createElement('option');
+ option.innerText = chapter.description();
+ option._chapter = chapter;
+
+ select.appendChild(option);
+ }
+}
+
+TestSuite.prototype.buildTestListForChapter = function(chapter)
+{
+ this.currentChapterTests = [];
+
+ for (var i in chapter.sections) {
+ var currSection = chapter.sections[i];
+ // FIXME: why do I need the assignment?
+ this.currentChapterTests = this.currentChapterTests.concat(currSection.tests);
+ }
+
+ // FIXME: test may occur more than once.
+ this.currentChapterTests.sort(function(a, b) {
+ return a.id.localeCompare(b.id);
+ });
+}
+
+TestSuite.prototype.initializeControls = function()
+{
+ var chaptersPopup = document.getElementById('chapters');
+
+ var _self = this;
+ chaptersPopup.addEventListener('change', function() {
+ _self.chapterPopupChanged();
+ }, false);
+
+ this.chapterPopupChanged();
+
+ // Results popup
+ var resultsPopup = document.getElementById('results-popup');
+ resultsPopup.innerHTML = '';
+
+ for (var i = 0; i < kResultsSelector.length; ++i) {
+ var option = document.createElement('option');
+ option.innerText = kResultsSelector[i].name;
+
+ resultsPopup.appendChild(option);
+ }
+}
+
+TestSuite.prototype.chapterPopupChanged = function()
+{
+ var chaptersPopup = document.getElementById('chapters');
+ var selectedChapter = chaptersPopup.options[chaptersPopup.selectedIndex]._chapter;
+
+ this.setSelectedChapter(selectedChapter);
+}
+
+TestSuite.prototype.fillTestList = function()
+{
+ var testList = document.getElementById('test-list');
+ testList.innerHTML = '';
+
+ for (var i = 0; i < this.currentChapterTests.length; ++i) {
+ var currTest = this.currentChapterTests[i];
+
+ var option = document.createElement('option');
+ option.innerText = currTest.id;
+ option.className = currTest.completed ? 'completed' : 'untested';
+ option._test = currTest;
+ testList.appendChild(option);
+ }
+}
+
+TestSuite.prototype.updateTestList = function()
+{
+ var testList = document.getElementById('test-list');
+
+ var options = testList.getElementsByTagName('option');
+ for (var i = 0; i < options.length; ++i) {
+ var currOption = options[i];
+ currOption.className = currOption._test.completed ? 'completed' : 'untested';
+ }
+}
+
+TestSuite.prototype.setSelectedChapter = function(chapter)
+{
+ this.currentChapter = chapter;
+ this.buildTestListForChapter(this.currentChapter);
+ this.currChapterTestIndex = -1;
+
+ this.fillTestList();
+ this.goToTestIndex(0);
+
+ var chaptersPopup = document.getElementById('chapters');
+ chaptersPopup.selectedIndex = this.indexOfChapter(chapter);
+}
+
+/* ------------------------------------------------------- */
+
+TestSuite.prototype.passTest = function()
+{
+ this.recordResult(this.currentTestName(), 'pass');
+ this.nextTest();
+}
+
+TestSuite.prototype.failTest = function()
+{
+ this.recordResult(this.currentTestName(), 'fail');
+ this.nextTest();
+}
+
+TestSuite.prototype.invalidTest = function()
+{
+ this.recordResult(this.currentTestName(), 'invalid');
+ this.nextTest();
+}
+
+TestSuite.prototype.skipTest = function(reason)
+{
+ this.recordResult(this.currentTestName(), 'skipped', reason);
+ this.nextTest();
+}
+
+TestSuite.prototype.nextTest = function()
+{
+ if (this.currChapterTestIndex < this.currentChapterTests.length - 1)
+ this.goToTestIndex(this.currChapterTestIndex + 1);
+ else {
+ var currChapterIndex = this.indexOfChapter(this.currentChapter);
+ this.goToChapterIndex(currChapterIndex + 1);
+ }
+}
+
+TestSuite.prototype.previousTest = function()
+{
+ if (this.currChapterTestIndex > 0)
+ this.goToTestIndex(this.currChapterTestIndex - 1);
+ else {
+ var currChapterIndex = this.indexOfChapter(this.currentChapter);
+ if (currChapterIndex > 0)
+ this.goToChapterIndex(currChapterIndex - 1);
+ }
+}
+
+/* ------------------------------------------------------- */
+
+TestSuite.prototype.goToTestIndex = function(index)
+{
+ if (index >= 0 && index < this.currentChapterTests.length) {
+ this.currChapterTestIndex = index;
+ this.loadCurrentTest();
+ }
+}
+
+TestSuite.prototype.goToChapterIndex = function(chapterIndex)
+{
+ if (chapterIndex >= 0 && chapterIndex < kChapterData.length) {
+ var chapterFile = kChapterData[chapterIndex].file;
+ this.setSelectedChapter(this.chapters[chapterFile]);
+ }
+}
+
+TestSuite.prototype.currentTestName = function()
+{
+ if (this.currChapterTestIndex < 0 || this.currChapterTestIndex >= this.currentChapterTests.length)
+ return undefined;
+
+ return this.currentChapterTests[this.currChapterTestIndex].id;
+}
+
+TestSuite.prototype.loadCurrentTest = function()
+{
+ var theTest = this.currentChapterTests[this.currChapterTestIndex];
+ if (!theTest) {
+ this.configureForManualTest();
+ this.clearTest();
+ return;
+ }
+
+ if (theTest.reference) {
+ this.configureForRefTest();
+ this.loadRef(theTest);
+ } else {
+ this.configureForManualTest();
+ }
+
+ this.loadTest(theTest);
+
+ document.getElementById('test-index').innerText = this.currChapterTestIndex + 1;
+ document.getElementById('chapter-test-count').innerText = this.currentChapterTests.length;
+
+ document.getElementById('test-list').selectedIndex = this.currChapterTestIndex;
+}
+
+TestSuite.prototype.configureForRefTest = function()
+{
+ $('#test-content').addClass('with-ref');
+}
+
+TestSuite.prototype.configureForManualTest = function()
+{
+ $('#test-content').removeClass('with-ref');
+}
+
+TestSuite.prototype.loadTest = function(test)
+{
+ var iframe = document.getElementById('test-frame');
+ iframe.src = this.urlForTest(test.id);
+
+ document.getElementById('test-title').innerText = test.title;
+ document.getElementById('test-url').innerText = this.pathForTest(test.id);
+ document.getElementById('test-assertion').innerText = test.assertion;
+ document.getElementById('test-flags').innerText = test.flags;
+}
+
+TestSuite.prototype.clearTest = function()
+{
+ var iframe = document.getElementById('test-frame');
+ iframe.src = 'about:blank';
+
+ document.getElementById('test-title').innerText = '';
+ document.getElementById('test-url').innerText = '';
+ document.getElementById('test-assertion').innerText = '';
+ document.getElementById('test-flags').innerText = '';
+}
+
+TestSuite.prototype.loadRef = function(test)
+{
+ var iframe = document.getElementById('ref-frame');
+ iframe.src = this.urlForTest(testInfo.reference);
+}
+
+TestSuite.prototype.loadTestByName = function(testName)
+{
+ var currChapterInfo = this.chapterInfoMap[this.currChapterName];
+
+ var testIndex = currChapterInfo.testNames.indexOf(testName);
+ if (testIndex >= 0 && testIndex < currChapterInfo.testNames.length)
+ this.goToTestIndex(testIndex);
+}
+
+TestSuite.prototype.pathForTest = function(testName)
+{
+ var prefix = this.formatInfo.path;
+ var suffix = this.formatInfo.suffix;
+
+ return prefix + '/' + testName + suffix;
+}
+
+TestSuite.prototype.urlForTest = function(testName)
+{
+ return kTestSuiteHome + this.pathForTest(testName);
+}
+
+/* ------------------------------------------------------- */
+
+TestSuite.prototype.recordResult = function(testName, resolution, comment)
+{
+ if (!testName)
+ return;
+
+ this.beginAppendingOutput();
+ this.appendResultToOutput(this.formatInfo, testName, resolution, comment);
+ this.endAppendingOutput();
+
+ if (comment == undefined)
+ comment = '';
+
+ this.storeTestResult(testName, this.format, resolution, comment, navigator.userAgent);
+ this.markTestCompleted(testName);
+ this.updateTestList();
+
+ this.updateSummaryData();
+}
+
+TestSuite.prototype.beginAppendingOutput = function()
+{
+}
+
+TestSuite.prototype.endAppendingOutput = function()
+{
+ var output = document.getElementById('output');
+ output.scrollTop = output.scrollHeight;
+}
+
+TestSuite.prototype.appendResultToOutput = function(formatData, testName, resolution, comment)
+{
+ var output = document.getElementById('output');
+
+ var result = formatData.path + '/' + testName + formatData.suffix + '\t' + resolution;
+ if (comment)
+ result += '\t(' + comment + ')';
+
+ var line = document.createElement('p');
+ line.className = resolution;
+ line.appendChild(document.createTextNode(result));
+ output.appendChild(line);
+}
+
+TestSuite.prototype.clearOutput = function()
+{
+ document.getElementById('output').innerHTML = '';
+}
+
+/* ------------------------------------------------------- */
+
+TestSuite.prototype.formatChanged = function(formatString)
+{
+ if (this.format == formatString)
+ return;
+
+ this.format = formatString;
+
+ if (formatString == 'html4')
+ this.formatInfo = kHTML4Data;
+ else
+ this.formatInfo = kXHTML1Data;
+
+ this.loadCurrentTest();
+}
+
+/* ------------------------------------------------------- */
+
+TestSuite.prototype.asyncLoad = function(url, type, handler)
+{
+ $.get(url, handler, type);
+}
+
+/* ------------------------------------------------------- */
+
+TestSuite.prototype.exportResults = function(resultTypeIndex)
+{
+ var resultInfo = kResultsSelector[resultTypeIndex];
+ if (!resultInfo)
+ return;
+
+ resultInfo.exporter(this);
+}
+
+TestSuite.prototype.exportHeader = function()
+{
+ var result = '# Safari 5.0.2' + ' ' + navigator.platform + '\n';
+ result += '# ' + navigator.userAgent + '\n';
+ result += '# http://test.csswg.org/suites/css2.1/' + kTestSuiteVersion + '/\n';
+ result += 'testname\tresult\n';
+
+ return result;
+}
+
+TestSuite.prototype.createExportLine = function(formatData, testName, resolution, comment)
+{
+ var result = formatData.path + '/' + testName + '\t' + resolution;
+ if (comment)
+ result += '\t(' + comment + ')';
+ return result;
+}
+
+TestSuite.prototype.exportQueryComplete = function(data)
+{
+ window.open("data:text/plain," + escape(data))
+}
+
+TestSuite.prototype.resultsPopupChanged = function(index)
+{
+ var resultInfo = kResultsSelector[index];
+ if (!resultInfo)
+ return;
+
+ this.clearOutput();
+ resultInfo.handler(this);
+
+ var enableExport = resultInfo.exporter != undefined;
+ document.getElementById('export-button').disabled = !enableExport;
+}
+
+/* -------------------------------------------------------- */
+
+TestSuite.prototype.exportResultsCompletion = function(exportTests)
+{
+ window.console.log('exportResultsCompletion')
+ // Lame workaround for ORDER BY not working
+ exportTests.sort(function(a, b) {
+ return a.test.localeCompare(b.test);
+ });
+
+ var exportLines = [];
+ for (var i = 0; i < exportTests.length; ++i) {
+ var currTest = exportTests[i];
+ if (currTest.html4 != '')
+ exportLines.push(currTest.html4);
+ if (currTest.xhtml1 != '')
+ exportLines.push(currTest.xhtml1);
+ }
+
+ var exportString = this.exportHeader() + exportLines.join('\n');
+ this.exportQueryComplete(exportString);
+}
+
+/* -------------------------------------------------------- */
+
+TestSuite.prototype.showResultsForCompletedTests = function()
+{
+ this.beginAppendingOutput();
+
+ var _self = this;
+ this.queryDatabaseForCompletedTests(
+ function(item) {
+ if (item.hstatus)
+ _self.appendResultToOutput(kHTML4Data, item.test, item.hstatus, item.hcomment);
+
+ if (item.xstatus)
+ _self.appendResultToOutput(kXHTML1Data, item.test, item.xstatus, item.xcomment);
+ },
+ function() {
+ _self.endAppendingOutput();
+ }
+ );
+}
+
+TestSuite.prototype.exportResultsForCompletedTests = function()
+{
+ var exportTests = []; // each test will have html and xhtml items on it
+
+ var _self = this;
+ this.queryDatabaseForCompletedTests(
+ function(item) {
+ var htmlLine = '';
+ if (item.hstatus)
+ htmlLine= _self.createExportLine(kHTML4Data, item.test, item.hstatus, item.hcomment);
+
+ var xhtmlLine = '';
+ if (item.xstatus)
+ xhtmlLine = _self.createExportLine(kXHTML1Data, item.test, item.xstatus, item.xcomment);
+
+ exportTests.push({
+ 'test' : item.test,
+ 'html4' : htmlLine,
+ 'xhtml1' : xhtmlLine });
+ },
+ function() {
+ _self.exportResultsCompletion(exportTests);
+ }
+ );
+}
+
+
+/* -------------------------------------------------------- */
+
+TestSuite.prototype.showResultsForAllTests = function()
+{
+ this.beginAppendingOutput();
+
+ var _self = this;
+ this.queryDatabaseForAllTests('test',
+ function(item) {
+ _self.appendResultToOutput(kHTML4Data, item.test, item.hstatus, item.hcomment);
+ _self.appendResultToOutput(kXHTML1Data, item.test, item.xstatus, item.xcomment);
+ },
+ function() {
+ _self.endAppendingOutput();
+ });
+}
+
+TestSuite.prototype.exportResultsForAllTests = function()
+{
+ var exportTests = [];
+
+ var _self = this;
+ this.queryDatabaseForAllTests('test',
+ function(item) {
+ var htmlLine= _self.createExportLine(kHTML4Data, item.test, item.hstatus, item.hcomment);
+ var xhtmlLine = _self.createExportLine(kXHTML1Data, item.test, item.xstatus, item.xcomment);
+ exportTests.push({
+ 'test' : item.test,
+ 'html4' : htmlLine,
+ 'xhtml1' : xhtmlLine });
+ },
+ function() {
+ _self.exportResultsCompletion(exportTests);
+ }
+ );
+}
+
+/* -------------------------------------------------------- */
+
+TestSuite.prototype.showResultsForTestsNotRun = function()
+{
+ this.beginAppendingOutput();
+
+ var _self = this;
+ this.queryDatabaseForTestsNotRun(
+ function(item) {
+ if (!item.hstatus)
+ _self.appendResultToOutput(kHTML4Data, item.test, '?', item.hcomment);
+ if (!item.xstatus)
+ _self.appendResultToOutput(kXHTML1Data, item.test, '?', item.xcomment);
+ },
+ function() {
+ _self.endAppendingOutput();
+ }
+ );
+}
+
+TestSuite.prototype.exportResultsForTestsNotRun = function()
+{
+ var exportTests = [];
+
+ var _self = this;
+ this.queryDatabaseForTestsNotRun(
+ function(item) {
+ var htmlLine = '';
+ if (!item.hstatus)
+ htmlLine= _self.createExportLine(kHTML4Data, item.test, '?', item.hcomment);
+
+ var xhtmlLine = '';
+ if (!item.xstatus)
+ xhtmlLine = _self.createExportLine(kXHTML1Data, item.test, '?', item.xcomment);
+
+ exportTests.push({
+ 'test' : item.test,
+ 'html4' : htmlLine,
+ 'xhtml1' : xhtmlLine });
+ },
+ function() {
+ _self.exportResultsCompletion(exportTests);
+ }
+ );
+}
+
+/* -------------------------------------------------------- */
+
+TestSuite.prototype.showResultsForTestsWithStatus = function(status)
+{
+ this.beginAppendingOutput();
+
+ var _self = this;
+ this.queryDatabaseForTestsWithStatus(status,
+ function(item) {
+ if (item.hstatus == status)
+ _self.appendResultToOutput(kHTML4Data, item.test, item.hstatus, item.hcomment);
+ if (item.xstatus == status)
+ _self.appendResultToOutput(kXHTML1Data, item.test, item.xstatus, item.xcomment);
+ },
+ function() {
+ _self.endAppendingOutput();
+ }
+ );
+}
+
+TestSuite.prototype.exportResultsForTestsWithStatus = function(status)
+{
+ var exportTests = [];
+
+ var _self = this;
+ this.queryDatabaseForTestsWithStatus(status,
+ function(item) {
+ var htmlLine = '';
+ if (item.hstatus == status)
+ htmlLine= _self.createExportLine(kHTML4Data, item.test, item.hstatus, item.hcomment);
+
+ var xhtmlLine = '';
+ if (item.xstatus == status)
+ xhtmlLine = _self.createExportLine(kXHTML1Data, item.test, item.xstatus, item.xcomment);
+
+ exportTests.push({
+ 'test' : item.test,
+ 'html4' : htmlLine,
+ 'xhtml1' : xhtmlLine });
+ },
+ function() {
+ _self.exportResultsCompletion(exportTests);
+ }
+ );
+}
+
+/* -------------------------------------------------------- */
+
+TestSuite.prototype.showResultsForTestsWithMismatchedResults = function()
+{
+ this.beginAppendingOutput();
+
+ var _self = this;
+ this.queryDatabaseForTestsWithMixedStatus(
+ function(item) {
+ _self.appendResultToOutput(kHTML4Data, item.test, item.hstatus, item.hcomment);
+ _self.appendResultToOutput(kXHTML1Data, item.test, item.xstatus, item.xcomment);
+ },
+ function() {
+ _self.endAppendingOutput();
+ }
+ );
+}
+
+TestSuite.prototype.exportResultsForTestsWithMismatchedResults = function()
+{
+ var exportTests = [];
+
+ var _self = this;
+ this.queryDatabaseForTestsWithMixedStatus(
+ function(item) {
+ var htmlLine= _self.createExportLine(kHTML4Data, item.test, item.hstatus, item.hcomment);
+ var xhtmlLine = _self.createExportLine(kXHTML1Data, item.test, item.xstatus, item.xcomment);
+ exportTests.push({
+ 'test' : item.test,
+ 'html4' : htmlLine,
+ 'xhtml1' : xhtmlLine });
+ },
+ function() {
+ _self.exportResultsCompletion(exportTests);
+ }
+ );
+}
+
+/* -------------------------------------------------------- */
+
+TestSuite.prototype.markTestCompleted = function(testID)
+{
+ var test = this.tests[testID];
+ if (!test) {
+ window.console.log('markTestCompleted to find test ' + testID);
+ return;
+ }
+
+ test.completed = true;
+}
+
+TestSuite.prototype.testCompletionStateChanged = function()
+{
+ // update the test list
+ this.updateTestList();
+}
+
+TestSuite.prototype.loadTestStatus = function()
+{
+ var _self = this;
+ this.queryDatabaseForCompletedTests(
+ function(item) {
+ _self.markTestCompleted(item.test);
+ },
+ function() {
+ _self.testCompletionStateChanged();
+ }
+ );
+}
+
+/* -------------------------------------------------------- */
+
+TestSuite.prototype.updateSummaryData = function()
+{
+ this.queryDatabaseForSummary(
+ function(results) {
+
+ var hTotal, xTotal;
+ var hDone, xDone;
+
+ for (var i = 0; i < results.length; ++i) {
+ var result = results[i];
+
+ switch (result.name) {
+ case 'h-total': hTotal = result.count; break;
+ case 'x-total': xTotal = result.count; break;
+ case 'h-tested': hDone = result.count; break;
+ case 'x-tested': xDone = result.count; break;
+ }
+
+ document.getElementById(result.name).innerText = result.count;
+ }
+
+ // We should get these all together.
+ if (hTotal) {
+ document.getElementById('h-percent').innerText = Math.round(100.0 * hDone / hTotal);
+ document.getElementById('x-percent').innerText = Math.round(100.0 * xDone / xTotal);
+ }
+ }
+ );
+}
+
+/* ------------------------------------------------------- */
+// Database stuff
+
+function errorHandler(transaction, error)
+{
+ alert('Database error: ' + error.message);
+ window.console.log('Database error: ' + error.message);
+}
+
+TestSuite.prototype.openDatabase = function()
+{
+ if (!'openDatabase' in window) {
+ alert('Your browser does not support client-side SQL databases, so results will not be stored.');
+ return;
+ }
+
+ var _self = this;
+ this.db = window.openDatabase('css21testsuite', '1.0', 'CSS 2.1 test suite results', 10 * 1024 * 1024, function() {
+ _self.databaseCreated();
+ }, errorHandler);
+
+ this.updateSummaryData();
+ this.loadTestStatus();
+}
+
+TestSuite.prototype.databaseCreated = function(db)
+{
+ this.populatingDatabase = true;
+
+ var _self = this;
+ this.db.transaction(function (tx) {
+ // hstatus: HTML4 result
+ // xstatus: XHTML1 result
+ tx.executeSql('CREATE TABLE tests (test PRIMARY KEY UNIQUE, ref, title, flags, links, assertion, hstatus, hcomment, xstatus, xcomment)', null,
+ function(tx, results) {
+ _self.populateDatabaseFromTestInfoData();
+ }, errorHandler);
+ });
+}
+
+TestSuite.prototype.storeTestResult = function(test, format, result, comment, useragent)
+{
+ if (!this.db)
+ return;
+
+ this.db.transaction(function (tx) {
+ if (format == 'html4')
+ tx.executeSql('UPDATE tests SET hstatus=?, hcomment=? WHERE test=?\n', [result, comment, test], null, errorHandler);
+ else if (format == 'xhtml1')
+ tx.executeSql('UPDATE tests SET xstatus=?, xcomment=? WHERE test=?\n', [result, comment, test], null, errorHandler);
+ });
+}
+
+TestSuite.prototype.populateDatabaseFromTestInfoData = function(testInfoURL)
+{
+ if (!this.testInfoLoaded) {
+ window.console.log('Tring to populate database before testinfo.data has been loaded');
+ return;
+ }
+
+ var _self = this;
+ this.db.transaction(function (tx) {
+ for (var testID in _self.tests) {
+ var currTest = _self.tests[testID];
+ tx.executeSql('INSERT INTO tests (test, ref, title, flags, links, assertion) VALUES (?, ?, ?, ?, ?, ?)', [currTest.id, currTest.reference, currTest.title, currTest.flags, currTest.links, currTest.assertion], null, errorHandler);
+ }
+
+ _self.populatingDatabase = false;
+ });
+
+}
+
+TestSuite.prototype.queryDatabaseForAllTests = function(sortKey, perRowHandler, completionHandler)
+{
+ if (this.populatingDatabase)
+ return;
+
+ var _self = this;
+ this.db.transaction(function (tx) {
+ if (_self.populatingDatabase)
+ return;
+ var query;
+ var args = [];
+ if (sortKey != '') {
+ query = 'SELECT * FROM tests ORDER BY ? ASC'; // ORDER BY doesn't seem to work
+ args.push(sortKey);
+ }
+ else
+ query = 'SELECT * FROM tests';
+
+ tx.executeSql(query, args, function(tx, results) {
+
+ var len = results.rows.length;
+ for (var i = 0; i < len; ++i)
+ perRowHandler(results.rows.item(i));
+
+ completionHandler();
+ }, errorHandler);
+ });
+}
+
+TestSuite.prototype.queryDatabaseForTestsWithStatus = function(status, perRowHandler, completionHandler)
+{
+ if (this.populatingDatabase)
+ return;
+
+ var _self = this;
+ this.db.transaction(function (tx) {
+ if (_self.populatingDatabase)
+ return;
+ tx.executeSql('SELECT * FROM tests WHERE hstatus=? OR xstatus=?', [status, status], function(tx, results) {
+
+ var len = results.rows.length;
+ for (var i = 0; i < len; ++i)
+ perRowHandler(results.rows.item(i));
+
+ completionHandler();
+ }, errorHandler);
+ });
+}
+
+TestSuite.prototype.queryDatabaseForTestsWithMixedStatus = function(perRowHandler, completionHandler)
+{
+ if (this.populatingDatabase)
+ return;
+
+ var _self = this;
+ this.db.transaction(function (tx) {
+ if (_self.populatingDatabase)
+ return;
+ tx.executeSql('SELECT * FROM tests WHERE hstatus IS NOT NULL AND xstatus IS NOT NULL AND hstatus <> xstatus', [], function(tx, results) {
+
+ var len = results.rows.length;
+ for (var i = 0; i < len; ++i)
+ perRowHandler(results.rows.item(i));
+
+ completionHandler();
+ }, errorHandler);
+ });
+}
+
+TestSuite.prototype.queryDatabaseForCompletedTests = function(perRowHandler, completionHandler)
+{
+ if (this.populatingDatabase)
+ return;
+
+ var _self = this;
+ this.db.transaction(function (tx) {
+
+ if (_self.populatingDatabase)
+ return;
+
+ tx.executeSql('SELECT * FROM tests WHERE hstatus IS NOT NULL OR xstatus IS NOT NULL', [], function(tx, results) {
+ var len = results.rows.length;
+ for (var i = 0; i < len; ++i)
+ perRowHandler(results.rows.item(i));
+
+ completionHandler();
+ }, errorHandler);
+ });
+}
+
+TestSuite.prototype.queryDatabaseForTestsNotRun = function(perRowHandler, completionHandler)
+{
+ if (this.populatingDatabase)
+ return;
+
+ var _self = this;
+ this.db.transaction(function (tx) {
+ if (_self.populatingDatabase)
+ return;
+
+ tx.executeSql('SELECT * FROM tests WHERE hstatus IS NULL OR xstatus IS NULL', [], function(tx, results) {
+
+ var len = results.rows.length;
+ for (var i = 0; i < len; ++i)
+ perRowHandler(results.rows.item(i));
+
+ completionHandler();
+ }, errorHandler);
+ });
+}
+
+/*
+
+ completionHandler gets called an array of results,
+ which may be some or all of:
+
+ data = [
+ { 'name' : ,
+ 'count' :
+ },
+ ]
+
+ where name is one of:
+
+ 'h-total'
+ 'h-tested'
+ 'h-passed'
+ 'h-failed'
+ 'h-skipped'
+
+ 'x-total'
+ 'x-tested'
+ 'x-passed'
+ 'x-failed'
+ 'x-skipped'
+
+ */
+
+
+TestSuite.prototype.countTestsWithColumnValue = function(tx, completionHandler, column, value, label)
+{
+ var allRowsCount = 'COUNT(*)';
+
+ tx.executeSql('SELECT COUNT(*) FROM tests WHERE ' + column + '=?', [value], function(tx, results) {
+ var data = [];
+ if (results.rows.length > 0)
+ data.push({ 'name' : label, 'count' : results.rows.item(0)[allRowsCount] })
+ completionHandler(data);
+ }, errorHandler);
+}
+
+TestSuite.prototype.queryDatabaseForSummary = function(completionHandler)
+{
+ if (!this.db || this.populatingDatabase)
+ return;
+
+ var _self = this;
+ this.db.transaction(function (tx) {
+
+ if (_self.populatingDatabase)
+ return;
+
+ var allRowsCount = 'COUNT(*)';
+ var html4RowsCount = 'COUNT(hstatus)';
+ var xhtml1RowsCount = 'COUNT(xstatus)';
+
+ tx.executeSql('SELECT COUNT(*), COUNT(hstatus), COUNT(xstatus) FROM tests', [], function(tx, results) {
+
+ var data = [];
+ if (results.rows.length > 0) {
+ var rowItem = results.rows.item(0);
+ data.push({ 'name' : 'h-total' , 'count' : rowItem[allRowsCount] })
+ data.push({ 'name' : 'x-total' , 'count' : rowItem[allRowsCount] })
+ data.push({ 'name' : 'h-tested', 'count' : rowItem[html4RowsCount] })
+ data.push({ 'name' : 'x-tested', 'count' : rowItem[xhtml1RowsCount] })
+ }
+ completionHandler(data);
+
+ }, errorHandler);
+
+ _self.countTestsWithColumnValue(tx, completionHandler, 'hstatus', 'pass', 'h-passed');
+ _self.countTestsWithColumnValue(tx, completionHandler, 'xstatus', 'pass', 'x-passed');
+
+ _self.countTestsWithColumnValue(tx, completionHandler, 'hstatus', 'fail', 'h-failed');
+ _self.countTestsWithColumnValue(tx, completionHandler, 'xstatus', 'fail', 'x-failed');
+
+ _self.countTestsWithColumnValue(tx, completionHandler, 'hstatus', 'skipped', 'h-skipped');
+ _self.countTestsWithColumnValue(tx, completionHandler, 'xstatus', 'skipped', 'x-skipped');
+
+ _self.countTestsWithColumnValue(tx, completionHandler, 'hstatus', 'invalid', 'h-invalid');
+ _self.countTestsWithColumnValue(tx, completionHandler, 'xstatus', 'invalid', 'x-invalid');
+ });
+}
+
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index eace217..b2a3791 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,1500 @@
+2010-09-28 Johnny Ding <jnd@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ https://bugs.webkit.org/show_bug.cgi?id=41292
+ Add a new parameter to the test plugin to allow specifying a script
+ and a mouse/keyboard event. The specified script will be evaluated
+ in the browser when the specified event is received by the plugin.
+
+ * DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp:
+ (pluginAllocate):
+ * DumpRenderTree/TestNetscapePlugIn/PluginObject.h:
+ * DumpRenderTree/TestNetscapePlugIn/main.cpp:
+ (NPP_New):
+ (handleEventCarbon):
+ (handleEventCocoa):
+
+2010-09-28 Simon Fraser <simon.fraser@apple.com>
+
+ Fix export by adding missing argument.
+
+ * CSSTestSuiteHarness/harness/harness.js:
+ (TestSuite.prototype.showResultsForAllTests):
+
+2010-09-28 Kevin Ollivier <kevino@theolliviers.com>
+
+ [wx] Build fix, add missing import.
+
+ * wx/packaging/build-win-installer.py:
+
+2010-09-28 Simon Fraser <simon.fraser@apple.com>
+
+ No review
+
+ Show which tests have been run by dimming them out in the test list.
+
+ Adjust some element sizes.
+
+ * CSSTestSuiteHarness/harness/harness.css:
+ (#test-list > option.untested):
+ (#test-list > option.completed):
+ (#output):
+ (.output-options):
+ * CSSTestSuiteHarness/harness/harness.js:
+ (Test):
+ (TestSuite.prototype.fillTestList):
+ (TestSuite.prototype.updateTestList):
+ (TestSuite.prototype.setSelectedChapter):
+ (TestSuite.prototype.recordResult):
+ (TestSuite.prototype.markTestCompleted):
+ (TestSuite.prototype.testCompletionStateChanged):
+ (TestSuite.prototype.loadTestStatus):
+
+2010-09-28 Simon Fraser <simon.fraser@apple.com>
+
+ No review.
+
+ Implement export of various queries on the test database, sharing
+ code with that which displays results inline.
+
+ * CSSTestSuiteHarness/harness/harness.js:
+ ():
+ (TestSuite.prototype.exportResultsCompletion.var):
+ (TestSuite.prototype.exportResultsCompletion):
+ (TestSuite.prototype.showResultsForCompletedTests):
+ (TestSuite.prototype.exportResultsForCompletedTests):
+ (TestSuite.prototype.showResultsForAllTests):
+ (TestSuite.prototype.exportResultsForAllTests):
+ (TestSuite.prototype.exportResultsForTestsNotRun):
+ (TestSuite.prototype.exportResultsForTestsWithStatus):
+ (TestSuite.prototype.exportResultsForTestsWithMismatchedResults):
+
+2010-09-28 Simon Fraser <simon.fraser@apple.com>
+
+ No review.
+
+ Work around uncertainty about the order of database
+ transactions when creating the database, so that we don't
+ try to query the table before it has been created.
+
+ * CSSTestSuiteHarness/harness/harness.js:
+ (TestSuite):
+ (TestSuite.prototype.databaseCreated):
+ (TestSuite.prototype.storeTestResult):
+ (TestSuite.prototype.populateDatabaseFromTestInfoData):
+ (TestSuite.prototype.queryDatabaseForTestsWithStatus):
+ (TestSuite.prototype.queryDatabaseForTestsWithMixedStatus):
+ (TestSuite.prototype.queryDatabaseForCompletedTests):
+ (TestSuite.prototype.queryDatabaseForTestsNotRun):
+
+2010-09-28 Tony Chang <tony@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ add python keyring support to webkit-patch
+ https://bugs.webkit.org/show_bug.cgi?id=41269
+
+ * Scripts/webkitpy/common/net/credentials.py: Add the ability to read passwords using
+ the python keyring module
+ * Scripts/webkitpy/common/net/credentials_unittest.py:
+ * Scripts/webkitpy/common/system/user.py: Allow confirm() to default to no and add testing params.
+ * Scripts/webkitpy/common/system/user_unittest.py:
+ * Scripts/webkitpy/tool/mocktool.py:
+
+2010-09-28 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [Cairo] FreeType fonts should obey FontConfig hinting/anti-aliasing settings
+ https://bugs.webkit.org/show_bug.cgi?id=46740
+
+ * DumpRenderTree/gtk/fonts/fonts.conf: Add specialized variants of common
+ fonts which can be used to fully test FontConfig rendering settings.
+
+2010-09-28 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [gtk] Fedora has a different path for the liberation fonts
+ https://bugs.webkit.org/show_bug.cgi?id=46709
+
+ When searching for DRT fonts, also look in the path where those fonts
+ are commonly found on Fedora systems.
+
+ * DumpRenderTree/gtk/DumpRenderTree.cpp:
+ (initializeFonts): Include logic for looking for Fedora-style font paths.
+
+2010-09-28 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Andreas Kling.
+
+ run-webkit-tests needs an updated list of directories with webgl tests
+ https://bugs.webkit.org/show_bug.cgi?id=46747
+
+ Update the list of directories containing WebGL tests and a unit test
+ which depends on this list.
+
+ * Scripts/old-run-webkit-tests: Update the list of directories.
+ * Scripts/webkitpy/layout_tests/port/webkit.py: Ditto.
+ * Scripts/webkitpy/layout_tests/port/webkit_unittest.py: Update the expected result.
+
+2010-09-28 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Introduce FailureMap to summaries the failures status of all the bots
+ https://bugs.webkit.org/show_bug.cgi?id=46700
+
+ This patch gives the SheriffBot a handle on the list of failing tests.
+
+ * Scripts/webkitpy/common/net/buildbot.py:
+ * Scripts/webkitpy/common/net/failuremap.py: Added.
+ * Scripts/webkitpy/tool/commands/queries.py:
+ * Scripts/webkitpy/tool/commands/sheriffbot.py:
+ * Scripts/webkitpy/tool/mocktool.py:
+
+2010-09-28 Adam Roben <aroben@apple.com>
+
+ Update for the addition of WKPageUIClient::didNotHandleKeyEvent
+
+ Fixes <http://webkit.org/b/46660> <rdar://problem/8483465> Need API to
+ tell a WebKit2 client application that a key event was not handled
+
+ Reviewed by Kenneth Rohde Christiansen and Sam Weinig.
+
+ * MiniBrowser/mac/BrowserWindowController.m:
+ (-[BrowserWindowController awakeFromNib]):
+ * MiniBrowser/win/BrowserView.cpp:
+ (BrowserView::create):
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::createOtherPage):
+ (WTR::TestController::initialize):
+
+2010-09-28 Simon Fraser <simon.fraser@apple.com>
+
+ Unreviewed.
+
+ Update the CSSTestSuiteHarness to not scrape the XHTML chapter files
+ for the test order, but instead use information from testinfo.data.
+
+ * CSSTestSuiteHarness/harness/harness.html:
+ * CSSTestSuiteHarness/harness/harness.js:
+
+2010-09-28 Kevin Ollivier <kevino@theolliviers.com>
+
+ [wx] Build fix, don't try to get the svn revision from the git repo when packaging,
+ it causes the process to hang on the gitorious repo.
+
+ * wx/packaging/build-mac-installer.py:
+ * wx/packaging/build-win-installer.py:
+
+2010-09-28 Adam Roben <aroben@apple.com>
+
+ Test that a plugin's HWND is sized/positioned before NPP_SetWindow is
+ called
+
+ Reviewed by Anders Carlsson.
+
+ Test for <http://webkit.org/b/46716> <rdar://problem/8482014>
+ Full-page Adobe Reader does not paint until window is resized
+
+ * DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp:
+ (PluginTest::NPP_SetWindow): Added. Just returns NPERR_NO_ERROR at
+ this level.
+
+ * DumpRenderTree/TestNetscapePlugIn/PluginTest.h: Declared
+ NPP_SetWindow.
+
+ * DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowGeometryInitializedBeforeSetWindow.cpp: Added.
+ (WindowGeometryInitializedBeforeSetWindow::NPP_SetWindow): Checks that
+ the plugin's HWND has a non-zero size and that its size/position
+ matches that specified in the NPWindow.
+
+ * DumpRenderTree/TestNetscapePlugIn/main.cpp:
+ (NPP_SetWindow): Call through to the PluginTest.
+
+ * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj:
+ Added WindowGeometryInitializedBeforeSetWindow.cpp, and let VS reorder
+ the files as it saw fit.
+
+2010-09-28 Benjamin Poulain <benjamin.poulain@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] Remove support for Qt 4.5
+ https://bugs.webkit.org/show_bug.cgi?id=46718
+
+ Remove the code for versions of Qt prior to 4.6.
+
+ * DumpRenderTree/qt/EventSenderQt.cpp:
+ (EventSender::addTouchPoint):
+ (EventSender::updateTouchPoint):
+ (EventSender::setTouchModifier):
+ (EventSender::touchStart):
+ (EventSender::touchMove):
+ (EventSender::touchEnd):
+ (EventSender::clearTouchPoints):
+ (EventSender::releaseTouchPoint):
+ (EventSender::sendTouchEvent):
+ * DumpRenderTree/qt/EventSenderQt.h:
+ * DumpRenderTree/qt/TextInputControllerQt.cpp:
+ (TextInputController::setMarkedText):
+ * QtTestBrowser/launcherwindow.cpp:
+ (LauncherWindow::LauncherWindow):
+ (LauncherWindow::initializeView):
+ (LauncherWindow::createChrome):
+ (LauncherWindow::sendTouchEvent):
+ (LauncherWindow::eventFilter):
+ (LauncherWindow::applyZoom):
+ (LauncherWindow::setTouchMocking):
+ * QtTestBrowser/launcherwindow.h:
+ * QtTestBrowser/utils.cpp:
+ (urlFromUserInput):
+ * QtTestBrowser/webview.cpp:
+ (WebViewGraphicsBased::animatedFlip):
+ (WebViewGraphicsBased::animatedYFlip):
+ * QtTestBrowser/webview.h:
+ (WebViewGraphicsBased::setYRotation):
+
+2010-09-28 İsmail Dönmez <ismail@namtrac.org>
+
+ Reviewed by Andreas Kling.
+
+ Fix DRT compilation on WinCE. Introduce a WCECOMPAT variable
+ which should point to wcecompat installation. Needs wcecompat
+ library from http://github.com/mauricek/wcecompat .
+
+ * DumpRenderTree/qt/DumpRenderTree.pro:
+ * DumpRenderTree/qt/DumpRenderTreeQt.cpp:
+ (WebCore::DumpRenderTree::resetToConsistentStateBeforeTesting):
+
+2010-09-28 Daniel Bates <dbates@rim.com>
+
+ Rollout changeset 68493 <http://trac.webkit.org/changeset/68493>
+ <https://bugs.webkit.org/show_bug.cgi?id=39136>
+
+ Rollout changeset 68493 because it broke Sheriffbot's rollout feature.
+ In particular, this change caused Sheriffbot to raise an exception when
+ trying to parse the bug id on a bug page. We need to look into this
+ some more.
+
+ * Scripts/webkitpy/common/net/bugzilla.py:
+ * Scripts/webkitpy/common/net/bugzilla_unittest.py:
+ * Scripts/webkitpy/tool/bot/sheriff.py:
+ * Scripts/webkitpy/tool/commands/download.py:
+ * Scripts/webkitpy/tool/commands/queues.py:
+ * Scripts/webkitpy/tool/commands/upload.py:
+ * Scripts/webkitpy/tool/steps/closebug.py:
+ * Scripts/webkitpy/tool/steps/obsoletepatches.py:
+ * Scripts/webkitpy/tool/steps/preparechangelog.py:
+ * Scripts/webkitpy/tool/steps/updatechangelogswithreviewer.py:
+
+2010-09-28 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Move RegressionWindow further up the dependency chain
+ https://bugs.webkit.org/show_bug.cgi?id=46698
+
+ Baby steps towards pushing this information into bug posts.
+
+ * Scripts/webkitpy/common/net/buildbot.py:
+ * Scripts/webkitpy/common/net/buildbot_unittest.py:
+ * Scripts/webkitpy/common/net/regressionwindow.py:
+ * Scripts/webkitpy/tool/commands/queries.py:
+
+2010-09-27 Daniel Bates <dbates@rim.com>
+
+ Reviewed by Adam Barth.
+
+ sheriffbot can't roll out security patches
+ https://bugs.webkit.org/show_bug.cgi?id=39136
+
+ Make SheriffBot determine if it's authorized to view a bug
+ whose change it wants to rollout before it tries to rollout
+ the change.
+
+ Moreover, make both webkit-patch and Sheriffbot provide human-
+ readable error messages when they are not authorized to view
+ a bug and when a bug number is invalid.
+
+ Currently, Sheriffbot does not parse Bugzilla bugs for
+ <bug error="...">, which indicates an error when retrieving
+ a bug. In particular, error="NotPermitted" if a person (or bot)
+ is not authorized to view a bug. For such error="NotPermitted" bugs,
+ Sheriffbot raises an exception when parsing the bug report and
+ this exception does not explicitly indicate Sheriffbot's lack
+ of authorization. Instead, Sheriffbot should explicitly check
+ for the presence <bug error="..."> before operating on a bug
+ and error with a human-readable message if it's not permitted
+ to view it.
+
+ * Scripts/webkitpy/common/net/bugzilla.py: Added BugzillaError class.
+ * Scripts/webkitpy/common/net/bugzilla_unittest.py:
+ - Added unit test test_bug_parsing_for_bugzilla_not_permitted_error().
+ - Added unit test test_bug_parsing_for_bugzilla_not_found_error().
+ - Added unit test test_bug_parsing_for_bugzilla_invalid_bug_id_error().
+ * Scripts/webkitpy/tool/bot/sheriff.py: Modified to catch BugzillaError.
+ * Scripts/webkitpy/tool/commands/download.py: Ditto.
+ * Scripts/webkitpy/tool/commands/queues.py: Ditto.
+ * Scripts/webkitpy/tool/commands/upload.py: Ditto.
+ * Scripts/webkitpy/tool/steps/closebug.py: Ditto.
+ * Scripts/webkitpy/tool/steps/obsoletepatches.py: Ditto.
+ * Scripts/webkitpy/tool/steps/preparechangelog.py: Ditto.
+ * Scripts/webkitpy/tool/steps/updatechangelogswithreviewer.py: Ditto.
+
+2010-09-27 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Expose more more failure information from Buildbot to SheriffBot
+ https://bugs.webkit.org/show_bug.cgi?id=46697
+
+ This patch moves the information about what tests failured closer to
+ SheriffBot. There are still a couple more patches to go before
+ SheriffBot can post this information to bugs, but this is a step in
+ that direction. Yay for unit tests, which caught some bugs in earlier
+ versions of this patch.
+
+ * Scripts/webkitpy/common/net/buildbot.py:
+ * Scripts/webkitpy/common/net/buildbot_unittest.py:
+ * Scripts/webkitpy/common/net/regressionwindow.py: Added.
+ * Scripts/webkitpy/tool/commands/queries.py:
+
+2010-09-27 Eric Seidel <eric@webkit.org>
+
+ Unreviewed. Fixing 500 error seen in the status server.
+
+ It turns out that a = b = []; b.append(1); then a[0] will be 1!
+ This should have been obvious to me, I guess, but it was not what I was expecting.
+
+ * QueueStatusServer/model/activeworkitems.py:
+
+2010-09-27 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ commit-queue should reject patches that fail to land
+ https://bugs.webkit.org/show_bug.cgi?id=46694
+
+ This can happen, for example, if there's no reviewer. Without this
+ patch, we'll keep retrying the patch.
+
+ * Scripts/webkitpy/tool/bot/commitqueuetask.py:
+ * Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py:
+
+2010-09-27 Simon Fraser <simon.fraser@apple.com>
+
+ Rubber-stamped by Adele Peterson.
+
+ Add a harness for running the CSS 2.1 test suite.
+
+ This harness assumes that you've got a local a copy of the suite
+ adjacent to the 'harness' directory.
+
+ The harness lets you go through the tests in chapter order,
+ denoting pass/fail/skipped for each test.
+
+ It uses a client-side database to store the results of testing.
+
+ * CSSTestSuiteHarness/harness/harness.css: Added.
+ * CSSTestSuiteHarness/harness/harness.html: Added.
+ * CSSTestSuiteHarness/harness/harness.js: Added.
+
+2010-09-27 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Patch locks should expire if a patch is marked for retry
+ https://bugs.webkit.org/show_bug.cgi?id=46682
+
+ This was part Adam's original CommitQueueTask design,
+ but support for it was missing from the server.
+ I added the support, but triggering lock-release based on this
+ special "retry" status feels a bit strange so I added a FIXME.
+
+ I also changed the text in queuestatus.html to say "Lock Acquired"
+ since "Last Activity" isn't really true. We only update the lock
+ date when the patch is started, not on every status update.
+
+ I also noticed an exception in next-patch, which I fixed by re-writing
+ the unzip logic in activeworkitems.py again.
+
+ * QueueStatusServer/handlers/updatestatus.py:
+ * QueueStatusServer/model/activeworkitems.py:
+ * QueueStatusServer/templates/queuestatus.html:
+
+2010-09-27 Tony Chang <tony@chromium.org>
+
+ Reviewed by David Levin.
+
+ [chromium] fix a warning when compiling DRT on 32-bit linux
+ https://bugs.webkit.org/show_bug.cgi?id=46641
+
+ * DumpRenderTree/chromium/TestEventPrinter.cpp:
+ (DRTPrinter::handleImage):
+
+2010-09-27 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ queue-status should report when the patch was last locked to a queue
+ https://bugs.webkit.org/show_bug.cgi?id=46674
+
+ This isn't necessarily the best way to expose this information
+ but having this accessible via the web interface is very
+ useful until we come up with a nicer way to display this.
+
+ I also cleaned up the code in activeworkitems.py a little
+ to use list comprehensions and to have the code work with
+ pairs instead of two lists at once. Eventually I think those
+ item/time pairs need to be their own little helper class.
+
+ * QueueStatusServer/handlers/queuestatus.py:
+ * QueueStatusServer/model/activeworkitems.py:
+ * QueueStatusServer/templates/queuestatus.html:
+
+2010-09-27 Tony Chang <tony@chromium.org>
+
+ Reviewed by David Levin.
+
+ [chromium] fix detection of missing fonts on DRT
+ https://bugs.webkit.org/show_bug.cgi?id=46651
+
+ * DumpRenderTree/chromium/TestShellGtk.cpp:
+ (setupFontconfig): Only print an error message if lohit isn't found in both locations.
+
+2010-09-27 Tony Chang <tony@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ add webkit unit tests to the chromium testers
+ https://bugs.webkit.org/show_bug.cgi?id=46669
+
+ * BuildSlaveSupport/build.webkit.org-config/master.cfg:
+ * Scripts/run-chromium-webkit-unit-tests: Fix a bug where we weren't using the right configuration.
+
+2010-09-27 Kwang Yul Seo <skyul@company100.net>
+
+ Unreviewed.
+
+ Adding myself to the committers list.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-27 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ webkitpy.common.system.user_unittest.UserTest.test_prompt_with_list spams the console
+ https://bugs.webkit.org/show_bug.cgi?id=46634
+
+ Use OutputCapture to prevent console spam (and also check for expected
+ output).
+
+ * Scripts/webkitpy/common/system/user_unittest.py:
+
+2010-09-27 Eric Seidel <eric@webkit.org>
+
+ Reviewed by James Robinson.
+
+ start-commit-queue should abort any rebases in progress
+ https://bugs.webkit.org/show_bug.cgi?id=46640
+
+ webkit-patch commit-queue would do this itself, but this just
+ helps ensure that the commit-queue script is properly updated
+ before we run it (in the case where a previous rebase is in
+ progress the git svn rebase would not work before we run the
+ commit-queue).
+
+ * EWSTools/start-commit-queue.sh:
+
+2010-09-18 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] Clean up the DRT fonts.conf and switch to Liberation
+ https://bugs.webkit.org/show_bug.cgi?id=46038
+
+ Switch to Liberation fonts for GTK+ layout tests. This will make our
+ test results metric-compatible with many Windows/Chromium results. It
+ also simplifies the fonts.conf that we load and prepares the way for
+ fixing many font bugs.
+
+ * DumpRenderTree/gtk/DumpRenderTree.cpp:
+ (initializeFonts): Initialize a known list of fonts instead of loading
+ every font in the WEBKIT_TESTFONTS directory.
+ * DumpRenderTree/gtk/fonts.conf: Removed.
+ * DumpRenderTree/gtk/fonts/AHEM____.TTF: Copied from WebKitTools/DumpRenderTree/qt/fonts/AHEM____.TTF.
+ * DumpRenderTree/gtk/fonts/fonts.conf: Added.
+ * GNUmakefile.am: Modify FONTS_CONF_FILE to be FONTS_CONF_DIR, so that
+ we can load both fonts.conf and AHEM____.TTF from this location.
+ * Scripts/old-run-webkit-tests: Remove the check for WEBKIT_TESTFONTS, since
+ it is no longer used.
+
+2010-09-26 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ new-run-webkit-httpd fails if Perl is not installed
+ https://bugs.webkit.org/show_bug.cgi?id=46602
+
+ Make Port._read_configuration catch all exceptions, since trying to run
+ perl (because of _webkit_build_directory) when it's not installed throws
+ a WindowsError or OSError, not an IOError (this became an issue after
+ r68268, since ChromiumPort ends up calling Port.default_configuration in
+ its constructor, which means that we're ending up on this codepath in
+ non-NRWT cases too, e.g. for the Chromium NaCl tests, which use
+ new-run-webkit-httpd).
+
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ * Scripts/webkitpy/layout_tests/port/base_unittest.py:
+
+2010-09-26 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ Reviewed by Antonio Gomes.
+
+ [EFL] Add setting API to set a local storage database path.
+ https://bugs.webkit.org/show_bug.cgi?id=45446
+
+ Add a setting API to set local storage database path.
+
+ * EWebLauncher/main.c:
+ (on_key_down):
+ (browserCreate):
+ (main):
+
+2010-09-26 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Anders Carlsson.
+
+ Move shared WebKit2 API (used by both bundle and main API) to WebKit2/Shared/API
+ https://bugs.webkit.org/show_bug.cgi?id=46587
+
+ * WebKitTestRunner/InjectedBundle/InjectedBundle.h:
+
+2010-09-26 Antonio Gomes <agomes@rim.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ DRT/Mac nodesFromRect support
+
+ [Mac][DRT] Implement LayoutTestController::nodesFromRect
+ https://bugs.webkit.org/show_bug.cgi?id=46580
+
+ Implements LayoutTestController::nodesFromRect for Mac DRT, and
+ adding stubs for GTK+ and Windows.
+
+ * DumpRenderTree/LayoutTestController.cpp:
+ (nodesFromRectCallback):
+ (LayoutTestController::staticFunctions):
+ * DumpRenderTree/LayoutTestController.h:
+ (LayoutTestController::LayoutTestController::nodesFromRect):
+ * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+ (LayoutTestController::nodesFromRect):
+
+2010-09-25 Nicolas Weber <thakis@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46555
+ Fix typo in prepare-ChangeLog's help output.
+
+ * Scripts/prepare-ChangeLog:
+
+2010-09-24 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Implement WebKit2 callback equivalent to -[WebUIDelegate mouseDidMoveOverElement:modifierFlags:]
+ <rdar://problem/8359279>
+ https://bugs.webkit.org/show_bug.cgi?id=46546
+
+ * MiniBrowser/mac/BrowserWindowController.m:
+ (mouseDidMoveOverElement):
+ (-[BrowserWindowController awakeFromNib]):
+ * MiniBrowser/win/BrowserView.cpp:
+ (mouseDidMoveOverElement):
+ (BrowserView::create):
+ * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+ (WTR::InjectedBundlePage::InjectedBundlePage):
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::createOtherPage):
+ (WTR::TestController::initialize):
+
+2010-09-24 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Allow rebaselines for webkit-patch rebaseline to be chosen
+ https://bugs.webkit.org/show_bug.cgi?id=46407
+
+ Instead of always rebaselining all failing tests, allow a subset to be
+ chosen.
+
+ * Scripts/webkitpy/common/system/user.py:
+ * Scripts/webkitpy/tool/commands/rebaseline.py:
+
+2010-09-24 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Tony Chang.
+
+ [chromium] Implement TextInputController::firstRectForCharacterRange
+ https://bugs.webkit.org/show_bug.cgi?id=38100
+
+ Implemented TextInputController::firstRectForCharacterRange for chromium platform.
+ No new tests are added since we need to implement the same feature in chromium side
+ in order to enable any tests that uses this function.
+
+ * DumpRenderTree/chromium/TextInputController.cpp:
+ (TextInputController::firstRectForCharacterRange): Added.
+
+2010-09-24 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ commit-queue reports land failures as "PASS"
+ https://bugs.webkit.org/show_bug.cgi?id=46530
+
+ We were ignoring the return value of land instead of passing it back to
+ CommitQueue. Of course, this was the one case I forgot to test!
+
+ * Scripts/webkitpy/tool/bot/commitqueuetask.py:
+ * Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py:
+
+2010-09-24 Kenichi Ishibashi <bashi@google.com>
+
+ Reviewed by Eric Seidel.
+
+ new-run-webkit-tests prints out nothing when build-dumprendertree fails
+ https://bugs.webkit.org/show_bug.cgi?id=37563
+
+ Print error message when build-dumprendertree fails.
+
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+
+2010-09-24 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ NRWT doesn't respect config set with set-webkit-configuration
+ https://bugs.webkit.org/show_bug.cgi?id=46278
+
+ Use Port.default_configuration() instead of hardcoding Release in
+ ChromiumPort configuration initialization, so that we still inherit the
+ configuration set by set-webkit-configuration.
+
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_unittest.py:
+
+2010-09-24 Chang Shu <chang.shu@nokia.com>
+
+ Reviewed by Csaba Osztrogonác.
+
+ [Qt] Fix the code to check file existence.
+ https://bugs.webkit.org/show_bug.cgi?id=46465
+
+ * QtTestBrowser/main.cpp:
+ (main):
+
+2010-09-23 Tony Chang <tony@chromium.org>
+
+ Unreviewed, rolling out r68232.
+ http://trac.webkit.org/changeset/68232
+
+ Broken NRWT on the canary bots.
+
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+
+2010-09-23 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, build fix.
+
+ r68008 broke new-run-webkit-tests in that the chromium ports no
+ longer respect set-webkit-configuration. The correct fix for this
+ is being pursued in bug 46278 (along with a bunch of unit tests),
+ but in the meantime I'm reverting the particular lines that broke
+ things. This was tested by hand.
+
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+
+2010-09-23 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Anders Carlsson.
+
+ WebKit2 API: Need way to know when a frame is removed from the hierarchy
+ <rdar://problem/8414062>
+ https://bugs.webkit.org/show_bug.cgi?id=46432
+
+ * MiniBrowser/mac/BrowserWindowController.m:
+ (didRemoveFrameFromHierarchy):
+ (-[BrowserWindowController awakeFromNib]):
+ * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+ (WTR::InjectedBundlePage::InjectedBundlePage):
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::initialize):
+
+2010-09-23 Tony Chang <tony@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ [chromium] implement layoutTestController.sampleSVGAnimationForElementAtTime
+ https://bugs.webkit.org/show_bug.cgi?id=46426
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::LayoutTestController):
+ (LayoutTestController::sampleSVGAnimationForElementAtTime):
+ * DumpRenderTree/chromium/LayoutTestController.h:
+
+2010-09-23 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Nate Chapin.
+
+ [GTK] r68199 introduced two test failures
+ https://bugs.webkit.org/show_bug.cgi?id=46424
+
+ Fix a regression handling preference overrides that are attached to boolean properties.
+
+ * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+ (LayoutTestController::overridePreference): g_strcasecmp returns 0 when strings match
+ so we must check for that when converting a string to a boolean.
+
+2010-09-23 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by David Levin.
+
+ Fix a condition check in ServerProcess, which becomes relevant when reading binary data.
+ https://bugs.webkit.org/show_bug.cgi?id=46406
+
+ This breaks when the method is called with specified size of data (image data), and the
+ buffer hasn't yet reached this size.
+
+ * Scripts/webkitpy/layout_tests/port/server_process.py: Changed to check for values of
+ index larger than 0.
+
+2010-09-23 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Nate Chapin.
+
+ [GTK] Some tests from r68174 fail on the GTK+ bots
+ https://bugs.webkit.org/show_bug.cgi?id=46396
+
+ Simplify LayoutTestController::overridePreference to make it easier for
+ people unfamiliar with the code to keep the list of preferences up to date.
+ Add the conversion for enable-hyperlink-auditing.
+
+ * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+ (LayoutTestController::overridePreference): Use a simple if-else block to determine
+ out the property name for overrridePreference. Also simplify the logic for setting
+ string properties. Add the conversion for enable-hyperlink-auditing.
+
+2010-09-23 Tony Chang <tony@chromium.org>
+
+ Reviewed by David Levin.
+
+ [chromium] add caretBrowsingEnabled to WebSettings and DRT
+ https://bugs.webkit.org/show_bug.cgi?id=46388
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::overridePreference):
+ * DumpRenderTree/chromium/WebPreferences.cpp:
+ (WebPreferences::reset):
+ (WebPreferences::applyTo):
+ * DumpRenderTree/chromium/WebPreferences.h:
+
+2010-09-23 Nate Chapin <japhet@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Allow DRT to toggle hyperlink auditing (i.e., <a ping>).
+ https://bugs.webkit.org/show_bug.cgi?id=30458
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::overridePreference):
+ * DumpRenderTree/chromium/WebPreferences.cpp:
+ (WebPreferences::reset):
+ (WebPreferences::applyTo):
+ * DumpRenderTree/chromium/WebPreferences.h:
+ * DumpRenderTree/gtk/DumpRenderTree.cpp:
+ (resetDefaultsToConsistentValues):
+ * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+ (LayoutTestController::overridePreference):
+
+2010-09-21 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by David Levin.
+
+ Implement --enable-accelerated-2d-canvas flag in DumpRenderTree.
+ https://bugs.webkit.org/show_bug.cgi?id=46208
+
+ This flag allows the layout tests to be run with or without accelerated
+ 2D canvas rendering.
+
+ * DumpRenderTree/chromium/DumpRenderTree.cpp:
+ (main):
+ Declare the new flag string, and check for it on startup.
+ * DumpRenderTree/chromium/TestShell.cpp:
+ (TestShell::TestShell):
+ Add a boolean for the new flag, in order to preserve its value over
+ preferences reset.
+ (TestShell::resetWebSettings):
+ Set the new flag to the stored value on reset.
+ * DumpRenderTree/chromium/TestShell.h:
+ (TestShell::setAccelerated2dCanvasEnabled):
+ Add an accessor for the new flag.
+ * DumpRenderTree/chromium/WebPreferences.cpp:
+ (WebPreferences::reset):
+ Initialize the new flag to false.
+ (WebPreferences::applyTo):
+ Copy the flag's value to the WebSettings.
+ * DumpRenderTree/chromium/WebPreferences.h:
+ Add the new flag.
+
+2010-09-23 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Refactor QtWebKitPlatformPlugin interface
+
+ Make it easier to keep source-compability for the
+ QtWebKitPlatformPlugin interface, and run qmake
+ on the example (but not build) for convenience.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46345
+
+ * Scripts/webkitdirs.pm:
+
+2010-09-23 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Tweak some status messages that Eric thought were confusing
+ https://bugs.webkit.org/show_bug.cgi?id=46342
+
+ * Scripts/webkitpy/tool/commands/queues.py:
+ * Scripts/webkitpy/tool/commands/queues_unittest.py:
+
+2010-09-22 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Fix comm-queue typo
+ https://bugs.webkit.org/show_bug.cgi?id=46339
+
+ We were missing a "self". The real problem is that we didn't have an
+ integration test for the failure case.
+
+ * Scripts/webkitpy/tool/commands/queues.py:
+ * Scripts/webkitpy/tool/commands/queues_unittest.py:
+
+2010-09-22 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ commit-queue should log more detailed messages to the QueueStatusServer
+ https://bugs.webkit.org/show_bug.cgi?id=46333
+
+ When I created CommitQueueTask, I removed most of the previous logging.
+ This patch adds back more detailed logging so folks can see their patch
+ progress through the queue.
+
+ * Scripts/webkitpy/tool/bot/commitqueuetask.py:
+ * Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py:
+ * Scripts/webkitpy/tool/commands/queues.py:
+ * Scripts/webkitpy/tool/commands/queues_unittest.py:
+
+2010-09-22 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [Chromium] User style layout tests don't pass on Chromium
+ https://bugs.webkit.org/show_bug.cgi?id=46069
+
+ Fix a typo in LayoutTestController::addUserStyleSheet that was causing a
+ crash the Chromium DRT. Pass InjectInExistingDocuments to mimic DRT
+ behavior from other ports.
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::addUserStyleSheet):
+
+2010-09-22 Brent Fulgham <bfulgham@webkit.org>
+
+ Reviewed by Martin Robinson.
+
+ [WinCairo] Part 2: Update WebKitTestRunner and DumpRenderTree Build.
+ https://bugs.webkit.org/show_bug.cgi?id=46303.
+
+ * MiniBrowser/Configurations/MiniBrowserCFLite.vsprops: Added.
+ * MiniBrowser/Configurations/MiniBrowserCommon.vsprops: Moved
+ CoreFoundation-specific stuff to new MiniBrowserCoreFoundation
+ property sheet.
+ * MiniBrowser/Configurations/MiniBrowserCoreFoundation.vsprops: Added.
+ * MiniBrowser/MiniBrowser.vcproj: Updated configuration to use
+ appropriate property sheet for the build types.
+ * WebKitTestRunner/win/WebKitTestRunner.vcproj: Updated the
+ configuration to use appropriate property sheet for CoreFoundation
+ and CFLite-style builds.
+
+2010-09-22 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Optimize commit-queue performance for green trees
+ https://bugs.webkit.org/show_bug.cgi?id=46254
+
+ This patch redesigns the controller logic for the commit-queue. In the
+ new design, the controller exercises much finer-grained control over
+ the landing process. In particular:
+
+ - Patches that fail to apply now get rejected almost immediately.
+ - Patches that fail to build get rejects after two builds (instead of
+ three builds and one test run).
+ - Patches that run into a flaky test now get accepted after one build
+ and two test runs instead of three full build-and-test runs.
+
+ The main cost of these optimizations is that we don't find out the tree
+ has a failing test until the very end of the process, but if the tree
+ has a busted test, there's not much we can do anyway. We might as well
+ burn commit-queue resources spinning optimisticly.
+
+ * Scripts/webkitpy/tool/bot/commitqueuetask.py: Added.
+ * Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py: Added.
+ * Scripts/webkitpy/tool/commands/queues.py:
+
+2010-09-22 Brent Fulgham <bfulgham@webkit.org>
+
+ Reviewed by Martin Robinson.
+
+ [WinCairo] Update WebKitTestRunner and DumpRenderTree Build.
+ https://bugs.webkit.org/show_bug.cgi?id=46303.
+
+ * DumpRenderTree/win/DumpRenderTree.vcproj: Disable local MD5 sources
+ for Cairo build. Copy wtf MD5 header to ForwardingHeaders for the
+ WinCairo build.
+ * WebKitTestRunner/Configurations/InjectedBundleCFLite.vsprops: Added.
+ * WebKitTestRunner/win/InjectedBundle.vcproj: Update win new *_Cairo
+ build targets that use the new InjectedBundleCFLite.vsprops file.
+
+2010-09-22 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, build fix.
+
+ Fix bustage of rebaseline-chromium-webkit-tests resulting from
+ r67974. Really need better unit tests for this tool :(
+
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py:
+
+2010-09-22 Adam Roben <aroben@apple.com>
+
+ Unbreak test-webkitpy
+
+ * Scripts/webkitpy/test/main.py:
+ (Tester.run_tests): Add a line that mysteriously got deleted.
+
+2010-09-22 Adam Roben <aroben@apple.com>
+
+ Make test-webkitpy test WebKit2's scripts
+
+ These scripts can't be in WebKitTools due to limitations of Apple's
+ build process. But that doesn't mean we can't test them!
+
+ Fixes <http://webkit.org/b/46297> test-webkitpy should test code in
+ WebKit2/Scripts
+
+ Reviewed by Adam Barth.
+
+ * Scripts/test-webkitpy:
+ (_clean_packages_with_test): Renamed from _clean_webkitpy_with_test.
+ Now takes an external_package_paths parameter and cleans both webkitpy
+ and any external packages.
+ (init): Added an external_package_paths parameter which we pass along
+ to _clean_packages_with_test.
+ (top level): Add WebKit2/Scripts/webkit2 as our only external package
+ and pass it along to init and Tester.run_tests.
+
+ * Scripts/webkitpy/test/main.py:
+ (Tester.run_tests): Added an optional external_package_paths
+ parameter. We modify sys.path so that the external packages can be
+ imported, and search for unittest files inside all external packages
+ in addition to inside webkitpy.
+
+2010-09-22 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ new-run-webkit-tests: r68063 broke linux python tests
+
+ Add a missing "from __future__ import with_statement" to this
+ new file; the perils of testing only on the Mac and by review :(
+
+ https://bugs.webkit.org/show_bug.cgi?id=46293
+
+ * Scripts/webkitpy/layout_tests/port/chromium_gpu.py:
+
+2010-09-22 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ Add a 'chromium-gpu' set of ports that will test the accelerated
+ GPU paths. This patch adds:
+
+ - support for the '--accelerated-compositing' and
+ 'accelerated-2d-canvas' flags to new-run-webkit-tests (and the
+ 'no-' flags)
+ - adds a new set of Ports that will look under
+ platform/chromium-gpu-$OS/ for baselines before looking in the
+ regular chromium search path
+ - adds a new test_expectations.txt file in platform/chromium-gpu
+ that skips all but the tests we actually want to run with
+ acceleration.
+
+ This patch will allow us to run both with and without acceleration
+ and to change the defaults for both the regular and -gpu options
+ as the code evolves.
+
+ We plan to add both --chromium-$OS and --chromium-gpu-$OS runs to
+ each test bot.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46225
+
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_gpu.py:
+ * Scripts/webkitpy/layout_tests/port/factory.py:
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+
+2010-09-22 Jamey Hicks <jamey.hicks@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Web Inspector: Remote Web Inspector support for QtWebKit
+ https://bugs.webkit.org/show_bug.cgi?id=43988
+
+ Runs a web debug server on port specified by QtTestBrowser
+ argument -remote-inspector-port. Property
+ _q_webInspectorServerPort of the QWebPage instance will be set
+ according to the argument. All pages with that property set will
+ be remotely inspectable.
+
+ URL for remote inspection of first QWebPage is
+ http://localhost:9222/webkit/inspector/inspector.html?page=1
+ where 1 is the number of the QWebPage instance.
+
+ The base URL yields an index page with links to the individual inspectors:
+ http://localhost:9222/
+
+ * QtTestBrowser/launcherwindow.cpp:
+ (LauncherWindow::init):
+ * QtTestBrowser/launcherwindow.h:
+ * QtTestBrowser/main.cpp:
+ (LauncherApplication::handleUserOptions):
+
+2010-09-22 Adam Roben <aroben@apple.com>
+
+ Fix webkit-patch failure-reason now that build.webkit.org has been
+ updated
+
+ Fixes <http://webkit.org/b/46273> webkit-patch failure-reason crashes
+ every time
+
+ Reviewed by Eric Seidel.
+
+ * Scripts/webkitpy/common/net/buildbot.py:
+ (BuildBot._file_cell_text): Added. Travels down the firstChild chain
+ looking for an element that contains text, then returns it.
+ (BuildBot._parse_twisted_file_row): Use _file_cell_text to get the
+ text out of the cells. This way it doesn't matter whether the cells
+ have <b> children (as for cells in directory rows) or not (as for
+ cells in file rows)
+ (BuildBot._parse_twisted_directory_listing): Look for rows that have
+ the "directory" or "file" class, rather than rows with any class,
+ since header rows now have a class attribute.
+
+ * Scripts/webkitpy/common/net/buildbot_unittest.py:
+ (BuildBotTest._example_directory_listing): Updated to more closely
+ match the markup that build.webkit.org is producing now.
+
+2010-09-21 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, build fix.
+
+ new-run-webkit-tests: fix bug introduced in r68008 where if you
+ specify --chromium and no --platform, and you're running on
+ windows, you use the 'chromium-win' port by default instead of the
+ version-specific port. This breaks the buildbots.
+
+ It will be good for this refactoring to settle down so I can
+ rewrite the logic for default ports and the unit tests to be
+ clearer (and the testing more comprehensive).
+
+ * Scripts/webkitpy/layout_tests/port/chromium_win.py:
+
+2010-09-21 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Modify the Port interface to take only a series of keyword arguments
+ in the constructor, and modify Port/factory.get() to accomodate that,
+ and to accept user=XXX as an argument so we can pass
+ webkitpy.common.system.user.User objects in.
+
+ Then, modify new-run-webkit-tests and rebaseline-chromium-webkit-tests
+ to use the common routine in webkitpy.common.system.user.open_url()
+ to display HTML files.
+
+ There was a routine in the Port interface to do the same thing,
+ but I see no need for a port-specific hook for this, since it is
+ something that will always be executed by the host environment
+ and displaying web pages has nothing to do with running layout tests.
+
+ Note that new-run-webkit-tests used to use test_shell to display
+ the page; this is potentially useful so that you can actually click
+ from a result to the broken page; however, since DumpRenderTree
+ doesn't support this functionality, it will be going away eventually.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46128
+
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ * Scripts/webkitpy/layout_tests/port/base_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_linux.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_mac.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_win.py:
+ * Scripts/webkitpy/layout_tests/port/dryrun.py:
+ * Scripts/webkitpy/layout_tests/port/factory.py:
+ * Scripts/webkitpy/layout_tests/port/google_chrome.py:
+ * Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/gtk.py:
+ * Scripts/webkitpy/layout_tests/port/mac.py:
+ * Scripts/webkitpy/layout_tests/port/qt.py:
+ * Scripts/webkitpy/layout_tests/port/test.py:
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+ * Scripts/webkitpy/layout_tests/port/win.py:
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py:
+
+2010-09-21 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [EFL] Get fresh theme when running EWebLauncher
+ https://bugs.webkit.org/show_bug.cgi?id=46210
+
+ If user tried to run EWebLauncher outside of the build tree, it would
+ not find the theme and fallback to the installed one. However, since
+ EWebLauncher is not installed, we always want to take the theme from
+ the just compiled source code. If user had never installed WebKit's
+ EFL port it could even receive a segv since no theme would be found.
+
+ Now EWebLauncher does not fallback to the installed theme and CMake
+ gives as DATA_DIR the directory of the theme it has just built.
+
+ * CMakeListsEfl.txt: Pass the build directory as DATA_DIR to
+ EWebLauncher.
+ * EWebLauncher/main.c: Use only the theme from build director. Do not
+ fallback to others as this could hide real bugs.
+ (quit):
+ (browserCreate):
+ (findThemePath):
+ (main):
+
+2010-09-21 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, build fix.
+
+ Don't pass the --test-shell arg to the Chromium Mac port of DRT;
+ it just confuses it.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46230
+
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+
+2010-09-21 Lucas Forschler <lforschler@apple.com>
+
+ Reviewed by Stephanie Lewis.
+
+ Make a new buildbot for Leopard Debug Test
+
+ * BuildSlaveSupport/build.webkit.org-config/config.json:
+
+2010-09-21 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, build fix.
+
+ Fix breakage of Chromium Mac DRT port caused by r67905.
+
+ https://bugs.webkit.org/show_bug.cgi?id=46230
+
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+
+2010-09-21 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, build fix.
+
+ Add missing import of 'tempfile'.
+
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+
+2010-09-17 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ new-run-webkit-tests: pull the list of tests from the Port, and
+ make it possible to run with no actual test files in the filesystem.
+
+ This set of changes allows us to delete the special
+ webkitpy/layout_tests/data directory and test the generic code without
+ touching the filesystem (except to write results). This speeds up
+ test-webkitpy substantially.
+
+ This also cleans up and removes several code paths in the generic
+ code and fixes some minor bugs, notably in the test_expectations
+ parsing, which was previously fragile if the tests weren't present.
+
+ We also change the way we diff image results to be able to do so
+ in memory, without relying on files. This slows down chromium
+ test_shell, which always writes images to files, but should speed
+ up DRT and ImageDiff-based implementations slightly.
+
+ Note that pulling the list of tests to run from the Port will allow
+ ports to specify what tests to run as an inclusive list; previously
+ you could only do this as an exclusive list by using a
+ test_expectations file or Skipped files; nothing actually uses this
+ feature yet and it's unclear if it should be used.
+
+ Note that there are no functional changes -- apart from now
+ always printing out the location of the checksum file when we are
+ tracing test runs -- and the total number of lines of non-test code
+ actually drops by two.
+
+ There is some more cleanup that can be done in the Port/Driver
+ interface and in some handling of filenames, but I'll save that
+ for another change.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45801
+
+ * Scripts/webkitpy/layout_tests/data/*: Removed.
+ - no longer need special mock layout_tests_directory in the
+ repository.
+ * Scripts/webkitpy/layout_tests/layout_package/printing.py:
+ - add code to display missing text files, checksums when tracing
+ - update to not look at the filesystem directly.
+ * Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py:
+ - add more unit tests
+ * Scripts/webkitpy/layout_tests/layout_package/test_expectations.py:
+ - remove tests_are_present flag
+ - update with changes in Port interface - no longer access
+ the filesystem directly, although we still use os.path for
+ filename manipulation.
+ * Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py:
+ - add more unit tests
+ * Scripts/webkitpy/layout_tests/layout_package/test_files.py: Removed.
+ - renamed to port/test_files.py
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ - change diff_image() to expect actual image data, not filenames
+ - add expected_checksum(), expected_image(), expected_text() to
+ return the content of the files so that we don't need a filesystem
+ - add path_exists(), path_isdir() for filesystem-like access.
+ - add test_dirs() to keep clobber-test-results from needing to
+ actually look at a real layout tests dir
+ - add tests() to return the list of tests to run on the port
+ (calls port/test_files to do the work).
+ - add update_baseline() to be able to save new baselines
+ - add uri_to_test_name() from port/dryrun.py so we can easily check
+ filename_to_uri()
+ * Scripts/webkitpy/layout_tests/port/base_unittest.py:
+ - add more unit tests
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+ - change diff_image() to accept image content, not filenames.
+ This will be slower for test_shell/image_diff, but faster
+ for DRT/ImageDiff.
+ * Scripts/webkitpy/layout_tests/port/chromium_unittest.py:
+ - add more unit tests
+ * Scripts/webkitpy/layout_tests/port/dryrun.py:
+ - simplify greatly
+ * Scripts/webkitpy/layout_tests/port/port_testcase.py:
+ - add more unit tests
+ * Scripts/webkitpy/layout_tests/port/test.py:
+ - massive rewrite to use in-script list of tests and expectations
+ * Scripts/webkitpy/layout_tests/port/test_files.py:
+ - rename from layout_package/test_files.
+ * Scripts/webkitpy/layout_tests/port/test_files_unittest.py:
+ - add unit tests
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+ - update diff_image() to take image contents, not files. Should
+ make things slightly faster.
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py:
+ - update with changes to diff_image()
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py:
+ - update with changes to diff_image()
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+ - remove tests_are_present from test_expectations
+ - pull the list of tests from port.tests() instead
+ of calling test_files.py directly.
+ * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py:
+ - update unit tests
+ * Scripts/webkitpy/layout_tests/test_types/image_diff.py:
+ - update with changes to
+ * Scripts/webkitpy/layout_tests/test_types/test_type_base.py:
+ - update with change in Port interface
+ * Scripts/webkitpy/layout_tests/test_types/text_diff.py:
+ - update with change in Port interface
+ * Scripts/webkitpy/style/checkers/test_expectations.py:
+ - remove the tests_are_present flag
+
+2010-09-21 Anders Carlsson <andersca@apple.com>
+
+ Disable logging.
+
+ * MiniBrowser/mac/MiniBrowser_Prefix.pch:
+
+2010-09-21 Tony Chang <tony@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ add a script for running webkit_unit_tests
+ https://bugs.webkit.org/show_bug.cgi?id=46014
+
+ * Scripts/run-chromium-webkit-unit-tests: Added.
+
+2010-09-21 Fridrich Strba <fridrich.strba@bluewin.ch>
+
+ Reviewed by Martin Robinson.
+
+ Fix linking problems on Windows.
+ https://bugs.webkit.org/show_bug.cgi?id=45844
+
+ * GNUmakefile.am: link the executables with winmm.dll
+
+2010-09-21 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ feeder-queue svn updates more often than needed
+ https://bugs.webkit.org/show_bug.cgi?id=46171
+
+ We don't need to poll SVN every time we feed the feeders. Rather, we
+ can count on the wrapper shell script to auto-update the queue.
+
+ * Scripts/webkitpy/tool/commands/queues.py:
+ * Scripts/webkitpy/tool/commands/queues_unittest.py:
+
+2010-09-21 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] Add robot loader timeout and extra time options.
+ https://bugs.webkit.org/show_bug.cgi?id=46172
+
+ [-robot-timeout <s>]: Load the next page after s seconds if the current
+ page didn't finish loading.
+ [-robot-extra-time <s>]: Wait s seconds after the current page finished
+ loading before loading the next one. This should allow some time for the
+ page's JavaScript to execute.
+
+ * QtTestBrowser/launcherwindow.cpp:
+ (LauncherWindow::applyPrefs):
+ * QtTestBrowser/main.cpp:
+ (LauncherApplication::robotTimeout):
+ (LauncherApplication::robotExtraTime):
+ (LauncherApplication::LauncherApplication):
+ (LauncherApplication::handleUserOptions):
+ (main):
+ * QtTestBrowser/urlloader.cpp:
+ (UrlLoader::UrlLoader):
+ (UrlLoader::loadNext):
+ (UrlLoader::loadUrlList):
+ * QtTestBrowser/urlloader.h:
+
+2010-09-21 Pavel Podivilov <podivilov@chromium.org>
+
+ Unreviewed.
+
+ Adding myself to the committers list.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-20 Philippe Normand <pnormand@igalia.com>
+
+ Reviewed by Eric Carlson.
+
+ [GTK] enhanced context menu for media elements
+ https://bugs.webkit.org/show_bug.cgi?id=45021
+
+ EventSender::contextClick() now returns an array of js
+ objects. Each object has a title property and a click() method.
+
+ * DumpRenderTree/gtk/EventSender.cpp:
+ (getMenuItemTitleCallback):
+ (setMenuItemTitleCallback):
+ (menuItemClickCallback):
+ (getMenuItemClass):
+ (contextClickCallback):
+
+2010-09-20 Hayato Ito <hayato@chromium.org>
+
+ Unreviewed.
+ Adding myself to the committers list.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-20 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ The tool member variable should be called _tool
+ https://bugs.webkit.org/show_bug.cgi?id=46160
+
+ Created by find-and-replace.
+
+ * Scripts/webkitpy/tool/commands/download.py:
+ * Scripts/webkitpy/tool/commands/openbugs.py:
+ * Scripts/webkitpy/tool/commands/queries.py:
+ * Scripts/webkitpy/tool/commands/queues.py:
+ * Scripts/webkitpy/tool/commands/queues_unittest.py:
+ * Scripts/webkitpy/tool/commands/rebaseline.py:
+ * Scripts/webkitpy/tool/commands/sheriffbot.py:
+ * Scripts/webkitpy/tool/commands/upload.py:
+ * Scripts/webkitpy/tool/multicommandtool.py:
+
+2010-09-20 Adam Barth <abarth@webkit.org>
+
+ I ran the tests before landing but ignored the fact that they failed. :(
+
+ * Scripts/webkitpy/tool/commands/queues.py:
+
+2010-09-20 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Add a feeder queue that polls bugs.webkit.org for the commit-cluster
+ https://bugs.webkit.org/show_bug.cgi?id=46141
+
+ The feeder-queue polls bugs.webkit.org every 30 seconds and updates the
+ list of work items on the status server. The individual commit-cluster
+ nodes then grab the patches from the server and process them.
+
+ * Scripts/webkitpy/tool/bot/feeders.py: Added.
+ * Scripts/webkitpy/tool/bot/feeders_unittest.py: Added.
+ * Scripts/webkitpy/tool/commands/queues.py:
+ * Scripts/webkitpy/tool/commands/queues_unittest.py:
+ * Scripts/webkitpy/tool/commands/queuestest.py:
+
+2010-09-20 Leandro Pereira <leandro@profusion.mobi>
+
+ Reviewed by Darin Adler.
+
+ build-webkit: Add support for CMake build system
+ https://bugs.webkit.org/show_bug.cgi?id=44979
+
+ * Scripts/build-webkit: Add "--efl" command-line option to build the
+ EFL port of WebKit.
+ * Scripts/webkitdirs.pm: Define buildCMakeProject() and
+ buildEflCMakeProject() subroutines.
+
2010-09-20 Dirk Pranke <dpranke@chromium.org>
Reviewed by Ojan Vafai.
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
index 1643ba6..ee44325 100644
--- a/WebKitTools/DumpRenderTree/LayoutTestController.cpp
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
@@ -513,6 +513,24 @@ static JSValueRef computedStyleIncludingVisitedInfoCallback(JSContextRef context
return controller->computedStyleIncludingVisitedInfo(context, arguments[0]);
}
+static JSValueRef nodesFromRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount != 8)
+ return JSValueMakeUndefined(context);
+
+ int x = JSValueToNumber(context, arguments[1], NULL);
+ int y = JSValueToNumber(context, arguments[2], NULL);
+ int top = static_cast<unsigned>(JSValueToNumber(context, arguments[3], NULL));
+ int right = static_cast<unsigned>(JSValueToNumber(context, arguments[4], NULL));
+ int bottom = static_cast<unsigned>(JSValueToNumber(context, arguments[5], NULL));
+ int left = static_cast<unsigned>(JSValueToNumber(context, arguments[6], NULL));
+ bool ignoreClipping = JSValueToBoolean(context, arguments[7]);
+
+ // Has mac implementation.
+ LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ return controller->nodesFromRect(context, arguments[0], x, y, top, right, bottom, left, ignoreClipping);
+}
+
static JSValueRef layerTreeAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
// Has mac & windows implementation
@@ -1843,6 +1861,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
{ "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "closeWebInspector", closeWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "computedStyleIncludingVisitedInfo", computedStyleIncludingVisitedInfoCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "nodesFromRect", nodesFromRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.h b/WebKitTools/DumpRenderTree/LayoutTestController.h
index 2bf7a75..755a2b2 100644
--- a/WebKitTools/DumpRenderTree/LayoutTestController.h
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.h
@@ -60,6 +60,7 @@ public:
bool isCommandEnabled(JSStringRef name);
void keepWebHistory();
JSValueRef computedStyleIncludingVisitedInfo(JSContextRef, JSValueRef);
+ JSValueRef nodesFromRect(JSContextRef, JSValueRef, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping);
void notifyDone();
int numberOfPages(float pageWidthInPixels, float pageHeightInPixels);
void overridePreference(JSStringRef key, JSStringRef value);
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
index 5002400..1df1c76 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
@@ -971,15 +971,18 @@ static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
newInstance->returnNegativeOneFromWrite = FALSE;
newInstance->stream = 0;
- newInstance->firstUrl = NULL;
- newInstance->firstHeaders = NULL;
- newInstance->lastUrl = NULL;
- newInstance->lastHeaders = NULL;
+ newInstance->firstUrl = 0;
+ newInstance->firstHeaders = 0;
+ newInstance->lastUrl = 0;
+ newInstance->lastHeaders = 0;
newInstance->testGetURLOnDestroy = FALSE;
newInstance->testWindowOpen = FALSE;
newInstance->testKeyboardFocusForPlugins = FALSE;
+ newInstance->mouseDownForEvaluateScript = FALSE;
+ newInstance->evaluateScriptOnMouseDownOrKeyDown = 0;
+
return (NPObject*)newInstance;
}
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h
index 2c1d325..6c30578 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h
@@ -57,6 +57,7 @@ typedef struct {
NPBool testGetURLOnDestroy;
NPBool testWindowOpen;
NPBool testKeyboardFocusForPlugins;
+ NPBool mouseDownForEvaluateScript;
char* onStreamLoad;
char* onStreamDestroy;
char* onDestroy;
@@ -66,6 +67,7 @@ typedef struct {
char* firstHeaders;
char* lastUrl;
char* lastHeaders;
+ char* evaluateScriptOnMouseDownOrKeyDown;
#ifdef XP_MACOSX
NPEventModel eventModel;
#endif
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
index 0ff7029..83eda3a 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
@@ -60,6 +60,11 @@ NPError PluginTest::NPP_GetValue(NPPVariable variable, void *value)
return NPERR_GENERIC_ERROR;
}
+NPError PluginTest::NPP_SetWindow(NPP, NPWindow*)
+{
+ return NPERR_NO_ERROR;
+}
+
NPIdentifier PluginTest::NPN_GetStringIdentifier(const NPUTF8 *name)
{
return browser->getstringidentifier(name);
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
index ecc0185..2e896a6 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
@@ -57,6 +57,7 @@ public:
// NPP functions.
virtual NPError NPP_DestroyStream(NPStream* stream, NPReason reason);
virtual NPError NPP_GetValue(NPPVariable, void* value);
+ virtual NPError NPP_SetWindow(NPP, NPWindow*);
// NPN functions.
NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name);
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowGeometryInitializedBeforeSetWindow.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowGeometryInitializedBeforeSetWindow.cpp
new file mode 100644
index 0000000..40bceb9
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowGeometryInitializedBeforeSetWindow.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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;
+
+// Plugin's HWND should be sized/positioned before NPP_SetWindow is called.
+
+class WindowGeometryInitializedBeforeSetWindow : public PluginTest {
+public:
+ WindowGeometryInitializedBeforeSetWindow(NPP npp, const string& identifier)
+ : PluginTest(npp, identifier)
+ {
+ }
+
+private:
+ virtual NPError NPP_SetWindow(NPP instance, NPWindow* window)
+ {
+ 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 rect;
+ if (!::GetClientRect(hwnd, &rect)) {
+ pluginLog(instance, "::GetClientRect failed");
+ return NPERR_GENERIC_ERROR;
+ }
+
+ if (::IsRectEmpty(&rect)) {
+ pluginLog(instance, "Plugin's HWND has not been sized when NPP_SetWindow is called");
+ return NPERR_GENERIC_ERROR;
+ }
+
+ HWND parent = ::GetParent(hwnd);
+ if (!parent) {
+ pluginLog(instance, "::GetParent failed");
+ return NPERR_GENERIC_ERROR;
+ }
+
+ // MSDN says that calling ::MapWindowPoints this way will tell it we're passing a RECT rather than two POINTs.
+ if (!::MapWindowPoints(hwnd, parent, reinterpret_cast<POINT*>(&rect), 2)) {
+ pluginLog(instance, "::MapWindowPoints failed");
+ return NPERR_GENERIC_ERROR;
+ }
+
+ if (rect.left != window->x || rect.top != window->y || (rect.right - rect.left) != window->width || (rect.bottom - rect.top) != window->height) {
+ pluginLog(instance, "HWND's rect and NPWindow's rect are not equal");
+ return NPERR_GENERIC_ERROR;
+ }
+
+ pluginLog(instance, "Plugin's HWND has been sized and positioned before NPP_SetWindow was called");
+ return NPERR_NO_ERROR;
+ }
+};
+
+static PluginTest::Register<WindowGeometryInitializedBeforeSetWindow> windowGeometryInitializedBeforeSetWindow("window-geometry-initialized-before-set-window");
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp
index c02e918..dd894f4 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp
@@ -218,8 +218,20 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc
// FIXME: When https://bugs.webkit.org/show_bug.cgi?id=41831 is fixed, this #ifdef can be removed.
obj->testGetURLOnDestroy = TRUE;
#endif
- } else if (strcasecmp(argn[i], "src") == 0 && strstr(argv[i], "plugin-document-has-focus.pl"))
+ } else if (!strcasecmp(argn[i], "src") && strstr(argv[i], "plugin-document-has-focus.pl"))
obj->testKeyboardFocusForPlugins = TRUE;
+ else if (!strcasecmp(argn[i], "evaluatescript")) {
+ char* script = argv[i];
+ if (script == strstr(script, "mouse::")) {
+ obj->mouseDownForEvaluateScript = true;
+ obj->evaluateScriptOnMouseDownOrKeyDown = strdup(script + sizeof("mouse::") - 1);
+ } else if (script == strstr(script, "key::")) {
+ obj->evaluateScriptOnMouseDownOrKeyDown = strdup(script + sizeof("key::") - 1);
+ }
+ // When testing evaluate script on mouse-down or key-down, allow event logging to handle events.
+ if (obj->evaluateScriptOnMouseDownOrKeyDown)
+ obj->eventLogging = true;
+ }
}
#if XP_MACOSX
@@ -300,7 +312,7 @@ NPError NPP_SetWindow(NPP instance, NPWindow *window)
}
}
- return NPERR_NO_ERROR;
+ return obj->pluginTest->NPP_SetWindow(instance, window);
}
static void executeScript(const PluginObject* obj, const char* script)
@@ -401,6 +413,8 @@ static int16_t handleEventCarbon(NPP instance, PluginObject* obj, EventRecord* e
case mouseDown:
GlobalToLocal(&pt);
pluginLog(instance, "mouseDown at (%d, %d)", pt.h, pt.v);
+ if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript)
+ executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
break;
case mouseUp:
GlobalToLocal(&pt);
@@ -408,6 +422,8 @@ static int16_t handleEventCarbon(NPP instance, PluginObject* obj, EventRecord* e
break;
case keyDown:
pluginLog(instance, "keyDown '%c'", (char)(event->message & 0xFF));
+ if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript)
+ executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
break;
case keyUp:
pluginLog(instance, "keyUp '%c'", (char)(event->message & 0xFF));
@@ -481,6 +497,8 @@ static int16_t handleEventCocoa(NPP instance, PluginObject* obj, NPCocoaEvent* e
case NPCocoaEventKeyDown:
if (event->data.key.characters)
pluginLog(instance, "keyDown '%c'", CFStringGetCharacterAtIndex(reinterpret_cast<CFStringRef>(event->data.key.characters), 0));
+ if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript)
+ executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
return 1;
case NPCocoaEventKeyUp:
@@ -501,6 +519,8 @@ static int16_t handleEventCocoa(NPP instance, PluginObject* obj, NPCocoaEvent* e
pluginLog(instance, "mouseDown at (%d, %d)",
(int)event->data.mouse.pluginX,
(int)event->data.mouse.pluginY);
+ if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript)
+ executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
return 1;
case NPCocoaEventMouseUp:
pluginLog(instance, "mouseUp at (%d, %d)",
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj
index c36666f..5ffb832 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj
@@ -367,6 +367,34 @@
<References>
</References>
<Files>
+ <Filter
+ Name="Tests"
+ >
+ <File
+ RelativePath="..\Tests\DocumentOpenInDestroyStream.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Tests\NPRuntimeObjectFromDestroyedPlugin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Tests\NPRuntimeRemoveProperty.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Tests\PluginScriptableNPObjectInvokeDefault.cpp"
+ >
+ </File>
+ <Filter
+ Name="win"
+ >
+ <File
+ RelativePath="..\Tests\win\WindowGeometryInitializedBeforeSetWindow.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
<File
RelativePath="..\main.cpp"
>
@@ -456,26 +484,6 @@
RelativePath="..\TestObject.h"
>
</File>
- <Filter
- Name="Tests"
- >
- <File
- RelativePath="..\Tests\DocumentOpenInDestroyStream.cpp"
- >
- </File>
- <File
- RelativePath="..\Tests\NPRuntimeObjectFromDestroyedPlugin.cpp"
- >
- </File>
- <File
- RelativePath="..\Tests\NPRuntimeRemoveProperty.cpp"
- >
- </File>
- <File
- RelativePath="..\Tests\PluginScriptableNPObjectInvokeDefault.cpp"
- >
- </File>
- </Filter>
</Files>
<Globals>
</Globals>
diff --git a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp
index 6e180d0..b2e50f7 100644
--- a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp
@@ -48,6 +48,7 @@ static const char optionTestShell[] = "--test-shell";
static const char optionAllowExternalPages[] = "--allow-external-pages";
static const char optionStartupDialog[] = "--testshell-startup-dialog";
static const char optionCheckLayoutTestSystemDeps[] = "--check-layout-test-sys-deps";
+static const char optionEnableAccelerated2DCanvas[] = "--enable-accelerated-2d-canvas";
static void runTest(TestShell& shell, TestParams& params, const string& testName, bool testShellMode)
{
@@ -92,6 +93,7 @@ int main(int argc, char* argv[])
bool testShellMode = false;
bool allowExternalPages = false;
bool startupDialog = false;
+ bool accelerated2DCanvasEnabled = false;
for (int i = 1; i < argc; ++i) {
string argument(argv[i]);
if (argument == "-")
@@ -112,6 +114,8 @@ int main(int argc, char* argv[])
startupDialog = true;
else if (argument == optionCheckLayoutTestSystemDeps)
exit(checkLayoutTestSystemDependencies() ? EXIT_SUCCESS : EXIT_FAILURE);
+ else if (argument == optionEnableAccelerated2DCanvas)
+ accelerated2DCanvasEnabled = true;
else if (argument.size() && argument[0] == '-')
fprintf(stderr, "Unknown option: %s\n", argv[i]);
else
@@ -128,6 +132,7 @@ int main(int argc, char* argv[])
{ // Explicit scope for the TestShell instance.
TestShell shell(testShellMode);
shell.setAllowExternalPages(allowExternalPages);
+ shell.setAccelerated2dCanvasEnabled(accelerated2DCanvasEnabled);
if (serverMode && !tests.size()) {
params.printSeparators = true;
char testString[2048]; // 2048 is the same as the sizes of other platforms.
diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
index 2c6c600..3d3c204 100644
--- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
@@ -126,6 +126,7 @@ LayoutTestController::LayoutTestController(TestShell* shell)
bindMethod("removeOriginAccessWhitelistEntry", &LayoutTestController::removeOriginAccessWhitelistEntry);
bindMethod("repaintSweepHorizontally", &LayoutTestController::repaintSweepHorizontally);
bindMethod("resumeAnimations", &LayoutTestController::resumeAnimations);
+ bindMethod("sampleSVGAnimationForElementAtTime", &LayoutTestController::sampleSVGAnimationForElementAtTime);
bindMethod("setAcceptsEditing", &LayoutTestController::setAcceptsEditing);
bindMethod("setAllowFileAccessFromFileURLs", &LayoutTestController::setAllowFileAccessFromFileURLs);
bindMethod("setAllowUniversalAccessFromFileURLs", &LayoutTestController::setAllowUniversalAccessFromFileURLs);
@@ -959,6 +960,19 @@ void LayoutTestController::resumeAnimations(const CppArgumentList&, CppVariant*
result->setNull();
}
+void LayoutTestController::sampleSVGAnimationForElementAtTime(const CppArgumentList& arguments, CppVariant* result)
+{
+ if (arguments.size() != 3) {
+ result->setNull();
+ return;
+ }
+ WebString animationId = cppVariantToWebString(arguments[0]);
+ double time = arguments[1].toDouble();
+ WebString elementId = cppVariantToWebString(arguments[2]);
+ bool success = m_shell->webView()->mainFrame()->pauseSVGAnimation(animationId, time, elementId);
+ result->set(success);
+}
+
void LayoutTestController::disableImageLoading(const CppArgumentList&, CppVariant* result)
{
m_shell->preferences()->loadsImagesAutomatically = false;
@@ -1251,6 +1265,10 @@ void LayoutTestController::overridePreference(const CppArgumentList& arguments,
prefs->tabsToLinks = cppVariantToBool(value);
else if (key == "WebKitWebGLEnabled")
prefs->experimentalWebGLEnabled = cppVariantToBool(value);
+ else if (key == "WebKitHyperlinkAuditingEnabled")
+ prefs->hyperlinkAuditingEnabled = cppVariantToBool(value);
+ else if (key == "WebKitEnableCaretBrowsing")
+ prefs->caretBrowsingEnabled = cppVariantToBool(value);
else {
string message("Invalid name for preference: ");
message.append(key);
@@ -1443,7 +1461,10 @@ void LayoutTestController::addUserStyleSheet(const CppArgumentList& arguments, C
return;
WebView::addUserStyleSheet(
cppVariantToWebString(arguments[0]), WebVector<WebString>(),
- arguments[2].toBoolean() ? WebView::UserContentInjectInAllFrames : WebView::UserContentInjectInTopFrameOnly);
+ arguments[1].toBoolean() ? WebView::UserContentInjectInAllFrames : WebView::UserContentInjectInTopFrameOnly,
+ // Chromium defaults to InjectInSubsequentDocuments, but for compatibility
+ // with the other ports' DRTs, we use UserStyleInjectInExistingDocuments.
+ WebView::UserStyleInjectInExistingDocuments);
}
void LayoutTestController::setEditingBehavior(const CppArgumentList& arguments, CppVariant* results)
diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h
index ec2503f..8467097 100644
--- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h
+++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h
@@ -223,6 +223,7 @@ public:
void numberOfActiveAnimations(const CppArgumentList&, CppVariant*);
void suspendAnimations(const CppArgumentList&, CppVariant*);
void resumeAnimations(const CppArgumentList&, CppVariant*);
+ void sampleSVGAnimationForElementAtTime(const CppArgumentList&, CppVariant*);
void disableImageLoading(const CppArgumentList&, CppVariant*);
void setIconDatabaseEnabled(const CppArgumentList&, CppVariant*);
void dumpSelectionRect(const CppArgumentList&, CppVariant*);
diff --git a/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.cpp b/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.cpp
index d9e79a0..2130534 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/TestEventPrinter.cpp
@@ -99,7 +99,8 @@ void DRTPrinter::handleImage(const char* actualHash, const char* expectedHash, c
printf("\nExpectedHash: %s\n", expectedHash);
if (imageData && imageSize) {
printf("Content-Type: image/png\n");
- printf("Content-Length: %lu\n", imageSize);
+ // Printf formatting for size_t on 32-bit, 64-bit, and on Windows is hard so just cast to an int.
+ printf("Content-Length: %d\n", static_cast<int>(imageSize));
if (fwrite(imageData, 1, imageSize, stdout) != imageSize) {
fprintf(stderr, "Short write to stdout.\n");
exit(1);
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp
index 15d6dee..1a99b7d 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp
@@ -83,6 +83,7 @@ TestShell::TestShell(bool testShellMode)
, m_focusedWidget(0)
, m_testShellMode(testShellMode)
, m_allowExternalPages(false)
+ , m_accelerated2dCanvasEnabled(false)
, m_devTools(0)
{
WebRuntimeFeatures::enableGeolocation(true);
@@ -155,6 +156,7 @@ void TestShell::closeDevTools()
void TestShell::resetWebSettings(WebView& webView)
{
m_prefs.reset();
+ m_prefs.accelerated2dCanvasEnabled = m_accelerated2dCanvasEnabled;
m_prefs.applyTo(&webView);
}
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.h b/WebKitTools/DumpRenderTree/chromium/TestShell.h
index 6d93d4a..4d022dc 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShell.h
+++ b/WebKitTools/DumpRenderTree/chromium/TestShell.h
@@ -123,6 +123,8 @@ public:
bool allowExternalPages() const { return m_allowExternalPages; }
void setAllowExternalPages(bool allowExternalPages) { m_allowExternalPages = allowExternalPages; }
+ void setAccelerated2dCanvasEnabled(bool enabled) { m_accelerated2dCanvasEnabled = enabled; }
+
#if defined(OS_WIN)
// Access to the finished event. Used by the static WatchDog thread.
HANDLE finishedEvent() { return m_finishedEvent; }
@@ -176,6 +178,7 @@ private:
TestParams m_params;
int m_timeout; // timeout value in millisecond
bool m_allowExternalPages;
+ bool m_accelerated2dCanvasEnabled;
WebPreferences m_prefs;
// List of all windows in this process.
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp b/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp
index 60408b9..1cf7c56 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp
@@ -134,22 +134,23 @@ static void setupFontconfig()
// few layout tests.
static const char* const optionalFonts[] = {
"/usr/share/fonts/truetype/ttf-lucida/LucidaSansRegular.ttf",
-
- // This font changed paths across Ubuntu releases.
"/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_pa.ttf",
- "/usr/share/fonts/truetype/ttf-punjabi-fonts/lohit_pa.ttf",
};
for (size_t i = 0; i < arraysize(optionalFonts); ++i) {
const char* font = optionalFonts[i];
+
+ // This font changed paths across Ubuntu releases, so try checking in both locations.
+ if (!strcmp(font, "/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_pa.ttf")
+ && access(font, R_OK) < 0)
+ font = "/usr/share/fonts/truetype/ttf-punjabi-fonts/lohit_pa.ttf";
+
if (access(font, R_OK) < 0) {
fprintf(stderr, "You are missing %s. Without this, some layout tests may fail. "
"See http://code.google.com/p/chromium/wiki/LinuxBuildInstructionsPrerequisites "
"for more.\n", font);
- } else {
- if (!FcConfigAppFontAddFile(fontcfg, (FcChar8 *) font)) {
- fprintf(stderr, "Failed to load font %s\n", font);
- exit(1);
- }
+ } else if (!FcConfigAppFontAddFile(fontcfg, (FcChar8 *) font)) {
+ fprintf(stderr, "Failed to load font %s\n", font);
+ exit(1);
}
}
diff --git a/WebKitTools/DumpRenderTree/chromium/TextInputController.cpp b/WebKitTools/DumpRenderTree/chromium/TextInputController.cpp
index 16f1575..4f06874 100644
--- a/WebKitTools/DumpRenderTree/chromium/TextInputController.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/TextInputController.cpp
@@ -32,6 +32,7 @@
#include "TextInputController.h"
#include "TestShell.h"
+#include "public/WebBindings.h"
#include "public/WebFrame.h"
#include "public/WebRange.h"
#include "public/WebString.h"
@@ -186,10 +187,27 @@ void TextInputController::selectedRange(const CppArgumentList&, CppVariant* resu
result->set(string(buffer));
}
-void TextInputController::firstRectForCharacterRange(const CppArgumentList&, CppVariant* result)
+void TextInputController::firstRectForCharacterRange(const CppArgumentList& arguments, CppVariant* result)
{
- // FIXME: Implement this.
result->setNull();
+
+ WebFrame* mainFrame = getMainFrame();
+ if (!mainFrame)
+ return;
+
+ if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
+ return;
+
+ WebRect rect;
+ if (!mainFrame->firstRectForCharacterRange(arguments[0].toInt32(), arguments[1].toInt32(), rect))
+ return;
+
+ Vector<int> intArray(4);
+ intArray[0] = rect.x;
+ intArray[1] = rect.y;
+ intArray[2] = rect.width;
+ intArray[3] = rect.height;
+ result->set(WebBindings::makeIntArray(intArray));
}
void TextInputController::characterIndexForPoint(const CppArgumentList&, CppVariant* result)
diff --git a/WebKitTools/DumpRenderTree/chromium/WebPreferences.cpp b/WebKitTools/DumpRenderTree/chromium/WebPreferences.cpp
index 004865a..35247ef 100644
--- a/WebKitTools/DumpRenderTree/chromium/WebPreferences.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/WebPreferences.cpp
@@ -88,6 +88,7 @@ void WebPreferences::reset()
userStyleSheetLocation = WebURL();
usesPageCache = false;
webSecurityEnabled = true;
+ caretBrowsingEnabled = false;
// Allow those layout tests running as local files, i.e. under
// LayoutTests/http/tests/local, to access http server.
@@ -100,6 +101,8 @@ void WebPreferences::reset()
#endif
tabsToLinks = false;
+ hyperlinkAuditingEnabled = false;
+ accelerated2dCanvasEnabled = false;
}
void WebPreferences::applyTo(WebView* webView)
@@ -139,9 +142,11 @@ void WebPreferences::applyTo(WebView* webView)
settings->setWebSecurityEnabled(webSecurityEnabled);
settings->setAllowUniversalAccessFromFileURLs(allowUniversalAccessFromFileURLs);
settings->setEditingBehavior(editingBehavior);
+ settings->setHyperlinkAuditingEnabled(hyperlinkAuditingEnabled);
// LayoutTests were written with Safari Mac in mind which does not allow
// tabbing to links by default.
webView->setTabsToLinks(tabsToLinks);
+ settings->setCaretBrowsingEnabled(caretBrowsingEnabled);
// Fixed values.
settings->setShouldPaintCustomScrollbars(true);
@@ -157,5 +162,7 @@ void WebPreferences::applyTo(WebView* webView)
// FIXME: crbug.com/51879
settings->setAcceleratedCompositingEnabled(false);
+
+ settings->setAccelerated2dCanvasEnabled(accelerated2dCanvasEnabled);
}
diff --git a/WebKitTools/DumpRenderTree/chromium/WebPreferences.h b/WebKitTools/DumpRenderTree/chromium/WebPreferences.h
index f197c16..c0ea70f 100644
--- a/WebKitTools/DumpRenderTree/chromium/WebPreferences.h
+++ b/WebKitTools/DumpRenderTree/chromium/WebPreferences.h
@@ -75,6 +75,9 @@ struct WebPreferences {
bool allowUniversalAccessFromFileURLs;
WebKit::WebSettings::EditingBehavior editingBehavior;
bool tabsToLinks;
+ bool hyperlinkAuditingEnabled;
+ bool caretBrowsingEnabled;
+ bool accelerated2dCanvasEnabled;
WebPreferences() { reset(); }
void reset();
diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
index af2e403..521a0e1 100644
--- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
@@ -35,6 +35,7 @@
#include "AccessibilityController.h"
#include "EventSender.h"
#include "GCController.h"
+#include "GOwnPtr.h"
#include "LayoutTestController.h"
#include "PixelDumpSupport.h"
#include "WorkQueue.h"
@@ -133,37 +134,81 @@ static void appendString(gchar*& target, gchar* string)
static void initializeFonts()
{
#if PLATFORM(X11)
- static int numFonts = -1;
-
FcInit();
- // Some tests may add or remove fonts via the @font-face rule.
- // If that happens, font config should be re-created to suppress any unwanted change.
+ // If a test resulted a font being added or removed via the @font-face rule, then
+ // we want to reset the FontConfig configuration to prevent it from affecting other tests.
+ static int numFonts = 0;
FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication);
- if (appFontSet && numFonts >= 0 && appFontSet->nfont == numFonts)
+ if (appFontSet && numFonts && appFontSet->nfont == numFonts)
return;
- const char* fontDirEnv = g_getenv("WEBKIT_TESTFONTS");
- if (!fontDirEnv)
- g_error("WEBKIT_TESTFONTS environment variable is not set, but it should point to the directory "
- "containing the fonts you can clone from git://gitorious.org/qtwebkit/testfonts.git\n");
+ // Load our configuration file, which sets up proper aliases for family
+ // names like sans, serif and monospace.
+ FcConfig* config = FcConfigCreate();
+ GOwnPtr<gchar> fontConfigFilename(g_build_filename(FONTS_CONF_DIR, "fonts.conf", NULL));
+ if (!FcConfigParseAndLoad(config, reinterpret_cast<FcChar8*>(fontConfigFilename.get()), true))
+ g_error("Couldn't load font configuration file from: %s", fontConfigFilename.get());
+
+ static const char *const fontPaths[][2] = {
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationMono-BoldItalic.ttf",
+ "/usr/share/fonts/liberation/LiberationMono-BoldItalic.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationMono-Bold.ttf",
+ "/usr/share/fonts/liberation/LiberationMono-Bold.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationMono-Italic.ttf",
+ "/usr/share/fonts/liberation/LiberationMono-Italic.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationMono-Regular.ttf",
+ "/usr/share/fonts/liberation/LiberationMono-Regular.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationSans-BoldItalic.ttf",
+ "/usr/share/fonts/liberation/LiberationSans-BoldItalic.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationSans-Bold.ttf",
+ "/usr/share/fonts/liberation/LiberationSans-Bold.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationSans-Italic.ttf",
+ "/usr/share/fonts/liberation/LiberationSans-Italic.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationSans-Regular.ttf",
+ "/usr/share/fonts/liberation/LiberationSans-Regular.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationSerif-BoldItalic.ttf",
+ "/usr/share/fonts/liberation/LiberationSerif-BoldItalic.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationSerif-Bold.ttf",
+ "/usr/share/fonts/liberation/LiberationSerif-Bold.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationSerif-Italic.ttf",
+ "/usr/share/fonts/liberation/LiberationSerif-Italic.ttf", },
+ { "/usr/share/fonts/truetype/ttf-liberation/LiberationSerif-Regular.ttf",
+ "/usr/share/fonts/liberation/LiberationSerif-Regular.ttf", },
+ { "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf",
+ "/usr/share/fonts/dejavu/DejaVuSans.ttf", },
+ };
- GFile* fontDir = g_file_new_for_path(fontDirEnv);
- if (!fontDir || !g_file_query_exists(fontDir, NULL))
- g_error("WEBKIT_TESTFONTS environment variable is not set correctly - it should point to the directory "
- "containing the fonts you can clone from git://gitorious.org/qtwebkit/testfonts.git\n");
+ // TODO: Some tests use Lucida. We should load these as well, once it becomes
+ // clear how to install these fonts easily on Fedora.
+ for (size_t font = 0; font < G_N_ELEMENTS(fontPaths); font++) {
+ bool found = false;
+ for (size_t path = 0; path < 2; path++) {
+
+ if (g_file_test(fontPaths[font][path], G_FILE_TEST_EXISTS)) {
+ found = true;
+ if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8*>(fontPaths[font][path])))
+ g_error("Could not load font at %s!", fontPaths[font][path]);
+ else
+ break;
+ }
+ }
+
+ if (!found)
+ g_error("Could not find font at %s. Either install this font or file a bug "
+ "at http://bugs.webkit.org if it is installed in another location.",
+ fontPaths[font][0]);
+ }
- FcConfig *config = FcConfigCreate();
- if (!FcConfigParseAndLoad (config, (FcChar8*) FONTS_CONF_FILE, true))
- g_error("Couldn't load font configuration file");
- if (!FcConfigAppFontAddDir (config, (FcChar8*) g_file_get_path(fontDir)))
- g_error("Couldn't add font dir!");
- FcConfigSetCurrent(config);
+ // Ahem is used by many layout tests.
+ GOwnPtr<gchar> ahemFontFilename(g_build_filename(FONTS_CONF_DIR, "AHEM____.TTF", NULL));
+ if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(ahemFontFilename.get())))
+ g_error("Could not load font at %s!", ahemFontFilename.get());
- g_object_unref(fontDir);
+ if (!FcConfigSetCurrent(config))
+ g_error("Could not set the current font configuration!");
- appFontSet = FcConfigGetFonts(config, FcSetApplication);
- numFonts = appFontSet->nfont;
+ numFonts = FcConfigGetFonts(config, FcSetApplication)->nfont;
#endif
}
@@ -336,6 +381,7 @@ static void resetDefaultsToConsistentValues()
"auto-resize-window", TRUE,
"enable-java-applet", FALSE,
"enable-plugins", TRUE,
+ "enable-hyperlink-auditing", FALSE,
"editing-behavior", WEBKIT_EDITING_BEHAVIOR_MAC,
NULL);
diff --git a/WebKitTools/DumpRenderTree/gtk/EventSender.cpp b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp
index d1529db..6e5fa5f 100644
--- a/WebKitTools/DumpRenderTree/gtk/EventSender.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp
@@ -147,6 +147,58 @@ bool prepareMouseButtonEvent(GdkEvent* event, int eventSenderButtonNumber, guint
return true;
}
+static JSValueRef getMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
+{
+ GtkWidget* widget = GTK_WIDGET(JSObjectGetPrivate(object));
+ CString label;
+ if (GTK_IS_SEPARATOR_MENU_ITEM(widget))
+ label = "<separator>";
+ else
+ label = gtk_menu_item_get_label(GTK_MENU_ITEM(widget));
+
+ return JSValueMakeString(context, JSStringCreateWithUTF8CString(label.data()));
+}
+
+static bool setMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
+{
+ return true;
+}
+
+static JSValueRef menuItemClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ GtkMenuItem* item = GTK_MENU_ITEM(JSObjectGetPrivate(thisObject));
+ gtk_menu_item_activate(item);
+ return JSValueMakeUndefined(context);
+}
+
+static JSStaticFunction staticMenuItemFunctions[] = {
+ { "click", menuItemClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+};
+
+static JSStaticValue staticMenuItemValues[] = {
+ { "title", getMenuItemTitleCallback, setMenuItemTitleCallback, kJSPropertyAttributeNone },
+ { 0, 0, 0, 0 }
+};
+
+static JSClassRef getMenuItemClass()
+{
+ static JSClassRef menuItemClass = 0;
+
+ if (!menuItemClass) {
+ JSClassDefinition classDefinition = {
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ classDefinition.staticFunctions = staticMenuItemFunctions;
+ classDefinition.staticValues = staticMenuItemValues;
+
+ menuItemClass = JSClassCreate(&classDefinition);
+ }
+
+ return menuItemClass;
+}
+
+
static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
GdkEvent* pressEvent = gdk_event_new(GDK_BUTTON_PRESS);
@@ -165,13 +217,7 @@ static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef functio
JSValueRef arrayValues[g_list_length(items)];
int index = 0;
for (GList* item = g_list_first(items); item; item = g_list_next(item)) {
- CString label;
- if (GTK_IS_SEPARATOR_MENU_ITEM(item->data))
- label = "<separator>";
- else
- label = gtk_menu_item_get_label(GTK_MENU_ITEM(item->data));
-
- arrayValues[index] = JSValueMakeString(context, JSStringCreateWithUTF8CString(label.data()));
+ arrayValues[index] = JSObjectMake(context, getMenuItemClass(), item->data);
index++;
}
if (index)
diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
index 32be43d..d831076 100644
--- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
@@ -38,7 +38,6 @@
#include "WorkQueueItem.h"
#include <JavaScriptCore/JSRetainPtr.h>
#include <JavaScriptCore/JSStringRef.h>
-
#include <cstring>
#include <iostream>
#include <sstream>
@@ -46,6 +45,7 @@
#include <glib.h>
#include <libsoup/soup.h>
#include <webkit/webkit.h>
+#include <wtf/gobject/GOwnPtr.h>
extern "C" {
bool webkit_web_frame_pause_animation(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element);
@@ -66,24 +66,6 @@ void webkit_web_view_execute_core_command_by_name(WebKitWebView* webView, const
gboolean webkit_web_view_is_command_enabled(WebKitWebView* webView, const gchar* name);
}
-static gchar* copyWebSettingKey(gchar* preferenceKey)
-{
- static GHashTable* keyTable;
-
- if (!keyTable) {
- // If you add a pref here, make sure you reset the value in
- // DumpRenderTree::resetDefaultsToConsistentValues.
- keyTable = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(keyTable, g_strdup("WebKitJavaScriptEnabled"), g_strdup("enable-scripts"));
- g_hash_table_insert(keyTable, g_strdup("WebKitDefaultFontSize"), g_strdup("default-font-size"));
- g_hash_table_insert(keyTable, g_strdup("WebKitEnableCaretBrowsing"), g_strdup("enable-caret-browsing"));
- g_hash_table_insert(keyTable, g_strdup("WebKitUsesPageCachePreferenceKey"), g_strdup("enable-page-cache"));
- g_hash_table_insert(keyTable, g_strdup("WebKitPluginsEnabled"), g_strdup("enable-plugins"));
- }
-
- return g_strdup(static_cast<gchar*>(g_hash_table_lookup(keyTable, preferenceKey)));
-}
-
LayoutTestController::~LayoutTestController()
{
// FIXME: implement
@@ -155,6 +137,12 @@ JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef
return JSValueMakeUndefined(context);
}
+JSValueRef LayoutTestController::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
+{
+ // FIXME: Implement this.
+ return JSValueMakeUndefined(context);
+}
+
JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
{
// FIXME: implement
@@ -664,48 +652,53 @@ void LayoutTestController::resumeAnimations() const
void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value)
{
- gchar* name = JSStringCopyUTF8CString(key);
- gchar* strValue = JSStringCopyUTF8CString(value);
+ GOwnPtr<gchar> originalName(JSStringCopyUTF8CString(key));
+ GOwnPtr<gchar> valueAsString(JSStringCopyUTF8CString(value));
WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
ASSERT(view);
- WebKitWebSettings* settings = webkit_web_view_get_settings(view);
- gchar* webSettingKey = copyWebSettingKey(name);
-
- if (webSettingKey) {
- GValue stringValue = { 0, { { 0 } } };
- g_value_init(&stringValue, G_TYPE_STRING);
- g_value_set_string(&stringValue, const_cast<gchar*>(strValue));
-
- WebKitWebSettingsClass* klass = WEBKIT_WEB_SETTINGS_GET_CLASS(settings);
- GParamSpec* pspec = g_object_class_find_property(G_OBJECT_CLASS(klass), webSettingKey);
- GValue propValue = { 0, { { 0 } } };
- g_value_init(&propValue, pspec->value_type);
-
- if (g_value_type_transformable(G_TYPE_STRING, pspec->value_type)) {
- g_value_transform(const_cast<GValue*>(&stringValue), &propValue);
- g_object_set_property(G_OBJECT(settings), webSettingKey, const_cast<GValue*>(&propValue));
- } else if (G_VALUE_HOLDS_BOOLEAN(&propValue)) {
- char* lowered = g_utf8_strdown(strValue, -1);
- g_object_set(G_OBJECT(settings), webSettingKey,
- g_str_equal(lowered, "true")
- || g_str_equal(strValue, "1"),
- NULL);
- g_free(lowered);
- } else if (G_VALUE_HOLDS_INT(&propValue)) {
- std::string str(strValue);
- std::stringstream ss(str);
- int val = 0;
- if (!(ss >> val).fail())
- g_object_set(G_OBJECT(settings), webSettingKey, val, NULL);
- } else
- printf("LayoutTestController::overridePreference failed to override preference '%s'.\n", name);
+ // This transformation could be handled by a hash table (and it once was), but
+ // having it prominent, makes it easier for people from other ports to keep the
+ // list up to date.
+ const gchar* propertyName = 0;
+ if (g_str_equal(originalName.get(), "WebKitJavaScriptEnabled"))
+ propertyName = "enable-scripts";
+ else if (g_str_equal(originalName.get(), "WebKitDefaultFontSize"))
+ propertyName = "default-font-size";
+ else if (g_str_equal(originalName.get(), "WebKitEnableCaretBrowsing"))
+ propertyName = "enable-caret-browsing";
+ else if (g_str_equal(originalName.get(), "WebKitUsesPageCachePreferenceKey"))
+ propertyName = "enable-page-cache";
+ else if (g_str_equal(originalName.get(), "WebKitPluginsEnabled"))
+ propertyName = "enable-plugins";
+ else if (g_str_equal(originalName.get(), "WebKitHyperlinkAuditingEnabled"))
+ propertyName = "enable-hyperlink-auditing";
+ else {
+ fprintf(stderr, "LayoutTestController::overridePreference tried to override "
+ "unknown preference '%s'.\n", originalName.get());
+ return;
}
- g_free(webSettingKey);
- g_free(name);
- g_free(strValue);
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ GParamSpec* pspec = g_object_class_find_property(G_OBJECT_CLASS(
+ WEBKIT_WEB_SETTINGS_GET_CLASS(settings)), propertyName);
+ GValue currentPropertyValue = { 0, { { 0 } } };
+ g_value_init(&currentPropertyValue, pspec->value_type);
+
+ if (G_VALUE_HOLDS_STRING(&currentPropertyValue))
+ g_object_set(settings, propertyName, valueAsString.get(), NULL);
+ else if (G_VALUE_HOLDS_BOOLEAN(&currentPropertyValue))
+ g_object_set(G_OBJECT(settings), propertyName, !g_ascii_strcasecmp(valueAsString.get(), "true")
+ || !g_ascii_strcasecmp(valueAsString.get(), "1"), NULL);
+ else if (G_VALUE_HOLDS_INT(&currentPropertyValue))
+ g_object_set(G_OBJECT(settings), propertyName, atoi(valueAsString.get()), NULL);
+ else if (G_VALUE_HOLDS_FLOAT(&currentPropertyValue)) {
+ gfloat newValue = g_ascii_strtod(valueAsString.get(), 0);
+ g_object_set(G_OBJECT(settings), propertyName, newValue, NULL);
+ } else
+ fprintf(stderr, "LayoutTestController::overridePreference failed to override "
+ "preference '%s'.\n", originalName.get());
}
void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
diff --git a/WebKitTools/DumpRenderTree/gtk/fonts.conf b/WebKitTools/DumpRenderTree/gtk/fonts.conf
deleted file mode 100644
index 3540c47..0000000
--- a/WebKitTools/DumpRenderTree/gtk/fonts.conf
+++ /dev/null
@@ -1,258 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
-<fontconfig>
-
-<!--
- Accept deprecated 'mono' alias, replacing it with 'monospace'
--->
- <match target="pattern">
- <test qual="any" name="family">
- <string>mono</string>
- </test>
- <edit name="family" mode="assign">
- <string>monospace</string>
- </edit>
- </match>
-
-<!--
- Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
--->
- <match target="pattern">
- <test qual="any" name="family">
- <string>sans serif</string>
- </test>
- <edit name="family" mode="assign">
- <string>sans-serif</string>
- </edit>
- </match>
-
-<!--
- Accept deprecated 'sans' alias, replacing it with 'sans-serif'
--->
- <match target="pattern">
- <test qual="any" name="family">
- <string>sans</string>
- </test>
- <edit name="family" mode="assign">
- <string>sans-serif</string>
- </edit>
- </match>
-
-
- <config>
-<!--
- These are the default Unicode chars that are expected to be blank
- in fonts. All other blank chars are assumed to be broken and
- won't appear in the resulting charsets
- -->
- <blank>
- <int>0x0020</int> <!-- SPACE -->
- <int>0x00A0</int> <!-- NO-BREAK SPACE -->
- <int>0x00AD</int> <!-- SOFT HYPHEN -->
- <int>0x034F</int> <!-- COMBINING GRAPHEME JOINER -->
- <int>0x0600</int> <!-- ARABIC NUMBER SIGN -->
- <int>0x0601</int> <!-- ARABIC SIGN SANAH -->
- <int>0x0602</int> <!-- ARABIC FOOTNOTE MARKER -->
- <int>0x0603</int> <!-- ARABIC SIGN SAFHA -->
- <int>0x06DD</int> <!-- ARABIC END OF AYAH -->
- <int>0x070F</int> <!-- SYRIAC ABBREVIATION MARK -->
- <int>0x115F</int> <!-- HANGUL CHOSEONG FILLER -->
- <int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER -->
- <int>0x1680</int> <!-- OGHAM SPACE MARK -->
- <int>0x17B4</int> <!-- KHMER VOWEL INHERENT AQ -->
- <int>0x17B5</int> <!-- KHMER VOWEL INHERENT AA -->
- <int>0x180E</int> <!-- MONGOLIAN VOWEL SEPARATOR -->
- <int>0x2000</int> <!-- EN QUAD -->
- <int>0x2001</int> <!-- EM QUAD -->
- <int>0x2002</int> <!-- EN SPACE -->
- <int>0x2003</int> <!-- EM SPACE -->
- <int>0x2004</int> <!-- THREE-PER-EM SPACE -->
- <int>0x2005</int> <!-- FOUR-PER-EM SPACE -->
- <int>0x2006</int> <!-- SIX-PER-EM SPACE -->
- <int>0x2007</int> <!-- FIGURE SPACE -->
- <int>0x2008</int> <!-- PUNCTUATION SPACE -->
- <int>0x2009</int> <!-- THIN SPACE -->
- <int>0x200A</int> <!-- HAIR SPACE -->
- <int>0x200B</int> <!-- ZERO WIDTH SPACE -->
- <int>0x200C</int> <!-- ZERO WIDTH NON-JOINER -->
- <int>0x200D</int> <!-- ZERO WIDTH JOINER -->
- <int>0x200E</int> <!-- LEFT-TO-RIGHT MARK -->
- <int>0x200F</int> <!-- RIGHT-TO-LEFT MARK -->
- <int>0x2028</int> <!-- LINE SEPARATOR -->
- <int>0x2029</int> <!-- PARAGRAPH SEPARATOR -->
- <int>0x202A</int> <!-- LEFT-TO-RIGHT EMBEDDING -->
- <int>0x202B</int> <!-- RIGHT-TO-LEFT EMBEDDING -->
- <int>0x202C</int> <!-- POP DIRECTIONAL FORMATTING -->
- <int>0x202D</int> <!-- LEFT-TO-RIGHT OVERRIDE -->
- <int>0x202E</int> <!-- RIGHT-TO-LEFT OVERRIDE -->
- <int>0x202F</int> <!-- NARROW NO-BREAK SPACE -->
- <int>0x205F</int> <!-- MEDIUM MATHEMATICAL SPACE -->
- <int>0x2060</int> <!-- WORD JOINER -->
- <int>0x2061</int> <!-- FUNCTION APPLICATION -->
- <int>0x2062</int> <!-- INVISIBLE TIMES -->
- <int>0x2063</int> <!-- INVISIBLE SEPARATOR -->
- <int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING -->
- <int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING -->
- <int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING -->
- <int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING -->
- <int>0x206E</int> <!-- NATIONAL DIGIT SHAPES -->
- <int>0x206F</int> <!-- NOMINAL DIGIT SHAPES -->
- <int>0x3000</int> <!-- IDEOGRAPHIC SPACE -->
- <int>0x3164</int> <!-- HANGUL FILLER -->
- <int>0xFEFF</int> <!-- ZERO WIDTH NO-BREAK SPACE -->
- <int>0xFFA0</int> <!-- HALFWIDTH HANGUL FILLER -->
- <int>0xFFF9</int> <!-- INTERLINEAR ANNOTATION ANCHOR -->
- <int>0xFFFA</int> <!-- INTERLINEAR ANNOTATION SEPARATOR -->
- <int>0xFFFB</int> <!-- INTERLINEAR ANNOTATION TERMINATOR -->
- </blank>
-<!--
- Rescan configuration every 30 seconds when FcFontSetList is called
- -->
- <rescan>
- <int>30</int>
- </rescan>
- </config>
-
-<!--
- URW provides metric and shape compatible fonts for these 10 Adobe families.
-
- However, these fonts are quite ugly and do not render well on-screen,
- so we avoid matching them if the application said `anymetrics'; in that
- case, a more generic font with different metrics but better appearance
- will be used.
- -->
- <match target="pattern">
- <test name="family">
- <string>Avant Garde</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append">
- <string>URW Gothic L</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family">
- <string>Bookman</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append">
- <string>URW Bookman L</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family">
- <string>Courier</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append">
- <string>Nimbus Mono L</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family">
- <string>Helvetica</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append">
- <string>Nimbus Sans L</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family">
- <string>New Century Schoolbook</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append">
- <string>Century Schoolbook L</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family">
- <string>Palatino</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append">
- <string>URW Palladio L</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family">
- <string>Times</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append">
- <string>Nimbus Roman No9 L</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family">
- <string>Zapf Chancery</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append">
- <string>URW Chancery L</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family">
- <string>Zapf Dingbats</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append">
- <string>Dingbats</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family">
- <string>Symbol</string>
- </test>
- <test name="anymetrics" qual="all" compare="not_eq">
- <bool>true</bool>
- </test>
- <edit name="family" mode="append" binding="same">
- <string>Standard Symbols L</string>
- </edit>
- </match>
-
-<!--
- Serif faces
- -->
- <alias>
- <family>Nimbus Roman No9 L</family>
- <default><family>serif</family></default>
- </alias>
-<!--
- Sans-serif faces
- -->
- <alias>
- <family>Nimbus Sans L</family>
- <default><family>sans-serif</family></default>
- </alias>
-<!--
- Monospace faces
- -->
- <alias>
- <family>Nimbus Mono L</family>
- <default><family>monospace</family></default>
- </alias>
-
-
-</fontconfig>
diff --git a/WebKitTools/DumpRenderTree/gtk/fonts/AHEM____.TTF b/WebKitTools/DumpRenderTree/gtk/fonts/AHEM____.TTF
new file mode 100644
index 0000000..ac81cb0
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/fonts/AHEM____.TTF
Binary files differ
diff --git a/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf b/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf
new file mode 100644
index 0000000..520f96e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/gtk/fonts/fonts.conf
@@ -0,0 +1,282 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+
+ <!-- The sans-serif font should be Liberation Serif -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>serif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Times</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Times New Roman</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ </match>
+
+ <!-- The sans-serif font should be Liberation Sans -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans serif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ </match>
+ <!-- We need to ensure that layout tests that use "Helvetica" don't
+ fall back to the default serif font -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Helvetica</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ </match>
+
+ <!-- The Monospace font should be Liberation Mono -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>monospace</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>mono</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+ <!-- We need to ensure that layout tests that use "Courier", "Courier New",
+ and "Monaco" (all monospace fonts) don't fall back to the default
+ serif font -->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Courier</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Courier New</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>Monaco</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Mono</string>
+ </edit>
+ </match>
+
+ <!-- The following hinting specializations are adapted from those in the
+ Chromium test_shell. We try to duplicate their incredibly thorough
+ testing here -->
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>NonAntiAliasedSans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ <edit name="antialias" mode="assign">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>SlightHintedSerif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ <edit name="hintstyle" mode="assign">
+ <const>hintslight</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>NonHintedSans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ <!-- These deliberately contradict each other. The 'hinting' preference
+ should take priority -->
+ <edit name="hintstyle" mode="assign">
+ <const>hintfull</const>
+ </edit>
+ <edit name="hinting" mode="assign">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>AutohintedSerif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ <edit name="autohint" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <edit name="hintstyle" mode="assign">
+ <const>hintmedium</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>HintedSerif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ <edit name="autohint" mode="assign">
+ <bool>false</bool>
+ </edit>
+ <edit name="hintstyle" mode="assign">
+ <const>hintmedium</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>FullAndAutoHintedSerif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Serif</string>
+ </edit>
+ <edit name="autohint" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <edit name="hintstyle" mode="assign">
+ <const>hintfull</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>SubpixelEnabledSans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ <edit name="rgba" mode="assign">
+ <const>rgb</const>
+ </edit>
+ </match>
+
+ <match target="pattern">
+ <test name="family" compare="eq">
+ <string>SubpixelDisabledSans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>Liberation Sans</string>
+ </edit>
+ <edit name="rgba" mode="assign">
+ <const>none</const>
+ </edit>
+ </match>
+
+ <config>
+ <!-- These are the default Unicode chars that are expected to be blank
+ in fonts. All other blank chars are assumed to be broken and won't
+ appear in the resulting charsets -->
+ <blank>
+ <int>0x0020</int> <!-- SPACE -->
+ <int>0x00A0</int> <!-- NO-BREAK SPACE -->
+ <int>0x00AD</int> <!-- SOFT HYPHEN -->
+ <int>0x034F</int> <!-- COMBINING GRAPHEME JOINER -->
+ <int>0x0600</int> <!-- ARABIC NUMBER SIGN -->
+ <int>0x0601</int> <!-- ARABIC SIGN SANAH -->
+ <int>0x0602</int> <!-- ARABIC FOOTNOTE MARKER -->
+ <int>0x0603</int> <!-- ARABIC SIGN SAFHA -->
+ <int>0x06DD</int> <!-- ARABIC END OF AYAH -->
+ <int>0x070F</int> <!-- SYRIAC ABBREVIATION MARK -->
+ <int>0x115F</int> <!-- HANGUL CHOSEONG FILLER -->
+ <int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER -->
+ <int>0x1680</int> <!-- OGHAM SPACE MARK -->
+ <int>0x17B4</int> <!-- KHMER VOWEL INHERENT AQ -->
+ <int>0x17B5</int> <!-- KHMER VOWEL INHERENT AA -->
+ <int>0x180E</int> <!-- MONGOLIAN VOWEL SEPARATOR -->
+ <int>0x2000</int> <!-- EN QUAD -->
+ <int>0x2001</int> <!-- EM QUAD -->
+ <int>0x2002</int> <!-- EN SPACE -->
+ <int>0x2003</int> <!-- EM SPACE -->
+ <int>0x2004</int> <!-- THREE-PER-EM SPACE -->
+ <int>0x2005</int> <!-- FOUR-PER-EM SPACE -->
+ <int>0x2006</int> <!-- SIX-PER-EM SPACE -->
+ <int>0x2007</int> <!-- FIGURE SPACE -->
+ <int>0x2008</int> <!-- PUNCTUATION SPACE -->
+ <int>0x2009</int> <!-- THIN SPACE -->
+ <int>0x200A</int> <!-- HAIR SPACE -->
+ <int>0x200B</int> <!-- ZERO WIDTH SPACE -->
+ <int>0x200C</int> <!-- ZERO WIDTH NON-JOINER -->
+ <int>0x200D</int> <!-- ZERO WIDTH JOINER -->
+ <int>0x200E</int> <!-- LEFT-TO-RIGHT MARK -->
+ <int>0x200F</int> <!-- RIGHT-TO-LEFT MARK -->
+ <int>0x2028</int> <!-- LINE SEPARATOR -->
+ <int>0x2029</int> <!-- PARAGRAPH SEPARATOR -->
+ <int>0x202A</int> <!-- LEFT-TO-RIGHT EMBEDDING -->
+ <int>0x202B</int> <!-- RIGHT-TO-LEFT EMBEDDING -->
+ <int>0x202C</int> <!-- POP DIRECTIONAL FORMATTING -->
+ <int>0x202D</int> <!-- LEFT-TO-RIGHT OVERRIDE -->
+ <int>0x202E</int> <!-- RIGHT-TO-LEFT OVERRIDE -->
+ <int>0x202F</int> <!-- NARROW NO-BREAK SPACE -->
+ <int>0x205F</int> <!-- MEDIUM MATHEMATICAL SPACE -->
+ <int>0x2060</int> <!-- WORD JOINER -->
+ <int>0x2061</int> <!-- FUNCTION APPLICATION -->
+ <int>0x2062</int> <!-- INVISIBLE TIMES -->
+ <int>0x2063</int> <!-- INVISIBLE SEPARATOR -->
+ <int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING -->
+ <int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING -->
+ <int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING -->
+ <int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING -->
+ <int>0x206E</int> <!-- NATIONAL DIGIT SHAPES -->
+ <int>0x206F</int> <!-- NOMINAL DIGIT SHAPES -->
+ <int>0x3000</int> <!-- IDEOGRAPHIC SPACE -->
+ <int>0x3164</int> <!-- HANGUL FILLER -->
+ <int>0xFEFF</int> <!-- ZERO WIDTH NO-BREAK SPACE -->
+ <int>0xFFA0</int> <!-- HALFWIDTH HANGUL FILLER -->
+ <int>0xFFF9</int> <!-- INTERLINEAR ANNOTATION ANCHOR -->
+ <int>0xFFFA</int> <!-- INTERLINEAR ANNOTATION SEPARATOR -->
+ <int>0xFFFB</int> <!-- INTERLINEAR ANNOTATION TERMINATOR -->
+ </blank>
+ </config>
+</fontconfig>
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
index f55093e..d2a6f79 100644
--- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -198,6 +198,11 @@ JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef
return [[mainFrame webView] _computedStyleIncludingVisitedInfo:context forElement:value];
}
+JSValueRef LayoutTestController::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
+{
+ return [[mainFrame webView] _nodesFromRect:context forDocument:value x:x y:y top:top right:right bottom:bottom left:left ignoreClipping:ignoreClipping];
+}
+
JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
{
JSRetainPtr<JSStringRef> string(Adopt, JSStringCreateWithCFString((CFStringRef)[mainFrame _layerTreeAsText]));
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
index 5b81901..801251d 100644
--- a/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTree.pro
@@ -43,4 +43,9 @@ unix:!mac {
QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR
}
+wince*: {
+ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/ce-compat $$WCECOMPAT/include
+ LIBS += $$WCECOMPAT/lib/wcecompat.lib
+}
+
DEFINES+=USE_SYSTEM_MALLOC
diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
index 4e6f049..80fa441 100644
--- a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
@@ -564,7 +564,10 @@ void DumpRenderTree::resetToConsistentStateBeforeTesting()
DumpRenderTreeSupportQt::setEditingBehavior(m_page, "win");
QLocale::setDefault(QLocale::c());
+
+#ifndef Q_OS_WINCE
setlocale(LC_ALL, "");
+#endif
}
static bool isGlobalHistoryTest(const QUrl& url)
diff --git a/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp b/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp
index 63dbd2a..fd7c925 100644
--- a/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/EventSenderQt.cpp
@@ -381,7 +381,6 @@ void EventSender::scheduleAsynchronousClick()
void EventSender::addTouchPoint(int x, int y)
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
// Use index to refer to the position in the vector that this touch
// is stored. We then create a unique id for the touch that will be
// passed into WebCore.
@@ -391,24 +390,20 @@ void EventSender::addTouchPoint(int x, int y)
m_touchPoints.append(point);
updateTouchPoint(index, x, y);
m_touchPoints[index].setState(Qt::TouchPointPressed);
-#endif
}
void EventSender::updateTouchPoint(int index, int x, int y)
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
if (index < 0 || index >= m_touchPoints.count())
return;
QTouchEvent::TouchPoint &p = m_touchPoints[index];
p.setPos(QPointF(x, y));
p.setState(Qt::TouchPointMoved);
-#endif
}
void EventSender::setTouchModifier(const QString &modifier, bool enable)
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
Qt::KeyboardModifier mod = Qt::NoModifier;
if (!modifier.compare(QLatin1String("shift"), Qt::CaseInsensitive))
mod = Qt::ShiftModifier;
@@ -423,30 +418,24 @@ void EventSender::setTouchModifier(const QString &modifier, bool enable)
m_touchModifiers |= mod;
else
m_touchModifiers &= ~mod;
-#endif
}
void EventSender::touchStart()
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
if (!m_touchActive) {
sendTouchEvent(QEvent::TouchBegin);
m_touchActive = true;
} else
sendTouchEvent(QEvent::TouchUpdate);
-#endif
}
void EventSender::touchMove()
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
sendTouchEvent(QEvent::TouchUpdate);
-#endif
}
void EventSender::touchEnd()
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
for (int i = 0; i < m_touchPoints.count(); ++i)
if (m_touchPoints[i].state() != Qt::TouchPointReleased) {
sendTouchEvent(QEvent::TouchUpdate);
@@ -454,31 +443,25 @@ void EventSender::touchEnd()
}
sendTouchEvent(QEvent::TouchEnd);
m_touchActive = false;
-#endif
}
void EventSender::clearTouchPoints()
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
m_touchPoints.clear();
m_touchModifiers = Qt::KeyboardModifiers();
m_touchActive = false;
-#endif
}
void EventSender::releaseTouchPoint(int index)
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
if (index < 0 || index >= m_touchPoints.count())
return;
m_touchPoints[index].setState(Qt::TouchPointReleased);
-#endif
}
void EventSender::sendTouchEvent(QEvent::Type type)
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
QTouchEvent event(type, QTouchEvent::TouchScreen, m_touchModifiers);
event.setTouchPoints(m_touchPoints);
sendEvent(m_page, &event);
@@ -491,7 +474,6 @@ void EventSender::sendTouchEvent(QEvent::Type type)
++it;
}
}
-#endif
}
void EventSender::zoomPageIn()
diff --git a/WebKitTools/DumpRenderTree/qt/EventSenderQt.h b/WebKitTools/DumpRenderTree/qt/EventSenderQt.h
index a17e938..4ba8382 100644
--- a/WebKitTools/DumpRenderTree/qt/EventSenderQt.h
+++ b/WebKitTools/DumpRenderTree/qt/EventSenderQt.h
@@ -41,13 +41,11 @@
#include <QPoint>
#include <QString>
#include <QStringList>
+#include <QTouchEvent>
#include <qwebpage.h>
#include <qwebframe.h>
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
-#include <QTouchEvent>
-#endif
class EventSender : public QObject {
Q_OBJECT
@@ -107,10 +105,8 @@ private:
QEventLoop* m_eventLoop;
QWebFrame* frameUnderMouse() const;
QBasicTimer m_clickTimer;
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
QList<QTouchEvent::TouchPoint> m_touchPoints;
Qt::KeyboardModifiers m_touchModifiers;
bool m_touchActive;
-#endif
};
#endif // EventSenderQt_h
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
index b2ef716..90a04c4 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
@@ -591,6 +591,8 @@ void LayoutTestController::overridePreference(const QString& name, const QVarian
settings->setAttribute(QWebSettings::PluginsEnabled, value.toBool());
else if (name == "WebKitWebGLEnabled")
settings->setAttribute(QWebSettings::WebGLEnabled, value.toBool());
+ else if (name == "WebKitHyperlinkAuditingEnabled")
+ settings->setAttribute(QWebSettings::HyperlinkAuditingEnabled, value.toBool());
else
printf("ERROR: LayoutTestController::overridePreference() does not support the '%s' preference\n",
name.toLatin1().data());
diff --git a/WebKitTools/DumpRenderTree/qt/TextInputControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/TextInputControllerQt.cpp
index e0c9b61..08d8850 100644
--- a/WebKitTools/DumpRenderTree/qt/TextInputControllerQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/TextInputControllerQt.cpp
@@ -133,10 +133,8 @@ void TextInputController::doCommand(const QString& command)
void TextInputController::setMarkedText(const QString& string, int start, int end)
{
QList<QInputMethodEvent::Attribute> attributes;
-#if QT_VERSION >= 0x040600
QInputMethodEvent::Attribute selection(QInputMethodEvent::Selection, start, end, QVariant());
attributes << selection;
-#endif
QInputMethodEvent event(string, attributes);
QApplication::sendEvent(parent(), &event);
}
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
index 1e765c6..1cba86a 100644
--- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
@@ -242,7 +242,7 @@
>
<Tool
Name="VCPreBuildEventTool"
- CommandLine="%SystemDrive%\cygwin\bin\which.exe bash&#x0D;&#x0A;if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;cmd /c&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash&#x0D;&#x0A;if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;cmd /c&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(TargetDir)\..\include\WebCore\ForwardingHeaders\wtf\MD5.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
@@ -316,7 +316,7 @@
>
<Tool
Name="VCPreBuildEventTool"
- CommandLine="%SystemDrive%\cygwin\bin\which.exe bash&#x0D;&#x0A;if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;cmd /c&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash&#x0D;&#x0A;if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;cmd /c&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(TargetDir)\..\include\WebCore\ForwardingHeaders\wtf\MD5.h&quot; &quot;$(WebKitOutputDir)\include\DumpRenderTree\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
@@ -566,23 +566,23 @@
</File>
</Filter>
<File
- RelativePath="..\AccessibilityUIElement.cpp"
+ RelativePath="..\AccessibilityTextMarker.cpp"
>
</File>
<File
- RelativePath="..\AccessibilityUIElement.h"
+ RelativePath="..\AccessibilityTextMarker.h"
>
</File>
<File
- RelativePath=".\AccessibilityUIElementWin.cpp"
+ RelativePath="..\AccessibilityUIElement.cpp"
>
</File>
<File
- RelativePath="..\AccessibilityTextMarker.cpp"
+ RelativePath="..\AccessibilityUIElement.h"
>
</File>
<File
- RelativePath="..\AccessibilityTextMarker.h"
+ RelativePath=".\AccessibilityUIElementWin.cpp"
>
</File>
<File
@@ -608,10 +608,42 @@
<File
RelativePath=".\MD5.cpp"
>
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
</File>
<File
RelativePath=".\MD5.h"
>
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ </FileConfiguration>
</File>
<File
RelativePath="..\PixelDumpSupport.cpp"
diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
index 68f4a6a..6dd609c 100644
--- a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
@@ -179,6 +179,12 @@ JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef
return JSValueMakeUndefined(context);
}
+JSValueRef LayoutTestController::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
+{
+ // FIXME: Implement this.
+ return JSValueMakeUndefined(context);
+}
+
JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
{
COMPtr<IWebFramePrivate> framePrivate(Query, frame);
diff --git a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
index f36c290..5fba1cf 100644
--- a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
+++ b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
@@ -486,6 +486,12 @@ JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef,
return 0;
}
+JSValueRef LayoutTestController::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
+{
+ // FIXME: Implement this.
+ return 0;
+}
+
void LayoutTestController::authenticateSession(JSStringRef, JSStringRef, JSStringRef)
{
}
diff --git a/WebKitTools/EWSTools/start-commit-queue.sh b/WebKitTools/EWSTools/start-commit-queue.sh
index 998300e..c55029a 100755
--- a/WebKitTools/EWSTools/start-commit-queue.sh
+++ b/WebKitTools/EWSTools/start-commit-queue.sh
@@ -30,8 +30,9 @@
cd "$HOME/Projects/CommitQueue"
while :
do
- git reset --hard
+ git reset --hard trunk
git clean -f
+ git rebase --abort
git svn rebase
./WebKitTools/Scripts/webkit-patch commit-queue --no-confirm --exit-after-iteration 10
done
diff --git a/WebKitTools/EWebLauncher/main.c b/WebKitTools/EWebLauncher/main.c
index c1956a2..8965c42 100644
--- a/WebKitTools/EWebLauncher/main.c
+++ b/WebKitTools/EWebLauncher/main.c
@@ -147,7 +147,7 @@ typedef struct _ELauncher {
static void browserDestroy(Ecore_Evas *ee);
static void closeWindow(Ecore_Evas *ee);
-static int browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Rectangle geometry, const char *engine, unsigned char isFullscreen);
+static int browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Rectangle geometry, const char *engine, unsigned char isFullscreen, const char *databasePath);
static void
print_history(Eina_List *list)
@@ -562,7 +562,7 @@ on_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
info("Create new window (F9) was pressed.\n");
Eina_Rectangle geometry = {0, 0, 0, 0};
browserCreate("http://www.google.com",
- app->theme, app->userAgent, geometry, NULL, 0);
+ app->theme, app->userAgent, geometry, NULL, 0, NULL);
} else if (!strcmp(ev->key, "F10")) {
Evas_Coord x, y, w, h;
Evas_Object *frame = ewk_view_frame_main_get(obj);
@@ -605,7 +605,10 @@ quit(Eina_Bool success, const char *msg)
if (msg)
fputs(msg, (success) ? stdout : stderr);
- free(themePath);
+ if (themePath) {
+ free(themePath);
+ themePath = NULL;
+ }
if (!success)
return EXIT_FAILURE;
@@ -614,7 +617,7 @@ quit(Eina_Bool success, const char *msg)
}
static int
-browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Rectangle geometry, const char *engine, unsigned char isFullscreen)
+browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Rectangle geometry, const char *engine, unsigned char isFullscreen, const char *databasePath)
{
if ((geometry.w <= 0) && (geometry.h <= 0)) {
geometry.w = DEFAULT_WIDTH;
@@ -642,9 +645,6 @@ browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Re
if (!app->evas)
return quit(EINA_FALSE, "ERROR: could not get evas from evas-ecore\n");
- if (!theme)
- theme = themePath;
-
app->theme = theme;
app->userAgent = userAgent;
@@ -660,6 +660,8 @@ browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Re
ewk_view_theme_set(app->browser, theme);
if (userAgent)
ewk_view_setting_user_agent_set(app->browser, userAgent);
+ ewk_view_setting_local_storage_database_path_set(app->browser, databasePath);
+
evas_object_name_set(app->browser, "browser");
evas_object_smart_callback_add(app->browser, "title,changed", on_title_changed, app);
@@ -741,26 +743,25 @@ main_signal_exit(void *data, int ev_type, void *ev)
}
static char *
-findThemePath(void)
+findThemePath(const char *theme)
{
- const char **itr, *locations[] = {
- "./default.edj",
- "./WebKit/efl/DefaultTheme/default.edj",
- "../WebKit/efl/DefaultTheme/default.edj",
- DATA_DIR"/themes/default.edj",
- NULL
- };
+ const char *defaultTheme = DATA_DIR"/default.edj";
+ char *rpath;
+ struct stat st;
- for (itr = locations; *itr; itr++) {
- struct stat st;
- if (!stat(*itr, &st)) {
- char path[PATH_MAX];
- if (realpath(*itr, path))
- return strdup(path);
- }
+ if (!theme)
+ theme = defaultTheme;
+
+ rpath = realpath(theme, NULL);
+ if (!rpath)
+ return NULL;
+
+ if (stat(rpath, &st)) {
+ free(rpath);
+ return NULL;
}
- return NULL;
+ return rpath;
}
int
@@ -824,7 +825,9 @@ main(int argc, char *argv[])
if (sudoWorkaround)
strcat(getenv("HOME"), "blah");
- themePath = findThemePath();
+ themePath = findThemePath(theme);
+ if (!themePath)
+ return quit(EINA_FALSE, "ERROR: could not find theme.\n");
ewk_init();
tmp = getenv("TMPDIR");
@@ -839,7 +842,7 @@ main(int argc, char *argv[])
if (proxyUri)
ewk_settings_proxy_uri_set(proxyUri);
- browserCreate(url, theme, userAgent, geometry, engine, isFullscreen);
+ browserCreate(url, themePath, userAgent, geometry, engine, isFullscreen, path);
ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, main_signal_exit, &windows);
ecore_main_loop_begin();
diff --git a/WebKitTools/GNUmakefile.am b/WebKitTools/GNUmakefile.am
index 292ca7e..1599e89 100644
--- a/WebKitTools/GNUmakefile.am
+++ b/WebKitTools/GNUmakefile.am
@@ -24,7 +24,8 @@ Programs_GtkLauncher_CFLAGS = \
Programs_GtkLauncher_LDADD = \
libwebkitgtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \
$(GTK_LIBS) \
- $(GLIB_LIBS)
+ $(GLIB_LIBS) \
+ $(WINMM_LIBS)
Programs_GtkLauncher_LDFLAGS = \
-no-fast-install \
@@ -100,7 +101,8 @@ Programs_DumpRenderTree_LDADD = \
$(GTK_LIBS) \
$(GLIB_LIBS) \
$(LIBSOUP_LIBS) \
- $(FREETYPE_LIBS)
+ $(FREETYPE_LIBS) \
+ $(WINMM_LIBS)
Programs_DumpRenderTree_LDFLAGS = \
-no-fast-install \
@@ -145,7 +147,7 @@ noinst_LTLIBRARIES += \
dumprendertree_cppflags += \
-DTEST_PLUGIN_DIR=\"${shell pwd}/${top_builddir}/TestNetscapePlugin/.libs\" \
- -DFONTS_CONF_FILE=\"${shell pwd}/${srcdir}/WebKitTools/DumpRenderTree/gtk/fonts.conf\"
+ -DFONTS_CONF_DIR=\"${shell pwd}/${srcdir}/WebKitTools/DumpRenderTree/gtk/fonts\"
TestNetscapePlugin_libtestnetscapeplugin_la_CPPFLAGS = \
-I$(srcdir)/WebKitTools/DumpRenderTree \
diff --git a/WebKitTools/MiniBrowser/Configurations/MiniBrowserCFLite.vsprops b/WebKitTools/MiniBrowser/Configurations/MiniBrowserCFLite.vsprops
new file mode 100644
index 0000000..4e1e538
--- /dev/null
+++ b/WebKitTools/MiniBrowser/Configurations/MiniBrowserCFLite.vsprops
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="MiniBrowserCFLite"
+ >
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shlwapi.lib WebKit$(WebKitDLLConfigSuffix).lib CFLite$(LibraryConfigSuffix).lib"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CFNetwork.resources&quot; &quot;$(WebKitOutputDir)\bin\CFNetwork.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\dnssd.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).pdb&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ />
+</VisualStudioPropertySheet>
diff --git a/WebKitTools/MiniBrowser/Configurations/MiniBrowserCommon.vsprops b/WebKitTools/MiniBrowser/Configurations/MiniBrowserCommon.vsprops
index 0031e14..f64d6ca 100644
--- a/WebKitTools/MiniBrowser/Configurations/MiniBrowserCommon.vsprops
+++ b/WebKitTools/MiniBrowser/Configurations/MiniBrowserCommon.vsprops
@@ -10,14 +10,6 @@
UsePrecompiledHeader="2"
/>
<Tool
- Name="VCLinkerTool"
- AdditionalDependencies="shlwapi.lib WebKit$(WebKitDLLConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib"
- />
- <Tool
- Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CFNetwork.resources&quot; &quot;$(WebKitOutputDir)\bin\CFNetwork.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\dnssd.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).pdb&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
- />
- <Tool
Name="VCPreBuildEventTool"
CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
diff --git a/WebKitTools/MiniBrowser/Configurations/MiniBrowserCoreFoundation.vsprops b/WebKitTools/MiniBrowser/Configurations/MiniBrowserCoreFoundation.vsprops
new file mode 100644
index 0000000..a34efd2
--- /dev/null
+++ b/WebKitTools/MiniBrowser/Configurations/MiniBrowserCoreFoundation.vsprops
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="MiniBrowserCoreFoundation"
+ >
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shlwapi.lib WebKit$(WebKitDLLConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib CFNetwork$(LibraryConfigSuffix).lib"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CFNetwork.resources&quot; &quot;$(WebKitOutputDir)\bin\CFNetwork.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\dnssd.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).pdb&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\QuartzCore$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ />
+</VisualStudioPropertySheet>
diff --git a/WebKitTools/MiniBrowser/MiniBrowser.vcproj b/WebKitTools/MiniBrowser/MiniBrowser.vcproj
index 3ae3f60..7af24ec 100644
--- a/WebKitTools/MiniBrowser/MiniBrowser.vcproj
+++ b/WebKitTools/MiniBrowser/MiniBrowser.vcproj
@@ -18,7 +18,7 @@
<Configuration
Name="Debug|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;.\Configurations\MiniBrowserCoreFoundation.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
UseOfATL="1"
CharacterSet="1"
>
@@ -80,7 +80,7 @@
<Configuration
Name="Release|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\Configurations\MiniBrowserCoreFoundation.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
UseOfATL="1"
CharacterSet="1"
WholeProgramOptimization="1"
@@ -143,7 +143,7 @@
<Configuration
Name="Debug_Internal|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\Configurations\MiniBrowserCoreFoundation.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
UseOfATL="1"
CharacterSet="1"
>
@@ -205,7 +205,7 @@
<Configuration
Name="Debug_All|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops;.\Configurations\MiniBrowserCoreFoundation.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
UseOfATL="1"
CharacterSet="1"
>
@@ -264,6 +264,135 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug_CFLite|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops;.\Configurations\MiniBrowserCFLite.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
+ UseOfATL="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CFLite|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\Configurations\MiniBrowserCFLite.vsprops;.\Configurations\MiniBrowserCommon.vsprops"
+ UseOfATL="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
@@ -324,6 +453,22 @@
UsePrecompiledHeader="1"
/>
</FileConfiguration>
+ <FileConfiguration
+ Name="Debug_CFLite|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_CFLite|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
</File>
</Filter>
<Filter
diff --git a/WebKitTools/MiniBrowser/mac/BrowserWindowController.m b/WebKitTools/MiniBrowser/mac/BrowserWindowController.m
index 9398e56..cb4c56a 100644
--- a/WebKitTools/MiniBrowser/mac/BrowserWindowController.m
+++ b/WebKitTools/MiniBrowser/mac/BrowserWindowController.m
@@ -300,6 +300,11 @@ static void didFirstVisuallyNonEmptyLayoutForFrame(WKPageRef page, WKFrameRef fr
LOG(@"didFirstVisuallyNonEmptyLayoutForFrame");
}
+static void didRemoveFrameFromHierarchy(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo)
+{
+ LOG(@"didRemoveFrameFromHierarchy");
+}
+
static void didStartProgress(WKPageRef page, const void *clientInfo)
{
[(BrowserWindowController *)clientInfo didStartProgress];
@@ -469,6 +474,11 @@ static void setStatusText(WKPageRef page, WKStringRef text, const void* clientIn
LOG(@"setStatusText");
}
+static void mouseDidMoveOverElement(WKPageRef page, WKEventModifiers modifiers, WKTypeRef userData, const void *clientInfo)
+{
+ LOG(@"mouseDidMoveOverElement");
+}
+
static void contentsSizeChanged(WKPageRef page, int width, int height, WKFrameRef frame, const void *clientInfo)
{
LOG(@"contentsSizeChanged");
@@ -496,6 +506,7 @@ static void contentsSizeChanged(WKPageRef page, int width, int height, WKFrameRe
didReceiveTitleForFrame,
didFirstLayoutForFrame,
didFirstVisuallyNonEmptyLayoutForFrame,
+ didRemoveFrameFromHierarchy,
didStartProgress,
didChangeProgress,
didFinishProgress,
@@ -525,7 +536,9 @@ static void contentsSizeChanged(WKPageRef page, int width, int height, WKFrameRe
runJavaScriptConfirm,
runJavaScriptPrompt,
setStatusText,
- contentsSizeChanged
+ mouseDidMoveOverElement,
+ contentsSizeChanged,
+ 0 /* didNotHandleKeyEvent */
};
WKPageSetPageUIClient(_webView.pageRef, &uiClient);
}
diff --git a/WebKitTools/MiniBrowser/mac/MiniBrowser_Prefix.pch b/WebKitTools/MiniBrowser/mac/MiniBrowser_Prefix.pch
index 0670cf4..a4e648e 100644
--- a/WebKitTools/MiniBrowser/mac/MiniBrowser_Prefix.pch
+++ b/WebKitTools/MiniBrowser/mac/MiniBrowser_Prefix.pch
@@ -29,7 +29,7 @@
#import <WebKit2/WebKit2.h>
-#define ENABLE_LOGGING 1
+#define ENABLE_LOGGING 0
#if ENABLE_LOGGING
#define LOG NSLog
diff --git a/WebKitTools/MiniBrowser/win/BrowserView.cpp b/WebKitTools/MiniBrowser/win/BrowserView.cpp
index 5e90fe2..76848fa 100644
--- a/WebKitTools/MiniBrowser/win/BrowserView.cpp
+++ b/WebKitTools/MiniBrowser/win/BrowserView.cpp
@@ -74,6 +74,10 @@ static void setStatusText(WKPageRef page, WKStringRef text, const void* clientIn
{
}
+static void mouseDidMoveOverElement(WKPageRef page, WKEventModifiers modifiers, WKTypeRef userData, const void *clientInfo)
+{
+}
+
static void contentsSizeChanged(WKPageRef page, int width, int height, WKFrameRef frame, const void *clientInfo)
{
}
@@ -104,7 +108,9 @@ void BrowserView::create(RECT webViewRect, BrowserWindow* parentWindow)
runJavaScriptConfirm,
runJavaScriptPrompt,
setStatusText,
- contentsSizeChanged
+ mouseDidMoveOverElement,
+ contentsSizeChanged,
+ 0 /* didNotHandleKeyEvent */
};
WKPageSetPageUIClient(WKViewGetPage(m_webView), &uiClient);
diff --git a/WebKitTools/QtTestBrowser/launcherwindow.cpp b/WebKitTools/QtTestBrowser/launcherwindow.cpp
index 65bcee7..df29f11 100644
--- a/WebKitTools/QtTestBrowser/launcherwindow.cpp
+++ b/WebKitTools/QtTestBrowser/launcherwindow.cpp
@@ -41,9 +41,7 @@ LauncherWindow::LauncherWindow(WindowOptions* data, QGraphicsScene* sharedScene)
, m_view(0)
, m_inspector(0)
, m_formatMenuAction(0)
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
, m_zoomAnimation(0)
-#endif
{
if (data)
m_windowOptions = *data;
@@ -91,6 +89,9 @@ void LauncherWindow::init()
m_inspector->hide();
connect(this, SIGNAL(destroyed()), m_inspector, SLOT(deleteLater()));
+ if (m_windowOptions.remoteInspectorPort)
+ page()->setProperty("_q_webInspectorServerPort", m_windowOptions.remoteInspectorPort);
+
// the zoom values are chosen to be like in Mozilla Firefox 3
if (!m_zoomLevels.count()) {
m_zoomLevels << 30 << 50 << 67 << 80 << 90;
@@ -134,9 +135,7 @@ void LauncherWindow::initializeView()
if (url.isValid())
page()->mainFrame()->load(url);
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
m_touchMocking = false;
-#endif
}
void LauncherWindow::applyPrefs()
@@ -240,11 +239,9 @@ void LauncherWindow::createChrome()
toggleFrameFlattening->setCheckable(true);
toggleFrameFlattening->setChecked(settings->testAttribute(QWebSettings::FrameFlatteningEnabled));
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
QAction* touchMockAction = toolsMenu->addAction("Toggle touch mocking", this, SLOT(setTouchMocking(bool)));
touchMockAction->setCheckable(true);
touchMockAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_T));
-#endif
toolsMenu->addSeparator();
@@ -406,7 +403,6 @@ void LauncherWindow::grabZoomKeys(bool grab)
#endif
}
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
void LauncherWindow::sendTouchEvent()
{
if (m_touchPoints.isEmpty())
@@ -430,7 +426,6 @@ void LauncherWindow::sendTouchEvent()
if (m_touchPoints.size() > 1 && m_touchPoints[1].state() == Qt::TouchPointReleased)
m_touchPoints.removeAt(1);
}
-#endif // QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
bool LauncherWindow::eventFilter(QObject* obj, QEvent* event)
{
@@ -446,7 +441,6 @@ bool LauncherWindow::eventFilter(QObject* obj, QEvent* event)
}
}
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
if (!m_touchMocking)
return QObject::eventFilter(obj, event);
@@ -508,7 +502,6 @@ bool LauncherWindow::eventFilter(QObject* obj, QEvent* event)
m_touchPoints.last().setState(Qt::TouchPointStationary);
}
}
-#endif // QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
return false;
}
@@ -546,7 +539,6 @@ void LauncherWindow::zoomAnimationFinished()
void LauncherWindow::applyZoom()
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
if (isGraphicsBased() && page()->settings()->testAttribute(QWebSettings::TiledBackingStoreEnabled)) {
QGraphicsWebView* view = static_cast<WebViewGraphicsBased*>(m_view)->graphicsWebView();
view->setTiledBackingStoreFrozen(true);
@@ -564,7 +556,6 @@ void LauncherWindow::applyZoom()
m_zoomAnimation->start();
return;
}
-#endif
page()->mainFrame()->setZoomFactor(qreal(m_currentZoom) / 100.0);
}
@@ -674,9 +665,7 @@ void LauncherWindow::selectElements()
void LauncherWindow::setTouchMocking(bool on)
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
m_touchMocking = on;
-#endif
}
void LauncherWindow::toggleWebView(bool graphicsBased)
diff --git a/WebKitTools/QtTestBrowser/launcherwindow.h b/WebKitTools/QtTestBrowser/launcherwindow.h
index d3b7f8e..84dedaa 100644
--- a/WebKitTools/QtTestBrowser/launcherwindow.h
+++ b/WebKitTools/QtTestBrowser/launcherwindow.h
@@ -110,6 +110,7 @@ public:
bool useQGLWidgetViewport;
#endif
QUrl inspectorUrl;
+ quint16 remoteInspectorPort;
};
class LauncherWindow : public MainWindow {
@@ -122,9 +123,7 @@ public:
virtual void keyPressEvent(QKeyEvent* event);
void grabZoomKeys(bool grab);
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
void sendTouchEvent();
-#endif
bool eventFilter(QObject* obj, QEvent* event);
@@ -199,11 +198,9 @@ private:
QAction* m_formatMenuAction;
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
QPropertyAnimation* m_zoomAnimation;
QList<QTouchEvent::TouchPoint> m_touchPoints;
bool m_touchMocking;
-#endif
};
#endif
diff --git a/WebKitTools/QtTestBrowser/main.cpp b/WebKitTools/QtTestBrowser/main.cpp
index ec864e9..41471fa 100644
--- a/WebKitTools/QtTestBrowser/main.cpp
+++ b/WebKitTools/QtTestBrowser/main.cpp
@@ -54,6 +54,8 @@ public:
LauncherApplication(int& argc, char** argv);
QStringList urls() const { return m_urls; }
bool isRobotized() const { return m_isRobotized; }
+ int robotTimeout() const { return m_robotTimeoutSeconds; }
+ int robotExtraTime() const { return m_robotExtraTimeSeconds; }
private:
void handleUserOptions();
@@ -61,6 +63,8 @@ private:
private:
bool m_isRobotized;
+ int m_robotTimeoutSeconds;
+ int m_robotExtraTimeSeconds;
QStringList m_urls;
};
@@ -78,6 +82,8 @@ void LauncherApplication::applyDefaultSettings()
LauncherApplication::LauncherApplication(int& argc, char** argv)
: QApplication(argc, argv, QApplication::GuiServer)
, m_isRobotized(false)
+ , m_robotTimeoutSeconds(0)
+ , m_robotExtraTimeSeconds(0)
{
// To allow QWebInspector's configuration persistence
setOrganizationName("Nokia");
@@ -115,6 +121,8 @@ void LauncherApplication::handleUserOptions()
<< "[-cache-webview]"
<< "[-show-fps]"
<< "[-r list]"
+ << "[-robot-timeout seconds]"
+ << "[-robot-extra-time seconds]"
<< "[-inspector-url location]"
<< "[-tiled-backing-store]"
<< "[-resizes-to-contents]"
@@ -180,6 +188,11 @@ void LauncherApplication::handleUserOptions()
if (inspectorUrlIndex != -1)
windowOptions.inspectorUrl = takeOptionValue(&args, inspectorUrlIndex);
+ QString remoteInspectorPortArg("-remote-inspector-port");
+ int remoteInspectorPortIndex = args.indexOf(remoteInspectorPortArg);
+ if (remoteInspectorPortIndex != -1)
+ windowOptions.remoteInspectorPort = takeOptionValue(&args, remoteInspectorPortIndex).toInt();
+
int robotIndex = args.indexOf("-r");
if (robotIndex != -1) {
QString listFile = takeOptionValue(&args, robotIndex);
@@ -190,11 +203,18 @@ void LauncherApplication::handleUserOptions()
m_isRobotized = true;
m_urls = QStringList(listFile);
- return;
+ } else {
+ int lastArg = args.lastIndexOf(QRegExp("^-.*"));
+ m_urls = (lastArg != -1) ? args.mid(++lastArg) : args.mid(1);
}
- int lastArg = args.lastIndexOf(QRegExp("^-.*"));
- m_urls = (lastArg != -1) ? args.mid(++lastArg) : args.mid(1);
+ int robotTimeoutIndex = args.indexOf("-robot-timeout");
+ if (robotTimeoutIndex != -1)
+ m_robotTimeoutSeconds = takeOptionValue(&args, robotTimeoutIndex).toInt();
+
+ int robotExtraTimeIndex = args.indexOf("-robot-extra-time");
+ if (robotExtraTimeIndex != -1)
+ m_robotExtraTimeSeconds = takeOptionValue(&args, robotExtraTimeIndex).toInt();
}
@@ -204,8 +224,7 @@ int main(int argc, char **argv)
if (app.isRobotized()) {
LauncherWindow* window = new LauncherWindow();
- UrlLoader loader(window->page()->mainFrame(), app.urls().at(0));
- QObject::connect(window->page()->mainFrame(), SIGNAL(loadFinished(bool)), &loader, SLOT(loadNext()));
+ UrlLoader loader(window->page()->mainFrame(), app.urls().at(0), app.robotTimeout(), app.robotExtraTime());
loader.loadNext();
window->show();
return launcherMain(app);
@@ -214,9 +233,9 @@ int main(int argc, char **argv)
QStringList urls = app.urls();
if (urls.isEmpty()) {
- QString defaultUrl = QString("file://%1/%2").arg(QDir::homePath()).arg(QLatin1String("index.html"));
- if (QDir(defaultUrl).exists())
- urls.append(defaultUrl);
+ QString defaultIndexFile = QString("%1/%2").arg(QDir::homePath()).arg(QLatin1String("index.html"));
+ if (QFile(defaultIndexFile).exists())
+ urls.append(QString("file://") + defaultIndexFile);
else
urls.append("");
}
diff --git a/WebKitTools/QtTestBrowser/urlloader.cpp b/WebKitTools/QtTestBrowser/urlloader.cpp
index 630ead6..abe9902 100644
--- a/WebKitTools/QtTestBrowser/urlloader.cpp
+++ b/WebKitTools/QtTestBrowser/urlloader.cpp
@@ -31,16 +31,31 @@
#include <QFile>
#include <QDebug>
-UrlLoader::UrlLoader(QWebFrame* frame, const QString& inputFileName)
+UrlLoader::UrlLoader(QWebFrame* frame, const QString& inputFileName, int timeoutSeconds, int extraTimeSeconds)
: m_frame(frame)
, m_stdOut(stdout)
, m_loaded(0)
{
- init(inputFileName);
+ if (timeoutSeconds) {
+ m_timeoutTimer.setInterval(timeoutSeconds * 1000);
+ m_timeoutTimer.setSingleShot(true);
+ connect(frame, SIGNAL(loadStarted()), &m_timeoutTimer, SLOT(start()));
+ connect(&m_timeoutTimer, SIGNAL(timeout()), this, SLOT(loadNext()));
+ }
+ if (extraTimeSeconds) {
+ m_extraTimeTimer.setInterval(extraTimeSeconds * 1000);
+ m_extraTimeTimer.setSingleShot(true);
+ connect(frame, SIGNAL(loadFinished(bool)), &m_extraTimeTimer, SLOT(start()));
+ connect(&m_extraTimeTimer, SIGNAL(timeout()), this, SLOT(loadNext()));
+ } else
+ connect(frame, SIGNAL(loadFinished(bool)), this, SLOT(loadNext()));
+ loadUrlList(inputFileName);
}
void UrlLoader::loadNext()
{
+ m_timeoutTimer.stop();
+ m_extraTimeTimer.stop();
QString qstr;
if (getUrl(qstr)) {
QUrl url(qstr, QUrl::StrictMode);
@@ -53,7 +68,7 @@ void UrlLoader::loadNext()
disconnect(m_frame, 0, this, 0);
}
-void UrlLoader::init(const QString& inputFileName)
+void UrlLoader::loadUrlList(const QString& inputFileName)
{
QFile inputFile(inputFileName);
if (inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
diff --git a/WebKitTools/QtTestBrowser/urlloader.h b/WebKitTools/QtTestBrowser/urlloader.h
index ed14adc..e2a6d87 100644
--- a/WebKitTools/QtTestBrowser/urlloader.h
+++ b/WebKitTools/QtTestBrowser/urlloader.h
@@ -32,19 +32,20 @@
#include "qwebframe.h"
#include <QTextStream>
+#include <QTimer>
#include <QVector>
class UrlLoader : public QObject {
Q_OBJECT
public:
- UrlLoader(QWebFrame* frame, const QString& inputFileName);
+ UrlLoader(QWebFrame* frame, const QString& inputFileName, int timeoutSeconds, int extraTimeSeconds);
public slots:
void loadNext();
private:
- void init(const QString& inputFileName);
+ void loadUrlList(const QString& inputFileName);
bool getUrl(QString& qstr);
private:
@@ -53,6 +54,8 @@ private:
QWebFrame* m_frame;
QTextStream m_stdOut;
int m_loaded;
+ QTimer m_timeoutTimer;
+ QTimer m_extraTimeTimer;
};
#endif
diff --git a/WebKitTools/QtTestBrowser/utils.cpp b/WebKitTools/QtTestBrowser/utils.cpp
index 2d45dd0..567c989 100644
--- a/WebKitTools/QtTestBrowser/utils.cpp
+++ b/WebKitTools/QtTestBrowser/utils.cpp
@@ -82,11 +82,7 @@ QUrl urlFromUserInput(const QString& string)
if (fi.exists() && fi.isRelative())
input = fi.absoluteFilePath();
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
return QUrl::fromUserInput(input);
-#else
- return QUrl(input);
-#endif
}
diff --git a/WebKitTools/QtTestBrowser/webview.cpp b/WebKitTools/QtTestBrowser/webview.cpp
index d8d89a9..242daf6 100644
--- a/WebKitTools/QtTestBrowser/webview.cpp
+++ b/WebKitTools/QtTestBrowser/webview.cpp
@@ -151,7 +151,6 @@ void WebViewGraphicsBased::updateFrameRate()
void WebViewGraphicsBased::animatedFlip()
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
QSizeF center = graphicsWebView()->boundingRect().size() / 2;
QPointF centerPoint = QPointF(center.width(), center.height());
graphicsWebView()->setTransformOriginPoint(centerPoint);
@@ -165,12 +164,10 @@ void WebViewGraphicsBased::animatedFlip()
animation->setEndValue(rotation + 180 - (rotation % 180));
animation->start(QAbstractAnimation::DeleteWhenStopped);
-#endif
}
void WebViewGraphicsBased::animatedYFlip()
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
if (!m_machine) {
m_machine = new QStateMachine(this);
@@ -202,7 +199,6 @@ void WebViewGraphicsBased::animatedYFlip()
}
m_machine->start();
-#endif
}
void WebViewGraphicsBased::paintEvent(QPaintEvent* event)
diff --git a/WebKitTools/QtTestBrowser/webview.h b/WebKitTools/QtTestBrowser/webview.h
index aadf85c..e34d081 100644
--- a/WebKitTools/QtTestBrowser/webview.h
+++ b/WebKitTools/QtTestBrowser/webview.h
@@ -117,13 +117,11 @@ private:
inline void WebViewGraphicsBased::setYRotation(qreal angle)
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
QRectF r = graphicsWebView()->boundingRect();
graphicsWebView()->setTransform(QTransform()
.translate(r.width() / 2, r.height() / 2)
.rotate(angle, Qt::YAxis)
.translate(-r.width() / 2, -r.height() / 2));
-#endif
m_yRotation = angle;
}
diff --git a/WebKitTools/QueueStatusServer/handlers/queuestatus.py b/WebKitTools/QueueStatusServer/handlers/queuestatus.py
index f76157d..0259c37 100644
--- a/WebKitTools/QueueStatusServer/handlers/queuestatus.py
+++ b/WebKitTools/QueueStatusServer/handlers/queuestatus.py
@@ -31,24 +31,27 @@ from google.appengine.ext.webapp import template
from model.queues import queues, display_name_for_queue
from model.workitems import WorkItems
+from model.activeworkitems import ActiveWorkItems
from model import queuestatus
class QueueStatus(webapp.RequestHandler):
- def _rows_for_work_items(self, work_items):
- if not work_items:
+ def _rows_for_work_items(self, queued_items, active_items):
+ if not queued_items:
return []
rows = []
- for item_id in work_items.item_ids:
+ for item_id in queued_items.item_ids:
rows.append({
"attachment_id": item_id,
"bug_id": 1,
+ "lock_time": active_items and active_items.time_for_item(item_id),
})
return rows
def get(self, queue_name):
- work_items = WorkItems.all().filter("queue_name =", queue_name).get()
+ queued_items = WorkItems.all().filter("queue_name =", queue_name).get()
+ active_items = ActiveWorkItems.all().filter("queue_name =", queue_name).get()
statuses = queuestatus.QueueStatus.all().filter("queue_name =", queue_name).order("-date").fetch(15)
status_groups = []
@@ -67,7 +70,7 @@ class QueueStatus(webapp.RequestHandler):
template_values = {
"display_queue_name": display_name_for_queue(queue_name),
- "work_item_rows": self._rows_for_work_items(work_items),
+ "work_item_rows": self._rows_for_work_items(queued_items, active_items),
"status_groups": status_groups,
}
self.response.out.write(template.render("templates/queuestatus.html", template_values))
diff --git a/WebKitTools/QueueStatusServer/handlers/updatestatus.py b/WebKitTools/QueueStatusServer/handlers/updatestatus.py
index 5a93dbd..89858b6 100644
--- a/WebKitTools/QueueStatusServer/handlers/updatestatus.py
+++ b/WebKitTools/QueueStatusServer/handlers/updatestatus.py
@@ -31,6 +31,7 @@ from google.appengine.ext import webapp, db
from google.appengine.ext.webapp import template
from handlers.updatebase import UpdateBase
+from model.activeworkitems import ActiveWorkItems
from model.attachment import Attachment
from model.queuestatus import QueueStatus
@@ -56,8 +57,24 @@ class UpdateStatus(UpdateBase):
queue_status.results_file = db.Blob(str(results_file))
return queue_status
+ @staticmethod
+ def _expire_item(key, item_id):
+ active_work_items = db.get(key)
+ active_work_items.expire_item(item_id)
+ active_work_items.put()
+
+ # FIXME: An explicit lock_release request would be cleaner than this magical "Retry" status.
+ def _update_active_work_items(self, queue_status):
+ if queue_status.message != "Retry": # From AbstractQueue._retry_status
+ return
+ active_items = ActiveWorkItems.all().filter("queue_name =", queue_status.queue_name).get()
+ if not active_items:
+ return
+ return db.run_in_transaction(self._expire_item, active_items.key(), queue_status.active_patch_id)
+
def post(self):
queue_status = self._queue_status_from_request()
queue_status.put()
+ self._update_active_work_items(queue_status)
Attachment.dirty(queue_status.active_patch_id)
self.response.out.write(queue_status.key().id())
diff --git a/WebKitTools/QueueStatusServer/model/activeworkitems.py b/WebKitTools/QueueStatusServer/model/activeworkitems.py
index e24e6ca..a244c7d 100644
--- a/WebKitTools/QueueStatusServer/model/activeworkitems.py
+++ b/WebKitTools/QueueStatusServer/model/activeworkitems.py
@@ -28,7 +28,7 @@
from google.appengine.ext import db
-from datetime import timedelta
+from datetime import timedelta, datetime
import time
@@ -38,21 +38,41 @@ class ActiveWorkItems(db.Model):
item_dates = db.ListProperty(float)
date = db.DateTimeProperty(auto_now_add=True)
+ # The id/date pairs should probably just be their own class.
+ def _item_time_pairs(self):
+ return zip(self.item_ids, self.item_dates)
+
+ def _set_item_time_pairs(self, pairs):
+ if pairs:
+ # The * operator raises on an empty list.
+ # db.Model does not tuples, we have to make lists.
+ self.item_ids, self.item_dates = map(list, zip(*pairs))
+ else:
+ self.item_ids = []
+ self.item_dates = []
+
+ def _append_item_time_pair(self, pair):
+ self.item_ids.append(pair[0])
+ self.item_dates.append(pair[1])
+
+ def expire_item(self, item_id):
+ nonexpired_pairs = [pair for pair in self._item_time_pairs() if pair[0] != item_id]
+ self._set_item_time_pairs(nonexpired_pairs)
+
def deactivate_expired(self, now):
one_hour_ago = time.mktime((now - timedelta(minutes=60)).timetuple())
- nonexpired_item_ids = []
- nonexpired_item_dates = []
- for i in range(len(self.item_ids)):
- if self.item_dates[i] > one_hour_ago:
- nonexpired_item_ids.append(self.item_ids[i])
- nonexpired_item_dates.append(self.item_dates[i])
- self.item_ids = nonexpired_item_ids
- self.item_dates = nonexpired_item_dates
+ nonexpired_pairs = [pair for pair in self._item_time_pairs() if pair[1] > one_hour_ago]
+ self._set_item_time_pairs(nonexpired_pairs)
def next_item(self, work_item_ids, now):
for item_id in work_item_ids:
if item_id not in self.item_ids:
- self.item_ids.append(item_id)
- self.item_dates.append(time.mktime(now.timetuple()))
+ self._append_item_time_pair([item_id, time.mktime(now.timetuple())])
return item_id
return None
+
+ def time_for_item(self, item_id):
+ for active_item_id, time in self._item_time_pairs():
+ if active_item_id == item_id:
+ return datetime.fromtimestamp(time)
+ return None
diff --git a/WebKitTools/QueueStatusServer/templates/queuestatus.html b/WebKitTools/QueueStatusServer/templates/queuestatus.html
index d2d72c7..1b98952 100644
--- a/WebKitTools/QueueStatusServer/templates/queuestatus.html
+++ b/WebKitTools/QueueStatusServer/templates/queuestatus.html
@@ -42,13 +42,18 @@
<h3>Patches in queue</h3>
<table>
- <tr><th>Position</th><th>Patch</th></tr>
+ <tr><th>Position</th><th>Patch</th><th>Lock Acquired</th></tr>
{% for row in work_item_rows %}
<tr>
<td>#{{ forloop.counter }}</td>
<td>
{{ row.attachment_id|force_escape|webkit_attachment_id|safe }}
</td>
+ <td>
+ {% if row.lock_time %}
+ {{ row.lock_time|timesince }} ago
+ {% endif %}
+ </td>
</tr>
{% endfor %}
</table>
diff --git a/WebKitTools/Scripts/build-webkit b/WebKitTools/Scripts/build-webkit
index cd43499..bc1e8ad 100755
--- a/WebKitTools/Scripts/build-webkit
+++ b/WebKitTools/Scripts/build-webkit
@@ -106,7 +106,7 @@ my @features = (
define => "ENABLE_EVENTSOURCE", default => 1, value => \$eventsourceSupport },
{ option => "filters", desc => "Toggle Filters support",
- define => "ENABLE_FILTERS", default => (isAppleWebKit() || isGtk() || isQt()), value => \$filtersSupport },
+ define => "ENABLE_FILTERS", default => (isAppleWebKit() || isGtk() || isQt() || isEfl()), value => \$filtersSupport },
{ option => "geolocation", desc => "Toggle Geolocation support",
define => "ENABLE_GEOLOCATION", default => (isAppleWebKit() || isGtk()), value => \$geolocationSupport },
@@ -245,13 +245,14 @@ Usage: $programName [options] [options to pass to build system]
--chromium Build the Chromium port on Mac/Win/Linux
--gtk Build the GTK+ port
--qt Build the Qt port
+ --efl Build the EFL port
--inspector-frontend Copy changes to the inspector front-end files to the build directory
--install-headers=<path> Set installation path for the headers (Qt only)
--install-libs=<path> Set installation path for the libraries (Qt only)
--v8 Use V8 as JavaScript engine (Qt only)
- --prefix=<path> Set installation prefix to the given path (Gtk only)
+ --prefix=<path> Set installation prefix to the given path (Gtk/Efl only)
--makeargs=<arguments> Optional Makefile flags
--minimal No optional features, unless explicitly enabled.
@@ -428,6 +429,22 @@ if (isChromium()) {
exit exitStatus($result) if exitStatus($result);
}
+if (isEfl()) {
+ @options = ();
+ @projects = ();
+ foreach (@features) {
+ my $featureName = $_->{define};
+ if ($featureName) {
+ my $featureEnabled = ${$_->{value}} ? "ON" : "OFF";
+ push @options, "-D$featureName=$featureEnabled";
+ }
+ }
+ push @options, "--makeargs=" . $makeArgs if defined($makeArgs);
+ push @options, "--prefix=" . $prefixPath if defined($prefixPath);
+ my $result = buildCMakeEflProject($clean, @options);
+ exit exitStatus($result) if exitStatus($result);
+}
+
# Build, and abort if the build fails.
for my $dir (@projects) {
chdir $dir or die;
diff --git a/WebKitTools/Scripts/old-run-webkit-tests b/WebKitTools/Scripts/old-run-webkit-tests
index 886b4a8..80801dc 100755
--- a/WebKitTools/Scripts/old-run-webkit-tests
+++ b/WebKitTools/Scripts/old-run-webkit-tests
@@ -236,7 +236,7 @@ if (isAppleMacWebKit()) {
}
}
-if (isQt() || isGtk() || isCygwin()) {
+if (isQt() || isCygwin()) {
my $testfontPath = $ENV{"WEBKIT_TESTFONTS"};
if (!$testfontPath || !-d "$testfontPath") {
print "The WEBKIT_TESTFONTS environment variable is not defined or not set properly\n";
@@ -528,6 +528,7 @@ if (!$has3DRendering) {
if (!checkWebCoreFeatureSupport("3D Canvas", 0)) {
$ignoredDirectories{'fast/canvas/webgl'} = 1;
$ignoredDirectories{'compositing/webgl'} = 1;
+ $ignoredDirectories{'http/tests/canvas/webgl'} = 1;
}
if (checkWebCoreFeatureSupport("WML", 0)) {
diff --git a/WebKitTools/Scripts/prepare-ChangeLog b/WebKitTools/Scripts/prepare-ChangeLog
index c2adaf5..608c9ce 100755
--- a/WebKitTools/Scripts/prepare-ChangeLog
+++ b/WebKitTools/Scripts/prepare-ChangeLog
@@ -269,7 +269,7 @@ if ($bugNumber) {
if (`curl --version | grep ^Protocols` !~ /\bhttps\b/) {
print STDERR " Could not get description for bug $bugNumber.\n";
print STDERR " It looks like your version of curl does not support ssl.\n";
- print STDERR " If you are using macports, this can be fixed with sudo port install curl+ssl.\n";
+ print STDERR " If you are using macports, this can be fixed with sudo port install curl +ssl.\n";
} else {
print STDERR " Bug $bugNumber has no bug description. Maybe you set wrong bug ID?\n";
print STDERR " The bug URL: $bugXMLURL\n";
diff --git a/WebKitTools/Scripts/run-chromium-webkit-unit-tests b/WebKitTools/Scripts/run-chromium-webkit-unit-tests
new file mode 100755
index 0000000..62646af
--- /dev/null
+++ b/WebKitTools/Scripts/run-chromium-webkit-unit-tests
@@ -0,0 +1,51 @@
+#!/usr/bin/perl -w
+# 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.
+
+use strict;
+use File::Spec;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+# Allow running this script from any directory.
+my $sourceRootDir = File::Spec->catfile($FindBin::Bin, "../..");
+chdir($sourceRootDir);
+
+setConfiguration();
+
+my $pathToBinary;
+if (isDarwin()) {
+ $pathToBinary = "WebKit/chromium/xcodebuild/" . configuration() . "/webkit_unit_tests";
+} elsif (isCygwin() || isWindows()) {
+ $pathToBinary = "WebKit/chromium/" . configuration() . "/webkit_unit_tests.exe";
+} elsif (isLinux()) {
+ $pathToBinary = "out/" . configuration() . "/webkit_unit_tests";
+}
+
+exit system ($pathToBinary, @ARGV);
diff --git a/WebKitTools/Scripts/test-webkitpy b/WebKitTools/Scripts/test-webkitpy
index e35c6e6..be7e870 100755
--- a/WebKitTools/Scripts/test-webkitpy
+++ b/WebKitTools/Scripts/test-webkitpy
@@ -137,8 +137,9 @@ def _clean_pyc_files(dir_to_clean, paths_not_to_log):
# As a substitute for a unit test, this method tests _clean_pyc_files()
# in addition to calling it. We chose not to use the unittest module
# because _clean_pyc_files() is called only once and is not used elsewhere.
-def _clean_webkitpy_with_test():
+def _clean_packages_with_test(external_package_paths):
webkitpy_dir = os.path.join(os.path.dirname(__file__), "webkitpy")
+ package_paths = [webkitpy_dir] + external_package_paths
# The test .pyc file is--
# webkitpy/python24/TEMP_test-webkitpy_test_pyc_file.pyc.
@@ -156,13 +157,14 @@ def _clean_webkitpy_with_test():
if not os.path.exists(test_path):
raise Exception("Test .pyc file not created: %s" % test_path)
- _clean_pyc_files(webkitpy_dir, [test_path])
+ for path in package_paths:
+ _clean_pyc_files(path, [test_path])
if os.path.exists(test_path):
raise Exception("Test .pyc file not deleted: %s" % test_path)
-def init(command_args):
+def init(command_args, external_package_paths):
"""Execute code prior to importing from webkitpy.unittests.
Args:
@@ -186,8 +188,8 @@ def init(command_args):
configure_logging(is_verbose_logging)
_log.debug("Verbose WebKit logging enabled.")
- # We clean orphaned *.pyc files from webkitpy prior to importing from
- # webkitpy to make sure that no import statements falsely succeed.
+ # We clean orphaned *.pyc files from the packages prior to importing from
+ # them to make sure that no import statements falsely succeed.
# This helps to check that import statements have been updated correctly
# after any file moves. Otherwise, incorrect import statements can
# be masked.
@@ -208,7 +210,7 @@ def init(command_args):
#
# Deleting the orphaned .pyc file prior to importing, however, would
# cause an ImportError to occur on import as desired.
- _clean_webkitpy_with_test()
+ _clean_packages_with_test(external_package_paths)
import webkitpy.python24.versioning as versioning
@@ -227,7 +229,8 @@ def init(command_args):
if __name__ == "__main__":
- init(sys.argv[1:])
+ external_package_paths = [os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'WebKit2', 'Scripts', 'webkit2')]
+ init(sys.argv[1:], external_package_paths)
# We import the unit test code after init() to ensure that any
# Python version warnings are displayed in case an error occurs
@@ -237,4 +240,4 @@ if __name__ == "__main__":
# running the unit tests.
from webkitpy.test.main import Tester
- Tester().run_tests(sys.argv)
+ Tester().run_tests(sys.argv, external_package_paths)
diff --git a/WebKitTools/Scripts/webkitdirs.pm b/WebKitTools/Scripts/webkitdirs.pm
index 2980750..08e14ab 100644
--- a/WebKitTools/Scripts/webkitdirs.pm
+++ b/WebKitTools/Scripts/webkitdirs.pm
@@ -1408,6 +1408,72 @@ sub buildAutotoolsProject($@)
return $result;
}
+sub buildCMakeProject($@)
+{
+ my ($port, $clean, @buildParams) = @_;
+ my $dir = File::Spec->canonpath(baseProductDir());
+ my $config = configuration();
+ my $result;
+ my $makeArgs = "";
+ my @buildArgs;
+
+ $makeArgs .= " -j" . numberOfCPUs() if ($makeArgs !~ m/-j\s*\d+/);
+
+ if ($clean) {
+ print "Cleaning the build directory '$dir'\n";
+ $dir = File::Spec->catfile($dir, $config);
+ File::Path::remove_tree($dir, {keep_root => 1});
+ $result = 0;
+ } else {
+ my $cmakebin = "cmake";
+ my $make = "make";
+
+ push @buildArgs, "-DPORT=$port";
+
+ for my $i (0 .. $#buildParams) {
+ my $opt = $buildParams[$i];
+ if ($opt =~ /^--makeargs=(.*)/i ) {
+ $makeArgs = $1;
+ } elsif ($opt =~ /^--prefix=(.*)/i ) {
+ push @buildArgs, "-DCMAKE_INSTALL_PREFIX=$1";
+ } else {
+ push @buildArgs, $opt;
+ }
+ }
+
+ if ($config =~ m/debug/i) {
+ push @buildArgs, "-DCMAKE_BUILD_TYPE=Debug";
+ } elsif ($config =~ m/release/i) {
+ push @buildArgs, "-DCMAKE_BUILD_TYPE=Release";
+ }
+
+ push @buildArgs, sourceDir();
+
+ $dir = File::Spec->catfile($dir, $config);
+ File::Path::mkpath($dir);
+ chdir $dir or die "Failed to cd into " . $dir . "\n";
+
+ print "Calling '$cmakebin @buildArgs' in " . $dir . "\n\n";
+ my $result = system "$cmakebin @buildArgs";
+ if ($result ne 0) {
+ die "Failed while running $cmakebin to generate makefiles!\n";
+ }
+
+ print "Calling '$make $makeArgs' in " . $dir . "\n\n";
+ $result = system "$make $makeArgs";
+
+ chdir ".." or die;
+ }
+
+ return $result;
+}
+
+sub buildCMakeEflProject($@)
+{
+ my ($clean, @buildArgs) = @_;
+ return buildCMakeProject("Efl", $clean, @buildArgs);
+}
+
sub buildQMakeProject($@)
{
my ($clean, @buildParams) = @_;
@@ -1480,7 +1546,6 @@ sub buildQMakeProject($@)
}
}
- push @buildArgs, sourceDir() . "/WebKit.pro";
if ($config =~ m/debug/i) {
push @buildArgs, "CONFIG-=release";
push @buildArgs, "CONFIG+=debug";
@@ -1495,6 +1560,8 @@ sub buildQMakeProject($@)
}
}
+ push @buildArgs, sourceDir() . "/WebKit.pro";
+
print "Calling '$qmakebin @buildArgs' in " . $dir . "\n\n";
print "Installation headers directory: $installHeaders\n" if(defined($installHeaders));
print "Installation libraries directory: $installLibs\n" if(defined($installLibs));
@@ -1504,6 +1571,16 @@ sub buildQMakeProject($@)
die "Failed to setup build environment using $qmakebin!\n";
}
+ # Manually create makefiles for the examples so we don't build by default
+ my $examplesDir = $dir . "/WebKit/qt/examples";
+ File::Path::mkpath($examplesDir);
+ $buildArgs[-1] = sourceDir() . "/WebKit/qt/examples/examples.pro";
+ chdir $examplesDir or die;
+ print "Calling '$qmakebin @buildArgs' in " . $examplesDir . "\n\n";
+ $result = system "$qmakebin @buildArgs";
+ die "Failed to create makefiles for the examples!\n" if $result ne 0;
+ chdir $dir or die;
+
if ($clean) {
print "Calling '$make $makeargs distclean' in " . $dir . "\n\n";
$result = system "$make $makeargs distclean";
diff --git a/WebKitTools/Scripts/webkitpy/common/config/committers.py b/WebKitTools/Scripts/webkitpy/common/config/committers.py
index 113131f..2d07158 100644
--- a/WebKitTools/Scripts/webkitpy/common/config/committers.py
+++ b/WebKitTools/Scripts/webkitpy/common/config/committers.py
@@ -111,6 +111,7 @@ committers_unable_to_review = [
Committer("Graham Dennis", ["Graham.Dennis@gmail.com", "gdennis@webkit.org"]),
Committer("Greg Bolsinga", "bolsinga@apple.com"),
Committer("Hans Wennborg", "hans@chromium.org", "hwennborg"),
+ Committer("Hayato Ito", "hayato@chromium.org", "hayato"),
Committer("Hin-Chung Lam", ["hclam@google.com", "hclam@chromium.org"]),
Committer("Ilya Tikhonovsky", "loislo@chromium.org", "loislo"),
Committer("Jakob Petsovits", ["jpetsovits@rim.com", "jpetso@gmx.at"], "jpetso"),
@@ -136,6 +137,7 @@ committers_unable_to_review = [
Committer("Kent Hansen", "kent.hansen@nokia.com", "khansen"),
Committer("Kinuko Yasuda", "kinuko@chromium.org", "kinuko"),
Committer("Krzysztof Kowalczyk", "kkowalczyk@gmail.com"),
+ Committer("Kwang Yul Seo", ["kwangyul.seo@gmail.com", "skyul@company100.net", "kseo@webkit.org"], "kwangseo"),
Committer("Leandro Pereira", ["leandro@profusion.mobi", "leandro@webkit.org"], "acidx"),
Committer("Levi Weintraub", "lweintraub@apple.com"),
Committer("Lucas De Marchi", ["lucas.demarchi@profusion.mobi", "demarchi@webkit.org"], "demarchi"),
@@ -158,6 +160,7 @@ committers_unable_to_review = [
Committer("Noam Rosenthal", "noam.rosenthal@nokia.com", "noamr"),
Committer("Pam Greene", "pam@chromium.org", "pamg"),
Committer("Patrick Gansterer", ["paroga@paroga.com", "paroga@webkit.org"], "paroga"),
+ Committer("Pavel Podivilov", "podivilov@chromium.org", "podivilov"),
Committer("Peter Kasting", ["pkasting@google.com", "pkasting@chromium.org"], "pkasting"),
Committer("Philippe Normand", ["pnormand@igalia.com", "philn@webkit.org"], "philn-tp"),
Committer("Pierre d'Herbemont", ["pdherbemont@free.fr", "pdherbemont@apple.com"], "pdherbemont"),
diff --git a/WebKitTools/Scripts/webkitpy/common/net/buildbot.py b/WebKitTools/Scripts/webkitpy/common/net/buildbot.py
index 593ebc1..17f6c7a 100644
--- a/WebKitTools/Scripts/webkitpy/common/net/buildbot.py
+++ b/WebKitTools/Scripts/webkitpy/common/net/buildbot.py
@@ -34,6 +34,8 @@ import urllib
import urllib2
import xmlrpclib
+from webkitpy.common.net.failuremap import FailureMap
+from webkitpy.common.net.regressionwindow import RegressionWindow
from webkitpy.common.system.logutils import get_logger
from webkitpy.thirdparty.autoinstalled.mechanize import Browser
from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup
@@ -145,9 +147,9 @@ class Builder(object):
)
return build
- def find_failure_transition(self, red_build, look_back_limit=30):
+ def find_regression_window(self, red_build, look_back_limit=30):
if not red_build or red_build.is_green():
- return (None, None)
+ return RegressionWindow(None, None)
common_failures = None
current_build = red_build
build_after_current_build = None
@@ -172,34 +174,25 @@ class Builder(object):
break
look_back_count += 1
if look_back_count > look_back_limit:
- return (None, current_build)
+ return RegressionWindow(None, current_build, common_failures=common_failures)
build_after_current_build = current_build
current_build = current_build.previous_build()
# We must iterate at least once because red_build is red.
assert(build_after_current_build)
# Current build must either be green or have no failures in common
# with red build, so we've found our failure transition.
- return (current_build, build_after_current_build)
+ return RegressionWindow(current_build, build_after_current_build, common_failures=common_failures)
- # FIXME: This likely does not belong on Builder
- def suspect_revisions_for_transition(self, last_good_build, first_bad_build):
- suspect_revisions = range(first_bad_build.revision(),
- last_good_build.revision(),
- -1)
- suspect_revisions.reverse()
- return suspect_revisions
-
- def blameworthy_revisions(self, red_build_number, look_back_limit=30, avoid_flakey_tests=True):
+ def find_blameworthy_regression_window(self, red_build_number, look_back_limit=30, avoid_flakey_tests=True):
red_build = self.build(red_build_number)
- (last_good_build, first_bad_build) = \
- self.find_failure_transition(red_build, look_back_limit)
- if not last_good_build:
- return [] # We ran off the limit of our search
+ regression_window = self.find_regression_window(red_build, look_back_limit)
+ if not regression_window.build_before_failure():
+ return None # We ran off the limit of our search
# If avoid_flakey_tests, require at least 2 bad builds before we
# suspect a real failure transition.
- if avoid_flakey_tests and first_bad_build == red_build:
- return []
- return self.suspect_revisions_for_transition(last_good_build, first_bad_build)
+ if avoid_flakey_tests and regression_window.failing_build() == red_build:
+ return None
+ return regression_window
# FIXME: This should be unified with all the layout test results code in the layout_tests package
@@ -414,20 +407,27 @@ class BuildBot(object):
build_status_url = "http://%s/one_box_per_builder" % self.buildbot_host
return urllib2.urlopen(build_status_url)
+ def _file_cell_text(self, file_cell):
+ """Traverses down through firstChild elements until one containing a string is found, then returns that string"""
+ element = file_cell
+ while element.string is None and element.contents:
+ element = element.contents[0]
+ return element.string
+
def _parse_twisted_file_row(self, file_row):
- string_or_empty = lambda soup: unicode(soup.string) if soup.string else u""
+ string_or_empty = lambda string: unicode(string) if string else u""
file_cells = file_row.findAll('td')
return {
- "filename": string_or_empty(file_cells[0].find("a")),
- "size": string_or_empty(file_cells[1]),
- "type": string_or_empty(file_cells[2]),
- "encoding": string_or_empty(file_cells[3]),
+ "filename": string_or_empty(self._file_cell_text(file_cells[0])),
+ "size": string_or_empty(self._file_cell_text(file_cells[1])),
+ "type": string_or_empty(self._file_cell_text(file_cells[2])),
+ "encoding": string_or_empty(self._file_cell_text(file_cells[3])),
}
def _parse_twisted_directory_listing(self, page):
soup = BeautifulSoup(page)
# HACK: Match only table rows with a class to ignore twisted header/footer rows.
- file_rows = soup.find('table').findAll('tr', { "class" : True })
+ file_rows = soup.find('table').findAll('tr', {'class': re.compile(r'\b(?:directory|file)\b')})
return [self._parse_twisted_file_row(file_row) for file_row in file_rows]
# FIXME: There should be a better way to get this information directly from twisted.
@@ -452,19 +452,17 @@ class BuildBot(object):
self._builder_by_name[name] = builder
return builder
- def revisions_causing_failures(self, only_core_builders=True):
+ def failure_map(self, only_core_builders=True):
builder_statuses = self.core_builder_statuses() if only_core_builders else self.builder_statuses()
+ failure_map = FailureMap()
revision_to_failing_bots = {}
for builder_status in builder_statuses:
if builder_status["is_green"]:
continue
builder = self.builder_with_name(builder_status["name"])
- revisions = builder.blameworthy_revisions(builder_status["build_number"])
- for revision in revisions:
- failing_bots = revision_to_failing_bots.get(revision, [])
- failing_bots.append(builder)
- revision_to_failing_bots[revision] = failing_bots
- return revision_to_failing_bots
+ regression_window = builder.find_blameworthy_regression_window(builder_status["build_number"])
+ failure_map.add_regression_window(builder, regression_window)
+ return failure_map
# This makes fewer requests than calling Builder.latest_build would. It grabs all builder
# statuses in one request using self.builder_statuses (fetching /one_box_per_builder instead of builder pages).
diff --git a/WebKitTools/Scripts/webkitpy/common/net/buildbot_unittest.py b/WebKitTools/Scripts/webkitpy/common/net/buildbot_unittest.py
index b48f0e4..c99ab32 100644
--- a/WebKitTools/Scripts/webkitpy/common/net/buildbot_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/common/net/buildbot_unittest.py
@@ -54,53 +54,53 @@ class BuilderTest(unittest.TestCase):
self.builder = Builder(u"Test Builder \u2661", self.buildbot)
self._install_fetch_build(lambda build_number: ["test1", "test2"])
- def test_find_failure_transition(self):
- (green_build, red_build) = self.builder.find_failure_transition(self.builder.build(10))
- self.assertEqual(green_build.revision(), 1003)
- self.assertEqual(red_build.revision(), 1004)
+ def test_find_regression_window(self):
+ regression_window = self.builder.find_regression_window(self.builder.build(10))
+ self.assertEqual(regression_window.build_before_failure().revision(), 1003)
+ self.assertEqual(regression_window.failing_build().revision(), 1004)
- (green_build, red_build) = self.builder.find_failure_transition(self.builder.build(10), look_back_limit=2)
- self.assertEqual(green_build, None)
- self.assertEqual(red_build.revision(), 1008)
+ regression_window = self.builder.find_regression_window(self.builder.build(10), look_back_limit=2)
+ self.assertEqual(regression_window.build_before_failure(), None)
+ self.assertEqual(regression_window.failing_build().revision(), 1008)
def test_none_build(self):
self.builder._fetch_build = lambda build_number: None
- (green_build, red_build) = self.builder.find_failure_transition(self.builder.build(10))
- self.assertEqual(green_build, None)
- self.assertEqual(red_build, None)
+ regression_window = self.builder.find_regression_window(self.builder.build(10))
+ self.assertEqual(regression_window.build_before_failure(), None)
+ self.assertEqual(regression_window.failing_build(), None)
def test_flaky_tests(self):
self._install_fetch_build(lambda build_number: ["test1"] if build_number % 2 else ["test2"])
- (green_build, red_build) = self.builder.find_failure_transition(self.builder.build(10))
- self.assertEqual(green_build.revision(), 1009)
- self.assertEqual(red_build.revision(), 1010)
+ regression_window = self.builder.find_regression_window(self.builder.build(10))
+ self.assertEqual(regression_window.build_before_failure().revision(), 1009)
+ self.assertEqual(regression_window.failing_build().revision(), 1010)
def test_failure_and_flaky(self):
self._install_fetch_build(lambda build_number: ["test1", "test2"] if build_number % 2 else ["test2"])
- (green_build, red_build) = self.builder.find_failure_transition(self.builder.build(10))
- self.assertEqual(green_build.revision(), 1003)
- self.assertEqual(red_build.revision(), 1004)
+ regression_window = self.builder.find_regression_window(self.builder.build(10))
+ self.assertEqual(regression_window.build_before_failure().revision(), 1003)
+ self.assertEqual(regression_window.failing_build().revision(), 1004)
def test_no_results(self):
self._install_fetch_build(lambda build_number: ["test1", "test2"] if build_number % 2 else ["test2"])
- (green_build, red_build) = self.builder.find_failure_transition(self.builder.build(10))
- self.assertEqual(green_build.revision(), 1003)
- self.assertEqual(red_build.revision(), 1004)
+ regression_window = self.builder.find_regression_window(self.builder.build(10))
+ self.assertEqual(regression_window.build_before_failure().revision(), 1003)
+ self.assertEqual(regression_window.failing_build().revision(), 1004)
def test_failure_after_flaky(self):
self._install_fetch_build(lambda build_number: ["test1", "test2"] if build_number > 6 else ["test3"])
- (green_build, red_build) = self.builder.find_failure_transition(self.builder.build(10))
- self.assertEqual(green_build.revision(), 1006)
- self.assertEqual(red_build.revision(), 1007)
+ regression_window = self.builder.find_regression_window(self.builder.build(10))
+ self.assertEqual(regression_window.build_before_failure().revision(), 1006)
+ self.assertEqual(regression_window.failing_build().revision(), 1007)
- def test_blameworthy_revisions(self):
- self.assertEqual(self.builder.blameworthy_revisions(10), [1004])
- self.assertEqual(self.builder.blameworthy_revisions(10, look_back_limit=2), [])
+ def test_find_blameworthy_regression_window(self):
+ self.assertEqual(self.builder.find_blameworthy_regression_window(10).revisions(), [1004])
+ self.assertEqual(self.builder.find_blameworthy_regression_window(10, look_back_limit=2), None)
# Flakey test avoidance requires at least 2 red builds:
- self.assertEqual(self.builder.blameworthy_revisions(4), [])
- self.assertEqual(self.builder.blameworthy_revisions(4, avoid_flakey_tests=False), [1004])
+ self.assertEqual(self.builder.find_blameworthy_regression_window(4), None)
+ self.assertEqual(self.builder.find_blameworthy_regression_window(4, avoid_flakey_tests=False).revisions(), [1004])
# Green builder:
- self.assertEqual(self.builder.blameworthy_revisions(3), [])
+ self.assertEqual(self.builder.find_blameworthy_regression_window(3), None)
def test_build_caching(self):
self.assertEqual(self.builder.build(10), self.builder.build(10))
@@ -361,22 +361,19 @@ class BuildBotTest(unittest.TestCase):
<h1>Directory listing for /results/SnowLeopard Intel Leaks/</h1>
<table>
- <thead>
- <tr>
+ <tr class="alt">
<th>Filename</th>
<th>Size</th>
<th>Content type</th>
<th>Content encoding</th>
</tr>
- </thead>
- <tbody>
-<tr class="odd">
- <td><a href="r47483%20%281%29/">r47483 (1)/</a></td>
- <td></td>
- <td>[Directory]</td>
- <td></td>
+<tr class="directory ">
+ <td><a href="r47483%20%281%29/"><b>r47483 (1)/</b></a></td>
+ <td><b></b></td>
+ <td><b>[Directory]</b></td>
+ <td><b></b></td>
</tr>
-<tr class="odd">
+<tr class="file alt">
<td><a href="r47484%20%282%29.zip">r47484 (2).zip</a></td>
<td>89K</td>
<td>[application/zip]</td>
diff --git a/WebKitTools/Scripts/webkitpy/common/net/credentials.py b/WebKitTools/Scripts/webkitpy/common/net/credentials.py
index 1d5f83d..1c3e6c0 100644
--- a/WebKitTools/Scripts/webkitpy/common/net/credentials.py
+++ b/WebKitTools/Scripts/webkitpy/common/net/credentials.py
@@ -39,14 +39,23 @@ from webkitpy.common.system.executive import Executive, ScriptError
from webkitpy.common.system.user import User
from webkitpy.common.system.deprecated_logging import log
+try:
+ # Use keyring, a cross platform keyring interface, as a fallback:
+ # http://pypi.python.org/pypi/keyring
+ import keyring
+except ImportError:
+ keyring = None
+
class Credentials(object):
- def __init__(self, host, git_prefix=None, executive=None, cwd=os.getcwd()):
+ def __init__(self, host, git_prefix=None, executive=None, cwd=os.getcwd(),
+ keyring=keyring):
self.host = host
self.git_prefix = "%s." % git_prefix if git_prefix else ""
self.executive = executive or Executive()
self.cwd = cwd
+ self._keyring = keyring
def _credentials_from_git(self):
return [Git.read_git_config(self.git_prefix + "username"),
@@ -117,10 +126,19 @@ class Credentials(object):
if not username or not password:
(username, password) = self._credentials_from_keychain(username)
+ if username and not password and self._keyring:
+ password = self._keyring.get_password(self.host, username)
+
if not username:
username = User.prompt("%s login: " % self.host)
if not password:
password = getpass.getpass("%s password for %s: " % (self.host,
username))
+ if self._keyring:
+ store_password = User().confirm(
+ "Store password in system keyring?", User.DEFAULT_NO)
+ if store_password:
+ self._keyring.set_password(self.host, username, password)
+
return [username, password]
diff --git a/WebKitTools/Scripts/webkitpy/common/net/credentials_unittest.py b/WebKitTools/Scripts/webkitpy/common/net/credentials_unittest.py
index 9a42bdd..d30291b 100644
--- a/WebKitTools/Scripts/webkitpy/common/net/credentials_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/common/net/credentials_unittest.py
@@ -113,5 +113,28 @@ password: "SECRETSAUCE"
self.assertEqual(credentials.read_credentials(), ["test@webkit.org", "SECRETSAUCE"])
os.rmdir(temp_dir_path)
+ def test_keyring_without_git_repo(self):
+ class MockKeyring(object):
+ def get_password(self, host, username):
+ return "NOMNOMNOM"
+
+ class FakeCredentials(Credentials):
+ def __init__(self, cwd):
+ Credentials.__init__(self, "fake.hostname", cwd=cwd,
+ keyring=MockKeyring())
+
+ def _is_mac_os_x(self):
+ return True
+
+ def _credentials_from_keychain(self, username):
+ return ("test@webkit.org", None)
+
+ temp_dir_path = tempfile.mkdtemp(suffix="not_a_git_repo")
+ credentials = FakeCredentials(temp_dir_path)
+ try:
+ self.assertEqual(credentials.read_credentials(), ["test@webkit.org", "NOMNOMNOM"])
+ finally:
+ os.rmdir(temp_dir_path)
+
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/common/net/failuremap.py b/WebKitTools/Scripts/webkitpy/common/net/failuremap.py
new file mode 100644
index 0000000..98e4b8f
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/common/net/failuremap.py
@@ -0,0 +1,48 @@
+# 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.
+
+
+class FailureMap(object):
+ def __init__(self):
+ self._failures = []
+
+ def add_regression_window(self, builder, regression_window):
+ self._failures.append({
+ 'builder': builder,
+ 'regression_window': regression_window,
+ })
+
+ def revisions_causing_failures(self):
+ revision_to_failing_bots = {}
+ for failure_info in self._failures:
+ revisions = failure_info['regression_window'].revisions()
+ for revision in revisions:
+ failing_bots = revision_to_failing_bots.get(revision, [])
+ failing_bots.append(failure_info['builder'])
+ revision_to_failing_bots[revision] = failing_bots
+ return revision_to_failing_bots
diff --git a/WebKitTools/Scripts/webkitpy/common/net/regressionwindow.py b/WebKitTools/Scripts/webkitpy/common/net/regressionwindow.py
new file mode 100644
index 0000000..231459f
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/common/net/regressionwindow.py
@@ -0,0 +1,48 @@
+# 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.
+
+
+class RegressionWindow(object):
+ def __init__(self, build_before_failure, failing_build, common_failures=None):
+ self._build_before_failure = build_before_failure
+ self._failing_build = failing_build
+ self._common_failures = common_failures
+
+ def build_before_failure(self):
+ return self._build_before_failure
+
+ def failing_build(self):
+ return self._failing_build
+
+ def common_failures(self):
+ return self._common_failures
+
+ def revisions(self):
+ revisions = range(self._failing_build.revision(), self._build_before_failure.revision(), -1)
+ revisions.reverse()
+ return revisions
diff --git a/WebKitTools/Scripts/webkitpy/common/system/user.py b/WebKitTools/Scripts/webkitpy/common/system/user.py
index 9444c00..240b67b 100644
--- a/WebKitTools/Scripts/webkitpy/common/system/user.py
+++ b/WebKitTools/Scripts/webkitpy/common/system/user.py
@@ -28,6 +28,7 @@
import logging
import os
+import re
import shlex
import subprocess
import sys
@@ -51,6 +52,9 @@ except ImportError:
class User(object):
+ DEFAULT_NO = 'n'
+ DEFAULT_YES = 'y'
+
# FIXME: These are @classmethods because bugzilla.py doesn't have a Tool object (thus no User instance).
@classmethod
def prompt(cls, message, repeat=1, raw_input=raw_input):
@@ -61,14 +65,30 @@ class User(object):
return response
@classmethod
- def prompt_with_list(cls, list_title, list_items):
+ def prompt_with_list(cls, list_title, list_items, can_choose_multiple=False, raw_input=raw_input):
print list_title
i = 0
for item in list_items:
i += 1
print "%2d. %s" % (i, item)
- result = int(cls.prompt("Enter a number: ")) - 1
- return list_items[result]
+
+ # Loop until we get valid input
+ while True:
+ if can_choose_multiple:
+ response = cls.prompt("Enter one or more numbers (comma-separated), or \"all\": ", raw_input=raw_input)
+ if not response.strip() or response == "all":
+ return list_items
+ try:
+ indices = [int(r) - 1 for r in re.split("\s*,\s*", response)]
+ except ValueError, err:
+ continue
+ return [list_items[i] for i in indices]
+ else:
+ try:
+ result = int(cls.prompt("Enter a number: ", raw_input=raw_input)) - 1
+ except ValueError, err:
+ continue
+ return list_items[result]
def edit(self, files):
editor = os.environ.get("EDITOR") or "vi"
@@ -98,11 +118,14 @@ class User(object):
except IOError, e:
pass
- def confirm(self, message=None):
+ def confirm(self, message=None, default=DEFAULT_YES, raw_input=raw_input):
if not message:
message = "Continue?"
- response = raw_input("%s [Y/n]: " % message)
- return not response or response.lower() == "y"
+ choice = {'y': 'Y/n', 'n': 'y/N'}[default]
+ response = raw_input("%s [%s]: " % (message, choice))
+ if not response:
+ response = default
+ return response.lower() == 'y'
def can_open_url(self):
try:
diff --git a/WebKitTools/Scripts/webkitpy/common/system/user_unittest.py b/WebKitTools/Scripts/webkitpy/common/system/user_unittest.py
index dadead3..ae1bad5 100644
--- a/WebKitTools/Scripts/webkitpy/common/system/user_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/common/system/user_unittest.py
@@ -28,6 +28,7 @@
import unittest
+from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.common.system.user import User
class UserTest(unittest.TestCase):
@@ -50,5 +51,51 @@ class UserTest(unittest.TestCase):
return None
self.assertEqual(User.prompt("input", repeat=self.repeatsRemaining, raw_input=mock_raw_input), None)
+ def test_prompt_with_list(self):
+ def run_prompt_test(inputs, expected_result, can_choose_multiple=False):
+ def mock_raw_input(message):
+ return inputs.pop(0)
+ output_capture = OutputCapture()
+ actual_result = output_capture.assert_outputs(
+ self,
+ User.prompt_with_list,
+ args=["title", ["foo", "bar"]],
+ kwargs={"can_choose_multiple": can_choose_multiple, "raw_input": mock_raw_input},
+ expected_stdout="title\n 1. foo\n 2. bar\n")
+ self.assertEqual(actual_result, expected_result)
+ self.assertEqual(len(inputs), 0)
+
+ run_prompt_test(["1"], "foo")
+ run_prompt_test(["badinput", "2"], "bar")
+
+ run_prompt_test(["1,2"], ["foo", "bar"], can_choose_multiple=True)
+ run_prompt_test([" 1, 2 "], ["foo", "bar"], can_choose_multiple=True)
+ run_prompt_test(["all"], ["foo", "bar"], can_choose_multiple=True)
+ run_prompt_test([""], ["foo", "bar"], can_choose_multiple=True)
+ run_prompt_test([" "], ["foo", "bar"], can_choose_multiple=True)
+ run_prompt_test(["badinput", "all"], ["foo", "bar"], can_choose_multiple=True)
+
+ def test_confirm(self):
+ test_cases = (
+ (("Continue? [Y/n]: ", True), (User.DEFAULT_YES, 'y')),
+ (("Continue? [Y/n]: ", False), (User.DEFAULT_YES, 'n')),
+ (("Continue? [Y/n]: ", True), (User.DEFAULT_YES, '')),
+ (("Continue? [Y/n]: ", False), (User.DEFAULT_YES, 'q')),
+ (("Continue? [y/N]: ", True), (User.DEFAULT_NO, 'y')),
+ (("Continue? [y/N]: ", False), (User.DEFAULT_NO, 'n')),
+ (("Continue? [y/N]: ", False), (User.DEFAULT_NO, '')),
+ (("Continue? [y/N]: ", False), (User.DEFAULT_NO, 'q')),
+ )
+ for test_case in test_cases:
+ expected, inputs = test_case
+
+ def mock_raw_input(message):
+ self.assertEquals(expected[0], message)
+ return inputs[1]
+
+ result = User().confirm(default=inputs[0],
+ raw_input=mock_raw_input)
+ self.assertEquals(expected[1], result)
+
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.checksum b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.checksum
deleted file mode 100644
index 5890112..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.checksum
+++ /dev/null
@@ -1 +0,0 @@
-checksum-checksum
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.png
deleted file mode 100644
index 83a5de3..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.png
+++ /dev/null
@@ -1 +0,0 @@
-checksum-png
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.txt
deleted file mode 100644
index 5628d69..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-checksum-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum.html
deleted file mode 100644
index 2b78d31..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/checksum.html
+++ /dev/null
@@ -1 +0,0 @@
-image_checksum
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/crash.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/crash.html
deleted file mode 100644
index 0bc3798..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/crash.html
+++ /dev/null
@@ -1 +0,0 @@
-crash
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/exception.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/exception.html
deleted file mode 100644
index 38c54e3..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/exception.html
+++ /dev/null
@@ -1 +0,0 @@
-exception
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/hang.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/hang.html
deleted file mode 100644
index 4e0de08..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/hang.html
+++ /dev/null
@@ -1 +0,0 @@
-timeout-thread
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.checksum b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.checksum
deleted file mode 100644
index 24b887a..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.checksum
+++ /dev/null
@@ -1 +0,0 @@
-image-checksum
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.png
deleted file mode 100644
index 4c23996..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.png
+++ /dev/null
@@ -1 +0,0 @@
-image-png
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.txt
deleted file mode 100644
index c6ee718..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-image-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image.html
deleted file mode 100644
index 53e4b27..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image.html
+++ /dev/null
@@ -1 +0,0 @@
-image_failure
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.checksum b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.checksum
deleted file mode 100644
index 8fa0851..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.checksum
+++ /dev/null
@@ -1 +0,0 @@
-image_checksum-checksum
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.png
deleted file mode 100644
index d677d2e..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.png
+++ /dev/null
@@ -1 +0,0 @@
-image_checksum-png
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.txt
deleted file mode 100644
index 453f213..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-image_checksum-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum.html
deleted file mode 100644
index 2b78d31..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/image_checksum.html
+++ /dev/null
@@ -1 +0,0 @@
-image_checksum
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/keyboard.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/keyboard.html
deleted file mode 100644
index c253983..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/keyboard.html
+++ /dev/null
@@ -1 +0,0 @@
-keyboard
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check-expected.png
deleted file mode 100644
index e45c7af..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check-expected.png
+++ /dev/null
@@ -1 +0,0 @@
-missing_check-png
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check-expected.txt
deleted file mode 100644
index 0ea9227..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-missing_check-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check.html
deleted file mode 100644
index 0af8000..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_check.html
+++ /dev/null
@@ -1 +0,0 @@
-missing_image
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_image.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_image.html
deleted file mode 100644
index 0af8000..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_image.html
+++ /dev/null
@@ -1 +0,0 @@
-missing_image
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_text.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_text.html
deleted file mode 100644
index 47b8ad6..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/missing_text.html
+++ /dev/null
@@ -1 +0,0 @@
-missing_text
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/text-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/text-expected.txt
deleted file mode 100644
index e21ea45..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/text-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-text_failures-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/text.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/text.html
deleted file mode 100644
index 91f5fc7..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/text.html
+++ /dev/null
@@ -1 +0,0 @@
-text_failure
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/timeout.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/timeout.html
deleted file mode 100644
index 790851a..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/timeout.html
+++ /dev/null
@@ -1 +0,0 @@
-timeout
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.checksum b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.checksum
deleted file mode 100644
index 0c4f6da..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.checksum
+++ /dev/null
@@ -1 +0,0 @@
-fail_checksum
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.png
deleted file mode 100644
index db483ee..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.png
+++ /dev/null
@@ -1 +0,0 @@
-fail_png
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.txt
deleted file mode 100644
index a1f3c24..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-fail_output
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum.html
deleted file mode 100644
index b325924..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/unexpected/text-image-checksum.html
+++ /dev/null
@@ -1 +0,0 @@
-Google
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text-expected.txt
deleted file mode 100644
index 2b38a06..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-text-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text.html
deleted file mode 100644
index 8e27be7..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text.html
+++ /dev/null
@@ -1 +0,0 @@
-text
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text-expected.txt
deleted file mode 100644
index 2b38a06..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-text-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text.html
deleted file mode 100644
index 8e27be7..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text.html
+++ /dev/null
@@ -1 +0,0 @@
-text
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/error-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/error-expected.txt
deleted file mode 100644
index 9427269..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/error-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-error-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/error.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/error.html
deleted file mode 100644
index 8276753..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/error.html
+++ /dev/null
@@ -1 +0,0 @@
-error
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.checksum b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.checksum
deleted file mode 100644
index 24b887a..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.checksum
+++ /dev/null
@@ -1 +0,0 @@
-image-checksum
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.png
deleted file mode 100644
index 4c23996..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.png
+++ /dev/null
@@ -1 +0,0 @@
-image-png
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.txt
deleted file mode 100644
index c6ee718..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-image-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image.html
deleted file mode 100644
index 773b222..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/image.html
+++ /dev/null
@@ -1 +0,0 @@
-image
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.checksum b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.checksum
deleted file mode 100644
index 52038ae..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.checksum
+++ /dev/null
@@ -1 +0,0 @@
-platform_image-generic-checksum
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.png
deleted file mode 100644
index 087872b..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.png
+++ /dev/null
@@ -1 +0,0 @@
-platform_image-generic-png
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.txt
deleted file mode 100644
index f71680c..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-platform_image-generic-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image.html
deleted file mode 100644
index ca48a7b..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/platform_image.html
+++ /dev/null
@@ -1 +0,0 @@
-platform_image
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text-expected.txt
deleted file mode 100644
index 2b38a06..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-text-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text.html
deleted file mode 100644
index 8e27be7..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text.html
+++ /dev/null
@@ -1 +0,0 @@
-text
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.checksum b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.checksum
deleted file mode 100644
index ea557cf..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.checksum
+++ /dev/null
@@ -1 +0,0 @@
-platform_image-checksum
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.png
deleted file mode 100644
index ec42fc1..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.png
+++ /dev/null
@@ -1 +0,0 @@
-platform_image-png
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.txt
deleted file mode 100644
index ff8bf43..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/passes/platform_image-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-platform_image-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt
deleted file mode 100644
index 0619fde..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-WONTFIX : failures/expected/checksum.html = IMAGE
-WONTFIX : failures/expected/crash.html = CRASH
-// This one actually passes because the checksums will match.
-WONTFIX : failures/expected/image.html = PASS
-WONTFIX : failures/expected/image_checksum.html = IMAGE
-WONTFIX : failures/expected/missing_check.html = MISSING PASS
-WONTFIX : failures/expected/missing_image.html = MISSING PASS
-WONTFIX : failures/expected/missing_text.html = MISSING PASS
-WONTFIX : failures/expected/text.html = TEXT
-WONTFIX : failures/expected/timeout.html = TIMEOUT
-WONTFIX SKIP : failures/expected/hang.html = TIMEOUT
-WONTFIX SKIP : failures/expected/keyboard.html = CRASH
-WONTFIX SKIP : failures/expected/exception.html = CRASH
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/resources/README.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/resources/README.txt
deleted file mode 100644
index b806b06..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/resources/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory exists solely to make sure that when we gather the lists of
-tests, we skip over directories named 'resources'.
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text-expected.txt
deleted file mode 100644
index 2b38a06..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-text-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text.html
deleted file mode 100644
index 8e27be7..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text.html
+++ /dev/null
@@ -1 +0,0 @@
-text
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py
index d420631..00ff211 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing.py
@@ -351,11 +351,20 @@ class Printer(object):
filename = result.filename
test_name = self._port.relative_test_filename(filename)
self._write('trace: %s' % test_name)
- self._write(' txt: %s' %
- self._port.relative_test_filename(
- self._port.expected_filename(filename, '.txt')))
+ txt_file = self._port.expected_filename(filename, '.txt')
+ if self._port.path_exists(txt_file):
+ self._write(' txt: %s' %
+ self._port.relative_test_filename(txt_file))
+ else:
+ self._write(' txt: <none>')
+ checksum_file = self._port.expected_filename(filename, '.checksum')
+ if self._port.path_exists(checksum_file):
+ self._write(' sum: %s' %
+ self._port.relative_test_filename(checksum_file))
+ else:
+ self._write(' sum: <none>')
png_file = self._port.expected_filename(filename, '.png')
- if os.path.exists(png_file):
+ if self._port.path_exists(png_file):
self._write(' png: %s' %
self._port.relative_test_filename(png_file))
else:
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py
index 29139d0..0344aa7 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py
@@ -151,7 +151,7 @@ class Testprinter(unittest.TestCase):
expectations = test_expectations.TestExpectations(
self._port, test_paths, expectations_str,
self._port.test_platform_name(), is_debug_mode=False,
- is_lint_mode=False, tests_are_present=False)
+ is_lint_mode=False)
rs = run_webkit_tests.ResultSummary(expectations, test_paths)
return test_paths, rs, expectations
@@ -318,6 +318,16 @@ class Testprinter(unittest.TestCase):
self.assertFalse(err.empty())
printer, err, out = self.get_printer(['--print', 'trace-everything'])
+ result = self.get_result('passes/image.html')
+ printer.print_test_result(result, expected=True, exp_str='',
+ got_str='')
+ result = self.get_result('failures/expected/missing_text.html')
+ printer.print_test_result(result, expected=True, exp_str='',
+ got_str='')
+ result = self.get_result('failures/expected/missing_check.html')
+ printer.print_test_result(result, expected=True, exp_str='',
+ got_str='')
+ result = self.get_result('failures/expected/missing_image.html')
printer.print_test_result(result, expected=True, exp_str='',
got_str='')
self.assertFalse(err.empty())
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
index 3d8349b..508a6ad 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
@@ -87,8 +87,7 @@ class TestExpectations:
TEST_LIST = "test_expectations.txt"
def __init__(self, port, tests, expectations, test_platform_name,
- is_debug_mode, is_lint_mode, tests_are_present=True,
- overrides=None):
+ is_debug_mode, is_lint_mode, overrides=None):
"""Loads and parses the test expectations given in the string.
Args:
port: handle to object containing platform-specific functionality
@@ -101,10 +100,6 @@ class TestExpectations:
in the expectations
is_lint_mode: If True, just parse the expectations string
looking for errors.
- tests_are_present: whether the test files exist in the file
- system and can be probed for. This is useful for distinguishing
- test files from directories, and is needed by the LTTF
- dashboard, where the files aren't actually locally present.
overrides: test expectations that are allowed to override any
entries in |expectations|. This is used by callers
that need to manage two sets of expectations (e.g., upstream
@@ -112,7 +107,7 @@ class TestExpectations:
"""
self._expected_failures = TestExpectationsFile(port, expectations,
tests, test_platform_name, is_debug_mode, is_lint_mode,
- tests_are_present=tests_are_present, overrides=overrides)
+ overrides=overrides)
# TODO(ojan): Allow for removing skipped tests when getting the list of
# tests to run, but not when getting metrics.
@@ -302,8 +297,7 @@ class TestExpectationsFile:
'flaky': FLAKY}
def __init__(self, port, expectations, full_test_list, test_platform_name,
- is_debug_mode, is_lint_mode, suppress_errors=False,
- tests_are_present=True, overrides=None):
+ is_debug_mode, is_lint_mode, suppress_errors=False, overrides=None):
"""
expectations: Contents of the expectations file
full_test_list: The list of all tests to be run pending processing of
@@ -314,9 +308,6 @@ class TestExpectationsFile:
is_debug_mode: Whether we testing a test_shell built debug mode.
is_lint_mode: Whether this is just linting test_expecatations.txt.
suppress_errors: Whether to suppress lint errors.
- tests_are_present: Whether the test files are present in the local
- filesystem. The LTTF Dashboard uses False here to avoid having to
- keep a local copy of the tree.
overrides: test expectations that are allowed to override any
entries in |expectations|. This is used by callers
that need to manage two sets of expectations (e.g., upstream
@@ -329,7 +320,6 @@ class TestExpectationsFile:
self._test_platform_name = test_platform_name
self._is_debug_mode = is_debug_mode
self._is_lint_mode = is_lint_mode
- self._tests_are_present = tests_are_present
self._overrides = overrides
self._suppress_errors = suppress_errors
self._errors = []
@@ -462,7 +452,7 @@ class TestExpectationsFile:
def remove_platform_from_expectations(self, tests, platform):
"""Returns a copy of the expectations with the tests matching the
- platform remove.
+ platform removed.
If a test is in the test list and has an option that matches the given
platform, remove the matching platform and save the updated test back
@@ -699,8 +689,8 @@ class TestExpectationsFile:
# WebKit's way of skipping tests is to add a -disabled suffix.
# So we should consider the path existing if the path or the
# -disabled version exists.
- if (self._tests_are_present and not os.path.exists(full_path)
- and not os.path.exists(full_path + '-disabled')):
+ if (not self._port.path_exists(full_path)
+ and not self._port.path_exists(full_path + '-disabled')):
# Log a non fatal error here since you hit this case any
# time you update test_expectations.txt without syncing
# the LayoutTests directory
@@ -735,7 +725,8 @@ class TestExpectationsFile:
path and make sure directories end with the OS path separator."""
path = os.path.join(self._port.layout_tests_dir(), test_list_path)
path = os.path.normpath(path)
- path = self._fix_dir(path)
+ if self._port.path_isdir(path):
+ path = os.path.join(path, '')
result = []
for test in self._full_test_list:
@@ -743,20 +734,6 @@ class TestExpectationsFile:
result.append(test)
return result
- def _fix_dir(self, path):
- """Check to see if the path points to a directory, and if so, append
- the directory separator if necessary."""
- if self._tests_are_present:
- if os.path.isdir(path):
- path = os.path.join(path, '')
- else:
- # If we can't check the filesystem to see if this is a directory,
- # we assume that files w/o an extension are directories.
- # TODO(dpranke): What happens w/ LayoutTests/css2.1 ?
- if os.path.splitext(path)[1] == '':
- path = os.path.join(path, '')
- return path
-
def _add_tests(self, tests, expectations, test_list_path, lineno,
modifiers, options, overrides_allowed):
for test in tests:
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py
index 26eb18d..2e1b6ec 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py
@@ -106,14 +106,13 @@ BUG_TEST WONTFIX WIN : failures/expected/image.html = IMAGE
"""
def parse_exp(self, expectations, overrides=None, is_lint_mode=False,
- is_debug_mode=False, tests_are_present=True):
+ is_debug_mode=False):
self._exp = TestExpectations(self._port,
tests=self.get_basic_tests(),
expectations=expectations,
test_platform_name=self._port.test_platform_name(),
is_debug_mode=is_debug_mode,
is_lint_mode=is_lint_mode,
- tests_are_present=tests_are_present,
overrides=overrides)
def assert_exp(self, test, result):
@@ -151,10 +150,6 @@ BUGX DEFER : failures/expected = IMAGE
self.assert_exp('failures/expected/text.html', TEXT)
self.assert_exp('failures/expected/crash.html', IMAGE)
- self.parse_exp(exp_str, tests_are_present=False)
- self.assert_exp('failures/expected/text.html', TEXT)
- self.assert_exp('failures/expected/crash.html', IMAGE)
-
def test_release_mode(self):
self.parse_exp('BUGX DEBUG : failures/expected/text.html = TEXT',
is_debug_mode=True)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
index 70beac3..6a5d43b 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
@@ -42,11 +42,13 @@ import sys
import time
import apache_http_server
+import test_files
import http_server
import websocket_server
from webkitpy.common.system import logutils
from webkitpy.common.system.executive import Executive, ScriptError
+from webkitpy.common.system.user import User
_log = logutils.get_logger(__file__)
@@ -81,14 +83,15 @@ class Port(object):
}
return flags_by_configuration[configuration]
- def __init__(self, port_name=None, options=None, executive=Executive()):
- self._name = port_name
- self._options = options
+ def __init__(self, **kwargs):
+ self._name = kwargs.get('port_name', None)
+ self._options = kwargs.get('options', None)
+ self._executive = kwargs.get('executive', Executive())
+ self._user = kwargs.get('user', User())
self._helper = None
self._http_server = None
self._webkit_base_dir = None
self._websocket_server = None
- self._executive = executive
def default_child_processes(self):
"""Return the number of DumpRenderTree instances to use for this
@@ -130,11 +133,11 @@ class Port(object):
interface so that it can be overriden for testing purposes."""
return expected_text != actual_text
- def diff_image(self, expected_filename, actual_filename,
+ def diff_image(self, expected_contents, actual_contents,
diff_filename=None, tolerance=0):
- """Compare two image files and produce a delta image file.
+ """Compare two images and produce a delta image file.
- Return True if the two files are different, False if they are the same.
+ Return True if the two images are different, False if they are the same.
Also produce a delta image of the two images and write that into
|diff_filename| if it is not None.
@@ -252,6 +255,31 @@ class Port(object):
return os.path.join(platform_dir, baseline_filename)
return os.path.join(self.layout_tests_dir(), baseline_filename)
+ def _expected_file_contents(self, test, extension, encoding):
+ path = self.expected_filename(test, extension)
+ if not os.path.exists(path):
+ return None
+ with codecs.open(path, 'r', encoding) as file:
+ return file.read()
+
+ def expected_checksum(self, test):
+ """Returns the checksum of the image we expect the test to produce, or None if it is a text-only test."""
+ return self._expected_file_contents(test, '.checksum', 'ascii')
+
+ def expected_image(self, test):
+ """Returns the image we expect the test to produce."""
+ return self._expected_file_contents(test, '.png', None)
+
+ def expected_text(self, test):
+ """Returns the text output we expect the test to produce."""
+ # NOTE: -expected.txt files are ALWAYS utf-8. However,
+ # we do not decode the output from DRT, so we should not
+ # decode the -expected.txt values either to allow comparisons.
+ text = self._expected_file_contents(test, '.txt', None)
+ if not text:
+ return ''
+ return text.strip("\r\n").replace("\r\n", "\n") + "\n"
+
def filename_to_uri(self, filename):
"""Convert a test file to a URI."""
LAYOUTTEST_HTTP_DIR = "http/tests/"
@@ -287,6 +315,73 @@ class Port(object):
return "file:///" + self.get_absolute_path(filename)
return "file://" + self.get_absolute_path(filename)
+ def tests(self, paths):
+ """Return the list of tests found (relative to layout_tests_dir()."""
+ return test_files.find(self, paths)
+
+ def test_dirs(self):
+ """Returns the list of top-level test directories.
+
+ Used by --clobber-old-results."""
+ layout_tests_dir = self.layout_tests_dir()
+ return filter(lambda x: os.path.isdir(os.path.join(layout_tests_dir, x)),
+ os.listdir(layout_tests_dir))
+
+ def path_isdir(self, path):
+ """Returns whether the path refers to a directory of tests.
+
+ Used by test_expectations.py to apply rules to whole directories."""
+ return os.path.isdir(path)
+
+ def path_exists(self, path):
+ """Returns whether the path refers to an existing test or baseline."""
+ # Used by test_expectations.py to determine if an entry refers to a
+ # valid test and by printing.py to determine if baselines exist."""
+ return os.path.exists(path)
+
+ def update_baseline(self, path, data, encoding):
+ """Updates the baseline for a test.
+
+ Args:
+ path: the actual path to use for baseline, not the path to
+ the test. This function is used to update either generic or
+ platform-specific baselines, but we can't infer which here.
+ data: contents of the baseline.
+ encoding: file encoding to use for the baseline.
+ """
+ with codecs.open(path, "w", encoding=encoding) as file:
+ file.write(data)
+
+ def uri_to_test_name(self, uri):
+ """Return the base layout test name for a given URI.
+
+ This returns the test name for a given URI, e.g., if you passed in
+ "file:///src/LayoutTests/fast/html/keygen.html" it would return
+ "fast/html/keygen.html".
+
+ """
+ test = uri
+ if uri.startswith("file:///"):
+ if sys.platform == 'win32':
+ test = test.replace('file:///', '')
+ test = test.replace('/', '\\')
+ else:
+ test = test.replace('file://', '')
+ return self.relative_test_filename(test)
+
+ if uri.startswith("http://127.0.0.1:8880/"):
+ # websocket tests
+ return test.replace('http://127.0.0.1:8880/', '')
+
+ if uri.startswith("http://"):
+ # regular HTTP test
+ return test.replace('http://127.0.0.1:8000/', 'http/tests/')
+
+ if uri.startswith("https://"):
+ return test.replace('https://127.0.0.1:8443/', 'http/tests/')
+
+ raise NotImplementedError('unknown url type: %s' % uri)
+
def get_absolute_path(self, filename):
"""Return the absolute path in unix format for the given filename.
@@ -369,10 +464,10 @@ class Port(object):
"""
return os.environ.copy()
- def show_html_results_file(self, results_filename):
+ def show_results_html_file(self, results_filename):
"""This routine should display the HTML file pointed at by
results_filename in a users' browser."""
- raise NotImplementedError('Port.show_html_results_file')
+ return self._user.open_url(results_filename)
def create_driver(self, image_path, options):
"""Return a newly created base.Driver subclass for starting/stopping
@@ -588,7 +683,7 @@ class Port(object):
try:
with self._open_configuration_file() as file:
return file.readline().rstrip()
- except IOError, e:
+ except:
return None
# FIXME: This list may be incomplete as Apple has some sekret configs.
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py
index 780cd22..71877b3 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py
@@ -57,16 +57,17 @@ class MockExecutive():
class UnitTestPort(base.Port):
"""Subclass of base.Port used for unit testing."""
- def __init__(self, configuration_contents=None, executive_exception=None):
+ def __init__(self, configuration_contents=None, configuration_exception=IOError, executive_exception=None):
base.Port.__init__(self)
self._configuration_contents = configuration_contents
+ self._configuration_exception = configuration_exception
if executive_exception:
self._executive = MockExecutive(executive_exception)
def _open_configuration_file(self):
if self._configuration_contents:
return NewStringIO(self._configuration_contents)
- raise IOError
+ raise self._configuration_exception
class PortTest(unittest.TestCase):
@@ -191,9 +192,14 @@ class PortTest(unittest.TestCase):
self.assertFalse('nosuchthing' in diff)
def test_default_configuration_notfound(self):
+ # Regular IOError thrown while trying to get the configuration.
port = UnitTestPort()
self.assertEqual(port.default_configuration(), "Release")
+ # More exotic OSError thrown.
+ port = UnitTestPort(configuration_exception=OSError)
+ self.assertEqual(port.default_configuration(), "Release")
+
def test_layout_tests_skipping(self):
port = base.Port()
port.skipped_layout_tests = lambda: ['foo/bar.html', 'media']
@@ -214,6 +220,11 @@ class PortTest(unittest.TestCase):
# This routine is a no-op. We just test it for coverage.
port.setup_test_run()
+ def test_test_dirs(self):
+ port = base.Port()
+ dirs = port.test_dirs()
+ self.assertTrue('canvas' in dirs)
+ self.assertTrue('css2.1' in dirs)
class VirtualTest(unittest.TestCase):
"""Tests that various methods expected to be virtual are."""
@@ -231,7 +242,6 @@ class VirtualTest(unittest.TestCase):
self.assertVirtual(port.path_to_test_expectations_file)
self.assertVirtual(port.test_platform_name)
self.assertVirtual(port.results_directory)
- self.assertVirtual(port.show_html_results_file, None)
self.assertVirtual(port.test_expectations)
self.assertVirtual(port.test_base_platform_names)
self.assertVirtual(port.test_platform_name)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py
index 3fc4613..a72627a 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py
@@ -39,6 +39,7 @@ import shutil
import signal
import subprocess
import sys
+import tempfile
import time
import webbrowser
@@ -46,7 +47,6 @@ import base
import http_server
from webkitpy.common.system.executive import Executive
-from webkitpy.layout_tests.layout_package import test_files
from webkitpy.layout_tests.layout_package import test_expectations
# Chromium DRT on OSX uses WebKitDriver.
@@ -82,8 +82,13 @@ def check_file_exists(path_to_file, file_description, override_step=None,
class ChromiumPort(base.Port):
"""Abstract base class for Chromium implementations of the Port class."""
- def __init__(self, port_name=None, options=None, **kwargs):
- base.Port.__init__(self, port_name, options, **kwargs)
+ def __init__(self, **kwargs):
+ base.Port.__init__(self, **kwargs)
+ if 'options' in kwargs:
+ options = kwargs['options']
+ if (options and (not hasattr(options, 'configuration') or
+ options.configuration is None)):
+ options.configuration = self.default_configuration()
self._chromium_base_dir = None
def baseline_path(self):
@@ -126,14 +131,18 @@ class ChromiumPort(base.Port):
return check_file_exists(image_diff_path, 'image diff exe',
override_step, logging)
- def diff_image(self, expected_filename, actual_filename,
+ def diff_image(self, expected_contents, actual_contents,
diff_filename=None, tolerance=0):
executable = self._path_to_image_diff()
+ expected_tmpfile = tempfile.NamedTemporaryFile()
+ expected_tmpfile.write(expected_contents)
+ actual_tmpfile = tempfile.NamedTemporaryFile()
+ actual_tmpfile.write(actual_contents)
if diff_filename:
- cmd = [executable, '--diff', expected_filename, actual_filename,
- diff_filename]
+ cmd = [executable, '--diff', expected_tmpfile.name,
+ actual_tmpfile.name, diff_filename]
else:
- cmd = [executable, expected_filename, actual_filename]
+ cmd = [executable, expected_tmpfile.name, actual_tmpfile.name]
result = True
try:
@@ -144,6 +153,9 @@ class ChromiumPort(base.Port):
_compare_available = False
else:
raise e
+ finally:
+ expected_tmpfile.close()
+ actual_tmpfile.close()
return result
def driver_name(self):
@@ -183,15 +195,6 @@ class ChromiumPort(base.Port):
if os.path.exists(cachedir):
shutil.rmtree(cachedir)
- def show_results_html_file(self, results_filename):
- uri = self.get_absolute_path(results_filename)
- if self._options.use_drt:
- # FIXME: This should use User.open_url
- webbrowser.open(uri, new=1)
- else:
- # Note: Not thread safe: http://bugs.python.org/issue2320
- subprocess.Popen([self._path_to_driver(), uri])
-
def create_driver(self, image_path, options):
"""Starts a new Driver and returns a handle to it."""
if options.use_drt and sys.platform == 'darwin':
@@ -236,7 +239,7 @@ class ChromiumPort(base.Port):
# FIXME: This drt_overrides handling should be removed when we switch
# from tes_shell to DRT.
drt_overrides = ''
- if self._options.use_drt:
+ if self._options and self._options.use_drt:
drt_overrides_path = self.path_from_webkit_base('LayoutTests',
'platform', 'chromium', 'drt_expectations.txt')
if os.path.exists(drt_overrides_path):
@@ -259,14 +262,13 @@ class ChromiumPort(base.Port):
test_platform_name = self.test_platform_name()
is_debug_mode = False
- all_test_files = test_files.gather_test_files(self, '*')
+ all_test_files = self.tests([])
if extra_test_files:
all_test_files.update(extra_test_files)
expectations = test_expectations.TestExpectations(
self, all_test_files, expectations_str, test_platform_name,
- is_debug_mode, is_lint_mode=True,
- tests_are_present=False, overrides=overrides_str)
+ is_debug_mode, is_lint_mode=True, overrides=overrides_str)
tests_dir = self.layout_tests_dir()
return [self.relative_test_filename(test)
for test in expectations.get_tests_with_result_type(test_expectations.SKIP)]
@@ -354,6 +356,12 @@ class ChromiumDriver(base.Driver):
if self._options.gp_fault_error_box:
driver_args.append('--gp-fault-error-box')
+
+ if self._options.accelerated_compositing:
+ driver_args.append('--enable-accelerated-compositing')
+
+ if self._options.accelerated_2d_canvas:
+ driver_args.append('--enable-accelerated-2d-canvas')
return driver_args
def start(self):
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py
new file mode 100644
index 0000000..80602d9
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from __future__ import with_statement
+
+import codecs
+import os
+import sys
+
+import chromium_linux
+import chromium_mac
+import chromium_win
+
+
+def get(**kwargs):
+ """Some tests have slightly different results when run while using
+ hardware acceleration. In those cases, we prepend an additional directory
+ to the baseline paths."""
+ port_name = kwargs.get('port_name', None)
+ if port_name == 'chromium-gpu':
+ if sys.platform in ('cygwin', 'win32'):
+ port_name = 'chromium-gpu-win'
+ elif sys.platform == 'linux2':
+ port_name = 'chromium-gpu-linux'
+ elif sys.platform == 'darwin':
+ port_name = 'chromium-gpu-mac'
+ else:
+ raise NotImplementedError('unsupported platform: %s' %
+ sys.platform)
+
+ if port_name == 'chromium-gpu-linux':
+ return ChromiumGpuLinuxPort(**kwargs)
+
+ if port_name.startswith('chromium-gpu-mac'):
+ return ChromiumGpuMacPort(**kwargs)
+
+ if port_name.startswith('chromium-gpu-win'):
+ return ChromiumGpuWinPort(**kwargs)
+
+ raise NotImplementedError('unsupported port: %s' % port_name)
+
+
+def _set_gpu_options(options):
+ if options:
+ if options.accelerated_compositing is None:
+ options.accelerated_composting = True
+ if options.accelerated_2d_canvas is None:
+ options.accelerated_2d_canvas = True
+
+
+def _gpu_overrides(port):
+ try:
+ overrides_path = port.path_from_chromium_base('webkit', 'tools',
+ 'layout_tests', 'test_expectations_gpu.txt')
+ except AssertionError:
+ return None
+ if not os.path.exists(overrides_path):
+ return None
+ with codecs.open(overrides_path, "r", "utf-8") as file:
+ return file.read()
+
+
+class ChromiumGpuLinuxPort(chromium_linux.ChromiumLinuxPort):
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'chromium-gpu-linux')
+ _set_gpu_options(kwargs.get('options'))
+ chromium_linux.ChromiumLinuxPort.__init__(self, **kwargs)
+
+ def baseline_search_path(self):
+ return ([self._webkit_baseline_path('chromium-gpu-linux')] +
+ chromium_linux.ChromiumLinuxPort.baseline_search_path(self))
+
+ def path_to_test_expectations_file(self):
+ return self.path_from_webkit_base('LayoutTests', 'platform',
+ 'chromium-gpu', 'test_expectations.txt')
+
+ def test_expectations_overrides(self):
+ return _gpu_overrides(self)
+
+
+class ChromiumGpuMacPort(chromium_mac.ChromiumMacPort):
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'chromium-gpu-mac')
+ _set_gpu_options(kwargs.get('options'))
+ chromium_mac.ChromiumMacPort.__init__(self, **kwargs)
+
+ def baseline_search_path(self):
+ return ([self._webkit_baseline_path('chromium-gpu-mac')] +
+ chromium_mac.ChromiumMacPort.baseline_search_path(self))
+
+ def path_to_test_expectations_file(self):
+ return self.path_from_webkit_base('LayoutTests', 'platform',
+ 'chromium-gpu', 'test_expectations.txt')
+
+ def test_expectations_overrides(self):
+ return _gpu_overrides(self)
+
+
+class ChromiumGpuWinPort(chromium_win.ChromiumWinPort):
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'chromium-gpu-win' + self.version())
+ _set_gpu_options(kwargs.get('options'))
+ chromium_win.ChromiumWinPort.__init__(self, **kwargs)
+
+ def baseline_search_path(self):
+ return ([self._webkit_baseline_path('chromium-gpu-win')] +
+ chromium_win.ChromiumWinPort.baseline_search_path(self))
+
+ def path_to_test_expectations_file(self):
+ return self.path_from_webkit_base('LayoutTests', 'platform',
+ 'chromium-gpu', 'test_expectations.txt')
+
+ def test_expectations_overrides(self):
+ return _gpu_overrides(self)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py
new file mode 100644
index 0000000..5c79a3f
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os
+import unittest
+import chromium_gpu
+
+
+class ChromiumGpuTest(unittest.TestCase):
+ def test_get_chromium_gpu_linux(self):
+ self.assertOverridesWorked('chromium-gpu-linux')
+
+ def test_get_chromium_gpu_mac(self):
+ self.assertOverridesWorked('chromium-gpu-mac')
+
+ def test_get_chromium_gpu_win(self):
+ self.assertOverridesWorked('chromium-gpu-win')
+
+ def assertOverridesWorked(self, port_name):
+ # test that we got the right port
+ port = chromium_gpu.get(port_name=port_name, options=None)
+
+ # we use startswith() instead of Equal to gloss over platform versions.
+ self.assertTrue(port.name().startswith(port_name))
+
+ # test that it has the right directory in front of the search path.
+ path = port.baseline_search_path()[0]
+ self.assertEqual(port._webkit_baseline_path(port_name), path)
+
+ # test that we have the right expectations file.
+ self.assertTrue('chromium-gpu' in
+ port.path_to_test_expectations_file())
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py
index 4df43e0..176991b 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py
@@ -41,12 +41,9 @@ _log = logging.getLogger("webkitpy.layout_tests.port.chromium_linux")
class ChromiumLinuxPort(chromium.ChromiumPort):
"""Chromium Linux implementation of the Port class."""
- def __init__(self, port_name=None, options=None):
- if port_name is None:
- port_name = 'chromium-linux'
- if options and not hasattr(options, 'configuration'):
- options.configuration = 'Release'
- chromium.ChromiumPort.__init__(self, port_name, options)
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'chromium-linux')
+ chromium.ChromiumPort.__init__(self, **kwargs)
def baseline_search_path(self):
port_names = ["chromium-linux", "chromium-win", "chromium", "win", "mac"]
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py
index abd84ae..64016ab 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py
@@ -44,12 +44,9 @@ _log = logging.getLogger("webkitpy.layout_tests.port.chromium_mac")
class ChromiumMacPort(chromium.ChromiumPort):
"""Chromium Mac implementation of the Port class."""
- def __init__(self, port_name=None, options=None):
- if port_name is None:
- port_name = 'chromium-mac'
- if options and not hasattr(options, 'configuration'):
- options.configuration = 'Release'
- chromium.ChromiumPort.__init__(self, port_name, options)
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'chromium-mac')
+ chromium.ChromiumPort.__init__(self, **kwargs)
def baseline_search_path(self):
port_names = ["chromium-mac", "chromium", "mac" + self.version(), "mac"]
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py
index 7a005b1..a4a9ea6 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py
@@ -83,17 +83,39 @@ class ChromiumDriverTest(unittest.TestCase):
self.driver._proc.stdout.readline = mock_readline
self._assert_write_command_and_read_line(expected_crash=True)
+
+class ChromiumPortTest(unittest.TestCase):
+ class TestMacPort(chromium_mac.ChromiumMacPort):
+ def __init__(self, options):
+ chromium_mac.ChromiumMacPort.__init__(self,
+ port_name='test-port',
+ options=options)
+
+ def default_configuration(self):
+ self.default_configuration_called = True
+ return 'default'
+
+ class TestLinuxPort(chromium_linux.ChromiumLinuxPort):
+ def __init__(self, options):
+ chromium_linux.ChromiumLinuxPort.__init__(self,
+ port_name='test-port',
+ options=options)
+
+ def default_configuration(self):
+ self.default_configuration_called = True
+ return 'default'
+
def test_path_to_image_diff(self):
class MockOptions:
def __init__(self):
self.use_drt = True
- port = chromium_linux.ChromiumLinuxPort('test-port', options=MockOptions())
+ port = ChromiumPortTest.TestLinuxPort(options=MockOptions())
self.assertTrue(port._path_to_image_diff().endswith(
- '/out/Release/ImageDiff'))
- port = chromium_mac.ChromiumMacPort('test-port', options=MockOptions())
+ '/out/default/ImageDiff'), msg=port._path_to_image_diff())
+ port = ChromiumPortTest.TestMacPort(options=MockOptions())
self.assertTrue(port._path_to_image_diff().endswith(
- '/xcodebuild/Release/ImageDiff'))
+ '/xcodebuild/default/ImageDiff'))
# FIXME: Figure out how this is going to work on Windows.
#port = chromium_win.ChromiumWinPort('test-port', options=MockOptions())
@@ -102,16 +124,37 @@ class ChromiumDriverTest(unittest.TestCase):
def __init__(self):
self.use_drt = True
- port = chromium_linux.ChromiumLinuxPort('test-port', options=MockOptions())
+ port = ChromiumPortTest.TestLinuxPort(options=MockOptions())
fake_test = os.path.join(port.layout_tests_dir(), "fast/js/not-good.js")
port.test_expectations = lambda: """BUG_TEST SKIP : fast/js/not-good.js = TEXT
DEFER LINUX WIN : fast/js/very-good.js = TIMEOUT PASS"""
port.test_expectations_overrides = lambda: ''
+ port.tests = lambda paths: set()
+ port.path_exists = lambda test: True
skipped_tests = port.skipped_layout_tests(extra_test_files=[fake_test, ])
self.assertTrue("fast/js/not-good.js" in skipped_tests)
+ def test_default_configuration(self):
+ class EmptyOptions:
+ def __init__(self):
+ pass
+
+ options = EmptyOptions()
+ port = ChromiumPortTest.TestLinuxPort(options)
+ self.assertEquals(options.configuration, 'default')
+ self.assertTrue(port.default_configuration_called)
+
+ class OptionsWithUnsetConfiguration:
+ def __init__(self):
+ self.configuration = None
+
+ options = OptionsWithUnsetConfiguration()
+ port = ChromiumPortTest.TestLinuxPort(options)
+ self.assertEquals(options.configuration, 'default')
+ self.assertTrue(port.default_configuration_called)
+
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
index e9a81e7..d2b0265 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
@@ -41,12 +41,9 @@ _log = logging.getLogger("webkitpy.layout_tests.port.chromium_win")
class ChromiumWinPort(chromium.ChromiumPort):
"""Chromium Win implementation of the Port class."""
- def __init__(self, port_name=None, options=None):
- if port_name is None:
- port_name = "chromium-win" + self.version()
- if options and not hasattr(options, "configuration"):
- options.configuration = "Release"
- chromium.ChromiumPort.__init__(self, port_name, options)
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'chromium-win' + self.version())
+ chromium.ChromiumPort.__init__(self, **kwargs)
def setup_environ_for_server(self):
env = chromium.ChromiumPort.setup_environ_for_server(self)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py
index 4940e4c..648ccad 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py
@@ -46,48 +46,24 @@
from __future__ import with_statement
+import os
import sys
import base
import factory
-def _read_file(path, mode='r'):
- """Return the contents of a file as a string.
-
- Returns '' if anything goes wrong, instead of throwing an IOError.
-
- """
- contents = ''
- try:
- with open(path, mode) as f:
- contents = f.read()
- except IOError:
- pass
- return contents
-
-
-def _write_file(path, contents, mode='w'):
- """Write the string to the specified path.
-
- Writes should never fail, so we may raise IOError.
-
- """
- with open(path, mode) as f:
- f.write(contents)
-
-
class DryRunPort(object):
"""DryRun implementation of the Port interface."""
- def __init__(self, port_name=None, options=None):
+ def __init__(self, **kwargs):
pfx = 'dryrun-'
- if port_name.startswith(pfx):
- port_name = port_name[len(pfx):]
- else:
- port_name = None
- self._options = options
- self.__delegate = factory.get(port_name, options)
+ if 'port_name' in kwargs:
+ if kwargs['port_name'].startswith(pfx):
+ kwargs['port_name'] = kwargs['port_name'][len(pfx):]
+ else:
+ kwargs['port_name'] = None
+ self.__delegate = factory.get(**kwargs)
def __getattr__(self, name):
return getattr(self.__delegate, name)
@@ -134,19 +110,16 @@ class DryrunDriver(base.Driver):
return None
def run_test(self, uri, timeoutms, image_hash):
- test_name = self._uri_to_test(uri)
-
- text_filename = self._port.expected_filename(test_name, '.txt')
- text_output = _read_file(text_filename)
+ test_name = self._port.uri_to_test_name(uri)
+ path = os.path.join(self._port.layout_tests_dir(), test_name)
+ text_output = self._port.expected_text(path)
if image_hash is not None:
- image_filename = self._port.expected_filename(test_name, '.png')
- image = _read_file(image_filename, 'rb')
- if self._image_path:
- _write_file(self._image_path, image)
- hash_filename = self._port.expected_filename(test_name,
- '.checksum')
- hash = _read_file(hash_filename)
+ image = self._port.expected_image(path)
+ if image and self._image_path:
+ with open(self._image_path, 'w') as f:
+ f.write(image)
+ hash = self._port.expected_checksum(path)
else:
hash = None
return (False, False, hash, text_output, None)
@@ -156,39 +129,3 @@ class DryrunDriver(base.Driver):
def stop(self):
pass
-
- def _uri_to_test(self, uri):
- """Return the base layout test name for a given URI.
-
- This returns the test name for a given URI, e.g., if you passed in
- "file:///src/LayoutTests/fast/html/keygen.html" it would return
- "fast/html/keygen.html".
-
- """
- if not self._layout_tests_dir:
- self._layout_tests_dir = self._port.layout_tests_dir()
- test = uri
-
- if uri.startswith("file:///"):
- if sys.platform == 'win32':
- test = test.replace('file:///', '')
- test = test.replace('/', '\\')
- else:
- test = test.replace('file://', '')
- return test
- elif uri.startswith("http://127.0.0.1:8880/"):
- # websocket tests
- test = test.replace('http://127.0.0.1:8880/',
- self._layout_tests_dir + '/')
- return test
- elif uri.startswith("http://"):
- # regular HTTP test
- test = test.replace('http://127.0.0.1:8000/',
- self._layout_tests_dir + '/http/tests/')
- return test
- elif uri.startswith("https://"):
- test = test.replace('https://127.0.0.1:8443/',
- self._layout_tests_dir + '/http/tests/')
- return test
- else:
- raise NotImplementedError('unknown url type: %s' % uri)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py
index 5704f65..6935744 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py
@@ -37,11 +37,21 @@ ALL_PORT_NAMES = ['test', 'dryrun', 'mac', 'win', 'gtk', 'qt', 'chromium-mac',
'google-chrome-mac', 'google-chrome-linux32', 'google-chrome-linux64']
-def get(port_name=None, options=None):
+def get(port_name=None, options=None, **kwargs):
"""Returns an object implementing the Port interface. If
port_name is None, this routine attempts to guess at the most
appropriate port on this platform."""
- port_to_use = port_name
+ # Wrapped for backwards-compatibility
+ if port_name:
+ kwargs['port_name'] = port_name
+ if options:
+ kwargs['options'] = options
+ return _get_kwargs(**kwargs)
+
+
+def _get_kwargs(**kwargs):
+ port_to_use = kwargs.get('port_name', None)
+ options = kwargs.get('options', None)
if port_to_use is None:
if sys.platform == 'win32' or sys.platform == 'cygwin':
if options and hasattr(options, 'chromium') and options.chromium:
@@ -62,37 +72,40 @@ def get(port_name=None, options=None):
if port_to_use == 'test':
import test
- return test.TestPort(port_name, options)
+ maker = test.TestPort
elif port_to_use.startswith('dryrun'):
import dryrun
- return dryrun.DryRunPort(port_name, options)
+ maker = dryrun.DryRunPort
elif port_to_use.startswith('mac'):
import mac
- return mac.MacPort(port_name, options)
+ maker = mac.MacPort
elif port_to_use.startswith('win'):
import win
- return win.WinPort(port_name, options)
+ maker = win.WinPort
elif port_to_use.startswith('gtk'):
import gtk
- return gtk.GtkPort(port_name, options)
+ maker = gtk.GtkPort
elif port_to_use.startswith('qt'):
import qt
- return qt.QtPort(port_name, options)
+ maker = qt.QtPort
+ elif port_to_use.startswith('chromium-gpu'):
+ import chromium_gpu
+ maker = chromium_gpu.get
elif port_to_use.startswith('chromium-mac'):
import chromium_mac
- return chromium_mac.ChromiumMacPort(port_name, options)
+ maker = chromium_mac.ChromiumMacPort
elif port_to_use.startswith('chromium-linux'):
import chromium_linux
- return chromium_linux.ChromiumLinuxPort(port_name, options)
+ maker = chromium_linux.ChromiumLinuxPort
elif port_to_use.startswith('chromium-win'):
import chromium_win
- return chromium_win.ChromiumWinPort(port_name, options)
+ maker = chromium_win.ChromiumWinPort
elif port_to_use.startswith('google-chrome'):
import google_chrome
- return google_chrome.GetGoogleChromePort(port_name, options)
-
- raise NotImplementedError('unsupported port: %s' % port_to_use)
-
+ maker = google_chrome.GetGoogleChromePort
+ else:
+ raise NotImplementedError('unsupported port: %s' % port_to_use)
+ return maker(**kwargs)
def get_all(options=None):
"""Returns all the objects implementing the Port interface."""
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py
index c0a4c5e..81c3732 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py
@@ -29,6 +29,7 @@
import sys
import unittest
+import chromium_gpu
import chromium_linux
import chromium_mac
import chromium_win
@@ -133,6 +134,15 @@ class FactoryTest(unittest.TestCase):
def test_qt(self):
self.assert_port("qt", qt.QtPort)
+ def test_chromium_gpu_linux(self):
+ self.assert_port("chromium-gpu-linux", chromium_gpu.ChromiumGpuLinuxPort)
+
+ def test_chromium_gpu_mac(self):
+ self.assert_port("chromium-gpu-mac", chromium_gpu.ChromiumGpuMacPort)
+
+ def test_chromium_gpu_win(self):
+ self.assert_port("chromium-gpu-win", chromium_gpu.ChromiumGpuWinPort)
+
def test_chromium_mac(self):
self.assert_port("chromium-mac", chromium_mac.ChromiumMacPort)
self.assert_platform_port("darwin", self.chromium_options,
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py
index 46ab3ed..bffc860 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py
@@ -25,10 +25,12 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-def GetGoogleChromePort(port_name, options):
+def GetGoogleChromePort(**kwargs):
"""Some tests have slightly different results when compiled as Google
Chrome vs Chromium. In those cases, we prepend an additional directory to
to the baseline paths."""
+ port_name = kwargs['port_name']
+ del kwargs['port_name']
if port_name == 'google-chrome-linux32':
import chromium_linux
@@ -39,7 +41,7 @@ def GetGoogleChromePort(port_name, options):
paths.insert(0, self._webkit_baseline_path(
'google-chrome-linux32'))
return paths
- return GoogleChromeLinux32Port(None, options)
+ return GoogleChromeLinux32Port(**kwargs)
elif port_name == 'google-chrome-linux64':
import chromium_linux
@@ -50,7 +52,7 @@ def GetGoogleChromePort(port_name, options):
paths.insert(0, self._webkit_baseline_path(
'google-chrome-linux64'))
return paths
- return GoogleChromeLinux64Port(None, options)
+ return GoogleChromeLinux64Port(**kwargs)
elif port_name.startswith('google-chrome-mac'):
import chromium_mac
@@ -61,7 +63,7 @@ def GetGoogleChromePort(port_name, options):
paths.insert(0, self._webkit_baseline_path(
'google-chrome-mac'))
return paths
- return GoogleChromeMacPort(None, options)
+ return GoogleChromeMacPort(**kwargs)
elif port_name.startswith('google-chrome-win'):
import chromium_win
@@ -72,5 +74,5 @@ def GetGoogleChromePort(port_name, options):
paths.insert(0, self._webkit_baseline_path(
'google-chrome-win'))
return paths
- return GoogleChromeWinPort(None, options)
+ return GoogleChromeWinPort(**kwargs)
raise NotImplementedError('unsupported port: %s' % port_name)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py
index a2d7056..85e9338 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py
@@ -41,6 +41,7 @@ class GetGoogleChromePortTest(unittest.TestCase):
self._verify_baseline_path('google-chrome-win', 'google-chrome-win-vista')
def _verify_baseline_path(self, expected_path, port_name):
- port = google_chrome.GetGoogleChromePort(port_name, None)
+ port = google_chrome.GetGoogleChromePort(port_name=port_name,
+ options=None)
path = port.baseline_search_path()[0]
self.assertEqual(expected_path, os.path.split(path)[1])
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/gtk.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/gtk.py
index 59dc1d9..c60909e 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/gtk.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/gtk.py
@@ -39,10 +39,9 @@ _log = logging.getLogger("webkitpy.layout_tests.port.gtk")
class GtkPort(WebKitPort):
"""WebKit Gtk implementation of the Port class."""
- def __init__(self, port_name=None, options=None):
- if port_name is None:
- port_name = 'gtk'
- WebKitPort.__init__(self, port_name, options)
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'gtk')
+ WebKitPort.__init__(self, **kwargs)
def _tests_for_other_platforms(self):
# FIXME: This list could be dynamic based on platform name and
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py
index 413b5f2..696e339 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py
@@ -43,10 +43,9 @@ _log = logging.getLogger("webkitpy.layout_tests.port.mac")
class MacPort(WebKitPort):
"""WebKit Mac implementation of the Port class."""
- def __init__(self, port_name=None, options=None):
- if port_name is None:
- port_name = 'mac' + self.version()
- WebKitPort.__init__(self, port_name, options)
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'mac' + self.version())
+ WebKitPort.__init__(self, **kwargs)
def default_child_processes(self):
# FIXME: new-run-webkit-tests is unstable on Mac running more than
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py
index 2d650f5..47597d6 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py
@@ -68,14 +68,20 @@ class PortTestCase(unittest.TestCase):
dir = port.layout_tests_dir()
file1 = os.path.join(dir, 'fast', 'css', 'button_center.png')
+ fh1 = file(file1)
+ contents1 = fh1.read()
file2 = os.path.join(dir, 'fast', 'css',
'remove-shorthand-expected.png')
+ fh2 = file(file2)
+ contents2 = fh2.read()
tmpfile = tempfile.mktemp()
- self.assertFalse(port.diff_image(file1, file1))
- self.assertTrue(port.diff_image(file1, file2))
+ self.assertFalse(port.diff_image(contents1, contents1))
+ self.assertTrue(port.diff_image(contents1, contents2))
- self.assertTrue(port.diff_image(file1, file2, tmpfile))
+ self.assertTrue(port.diff_image(contents1, contents2, tmpfile))
+ fh1.close()
+ fh2.close()
# FIXME: this may not be being written?
# self.assertTrue(os.path.exists(tmpfile))
# os.remove(tmpfile)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py
index 158c633..4c8fa0a 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py
@@ -42,10 +42,9 @@ _log = logging.getLogger("webkitpy.layout_tests.port.qt")
class QtPort(WebKitPort):
"""QtWebKit implementation of the Port class."""
- def __init__(self, port_name=None, options=None):
- if port_name is None:
- port_name = 'qt'
- WebKitPort.__init__(self, port_name, options)
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'qt')
+ WebKitPort.__init__(self, **kwargs)
def _tests_for_other_platforms(self):
# FIXME: This list could be dynamic based on platform name and
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py
index 8e0bc11..5a0a40c 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py
@@ -179,7 +179,7 @@ class ServerProcess:
elif size == 0:
index = self._output.find('\n') + 1
- if index or self.crashed or self.timed_out:
+ if index > 0 or self.crashed or self.timed_out:
output = self._output[0:index]
self._output = self._output[index:]
return output
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
index 2ccddb0..3b81167 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
@@ -31,17 +31,100 @@
from __future__ import with_statement
import codecs
+import fnmatch
import os
+import sys
import time
import base
+# This sets basic expectations for a test. Each individual expectation
+# can be overridden by a keyword argument in TestList.add().
+class TestInstance:
+ def __init__(self, name):
+ self.name = name
+ self.base = name[(name.rfind("/") + 1):name.rfind(".html")]
+ self.crash = False
+ self.exception = False
+ self.hang = False
+ self.keyboard = False
+ self.error = ''
+ self.timeout = False
+ self.actual_text = self.base + '-txt\n'
+ self.actual_checksum = self.base + '-checksum\n'
+ self.actual_image = self.base + '-png\n'
+ self.expected_text = self.actual_text
+ self.expected_checksum = self.actual_checksum
+ self.expected_image = self.actual_image
+
+
+# This is an in-memory list of tests, what we want them to produce, and
+# what we want to claim are the expected results.
+class TestList:
+ def __init__(self, port):
+ self.port = port
+ self.tests = {}
+
+ def add(self, name, **kwargs):
+ test = TestInstance(name)
+ for key, value in kwargs.items():
+ test.__dict__[key] = value
+ self.tests[name] = test
+
+ def keys(self):
+ return self.tests.keys()
+
+ def __contains__(self, item):
+ return item in self.tests
+
+ def __getitem__(self, item):
+ return self.tests[item]
+
+
class TestPort(base.Port):
"""Test implementation of the Port interface."""
- def __init__(self, port_name=None, options=None):
- base.Port.__init__(self, port_name, options)
+ def __init__(self, **kwargs):
+ base.Port.__init__(self, **kwargs)
+ tests = TestList(self)
+ tests.add('passes/image.html')
+ tests.add('passes/text.html')
+ tests.add('failures/expected/checksum.html',
+ actual_checksum='checksum_fail-checksum')
+ tests.add('failures/expected/crash.html', crash=True)
+ tests.add('failures/expected/exception.html', exception=True)
+ tests.add('failures/expected/timeout.html', timeout=True)
+ tests.add('failures/expected/hang.html', hang=True)
+ tests.add('failures/expected/missing_text.html',
+ expected_text=None)
+ tests.add('failures/expected/image.html',
+ actual_image='image_fail-png',
+ expected_image='image-png')
+ tests.add('failures/expected/image_checksum.html',
+ actual_checksum='image_checksum_fail-checksum',
+ actual_image='image_checksum_fail-png')
+ tests.add('failures/expected/keyboard.html',
+ keyboard=True)
+ tests.add('failures/expected/missing_check.html',
+ expected_checksum=None)
+ tests.add('failures/expected/missing_image.html',
+ expected_image=None)
+ tests.add('failures/expected/missing_text.html',
+ expected_text=None)
+ tests.add('failures/expected/text.html',
+ actual_text='text_fail-png')
+ tests.add('failures/unexpected/text-image-checksum.html',
+ actual_text='text-image-checksum_fail-txt',
+ actual_checksum='text-image-checksum_fail-checksum')
+ tests.add('http/tests/passes/text.html')
+ tests.add('http/tests/ssl/text.html')
+ tests.add('passes/error.html', error='stuff going to stderr')
+ tests.add('passes/image.html')
+ tests.add('passes/platform_image.html')
+ tests.add('passes/text.html')
+ tests.add('websocket/tests/passes/text.html')
+ self._tests = tests
def baseline_path(self):
return os.path.join(self.layout_tests_dir(), 'platform',
@@ -53,12 +136,8 @@ class TestPort(base.Port):
def check_build(self, needs_http):
return True
- def diff_image(self, expected_filename, actual_filename,
+ def diff_image(self, expected_contents, actual_contents,
diff_filename=None, tolerance=0):
- with codecs.open(actual_filename, "r", "utf-8") as actual_fh:
- actual_contents = actual_fh.read()
- with codecs.open(expected_filename, "r", "utf-8") as expected_fh:
- expected_contents = expected_fh.read()
diffed = actual_contents != expected_contents
if diffed and diff_filename:
with codecs.open(diff_filename, "w", "utf-8") as diff_fh:
@@ -66,24 +145,79 @@ class TestPort(base.Port):
(expected_contents, actual_contents))
return diffed
+ def expected_checksum(self, test):
+ test = self.relative_test_filename(test)
+ return self._tests[test].expected_checksum
+
+ def expected_image(self, test):
+ test = self.relative_test_filename(test)
+ return self._tests[test].expected_image
+
+ def expected_text(self, test):
+ test = self.relative_test_filename(test)
+ text = self._tests[test].expected_text
+ if not text:
+ text = ''
+ return text
+
+ def tests(self, paths):
+ # Test the idea of port-specific overrides for test lists. Also
+ # keep in memory to speed up the test harness.
+ if not paths:
+ paths = ['*']
+
+ matched_tests = []
+ for p in paths:
+ if self.path_isdir(p):
+ matched_tests.extend(fnmatch.filter(self._tests.keys(), p + '*'))
+ else:
+ matched_tests.extend(fnmatch.filter(self._tests.keys(), p))
+ layout_tests_dir = self.layout_tests_dir()
+ return set([os.path.join(layout_tests_dir, p) for p in matched_tests])
+
+ def path_exists(self, path):
+ # used by test_expectations.py and printing.py
+ rpath = self.relative_test_filename(path)
+ if rpath in self._tests:
+ return True
+ if self.path_isdir(rpath):
+ return True
+ if rpath.endswith('-expected.txt'):
+ test = rpath.replace('-expected.txt', '.html')
+ return (test in self._tests and
+ self._tests[test].expected_text)
+ if rpath.endswith('-expected.checksum'):
+ test = rpath.replace('-expected.checksum', '.html')
+ return (test in self._tests and
+ self._tests[test].expected_checksum)
+ if rpath.endswith('-expected.png'):
+ test = rpath.replace('-expected.png', '.html')
+ return (test in self._tests and
+ self._tests[test].expected_image)
+ return False
+
def layout_tests_dir(self):
return self.path_from_webkit_base('WebKitTools', 'Scripts',
'webkitpy', 'layout_tests', 'data')
+ def path_isdir(self, path):
+ # Used by test_expectations.py
+ #
+ # We assume that a path is a directory if we have any tests that
+ # whose prefix matches the path plus a directory modifier.
+ if path[-1] != '/':
+ path += '/'
+ return any([t.startswith(path) for t in self._tests.keys()])
+
+ def test_dirs(self):
+ return ['passes', 'failures']
+
def name(self):
return self._name
def options(self):
return self._options
- def skipped_layout_tests(self):
- return []
-
- def path_to_test_expectations_file(self):
- return self.path_from_webkit_base('WebKitTools', 'Scripts',
- 'webkitpy', 'layout_tests', 'data', 'platform', 'test',
- 'test_expectations.txt')
-
def _path_to_wdiff(self):
return None
@@ -93,9 +227,6 @@ class TestPort(base.Port):
def setup_test_run(self):
pass
- def show_results_html_file(self, filename):
- pass
-
def create_driver(self, image_path, options):
return TestDriver(self, image_path, options, executive=None)
@@ -116,9 +247,21 @@ class TestPort(base.Port):
Basically this string should contain the equivalent of a
test_expectations file. See test_expectations.py for more details."""
- expectations_path = self.path_to_test_expectations_file()
- with codecs.open(expectations_path, "r", "utf-8") as file:
- return file.read()
+ return """
+WONTFIX : failures/expected/checksum.html = IMAGE
+WONTFIX : failures/expected/crash.html = CRASH
+// This one actually passes because the checksums will match.
+WONTFIX : failures/expected/image.html = PASS
+WONTFIX : failures/expected/image_checksum.html = IMAGE
+WONTFIX : failures/expected/missing_check.html = MISSING PASS
+WONTFIX : failures/expected/missing_image.html = MISSING PASS
+WONTFIX : failures/expected/missing_text.html = MISSING PASS
+WONTFIX : failures/expected/text.html = TEXT
+WONTFIX : failures/expected/timeout.html = TIMEOUT
+WONTFIX SKIP : failures/expected/hang.html = TIMEOUT
+WONTFIX SKIP : failures/expected/keyboard.html = CRASH
+WONTFIX SKIP : failures/expected/exception.html = CRASH
+"""
def test_base_platform_names(self):
return ('mac', 'win')
@@ -150,68 +293,21 @@ class TestDriver(base.Driver):
return True
def run_test(self, uri, timeoutms, image_hash):
- basename = uri[(uri.rfind("/") + 1):uri.rfind(".html")]
-
- if 'error' in basename:
- error = basename + "_error\n"
- else:
- error = ''
- checksum = None
- # There are four currently supported types of tests: text, image,
- # image hash (checksum), and stderr output. The fake output
- # is the basename of the file + "-" plus the type of test output
- # (or a blank string for stderr).
- #
- # If 'image' or 'check' appears in the basename, we assume this is
- # simulating a pixel test.
- #
- # If 'failures' appears in the URI, then we assume this test should
- # fail. Which type of failures are determined by which strings appear
- # in the basename of the test. For failures that produce outputs,
- # we change the fake output to basename + "_failed-".
- #
- # The fact that each test produces (more or less) unique output data
- # will allow us to see if any results get crossed by the rest of the
- # program.
- if 'failures' in uri:
- if 'keyboard' in basename:
- raise KeyboardInterrupt
- if 'exception' in basename:
- raise ValueError('exception from ' + basename)
-
- crash = 'crash' in basename
- timeout = 'timeout' in basename or 'hang' in basename
- timeout = 'timeout' in basename
- if 'text' in basename:
- output = basename + '_failed-txt\n'
- else:
- output = basename + '-txt\n'
- if self._port.options().pixel_tests:
- if ('image' in basename or 'check' in basename):
- checksum = basename + "-checksum\n"
-
- if 'image' in basename:
- with open(self._image_path, "w") as f:
- f.write(basename + "_failed-png\n")
- elif 'check' in basename:
- with open(self._image_path, "w") as f:
- f.write(basename + "-png\n")
- if 'checksum' in basename:
- checksum = basename + "_failed-checksum\n"
-
- if 'hang' in basename:
- time.sleep((float(timeoutms) * 4) / 1000.0)
- else:
- crash = False
- timeout = False
- output = basename + '-txt\n'
- if self._options.pixel_tests and (
- 'image' in basename or 'check' in basename):
- checksum = basename + '-checksum\n'
- with open(self._image_path, "w") as f:
- f.write(basename + "-png")
-
- return (crash, timeout, checksum, output, error)
+ test_name = self._port.uri_to_test_name(uri)
+ test = self._port._tests[test_name]
+ if test.keyboard:
+ raise KeyboardInterrupt
+ if test.exception:
+ raise ValueError('exception from ' + test_name)
+ if test.hang:
+ time.sleep((float(timeoutms) * 4) / 1000.0)
+
+ if self._port.options().pixel_tests and test.actual_image:
+ with open(self._image_path, 'w') as file:
+ file.write(test.actual_image)
+
+ return (test.crash, test.timeout, test.actual_checksum,
+ test.actual_text, test.error)
def start(self):
pass
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files.py
index 8f79505..3fa0fb3 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files.py
@@ -27,11 +27,11 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""This module is used to find all of the layout test files used by Chromium
-(across all platforms). It exposes one public function - GatherTestFiles() -
+"""This module is used to find all of the layout test files used by
+run-webkit-tests. It exposes one public function - find() -
which takes an optional list of paths. If a list is passed in, the returned
list of test files is constrained to those found under the paths passed in,
-i.e. calling GatherTestFiles(["LayoutTests/fast"]) will only return files
+i.e. calling find(["LayoutTests/fast"]) will only return files
under that directory."""
import glob
@@ -51,12 +51,12 @@ _supported_file_extensions = set(['.html', '.shtml', '.xml', '.xhtml', '.xhtmlmp
_skipped_directories = set(['.svn', '_svn', 'resources', 'script-tests'])
-def gather_test_files(port, paths):
- """Generate a set of test files and return them.
+def find(port, paths):
+ """Finds the set of tests under port.layout_tests_dir().
Args:
- paths: a list of command line paths relative to the webkit/tests
- directory. glob patterns are ok.
+ paths: a list of command line paths relative to the layout_tests_dir()
+ to limit the search to. glob patterns are ok.
"""
gather_start_time = time.time()
paths_to_walk = set()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files_unittest.py
new file mode 100644
index 0000000..c37eb92
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files_unittest.py
@@ -0,0 +1,68 @@
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os
+import unittest
+
+import base
+import test_files
+
+
+class TestFilesTest(unittest.TestCase):
+ def test_find_no_paths_specified(self):
+ port = base.Port()
+ layout_tests_dir = port.layout_tests_dir()
+ port.layout_tests_dir = lambda: os.path.join(layout_tests_dir,
+ 'fast', 'html')
+ tests = test_files.find(port, [])
+ self.assertNotEqual(tests, 0)
+
+ def test_find_one_test(self):
+ port = base.Port()
+ # This is just a test picked at random but known to exist.
+ tests = test_files.find(port, ['fast/html/keygen.html'])
+ self.assertEqual(len(tests), 1)
+
+ def test_find_glob(self):
+ port = base.Port()
+ tests = test_files.find(port, ['fast/html/key*'])
+ self.assertEqual(len(tests), 1)
+
+ def test_find_with_skipped_directories(self):
+ port = base.Port()
+ tests = port.tests('userscripts')
+ self.assertTrue('userscripts/resources/frame1.html' not in tests)
+
+ def test_find_with_skipped_directories_2(self):
+ port = base.Port()
+ tests = test_files.find(port, ['userscripts/resources'])
+ self.assertEqual(tests, set([]))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py
index 88c9bdf..ed19c09 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py
@@ -58,16 +58,16 @@ _log = logging.getLogger("webkitpy.layout_tests.port.webkit")
class WebKitPort(base.Port):
"""WebKit implementation of the Port class."""
- def __init__(self, port_name=None, options=None, **kwargs):
- base.Port.__init__(self, port_name, options, **kwargs)
+ 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
# build machines.
- if options and (not hasattr(options, "pixel_tests") or
- options.pixel_tests is None):
- options.pixel_tests = False
+ if self._options and (not hasattr(self._options, "pixel_tests") or
+ self._options.pixel_tests is None):
+ self._options.pixel_tests = False
def baseline_path(self):
return self._webkit_baseline_path(self._name)
@@ -84,10 +84,14 @@ class WebKitPort(base.Port):
return ''
def _build_driver(self):
- return not self._executive.run_command([
+ exit_code = self._executive.run_command([
self.script_path("build-dumprendertree"),
self.flag_from_configuration(self._options.configuration),
], return_exit_code=True)
+ if exit_code != 0:
+ _log.error("Failed to build DumpRenderTree")
+ return False
+ return True
def _check_driver(self):
driver_path = self._path_to_driver()
@@ -119,7 +123,7 @@ class WebKitPort(base.Port):
return False
return True
- def diff_image(self, expected_filename, actual_filename,
+ def diff_image(self, expected_contents, actual_contents,
diff_filename=None, tolerance=0.1):
"""Return True if the two files are different. Also write a delta
image of the two images into |diff_filename| if it is not None."""
@@ -128,31 +132,24 @@ class WebKitPort(base.Port):
# parameter, or make it go away and always use exact matches.
# Handle the case where the test didn't actually generate an image.
- actual_length = os.stat(actual_filename).st_size
- if actual_length == 0:
- if diff_filename:
- shutil.copyfile(actual_filename, expected_filename)
+ if not actual_contents:
return True
- sp = self._diff_image_request(expected_filename, actual_filename, tolerance)
- return self._diff_image_reply(sp, expected_filename, diff_filename)
+ sp = self._diff_image_request(expected_contents, actual_contents,
+ tolerance)
+ return self._diff_image_reply(sp, diff_filename)
- def _diff_image_request(self, expected_filename, actual_filename, tolerance):
+ def _diff_image_request(self, expected_contents, actual_contents, tolerance):
command = [self._path_to_image_diff(), '--tolerance', str(tolerance)]
sp = server_process.ServerProcess(self, 'ImageDiff', command)
- actual_length = os.stat(actual_filename).st_size
- with open(actual_filename) as file:
- actual_file = file.read()
- expected_length = os.stat(expected_filename).st_size
- with open(expected_filename) as file:
- expected_file = file.read()
sp.write('Content-Length: %d\n%sContent-Length: %d\n%s' %
- (actual_length, actual_file, expected_length, expected_file))
+ (len(actual_contents), actual_contents,
+ len(expected_contents), expected_contents))
return sp
- def _diff_image_reply(self, sp, expected_filename, diff_filename):
+ def _diff_image_reply(self, sp, diff_filename):
timeout = 2.0
deadline = time.time() + timeout
output = sp.read_line(timeout)
@@ -178,7 +175,7 @@ class WebKitPort(base.Port):
with open(diff_filename, 'w') as file:
file.write(output)
elif sp.timed_out:
- _log.error("ImageDiff timed out on %s" % expected_filename)
+ _log.error("ImageDiff timed out")
elif sp.crashed:
_log.error("ImageDiff crashed")
sp.stop()
@@ -193,11 +190,6 @@ class WebKitPort(base.Port):
# This port doesn't require any specific configuration.
pass
- def show_results_html_file(self, results_filename):
- uri = self.filename_to_uri(results_filename)
- # FIXME: We should open results in the version of WebKit we built.
- webbrowser.open(uri, new=1)
-
def create_driver(self, image_path, options):
return WebKitDriver(self, image_path, options,
executive=self._executive)
@@ -255,7 +247,7 @@ class WebKitPort(base.Port):
"MathMLElement": ["mathml"],
"GraphicsLayer": ["compositing"],
"WebCoreHas3DRendering": ["animations/3d", "transforms/3d"],
- "WebGLShader": ["fast/canvas/webgl"],
+ "WebGLShader": ["fast/canvas/webgl", "compositing/webgl", "http/tests/canvas/webgl"],
"WMLElement": ["http/tests/wml", "fast/wml", "wml"],
"parseWCSSInputProperty": ["fast/wcss"],
"isXHTMLMPDocument": ["fast/xhtmlmp"],
@@ -418,12 +410,17 @@ class WebKitDriver(base.Driver):
def _driver_args(self):
driver_args = []
+
if self._image_path:
driver_args.append('--pixel-tests')
- # These are used by the Chromium DRT port
if self._options.use_drt:
- driver_args.append('--test-shell')
+ if self._options.accelerated_compositing:
+ driver_args.append('--enable-accelerated-compositing')
+
+ if self._options.accelerated_2d_canvas:
+ driver_args.append('--enable-accelerated-2d-canvas')
+
return driver_args
def start(self):
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py
index fbfadc3..7b68310 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py
@@ -53,7 +53,7 @@ class WebKitPortTest(unittest.TestCase):
def test_skipped_directories_for_symbols(self):
supported_symbols = ["GraphicsLayer", "WebCoreHas3DRendering", "isXHTMLMPDocument", "fooSymbol"]
- expected_directories = set(["mathml", "fast/canvas/webgl", "http/tests/wml", "fast/wml", "wml", "fast/wcss"])
+ expected_directories = set(["mathml", "fast/canvas/webgl", "compositing/webgl", "http/tests/canvas/webgl", "http/tests/wml", "fast/wml", "wml", "fast/wcss"])
result_directories = set(TestWebKitPort(supported_symbols, None)._skipped_tests_for_unsupported_features())
self.assertEqual(result_directories, expected_directories)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/win.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/win.py
index e05a69d..9e30155 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/win.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/win.py
@@ -39,10 +39,9 @@ _log = logging.getLogger("webkitpy.layout_tests.port.win")
class WinPort(WebKitPort):
"""WebKit Win implementation of the Port class."""
- def __init__(self, port_name=None, options=None):
- if port_name is None:
- port_name = 'win'
- WebKitPort.__init__(self, port_name, options)
+ def __init__(self, **kwargs):
+ kwargs.setdefault('port_name', 'win')
+ WebKitPort.__init__(self, **kwargs)
def baseline_search_path(self):
# Based on code from old-run-webkit-tests expectedDirectoryForTest()
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 3a9f923..e57ceb2 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
@@ -55,9 +55,9 @@ import sys
import tempfile
import time
import urllib
-import webbrowser
import zipfile
+from webkitpy.common.system import user
from webkitpy.common.system.executive import run_command, ScriptError
import webkitpy.common.checkout.scm as scm
@@ -518,8 +518,15 @@ class Rebaseliner(object):
fallback_fullpath = os.path.normpath(
os.path.join(fallback_dir, fallback_file))
if fallback_fullpath.lower() != baseline_path.lower():
- if not self._diff_baselines(new_baseline,
- fallback_fullpath):
+ with codecs.open(new_baseline, "r",
+ None) as file_handle1:
+ new_output = file_handle1.read()
+ with codecs.open(fallback_fullpath, "r",
+ None) as file_handle2:
+ fallback_output = file_handle2.read()
+ is_image = baseline_path.lower().endswith('.png')
+ if not self._diff_baselines(new_output, fallback_output,
+ is_image):
_log.info(' Found same baseline at %s',
fallback_fullpath)
return True
@@ -528,31 +535,20 @@ class Rebaseliner(object):
return False
- def _diff_baselines(self, file1, file2):
+ def _diff_baselines(self, output1, output2, is_image):
"""Check whether two baselines are different.
Args:
- file1, file2: full paths of the baselines to compare.
+ output1, output2: contents of the baselines to compare.
Returns:
True if two files are different or have different extensions.
False otherwise.
"""
- ext1 = os.path.splitext(file1)[1].upper()
- ext2 = os.path.splitext(file2)[1].upper()
- if ext1 != ext2:
- _log.warn('Files to compare have different ext. '
- 'File1: %s; File2: %s', file1, file2)
- return True
-
- if ext1 == '.PNG':
- return self._port.diff_image(file1, file2)
+ if is_image:
+ return self._port.diff_image(output1, output2)
else:
- with codecs.open(file1, "r", "utf8") as file_handle1:
- output1 = file_handle1.read()
- with codecs.open(file2, "r", "utf8") as file_handle2:
- output2 = file_handle2.read()
return self._port.compare_text(output1, output2)
def _delete_baseline(self, filename):
@@ -593,7 +589,7 @@ class Rebaseliner(object):
# Or is new_expectations always a byte array?
with open(path, "w") as file:
file.write(new_expectations)
- self._scm.add(path)
+ # self._scm.add(path)
else:
_log.info('No test was rebaselined so nothing to remove.')
@@ -737,10 +733,7 @@ class HtmlGenerator(object):
"""Launch the rebaselining html in brwoser."""
_log.info('Launching html: "%s"', self._html_file)
-
- html_uri = self._target_port.filename_to_uri(self._html_file)
- webbrowser.open(html_uri, 1)
-
+ user.User().open_url(self._html_file)
_log.info('Html launched.')
def _generate_baseline_links(self, test_basename, suffix, platform):
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 dbb2b91..9ba3d6b 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
@@ -103,15 +103,20 @@ class TestRebaseliner(unittest.TestCase):
def test_diff_baselines_txt(self):
rebaseliner = self.make_rebaseliner()
- path = os.path.join(rebaseliner._port.layout_tests_dir(),
- "passes", "text-expected.txt")
- self.assertFalse(rebaseliner._diff_baselines(path, path))
+ output = rebaseliner._port.expected_text(
+ os.path.join(rebaseliner._port.layout_tests_dir(),
+ 'passes/text.html'))
+ self.assertFalse(rebaseliner._diff_baselines(output, output,
+ is_image=False))
def test_diff_baselines_png(self):
+ return
rebaseliner = self.make_rebaseliner()
- path = os.path.join(rebaseliner._port.layout_tests_dir(),
- "passes", "image-expected.png")
- self.assertFalse(rebaseliner._diff_baselines(path, path))
+ image = rebaseliner._port.expected_image(
+ os.path.join(rebaseliner._port.layout_tests_dir(),
+ 'passes/image.html'))
+ self.assertFalse(rebaseliner._diff_baselines(image, image,
+ is_image=True))
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
index 14d4f0e..e9c6d2c 100755
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -68,12 +68,12 @@ from layout_package import json_layout_results_generator
from layout_package import printing
from layout_package import test_expectations
from layout_package import test_failures
-from layout_package import test_files
from layout_package import test_results_uploader
from test_types import image_diff
from test_types import text_diff
from test_types import test_type_base
+from webkitpy.common.system import user
from webkitpy.thirdparty import simplejson
import port
@@ -96,28 +96,21 @@ class TestInfo:
timeout: Timeout for running the test in TestShell.
"""
self.filename = filename
+ self._port = port
self.uri = port.filename_to_uri(filename)
self.timeout = timeout
- # FIXME: Confusing that the file is .checksum and we call it "hash"
- self._expected_hash_path = port.expected_filename(filename, '.checksum')
- self._have_read_expected_hash = False
- self._image_hash = None
-
- def _read_image_hash(self):
- if not os.path.exists(self._expected_hash_path):
- return None
-
- with codecs.open(self._expected_hash_path, "r", "ascii") as hash_file:
- return hash_file.read()
+ self._image_checksum = -1
def image_hash(self):
# Read the image_hash lazily to reduce startup time.
# This class is accessed across threads, but only one thread should
# ever be dealing with any given TestInfo so no locking is needed.
- if not self._have_read_expected_hash:
- self._have_read_expected_hash = True
- self._image_hash = self._read_image_hash()
- return self._image_hash
+ #
+ # Note that we use -1 to indicate that we haven't read the value,
+ # because expected_checksum() returns a string or None.
+ if self._image_checksum == -1:
+ self._image_checksum = self._port.expected_checksum(self.filename)
+ return self._image_checksum
class ResultSummary(object):
@@ -292,7 +285,7 @@ class TestRunner:
paths += last_unexpected_results
if self._options.test_list:
paths += read_test_files(self._options.test_list)
- self._test_files = test_files.gather_test_files(self._port, paths)
+ self._test_files = self._port.tests(paths)
def lint(self):
# Creating the expecations for each platform/configuration pair does
@@ -321,7 +314,7 @@ class TestRunner:
self._expectations = test_expectations.TestExpectations(
self._port, test_files, expectations_str, test_platform_name,
is_debug_mode, self._options.lint_test_files,
- tests_are_present=True, overrides=overrides_str)
+ overrides=overrides_str)
return self._expectations
except SyntaxError, err:
if self._options.lint_test_files:
@@ -865,7 +858,7 @@ class TestRunner:
self._printer.print_update("Clobbering old results in %s" %
self._options.results_directory)
layout_tests_dir = self._port.layout_tests_dir()
- possible_dirs = os.listdir(layout_tests_dir)
+ possible_dirs = self._port.test_dirs()
for dirname in possible_dirs:
if os.path.isdir(os.path.join(layout_tests_dir, dirname)):
shutil.rmtree(os.path.join(self._options.results_directory,
@@ -1408,6 +1401,7 @@ def run(port, options, args, regular_output=sys.stderr,
printer.print_update("Checking build ...")
if not port.check_build(test_runner.needs_http()):
+ _log.error("Build check failed")
return -1
result_summary = test_runner.set_up_run()
@@ -1515,6 +1509,20 @@ def parse_args(args=None):
optparse.make_option("--use-drt", action="store_true",
default=False,
help="Use DumpRenderTree instead of test_shell"),
+ optparse.make_option("--accelerated-compositing",
+ action="store_true",
+ help="Use hardware-accelated compositing for rendering"),
+ optparse.make_option("--no-accelerated-compositing",
+ action="store_false",
+ dest="accelerated_compositing",
+ help="Don't use hardware-accelerated compositing for rendering"),
+ optparse.make_option("--accelerated-2d-canvas",
+ action="store_true",
+ help="Use hardware-accelerated 2D Canvas calls"),
+ optparse.make_option("--no-accelerated-2d-canvas",
+ action="store_false",
+ dest="accelerated_2d_canvas",
+ help="Don't use hardware-accelerated 2D Canvas calls"),
]
# Missing Mac-specific old-run-webkit-tests options:
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
index aa96962..6fe99d6 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
@@ -42,6 +42,7 @@ import unittest
from webkitpy.common import array_stream
from webkitpy.common.system import outputcapture
+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
@@ -49,6 +50,14 @@ from webkitpy.layout_tests.layout_package import dump_render_tree_thread
from webkitpy.thirdparty.mock import Mock
+class MockUser():
+ def __init__(self):
+ self.url = None
+
+ def open_url(self, url):
+ self.url = url
+
+
def passing_run(args=[], port_obj=None, record_results=False,
tests_included=False):
new_args = ['--print', 'nothing']
@@ -65,7 +74,8 @@ def passing_run(args=[], port_obj=None, record_results=False,
'failures/expected/*'])
options, parsed_args = run_webkit_tests.parse_args(new_args)
if port_obj is None:
- port_obj = port.get(options.platform, options)
+ 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
@@ -77,20 +87,31 @@ def logging_run(args=[], tests_included=False):
new_args.extend(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)
- port_obj = port.get(options.platform, options)
+ user = MockUser()
+ 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,
buildbot_output=buildbot_output,
regular_output=regular_output)
- return (res, buildbot_output, regular_output)
+ return (res, buildbot_output, regular_output, user)
class MainTest(unittest.TestCase):
+ def test_accelerated_compositing(self):
+ # This just tests that we recognize the command line args
+ self.assertTrue(passing_run(['--accelerated-compositing']))
+ self.assertTrue(passing_run(['--no-accelerated-compositing']))
+
+ def test_accelerated_2d_canvas(self):
+ # This just tests that we recognize the command line args
+ self.assertTrue(passing_run(['--accelerated-2d-canvas']))
+ self.assertTrue(passing_run(['--no-accelerated-2d-canvas']))
+
def test_basic(self):
self.assertTrue(passing_run())
@@ -99,13 +120,13 @@ class MainTest(unittest.TestCase):
self.assertTrue(passing_run(['--batch-size', '2']))
def test_child_process_1(self):
- (res, buildbot_output, regular_output) = logging_run(
+ (res, buildbot_output, regular_output, user) = logging_run(
['--print', 'config', '--child-processes', '1'])
self.assertTrue('Running one DumpRenderTree\n'
in regular_output.get())
def test_child_processes_2(self):
- (res, buildbot_output, regular_output) = logging_run(
+ (res, buildbot_output, regular_output, user) = logging_run(
['--print', 'config', '--child-processes', '2'])
self.assertTrue('Running 2 DumpRenderTrees in parallel\n'
in regular_output.get())
@@ -119,15 +140,15 @@ class MainTest(unittest.TestCase):
self.assertTrue(passing_run(['--full-results-html']))
def test_help_printing(self):
- res, out, err = logging_run(['--help-printing'])
+ res, out, err, user = logging_run(['--help-printing'])
self.assertEqual(res, 0)
self.assertTrue(out.empty())
self.assertFalse(err.empty())
def test_hung_thread(self):
- res, out, err = logging_run(['--run-singly', '--time-out-ms=50',
- 'failures/expected/hang.html'],
- tests_included=True)
+ res, out, err, user = logging_run(['--run-singly', '--time-out-ms=50',
+ 'failures/expected/hang.html'],
+ tests_included=True)
self.assertEqual(res, 0)
self.assertFalse(out.empty())
self.assertFalse(err.empty())
@@ -140,26 +161,27 @@ class MainTest(unittest.TestCase):
def test_last_results(self):
passing_run(['--clobber-old-results'], record_results=True)
- (res, buildbot_output, regular_output) = logging_run(
+ (res, buildbot_output, regular_output, user) = logging_run(
['--print-last-failures'])
self.assertEqual(regular_output.get(), ['\n\n'])
self.assertEqual(buildbot_output.get(), [])
def test_lint_test_files(self):
# FIXME: add errors?
- res, out, err = logging_run(['--lint-test-files'], tests_included=True)
+ res, out, err, user = logging_run(['--lint-test-files'],
+ tests_included=True)
self.assertEqual(res, 0)
self.assertTrue(out.empty())
self.assertTrue(any(['lint succeeded' in msg for msg in err.get()]))
def test_no_tests_found(self):
- res, out, err = logging_run(['resources'], tests_included=True)
+ res, out, err, user = logging_run(['resources'], tests_included=True)
self.assertEqual(res, -1)
self.assertTrue(out.empty())
self.assertTrue('No tests to run.\n' in err.get())
def test_no_tests_found_2(self):
- res, out, err = logging_run(['foo'], tests_included=True)
+ res, out, err, user = logging_run(['foo'], tests_included=True)
self.assertEqual(res, -1)
self.assertTrue(out.empty())
self.assertTrue('No tests to run.\n' in err.get())
@@ -196,17 +218,19 @@ class MainTest(unittest.TestCase):
self.assertTrue(passing_run(['--test-list=%s' % filename],
tests_included=True))
os.remove(filename)
- res, out, err = logging_run(['--test-list=%s' % filename],
- tests_included=True)
+ res, out, err, user = logging_run(['--test-list=%s' % filename],
+ tests_included=True)
self.assertEqual(res, -1)
self.assertFalse(err.empty())
def test_unexpected_failures(self):
# Run tests including the unexpected failures.
- res, out, err = logging_run(tests_included=True)
+ self._url_opened = None
+ res, out, err, user = logging_run(tests_included=True)
self.assertEqual(res, 1)
self.assertFalse(out.empty())
self.assertFalse(err.empty())
+ self.assertEqual(user.url, '/tmp/layout-test-results/results.html')
def _mocked_open(original_open, file_list):
@@ -269,6 +293,7 @@ class RebaselineTest(unittest.TestCase):
finally:
codecs.open = original_open
+
class TestRunnerTest(unittest.TestCase):
def test_results_html(self):
mock_port = Mock()
@@ -306,11 +331,8 @@ class DryrunTest(unittest.TestCase):
'fast/html']))
def test_test(self):
- res, out, err = logging_run(['--platform', 'dryrun-test',
- '--pixel-tests'])
- self.assertEqual(res, 2)
- self.assertFalse(out.empty())
- self.assertFalse(err.empty())
+ self.assertTrue(passing_run(['--platform', 'dryrun-test',
+ '--pixel-tests']))
class TestThread(dump_render_tree_thread.WatchableThread):
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
index 879646c..1ad0fe6 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
@@ -103,7 +103,11 @@ class ImageDiff(test_type_base.TestTypeBase):
expected_filename = self.output_filename(filename,
self.FILENAME_SUFFIX_EXPECTED + '.png')
- result = port.diff_image(expected_filename, actual_filename,
+ expected_image = port.expected_image(filename)
+ with codecs.open(actual_filename, 'r', None) as file:
+ actual_image = file.read()
+
+ result = port.diff_image(expected_image, actual_image,
diff_filename)
return result
@@ -124,19 +128,12 @@ class ImageDiff(test_type_base.TestTypeBase):
return failures
# Compare hashes.
- expected_hash_file = self._port.expected_filename(filename,
- '.checksum')
- expected_png_file = self._port.expected_filename(filename, '.png')
-
- # FIXME: We repeat this pattern often, we should share code.
- expected_hash = ''
- if os.path.exists(expected_hash_file):
- with codecs.open(expected_hash_file, "r", "ascii") as file:
- expected_hash = file.read()
+ expected_hash = self._port.expected_checksum(filename)
+ expected_png = self._port.expected_image(filename)
- if not os.path.isfile(expected_png_file):
+ if not expected_png:
# Report a missing expected PNG file.
- self.write_output_files(port, filename, '.checksum',
+ self.write_output_files(filename, '.checksum',
test_args.hash, expected_hash,
encoding="ascii",
print_text_diffs=False)
@@ -147,17 +144,21 @@ class ImageDiff(test_type_base.TestTypeBase):
# Hash matched (no diff needed, okay to return).
return failures
- self.write_output_files(port, filename, '.checksum',
+ self.write_output_files(filename, '.checksum',
test_args.hash, expected_hash,
encoding="ascii",
print_text_diffs=False)
+
+ # FIXME: combine next two lines
self._copy_output_png(filename, test_args.png_path, '-actual.png')
- self._copy_output_png(filename, expected_png_file, '-expected.png')
+ self.write_output_files(filename, '.png', output=None,
+ expected=expected_png,
+ encoding=None, print_text_diffs=False)
# Even though we only use the result in one codepath below but we
# still need to call CreateImageDiff for other codepaths.
images_are_different = self._create_image_diff(port, filename, configuration)
- if expected_hash == '':
+ if not expected_hash:
failures.append(test_failures.FailureMissingImageHash())
elif test_args.hash != expected_hash:
if images_are_different:
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
index 753dbee..3a6e92b 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
@@ -120,7 +120,7 @@ class TestTypeBase(object):
output_path = self._port.expected_filename(filename, modifier)
_log.debug('resetting baseline result "%s"' % output_path)
- self._write_into_file_at_path(output_path, data, encoding)
+ self._port.update_baseline(output_path, data, encoding)
def output_filename(self, filename, modifier):
"""Returns a filename inside the output dir that contains modifier.
@@ -164,7 +164,7 @@ class TestTypeBase(object):
with codecs.open(file_path, "w", encoding=encoding) as file:
file.write(contents)
- def write_output_files(self, port, filename, file_type,
+ def write_output_files(self, filename, file_type,
output, expected, encoding,
print_text_diffs=False):
"""Writes the test output, the expected output and optionally the diff
@@ -201,16 +201,16 @@ class TestTypeBase(object):
# Note: We pass encoding=None for all diff writes, as we treat diff
# output as binary. Diff output may contain multiple files in
# conflicting encodings.
- diff = port.diff_text(expected, output, expected_filename, actual_filename)
+ diff = self._port.diff_text(expected, output, expected_filename, actual_filename)
diff_filename = self.output_filename(filename, self.FILENAME_SUFFIX_DIFF + file_type)
self._write_into_file_at_path(diff_filename, diff, encoding=None)
# Shell out to wdiff to get colored inline diffs.
- wdiff = port.wdiff_text(expected_filename, actual_filename)
+ wdiff = self._port.wdiff_text(expected_filename, actual_filename)
wdiff_filename = self.output_filename(filename, self.FILENAME_SUFFIX_WDIFF)
self._write_into_file_at_path(wdiff_filename, wdiff, encoding=None)
# Use WebKit's PrettyPatch.rb to get an HTML diff.
- pretty_patch = port.pretty_patch_text(diff_filename)
+ pretty_patch = self._port.pretty_patch_text(diff_filename)
pretty_patch_filename = self.output_filename(filename, self.FILENAME_SUFFIX_PRETTY_PATCH)
self._write_into_file_at_path(pretty_patch_filename, pretty_patch, encoding=None)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
index 50a9995..b1f621e 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
@@ -59,24 +59,7 @@ class TestTextDiff(test_type_base.TestTypeBase):
"""Given the filename of the test, read the expected output from a file
and normalize the text. Returns a string with the expected text, or ''
if the expected output file was not found."""
- # Read the port-specific expected text.
- expected_filename = self._port.expected_filename(filename, '.txt')
- return self._get_normalized_text(expected_filename)
-
- def _get_normalized_text(self, filename):
- # FIXME: We repeat this pattern often, we should share code.
- if not os.path.exists(filename):
- return ''
-
- # NOTE: -expected.txt files are ALWAYS utf-8. However,
- # we do not decode the output from DRT, so we should not
- # decode the -expected.txt values either to allow comparisons.
- with codecs.open(filename, "r", encoding=None) as file:
- text = file.read()
- # We could assert that the text is valid utf-8.
-
- # Normalize line endings
- return text.strip("\r\n").replace("\r\n", "\n") + "\n"
+ return self._port.expected_text(filename)
def compare_output(self, port, filename, output, test_args, configuration):
"""Implementation of CompareOutput that checks the output text against
@@ -99,7 +82,7 @@ class TestTextDiff(test_type_base.TestTypeBase):
# Write output files for new tests, too.
if port.compare_text(output, expected):
# Text doesn't match, write output files.
- self.write_output_files(port, filename, ".txt", output,
+ self.write_output_files(filename, ".txt", output,
expected, encoding=None,
print_text_diffs=True)
diff --git a/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations.py b/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations.py
index ddc3983..d2d67f3 100644
--- a/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations.py
+++ b/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations.py
@@ -93,8 +93,7 @@ class TestExpectationsChecker(object):
expectations = test_expectations.TestExpectationsFile(
port=self._port_obj, expectations=expectations_str, full_test_list=tests,
test_platform_name=self._port_to_check, is_debug_mode=False,
- is_lint_mode=True, suppress_errors=False, tests_are_present=True,
- overrides=overrides)
+ is_lint_mode=True, suppress_errors=False, overrides=overrides)
except SyntaxError, error:
errors = str(error).splitlines()
diff --git a/WebKitTools/Scripts/webkitpy/test/main.py b/WebKitTools/Scripts/webkitpy/test/main.py
index daf255f..9351768 100644
--- a/WebKitTools/Scripts/webkitpy/test/main.py
+++ b/WebKitTools/Scripts/webkitpy/test/main.py
@@ -78,7 +78,7 @@ class Tester(object):
return modules
- def run_tests(self, sys_argv):
+ def run_tests(self, sys_argv, external_package_paths=None):
"""Run the unit tests in all *_unittest.py modules in webkitpy.
This method excludes "webkitpy.common.checkout.scm_unittest" unless
@@ -88,6 +88,11 @@ class Tester(object):
sys_argv: A reference to sys.argv.
"""
+ if external_package_paths is None:
+ external_package_paths = []
+ else:
+ sys.path.extend(set(os.path.dirname(path) for path in external_package_paths))
+
if len(sys_argv) > 1 and not sys_argv[-1].startswith("-"):
# Then explicit modules or test names were provided, which
# the unittest module is equipped to handle.
@@ -97,9 +102,10 @@ class Tester(object):
# Otherwise, auto-detect all unit tests.
webkitpy_dir = os.path.dirname(webkitpy.__file__)
- unittest_paths = self._find_unittest_files(webkitpy_dir)
- modules = self._modules_from_paths(webkitpy_dir, unittest_paths)
+ modules = []
+ for path in [webkitpy_dir] + external_package_paths:
+ modules.extend(self._modules_from_paths(path, self._find_unittest_files(path)))
modules.sort()
# This is a sanity check to ensure that the unit-test discovery
diff --git a/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask.py b/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask.py
new file mode 100644
index 0000000..a347972
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask.py
@@ -0,0 +1,158 @@
+# 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.
+
+from webkitpy.common.system.executive import ScriptError
+
+
+class CommitQueueTask(object):
+ def __init__(self, tool, commit_queue, patch):
+ self._tool = tool
+ self._commit_queue = commit_queue
+ self._patch = patch
+ self._script_error = None
+
+ def _validate(self):
+ # Bugs might get closed, or patches might be obsoleted or r-'d while the
+ # commit-queue is processing.
+ self._patch = self._tool.bugs.fetch_attachment(self._patch.id())
+ if self._patch.is_obsolete():
+ return False
+ if self._patch.bug().is_closed():
+ return False
+ if not self._patch.committer():
+ return False
+ # Reviewer is not required. Missing reviewers will be caught during
+ # the ChangeLog check during landing.
+ return True
+
+ def _run_command(self, command, success_message, failure_message):
+ try:
+ self._commit_queue.run_webkit_patch(command)
+ self._commit_queue.command_passed(success_message, patch=self._patch)
+ return True
+ except ScriptError, e:
+ self._script_error = e
+ self.failure_status_id = self._commit_queue.command_failed(failure_message, script_error=self._script_error, patch=self._patch)
+ return False
+
+ def _apply(self):
+ return self._run_command([
+ "apply-attachment",
+ "--force-clean",
+ "--non-interactive",
+ "--quiet",
+ self._patch.id(),
+ ],
+ "Applied patch",
+ "Patch does not apply")
+
+ def _build(self):
+ return self._run_command([
+ "build",
+ "--no-clean",
+ "--no-update",
+ "--build",
+ "--build-style=both",
+ "--quiet",
+ ],
+ "Built patch",
+ "Patch does not build")
+
+ def _build_without_patch(self):
+ return self._run_command([
+ "build",
+ "--force-clean",
+ "--no-update",
+ "--build",
+ "--build-style=both",
+ "--quiet",
+ ],
+ "Able to build without patch",
+ "Unable to build without patch")
+
+ def _test(self):
+ return self._run_command([
+ "build-and-test",
+ "--no-clean",
+ "--no-update",
+ # Notice that we don't pass --build, which means we won't build!
+ "--test",
+ "--quiet",
+ "--non-interactive",
+ ],
+ "Passed tests",
+ "Patch does not pass tests")
+
+ def _build_and_test_without_patch(self):
+ return self._run_command([
+ "build-and-test",
+ "--force-clean",
+ "--no-update",
+ "--build",
+ "--test",
+ "--quiet",
+ "--non-interactive",
+ ],
+ "Able to pass tests without patch",
+ "Unable to pass tests without patch (tree is red?)")
+
+ def _land(self):
+ return self._run_command([
+ "land-attachment",
+ "--force-clean",
+ "--ignore-builders",
+ "--quiet",
+ "--non-interactive",
+ "--parent-command=commit-queue",
+ self._patch.id(),
+ ],
+ "Landed patch",
+ "Unable to land patch")
+
+ def run(self):
+ if not self._validate():
+ return False
+ if not self._apply():
+ raise self._script_error
+ if not self._build():
+ if not self._build_without_patch():
+ return False
+ raise self._script_error
+ if not self._patch.is_rollout():
+ if not self._test():
+ if not self._test():
+ if not self._build_and_test_without_patch():
+ return False
+ raise self._script_error
+ # Make sure the patch is still valid before landing (e.g., make sure
+ # no one has set commit-queue- since we started working on the patch.)
+ if not self._validate():
+ return False
+ if not self._land():
+ raise self._script_error
+ return True
diff --git a/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py b/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py
new file mode 100644
index 0000000..8b46146
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py
@@ -0,0 +1,194 @@
+# 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.
+
+from datetime import datetime
+import unittest
+
+from webkitpy.common.system.deprecated_logging import error, log
+from webkitpy.common.system.outputcapture import OutputCapture
+from webkitpy.thirdparty.mock import Mock
+from webkitpy.tool.bot.commitqueuetask import *
+from webkitpy.tool.mocktool import MockTool
+
+
+class MockCommitQueue:
+ def __init__(self, error_plan):
+ self._error_plan = error_plan
+
+ def run_webkit_patch(self, command):
+ log("run_webkit_patch: %s" % command)
+ if self._error_plan:
+ error = self._error_plan.pop(0)
+ if error:
+ raise error
+
+ def command_passed(self, success_message, patch):
+ log("command_passed: success_message='%s' patch='%s'" % (
+ success_message, patch.id()))
+
+ def command_failed(self, failure_message, script_error, patch):
+ log("command_failed: failure_message='%s' script_error='%s' patch='%s'" % (
+ failure_message, script_error, patch.id()))
+ return 3947
+
+
+class CommitQueueTaskTest(unittest.TestCase):
+ def _run_through_task(self, commit_queue, expected_stderr, expected_exception=None):
+ tool = MockTool(log_executive=True)
+ patch = tool.bugs.fetch_attachment(197)
+ task = CommitQueueTask(tool, commit_queue, patch)
+ OutputCapture().assert_outputs(self, task.run, expected_stderr=expected_stderr, expected_exception=expected_exception)
+
+ def test_success_case(self):
+ commit_queue = MockCommitQueue([])
+ expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+command_passed: success_message='Applied patch' patch='197'
+run_webkit_patch: ['build', '--no-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+command_passed: success_message='Built patch' patch='197'
+run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+command_passed: success_message='Passed tests' patch='197'
+run_webkit_patch: ['land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197]
+command_passed: success_message='Landed patch' patch='197'
+"""
+ self._run_through_task(commit_queue, expected_stderr)
+
+ def test_apply_failure(self):
+ commit_queue = MockCommitQueue([
+ ScriptError("MOCK apply failure"),
+ ])
+ expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+command_failed: failure_message='Patch does not apply' script_error='MOCK apply failure' patch='197'
+"""
+ self._run_through_task(commit_queue, expected_stderr, ScriptError)
+
+ def test_build_failure(self):
+ commit_queue = MockCommitQueue([
+ None,
+ ScriptError("MOCK build failure"),
+ ])
+ expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+command_passed: success_message='Applied patch' patch='197'
+run_webkit_patch: ['build', '--no-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+command_failed: failure_message='Patch does not build' script_error='MOCK build failure' patch='197'
+run_webkit_patch: ['build', '--force-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+command_passed: success_message='Able to build without patch' patch='197'
+"""
+ self._run_through_task(commit_queue, expected_stderr, ScriptError)
+
+ def test_red_build_failure(self):
+ commit_queue = MockCommitQueue([
+ None,
+ ScriptError("MOCK build failure"),
+ ScriptError("MOCK clean build failure"),
+ ])
+ expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+command_passed: success_message='Applied patch' patch='197'
+run_webkit_patch: ['build', '--no-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+command_failed: failure_message='Patch does not build' script_error='MOCK build failure' patch='197'
+run_webkit_patch: ['build', '--force-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+command_failed: failure_message='Unable to build without patch' script_error='MOCK clean build failure' patch='197'
+"""
+ self._run_through_task(commit_queue, expected_stderr)
+
+ def test_flaky_test_failure(self):
+ commit_queue = MockCommitQueue([
+ None,
+ None,
+ ScriptError("MOCK tests failure"),
+ ])
+ expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+command_passed: success_message='Applied patch' patch='197'
+run_webkit_patch: ['build', '--no-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+command_passed: success_message='Built patch' patch='197'
+run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+command_failed: failure_message='Patch does not pass tests' script_error='MOCK tests failure' patch='197'
+run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+command_passed: success_message='Passed tests' patch='197'
+run_webkit_patch: ['land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197]
+command_passed: success_message='Landed patch' patch='197'
+"""
+ self._run_through_task(commit_queue, expected_stderr)
+
+ def test_test_failure(self):
+ commit_queue = MockCommitQueue([
+ None,
+ None,
+ ScriptError("MOCK test failure"),
+ ScriptError("MOCK test failure again"),
+ ])
+ expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+command_passed: success_message='Applied patch' patch='197'
+run_webkit_patch: ['build', '--no-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+command_passed: success_message='Built patch' patch='197'
+run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+command_failed: failure_message='Patch does not pass tests' script_error='MOCK test failure' patch='197'
+run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+command_failed: failure_message='Patch does not pass tests' script_error='MOCK test failure again' patch='197'
+run_webkit_patch: ['build-and-test', '--force-clean', '--no-update', '--build', '--test', '--quiet', '--non-interactive']
+command_passed: success_message='Able to pass tests without patch' patch='197'
+"""
+ self._run_through_task(commit_queue, expected_stderr, ScriptError)
+
+ def test_red_test_failure(self):
+ commit_queue = MockCommitQueue([
+ None,
+ None,
+ ScriptError("MOCK test failure"),
+ ScriptError("MOCK test failure again"),
+ ScriptError("MOCK clean test failure"),
+ ])
+ expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+command_passed: success_message='Applied patch' patch='197'
+run_webkit_patch: ['build', '--no-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+command_passed: success_message='Built patch' patch='197'
+run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+command_failed: failure_message='Patch does not pass tests' script_error='MOCK test failure' patch='197'
+run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+command_failed: failure_message='Patch does not pass tests' script_error='MOCK test failure again' patch='197'
+run_webkit_patch: ['build-and-test', '--force-clean', '--no-update', '--build', '--test', '--quiet', '--non-interactive']
+command_failed: failure_message='Unable to pass tests without patch (tree is red?)' script_error='MOCK clean test failure' patch='197'
+"""
+ self._run_through_task(commit_queue, expected_stderr)
+
+ def test_land_failure(self):
+ commit_queue = MockCommitQueue([
+ None,
+ None,
+ None,
+ ScriptError("MOCK land failure"),
+ ])
+ expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+command_passed: success_message='Applied patch' patch='197'
+run_webkit_patch: ['build', '--no-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+command_passed: success_message='Built patch' patch='197'
+run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+command_passed: success_message='Passed tests' patch='197'
+run_webkit_patch: ['land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197]
+command_failed: failure_message='Unable to land patch' script_error='MOCK land failure' patch='197'
+"""
+ self._run_through_task(commit_queue, expected_stderr, ScriptError)
diff --git a/WebKitTools/Scripts/webkitpy/tool/bot/feeders.py b/WebKitTools/Scripts/webkitpy/tool/bot/feeders.py
new file mode 100644
index 0000000..15eaaf3
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/bot/feeders.py
@@ -0,0 +1,73 @@
+# 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.
+
+from webkitpy.common.system.deprecated_logging import log
+from webkitpy.common.net.bugzilla import CommitterValidator
+
+
+class AbstractFeeder(object):
+ def __init__(self, tool):
+ self._tool = tool
+
+ def feed(tool):
+ raise NotImplementedError, "subclasses must implement"
+
+ def update_work_items(self, item_ids):
+ self._tool.status_server.update_work_items(self.queue_name, item_ids)
+ log("Feeding %s items %s" % (self.queue_name, item_ids))
+
+
+class CommitQueueFeeder(AbstractFeeder):
+ queue_name = "commit-queue"
+
+ def __init__(self, tool):
+ AbstractFeeder.__init__(self, tool)
+ self.committer_validator = CommitterValidator(self._tool.bugs)
+
+ def feed(self):
+ patches = self._validate_patches()
+ patches = sorted(patches, self._patch_cmp)
+ patch_ids = [patch.id() for patch in patches]
+ self.update_work_items(patch_ids)
+
+ def _patches_for_bug(self, bug_id):
+ return self._tool.bugs.fetch_bug(bug_id).commit_queued_patches(include_invalid=True)
+
+ def _validate_patches(self):
+ # Not using BugzillaQueries.fetch_patches_from_commit_queue() so we can reject patches with invalid committers/reviewers.
+ bug_ids = self._tool.bugs.queries.fetch_bug_ids_from_commit_queue()
+ all_patches = sum([self._patches_for_bug(bug_id) for bug_id in bug_ids], [])
+ return self.committer_validator.patches_after_rejecting_invalid_commiters_and_reviewers(all_patches)
+
+ def _patch_cmp(self, a, b):
+ # Sort first by is_rollout, then by attach_date.
+ # Reversing the order so that is_rollout is first.
+ rollout_cmp = cmp(b.is_rollout(), a.is_rollout())
+ if rollout_cmp != 0:
+ return rollout_cmp
+ return cmp(a.attach_date(), b.attach_date())
diff --git a/WebKitTools/Scripts/webkitpy/tool/bot/feeders_unittest.py b/WebKitTools/Scripts/webkitpy/tool/bot/feeders_unittest.py
new file mode 100644
index 0000000..5ce00b4
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/bot/feeders_unittest.py
@@ -0,0 +1,70 @@
+# 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.
+
+from datetime import datetime
+import unittest
+
+from webkitpy.common.system.outputcapture import OutputCapture
+from webkitpy.thirdparty.mock import Mock
+from webkitpy.tool.bot.feeders import *
+from webkitpy.tool.mocktool import MockTool
+
+
+class FeedersTest(unittest.TestCase):
+ def test_commit_queue_feeder(self):
+ feeder = CommitQueueFeeder(MockTool())
+ expected_stderr = u"""Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
+Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
+MOCK setting flag 'commit-queue' to '-' on attachment '128' with comment 'Rejecting patch 128 from commit-queue.' and additional comment 'non-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py.
+
+- If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
+
+- If you have committer rights please correct the error in WebKitTools/Scripts/webkitpy/common/config/committers.py by adding yourself to the file (no review needed). The commit-queue restarts itself every 2 hours. After restart the commit-queue will correctly respect your committer rights.'
+MOCK: update_work_items: commit-queue [106, 197]
+Feeding commit-queue items [106, 197]
+"""
+ OutputCapture().assert_outputs(self, feeder.feed, expected_stderr=expected_stderr)
+
+ def _mock_attachment(self, is_rollout, attach_date):
+ attachment = Mock()
+ attachment.is_rollout = lambda: is_rollout
+ attachment.attach_date = lambda: attach_date
+ return attachment
+
+ def test_patch_cmp(self):
+ long_ago_date = datetime(1900, 1, 21)
+ recent_date = datetime(2010, 1, 21)
+ attachment1 = self._mock_attachment(is_rollout=False, attach_date=recent_date)
+ attachment2 = self._mock_attachment(is_rollout=False, attach_date=long_ago_date)
+ attachment3 = self._mock_attachment(is_rollout=True, attach_date=recent_date)
+ attachment4 = self._mock_attachment(is_rollout=True, attach_date=long_ago_date)
+ attachments = [attachment1, attachment2, attachment3, attachment4]
+ expected_sort = [attachment4, attachment3, attachment2, attachment1]
+ queue = CommitQueueFeeder(MockTool())
+ attachments.sort(queue._patch_cmp)
+ self.assertEqual(attachments, expected_sort)
diff --git a/WebKitTools/Scripts/webkitpy/tool/bot/queueengine.py b/WebKitTools/Scripts/webkitpy/tool/bot/queueengine.py
index 289dc4a..8118653 100644
--- a/WebKitTools/Scripts/webkitpy/tool/bot/queueengine.py
+++ b/WebKitTools/Scripts/webkitpy/tool/bot/queueengine.py
@@ -141,6 +141,8 @@ class QueueEngine:
def _open_work_log(self, work_item):
work_item_log_path = self._delegate.work_item_log_path(work_item)
+ if not work_item_log_path:
+ return
self._work_log = self._output_tee.add_log(work_item_log_path)
def _ensure_work_log_closed(self):
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/download.py b/WebKitTools/Scripts/webkitpy/tool/commands/download.py
index ed0e3d6..9916523 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/download.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/download.py
@@ -289,7 +289,7 @@ class AbstractRolloutPrepCommand(AbstractSequencedCommand):
argument_names = "REVISION REASON"
def _commit_info(self, revision):
- commit_info = self.tool.checkout().commit_info_for_revision(revision)
+ commit_info = self._tool.checkout().commit_info_for_revision(revision)
if commit_info and commit_info.bug_id():
# Note: Don't print a bug URL here because it will confuse the
# SheriffBot because the SheriffBot just greps the output
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/openbugs.py b/WebKitTools/Scripts/webkitpy/tool/commands/openbugs.py
index 5da5bbb..1b51c9f 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/openbugs.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/openbugs.py
@@ -41,8 +41,8 @@ class OpenBugs(AbstractDeclarativeCommand):
def _open_bugs(self, bug_ids):
for bug_id in bug_ids:
- bug_url = self.tool.bugs.bug_url_for_bug_id(bug_id)
- self.tool.user.open_url(bug_url)
+ bug_url = self._tool.bugs.bug_url_for_bug_id(bug_id)
+ self._tool.user.open_url(bug_url)
# _find_bugs_in_string mostly exists for easy unit testing.
def _find_bugs_in_string(self, string):
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queries.py b/WebKitTools/Scripts/webkitpy/tool/commands/queries.py
index 9b8d162..c6e45aa 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/queries.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/queries.py
@@ -33,6 +33,7 @@ from optparse import make_option
from webkitpy.common.checkout.commitinfo import CommitInfo
from webkitpy.common.config.committers import CommitterList
from webkitpy.common.net.buildbot import BuildBot
+from webkitpy.common.net.regressionwindow import RegressionWindow
from webkitpy.common.system.user import User
from webkitpy.tool.grammar import pluralize
from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand
@@ -112,7 +113,7 @@ class LastGreenRevision(AbstractDeclarativeCommand):
help_text = "Prints the last known good revision"
def execute(self, options, args, tool):
- print self.tool.buildbot.last_green_revision()
+ print self._tool.buildbot.last_green_revision()
class WhatBroke(AbstractDeclarativeCommand):
@@ -122,29 +123,26 @@ class WhatBroke(AbstractDeclarativeCommand):
def _print_builder_line(self, builder_name, max_name_width, status_message):
print "%s : %s" % (builder_name.ljust(max_name_width), status_message)
- # FIXME: This is slightly different from Builder.suspect_revisions_for_green_to_red_transition
- # due to needing to detect the "hit the limit" case an print a special message.
def _print_blame_information_for_builder(self, builder_status, name_width, avoid_flakey_tests=True):
- builder = self.tool.buildbot.builder_with_name(builder_status["name"])
+ builder = self._tool.buildbot.builder_with_name(builder_status["name"])
red_build = builder.build(builder_status["build_number"])
- (last_green_build, first_red_build) = builder.find_failure_transition(red_build)
- if not first_red_build:
+ regression_window = builder.find_regression_window(red_build)
+ if not regression_window.failing_build():
self._print_builder_line(builder.name(), name_width, "FAIL (error loading build information)")
return
- if not last_green_build:
- self._print_builder_line(builder.name(), name_width, "FAIL (blame-list: sometime before %s?)" % first_red_build.revision())
+ if not regression_window.build_before_failure():
+ self._print_builder_line(builder.name(), name_width, "FAIL (blame-list: sometime before %s?)" % regression_window.failing_build().revision())
return
- suspect_revisions = range(first_red_build.revision(), last_green_build.revision(), -1)
- suspect_revisions.reverse()
+ revisions = regression_window.revisions()
first_failure_message = ""
- if (first_red_build == builder.build(builder_status["build_number"])):
+ if (regression_window.failing_build() == builder.build(builder_status["build_number"])):
first_failure_message = " FIRST FAILURE, possibly a flaky test"
- self._print_builder_line(builder.name(), name_width, "FAIL (blame-list: %s%s)" % (suspect_revisions, first_failure_message))
- for revision in suspect_revisions:
- commit_info = self.tool.checkout().commit_info_for_revision(revision)
+ self._print_builder_line(builder.name(), name_width, "FAIL (blame-list: %s%s)" % (revisions, first_failure_message))
+ for revision in revisions:
+ commit_info = self._tool.checkout().commit_info_for_revision(revision)
if commit_info:
- print commit_info.blame_string(self.tool.bugs)
+ print commit_info.blame_string(self._tool.bugs)
else:
print "FAILED to fetch CommitInfo for r%s, likely missing ChangeLog" % revision
@@ -169,7 +167,7 @@ class WhoBrokeIt(AbstractDeclarativeCommand):
help_text = "Print a list of revisions causing failures on %s" % BuildBot.default_host
def execute(self, options, args, tool):
- for revision, builders in self.tool.buildbot.revisions_causing_failures(False).items():
+ for revision, builders in self._tool.buildbot.failure_map(False).revisions_causing_failures().items():
print "r%s appears to have broken %s" % (revision, [builder.name() for builder in builders])
@@ -188,7 +186,7 @@ class ResultsFor(AbstractDeclarativeCommand):
print " %s" % filename
def execute(self, options, args, tool):
- builders = self.tool.buildbot.builders()
+ builders = self._tool.buildbot.builders()
for builder in builders:
print "%s:" % builder.name()
build = builder.build_for_revision(args[0], allow_failed_lookups=True)
@@ -200,13 +198,14 @@ class FailureReason(AbstractDeclarativeCommand):
help_text = "Lists revisions where individual test failures started at %s" % BuildBot.default_host
def _print_blame_information_for_transition(self, green_build, red_build, failing_tests):
- suspect_revisions = green_build.builder().suspect_revisions_for_transition(green_build, red_build)
+ regression_window = RegressionWindow(green_build, red_build)
+ revisions = regression_window.revisions()
print "SUCCESS: Build %s (r%s) was the first to show failures: %s" % (red_build._number, red_build.revision(), failing_tests)
print "Suspect revisions:"
- for revision in suspect_revisions:
- commit_info = self.tool.checkout().commit_info_for_revision(revision)
+ for revision in revisions:
+ commit_info = self._tool.checkout().commit_info_for_revision(revision)
if commit_info:
- print commit_info.blame_string(self.tool.bugs)
+ print commit_info.blame_string(self._tool.bugs)
else:
print "FAILED to fetch CommitInfo for r%s, likely missing ChangeLog" % revision
@@ -255,7 +254,7 @@ class FailureReason(AbstractDeclarativeCommand):
return 0
def _builder_to_explain(self):
- builder_statuses = self.tool.buildbot.builder_statuses()
+ builder_statuses = self._tool.buildbot.builder_statuses()
red_statuses = [status for status in builder_statuses if not status["is_green"]]
print "%s failing" % (pluralize("builder", len(red_statuses)))
builder_choices = [status["name"] for status in red_statuses]
@@ -264,11 +263,11 @@ class FailureReason(AbstractDeclarativeCommand):
# FIXME: prompt_with_list should really take a set of objects and a set of names and then return the object.
for status in red_statuses:
if status["name"] == chosen_name:
- return (self.tool.buildbot.builder_with_name(chosen_name), status["built_revision"])
+ return (self._tool.buildbot.builder_with_name(chosen_name), status["built_revision"])
def execute(self, options, args, tool):
(builder, latest_revision) = self._builder_to_explain()
- start_revision = self.tool.user.prompt("Revision to walk backwards from? [%s] " % latest_revision) or latest_revision
+ start_revision = self._tool.user.prompt("Revision to walk backwards from? [%s] " % latest_revision) or latest_revision
if not start_revision:
print "Revision required."
return 1
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queues.py b/WebKitTools/Scripts/webkitpy/tool/commands/queues.py
index bc9ee42..80fd2ea 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/queues.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/queues.py
@@ -27,6 +27,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import time
import traceback
import os
@@ -39,6 +40,8 @@ from webkitpy.common.net.statusserver import StatusServer
from webkitpy.common.system.executive import ScriptError
from webkitpy.common.system.deprecated_logging import error, log
from webkitpy.tool.commands.stepsequence import StepSequenceErrorHandler
+from webkitpy.tool.bot.commitqueuetask import CommitQueueTask
+from webkitpy.tool.bot.feeders import CommitQueueFeeder
from webkitpy.tool.bot.patchcollection import PersistentPatchCollection, PersistentPatchCollectionDelegate
from webkitpy.tool.bot.queueengine import QueueEngine, QueueEngineDelegate
from webkitpy.tool.grammar import pluralize
@@ -50,6 +53,7 @@ class AbstractQueue(Command, QueueEngineDelegate):
_pass_status = "Pass"
_fail_status = "Fail"
+ _retry_status = "Retry"
_error_status = "Error"
def __init__(self, options=None): # Default values should never be collections (like []) as default values are shared between invocations
@@ -62,20 +66,20 @@ class AbstractQueue(Command, QueueEngineDelegate):
def _cc_watchers(self, bug_id):
try:
- self.tool.bugs.add_cc_to_bug(bug_id, self.watchers)
+ self._tool.bugs.add_cc_to_bug(bug_id, self.watchers)
except Exception, e:
traceback.print_exc()
log("Failed to CC watchers.")
def run_webkit_patch(self, args):
- webkit_patch_args = [self.tool.path()]
+ webkit_patch_args = [self._tool.path()]
# FIXME: This is a hack, we should have a more general way to pass global options.
# FIXME: We must always pass global options and their value in one argument
# because our global option code looks for the first argument which does
# not begin with "-" and assumes that is the command name.
- webkit_patch_args += ["--status-host=%s" % self.tool.status_server.host]
+ webkit_patch_args += ["--status-host=%s" % self._tool.status_server.host]
webkit_patch_args.extend(args)
- return self.tool.executive.run_and_throw_if_fail(webkit_patch_args)
+ return self._tool.executive.run_and_throw_if_fail(webkit_patch_args)
def _log_directory(self):
return "%s-logs" % self.name
@@ -89,16 +93,16 @@ class AbstractQueue(Command, QueueEngineDelegate):
raise NotImplementedError, "subclasses must implement"
def begin_work_queue(self):
- log("CAUTION: %s will discard all local changes in \"%s\"" % (self.name, self.tool.scm().checkout_root))
+ log("CAUTION: %s will discard all local changes in \"%s\"" % (self.name, self._tool.scm().checkout_root))
if self.options.confirm:
- response = self.tool.user.prompt("Are you sure? Type \"yes\" to continue: ")
+ response = self._tool.user.prompt("Are you sure? Type \"yes\" to continue: ")
if (response != "yes"):
error("User declined.")
log("Running WebKit %s." % self.name)
- self.tool.status_server.update_status(self.name, "Starting Queue")
+ self._tool.status_server.update_status(self.name, "Starting Queue")
def stop_work_queue(self, reason):
- self.tool.status_server.update_status(self.name, "Stopping Queue, reason: %s" % reason)
+ self._tool.status_server.update_status(self.name, "Stopping Queue, reason: %s" % reason)
def should_continue_work_queue(self):
self._iteration_count += 1
@@ -120,8 +124,8 @@ class AbstractQueue(Command, QueueEngineDelegate):
def execute(self, options, args, tool, engine=QueueEngine):
self.options = options # FIXME: This code is wrong. Command.options is a list, this assumes an Options element!
- self.tool = tool # FIXME: This code is wrong too! Command.bind_to_tool handles this!
- return engine(self.name, self, self.tool.wakeup_event).run()
+ self._tool = tool # FIXME: This code is wrong too! Command.bind_to_tool handles this!
+ return engine(self.name, self, self._tool.wakeup_event).run()
@classmethod
def _log_from_script_error_for_upload(cls, script_error, output_limit=None):
@@ -144,20 +148,47 @@ class AbstractQueue(Command, QueueEngineDelegate):
return tool.status_server.update_status(cls.name, message, state["patch"], failure_log)
+class FeederQueue(AbstractQueue):
+ name = "feeder-queue"
+
+ _sleep_duration = 30 # seconds
+
+ # AbstractPatchQueue methods
+
+ def begin_work_queue(self):
+ AbstractQueue.begin_work_queue(self)
+ self.feeders = [
+ CommitQueueFeeder(self._tool),
+ ]
+
+ def next_work_item(self):
+ # This really show inherit from some more basic class that doesn't
+ # understand work items, but the base class in the heirarchy currently
+ # understands work items.
+ return "synthetic-work-item"
+
+ def should_proceed_with_work_item(self, work_item):
+ return True
+
+ def process_work_item(self, work_item):
+ for feeder in self.feeders:
+ feeder.feed()
+ time.sleep(self._sleep_duration)
+ return True
+
+ def work_item_log_path(self, work_item):
+ return None
+
+ def handle_unexpected_error(self, work_item, message):
+ log(message)
+
+
class AbstractPatchQueue(AbstractQueue):
def _update_status(self, message, patch=None, results_file=None):
- self.tool.status_server.update_status(self.name, message, patch, results_file)
-
- # Note, eventually this will be done by a separate "feeder" queue
- # whose job it is to poll bugzilla and feed work items into the
- # status server for other queues to munch on.
- def _update_work_items(self, patch_ids):
- self.tool.status_server.update_work_items(self.name, patch_ids)
- if patch_ids:
- self.log_progress(patch_ids)
+ return self._tool.status_server.update_status(self.name, message, patch, results_file)
def _fetch_next_work_item(self):
- return self.tool.status_server.next_work_item(self.name)
+ return self._tool.status_server.next_work_item(self.name)
def _did_pass(self, patch):
self._update_status(self._pass_status, patch)
@@ -165,6 +196,9 @@ class AbstractPatchQueue(AbstractQueue):
def _did_fail(self, patch):
self._update_status(self._fail_status, patch)
+ def _did_retry(self, patch):
+ self._update_status(self._retry_status, patch)
+
def _did_error(self, patch, reason):
message = "%s: %s" % (self._error_status, reason)
self._update_status(message, patch)
@@ -172,178 +206,63 @@ class AbstractPatchQueue(AbstractQueue):
def work_item_log_path(self, patch):
return os.path.join(self._log_directory(), "%s.log" % patch.bug_id())
- def log_progress(self, patch_ids):
- log("%s in %s [%s]" % (pluralize("patch", len(patch_ids)), self.name, ", ".join(map(str, patch_ids))))
-
class CommitQueue(AbstractPatchQueue, StepSequenceErrorHandler):
name = "commit-queue"
- def __init__(self):
- AbstractPatchQueue.__init__(self)
# AbstractPatchQueue methods
def begin_work_queue(self):
AbstractPatchQueue.begin_work_queue(self)
- self.committer_validator = CommitterValidator(self.tool.bugs)
-
- def _validate_patches_in_commit_queue(self):
- # Not using BugzillaQueries.fetch_patches_from_commit_queue() so we can reject patches with invalid committers/reviewers.
- bug_ids = self.tool.bugs.queries.fetch_bug_ids_from_commit_queue()
- all_patches = sum([self.tool.bugs.fetch_bug(bug_id).commit_queued_patches(include_invalid=True) for bug_id in bug_ids], [])
- return self.committer_validator.patches_after_rejecting_invalid_commiters_and_reviewers(all_patches)
-
- def _patch_cmp(self, a, b):
- # Sort first by is_rollout, then by attach_date.
- # Reversing the order so that is_rollout is first.
- rollout_cmp = cmp(b.is_rollout(), a.is_rollout())
- if (rollout_cmp != 0):
- return rollout_cmp
- return cmp(a.attach_date(), b.attach_date())
-
- def _feed_work_items_to_server(self):
- # Grab the set of patches from bugzilla, sort them, and update the status server.
- # Eventually this will all be done by a separate feeder queue.
- patches = self._validate_patches_in_commit_queue()
- patches = sorted(patches, self._patch_cmp)
- self._update_work_items([patch.id() for patch in patches])
+ self.committer_validator = CommitterValidator(self._tool.bugs)
def next_work_item(self):
- self._feed_work_items_to_server()
- # The grab the next patch to work on back from the status server.
patch_id = self._fetch_next_work_item()
if not patch_id:
return None
- return self.tool.bugs.fetch_attachment(patch_id)
-
- def _can_build_and_test_without_patch(self):
- try:
- self.run_webkit_patch([
- "build-and-test",
- "--force-clean",
- "--build",
- "--test",
- "--non-interactive",
- "--no-update",
- "--build-style=both",
- "--quiet"])
- return True
- except ScriptError, e:
- failure_log = self._log_from_script_error_for_upload(e)
- self._update_status("Unable to build and test without patch", results_file=failure_log)
- return False
+ return self._tool.bugs.fetch_attachment(patch_id)
def should_proceed_with_work_item(self, patch):
patch_text = "rollout patch" if patch.is_rollout() else "patch"
- self._update_status("Landing %s" % patch_text, patch)
+ self._update_status("Processing %s" % patch_text, patch)
return True
- def _build_and_test_patch(self, patch, first_run=False):
+ def process_work_item(self, patch):
+ self._cc_watchers(patch.bug_id())
+ task = CommitQueueTask(self._tool, self, patch)
try:
- args = [
- "build-and-test-attachment",
- "--force-clean",
- "--build",
- "--non-interactive",
- "--build-style=both",
- "--quiet",
- patch.id()
- ]
- # We don't bother to run tests for rollouts as that makes them too slow.
- if not patch.is_rollout():
- args.append("--test")
- if not first_run:
- # The first time through, we don't reject the patch from the
- # commit queue because we want to make sure we can build and
- # test ourselves. However, the second time through, we
- # register ourselves as the parent-command so we can reject
- # the patch on failure.
- args.append("--parent-command=commit-queue")
- # The second time through, we also don't want to update so we
- # know we're testing the same revision that we successfully
- # built and tested.
- args.append("--no-update")
- self.run_webkit_patch(args)
- return True
+ if task.run():
+ self._did_pass(patch)
+ return True
+ self._did_retry(patch)
except ScriptError, e:
- failure_log = self._log_from_script_error_for_upload(e)
- self._update_status("Unable to build and test patch", patch=patch, results_file=failure_log)
- if first_run:
- return False
+ validator = CommitterValidator(self._tool.bugs)
+ validator.reject_patch_from_commit_queue(patch.id(), self._error_message_for_bug(task.failure_status_id, e))
self._did_fail(patch)
- raise
-
- def _revalidate_patch(self, patch):
- # Bugs might get closed, or patches might be obsoleted or r-'d while the
- # commit-queue is processing. Do one last minute check before landing.
- patch = self.tool.bugs.fetch_attachment(patch.id())
- if patch.is_obsolete():
- return None
- if patch.bug().is_closed():
- return None
- if not patch.committer():
- return None
- # Reviewer is not required. Misisng reviewers will be caught during the ChangeLog check during landing.
- return patch
-
- def _land(self, patch):
- try:
- args = [
- "land-attachment",
- "--force-clean",
- "--non-interactive",
- "--ignore-builders",
- "--quiet",
- "--parent-command=commit-queue",
- patch.id(),
- ]
- self.run_webkit_patch(args)
- self._did_pass(patch)
- except ScriptError, e:
- failure_log = self._log_from_script_error_for_upload(e)
- self._update_status("Unable to land patch", patch=patch, results_file=failure_log)
- self._did_fail(patch)
- raise
-
- def process_work_item(self, patch):
- self._cc_watchers(patch.bug_id())
- if not self._build_and_test_patch(patch, first_run=True):
- self._update_status("Building and testing without the patch as a sanity check", patch)
- # The patch failed to build and test. It's possible that the
- # tree is busted. To check that case, we try to build and test
- # without the patch.
- if not self._can_build_and_test_without_patch():
- return False
- self._update_status("Build and test succeeded, trying again with patch", patch)
- # Hum, looks like the patch is actually bad. Of course, we could
- # have been bitten by a flaky test the first time around. We try
- # to build and test again. If it fails a second time, we're pretty
- # sure its a bad test and re can reject it outright.
- self._build_and_test_patch(patch)
- # Do one last check to catch any bug changes (cq-, closed, reviewer changed, etc.)
- # This helps catch races between the bots if locks expire.
- patch = self._revalidate_patch(patch)
- if not patch:
- return False
- self._land(patch)
- return True
def handle_unexpected_error(self, patch, message):
self.committer_validator.reject_patch_from_commit_queue(patch.id(), message)
- # StepSequenceErrorHandler methods
- @staticmethod
- def _error_message_for_bug(tool, status_id, script_error):
+ def command_passed(self, message, patch):
+ self._update_status(message, patch=patch)
+
+ def command_failed(self, message, script_error, patch):
+ failure_log = self._log_from_script_error_for_upload(script_error)
+ return self._update_status(message, patch=patch, results_file=failure_log)
+
+ def _error_message_for_bug(self, status_id, script_error):
if not script_error.output:
return script_error.message_with_output()
- results_link = tool.status_server.results_url_for_status(status_id)
+ results_link = self._tool.status_server.results_url_for_status(status_id)
return "%s\nFull output: %s" % (script_error.message_with_output(), results_link)
- @classmethod
+ # StepSequenceErrorHandler methods
+
def handle_script_error(cls, tool, state, script_error):
- status_id = cls._update_status_for_script_error(tool, state, script_error)
- validator = CommitterValidator(tool.bugs)
- validator.reject_patch_from_commit_queue(state["patch"].id(), cls._error_message_for_bug(tool, status_id, script_error))
+ # Hitting this error handler should be pretty rare. It does occur,
+ # however, when a patch no longer applies to top-of-tree in the final
+ # land step.
+ log(script_error.message_with_output())
@classmethod
def handle_checkout_needs_update(cls, tool, state, options, error):
@@ -368,7 +287,7 @@ class RietveldUploadQueue(AbstractPatchQueue, StepSequenceErrorHandler):
# AbstractPatchQueue methods
def next_work_item(self):
- patch_id = self.tool.bugs.queries.fetch_first_patch_from_rietveld_queue()
+ patch_id = self._tool.bugs.queries.fetch_first_patch_from_rietveld_queue()
if patch_id:
return patch_id
self._update_status("Empty queue")
@@ -393,7 +312,7 @@ class RietveldUploadQueue(AbstractPatchQueue, StepSequenceErrorHandler):
def handle_unexpected_error(self, patch, message):
log(message)
- self._reject_patch(self.tool, patch.id())
+ self._reject_patch(self._tool, patch.id())
# StepSequenceErrorHandler methods
@@ -417,10 +336,10 @@ class AbstractReviewQueue(AbstractPatchQueue, PersistentPatchCollectionDelegate,
return self.name
def fetch_potential_patch_ids(self):
- return self.tool.bugs.queries.fetch_attachment_ids_from_review_queue()
+ return self._tool.bugs.queries.fetch_attachment_ids_from_review_queue()
def status_server(self):
- return self.tool.status_server
+ return self._tool.status_server
def is_terminal_status(self, status):
return status == "Pass" or status == "Fail" or status.startswith("Error:")
@@ -434,7 +353,7 @@ class AbstractReviewQueue(AbstractPatchQueue, PersistentPatchCollectionDelegate,
def next_work_item(self):
patch_id = self._patches.next()
if patch_id:
- return self.tool.bugs.fetch_attachment(patch_id)
+ return self._tool.bugs.fetch_attachment(patch_id)
def should_proceed_with_work_item(self, patch):
raise NotImplementedError, "subclasses must implement"
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py
index 2deee76..029814e 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py
@@ -47,20 +47,16 @@ class TestReviewQueue(AbstractReviewQueue):
name = "test-review-queue"
+class TestFeederQueue(FeederQueue):
+ _sleep_duration = 0
+
+
class MockRolloutPatch(MockPatch):
def is_rollout(self):
return True
class AbstractQueueTest(CommandsTest):
- def _assert_log_progress_output(self, patch_ids, progress_output):
- OutputCapture().assert_outputs(self, TestQueue().log_progress, [patch_ids], expected_stderr=progress_output)
-
- def test_log_progress(self):
- self._assert_log_progress_output([1,2,3], "3 patches in test-queue [1, 2, 3]\n")
- self._assert_log_progress_output(["1","2","3"], "3 patches in test-queue [1, 2, 3]\n")
- self._assert_log_progress_output([1], "1 patch in test-queue [1]\n")
-
def test_log_directory(self):
self.assertEquals(TestQueue()._log_directory(), "test-queue-logs")
@@ -115,6 +111,29 @@ class AbstractQueueTest(CommandsTest):
self._assert_log_message(script_error, expected_output)
+class FeederQueueTest(QueuesTest):
+ def test_feeder_queue(self):
+ queue = TestFeederQueue()
+ tool = MockTool(log_executive=True)
+ expected_stderr = {
+ "begin_work_queue": self._default_begin_work_queue_stderr("feeder-queue", MockSCM.fake_checkout_root),
+ "should_proceed_with_work_item": "",
+ "next_work_item": "",
+ "process_work_item": """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
+Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
+MOCK setting flag 'commit-queue' to '-' on attachment '128' with comment 'Rejecting patch 128 from commit-queue.' and additional comment 'non-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py.
+
+- If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
+
+- If you have committer rights please correct the error in WebKitTools/Scripts/webkitpy/common/config/committers.py by adding yourself to the file (no review needed). The commit-queue restarts itself every 2 hours. After restart the commit-queue will correctly respect your committer rights.'
+MOCK: update_work_items: commit-queue [106, 197]
+Feeding commit-queue items [106, 197]
+""",
+ "handle_unexpected_error": "Mock error message\n",
+ }
+ self.assert_queue_outputs(queue, tool=tool, expected_stderr=expected_stderr)
+
+
class AbstractPatchQueueTest(CommandsTest):
def test_fetch_next_work_item(self):
queue = AbstractPatchQueue()
@@ -167,7 +186,7 @@ class SecondThoughtsCommitQueue(CommitQueue):
"attacher_email": "Contributer1",
}
patch = Attachment(attachment_dictionary, None)
- self.tool.bugs.set_override_patch(patch)
+ self._tool.bugs.set_override_patch(patch)
return True
@@ -175,40 +194,58 @@ class CommitQueueTest(QueuesTest):
def test_commit_queue(self):
expected_stderr = {
"begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root),
- "should_proceed_with_work_item": "MOCK: update_status: commit-queue Landing patch\n",
- # FIXME: The commit-queue warns about bad committers twice. This is due to the fact that we access Attachment.reviewer() twice and it logs each time.
- "next_work_item": """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
-Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
-MOCK setting flag 'commit-queue' to '-' on attachment '128' with comment 'Rejecting patch 128 from commit-queue.' and additional comment 'non-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py.\n\n- If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.\n\n- If you have committer rights please correct the error in WebKitTools/Scripts/webkitpy/common/config/committers.py by adding yourself to the file (no review needed). The commit-queue restarts itself every 2 hours. After restart the commit-queue will correctly respect your committer rights.'
-MOCK: update_work_items: commit-queue [106, 197]
-2 patches in commit-queue [106, 197]
+ "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing patch\n",
+ "next_work_item": "",
+ "process_work_item": """MOCK: update_status: commit-queue Applied patch
+MOCK: update_status: commit-queue Built patch
+MOCK: update_status: commit-queue Passed tests
+MOCK: update_status: commit-queue Landed patch
+MOCK: update_status: commit-queue Pass
""",
- "process_work_item": "MOCK: update_status: commit-queue Pass\n",
"handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'Mock error message'\n",
- "handle_script_error": "MOCK: update_status: commit-queue ScriptError error message\nMOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'ScriptError error message'\n",
+ "handle_script_error": "ScriptError error message\n",
}
self.assert_queue_outputs(CommitQueue(), expected_stderr=expected_stderr)
+ def test_commit_queue_failure(self):
+ expected_stderr = {
+ "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root),
+ "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing patch\n",
+ "next_work_item": "",
+ "process_work_item": """MOCK: update_status: commit-queue Patch does not apply
+MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'MOCK script error'
+MOCK: update_status: commit-queue Fail
+""",
+ "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'Mock error message'\n",
+ "handle_script_error": "ScriptError error message\n",
+ }
+ queue = CommitQueue()
+
+ def mock_run_webkit_patch(command):
+ raise ScriptError('MOCK script error')
+
+ queue.run_webkit_patch = mock_run_webkit_patch
+ self.assert_queue_outputs(queue, expected_stderr=expected_stderr)
+
def test_rollout(self):
tool = MockTool(log_executive=True)
tool.buildbot.light_tree_on_fire()
expected_stderr = {
"begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root),
- "should_proceed_with_work_item": "MOCK: update_status: commit-queue Landing patch\n",
- # FIXME: The commit-queue warns about bad committers twice. This is due to the fact that we access Attachment.reviewer() twice and it logs each time.
- "next_work_item": """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
-Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
-MOCK setting flag 'commit-queue' to '-' on attachment '128' with comment 'Rejecting patch 128 from commit-queue.' and additional comment 'non-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py.
-
-- If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
-
-- If you have committer rights please correct the error in WebKitTools/Scripts/webkitpy/common/config/committers.py by adding yourself to the file (no review needed). The commit-queue restarts itself every 2 hours. After restart the commit-queue will correctly respect your committer rights.'
-MOCK: update_work_items: commit-queue [106, 197]
-2 patches in commit-queue [106, 197]
+ "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing patch\n",
+ "next_work_item": "",
+ "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+MOCK: update_status: commit-queue Applied patch
+MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--no-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+MOCK: update_status: commit-queue Built patch
+MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+MOCK: update_status: commit-queue Passed tests
+MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197]
+MOCK: update_status: commit-queue Landed patch
+MOCK: update_status: commit-queue Pass
""",
- "process_work_item": "MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test-attachment', '--force-clean', '--build', '--non-interactive', '--build-style=both', '--quiet', 197, '--test']\nMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--non-interactive', '--ignore-builders', '--quiet', '--parent-command=commit-queue', 197]\nMOCK: update_status: commit-queue Pass\n",
"handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'Mock error message'\n",
- "handle_script_error": "MOCK: update_status: commit-queue ScriptError error message\nMOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'ScriptError error message'\n",
+ "handle_script_error": "ScriptError error message\n",
}
self.assert_queue_outputs(CommitQueue(), tool=tool, expected_stderr=expected_stderr)
@@ -218,52 +255,23 @@ MOCK: update_work_items: commit-queue [106, 197]
rollout_patch = MockRolloutPatch()
expected_stderr = {
"begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root),
- "should_proceed_with_work_item": "MOCK: update_status: commit-queue Landing rollout patch\n",
- # FIXME: The commit-queue warns about bad committers twice. This is due to the fact that we access Attachment.reviewer() twice and it logs each time.
- "next_work_item": """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
-Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
-MOCK setting flag 'commit-queue' to '-' on attachment '128' with comment 'Rejecting patch 128 from commit-queue.' and additional comment 'non-committer@example.com does not have committer permissions according to http://trac.webkit.org/browser/trunk/WebKitTools/Scripts/webkitpy/common/config/committers.py.
-
-- If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
-
-- If you have committer rights please correct the error in WebKitTools/Scripts/webkitpy/common/config/committers.py by adding yourself to the file (no review needed). The commit-queue restarts itself every 2 hours. After restart the commit-queue will correctly respect your committer rights.'
-MOCK: update_work_items: commit-queue [106, 197]
-2 patches in commit-queue [106, 197]
+ "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing rollout patch\n",
+ "next_work_item": "",
+ "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197]
+MOCK: update_status: commit-queue Applied patch
+MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--no-clean', '--no-update', '--build', '--build-style=both', '--quiet']
+MOCK: update_status: commit-queue Built patch
+MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive']
+MOCK: update_status: commit-queue Passed tests
+MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197]
+MOCK: update_status: commit-queue Landed patch
+MOCK: update_status: commit-queue Pass
""",
- "process_work_item": "MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test-attachment', '--force-clean', '--build', '--non-interactive', '--build-style=both', '--quiet', 197]\nMOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--non-interactive', '--ignore-builders', '--quiet', '--parent-command=commit-queue', 197]\nMOCK: update_status: commit-queue Pass\n",
"handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'Mock error message'\n",
- "handle_script_error": "MOCK: update_status: commit-queue ScriptError error message\nMOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'ScriptError error message'\n",
+ "handle_script_error": "ScriptError error message\n",
}
self.assert_queue_outputs(CommitQueue(), tool=tool, work_item=rollout_patch, expected_stderr=expected_stderr)
- def test_can_build_and_test(self):
- queue = CommitQueue()
- tool = MockTool()
- tool.executive = Mock()
- queue.bind_to_tool(tool)
- self.assertTrue(queue._can_build_and_test_without_patch())
- expected_run_args = ["echo", "--status-host=example.com", "build-and-test", "--force-clean", "--build", "--test", "--non-interactive", "--no-update", "--build-style=both", "--quiet"]
- tool.executive.run_and_throw_if_fail.assert_called_with(expected_run_args)
-
- def _mock_attachment(self, is_rollout, attach_date):
- attachment = Mock()
- attachment.is_rollout = lambda: is_rollout
- attachment.attach_date = lambda: attach_date
- return attachment
-
- def test_patch_cmp(self):
- long_ago_date = datetime(1900, 1, 21)
- recent_date = datetime(2010, 1, 21)
- attachment1 = self._mock_attachment(is_rollout=False, attach_date=recent_date)
- attachment2 = self._mock_attachment(is_rollout=False, attach_date=long_ago_date)
- attachment3 = self._mock_attachment(is_rollout=True, attach_date=recent_date)
- attachment4 = self._mock_attachment(is_rollout=True, attach_date=long_ago_date)
- attachments = [attachment1, attachment2, attachment3, attachment4]
- expected_sort = [attachment4, attachment3, attachment2, attachment1]
- queue = CommitQueue()
- attachments.sort(queue._patch_cmp)
- self.assertEqual(attachments, expected_sort)
-
def test_auto_retry(self):
queue = CommitQueue()
options = Mock()
@@ -282,7 +290,13 @@ MOCK: update_work_items: commit-queue [106, 197]
def test_manual_reject_during_processing(self):
queue = SecondThoughtsCommitQueue()
queue.bind_to_tool(MockTool())
- queue.process_work_item(MockPatch())
+ expected_stderr = """MOCK: update_status: commit-queue Applied patch
+MOCK: update_status: commit-queue Built patch
+MOCK: update_status: commit-queue Passed tests
+MOCK: update_status: commit-queue Landed patch
+MOCK: update_status: commit-queue Pass
+"""
+ OutputCapture().assert_outputs(self, queue.process_work_item, [MockPatch()], expected_stderr=expected_stderr)
class RietveldUploadQueueTest(QueuesTest):
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queuestest.py b/WebKitTools/Scripts/webkitpy/tool/commands/queuestest.py
index aa3cef4..9f3583d 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/queuestest.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/queuestest.py
@@ -32,6 +32,7 @@ from webkitpy.common.net.bugzilla import Attachment
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.common.system.executive import ScriptError
from webkitpy.thirdparty.mock import Mock
+from webkitpy.tool.commands.stepsequence import StepSequenceErrorHandler
from webkitpy.tool.mocktool import MockTool
@@ -100,4 +101,6 @@ class QueuesTest(unittest.TestCase):
self.assert_outputs(queue.should_proceed_with_work_item, "should_proceed_with_work_item", [work_item], expected_stdout, expected_stderr, expected_exceptions)
self.assert_outputs(queue.process_work_item, "process_work_item", [work_item], expected_stdout, expected_stderr, expected_exceptions)
self.assert_outputs(queue.handle_unexpected_error, "handle_unexpected_error", [work_item, "Mock error message"], expected_stdout, expected_stderr, expected_exceptions)
- self.assert_outputs(queue.handle_script_error, "handle_script_error", [tool, {"patch": MockPatch()}, ScriptError(message="ScriptError error message", script_args="MockErrorCommand")], expected_stdout, expected_stderr, expected_exceptions)
+ # Should we have a different function for testing StepSequenceErrorHandlers?
+ if isinstance(queue, StepSequenceErrorHandler):
+ self.assert_outputs(queue.handle_script_error, "handle_script_error", [tool, {"patch": MockPatch()}, ScriptError(message="ScriptError error message", script_args="MockErrorCommand")], expected_stdout, expected_stderr, expected_exceptions)
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/rebaseline.py b/WebKitTools/Scripts/webkitpy/tool/commands/rebaseline.py
index 78e06c6..abfa850 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/rebaseline.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/rebaseline.py
@@ -72,15 +72,15 @@ class Rebaseline(AbstractDeclarativeCommand):
# FIXME: This should share more code with FailureReason._builder_to_explain
def _builder_to_pull_from(self):
- builder_statuses = self.tool.buildbot.builder_statuses()
+ builder_statuses = self._tool.buildbot.builder_statuses()
red_statuses = [status for status in builder_statuses if not status["is_green"]]
print "%s failing" % (pluralize("builder", len(red_statuses)))
builder_choices = [status["name"] for status in red_statuses]
- chosen_name = self.tool.user.prompt_with_list("Which builder to pull results from:", builder_choices)
+ chosen_name = self._tool.user.prompt_with_list("Which builder to pull results from:", builder_choices)
# FIXME: prompt_with_list should really take a set of objects and a set of names and then return the object.
for status in red_statuses:
if status["name"] == chosen_name:
- return (self.tool.buildbot.builder_with_name(chosen_name), status["build_number"])
+ return (self._tool.buildbot.builder_with_name(chosen_name), status["build_number"])
def _replace_expectation_with_remote_result(self, local_file, remote_file):
(downloaded_file, headers) = urllib.urlretrieve(remote_file)
@@ -90,7 +90,8 @@ class Rebaseline(AbstractDeclarativeCommand):
parsed_results = build.layout_test_results().parsed_results()
# FIXME: This probably belongs as API on LayoutTestResults
# but .failing_tests() already means something else.
- return parsed_results[LayoutTestResults.fail_key]
+ failing_tests = parsed_results[LayoutTestResults.fail_key]
+ return self._tool.user.prompt_with_list("Which test(s) to rebaseline:", failing_tests, can_choose_multiple=True)
def _results_url_for_test(self, build, test):
test_base = os.path.splitext(test)[0]
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot.py b/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot.py
index 24c8517..23d013d 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot.py
@@ -50,9 +50,9 @@ class SheriffBot(AbstractQueue, StepSequenceErrorHandler):
def begin_work_queue(self):
AbstractQueue.begin_work_queue(self)
- self._sheriff = Sheriff(self.tool, self)
- self._irc_bot = SheriffIRCBot(self.tool, self._sheriff)
- self.tool.ensure_irc_connected(self._irc_bot.irc_delegate())
+ self._sheriff = Sheriff(self._tool, self)
+ self._irc_bot = SheriffIRCBot(self._tool, self._sheriff)
+ self._tool.ensure_irc_connected(self._irc_bot.irc_delegate())
def work_item_log_path(self, new_failures):
return os.path.join("%s-logs" % self.name, "%s.log" % new_failures.keys()[0])
@@ -86,12 +86,12 @@ class SheriffBot(AbstractQueue, StepSequenceErrorHandler):
self._update()
# We do one read from buildbot to ensure a consistent view.
- revisions_causing_failures = self.tool.buildbot.revisions_causing_failures()
+ revisions_causing_failures = self._tool.buildbot.failure_map().revisions_causing_failures()
# Similarly, we read once from our the status_server.
old_failing_svn_revisions = []
for svn_revision in revisions_causing_failures.keys():
- if self.tool.status_server.svn_revision(svn_revision):
+ if self._tool.status_server.svn_revision(svn_revision):
old_failing_svn_revisions.append(svn_revision)
new_failures = self._new_failures(revisions_causing_failures,
@@ -108,7 +108,7 @@ class SheriffBot(AbstractQueue, StepSequenceErrorHandler):
blame_list = new_failures.keys()
for svn_revision, builders in new_failures.items():
try:
- commit_info = self.tool.checkout().commit_info_for_revision(svn_revision)
+ commit_info = self._tool.checkout().commit_info_for_revision(svn_revision)
if not commit_info:
print "FAILED to fetch CommitInfo for r%s, likely missing ChangeLog" % revision
continue
@@ -120,7 +120,7 @@ class SheriffBot(AbstractQueue, StepSequenceErrorHandler):
builders)
finally:
for builder in builders:
- self.tool.status_server.update_svn_revision(svn_revision,
+ self._tool.status_server.update_svn_revision(svn_revision,
builder.name())
return True
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py
index 4a15ed6..107d8db 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py
@@ -82,14 +82,14 @@ class CleanPendingCommit(AbstractDeclarativeCommand):
def execute(self, options, args, tool):
committers = CommitterList()
for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
- bug = self.tool.bugs.fetch_bug(bug_id)
+ bug = self._tool.bugs.fetch_bug(bug_id)
patches = bug.patches(include_obsolete=True)
for patch in patches:
flags_to_clear = self._flags_to_clear_on_patch(patch)
if not flags_to_clear:
continue
message = "Cleared %s from obsolete attachment %s so that this bug does not appear in http://webkit.org/pending-commit." % (flags_to_clear, patch.id())
- self.tool.bugs.obsolete_attachment(patch.id(), message)
+ self._tool.bugs.obsolete_attachment(patch.id(), message)
class AssignToCommitter(AbstractDeclarativeCommand):
@@ -104,7 +104,7 @@ class AssignToCommitter(AbstractDeclarativeCommand):
def _assign_bug_to_last_patch_attacher(self, bug_id):
committers = CommitterList()
- bug = self.tool.bugs.fetch_bug(bug_id)
+ bug = self._tool.bugs.fetch_bug(bug_id)
if not bug.is_unassigned():
assigned_to_email = bug.assigned_to_email()
log("Bug %s is already assigned to %s (%s)." % (bug_id, assigned_to_email, committers.committer_by_email(assigned_to_email)))
@@ -128,7 +128,7 @@ class AssignToCommitter(AbstractDeclarativeCommand):
return
reassign_message = "Attachment %s was posted by a committer and has review+, assigning to %s for commit." % (latest_patch.id(), committer.full_name)
- self.tool.bugs.reassign_bug(bug_id, committer.bugzilla_email(), reassign_message)
+ self._tool.bugs.reassign_bug(bug_id, committer.bugzilla_email(), reassign_message)
def execute(self, options, args, tool):
for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
diff --git a/WebKitTools/Scripts/webkitpy/tool/mocktool.py b/WebKitTools/Scripts/webkitpy/tool/mocktool.py
index 8a6188a..277bd08 100644
--- a/WebKitTools/Scripts/webkitpy/tool/mocktool.py
+++ b/WebKitTools/Scripts/webkitpy/tool/mocktool.py
@@ -350,6 +350,16 @@ class MockBuilder(object):
self._name, username, comments))
+class MockFailureMap():
+ def __init__(self, buildbot):
+ self._buildbot = buildbot
+
+ def revisions_causing_failures(self):
+ return {
+ "29837": [self._buildbot.builder_with_name("Builder1")],
+ }
+
+
class MockBuildBot(object):
buildbot_host = "dummy_buildbot_host"
def __init__(self):
@@ -394,10 +404,8 @@ class MockBuildBot(object):
def light_tree_on_fire(self):
self._mock_builder2_status["is_green"] = False
- def revisions_causing_failures(self):
- return {
- "29837": [self.builder_with_name("Builder1")],
- }
+ def failure_map(self):
+ return MockFailureMap(self)
class MockSCM(Mock):
@@ -483,8 +491,8 @@ class MockUser(object):
def page(self, message):
pass
- def confirm(self, message=None):
- return True
+ def confirm(self, message=None, default='y'):
+ return default == 'y'
def can_open_url(self):
return True
diff --git a/WebKitTools/Scripts/webkitpy/tool/multicommandtool.py b/WebKitTools/Scripts/webkitpy/tool/multicommandtool.py
index 12ede2e..4848ae5 100644
--- a/WebKitTools/Scripts/webkitpy/tool/multicommandtool.py
+++ b/WebKitTools/Scripts/webkitpy/tool/multicommandtool.py
@@ -53,7 +53,7 @@ class Command(object):
self.required_arguments = self._parse_required_arguments(argument_names)
self.options = options
self.requires_local_commits = requires_local_commits
- self.tool = None
+ self._tool = None
# option_parser can be overriden by the tool using set_option_parser
# This default parser will be used for standalone_help printing.
self.option_parser = HelpPrintingOptionParser(usage=SUPPRESS_USAGE, add_help_option=False, option_list=self.options)
@@ -73,9 +73,9 @@ class Command(object):
# The tool calls bind_to_tool on each Command after adding it to its list.
def bind_to_tool(self, tool):
# Command instances can only be bound to one tool at a time.
- if self.tool and tool != self.tool:
+ if self._tool and tool != self._tool:
raise Exception("Command already bound to tool!")
- self.tool = tool
+ self._tool = tool
@staticmethod
def _parse_required_arguments(argument_names):
@@ -179,17 +179,17 @@ class HelpCommand(AbstractDeclarativeCommand):
# Only show commands which are relevant to this checkout's SCM system. Might this be confusing to some users?
if self.show_all_commands:
epilog = "All %prog commands:\n"
- relevant_commands = self.tool.commands[:]
+ relevant_commands = self._tool.commands[:]
else:
epilog = "Common %prog commands:\n"
- relevant_commands = filter(self.tool.should_show_in_main_help, self.tool.commands)
+ relevant_commands = filter(self._tool.should_show_in_main_help, self._tool.commands)
longest_name_length = max(map(lambda command: len(command.name), relevant_commands))
relevant_commands.sort(lambda a, b: cmp(a.name, b.name))
command_help_texts = map(lambda command: " %s %s\n" % (command.name.ljust(longest_name_length), command.help_text), relevant_commands)
epilog += "%s\n" % "".join(command_help_texts)
epilog += "See '%prog help --all-commands' to list all commands.\n"
epilog += "See '%prog help COMMAND' for more information on a specific command.\n"
- return epilog.replace("%prog", self.tool.name()) # Use of %prog here mimics OptionParser.expand_prog_name().
+ return epilog.replace("%prog", self._tool.name()) # Use of %prog here mimics OptionParser.expand_prog_name().
# FIXME: This is a hack so that we don't show --all-commands as a global option:
def _remove_help_options(self):
@@ -198,7 +198,7 @@ class HelpCommand(AbstractDeclarativeCommand):
def execute(self, options, args, tool):
if args:
- command = self.tool.command_by_name(args[0])
+ command = self._tool.command_by_name(args[0])
if command:
print command.standalone_help()
return 0
diff --git a/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCFLite.vsprops b/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCFLite.vsprops
new file mode 100644
index 0000000..03c7501
--- /dev/null
+++ b/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCFLite.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="InjectedBundleCFLite"
+ >
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CFLite$(LibraryConfigSuffix).lib"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix).dll"
+ />
+</VisualStudioPropertySheet>
diff --git a/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCommon.vsprops b/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCommon.vsprops
index e90ddb1..4e7b84e 100644
--- a/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCommon.vsprops
+++ b/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCommon.vsprops
@@ -10,11 +10,6 @@
ForcedIncludeFiles="WebKitTestRunnerPrefix.h"
/>
<Tool
- Name="VCLinkerTool"
- AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib"
- OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix).dll"
- />
- <Tool
Name="VCPostBuildEventTool"
CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;"
/>
diff --git a/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCoreFoundation.vsprops b/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCoreFoundation.vsprops
new file mode 100644
index 0000000..d58b221
--- /dev/null
+++ b/WebKitTools/WebKitTestRunner/Configurations/InjectedBundleCoreFoundation.vsprops
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="InjectedBundleCoreFoundation"
+ >
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CoreFoundation$(LibraryConfigSuffix).lib"
+ OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix).dll"
+ />
+</VisualStudioPropertySheet>
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
index d094f42..520ea1f 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h
@@ -30,7 +30,6 @@
#include "GCController.h"
#include "LayoutTestController.h"
#include <WebKit2/WKBase.h>
-#include <WebKit2/WKBundleBase.h>
#include <wtf/HashMap.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
index dd92eca..32b92cb 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
@@ -169,6 +169,7 @@ InjectedBundlePage::InjectedBundlePage(WKBundlePageRef page)
didReceiveTitleForFrame,
0,
0,
+ 0,
didClearWindowForFrame,
didCancelClientRedirectForFrame,
willPerformClientRedirectForFrame,
@@ -186,7 +187,8 @@ InjectedBundlePage::InjectedBundlePage(WKBundlePageRef page)
willSetStatusbarText,
willRunJavaScriptAlert,
willRunJavaScriptConfirm,
- willRunJavaScriptPrompt
+ willRunJavaScriptPrompt,
+ 0 /*mouseDidMoveOverElement*/
};
WKBundlePageSetUIClient(m_page, &uiClient);
diff --git a/WebKitTools/WebKitTestRunner/TestController.cpp b/WebKitTools/WebKitTestRunner/TestController.cpp
index a71b07d..fc2e28d 100644
--- a/WebKitTools/WebKitTestRunner/TestController.cpp
+++ b/WebKitTools/WebKitTestRunner/TestController.cpp
@@ -84,6 +84,8 @@ static WKPageRef createOtherPage(WKPageRef oldPage, const void*)
0,
0,
0,
+ 0,
+ 0,
0
};
WKPageSetPageUIClient(newPage, &otherPageUIClient);
@@ -163,6 +165,8 @@ void TestController::initialize(int argc, const char* argv[])
0,
0,
0,
+ 0,
+ 0,
0
};
WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient);
@@ -186,6 +190,7 @@ void TestController::initialize(int argc, const char* argv[])
0,
0,
0,
+ 0,
0
};
WKPageSetPageLoaderClient(m_mainWebView->page(), &pageLoaderClient);
diff --git a/WebKitTools/WebKitTestRunner/win/InjectedBundle.vcproj b/WebKitTools/WebKitTestRunner/win/InjectedBundle.vcproj
index 22c9a89..0412562 100644
--- a/WebKitTools/WebKitTestRunner/win/InjectedBundle.vcproj
+++ b/WebKitTools/WebKitTestRunner/win/InjectedBundle.vcproj
@@ -18,7 +18,7 @@
<Configuration
Name="Debug|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;..\Configurations\InjectedBundleCoreFoundation.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
CharacterSet="1"
>
<Tool
@@ -79,7 +79,7 @@
<Configuration
Name="Release|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;..\Configurations\InjectedBundleCoreFoundation.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -141,7 +141,7 @@
<Configuration
Name="Debug_All|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops;..\Configurations\InjectedBundleCoreFoundation.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
CharacterSet="1"
>
<Tool
@@ -202,7 +202,7 @@
<Configuration
Name="Debug_Internal|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;..\Configurations\InjectedBundleCoreFoundation.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
CharacterSet="1"
>
<Tool
@@ -260,6 +260,133 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug_CFLite|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops;..\Configurations\InjectedBundleCFLite.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CFLite|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;..\Configurations\InjectedBundleCFLite.vsprops;..\Configurations\InjectedBundleCommon.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
diff --git a/WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj b/WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj
index d7ddd5c..e4cd870 100644
--- a/WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj
+++ b/WebKitTools/WebKitTestRunner/win/WebKitTestRunner.vcproj
@@ -298,6 +298,153 @@
CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;if not defined ARCHIVE_BUILD (if defined PRODUCTION exit /b)&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if not exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; exit /b&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CFNetwork.resources&quot; &quot;$(WebKitOutputDir)\bin\CFNetwork.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\dnssd.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;"
/>
</Configuration>
+ <Configuration
+ Name="Debug_CFLite|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash&#x0D;&#x0A;if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;cmd /c&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebKitTestRunner&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebKitTestRunner\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebKitTestRunner\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebKitTestRunner\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)\..&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\private&quot;;&quot;$(WebKitOutputDir)\Include\WebKitTestRunner\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;"
+ PreprocessorDefinitions="__WIN32__;_CONSOLE"
+ DisableSpecificWarnings="4146"
+ ForcedIncludeFiles="WebKitTestRunnerPrefix.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/NXCOMPAT"
+ AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CFLite$(LibraryConfigSuffix).lib shlwapi.lib"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;if not defined ARCHIVE_BUILD (if defined PRODUCTION exit /b)&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if not exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; exit /b&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CFNetwork.resources&quot; &quot;$(WebKitOutputDir)\bin\CFNetwork.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\dnssd.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CFLite|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash&#x0D;&#x0A;if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;cmd /c&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebKitTestRunner&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebKitTestRunner\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebKitTestRunner\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebKitTestRunner\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)\..&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitOutputDir)\Include\private&quot;;&quot;$(WebKitOutputDir)\Include\WebKitTestRunner\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include&quot;"
+ PreprocessorDefinitions="__WIN32__;_CONSOLE"
+ DisableSpecificWarnings="4146"
+ ForcedIncludeFiles="WebKitTestRunnerPrefix.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/NXCOMPAT"
+ AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WebKit$(WebKitDLLConfigSuffix).lib CFLite$(LibraryConfigSuffix).lib shlwapi.lib"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;if not defined ARCHIVE_BUILD (if defined PRODUCTION exit /b)&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;if not exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; exit /b&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CFNetwork$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CFNetwork.resources&quot; &quot;$(WebKitOutputDir)\bin\CFNetwork.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CharacterSets&quot; &quot;$(WebKitOutputDir)\bin\CharacterSets&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreGraphics$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\dnssd.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).pdb&quot;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxml2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libxslt$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\SQLite3$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\zlib1$(LibraryConfigSuffix).pdb&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
diff --git a/WebKitTools/wx/packaging/build-mac-installer.py b/WebKitTools/wx/packaging/build-mac-installer.py
index a0c1b22..5b76b0b 100644
--- a/WebKitTools/wx/packaging/build-mac-installer.py
+++ b/WebKitTools/wx/packaging/build-mac-installer.py
@@ -26,6 +26,7 @@
# Script for building Mac .pkg installer
import commands
+import datetime
import distutils.sysconfig
import glob
import optparse
@@ -48,11 +49,11 @@ wxwebkit_dir = os.path.abspath(os.path.join(wxwk_root, "WebKitBuild", get_config
wx_version = wx.__version__[:5]
py_version = sys.version[:3]
-wxwk_version = svn_revision()
+date = str(datetime.date.today())
platform = "osx"
-pkgname = "wxWebKit-%s-wx%s-py%s" % (platform, wx_version[:3], py_version)
+pkgname = "wxWebKit-%s-wx%s-py%s-%s" % (platform, wx_version[:3], py_version, date)
tempdir = "/tmp/%s" % (pkgname)
@@ -141,7 +142,7 @@ try:
pkg_args = ['--title ' + pkgname,
'--out %s.pkg' % pkgname,
- '--version ' + wxwk_version.strip(),
+ '--version ' + date.strip(),
'--id org.wxwebkit.wxwebkit',
'--domain system',
'--root-volume-only',
diff --git a/WebKitTools/wx/packaging/build-win-installer.py b/WebKitTools/wx/packaging/build-win-installer.py
index 2bb8034..ffbdd19 100644
--- a/WebKitTools/wx/packaging/build-win-installer.py
+++ b/WebKitTools/wx/packaging/build-win-installer.py
@@ -27,6 +27,7 @@
import sys, os, string
import commands
+import datetime
import glob
from subprocess import *
@@ -62,7 +63,7 @@ if __name__ == "__main__":
innoSetup = getInnoSetupPath()
os.chdir(sys.path[0])
- svnrevision = svn_revision()
+ date = str(datetime.date.today())
if not os.path.exists(innoSetup):
print "ERROR: Cannot find InnoSetup."
@@ -84,7 +85,7 @@ CopyMode: alwaysoverwrite; Source: *.py; DestDir: "{app}"
installerTemplate = open("wxWebKitInstaller.iss.in", "r").read()
- installerTemplate = installerTemplate.replace("<<VERSION>>", svnrevision)
+ installerTemplate = installerTemplate.replace("<<VERSION>>", date)
installerTemplate = installerTemplate.replace("<<ROOTDIR>>", wxwebkit_dir )
installerTemplate = installerTemplate.replace("<<PYTHONVER>>", sys.version[0:3] )
installerTemplate = installerTemplate.replace("<<FILES>>", fileList )