diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-01 10:36:58 +0200 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-01 10:36:58 +0200 |
| commit | b1e9e47fa11f608ae16bc07f97a2acf95bf80272 (patch) | |
| tree | c88c45e80c9c44506e7cdf9a3bb39ebf82a8cd5b /Tools | |
| parent | be01689f43cf6882cf670d33df49ead1f570c53a (diff) | |
| download | qtwebkit-b1e9e47fa11f608ae16bc07f97a2acf95bf80272.tar.gz | |
Imported WebKit commit 499c84c99aa98e9870fa7eaa57db476c6d160d46 (http://svn.webkit.org/repository/webkit/trunk@119200)
Weekly update :). Particularly relevant changes for Qt are the use of the WebCore image decoders and direct usage
of libpng/libjpeg if available in the system.
Diffstat (limited to 'Tools')
101 files changed, 2868 insertions, 485 deletions
diff --git a/Tools/BuildSlaveSupport/build.webkit.org-config/config.json b/Tools/BuildSlaveSupport/build.webkit.org-config/config.json index 6e8d1c7ff..dc62cd8fc 100644 --- a/Tools/BuildSlaveSupport/build.webkit.org-config/config.json +++ b/Tools/BuildSlaveSupport/build.webkit.org-config/config.json @@ -3,12 +3,7 @@ { "name": "apple-xserve-4", "platform": "mac-snowleopard" }, - { "name": "apple-xserve-5", "platform": "mac-snowleopard" }, - { "name": "apple-xserve-6", "platform": "mac-snowleopard" }, - { "name": "apple-xserve-7", "platform": "mac-snowleopard" }, - { "name": "apple-xserve-8", "platform": "mac-snowleopard" }, { "name": "apple-xserve-9", "platform": "mac-snowleopard" }, - { "name": "apple-macpro-7", "platform": "mac-snowleopard" }, { "name": "apple-macpro-3", "platform": "mac-lion" }, { "name": "apple-macpro-4", "platform": "mac-lion" }, @@ -75,34 +70,16 @@ "builders": [ { "name": "SnowLeopard Intel Release (Build)", "type": "Build", "builddir": "snowleopard-intel-release", "platform": "mac-snowleopard", "configuration": "release", "architectures": ["x86_64"], - "triggers": ["snowleopard-intel-release-tests", "snowleopard-intel-release-tests-wk2"], "slavenames": ["apple-xserve-4", "test-slave"] }, { "name": "SnowLeopard Intel Debug (Build)", "type": "Build", "builddir": "snowleopard-intel-debug", "platform": "mac-snowleopard", "configuration": "debug", "architectures": ["x86_64"], - "triggers": ["snowleopard-intel-debug-tests", "snowleopard-intel-debug-tests-wk2"], "slavenames": ["apple-xserve-9"] }, - { "name": "SnowLeopard Intel Release (Tests)", "type": "Test", "builddir": "snowleopard-intel-release-tests", - "platform": "mac-snowleopard", "configuration": "release", "architectures": ["x86_64"], - "slavenames": ["apple-xserve-5", "apple-xserve-6", "test-slave"] - }, - { "name": "SnowLeopard Intel Debug (Tests)", "type": "Test", "builddir": "snowleopard-intel-debug-tests", - "platform": "mac-snowleopard", "configuration": "debug", "architectures": ["x86_64"], - "slavenames": ["apple-xserve-8"] - }, { "name": "Lion Leaks", "type": "BuildAndTestLeaks", "builddir": "lion-intel-leaks", "platform": "mac-lion", "configuration": "debug", "architectures": ["x86_64"], "slavenames": ["apple-macpro-3"] }, - { "name": "SnowLeopard Intel Release (WebKit2 Tests)", "type": "TestWebKit2", "builddir": "snowleopard-intel-release-tests-wk2", - "platform": "mac-snowleopard", "configuration": "release", "architectures": ["x86_64"], - "slavenames": ["apple-xserve-7", "test-slave"] - }, - { "name": "SnowLeopard Intel Debug (WebKit2 Tests)", "type": "TestWebKit2", "builddir": "snowleopard-intel-debug-tests-wk2", - "platform": "mac-snowleopard", "configuration": "debug", "architectures": ["x86_64"], - "slavenames": ["apple-macpro-7"] - }, { "name": "Lion Debug (Build)", "type": "Build", "builddir": "lion-intel-debug", "platform": "mac-lion", "configuration": "debug", "architectures": ["x86_64"], "triggers": ["lion-intel-debug-tests", "lion-intel-debug-tests-wk2"], @@ -340,18 +317,6 @@ { "type": "Triggerable", "name": "lion-intel-debug-tests-wk2", "builderNames": ["Lion Debug (WebKit2 Tests)"] }, - { "type": "Triggerable", "name": "snowleopard-intel-release-tests", - "builderNames": ["SnowLeopard Intel Release (Tests)"] - }, - { "type": "Triggerable", "name": "snowleopard-intel-release-tests-wk2", - "builderNames": ["SnowLeopard Intel Release (WebKit2 Tests)"] - }, - { "type": "Triggerable", "name": "snowleopard-intel-debug-tests", - "builderNames": ["SnowLeopard Intel Debug (Tests)"] - }, - { "type": "Triggerable", "name": "snowleopard-intel-debug-tests-wk2", - "builderNames": ["SnowLeopard Intel Debug (WebKit2 Tests)"] - }, { "type": "Triggerable", "name": "win-release-tests", "builderNames": ["Windows 7 Release (Tests)"] }, diff --git a/Tools/CMakeLists.txt b/Tools/CMakeLists.txt index dccf023d1..689467061 100644 --- a/Tools/CMakeLists.txt +++ b/Tools/CMakeLists.txt @@ -1,6 +1,8 @@ IF ("${PORT}" STREQUAL "Efl") - ADD_SUBDIRECTORY(DumpRenderTree/efl) - ADD_SUBDIRECTORY(EWebLauncher) + IF (ENABLE_WEBKIT) + ADD_SUBDIRECTORY(DumpRenderTree/efl) + ADD_SUBDIRECTORY(EWebLauncher) + ENDIF () ELSEIF ("${PORT}" STREQUAL "WinCE") ADD_SUBDIRECTORY(WinCELauncher) ENDIF() diff --git a/Tools/ChangeLog b/Tools/ChangeLog index e86900fe5..63af81316 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,3 +1,937 @@ +2012-06-01 Ryosuke Niwa <rniwa@webkit.org> + + Add public page loading performance tests using web-page-replay + https://bugs.webkit.org/show_bug.cgi?id=84008 + + Reviewed by Dirk Pranke. + + Add the primitive implementation of replay performance tests. We use web-page-replay (http://code.google.com/p/web-page-replay/) + to cache data locally. Each replay test is represented by a text file with .replay extension containing a single URL. + To hash out bugs and isolate them from the rest of performance tests, replay tests are hidden behind --replay flag. + + Run "run-perf-tests --replay PerformanceTests/Replay" after changing the system network preference to forward HTTP and HTTPS requests + to localhost:8080 and localhost:8443 respectively (i.e. configure the system as if there are HTTP proxies at ports 8080 and 8443) + excluding: *.webkit.org, *.googlecode.com, *.sourceforge.net, pypi.python.org, and www.adambarth.com for thirdparty Python dependencies. + run-perf-tests starts web-page-replay, which provides HTTP proxies at ports 8080 and 8443 to replay pages. + + * Scripts/webkitpy/layout_tests/port/driver.py: + (Driver.is_external_http_test): Added. + * Scripts/webkitpy/layout_tests/port/webkit.py: + (WebKitDriver._command_from_driver_input): Allow test names that starts with http:// or https://. + * Scripts/webkitpy/performance_tests/perftest.py: + (PerfTest.__init__): Takes port. + (PerfTest.prepare): Added. Overridden by ReplayPerfTest. + (PerfTest): + (PerfTest.run): Calls run_single. + (PerfTest.run_single): Extracted from PageLoadingPerfTest.run. + (ChromiumStylePerfTest.__init__): + (PageLoadingPerfTest.__init__): + (PageLoadingPerfTest.run): + (ReplayServer): Added. Responsible for starting and stopping replay.py in the web-page-replay. + (ReplayServer.__init__): + (ReplayServer.wait_until_ready): Wait until port 8080 is ready. I have tried looking at the piped output from web-page-replay + but it caused a dead lock on some web pages. + (ReplayServer.stop): + (ReplayServer.__del__): + (ReplayPerfTest): + (ReplayPerfTest.__init__): + (ReplayPerfTest._start_replay_server): + (ReplayPerfTest.prepare): Creates test.wpr and test-expected.png to cache the page when a replay test is ran for the first time. + The subsequent runs of the same test will just use test.wpr. + (ReplayPerfTest.run_single): + (PerfTestFactory): + (PerfTestFactory.create_perf_test): + * Scripts/webkitpy/performance_tests/perftest_unittest.py: + (MainTest.test_parse_output): + (MainTest.test_parse_output_with_failing_line): + (TestPageLoadingPerfTest.test_run): + (TestPageLoadingPerfTest.test_run_with_bad_output): + (TestReplayPerfTest): + (TestReplayPerfTest.ReplayTestPort): + (TestReplayPerfTest.ReplayTestPort.__init__): + (TestReplayPerfTest.ReplayTestPort.__init__.ReplayTestDriver): + (TestReplayPerfTest.ReplayTestPort.__init__.ReplayTestDriver.run_test): + (TestReplayPerfTest.ReplayTestPort._driver_class): + (TestReplayPerfTest.MockReplayServer): + (TestReplayPerfTest.MockReplayServer.__init__): + (TestReplayPerfTest.MockReplayServer.stop): + (TestReplayPerfTest._add_file): + (TestReplayPerfTest._setup_test): + (TestReplayPerfTest.test_run_single): + (TestReplayPerfTest.test_run_single.run_test): + (TestReplayPerfTest.test_run_single_fails_without_webpagereplay): + (TestReplayPerfTest.test_prepare_fails_when_wait_until_ready_fails): + (TestReplayPerfTest.test_run_single_fails_when_output_has_error): + (TestReplayPerfTest.test_run_single_fails_when_output_has_error.run_test): + (TestReplayPerfTest.test_prepare): + (TestReplayPerfTest.test_prepare.run_test): + (TestReplayPerfTest.test_prepare_calls_run_single): + (TestReplayPerfTest.test_prepare_calls_run_single.run_single): + (TestPerfTestFactory.test_regular_test): + (TestPerfTestFactory.test_inspector_test): + (TestPerfTestFactory.test_page_loading_test): + * Scripts/webkitpy/performance_tests/perftestsrunner.py: + (PerfTestsRunner): + (PerfTestsRunner._parse_args): Added --replay flag to enable replay tests. + (PerfTestsRunner._collect_tests): Collect .replay files when replay tests are enabled. + (PerfTestsRunner._collect_tests._is_test_file): + (PerfTestsRunner.run): Exit early if one of calls to prepare() fails. + * Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py: + (create_runner): + (run_test): + (_tests_for_runner): + (test_run_test_set): + (test_run_test_set_kills_drt_per_run): + (test_run_test_pause_before_testing): + (test_run_test_set_for_parser_tests): + (test_run_test_set_with_json_output): + (test_run_test_set_with_json_source): + (test_run_test_set_with_multiple_repositories): + (test_run_with_upload_json): + (test_upload_json): + (test_upload_json.MockFileUploader.upload_single_text_file): + (_add_file): + (test_collect_tests): + (test_collect_tests_with_multile_files): + (test_collect_tests_with_multile_files.add_file): + (test_collect_tests_with_skipped_list): + (test_collect_tests_with_page_load_svg): + (test_collect_tests_should_ignore_replay_tests_by_default): + (test_collect_tests_with_replay_tests): + (test_parse_args): + * Scripts/webkitpy/thirdparty/__init__.py: Added the dependency for web-page-replay version 1.1.1. + (AutoinstallImportHook.find_module): + (AutoinstallImportHook._install_webpagereplay): + +2012-05-31 Yaron Friedman <yfriedman@chromium.org> + + Support building the Android port of chromium with Ninja + https://bugs.webkit.org/show_bug.cgi?id=87545 + + Reviewed by Adam Barth. + + Ensures that shared libraries are looked up in a generator-agnostic + way and that output is placed in the correct directory. + + Depends on http://codereview.chromium.org/10386188/ + + * DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp: + +2012-05-31 Ryosuke Niwa <rniwa@webkit.org> + + [Chromium] Chromium DRT should be able to load external resources + https://bugs.webkit.org/show_bug.cgi?id=87893 + + Reviewed by Dirk Pranke. + + Allow external resources to be loaded when the main frame's URL is also an external resource. + This change is analogous to r118231 for Mac port. + + * DumpRenderTree/chromium/WebViewHost.cpp: + (blockRequest): + (isLocalhost): + (hostIsUsedBySomeTestsToGenerateError): + (WebViewHost::willSendRequest): + +2012-05-31 Anders Carlsson <andersca@apple.com> + + Build fixes. + + Disable the C++11 extensions warning. + + * DumpRenderTree/mac/Configurations/Base.xcconfig: + * TestWebKitAPI/Configurations/Base.xcconfig: + * WebKitTestRunner/Configurations/Base.xcconfig: + +2012-05-31 Alexey Proskuryakov <ap@apple.com> + + [WK2] window.internals settings are not reset between tests + https://bugs.webkit.org/show_bug.cgi?id=87783 + + Reviewed by Mihai Parparita. + + * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: + (WTR::InjectedBundle::done): Call resetAfterTest(). + + * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp: + (WTR::InjectedBundlePage::prepare): Renamed from "reset" for clarity. + (WTR::InjectedBundlePage::resetAfterTest): Added a function that resets internals. + This needs to be done after a tets, because the code assumes that there is an object + with this name in global scope. + + * WebKitTestRunner/InjectedBundle/InjectedBundlePage.h: + +2012-05-31 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com> + + [EFL][DRT] EFL's DRT navigation_policy_decision implementation + https://bugs.webkit.org/show_bug.cgi?id=85006 + + Reviewed by Tor Arne Vestbø. + + Added navigation_policy_decision implementation for DumpRenderTreeView. + Added LayoutTestController::setCustomPolicyDelegate implementation. + Modified LayoutTestController::waitForPolicyDelegate. + + * DumpRenderTree/efl/DumpRenderTree.cpp: + * DumpRenderTree/efl/DumpRenderTreeChrome.cpp: + (DumpRenderTreeChrome::resetDefaultsToConsistentValues): + * DumpRenderTree/efl/DumpRenderTreeEfl.h: + * DumpRenderTree/efl/DumpRenderTreeView.cpp: + (navigationTypeToString): aux function + (onNavigationPolicyDecision): navigation_policy_decision implementation + (drtViewAdd): + * DumpRenderTree/efl/LayoutTestControllerEfl.cpp: + (LayoutTestController::setCustomPolicyDelegate): + (LayoutTestController::waitForPolicyDelegate): + +2012-05-31 Jussi Kukkonen <jussi.kukkonen@intel.com> + + [EFL][DRT] LayoutTestController does not implement clearApplicationCacheForOrigin + https://bugs.webkit.org/show_bug.cgi?id=86195 + + Reviewed by Gustavo Noronha Silva. + + Implement clearApplicationCacheForOrigin in EFL + LayoutTestController. + + * DumpRenderTree/efl/LayoutTestControllerEfl.cpp: + (LayoutTestController::clearApplicationCacheForOrigin): + +2012-05-31 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + [Qt] Simplify QT_VERSION_CHECKS for Qt5 by introducing HAVE(QT5) + https://bugs.webkit.org/show_bug.cgi?id=87955 + + Reviewed by Simon Hausmann. + + * DumpRenderTree/qt/DumpRenderTreeQt.cpp: + * DumpRenderTree/qt/EventSenderQt.cpp: + * DumpRenderTree/qt/QtInitializeTestFonts.cpp: + * DumpRenderTree/qt/main.cpp: + * QtTestBrowser/cookiejar.cpp: + * QtTestBrowser/launcherwindow.cpp: + * WebKitTestRunner/InjectedBundle/qt/LayoutTestControllerQt.cpp: + * qmake/mkspecs/features/default_post.prf: + +2012-05-31 Zoltan Horvath <zoltan@webkit.org> + + [Qt] Don't enforce the version of libpng for the config test when passing the option to the linker + + Rubber-stamped by Kenneth Rohde Christiansen. + + * qmake/config.tests/libpng/libpng.pro: + +2012-05-30 Peter Beverloo <peter@chromium.org> + + [Chromium] Automatically install 64-bit linker for Android + https://bugs.webkit.org/show_bug.cgi?id=79780 + + Reviewed by Adam Barth. + + Change the update-webkit-chromium script to check whether the 64-bit + linker needs to be installed as part of the update process. The actual + code for doing these checks and "installing" it has been added to the + webkitdirs.pm script. + + The linker itself is part of the third_party/aosp repository, which + will be pulled in through the DEPS change. + + * Scripts/update-webkit-chromium: + * Scripts/webkitdirs.pm: + (chromiumInstall64BitAndroidLinkerIfNeeded): + (chromiumReplaceAndroidLinkerIfNeeded): + +2012-05-30 Stephanie Lewis <slewis@apple.com> + + https://bugs.webkit.org/show_bug.cgi?id=87803 + Layout tests often fail trying to stat nonexistent logs + + Reviewed by Dirk Pranke. + + CrashReporter removes logs using a heuristic to conserve space. Wrap a + try/catch block around accessing the logs as a precaution. + + * Scripts/webkitpy/common/system/crashlogs.py: + (CrashLogs._find_newest_log_darwin): + +2012-05-30 Gavin Peters <gavinp@chromium.org> + + Add a LayoutTest for prerender remove after stop. + https://bugs.webkit.org/show_bug.cgi?id=87860 + + These very boring mocks in DumpRenderTree mean that the basic Prerendering API + can be tested by LayoutTests now. + + Reviewed by Adam Barth. + + * DumpRenderTree/DumpRenderTree.gypi: + * DumpRenderTree/chromium/MockWebPrerenderingSupport.cpp: Added. + (MockWebPrerenderingSupport::MockWebPrerenderingSupport): + (MockWebPrerenderingSupport::~MockWebPrerenderingSupport): + (MockWebPrerenderingSupport::add): + (MockWebPrerenderingSupport::cancel): + (MockWebPrerenderingSupport::abandon): + * DumpRenderTree/chromium/MockWebPrerenderingSupport.h: Added. + (MockWebPrerenderingSupport): + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::initialize): + * DumpRenderTree/chromium/TestShell.h: + (TestShell): + * DumpRenderTree/chromium/WebViewHost.cpp: + (WebViewHost::willAddPrerender): + (WebViewHost::setWebWidget): + * DumpRenderTree/chromium/WebViewHost.h: + (WebViewHost): + +2012-05-30 Stephanie Lewis <slewis@apple.com> + + https://bugs.webkit.org/show_bug.cgi?id=87717 + Unresponsive WebProcesses can be mistaken for WebProcess crashes. + + Reviewed by Dirk Pranke. + + Change the error message from #CRASHED to #UNRESPONSIVE PROCESS + If there isn't a crash log found for the process add a message saying + the process was unresponsive. + + * Scripts/webkitpy/layout_tests/port/webkit.py: + (WebKitDriver.__init__): + (WebKitDriver._check_for_driver_crash): + (WebKitDriver.run_test): + * Scripts/webkitpy/layout_tests/port/webkit_unittest.py: + (WebKitDriverTest.test_check_for_driver_crash.assert_crash): + (WebKitDriverTest): + (WebKitDriverTest.test_check_for_driver_crash): + * WebKitTestRunner/TestController.cpp: + (WTR): + (WTR::TestController::runTest): + +2012-05-30 Stephanie Lewis <slewis@apple.com> + + https://bugs.webkit.org/show_bug.cgi?id=87714 + Mac crash logs can take a really long time to be written out. + + Reviewed by Dirk Pranke. + + Make a second pass looking for crash logs after the tests have completed running. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (use_trac_links_in_results_html): + (Manager.run): + * Scripts/webkitpy/layout_tests/port/base.py: + (Port.repository_paths): + (Port.look_for_new_crash_logs): + * Scripts/webkitpy/layout_tests/port/mac.py: + (MacPort.look_for_new_crash_logs): + * Scripts/webkitpy/layout_tests/port/mac_unittest.py: + (test_get_crash_log): + (test_look_for_new_crash_logs): + (test_look_for_new_crash_logs.fake_time_cb): + +2012-05-30 Kevin Ollivier <kevino@theolliviers.com> + + [wx] Fix 2.9 issues with c_str() type by using the wx fprintf wrapper. + + * DumpRenderTree/wx/DumpRenderTreeWx.cpp: + (LayoutWebViewEventHandler::OnAlertEvent): + (LayoutWebViewEventHandler::OnConfirmEvent): + (LayoutWebViewEventHandler): + (LayoutWebViewEventHandler::OnPromptEvent): + (LayoutWebViewEventHandler::OnConsoleMessageEvent): + (LayoutWebViewEventHandler::OnReceivedTitleEvent): + +2012-05-30 Ojan Vafai <ojan@chromium.org> + + Only give lint errors for -expected.png png files that lack a checksum + https://bugs.webkit.org/show_bug.cgi?id=87875 + + Reviewed by Tony Chang. + + We have other pngs in the tree, e.g. for the inspector, that legitimately + lack a checksum. + + * Scripts/webkitpy/style/checkers/png.py: + (PNGChecker.check): + * Scripts/webkitpy/style/checkers/png_unittest.py: + (PNGCheckerTest.test_check): + +2012-05-30 Dirk Pranke <dpranke@chromium.org> + + nrwt: seems to leak temp dirs + https://bugs.webkit.org/show_bug.cgi?id=87795 + + Reviewed by Ojan Vafai. + + There appears to be a bug where the chromium bots are creating + temporary directories and not cleaning them up that started + after the switch to WebKitDriver. It's possible that __del__ + wasn't getting called in a timely manner (or at all), and it's + generally bad style to rely on __del__ being called, so this + code changes things so that we create a temp dir in + driver.start() and remove it in driver.stop(). We could be + paranoid and leave the __del__ code in, but there doesn't seem + to be much advantage to it. If there are bugs that result in + drivers being started but not stopped, we have other problems. + + * Scripts/webkitpy/common/system/filesystem_mock.py: + (MockFileSystem.__init__): + (MockFileSystem._mktemp): + (MockFileSystem.mkdtemp): + * Scripts/webkitpy/layout_tests/port/webkit.py: + (WebKitDriver.__init__): + (WebKitDriver._start): + (WebKitDriver.stop): + * Scripts/webkitpy/layout_tests/port/webkit_unittest.py: + (WebKitDriverTest.test_check_for_driver_crash): + (WebKitDriverTest): + (WebKitDriverTest.test_creating_a_port_does_not_write_to_the_filesystem): + (WebKitDriverTest.test_stop_cleans_up_properly): + +2012-05-30 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] EFL's DRT should print the number of MessagePorts for new each new intent + https://bugs.webkit.org/show_bug.cgi?id=86841 + + Reviewed by Adam Barth. + + Print the number of MessagePorts for each new intent in EFL's DRT. + This output is expected by several Web Intents test cases. + + * DumpRenderTree/efl/DumpRenderTreeChrome.cpp: + (DumpRenderTreeChrome::onFrameIntentNew): + +2012-05-30 Kevin Ollivier <kevino@theolliviers.com> + + [wx] Unreviewed build fix after removal of setJavaScriptProfilingEnabled. + + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + +2012-05-30 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] Ewk_Intent_Request's postResult/postFailure should take serialized script values in argument + https://bugs.webkit.org/show_bug.cgi?id=87829 + + Reviewed by Adam Barth. + + EFL's LayoutTestController now makes uses of the new helper method in + DumpRenderTreeSupportEfl in order to send the intent response. This is + now needed because the Ewk_Intent_Request postResult / postFailure + methods were made private. + + * DumpRenderTree/efl/LayoutTestControllerEfl.cpp: + (LayoutTestController::sendWebIntentResponse): + +2012-05-30 Xueqing Huang <huangxueqing@baidu.com> + + eventSender.beginDragWithFiles should be implemented in Windows, which blocked drag and drop related tests. + https://bugs.webkit.org/show_bug.cgi?id=86296 + + Reviewed by Tony Chang. + + * DumpRenderTree/win/DRTDataObject.cpp: Added. + (cfHDropFormat): + (cfFileNameWFormat): + (cfUrlWFormat): + (WCEnumFormatEtc): + (WCEnumFormatEtc::WCEnumFormatEtc): + (WCEnumFormatEtc::QueryInterface): + (WCEnumFormatEtc::AddRef): + (WCEnumFormatEtc::Release): + (WCEnumFormatEtc::Next): + (WCEnumFormatEtc::Skip): + (WCEnumFormatEtc::Reset): + (WCEnumFormatEtc::Clone): + (DRTDataObject::createInstance): + (DRTDataObject::DRTDataObject): + (DRTDataObject::~DRTDataObject): + (DRTDataObject::QueryInterface): + (DRTDataObject::AddRef): + (DRTDataObject::Release): + (DRTDataObject::GetData): + (DRTDataObject::GetDataHere): + (DRTDataObject::QueryGetData): + (DRTDataObject::GetCanonicalFormatEtc): + (DRTDataObject::SetData): + (DRTDataObject::CopyMedium): + (DRTDataObject::EnumFormatEtc): + (DRTDataObject::DAdvise): + (DRTDataObject::DUnadvise): + (DRTDataObject::EnumDAdvise): + (DRTDataObject::clearData): + * DumpRenderTree/win/DRTDataObject.h: Added. + (DRTDataObject): + * DumpRenderTree/win/DRTDropSource.cpp: Added. + (DRTDropSource::DRTDropSource): + (DRTDropSource::~DRTDropSource): + (DRTDropSource::QueryInterface): + (DRTDropSource::AddRef): + (DRTDropSource::Release): + (DRTDropSource::createInstance): + (DRTDropSource::QueryContinueDrag): + (DRTDropSource::GiveFeedback): + * DumpRenderTree/win/DRTDropSource.h: Added. + (DRTDropSource): + * DumpRenderTree/win/DumpRenderTree.vcproj: + * DumpRenderTree/win/EventSender.cpp: + (beginDragWithFilesCallback): + +2012-05-30 Marcelo Lira <marcelo.lira@openbossa.org> + + WebKit2: Implement layoutTestController.setPluginsEnabled() in WebKitTestRunner. + https://bugs.webkit.org/show_bug.cgi?id=58593 + + Adds the ability to change the pluginsEnabled flag in WebCore::Settings + to WebKitTestRunner's LayoutTestController. The flag is modified via the + public C API of the WebProcess. + + Reviewed by Darin Adler. + + * WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl: + * WebKitTestRunner/InjectedBundle/LayoutTestController.cpp: + (WTR::LayoutTestController::setPluginsEnabled): Just calls the + WKBundleSetPluginsEnabled function in the public C API of WebProcess. + * WebKitTestRunner/InjectedBundle/LayoutTestController.h: + +2012-05-30 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com> + + [EFL][DRT] http/tests/navigation/new-window-redirect-history.html does not pass + https://bugs.webkit.org/show_bug.cgi?id=87848 + + Reviewed by Csaba Osztrogonác. + + The reason was that DumpRenderTreeChrome::extraViews() returned copy of the vector + and dumpBackForwardListForWebViews() used iterators belonging actually to different vectors + (browser->extraViews().begin() and browser->extraViews().end()) as if they had belonged to the same vector. + + * DumpRenderTree/efl/DumpRenderTreeChrome.cpp: + (DumpRenderTreeChrome::extraViews): + * DumpRenderTree/efl/DumpRenderTreeChrome.h: + (DumpRenderTreeChrome): + +2012-05-30 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com> + + [EFL][DRT] EFL's DRT needs "postProgressFinishedNotification" message + https://bugs.webkit.org/show_bug.cgi?id=87833 + + Reviewed by Tor Arne Vestbø. + + Print "postProgressFinishedNotification" message if frame load finished + to unskip http/tests/loading/progress-finished-callback.html. + + * DumpRenderTree/efl/DumpRenderTreeChrome.cpp: + (DumpRenderTreeChrome::onFrameLoadFinished): + +2012-05-30 Mariusz Grzegorczyk <mariusz.g@samsung.com>, Ryuan Choi <ryuan.choi@samsung.com> + + [EFL][WK2] Fix WebKit2-EFL build + https://bugs.webkit.org/show_bug.cgi?id=83693 + + Reviewed by Carlos Garcia Campos. + + * CMakeLists.txt: Guard Webkit1 related codes with ENABLE_WEBKIT. + +2012-05-29 János Badics <jbadics@inf.u-szeged.hu> + + [Qt] Modified ORWT and NRWT to check for test expectations in platform/qt-5.0-wk1 too + (They only used to check for Skipped in platform/qt-5.0-wk1) + https://bugs.webkit.org/show_bug.cgi?id=87376 + + Reviewed by Csaba Osztrogonác. + + * Scripts/old-run-webkit-tests: + (buildPlatformResultHierarchy): + * Scripts/webkitpy/layout_tests/port/qt.py: + (QtPort.baseline_search_path): + +2012-05-29 Ojan Vafai <ojan@chromium.org> + + Add a linter error for pngs that lack an embedded checksum + https://bugs.webkit.org/show_bug.cgi?id=87793 + + Reviewed by Dirk Pranke. + + * Scripts/read-checksum-from-png: + * Scripts/webkitpy/common/read_checksum_from_png.py: Renamed from Tools/Scripts/webkitpy/layout_tests/read_checksum_from_png.py. + (read_checksum): + * Scripts/webkitpy/common/read_checksum_from_png_unittest.py: Renamed from Tools/Scripts/webkitpy/layout_tests/read_checksum_from_png_unittest.py. + (ReadChecksumFromPngTest): + (ReadChecksumFromPngTest.test_read_checksum): + * Scripts/webkitpy/layout_tests/port/base.py: + * Scripts/webkitpy/style/checkers/png.py: + (PNGChecker.check): + * Scripts/webkitpy/style/checkers/png_unittest.py: + (PNGCheckerTest.test_check): + +2012-05-29 Stephanie Lewis <slewis@apple.com> + + https://bugs.webkit.org/show_bug.cgi?id=87720 + WebProcess is often killed due to being unresponsive on the bots + + Reviewed by Alexey Proskuryakov. + + Blind attempt to improve flakiness on the bots by reducing the number + of crashes due to an unresponsive process. This helped on my personal machine + under stress conditions. I don't have enough cores to hit the problem + under normal conditions. + + * WebKitTestRunner/TestController.cpp: + (WTR): + +2012-05-29 Dirk Pranke <dpranke@chromium.org> + + webkitpy: rename 'rm' to 'delete' in rebaseline scm output + https://bugs.webkit.org/show_bug.cgi?id=87779 + + Reviewed by Eric Seidel. + + Update output to match the names in scm.py as per + https://bugs.webkit.org/show_bug.cgi?id=87451#c26 . + + * Scripts/webkitpy/tool/commands/rebaseline.py: + (RebaselineTest.execute): + * Scripts/webkitpy/tool/commands/rebaseline_unittest.py: + (test_rebaseline_test_and_print_scm_changes): + * Scripts/webkitpy/tool/servers/gardeningserver_unittest.py: + (GardeningServerTest.test_rebaselineall): + +2012-05-29 Stephanie Lewis <slewis@apple.com> + + https://bugs.webkit.org/show_bug.cgi?id=87711 + + Reviewed by Jessie Berlin. + + Remove Snowleopard testers so the hardware can be repurposed. The lion bots + are better maintained. + + * BuildSlaveSupport/build.webkit.org-config/config.json: + +2012-05-29 Dirk Pranke <dpranke@chromium.org> + + webkit-patch optimize-baselines should add/delete files in batches from the vcs + https://bugs.webkit.org/show_bug.cgi?id=87538 + + Reviewed by Ojan Vafai. + + Invoking git and svn on one file at a time is kinda slow. We + should batch the add and rm operations together. + + * Scripts/webkitpy/common/checkout/baselineoptimizer.py: + (BaselineOptimizer._move_baselines): + +2012-05-29 Dirk Pranke <dpranke@chromium.org> + + garden-o-matic should rebaseline baselines in parallel + https://bugs.webkit.org/show_bug.cgi?id=87451 + + Reviewed by Ojan Vafai. + + This modifies garden-o-matic so that we will fetch all + of the baselines in parallel from the bots, and then + optimize the baselines serially (since that should be fairly + quick and we get into trouble if we optimize in parallel due + to concurrent access to the source control system). + + This change adds a flag to webkit-patch rebaseline-test (--print-scm-changes) + so that the files that need to be modified in the SCM are returned to + garden-o-matic rather than actually added or removed. This is done so that + we can run multiple rebaseline-tests in parallel (we can't modify the SCM + concurrently). In order to safely return the files (as a JSON dict) I + needed to shift all of the logging in rebaseline-test to use the logging + module (and hence log to stderr). + + I also had to stub out a line in chromium.py that would get confused if + the skia overrides file didn't exist in a mock checkout. + + * Scripts/webkitpy/common/system/executive.py: + (Executive.popen): + (Executive): + (Executive.run_in_parallel): + (_run_command_thunk): + * Scripts/webkitpy/common/system/executive_mock.py: + (MockExecutive.run_in_parallel): + * Scripts/webkitpy/common/system/executive_unittest.py: + (ExecutiveTest.test_run_in_parallel): + * Scripts/webkitpy/layout_tests/port/chromium.py: + (ChromiumPort._expectations_file_contents): + * Scripts/webkitpy/tool/commands/rebaseline.py: + (AbstractRebaseliningCommand.__init__): + (RebaselineTest.__init__): + (RebaselineTest._copy_existing_baseline): + (RebaselineTest._save_baseline): + (RebaselineTest): + (RebaselineTest._add_to_scm): + (RebaselineTest._rebaseline_test): + (RebaselineTest.execute): + (RebaselineExpectations._rebaseline_port): + (RebaselineExpectations.execute): + (Rebaseline._builder_to_pull_from): + (Rebaseline.execute): + * Scripts/webkitpy/tool/commands/rebaseline_unittest.py: + (test_rebaseline_updates_expectations_file): + (test_rebaseline_test): + (test_rebaseline_test_and_print_scm_changes): + (test_rebaseline_and_copy_test): + (test_rebaseline_and_copy_test_no_existing_result): + (test_rebaseline_and_copy_test_with_lion_result): + (test_rebaseline_and_copy_no_overwrite_test): + (test_rebaseline_expectations): + * Scripts/webkitpy/tool/servers/gardeningserver.py: + (GardeningHTTPRequestHandler._rebaseline_commands): + (GardeningHTTPRequestHandler): + (GardeningHTTPRequestHandler._files_to_add): + (GardeningHTTPRequestHandler._optimize_baselines): + (GardeningHTTPRequestHandler.rebaselineall): + * Scripts/webkitpy/tool/servers/gardeningserver_unittest.py: + (GardeningServerTest._post_to_path): + (GardeningServerTest.test_rebaselineall): + (GardeningServerTest.test_rebaselineall.run_command): + +2012-05-29 Benjamin Poulain <bpoulain@apple.com> + + Fix the type of dispatch_time() offset + + Rubber-stamped by Joseph Pecoraro. + + In r118631, I erroneously used the type NSTimeInterval for the delta of dispatch_time(). + + * DumpRenderTree/mac/FrameLoadDelegate.mm: + (-[FrameLoadDelegate webView:didStartProvisionalLoadForFrame:]): + +2012-05-29 Arvid Nilsson <anilsson@rim.com> + + 2012-05-29 Arvid Nilsson <anilsson@rim.com> + + [BlackBerry] OpenGL content is not rendered on simulator + https://bugs.webkit.org/show_bug.cgi?id=87721 + + Reviewed by George Staikos. + + Fixed by enabling GLES2 support in simulator builds. + + To experiment with building without OpenGL support, you can set the + DISABLE_GLES2 environment variable to a non-empty string and rebuild. + + PR #150695 + + * Scripts/webkitdirs.pm: + (blackberryCMakeArguments): + +2012-05-29 David Barr <davidbarr@chromium.org> + + Introduce ENABLE_CSS_IMAGE_RESOLUTION compile flag + https://bugs.webkit.org/show_bug.cgi?id=87685 + + Reviewed by Eric Seidel. + + Add a configuration option for CSS image-resolution support, disabling it by default. + + * Scripts/webkitperl/FeatureList.pm: + * qmake/mkspecs/features/features.pri: + +2012-05-29 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + [Qt] Don't add cxx-flags to QMAKE_CFLAGS + + Prevents warnings such as: "command line option ‘-Wno-c++0x-compat’ is + valid for C++/ObjC++ but not for C [enabled by default]" + + Reviewed by Simon Hausmann. + + * qmake/mkspecs/features/unix/default_post.prf: + +2012-05-29 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + [Qt] Sync up favicon-implementation with WebView url changes in r118158 + + https://bugs.webkit.org/show_bug.cgi?id=87133 + + We now base64-encode the page url in the image-provider url, so that any + normalization done by QUrl will not mess up the page-url. The logic of + creating and parsing the provider-url has been moved into the image + provider, to keep it in one place. + + We were also releasing icons (even ones we hadn't retained), which we can't + do since we don't know when the icon url is no longer in use. + + Reviewed-by Simon Hausmann. + + * MiniBrowser/qt/icons/favicon.png: + * MiniBrowser/qt/qml/BrowserWindow.qml: + +2012-05-29 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com> + + [EFL] Refactoring. Get rid of unnecessary singleCharacterString() function + https://bugs.webkit.org/show_bug.cgi?id=87654 + + Reviewed by Csaba Osztrogonác. + + Event sender provides strings for all the key events. + Also KeyEventInfo constructor parameters order was changed to simplify the case when + a key event has empty string. + + * DumpRenderTree/efl/EventSender.cpp: + (KeyEventInfo::KeyEventInfo): + (keyPadNameFromJSValue): + (keyNameFromJSValue): + +2012-05-23 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + [Qt] Cancel potential url-edit when going back/forward + + Reviewed by Kenneth Rohde Christiansen. + + * MiniBrowser/qt/qml/BrowserWindow.qml: + +2012-05-29 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] Compilation warning in DumpRenderTreeView.cpp + https://bugs.webkit.org/show_bug.cgi?id=87636 + + Reviewed by Filip Pizlo. + + Fix compilation error in DumpRenderTreeView.cpp due to wrong format + specifier in printf. Also fix the return type for + onExceededApplicationCacheQuota callback. + + * DumpRenderTree/efl/DumpRenderTreeView.cpp: + (onExceededApplicationCacheQuota): + +2012-05-29 Hironori Bono <hbono@chromium.org> + + Adding Hironori Bono to committers.py. + https://bugs.webkit.org/show_bug.cgi?id=87697 + + * Scripts/webkitpy/common/config/committers.py: + +2012-05-28 Jonathan Dong <jonathan.dong@torchmobile.com.cn> + + [BlackBerry] http authenticate dialog popup only once no matter authentication pass or fail + https://bugs.webkit.org/show_bug.cgi?id=80135 + + Reviewed by Rob Buis. + + Implemented interface function didReceiveAuthenticationChallenge in class + DumpRenderTree. + + Resubmit the patch reverted by r115104 after the digest infinite loop + issue for BlackBerry porting get identified and fixed. + + Internally reviewed by Joe Mason <jmason@rim.com> + + * DumpRenderTree/blackberry/DumpRenderTree.cpp: + (drtCredentialDescription): + (BlackBerry::WebKit::DumpRenderTree::didReceiveAuthenticationChallenge): + (WebKit): + * DumpRenderTree/blackberry/DumpRenderTreeBlackBerry.h: + (WebCore): + (DumpRenderTree): + +2012-05-25 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org> + + WebKitTestRunner needs to support layoutTestController.setJavaScriptProfilingEnabled + https://bugs.webkit.org/show_bug.cgi?id=42328 + + Reviewed by Eric Seidel. + + Removed unneeded setJavaScriptProfilingEnabled function from DRT after its + move to windows.internals.settings. + + * DumpRenderTree/LayoutTestController.cpp: + (LayoutTestController::staticFunctions): + * DumpRenderTree/LayoutTestController.h: + (LayoutTestController): + * DumpRenderTree/blackberry/LayoutTestControllerBlackBerry.cpp: + * DumpRenderTree/chromium/DRTDevToolsAgent.cpp: + * DumpRenderTree/chromium/DRTDevToolsAgent.h: + (DRTDevToolsAgent): + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::LayoutTestController): + * DumpRenderTree/chromium/LayoutTestController.h: + (LayoutTestController): + * DumpRenderTree/efl/DumpRenderTreeChrome.cpp: + (DumpRenderTreeChrome::resetDefaultsToConsistentValues): + * DumpRenderTree/efl/LayoutTestControllerEfl.cpp: + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetWebViewToConsistentStateBeforeTesting): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + * DumpRenderTree/qt/LayoutTestControllerQt.cpp: + * DumpRenderTree/qt/LayoutTestControllerQt.h: + (LayoutTestController): + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetWebViewToConsistentStateBeforeTesting): + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + * WebKitTestRunner/InjectedBundle/LayoutTestController.cpp: + * WebKitTestRunner/InjectedBundle/LayoutTestController.h: + (LayoutTestController): + +2012-05-28 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Move allowRoundingHacks to Internals interface + https://bugs.webkit.org/show_bug.cgi?id=87328 + + Reviewed by Hajime Morita. + + Remove allowRoundingHacks functions, because it is able to work in the + cross-port way through the Internals interface. + + * DumpRenderTree/LayoutTestController.cpp: + (LayoutTestController::staticFunctions): + * DumpRenderTree/LayoutTestController.h: + (LayoutTestController): + * DumpRenderTree/blackberry/LayoutTestControllerBlackBerry.cpp: + * DumpRenderTree/efl/LayoutTestControllerEfl.cpp: + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + +2012-05-28 Luke Macpherson <macpherson@chromium.org> + + Fix mac build with older XCode by defining NSEC_PER_MSEC. + https://bugs.webkit.org/show_bug.cgi?id=87616 + + Reviewed by Hajime Morita. + + The following patch introduced the use of NSEC_PER_MSEC which is not defined for older XCode versions. + http://trac.webkit.org/changeset/118631/trunk/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm + Patch just adds a #ifndef / #define check. + + * DumpRenderTree/mac/FrameLoadDelegate.mm: + (-[FrameLoadDelegate webView:didStartProvisionalLoadForFrame:]): + +2012-05-27 Sudarsana Nagineni <sudarsana.nagineni@linux.intel.com> + + [EFL] Enable blob support for the EFL port + https://bugs.webkit.org/show_bug.cgi?id=85363 + + Reviewed by Hajime Morita. + + Enable Blob support by default for the EFL port. + + * Scripts/webkitperl/FeatureList.pm: + +2012-05-27 Benjamin Poulain <bpoulain@apple.com> + + When pages are loaded from AppCache with DeferredLoading, willSendRequest() is never called + https://bugs.webkit.org/show_bug.cgi?id=87582 + + Reviewed by Darin Adler. + + Extend DumpRenderTree to support loading the main resource deferred with a delay. This makes it + possible to test pages in a similar way as they are loaded in Browsers. + + * DumpRenderTree/LayoutTestController.cpp: + (LayoutTestController::LayoutTestController): + (setUseDeferredFrameLoadingCallback): + (LayoutTestController::staticFunctions): + * DumpRenderTree/LayoutTestController.h: + (LayoutTestController::useDeferredFrameLoading): + (LayoutTestController::setUseDeferredFrameLoading): + (LayoutTestController): + * DumpRenderTree/mac/FrameLoadDelegate.mm: + (-[FrameLoadDelegate webView:didStartProvisionalLoadForFrame:]): + 2012-05-27 David Barton <dbarton@mathscribe.com> [watchlist] Improve MathML rule diff --git a/Tools/DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp b/Tools/DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp index 92e6b104d..edae3aaeb 100644 --- a/Tools/DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp +++ b/Tools/DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp @@ -416,7 +416,7 @@ 'action_name': 'generate_and_build', 'inputs': [ '<(chromium_src_dir)/testing/android/generate_native_test.py', - '<(PRODUCT_DIR)/lib.target/libDumpRenderTree.so', + '<(SHARED_LIB_DIR)/<(SHARED_LIB_PREFIX)DumpRenderTree<(SHARED_LIB_SUFFIX)', # FIXME: Build the jar for native tests with SDK. # For now we are using Android.mk to build the apk. ], @@ -426,14 +426,14 @@ 'action': [ '<(chromium_src_dir)/testing/android/generate_native_test.py', '--native_library', - '<(PRODUCT_DIR)/lib.target/libDumpRenderTree.so', + '<(SHARED_LIB_DIR)/<(SHARED_LIB_PREFIX)DumpRenderTree<(SHARED_LIB_SUFFIX)', # FIXME: Build the jar for native tests with SDK. # '--jar', # 'foo/bar.jar', '--output', '<(PRODUCT_DIR)/DumpRenderTree_apk', '--ant-args', - '-DPRODUCT_DIR=<(PRODUCT_DIR)', + '-DPRODUCT_DIR=<(ant_build_out)', '--ant-compile' ], }], diff --git a/Tools/DumpRenderTree/DumpRenderTree.gypi b/Tools/DumpRenderTree/DumpRenderTree.gypi index 55b58aed6..e8d88be74 100644 --- a/Tools/DumpRenderTree/DumpRenderTree.gypi +++ b/Tools/DumpRenderTree/DumpRenderTree.gypi @@ -24,6 +24,8 @@ 'chromium/MockGrammarCheck.h', 'chromium/MockSpellCheck.cpp', 'chromium/MockSpellCheck.h', + 'chromium/MockWebPrerenderingSupport.cpp', + 'chromium/MockWebPrerenderingSupport.h', 'chromium/MockWebSpeechInputController.cpp', 'chromium/MockWebSpeechInputController.h', 'chromium/NotificationPresenter.h', diff --git a/Tools/DumpRenderTree/LayoutTestController.cpp b/Tools/DumpRenderTree/LayoutTestController.cpp index f91c874d4..f1dee2419 100644 --- a/Tools/DumpRenderTree/LayoutTestController.cpp +++ b/Tools/DumpRenderTree/LayoutTestController.cpp @@ -89,6 +89,7 @@ LayoutTestController::LayoutTestController(const std::string& testPathOrURL, con , m_handlesAuthenticationChallenges(false) , m_isPrinting(false) , m_deferMainResourceDataLoad(true) + , m_useDeferredFrameLoading(false) , m_shouldPaintBrokenImage(true) , m_shouldStayOnPageAfterHandlingBeforeUnload(false) , m_areDesktopNotificationPermissionRequestsIgnored(false) @@ -1231,6 +1232,17 @@ static JSValueRef setDefersLoadingCallback(JSContextRef context, JSObjectRef fun return JSValueMakeUndefined(context); } +static JSValueRef setUseDeferredFrameLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setUseDeferredFrameLoading(JSValueToBoolean(context, arguments[0])); + + return JSValueMakeUndefined(context); +} + static JSValueRef setDomainRelaxationForbiddenForURLSchemeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has Mac and Windows implementation @@ -1388,17 +1400,6 @@ static JSValueRef setIconDatabaseEnabledCallback(JSContextRef context, JSObjectR return JSValueMakeUndefined(context); } -static JSValueRef setJavaScriptProfilingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount < 1) - return JSValueMakeUndefined(context); - - LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); - controller->setJavaScriptProfilingEnabled(JSValueToBoolean(context, arguments[0])); - - return JSValueMakeUndefined(context); -} - static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { // Has mac implementation @@ -2063,14 +2064,6 @@ static JSValueRef setSerializeHTTPLoadsCallback(JSContextRef context, JSObjectRe return JSValueMakeUndefined(context); } -static JSValueRef allowRoundingHacksCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); - - controller->allowRoundingHacks(); - return JSValueMakeUndefined(context); -} - static JSValueRef setShouldStayOnPageAfterHandlingBeforeUnloadCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); @@ -2372,12 +2365,12 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setDeferMainResourceDataLoad", setDeferMainResourceDataLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setDefersLoading", setDefersLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setUseDeferredFrameLoading", setUseDeferredFrameLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setDomainRelaxationForbiddenForURLScheme", setDomainRelaxationForbiddenForURLSchemeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setFrameFlatteningEnabled", setFrameFlatteningEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setGeolocationPermission", setGeolocationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setHandlesAuthenticationChallenges", setHandlesAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "setJavaScriptProfilingEnabled", setJavaScriptProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAutomaticLinkDetectionEnabled", setAutomaticLinkDetectionEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setMinimumTimerInterval", setMinimumTimerIntervalCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2431,7 +2424,6 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "originsWithLocalStorage", originsWithLocalStorageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setShouldPaintBrokenImage", setShouldPaintBrokenImageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setTextDirection", setTextDirectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "allowRoundingHacks", allowRoundingHacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setShouldStayOnPageAfterHandlingBeforeUnload", setShouldStayOnPageAfterHandlingBeforeUnloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "addChromeInputField", addChromeInputFieldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "removeChromeInputField", removeChromeInputFieldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, diff --git a/Tools/DumpRenderTree/LayoutTestController.h b/Tools/DumpRenderTree/LayoutTestController.h index 2b9f5fe24..6f02db3a1 100644 --- a/Tools/DumpRenderTree/LayoutTestController.h +++ b/Tools/DumpRenderTree/LayoutTestController.h @@ -100,7 +100,6 @@ public: void setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme); void setDefersLoading(bool); void setIconDatabaseEnabled(bool iconDatabaseEnabled); - void setJavaScriptProfilingEnabled(bool profilingEnabled); void setJavaScriptCanAccessClipboard(bool flag); void setAutomaticLinkDetectionEnabled(bool flag); void setMainFrameIsFirstResponder(bool flag); @@ -282,6 +281,9 @@ public: bool deferMainResourceDataLoad() const { return m_deferMainResourceDataLoad; } void setDeferMainResourceDataLoad(bool flag) { m_deferMainResourceDataLoad = flag; } + bool useDeferredFrameLoading() const { return m_useDeferredFrameLoading; } + void setUseDeferredFrameLoading(bool flag) { m_useDeferredFrameLoading = flag; } + const std::string& testPathOrURL() const { return m_testPathOrURL; } const std::string& expectedPixelHash() const { return m_expectedPixelHash; } @@ -309,7 +311,6 @@ public: void evaluateInWebInspector(long callId, JSStringRef script); void evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script); void evaluateScriptInIsolatedWorldAndReturnValue(unsigned worldID, JSObjectRef globalObject, JSStringRef script); - void allowRoundingHacks(); bool shouldStayOnPageAfterHandlingBeforeUnload() const { return m_shouldStayOnPageAfterHandlingBeforeUnload; } void setShouldStayOnPageAfterHandlingBeforeUnload(bool shouldStayOnPageAfterHandlingBeforeUnload) { m_shouldStayOnPageAfterHandlingBeforeUnload = shouldStayOnPageAfterHandlingBeforeUnload; } @@ -412,6 +413,7 @@ private: bool m_handlesAuthenticationChallenges; bool m_isPrinting; bool m_deferMainResourceDataLoad; + bool m_useDeferredFrameLoading; bool m_shouldPaintBrokenImage; bool m_shouldStayOnPageAfterHandlingBeforeUnload; bool m_areDesktopNotificationPermissionRequestsIgnored; diff --git a/Tools/DumpRenderTree/blackberry/DumpRenderTree.cpp b/Tools/DumpRenderTree/blackberry/DumpRenderTree.cpp index 620e6acd5..a19742c33 100644 --- a/Tools/DumpRenderTree/blackberry/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/blackberry/DumpRenderTree.cpp @@ -24,6 +24,7 @@ #include "BackForwardController.h" #include "BackForwardListImpl.h" #include "CString.h" +#include "Credential.h" #include "DatabaseTracker.h" #include "DocumentLoader.h" #include "DumpRenderTree/GCController.h" @@ -124,6 +125,12 @@ static String drtFrameDescription(WebCore::Frame* frame) return "frame (anonymous)"; } +static WTF::String drtCredentialDescription(WebCore::Credential&) +{ + // TODO: Implementation needed. + return "<unknown>"; +} + static bool shouldLogFrameLoadDelegates(const String& url) { return url.contains("loading/"); @@ -857,6 +864,20 @@ void DumpRenderTree::didReceiveResponseForFrame(WebCore::Frame* frame, const Web printf("%s has MIME type %s\n", response.url().lastPathComponent().utf8().data(), response.mimeType().utf8().data()); } +bool DumpRenderTree::didReceiveAuthenticationChallenge(WebCore::Credential& credential) +{ + if (!gLayoutTestController->handlesAuthenticationChallenges()) { + credential = WebCore::Credential(); + printf("%s - didReceiveAuthenticationChallenge - Simulating cancelled authentication\n", drtCredentialDescription(credential).utf8().data()); + return false; + } + const char* user = gLayoutTestController->authenticationUsername().c_str(); + const char* password = gLayoutTestController->authenticationPassword().c_str(); + credential = WebCore::Credential(user, password, WebCore::CredentialPersistenceForSession); + printf("%s - didReceiveAuthenticationChallenge - Responding with %s:%s\n", drtCredentialDescription(credential).utf8().data(), user, password); + return true; +} + } } diff --git a/Tools/DumpRenderTree/blackberry/DumpRenderTreeBlackBerry.h b/Tools/DumpRenderTree/blackberry/DumpRenderTreeBlackBerry.h index 2ff69161c..c6eba9d19 100644 --- a/Tools/DumpRenderTree/blackberry/DumpRenderTreeBlackBerry.h +++ b/Tools/DumpRenderTree/blackberry/DumpRenderTreeBlackBerry.h @@ -28,8 +28,9 @@ #include <wtf/Vector.h> namespace WebCore { -class Frame; +class Credential; class DOMWrapperWorld; +class Frame; class Range; } @@ -101,6 +102,7 @@ public: bool isSelectTrailingWhitespaceEnabled() const { return s_selectTrailingWhitespaceEnabled; } void setSelectTrailingWhitespaceEnabled(bool enabled) { s_selectTrailingWhitespaceEnabled = enabled; } + bool didReceiveAuthenticationChallenge(WebCore::Credential&); private: void runTest(const String& url); diff --git a/Tools/DumpRenderTree/blackberry/LayoutTestControllerBlackBerry.cpp b/Tools/DumpRenderTree/blackberry/LayoutTestControllerBlackBerry.cpp index aee4e6f20..c97ba39c1 100644 --- a/Tools/DumpRenderTree/blackberry/LayoutTestControllerBlackBerry.cpp +++ b/Tools/DumpRenderTree/blackberry/LayoutTestControllerBlackBerry.cpp @@ -234,12 +234,6 @@ void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled) notImplemented(); } -void LayoutTestController::setJavaScriptProfilingEnabled(bool profilingEnabled) -{ - UNUSED_PARAM(profilingEnabled); - notImplemented(); -} - void LayoutTestController::setMainFrameIsFirstResponder(bool flag) { UNUSED_PARAM(flag); @@ -705,11 +699,6 @@ void LayoutTestController::setTextDirection(JSStringRef) notImplemented(); } -void LayoutTestController::allowRoundingHacks() -{ - notImplemented(); -} - void LayoutTestController::goBack() { // FIXME: implement to enable loader/navigation-while-deferring-loads.html diff --git a/Tools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp b/Tools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp index 21aed1b9d..b6659a47f 100644 --- a/Tools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp +++ b/Tools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp @@ -112,15 +112,6 @@ void DRTDevToolsAgent::detach() m_drtDevToolsClient = 0; } -bool DRTDevToolsAgent::setJavaScriptProfilingEnabled(bool enabled) -{ - WebDevToolsAgent* agent = webDevToolsAgent(); - if (!agent) - return false; - agent->setJavaScriptProfilingEnabled(enabled); - return true; -} - bool DRTDevToolsAgent::evaluateInWebInspector(long callID, const std::string& script) { WebDevToolsAgent* agent = webDevToolsAgent(); diff --git a/Tools/DumpRenderTree/chromium/DRTDevToolsAgent.h b/Tools/DumpRenderTree/chromium/DRTDevToolsAgent.h index 6e491ad53..f3564bd78 100644 --- a/Tools/DumpRenderTree/chromium/DRTDevToolsAgent.h +++ b/Tools/DumpRenderTree/chromium/DRTDevToolsAgent.h @@ -69,7 +69,6 @@ public: void detach(); bool evaluateInWebInspector(long callID, const std::string& script); - bool setJavaScriptProfilingEnabled(bool); TaskList* taskList() { return &m_taskList; } private: diff --git a/Tools/DumpRenderTree/chromium/LayoutTestController.cpp b/Tools/DumpRenderTree/chromium/LayoutTestController.cpp index 38c2ad652..c739143e0 100644 --- a/Tools/DumpRenderTree/chromium/LayoutTestController.cpp +++ b/Tools/DumpRenderTree/chromium/LayoutTestController.cpp @@ -196,7 +196,6 @@ LayoutTestController::LayoutTestController(TestShell* shell) bindMethod("setGeolocationPermission", &LayoutTestController::setGeolocationPermission); bindMethod("setIconDatabaseEnabled", &LayoutTestController::setIconDatabaseEnabled); bindMethod("setJavaScriptCanAccessClipboard", &LayoutTestController::setJavaScriptCanAccessClipboard); - bindMethod("setJavaScriptProfilingEnabled", &LayoutTestController::setJavaScriptProfilingEnabled); bindMethod("setMinimumTimerInterval", &LayoutTestController::setMinimumTimerInterval); bindMethod("setMockDeviceOrientation", &LayoutTestController::setMockDeviceOrientation); bindMethod("setMockGeolocationError", &LayoutTestController::setMockGeolocationError); @@ -1831,14 +1830,6 @@ void LayoutTestController::logErrorToConsole(const std::string& text) WebString(), 0); } -void LayoutTestController::setJavaScriptProfilingEnabled(const CppArgumentList& arguments, CppVariant* result) -{ - result->setNull(); - if (arguments.size() < 1 || !arguments[0].isBool()) - return; - m_shell->drtDevToolsAgent()->setJavaScriptProfilingEnabled(arguments[0].toBoolean()); -} - void LayoutTestController::evaluateInWebInspector(const CppArgumentList& arguments, CppVariant* result) { result->setNull(); diff --git a/Tools/DumpRenderTree/chromium/LayoutTestController.h b/Tools/DumpRenderTree/chromium/LayoutTestController.h index 0703ef010..37978657e 100644 --- a/Tools/DumpRenderTree/chromium/LayoutTestController.h +++ b/Tools/DumpRenderTree/chromium/LayoutTestController.h @@ -349,9 +349,6 @@ public: // Gets the number of geolocation permissions requests pending. void numberOfPendingGeolocationPermissionRequests(const CppArgumentList&, CppVariant*); - // Allows layout tests to start JavaScript profiling. - void setJavaScriptProfilingEnabled(const CppArgumentList&, CppVariant*); - // Allows layout tests to exec scripts at WebInspector side. void evaluateInWebInspector(const CppArgumentList&, CppVariant*); diff --git a/Tools/DumpRenderTree/chromium/MockWebPrerenderingSupport.cpp b/Tools/DumpRenderTree/chromium/MockWebPrerenderingSupport.cpp new file mode 100644 index 000000000..d667d8865 --- /dev/null +++ b/Tools/DumpRenderTree/chromium/MockWebPrerenderingSupport.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "MockWebPrerenderingSupport.h" + +#include <wtf/Assertions.h> + +MockWebPrerenderingSupport::MockWebPrerenderingSupport() +{ + ASSERT(!current()); + initialize(this); +} + +MockWebPrerenderingSupport::~MockWebPrerenderingSupport() +{ + ASSERT(current() == this); + shutdown(); +} + +void MockWebPrerenderingSupport::add(const WebKit::WebPrerender&) +{ +} + +void MockWebPrerenderingSupport::cancel(const WebKit::WebPrerender&) +{ +} + +void MockWebPrerenderingSupport::abandon(const WebKit::WebPrerender&) +{ +} diff --git a/Tools/DumpRenderTree/chromium/MockWebPrerenderingSupport.h b/Tools/DumpRenderTree/chromium/MockWebPrerenderingSupport.h new file mode 100644 index 000000000..b5d4af53d --- /dev/null +++ b/Tools/DumpRenderTree/chromium/MockWebPrerenderingSupport.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 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. + */ + +#ifndef MockWebPrerenderingSupport_h +#define MockWebPrerenderingSupport_h + +#include "third_party/WebKit/Source/Platform/chromium/public/WebPrerenderingSupport.h" + +class MockWebPrerenderingSupport : public WebKit::WebPrerenderingSupport { +public: + MockWebPrerenderingSupport(); + virtual ~MockWebPrerenderingSupport(); + +private: + void add(const WebKit::WebPrerender&) OVERRIDE; + void cancel(const WebKit::WebPrerender&) OVERRIDE; + void abandon(const WebKit::WebPrerender&) OVERRIDE; +}; + +#endif // MockWebPrerenderingSupport_h diff --git a/Tools/DumpRenderTree/chromium/TestShell.cpp b/Tools/DumpRenderTree/chromium/TestShell.cpp index 07a72e3f4..9b9ca4a5b 100644 --- a/Tools/DumpRenderTree/chromium/TestShell.cpp +++ b/Tools/DumpRenderTree/chromium/TestShell.cpp @@ -34,6 +34,7 @@ #include "DRTDevToolsAgent.h" #include "DRTDevToolsClient.h" #include "LayoutTestController.h" +#include "MockWebPrerenderingSupport.h" #include "platform/WebArrayBufferView.h" #include "WebCompositor.h" #include "WebDataSource.h" @@ -66,6 +67,7 @@ #include <wtf/MD5.h> #include <wtf/OwnArrayPtr.h> + using namespace WebKit; using namespace std; @@ -147,6 +149,7 @@ void TestShell::initialize() m_webPermissions = adoptPtr(new WebPermissions(this)); m_accessibilityController = adoptPtr(new AccessibilityController(this)); m_gamepadController = adoptPtr(new GamepadController(this)); + m_layoutTestController = adoptPtr(new LayoutTestController(this)); m_eventSender = adoptPtr(new EventSender(this)); m_textInputController = adoptPtr(new TextInputController(this)); @@ -154,6 +157,9 @@ void TestShell::initialize() m_notificationPresenter = adoptPtr(new NotificationPresenter(this)); #endif m_printer = m_testShellMode ? TestEventPrinter::createTestShellPrinter() : TestEventPrinter::createDRTPrinter(); +#if ENABLE(LINK_PRERENDER) + m_prerenderingSupport = adoptPtr(new MockWebPrerenderingSupport()); +#endif WTF::initializeThreading(); diff --git a/Tools/DumpRenderTree/chromium/TestShell.h b/Tools/DumpRenderTree/chromium/TestShell.h index fc340248d..ae9d8d8a1 100644 --- a/Tools/DumpRenderTree/chromium/TestShell.h +++ b/Tools/DumpRenderTree/chromium/TestShell.h @@ -59,6 +59,7 @@ class WebURL; class DRTDevToolsAgent; class DRTDevToolsCallArgs; class DRTDevToolsClient; +class MockWebPrerenderingSupport; class WebPermissions; struct TestParams { @@ -224,6 +225,9 @@ private: #endif OwnPtr<WebViewHost> m_webViewHost; OwnPtr<WebKit::WebThread> m_webCompositorThread; +#if ENABLE(LINK_PRERENDER) + OwnPtr<MockWebPrerenderingSupport> m_prerenderingSupport; +#endif TestParams m_params; int m_timeout; // timeout value in millisecond diff --git a/Tools/DumpRenderTree/chromium/WebViewHost.cpp b/Tools/DumpRenderTree/chromium/WebViewHost.cpp index ef82f2b88..6c48bc1e1 100644 --- a/Tools/DumpRenderTree/chromium/WebViewHost.cpp +++ b/Tools/DumpRenderTree/chromium/WebViewHost.cpp @@ -450,6 +450,15 @@ bool WebViewHost::handleCurrentKeyboardEvent() return frame->executeCommand(WebString::fromUTF8(m_editCommandName), WebString::fromUTF8(m_editCommandValue)); } +// WebKit::WebPrerendererClient + +void WebViewHost::willAddPrerender(WebKit::WebPrerender*) +{ +} + + +// WebKit::WebSpellCheckClient + void WebViewHost::spellCheck(const WebString& text, int& misspelledOffset, int& misspelledLength, WebVector<WebString>* optionalSuggestions) { // Check the spelling of the given text. @@ -1206,6 +1215,21 @@ void WebViewHost::removeIdentifierForRequest(unsigned identifier) m_resourceIdentifierMap.remove(identifier); } +static void blockRequest(WebURLRequest& request) +{ + request.setURL(WebURL()); +} + +static bool isLocalhost(const string& host) +{ + return host == "127.0.0.1" || host == "localhost"; +} + +static bool hostIsUsedBySomeTestsToGenerateError(const string& host) +{ + return host == "255.255.255.255"; +} + void WebViewHost::willSendRequest(WebFrame* frame, unsigned identifier, WebURLRequest& request, const WebURLResponse& redirectResponse) { // Need to use GURL for host() and SchemeIs() @@ -1228,29 +1252,25 @@ void WebViewHost::willSendRequest(WebFrame* frame, unsigned identifier, WebURLRe if (!redirectResponse.isNull() && m_blocksRedirects) { fputs("Returning null for this redirect\n", stdout); - // To block the request, we set its URL to an empty one. - request.setURL(WebURL()); + blockRequest(request); return; } if (m_requestReturnNull) { - // To block the request, we set its URL to an empty one. - request.setURL(WebURL()); + blockRequest(request); return; } string host = url.host(); - // 255.255.255.255 is used in some tests that expect to get back an error. - if (!host.empty() && (url.SchemeIs("http") || url.SchemeIs("https")) - && host != "127.0.0.1" - && host != "255.255.255.255" - && host != "localhost" - && !m_shell->allowExternalPages()) { - printf("Blocked access to external URL %s\n", requestURL.c_str()); - - // To block the request, we set its URL to an empty one. - request.setURL(WebURL()); - return; + if (!host.empty() && (url.SchemeIs("http") || url.SchemeIs("https"))) { + GURL testURL = webView()->mainFrame()->document().url(); + const string& testHost = testURL.host(); + if (!isLocalhost(host) && !hostIsUsedBySomeTestsToGenerateError(host) && ((!testURL.SchemeIs("http") && !testURL.SchemeIs("https")) || isLocalhost(testHost)) + && !m_shell->allowExternalPages()) { + printf("Blocked access to external URL %s\n", requestURL.c_str()); + blockRequest(request); + return; + } } HashSet<String>::const_iterator end = m_clearHeaders.end(); @@ -1409,6 +1429,7 @@ void WebViewHost::setWebWidget(WebKit::WebWidget* widget) { m_webWidget = widget; webView()->setSpellCheckClient(this); + webView()->setPrerendererClient(this); webView()->setCompositorSurfaceReady(); } diff --git a/Tools/DumpRenderTree/chromium/WebViewHost.h b/Tools/DumpRenderTree/chromium/WebViewHost.h index c5f930127..21dbb4c8d 100644 --- a/Tools/DumpRenderTree/chromium/WebViewHost.h +++ b/Tools/DumpRenderTree/chromium/WebViewHost.h @@ -38,6 +38,7 @@ #include "WebCursorInfo.h" #include "WebFrameClient.h" #include "WebIntentRequest.h" +#include "WebPrerendererClient.h" #include "WebSpellCheckClient.h" #include "WebViewClient.h" #include <wtf/HashMap.h> @@ -74,7 +75,8 @@ class MediaStreamUtil; class TestMediaStreamClient; } -class WebViewHost : public WebKit::WebSpellCheckClient, public WebKit::WebViewClient, public WebKit::WebFrameClient, public NavigationHost { +class WebViewHost : public WebKit::WebViewClient, public WebKit::WebFrameClient, public NavigationHost, + public WebKit::WebPrerendererClient, public WebKit::WebSpellCheckClient { public: WebViewHost(TestShell*); virtual ~WebViewHost(); @@ -124,6 +126,9 @@ class WebViewHost : public WebKit::WebSpellCheckClient, public WebKit::WebViewCl // NavigationHost virtual bool navigate(const TestNavigationEntry&, bool reload); + // WebKit::WebPrerendererClient + virtual void willAddPrerender(WebKit::WebPrerender*) OVERRIDE; + // WebKit::WebSpellCheckClient virtual void spellCheck(const WebKit::WebString&, int& offset, int& length, WebKit::WebVector<WebKit::WebString>* optionalSuggestions); virtual void requestCheckingOfText(const WebKit::WebString&, WebKit::WebTextCheckingCompletion*); diff --git a/Tools/DumpRenderTree/efl/DumpRenderTree.cpp b/Tools/DumpRenderTree/efl/DumpRenderTree.cpp index 668aa46a0..f8bf85e54 100644 --- a/Tools/DumpRenderTree/efl/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/efl/DumpRenderTree.cpp @@ -54,6 +54,8 @@ OwnPtr<DumpRenderTreeChrome> browser; Evas_Object* topLoadingFrame = 0; bool waitForPolicy = false; +bool policyDelegateEnabled = false; +bool policyDelegatePermissive = false; Ecore_Timer* waitToDumpWatchdog = 0; extern Ewk_History_Item* prevTestBFItem; diff --git a/Tools/DumpRenderTree/efl/DumpRenderTreeChrome.cpp b/Tools/DumpRenderTree/efl/DumpRenderTreeChrome.cpp index 2a39a693a..22f0ecff7 100644 --- a/Tools/DumpRenderTree/efl/DumpRenderTreeChrome.cpp +++ b/Tools/DumpRenderTree/efl/DumpRenderTreeChrome.cpp @@ -174,7 +174,7 @@ bool DumpRenderTreeChrome::initialize() return true; } -Vector<Evas_Object*> DumpRenderTreeChrome::extraViews() const +const Vector<Evas_Object*>& DumpRenderTreeChrome::extraViews() const { return m_extraViews; } @@ -265,7 +265,6 @@ void DumpRenderTreeChrome::resetDefaultsToConsistentValues() DumpRenderTreeSupportEfl::setSmartInsertDeleteEnabled(mainView(), false); DumpRenderTreeSupportEfl::setSelectTrailingWhitespaceEnabled(mainView(), false); DumpRenderTreeSupportEfl::setDefersLoading(mainView(), false); - DumpRenderTreeSupportEfl::setJavaScriptProfilingEnabled(mainView(), false); DumpRenderTreeSupportEfl::setLoadsSiteIconsIgnoringImageLoadingSetting(mainView(), false); DumpRenderTreeSupportEfl::setSerializeHTTPLoads(false); DumpRenderTreeSupportEfl::setDeadDecodedDataDeletionInterval(0); @@ -274,6 +273,9 @@ void DumpRenderTreeChrome::resetDefaultsToConsistentValues() ewk_intent_request_unref(m_currentIntentRequest); m_currentIntentRequest = 0; } + + policyDelegateEnabled = false; + policyDelegatePermissive = false; } static CString pathSuitableForTestResult(const char* uriString) @@ -582,6 +584,9 @@ void DumpRenderTreeChrome::onFrameLoadFinished(void*, Evas_Object* frame, void* if (error) return; + if (!done && gLayoutTestController->dumpProgressFinishedCallback()) + printf("postProgressFinishedNotification\n"); + if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) { const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame)); printf("%s - didFinishLoadForFrame\n", frameName.utf8().data()); @@ -701,7 +706,9 @@ void DumpRenderTreeChrome::onFrameIntentNew(void*, Evas_Object*, void* eventInfo ewk_intent_action_get(intent), ewk_intent_type_get(intent)); - // TODO: Display number of ports once Ewk_Intent exposes this information. + const MessagePortChannelArray* messagePorts = DumpRenderTreeSupportEfl::intentMessagePorts(intent); + if (messagePorts) + printf("Have %d ports\n", static_cast<int>(messagePorts->size())); const char* service = ewk_intent_service_get(intent); if (service && strcmp(service, "")) diff --git a/Tools/DumpRenderTree/efl/DumpRenderTreeChrome.h b/Tools/DumpRenderTree/efl/DumpRenderTreeChrome.h index 6ae30a34e..0d3b3f2f3 100644 --- a/Tools/DumpRenderTree/efl/DumpRenderTreeChrome.h +++ b/Tools/DumpRenderTree/efl/DumpRenderTreeChrome.h @@ -48,7 +48,7 @@ public: Evas_Object* createNewWindow(); void removeWindow(Evas_Object*); - Vector<Evas_Object*> extraViews() const; + const Vector<Evas_Object*>& extraViews() const; void clearExtraViews(); Evas_Object* mainFrame() const; diff --git a/Tools/DumpRenderTree/efl/DumpRenderTreeEfl.h b/Tools/DumpRenderTree/efl/DumpRenderTreeEfl.h index 43812b19b..f474c89e2 100644 --- a/Tools/DumpRenderTree/efl/DumpRenderTreeEfl.h +++ b/Tools/DumpRenderTree/efl/DumpRenderTreeEfl.h @@ -36,6 +36,8 @@ class DumpRenderTreeChrome; extern OwnPtr<DumpRenderTreeChrome> browser; extern Evas_Object* topLoadingFrame; extern bool waitForPolicy; +extern bool policyDelegateEnabled; +extern bool policyDelegatePermissive; extern Ecore_Timer* waitToDumpWatchdog; #endif /* DumpRenderTreeEfl_h */ diff --git a/Tools/DumpRenderTree/efl/DumpRenderTreeView.cpp b/Tools/DumpRenderTree/efl/DumpRenderTreeView.cpp index f9f8f65cb..f07d3815b 100644 --- a/Tools/DumpRenderTree/efl/DumpRenderTreeView.cpp +++ b/Tools/DumpRenderTree/efl/DumpRenderTreeView.cpp @@ -28,6 +28,7 @@ #include "DumpRenderTree.h" #include "DumpRenderTreeChrome.h" +#include "DumpRenderTreeEfl.h" #include "LayoutTestController.h" #include <EWebKit.h> #include <Ecore.h> @@ -120,7 +121,7 @@ static uint64_t onExceededDatabaseQuota(Ewk_View_Smart_Data* smartData, Evas_Obj return 5 * 1024 * 1024; } -static uint64_t onExceededApplicationCacheQuota(Ewk_View_Smart_Data*, Ewk_Security_Origin *origin, int64_t defaultOriginQuota, int64_t totalSpaceNeeded) +static int64_t onExceededApplicationCacheQuota(Ewk_View_Smart_Data*, Ewk_Security_Origin *origin, int64_t defaultOriginQuota, int64_t totalSpaceNeeded) { if (gLayoutTestController->dumpApplicationCacheDelegateCallbacks()) { // For example, numbers from 30000 - 39999 will output as 30000. @@ -128,7 +129,7 @@ static uint64_t onExceededApplicationCacheQuota(Ewk_View_Smart_Data*, Ewk_Securi // sufficient to just get a range of 10000 to determine if we were // above or below a threshold. int64_t truncatedSpaceNeeded = (totalSpaceNeeded / 10000) * 10000; - printf("UI DELEGATE APPLICATION CACHE CALLBACK: exceededApplicationCacheOriginQuotaForSecurityOrigin:{%s, %s, %i} totalSpaceNeeded:~%llu\n", + printf("UI DELEGATE APPLICATION CACHE CALLBACK: exceededApplicationCacheOriginQuotaForSecurityOrigin:{%s, %s, %i} totalSpaceNeeded:~%lld\n", ewk_security_origin_protocol_get(origin), ewk_security_origin_host_get(origin), ewk_security_origin_port_get(origin), @@ -152,6 +153,40 @@ static bool chooseAndInitializeAppropriateSmartClass(Ewk_View_Smart_Class* api) return shouldUseSingleBackingStore() ? ewk_view_single_smart_set(api) : ewk_view_tiled_smart_set(api); } +// Taken from the file "WebKit/Tools/DumpRenderTree/chromium/WebViewHost.cpp". +static inline const char* navigationTypeToString(const Ewk_Navigation_Type type) +{ + switch (type) { + case EWK_NAVIGATION_TYPE_LINK_CLICKED: + return "link clicked"; + case EWK_NAVIGATION_TYPE_FORM_SUBMITTED: + return "form submitted"; + case EWK_NAVIGATION_TYPE_BACK_FORWARD: + return "back/forward"; + case EWK_NAVIGATION_TYPE_RELOAD: + return "reload"; + case EWK_NAVIGATION_TYPE_FORM_RESUBMITTED: + return "form resubmitted"; + case EWK_NAVIGATION_TYPE_OTHER: + return "other"; + } + return "illegal value"; +} + +static Eina_Bool onNavigationPolicyDecision(Ewk_View_Smart_Data*, Ewk_Frame_Resource_Request* request, Ewk_Navigation_Type navigationType) +{ + if (!policyDelegateEnabled) + return true; + + printf("Policy delegate: attempt to load %s with navigation type '%s'\n", urlSuitableForTestResult(request->url).utf8().data(), + navigationTypeToString(navigationType)); + + if (gLayoutTestController) + gLayoutTestController->notifyDone(); + + return policyDelegatePermissive; +} + Evas_Object* drtViewAdd(Evas* evas) { static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("DRT_View"); @@ -170,6 +205,7 @@ Evas_Object* drtViewAdd(Evas* evas) api.window_close = onWindowClose; api.exceeded_application_cache_quota = onExceededApplicationCacheQuota; api.exceeded_database_quota = onExceededDatabaseQuota; + api.navigation_policy_decision = onNavigationPolicyDecision; return evas_object_smart_add(evas, evas_smart_class_new(&api.sc)); } diff --git a/Tools/DumpRenderTree/efl/EventSender.cpp b/Tools/DumpRenderTree/efl/EventSender.cpp index 83385c4fa..d606b37e3 100644 --- a/Tools/DumpRenderTree/efl/EventSender.cpp +++ b/Tools/DumpRenderTree/efl/EventSender.cpp @@ -112,7 +112,7 @@ enum EventQueueStrategy { }; struct KeyEventInfo { - KeyEventInfo(const CString& keyName, const CString& keyString, unsigned modifiers) + KeyEventInfo(const CString& keyName, unsigned modifiers, const CString& keyString = CString()) : keyName(keyName) , keyString(keyString) , modifiers(modifiers) @@ -389,108 +389,108 @@ static JSValueRef continuousMouseScrollByCallback(JSContextRef context, JSObject static KeyEventInfo* keyPadNameFromJSValue(JSStringRef character, unsigned modifiers) { if (equals(character, "leftArrow")) - return new KeyEventInfo("KP_Left", "", modifiers); + return new KeyEventInfo("KP_Left", modifiers); if (equals(character, "rightArrow")) - return new KeyEventInfo("KP_Right", "", modifiers); + return new KeyEventInfo("KP_Right", modifiers); if (equals(character, "upArrow")) - return new KeyEventInfo("KP_Up", "", modifiers); + return new KeyEventInfo("KP_Up", modifiers); if (equals(character, "downArrow")) - return new KeyEventInfo("KP_Down", "", modifiers); + return new KeyEventInfo("KP_Down", modifiers); if (equals(character, "pageUp")) - return new KeyEventInfo("KP_Prior", "", modifiers); + return new KeyEventInfo("KP_Prior", modifiers); if (equals(character, "pageDown")) - return new KeyEventInfo("KP_Next", "", modifiers); + return new KeyEventInfo("KP_Next", modifiers); if (equals(character, "home")) - return new KeyEventInfo("KP_Home", "", modifiers); + return new KeyEventInfo("KP_Home", modifiers); if (equals(character, "end")) - return new KeyEventInfo("KP_End", "", modifiers); + return new KeyEventInfo("KP_End", modifiers); if (equals(character, "insert")) - return new KeyEventInfo("KP_Insert", "", modifiers); + return new KeyEventInfo("KP_Insert", modifiers); if (equals(character, "delete")) - return new KeyEventInfo("KP_Delete", "", modifiers); + return new KeyEventInfo("KP_Delete", modifiers); - return new KeyEventInfo(character->ustring().utf8(), character->ustring().utf8(), modifiers); + return new KeyEventInfo(character->ustring().utf8(), modifiers, character->ustring().utf8()); } static KeyEventInfo* keyNameFromJSValue(JSStringRef character, unsigned modifiers) { if (equals(character, "leftArrow")) - return new KeyEventInfo("Left", "", modifiers); + return new KeyEventInfo("Left", modifiers); if (equals(character, "rightArrow")) - return new KeyEventInfo("Right", "", modifiers); + return new KeyEventInfo("Right", modifiers); if (equals(character, "upArrow")) - return new KeyEventInfo("Up", "", modifiers); + return new KeyEventInfo("Up", modifiers); if (equals(character, "downArrow")) - return new KeyEventInfo("Down", "", modifiers); + return new KeyEventInfo("Down", modifiers); if (equals(character, "pageUp")) - return new KeyEventInfo("Prior", "", modifiers); + return new KeyEventInfo("Prior", modifiers); if (equals(character, "pageDown")) - return new KeyEventInfo("Next", "", modifiers); + return new KeyEventInfo("Next", modifiers); if (equals(character, "home")) - return new KeyEventInfo("Home", "", modifiers); + return new KeyEventInfo("Home", modifiers); if (equals(character, "end")) - return new KeyEventInfo("End", "", modifiers); + return new KeyEventInfo("End", modifiers); if (equals(character, "insert")) - return new KeyEventInfo("Insert", "", modifiers); + return new KeyEventInfo("Insert", modifiers); if (equals(character, "delete")) - return new KeyEventInfo("Delete", "", modifiers); + return new KeyEventInfo("Delete", modifiers); if (equals(character, "printScreen")) - return new KeyEventInfo("Print", "", modifiers); + return new KeyEventInfo("Print", modifiers); if (equals(character, "menu")) - return new KeyEventInfo("Menu", "", modifiers); + return new KeyEventInfo("Menu", modifiers); if (equals(character, "leftControl")) - return new KeyEventInfo("Control_L", "", modifiers); + return new KeyEventInfo("Control_L", modifiers); if (equals(character, "rightControl")) - return new KeyEventInfo("Control_R", "", modifiers); + return new KeyEventInfo("Control_R", modifiers); if (equals(character, "leftShift")) - return new KeyEventInfo("Shift_L", "", modifiers); + return new KeyEventInfo("Shift_L", modifiers); if (equals(character, "rightShift")) - return new KeyEventInfo("Shift_R", "", modifiers); + return new KeyEventInfo("Shift_R", modifiers); if (equals(character, "leftAlt")) - return new KeyEventInfo("Alt_L", "", modifiers); + return new KeyEventInfo("Alt_L", modifiers); if (equals(character, "rightAlt")) - return new KeyEventInfo("Alt_R", "", modifiers); + return new KeyEventInfo("Alt_R", modifiers); if (equals(character, "F1")) - return new KeyEventInfo("F1", "", modifiers); + return new KeyEventInfo("F1", modifiers); if (equals(character, "F2")) - return new KeyEventInfo("F2", "", modifiers); + return new KeyEventInfo("F2", modifiers); if (equals(character, "F3")) - return new KeyEventInfo("F3", "", modifiers); + return new KeyEventInfo("F3", modifiers); if (equals(character, "F4")) - return new KeyEventInfo("F4", "", modifiers); + return new KeyEventInfo("F4", modifiers); if (equals(character, "F5")) - return new KeyEventInfo("F5", "", modifiers); + return new KeyEventInfo("F5", modifiers); if (equals(character, "F6")) - return new KeyEventInfo("F6", "", modifiers); + return new KeyEventInfo("F6", modifiers); if (equals(character, "F7")) - return new KeyEventInfo("F7", "", modifiers); + return new KeyEventInfo("F7", modifiers); if (equals(character, "F8")) - return new KeyEventInfo("F8", "", modifiers); + return new KeyEventInfo("F8", modifiers); if (equals(character, "F9")) - return new KeyEventInfo("F9", "", modifiers); + return new KeyEventInfo("F9", modifiers); if (equals(character, "F10")) - return new KeyEventInfo("F10", "", modifiers); + return new KeyEventInfo("F10", modifiers); if (equals(character, "F11")) - return new KeyEventInfo("F11", "", modifiers); + return new KeyEventInfo("F11", modifiers); if (equals(character, "F12")) - return new KeyEventInfo("F12", "", modifiers); + return new KeyEventInfo("F12", modifiers); int charCode = JSStringGetCharactersPtr(character)[0]; if (charCode == '\n' || charCode == '\r') - return new KeyEventInfo("Return", "Return", modifiers); + return new KeyEventInfo("Return", modifiers, "\r"); if (charCode == '\t') - return new KeyEventInfo("Tab", "Tab", modifiers); + return new KeyEventInfo("Tab", modifiers, "\t"); if (charCode == '\x8') - return new KeyEventInfo("BackSpace", "BackSpace", modifiers); + return new KeyEventInfo("BackSpace", modifiers, "\x8"); if (charCode == ' ') - return new KeyEventInfo("space", " ", modifiers); + return new KeyEventInfo("space", modifiers, " "); if (charCode == '\x1B') - return new KeyEventInfo("Escape", "Escape", modifiers); + return new KeyEventInfo("Escape", modifiers, "\x1B"); if ((character->length() == 1) && (charCode >= 'A' && charCode <= 'Z')) modifiers |= EvasKeyModifierShift; - return new KeyEventInfo(character->ustring().utf8(), character->ustring().utf8(), modifiers); + return new KeyEventInfo(character->ustring().utf8(), modifiers, character->ustring().utf8()); } static KeyEventInfo* createKeyEventInfo(JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) diff --git a/Tools/DumpRenderTree/efl/LayoutTestControllerEfl.cpp b/Tools/DumpRenderTree/efl/LayoutTestControllerEfl.cpp index 92123e881..992785143 100644 --- a/Tools/DumpRenderTree/efl/LayoutTestControllerEfl.cpp +++ b/Tools/DumpRenderTree/efl/LayoutTestControllerEfl.cpp @@ -202,13 +202,15 @@ void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) ewk_cookies_policy_set(alwaysAcceptCookies ? EWK_COOKIE_JAR_ACCEPT_ALWAYS : EWK_COOKIE_JAR_ACCEPT_NEVER); } -void LayoutTestController::setCustomPolicyDelegate(bool, bool) +void LayoutTestController::setCustomPolicyDelegate(bool enabled, bool permissive) { - notImplemented(); + policyDelegateEnabled = enabled; + policyDelegatePermissive = permissive; } void LayoutTestController::waitForPolicyDelegate() { + setCustomPolicyDelegate(true, false); waitForPolicy = true; setWaitToDump(true); } @@ -449,14 +451,6 @@ void LayoutTestController::setIconDatabaseEnabled(bool enabled) ewk_settings_icon_database_path_set(databasePath.utf8().data()); } -void LayoutTestController::setJavaScriptProfilingEnabled(bool enabled) -{ - if (enabled) - setDeveloperExtrasEnabled(enabled); - - DumpRenderTreeSupportEfl::setJavaScriptProfilingEnabled(browser->mainView(), enabled); -} - void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) { DumpRenderTreeSupportEfl::setSelectTrailingWhitespaceEnabled(browser->mainView(), flag); @@ -586,10 +580,11 @@ void LayoutTestController::setApplicationCacheOriginQuota(unsigned long long quo ewk_security_origin_free(origin); } -void LayoutTestController::clearApplicationCacheForOrigin(OpaqueJSString*) +void LayoutTestController::clearApplicationCacheForOrigin(OpaqueJSString* url) { - // FIXME: Implement to support deleting all application caches for an origin. - notImplemented(); + Ewk_Security_Origin* origin = ewk_security_origin_new_from_string(url->ustring().utf8().data()); + ewk_security_origin_application_cache_clear(origin); + ewk_security_origin_free(origin); } long long LayoutTestController::localStorageDiskUsageForOrigin(JSStringRef) @@ -838,11 +833,6 @@ void LayoutTestController::setTextDirection(JSStringRef) notImplemented(); } -void LayoutTestController::allowRoundingHacks() -{ - notImplemented(); -} - void LayoutTestController::addChromeInputField() { notImplemented(); @@ -896,9 +886,5 @@ void LayoutTestController::sendWebIntentResponse(JSStringRef response) if (!request) return; - JSC::UString responseString = response->ustring(); - if (responseString.isNull()) - ewk_intent_request_failure_post(request, "ERROR"); - else - ewk_intent_request_result_post(request, responseString.utf8().data()); + DumpRenderTreeSupportEfl::sendWebIntentResponse(request, response); } diff --git a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index 45c80e81f..8e4c16c5d 100644 --- a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -540,17 +540,6 @@ void LayoutTestController::setIconDatabaseEnabled(bool enabled) webkit_icon_database_set_path(database, 0); } -void LayoutTestController::setJavaScriptProfilingEnabled(bool flag) -{ - WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); - ASSERT(view); - - setDeveloperExtrasEnabled(flag); - - WebKitWebInspector* inspector = webkit_web_view_get_inspector(view); - g_object_set(G_OBJECT(inspector), "javascript-profiling-enabled", flag, NULL); -} - void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) { DumpRenderTreeSupportGtk::setSelectTrailingWhitespaceEnabled(flag); @@ -982,10 +971,6 @@ void LayoutTestController::setTextDirection(JSStringRef direction) // FIXME: Implement. } -void LayoutTestController::allowRoundingHacks() -{ -} - void LayoutTestController::addChromeInputField() { } diff --git a/Tools/DumpRenderTree/mac/Configurations/Base.xcconfig b/Tools/DumpRenderTree/mac/Configurations/Base.xcconfig index 3ad47a260..8180cabdd 100644 --- a/Tools/DumpRenderTree/mac/Configurations/Base.xcconfig +++ b/Tools/DumpRenderTree/mac/Configurations/Base.xcconfig @@ -23,6 +23,7 @@ #include "CompilerVersion.xcconfig" +CLANG_WARN_CXX0X_EXTENSIONS = NO; HEADER_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR)/usr/local/include ForwardingHeaders mac/InternalHeaders $(NEXT_ROOT)/usr/local/include/WebCoreTestSupport; FRAMEWORK_SEARCH_PATHS = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks; GCC_PREPROCESSOR_DEFINITIONS = ENABLE_DASHBOARD_SUPPORT WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST; diff --git a/Tools/DumpRenderTree/mac/DumpRenderTree.mm b/Tools/DumpRenderTree/mac/DumpRenderTree.mm index c1f44a473..00bdb2184 100644 --- a/Tools/DumpRenderTree/mac/DumpRenderTree.mm +++ b/Tools/DumpRenderTree/mac/DumpRenderTree.mm @@ -525,6 +525,7 @@ WebView *createWebViewAndOffscreenWindow() [WebView registerURLSchemeAsLocal:@"feedsearch"]; [webView setContinuousSpellCheckingEnabled:YES]; + [webView setDefersCallbacks:NO]; [webView setGrammarCheckingEnabled:YES]; [webView setInteractiveFormValidationEnabled:YES]; [webView setValidationMessageTimerMagnification:-1]; @@ -1264,7 +1265,6 @@ static void resetWebViewToConsistentStateBeforeTesting() } [[mainFrame webView] setSmartInsertDeleteEnabled:YES]; - [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:NO]; [WebView _setUsesTestModeFocusRingColor:YES]; [WebView _resetOriginAccessWhitelists]; diff --git a/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm b/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm index c88296262..69c246197 100644 --- a/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm +++ b/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm @@ -54,6 +54,10 @@ #import <WebKit/WebViewPrivate.h> #import <wtf/Assertions.h> +#ifndef NSEC_PER_MSEC +#define NSEC_PER_MSEC 1000000ull +#endif + @interface NSURL (DRTExtras) - (NSString *)_drt_descriptionSuitableForTestResult; @end @@ -173,6 +177,15 @@ printf ("%s\n", [string UTF8String]); [frame stopLoading]; } + + if (!done && gLayoutTestController->useDeferredFrameLoading()) { + [sender setDefersCallbacks:YES]; + int64_t deferredWaitTime = 5 * NSEC_PER_MSEC; + dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, deferredWaitTime); + dispatch_after(when, dispatch_get_main_queue(), ^{ + [sender setDefersCallbacks:NO]; + }); + } } - (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame diff --git a/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm index 5b2e060c6..419a2cf92 100644 --- a/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm +++ b/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm @@ -561,12 +561,6 @@ void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled) [sharedWebIconDatabase setEnabled:iconDatabaseEnabled]; } -void LayoutTestController::setJavaScriptProfilingEnabled(bool profilingEnabled) -{ - setDeveloperExtrasEnabled(profilingEnabled); - [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:profilingEnabled]; -} - void LayoutTestController::setMainFrameIsFirstResponder(bool flag) { NSView *documentView = [[mainFrame frameView] documentView]; @@ -967,11 +961,6 @@ void LayoutTestController::evaluateScriptInIsolatedWorld(unsigned worldID, JSObj [mainFrame _stringByEvaluatingJavaScriptFromString:scriptNS withGlobalObject:globalObject inScriptWorld:world]; } -void LayoutTestController::allowRoundingHacks() -{ - [WebView _setAllowsRoundingHacks:YES]; -} - @interface APITestDelegate : NSObject { bool* m_condition; diff --git a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp index a9f27bf3b..df70e08a6 100644 --- a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp +++ b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp @@ -620,9 +620,7 @@ void DumpRenderTree::open(const QUrl& url) m_page->event(&ev); QWebSettings::clearMemoryCaches(); -#if !(QT_VERSION <= QT_VERSION_CHECK(4, 6, 2)) QFontDatabase::removeAllApplicationFonts(); -#endif WebKit::initializeTestFonts(); DumpRenderTreeSupportQt::dumpFrameLoader(url.toString().contains("loading/")); diff --git a/Tools/DumpRenderTree/qt/EventSenderQt.cpp b/Tools/DumpRenderTree/qt/EventSenderQt.cpp index 4a3b245ab..c0506efe2 100644 --- a/Tools/DumpRenderTree/qt/EventSenderQt.cpp +++ b/Tools/DumpRenderTree/qt/EventSenderQt.cpp @@ -511,7 +511,7 @@ void EventSender::cancelTouchPoint(int index) void EventSender::sendTouchEvent(QEvent::Type type) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) static QTouchDevice* device = 0; if (!device) { device = new QTouchDevice; diff --git a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp index c1683f10e..9bbf439bc 100644 --- a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp +++ b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp @@ -477,12 +477,6 @@ void LayoutTestController::setAutofilled(const QWebElement& element, bool isAuto return DumpRenderTreeSupportQt::setAutofilled(element, isAutofilled); } -void LayoutTestController::setJavaScriptProfilingEnabled(bool enable) -{ - setDeveloperExtrasEnabled(enable); - DumpRenderTreeSupportQt::setJavaScriptProfilingEnabled(m_topLoadingFrame, enable); -} - void LayoutTestController::setValueForUser(const QWebElement& element, const QString& value) { DumpRenderTreeSupportQt::setValueForUser(element, value); diff --git a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h index 551167672..ef68b36e9 100644 --- a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h +++ b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h @@ -159,7 +159,6 @@ public slots: void setAllowFileAccessFromFileURLs(bool enable); void setAppCacheMaximumSize(unsigned long long quota); void setAutofilled(const QWebElement&, bool enable); - void setJavaScriptProfilingEnabled(bool enable); void setValueForUser(const QWebElement&, const QString& value); void setFixedContentsSize(int width, int height); void setPrivateBrowsingEnabled(bool enable); diff --git a/Tools/DumpRenderTree/qt/QtInitializeTestFonts.cpp b/Tools/DumpRenderTree/qt/QtInitializeTestFonts.cpp index ca6b66c49..7ae5e22a3 100644 --- a/Tools/DumpRenderTree/qt/QtInitializeTestFonts.cpp +++ b/Tools/DumpRenderTree/qt/QtInitializeTestFonts.cpp @@ -67,7 +67,7 @@ void initializeTestFonts() // The resolving of default font families was altered in Qt5 with 2cc5442 (qtbase), // we use this hack to keep resolving to the same font Qt4 did for serif while // supporting both versions. -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) configFile = fontDir + "/fonts-qt5-wk1.conf"; if (!FcConfigParseAndLoad(config, reinterpret_cast<const FcChar8*>(configFile.constData()), FcTrue)) qFatal("Couldn't load font configuration file"); diff --git a/Tools/DumpRenderTree/qt/main.cpp b/Tools/DumpRenderTree/qt/main.cpp index 176336770..3125d61bc 100644 --- a/Tools/DumpRenderTree/qt/main.cpp +++ b/Tools/DumpRenderTree/qt/main.cpp @@ -152,7 +152,9 @@ int main(int argc, char* argv[]) QApplication app(argc, argv); app.setQuitOnLastWindowClosed(false); -#if QT_VERSION <= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) + QCoreApplication::setAttribute(Qt::AA_Use96Dpi, true); +#else #ifdef Q_WS_X11 QX11Info::setAppDpiY(0, 96); QX11Info::setAppDpiX(0, 96); @@ -170,8 +172,6 @@ int main(int argc, char* argv[]) * default font, but with the correct paint-device DPI. */ QApplication::setFont(QWidget().font()); -#else - QCoreApplication::setAttribute(Qt::AA_Use96Dpi, true); #endif #if HAVE(SIGNAL_H) diff --git a/Tools/DumpRenderTree/win/DRTDataObject.cpp b/Tools/DumpRenderTree/win/DRTDataObject.cpp new file mode 100644 index 000000000..b3504539b --- /dev/null +++ b/Tools/DumpRenderTree/win/DRTDataObject.cpp @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2012 Baidu 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 COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DRTDataObject.h" + +FORMATETC* cfHDropFormat() +{ + static FORMATETC urlFormat = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &urlFormat; +} + +FORMATETC* cfFileNameWFormat() +{ + static UINT cf = RegisterClipboardFormat(L"FileNameW"); + static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &urlFormat; +} + +FORMATETC* cfUrlWFormat() +{ + static UINT cf = RegisterClipboardFormat(L"UniformResourceLocatorW"); + static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &urlFormat; +} + +class WCEnumFormatEtc : public IEnumFORMATETC { +public: + explicit WCEnumFormatEtc(const Vector<FORMATETC>& formats); + explicit WCEnumFormatEtc(const Vector<FORMATETC*>& formats); + + // IUnknown members + STDMETHOD(QueryInterface)(REFIID, void**); + STDMETHOD_(ULONG, AddRef)(); + STDMETHOD_(ULONG, Release)(); + + // IEnumFORMATETC members + STDMETHOD(Next)(ULONG, LPFORMATETC, ULONG*); + STDMETHOD(Skip)(ULONG); + STDMETHOD(Reset)(); + STDMETHOD(Clone)(IEnumFORMATETC**); + +private: + long m_ref; + Vector<FORMATETC> m_formats; + size_t m_current; +}; + +WCEnumFormatEtc::WCEnumFormatEtc(const Vector<FORMATETC>& formats) + : m_ref(1) + , m_current(0) + , m_formats(formats) +{ +} + +WCEnumFormatEtc::WCEnumFormatEtc(const Vector<FORMATETC*>& formats) + : m_ref(1) + , m_current(0) +{ + for (size_t i = 0; i < formats.size(); ++i) + m_formats.append(*formats[i]); +} + +STDMETHODIMP WCEnumFormatEtc::QueryInterface(REFIID riid, void** ppvObject) +{ + *ppvObject = 0; + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumFORMATETC)) { + *ppvObject = this; + AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) WCEnumFormatEtc::AddRef() +{ + return InterlockedIncrement(&m_ref); +} + +STDMETHODIMP_(ULONG) WCEnumFormatEtc::Release() +{ + long refCount = InterlockedDecrement(&m_ref); + if (!refCount) + delete this; + return refCount; +} + +STDMETHODIMP WCEnumFormatEtc::Next(ULONG celt, LPFORMATETC lpFormatEtc, ULONG* pceltFetched) +{ + if (pceltFetched) + *pceltFetched = 0; + + ULONG cReturn = celt; + + if (celt <= 0 || !lpFormatEtc || m_current >= m_formats.size()) + return S_FALSE; + + if (!pceltFetched && celt != 1) // pceltFetched can be 0 only for 1 item request + return S_FALSE; + + while (m_current < m_formats.size() && cReturn > 0) { + *lpFormatEtc++ = m_formats[m_current++]; + --cReturn; + } + if (pceltFetched) + *pceltFetched = celt - cReturn; + + return !cReturn ? S_OK : S_FALSE; +} + +STDMETHODIMP WCEnumFormatEtc::Skip(ULONG celt) +{ + if ((m_current + celt) >= m_formats.size()) + return S_FALSE; + m_current += celt; + return S_OK; +} + +STDMETHODIMP WCEnumFormatEtc::Reset() +{ + m_current = 0; + return S_OK; +} + +STDMETHODIMP WCEnumFormatEtc::Clone(IEnumFORMATETC** ppCloneEnumFormatEtc) +{ + if (!ppCloneEnumFormatEtc) + return E_POINTER; + + WCEnumFormatEtc* newEnum = new WCEnumFormatEtc(m_formats); + if (!newEnum) + return E_OUTOFMEMORY; + + newEnum->AddRef(); + newEnum->m_current = m_current; + *ppCloneEnumFormatEtc = newEnum; + return S_OK; +} + +////////////////////////////////////////////////////////////////////////// +HRESULT DRTDataObject::createInstance(DRTDataObject** result) +{ + if (!result) + return E_POINTER; + *result = new DRTDataObject(); + return S_OK; +} + +DRTDataObject::DRTDataObject() + : m_ref(1) +{ +} + +DRTDataObject::~DRTDataObject() +{ + for (size_t i = 0; i < m_medium.size(); ++i) { + ReleaseStgMedium(m_medium[i]); + delete m_medium[i]; + } + WTF::deleteAllValues(m_formats); +} + +STDMETHODIMP DRTDataObject::QueryInterface(REFIID riid, void** ppvObject) +{ + *ppvObject = 0; + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDataObject)) + *ppvObject = this; + + if (*ppvObject) { + AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) DRTDataObject::AddRef() +{ + return InterlockedIncrement(&m_ref); +} + +STDMETHODIMP_(ULONG) DRTDataObject::Release() +{ + long refCount = InterlockedDecrement(&m_ref); + if (!refCount) + delete this; + return refCount; +} + +STDMETHODIMP DRTDataObject::GetData(FORMATETC* pformatetcIn, STGMEDIUM* pmedium) +{ + if (!pformatetcIn || !pmedium) + return E_POINTER; + pmedium->hGlobal = 0; + + for (size_t i = 0; i < m_formats.size(); ++i) { + if (pformatetcIn->lindex == m_formats[i]->lindex && pformatetcIn->dwAspect == m_formats[i]->dwAspect && pformatetcIn->cfFormat == m_formats[i]->cfFormat) { + CopyMedium(pmedium, m_medium[i], m_formats[i]); + return S_OK; + } + } + return DV_E_FORMATETC; +} + +STDMETHODIMP DRTDataObject::GetDataHere(FORMATETC*, STGMEDIUM*) +{ + return E_NOTIMPL; +} + +STDMETHODIMP DRTDataObject::QueryGetData(FORMATETC* pformatetc) +{ + if (!pformatetc) + return E_POINTER; + + if (!(DVASPECT_CONTENT & pformatetc->dwAspect)) + return (DV_E_DVASPECT); + + for (size_t i = 0; i < m_formats.size(); ++i) { + if (pformatetc->tymed & m_formats[i]->tymed) { + if (pformatetc->cfFormat == m_formats[i]->cfFormat) + return S_OK; + } + } + return DV_E_TYMED; +} + +STDMETHODIMP DRTDataObject::GetCanonicalFormatEtc(FORMATETC*, FORMATETC*) +{ + return DATA_S_SAMEFORMATETC; +} + +STDMETHODIMP DRTDataObject::SetData(FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease) +{ + if (!pformatetc || !pmedium) + return E_POINTER; + + FORMATETC* formatetc = new FORMATETC; + if (!formatetc) + return E_OUTOFMEMORY; + + STGMEDIUM* pStgMed = new STGMEDIUM; + + if (!pStgMed) { + delete formatetc; + return E_OUTOFMEMORY; + } + + ZeroMemory(formatetc, sizeof(FORMATETC)); + ZeroMemory(pStgMed, sizeof(STGMEDIUM)); + + *formatetc = *pformatetc; + m_formats.append(formatetc); + + if (fRelease) + *pStgMed = *pmedium; + else + CopyMedium(pStgMed, pmedium, pformatetc); + m_medium.append(pStgMed); + + return S_OK; +} + +void DRTDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc) +{ + switch (pMedSrc->tymed) { +#if !OS(WINCE) + case TYMED_HGLOBAL: + pMedDest->hGlobal = static_cast<HGLOBAL>(OleDuplicateData(pMedSrc->hGlobal, pFmtSrc->cfFormat, 0)); + break; + case TYMED_GDI: + pMedDest->hBitmap = static_cast<HBITMAP>(OleDuplicateData(pMedSrc->hBitmap, pFmtSrc->cfFormat, 0)); + break; + case TYMED_MFPICT: + pMedDest->hMetaFilePict = static_cast<HMETAFILEPICT>(OleDuplicateData(pMedSrc->hMetaFilePict, pFmtSrc->cfFormat, 0)); + break; + case TYMED_ENHMF: + pMedDest->hEnhMetaFile = static_cast<HENHMETAFILE>(OleDuplicateData(pMedSrc->hEnhMetaFile, pFmtSrc->cfFormat, 0)); + break; + case TYMED_FILE: + pMedSrc->lpszFileName = static_cast<LPOLESTR>(OleDuplicateData(pMedSrc->lpszFileName, pFmtSrc->cfFormat, 0)); + break; +#endif + case TYMED_ISTREAM: + pMedDest->pstm = pMedSrc->pstm; + pMedSrc->pstm->AddRef(); + break; + case TYMED_ISTORAGE: + pMedDest->pstg = pMedSrc->pstg; + pMedSrc->pstg->AddRef(); + break; + default: + break; + } + pMedDest->tymed = pMedSrc->tymed; + pMedDest->pUnkForRelease = 0; + if (pMedSrc->pUnkForRelease) { + pMedDest->pUnkForRelease = pMedSrc->pUnkForRelease; + pMedSrc->pUnkForRelease->AddRef(); + } +} +STDMETHODIMP DRTDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc) +{ + if (!ppenumFormatEtc) + return E_POINTER; + + *ppenumFormatEtc = 0; + switch (dwDirection) { + case DATADIR_GET: + *ppenumFormatEtc = new WCEnumFormatEtc(m_formats); + if (!(*ppenumFormatEtc)) + return E_OUTOFMEMORY; + break; + + case DATADIR_SET: + default: + return E_NOTIMPL; + break; + } + + return S_OK; +} + +STDMETHODIMP DRTDataObject::DAdvise(FORMATETC*, DWORD, IAdviseSink*, DWORD*) +{ + return OLE_E_ADVISENOTSUPPORTED; +} + +STDMETHODIMP DRTDataObject::DUnadvise(DWORD) +{ + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE DRTDataObject::EnumDAdvise(IEnumSTATDATA**) +{ + return OLE_E_ADVISENOTSUPPORTED; +} + +void DRTDataObject::clearData(CLIPFORMAT format) +{ + size_t position = 0; + while (position < m_formats.size()) { + if (m_formats[position]->cfFormat == format) { + FORMATETC* current = m_formats[position]; + m_formats[position] = m_formats[m_formats.size() - 1]; + m_formats[m_formats.size() - 1] = 0; + m_formats.removeLast(); + delete current; + STGMEDIUM* medium = m_medium[position]; + m_medium[position] = m_medium[m_medium.size() - 1]; + m_medium[m_medium.size() - 1] = 0; + m_medium.removeLast(); + ReleaseStgMedium(medium); + delete medium; + continue; + } + position++; + } +} diff --git a/Tools/DumpRenderTree/win/DRTDataObject.h b/Tools/DumpRenderTree/win/DRTDataObject.h new file mode 100644 index 000000000..b772b253d --- /dev/null +++ b/Tools/DumpRenderTree/win/DRTDataObject.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2012 Baidu 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 COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DRTDataObject_h +#define DRTDataObject_h + +#include <ShlObj.h> +#include <objidl.h> +#include <wtf/Vector.h> + +FORMATETC* cfHDropFormat(); + +FORMATETC* cfFileNameWFormat(); + +FORMATETC* cfUrlWFormat(); + +class DRTDataObject : public IDataObject { +public: + void CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc); + + // IUnknown + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + + // IDataObject + virtual HRESULT STDMETHODCALLTYPE GetData(FORMATETC* pformatIn, STGMEDIUM* pmedium); + virtual HRESULT STDMETHODCALLTYPE GetDataHere(FORMATETC* pformat, STGMEDIUM* pmedium); + virtual HRESULT STDMETHODCALLTYPE QueryGetData(FORMATETC* pformat); + virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(FORMATETC* pformatectIn, FORMATETC* pformatOut); + virtual HRESULT STDMETHODCALLTYPE SetData(FORMATETC* pformat, STGMEDIUM*pmedium, BOOL release); + virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc); + virtual HRESULT STDMETHODCALLTYPE DAdvise(FORMATETC*, DWORD, IAdviseSink*, DWORD*); + virtual HRESULT STDMETHODCALLTYPE DUnadvise(DWORD); + virtual HRESULT STDMETHODCALLTYPE EnumDAdvise(IEnumSTATDATA**); + + void clearData(CLIPFORMAT); + + static HRESULT createInstance(DRTDataObject**); +private: + DRTDataObject(); + ~DRTDataObject(); + long m_ref; + Vector<FORMATETC*> m_formats; + Vector<STGMEDIUM*> m_medium; +}; + +#endif // DRTDataObject_h diff --git a/Tools/DumpRenderTree/win/DRTDropSource.cpp b/Tools/DumpRenderTree/win/DRTDropSource.cpp new file mode 100644 index 000000000..08b1be887 --- /dev/null +++ b/Tools/DumpRenderTree/win/DRTDropSource.cpp @@ -0,0 +1,86 @@ +/* +* Copyright (C) 2012 Baidu 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 COMPUTER, INC. ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "config.h" +#include "DRTDropSource.h" + +DRTDropSource::DRTDropSource() + : m_ref(1) + , m_dropped(false) +{ +} + +DRTDropSource::~DRTDropSource() +{ +} + +STDMETHODIMP DRTDropSource::QueryInterface(REFIID riid, void** ppvObject) +{ + *ppvObject = 0; + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDropSource)) { + *ppvObject = this; + AddRef(); + + return S_OK; + } + + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) DRTDropSource::AddRef() +{ + return InterlockedIncrement(&m_ref); +} + +STDMETHODIMP_(ULONG) DRTDropSource::Release() +{ + long refCount = InterlockedDecrement(&m_ref); + if (!refCount) + delete this; + return refCount; +} + +HRESULT DRTDropSource::createInstance(IDropSource** result) +{ + if (!result) + return E_INVALIDARG; + *result = new DRTDropSource; + return S_OK; +} + +STDMETHODIMP DRTDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) +{ + if (fEscapePressed || !(grfKeyState & (MK_LBUTTON | MK_RBUTTON))) { + m_dropped = !fEscapePressed; + return fEscapePressed ? DRAGDROP_S_CANCEL : DRAGDROP_S_DROP; + } + + return S_OK; +} + +STDMETHODIMP DRTDropSource::GiveFeedback(DWORD dwEffect) +{ + return DRAGDROP_S_USEDEFAULTCURSORS; +} diff --git a/Tools/DumpRenderTree/win/DRTDropSource.h b/Tools/DumpRenderTree/win/DRTDropSource.h new file mode 100644 index 000000000..f37f2b7e4 --- /dev/null +++ b/Tools/DumpRenderTree/win/DRTDropSource.h @@ -0,0 +1,48 @@ +/* +* Copyright (C) 2012 Baidu 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 COMPUTER, INC. ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef DRTDropSource_h +#define DRTDropSource_h + +#include <ShlObj.h> +#include <windows.h> + +class DRTDropSource : public IDropSource { +public: + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState); + virtual HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD dwEffect); + + static HRESULT createInstance(IDropSource** result); +private: + DRTDropSource(); + ~DRTDropSource(); + long m_ref; + bool m_dropped; +}; + +#endif // DRTDropSource_h diff --git a/Tools/DumpRenderTree/win/DumpRenderTree.cpp b/Tools/DumpRenderTree/win/DumpRenderTree.cpp index 4ed8e0dc6..92ab8632c 100644 --- a/Tools/DumpRenderTree/win/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/win/DumpRenderTree.cpp @@ -905,10 +905,6 @@ static void resetWebViewToConsistentStateBeforeTesting() if (SUCCEEDED(webViewPrivate->defaultMinimumTimerInterval(&minimumInterval))) webViewPrivate->setMinimumTimerInterval(minimumInterval); - COMPtr<IWebInspector> inspector; - if (SUCCEEDED(webViewPrivate->inspector(&inspector))) - inspector->setJavaScriptProfilingEnabled(FALSE); - HWND viewWindow; if (SUCCEEDED(webViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))) && viewWindow) SetFocus(viewWindow); diff --git a/Tools/DumpRenderTree/win/DumpRenderTree.vcproj b/Tools/DumpRenderTree/win/DumpRenderTree.vcproj index 18137a242..4843c390e 100644 --- a/Tools/DumpRenderTree/win/DumpRenderTree.vcproj +++ b/Tools/DumpRenderTree/win/DumpRenderTree.vcproj @@ -402,6 +402,22 @@ > </File> <File + RelativePath=".\DRTDataObject.cpp" + > + </File> + <File + RelativePath=".\DRTDataObject.h" + > + </File> + <File + RelativePath=".\DRTDropSource.cpp" + > + </File> + <File + RelativePath=".\DRTDropSource.h" + > + </File> + <File RelativePath=".\EventSender.cpp" > </File> diff --git a/Tools/DumpRenderTree/win/EventSender.cpp b/Tools/DumpRenderTree/win/EventSender.cpp index 5c0993689..76dafd948 100644 --- a/Tools/DumpRenderTree/win/EventSender.cpp +++ b/Tools/DumpRenderTree/win/EventSender.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2012 Baidu Inc. All rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,16 +30,19 @@ #include "config.h" #include "EventSender.h" +#include "DRTDataObject.h" +#include "DRTDropSource.h" #include "DraggingInfo.h" #include "DumpRenderTree.h" +#include <JavaScriptCore/JavaScriptCore.h> #include <WebCore/COMPtr.h> +#include <WebKit/WebKit.h> +#include <windows.h> #include <wtf/ASCIICType.h> #include <wtf/Assertions.h> #include <wtf/Platform.h> -#include <JavaScriptCore/JavaScriptCore.h> -#include <WebKit/WebKit.h> -#include <windows.h> +#include <wtf/text/WTFString.h> #define WM_DRT_SEND_QUEUED_EVENT (WM_APP+1) @@ -642,6 +646,86 @@ static JSValueRef zoomPageOutCallback(JSContextRef context, JSObjectRef function return JSValueMakeUndefined(context); } +static JSValueRef beginDragWithFilesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + JSObjectRef filesArray = JSValueToObject(context, arguments[0], 0); + + if (!filesArray) + return JSValueMakeUndefined(context); + + JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length"); + Vector<UChar> files; + int filesCount = JSValueToNumber(context, JSObjectGetProperty(context, filesArray, lengthProperty, 0), 0); + for (int i = 0; i < filesCount; ++i) { + JSValueRef value = JSObjectGetPropertyAtIndex(context, filesArray, i, 0); + JSStringRef file = JSValueToStringCopy(context, value, 0); + files.append(JSStringGetCharactersPtr(file), JSStringGetLength(file)); + files.append(0); + JSStringRelease(file); + } + + if (files.isEmpty()) + return JSValueMakeUndefined(context); + + // We should append "0" in the end of |files| so that |DragQueryFileW| retrieved the number of files correctly from Ole Clipboard. + files.append(0); + + STGMEDIUM hDropMedium = {0}; + hDropMedium.tymed = TYMED_HGLOBAL; + SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * files.size()); + hDropMedium.hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dropFilesSize); + DROPFILES* dropFiles = reinterpret_cast<DROPFILES*>(GlobalLock(hDropMedium.hGlobal)); + memset(dropFiles, 0, sizeof(DROPFILES)); + dropFiles->pFiles = sizeof(DROPFILES); + dropFiles->fWide = TRUE; + + UChar* data = reinterpret_cast<UChar*>(reinterpret_cast<BYTE*>(dropFiles) + sizeof(DROPFILES)); + for (size_t i = 0; i < files.size(); ++i) + data[i] = files[i]; + GlobalUnlock(hDropMedium.hGlobal); + + STGMEDIUM hFileNameMedium = {0}; + hFileNameMedium.tymed = TYMED_HGLOBAL; + SIZE_T hFileNameSize = sizeof(WCHAR) * files.size(); + hFileNameMedium.hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, hFileNameSize); + WCHAR* hFileName = static_cast<WCHAR*>(GlobalLock(hFileNameMedium.hGlobal)); + for (size_t i = 0; i < files.size(); i++) + hFileName[i] = files[i]; + GlobalUnlock(hFileNameMedium.hGlobal); + + if (draggingInfo) { + delete draggingInfo; + draggingInfo = 0; + } + + COMPtr<DRTDataObject> dataObeject; + COMPtr<IDropSource> source; + if (FAILED(DRTDataObject::createInstance(&dataObeject))) + dataObeject = 0; + + if (FAILED(DRTDropSource::createInstance(&source))) + source = 0; + + if (dataObeject && source) { + draggingInfo = new DraggingInfo(dataObeject.get(), source.get()); + draggingInfo->setPerformedDropEffect(DROPEFFECT_COPY); + } + + if (draggingInfo) { + draggingInfo->dataObject()->SetData(cfHDropFormat(), &hDropMedium, FALSE); + draggingInfo->dataObject()->SetData(cfFileNameWFormat(), &hFileNameMedium, FALSE); + draggingInfo->dataObject()->SetData(cfUrlWFormat(), &hFileNameMedium, FALSE); + OleSetClipboard(draggingInfo->dataObject()); + down = true; + } + + JSStringRelease(lengthProperty); + return JSValueMakeUndefined(context); +} + static JSStaticFunction staticFunctions[] = { { "contextClick", contextClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "mouseDown", mouseDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -654,6 +738,7 @@ static JSStaticFunction staticFunctions[] = { { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "zoomPageIn", zoomPageInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "zoomPageOut", zoomPageOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "beginDragWithFiles", beginDragWithFilesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { 0, 0, 0 } }; diff --git a/Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp index c6723bdf9..a168e1e93 100644 --- a/Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp +++ b/Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp @@ -846,24 +846,6 @@ void LayoutTestController::setSmartInsertDeleteEnabled(bool flag) viewEditing->setSmartInsertDeleteEnabled(flag ? TRUE : FALSE); } -void LayoutTestController::setJavaScriptProfilingEnabled(bool flag) -{ - COMPtr<IWebView> webView; - if (FAILED(frame->webView(&webView))) - return; - - COMPtr<IWebViewPrivate> viewPrivate; - if (FAILED(webView->QueryInterface(&viewPrivate))) - return; - - COMPtr<IWebInspector> inspector; - if (FAILED(viewPrivate->inspector(&inspector))) - return; - - setDeveloperExtrasEnabled(flag); - inspector->setJavaScriptProfilingEnabled(flag); -} - void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) { COMPtr<IWebView> webView; @@ -1475,10 +1457,6 @@ void LayoutTestController::setTextDirection(JSStringRef direction) framePrivate->setTextDirection(bstrT(direction).GetBSTR()); } -void LayoutTestController::allowRoundingHacks() -{ -} - void LayoutTestController::addChromeInputField() { } diff --git a/Tools/DumpRenderTree/wx/DumpRenderTreeWx.cpp b/Tools/DumpRenderTree/wx/DumpRenderTreeWx.cpp index 1562886ef..31add11a2 100644 --- a/Tools/DumpRenderTree/wx/DumpRenderTreeWx.cpp +++ b/Tools/DumpRenderTree/wx/DumpRenderTreeWx.cpp @@ -103,18 +103,18 @@ public: void OnAlertEvent(WebViewAlertEvent& event) { - fprintf(stdout, "ALERT: %S\n", event.GetMessage().c_str()); + wxFprintf(stdout, "ALERT: %S\n", event.GetMessage()); } void OnConfirmEvent(WebViewConfirmEvent& event) { - fprintf(stdout, "CONFIRM: %S\n", event.GetMessage().c_str()); + wxFprintf(stdout, "CONFIRM: %S\n", event.GetMessage()); event.SetReturnCode(1); } - + void OnPromptEvent(WebViewPromptEvent& event) { - fprintf(stdout, "PROMPT: %S, default text: %S\n", event.GetMessage().c_str(), event.GetResponse().c_str()); + wxFprintf(stdout, "PROMPT: %S, default text: %S\n", event.GetMessage(), event.GetResponse()); event.SetReturnCode(1); } @@ -123,15 +123,13 @@ public: fprintf(stdout, "CONSOLE MESSAGE: "); if (event.GetLineNumber()) fprintf(stdout, "line %d: ", event.GetLineNumber()); - fprintf(stdout, "%S\n", event.GetMessage().c_str()); + wxFprintf(stdout, "%S\n", event.GetMessage()); } void OnReceivedTitleEvent(WebViewReceivedTitleEvent& event) { - if (gLayoutTestController->dumpTitleChanges() && !done) { - const char* title = event.GetTitle().mb_str(wxConvUTF8); - printf("TITLE CHANGED: %S\n", title ? title : ""); - } + if (gLayoutTestController->dumpTitleChanges() && !done) + wxFprintf(stdout, "TITLE CHANGED: %S\n", event.GetTitle()); } void OnWindowObjectClearedEvent(WebViewWindowObjectClearedEvent& event) diff --git a/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp index b65e87ddf..37e3f055c 100644 --- a/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp +++ b/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp @@ -155,10 +155,6 @@ void LayoutTestController::setSmartInsertDeleteEnabled(bool flag) // FIXME: implement } -void LayoutTestController::setJavaScriptProfilingEnabled(bool flag) -{ -} - void LayoutTestController::setWaitToDump(bool waitUntilDone) { static const int timeoutSeconds = 10; @@ -608,10 +604,6 @@ void LayoutTestController::setTextDirection(JSStringRef direction) // FIXME: Implement. } -void LayoutTestController::allowRoundingHacks() -{ -} - void LayoutTestController::addChromeInputField() { } diff --git a/Tools/MiniBrowser/qt/icons/favicon.png b/Tools/MiniBrowser/qt/icons/favicon.png Binary files differindex 4462752a5..325d5bd1e 100644 --- a/Tools/MiniBrowser/qt/icons/favicon.png +++ b/Tools/MiniBrowser/qt/icons/favicon.png diff --git a/Tools/MiniBrowser/qt/qml/BrowserWindow.qml b/Tools/MiniBrowser/qt/qml/BrowserWindow.qml index 5237c715c..0ebf02860 100644 --- a/Tools/MiniBrowser/qt/qml/BrowserWindow.qml +++ b/Tools/MiniBrowser/qt/qml/BrowserWindow.qml @@ -105,6 +105,7 @@ Rectangle { if (parent.enabled) { console.log("MiniBrowser: Going backward in session history.") webView.goBack() + webView.forceActiveFocus() } } } @@ -139,6 +140,7 @@ Rectangle { if (parent.enabled) { console.log("MiniBrowser: Going forward in session history.") webView.goForward() + webView.forceActiveFocus() } } } @@ -267,7 +269,7 @@ Rectangle { height: 16 anchors { left: parent.left - leftMargin: 4 + leftMargin: 6 verticalCenter: parent.verticalCenter } } diff --git a/Tools/QtTestBrowser/cookiejar.cpp b/Tools/QtTestBrowser/cookiejar.cpp index 22a8d17a2..b8ed7d003 100644 --- a/Tools/QtTestBrowser/cookiejar.cpp +++ b/Tools/QtTestBrowser/cookiejar.cpp @@ -25,9 +25,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "config.h" + #include "cookiejar.h" -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) #include <QStandardPaths> #else #include <QDesktopServices> @@ -46,7 +48,7 @@ TestBrowserCookieJar::TestBrowserCookieJar(QObject* parent) connect(&m_timer, SIGNAL(timeout()), this, SLOT(saveToDisk())); #ifndef QT_NO_DESKTOPSERVICES -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) QString path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); #else QString path = QDesktopServices::storageLocation(QDesktopServices::CacheLocation); diff --git a/Tools/QtTestBrowser/launcherwindow.cpp b/Tools/QtTestBrowser/launcherwindow.cpp index 623a7efa1..e4ae456db 100644 --- a/Tools/QtTestBrowser/launcherwindow.cpp +++ b/Tools/QtTestBrowser/launcherwindow.cpp @@ -32,6 +32,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "config.h" + #include "launcherwindow.h" #include "cookiejar.h" #include "urlloader.h" @@ -64,7 +66,7 @@ #endif #if !defined(QT_NO_NETWORKDISKCACHE) && !defined(QT_NO_DESKTOPSERVICES) -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) #include <QStandardPaths> #else #include <QDesktopServices> @@ -806,7 +808,7 @@ void LauncherWindow::setDiskCache(bool enable) QNetworkDiskCache* cache = 0; if (enable) { cache = new QNetworkDiskCache(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#if HAVE(QT5) QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); #else QString cacheLocation = QDesktopServices::storageLocation(QDesktopServices::CacheLocation); diff --git a/Tools/Scripts/old-run-webkit-tests b/Tools/Scripts/old-run-webkit-tests index 5b308ab03..09443c87c 100755 --- a/Tools/Scripts/old-run-webkit-tests +++ b/Tools/Scripts/old-run-webkit-tests @@ -2158,8 +2158,11 @@ sub buildPlatformResultHierarchy() @platforms = $platform; } } elsif ($platform =~ /^qt/) { - if ($platform eq "qt-5.0-wk2") { - push @platforms, $platform; + if ($platform eq "qt-5.0-wk2" || getQtVersion() eq "5.0" && $useWebKitTestRunner) { + push @platforms, "qt-5.0-wk2"; + } + elsif ($platform eq "qt-5.0-wk1" || getQtVersion() eq "5.0" && !$useWebKitTestRunner) { + push @platforms, "qt-5.0-wk1" } if (isARM() || $platform eq "qt-arm") { @@ -2488,9 +2491,6 @@ sub readSkippedFiles($) # additionally to their own to avoid maintaining separate lists. push(@skippedFileDirectories, catdir($platformBaseDirectory, "wk2")) if ($platform eq "win-wk2" || $platform eq "qt-5.0-wk2" || $platform eq "mac-wk2" || $platform eq "gtk-wk2"); - # Add Qt WK1-only skipped tests. - push(@skippedFileDirectories, catdir($platformBaseDirectory, "qt-5.0-wk1")) if (isQt() && !$useWebKitTestRunner); - if ($verbose) { foreach my $skippedPath (@skippedFileDirectories) { print "Using Skipped file: $skippedPath\n"; diff --git a/Tools/Scripts/read-checksum-from-png b/Tools/Scripts/read-checksum-from-png index ab08b253b..fb03f28b7 100755 --- a/Tools/Scripts/read-checksum-from-png +++ b/Tools/Scripts/read-checksum-from-png @@ -30,7 +30,7 @@ from __future__ import with_statement import sys -from webkitpy.layout_tests import read_checksum_from_png +from webkitpy.common import read_checksum_from_png if '__main__' == __name__: diff --git a/Tools/Scripts/update-webkit-chromium b/Tools/Scripts/update-webkit-chromium index 550830e1c..a5c242442 100755 --- a/Tools/Scripts/update-webkit-chromium +++ b/Tools/Scripts/update-webkit-chromium @@ -55,7 +55,7 @@ if (! -e ".gclient") { # If .gclient configuration file doesn't exist, create it. print "Configuring gclient...\n"; system($gclientPath, - "config", + "config", "--spec=solutions=[{'name':'./','url':None}]") == 0 or die $!; } @@ -72,7 +72,13 @@ if (isChromiumAndroid()) { die "Couldn't extract the Android NDK." if $result; } - $ENV{ANDROID_NDK_ROOT} = sourceDir() . "/Source/WebKit/chromium/android-ndk-r7b"; + my $androidNdkRoot = sourceDir() . "/Source/WebKit/chromium/android-ndk-r7b"; + + # Attempt to replace the NDK's linker with a 64-bit version if the host + # OS is Linux. This will significantly speed up link times. + chromiumInstall64BitAndroidLinkerIfNeeded($androidNdkRoot) if isLinux(); + + $ENV{ANDROID_NDK_ROOT} = $androidNdkRoot; $ENV{WEBKIT_ANDROID_BUILD} = 1; } diff --git a/Tools/Scripts/webkitdirs.pm b/Tools/Scripts/webkitdirs.pm index d293d81ef..b728bad0b 100755 --- a/Tools/Scripts/webkitdirs.pm +++ b/Tools/Scripts/webkitdirs.pm @@ -939,7 +939,6 @@ sub blackberryCMakeArguments() if ($cpu eq "a9") { $cpu = $arch . "v7le"; push @cmakeExtraOptions, '-DTARGETING_PLAYBOOK=1'; - push @cmakeExtraOptions, '-DENABLE_GLES2=1'; } my $stageDir = $ENV{"STAGE_DIR"}; @@ -966,7 +965,7 @@ sub blackberryCMakeArguments() push @cmakeExtraOptions, "-DCMAKE_SKIP_RPATH='ON'" if isDarwin(); push @cmakeExtraOptions, "-DENABLE_DRT=1" if $ENV{"ENABLE_DRT"}; - push @cmakeExtraOptions, "-DENABLE_GLES2=1" if $ENV{"ENABLE_GLES2"}; + push @cmakeExtraOptions, "-DENABLE_GLES2=1" unless $ENV{"DISABLE_GLES2"}; my @includeSystemDirectories; push @includeSystemDirectories, File::Spec->catdir($stageInc, "grskia", "skia"); @@ -2495,6 +2494,49 @@ sub buildChromium($@) return $result; } +sub chromiumInstall64BitAndroidLinkerIfNeeded +{ + my ($androidNdkRoot) = @_; + + # Resolve the toolchain version through glob(). + my $linkerDirPrefix = glob("$androidNdkRoot/toolchains/arm-linux-androideabi-*/prebuilt/linux-x86"); + + my $linkerDirname1 = "$linkerDirPrefix/bin"; + my $linkerBasename1 = "arm-linux-androideabi-ld"; + my $linkerDirname2 = "$linkerDirPrefix/arm-linux-androideabi/bin"; + my $linkerBasename2 = "ld"; + my $newLinker = "arm-linux-androideabi-ld.e4df3e0a5bb640ccfa2f30ee67fe9b3146b152d6"; + + # Do not continue if the new linker is not (yet) available. + if (! -e "third_party/aosp/$newLinker") { + return; + } + + chromiumReplaceAndroidLinkerIfNeeded($linkerDirname1, $linkerBasename1, $newLinker); + chromiumReplaceAndroidLinkerIfNeeded($linkerDirname2, $linkerBasename2, $newLinker); +} + +sub chromiumReplaceAndroidLinkerIfNeeded +{ + my ($linkerDirname, $linkerBasename, $newLinker) = @_; + + # If the destination directory does not exist, or the linker has already + # been installed, replacing it will not be necessary. + if (! -d "$linkerDirname" || -e "$linkerDirname/$newLinker") { + return; + } + + print "Installing 64-bit Android linker in $linkerDirname..\n"; + system("cp", "third_party/aosp/$newLinker", "$linkerDirname/$newLinker"); + system("mv", "$linkerDirname/$linkerBasename", "$linkerDirname/$linkerBasename.orig"); + system("ln", "-s", "$newLinker", "$linkerDirname/$linkerBasename"); + + if (! -e "$linkerDirname/$newLinker") { + print "Unable to copy the linker.\n"; + exit 1; + } +} + sub appleApplicationSupportPath { open INSTALL_DIR, "</proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Apple\ Inc./Apple\ Application\ Support/InstallDir"; diff --git a/Tools/Scripts/webkitperl/FeatureList.pm b/Tools/Scripts/webkitperl/FeatureList.pm index 48b885af9..e96851f09 100644 --- a/Tools/Scripts/webkitperl/FeatureList.pm +++ b/Tools/Scripts/webkitperl/FeatureList.pm @@ -51,6 +51,7 @@ my ( $css3FlexboxSupport, $cssExclusionsSupport, $cssFiltersSupport, + $cssImageResolutionSupport, $cssRegionsSupport, $cssShadersSupport, $cssVariablesSupport, @@ -140,7 +141,7 @@ my @features = ( define => "ENABLE_BATTERY_STATUS", default => (isEfl() || isBlackBerry()), value => \$batteryStatusSupport }, { option => "blob", desc => "Toggle Blob support", - define => "ENABLE_BLOB", default => (isAppleMacWebKit() || isGtk() || isChromium() || isBlackBerry()), value => \$blobSupport }, + define => "ENABLE_BLOB", default => (isAppleMacWebKit() || isGtk() || isChromium() || isBlackBerry() || isEfl()), value => \$blobSupport }, { option => "channel-messaging", desc => "Toggle Channel Messaging support", define => "ENABLE_CHANNEL_MESSAGING", default => 1, value => \$channelMessagingSupport }, @@ -154,6 +155,9 @@ my @features = ( { option => "css3-flexbox", desc => "Toggle CSS3 Flexbox support", define => "ENABLE_CSS3_FLEXBOX", default => 1, value => \$css3FlexboxSupport }, + { option => "css-image-resolution", desc => "Toggle CSS image-resolution support", + define => "ENABLE_CSS_IMAGE_RESOLUTION", default => 0, value => \$cssImageResolutionSupport }, + { option => "css-regions", desc => "Toggle CSS Regions support", define => "ENABLE_CSS_REGIONS", default => 1, value => \$cssRegionsSupport }, diff --git a/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py b/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py index b305c19b8..8ae0bb9b9 100644 --- a/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py +++ b/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py @@ -154,17 +154,22 @@ class BaselineOptimizer(object): source = self._filesystem.join(self._scm.checkout_root, directory, baseline_name) data_for_result[result] = self._filesystem.read_binary_file(source) + file_names = [] for directory, result in results_by_directory.items(): if new_results_by_directory.get(directory) != result: - file_name = self._filesystem.join(self._scm.checkout_root, directory, baseline_name) - self._scm.delete(file_name) + file_names.append(self._filesystem.join(self._scm.checkout_root, directory, baseline_name)) + if file_names: + self._scm.delete_list(file_names) + file_names = [] for directory, result in new_results_by_directory.items(): if results_by_directory.get(directory) != result: destination = self._filesystem.join(self._scm.checkout_root, directory, baseline_name) self._filesystem.maybe_make_directory(self._filesystem.split(destination)[0]) self._filesystem.write_binary_file(destination, data_for_result[result]) - self._scm.add(destination) + file_names.append(destination) + if file_names: + self._scm.add_list(file_names) def directories_by_result(self, baseline_name): results_by_directory = self._read_results_by_directory(baseline_name) diff --git a/Tools/Scripts/webkitpy/common/config/committers.py b/Tools/Scripts/webkitpy/common/config/committers.py index 3f99eaddc..04ae256d2 100644 --- a/Tools/Scripts/webkitpy/common/config/committers.py +++ b/Tools/Scripts/webkitpy/common/config/committers.py @@ -251,6 +251,7 @@ committers_unable_to_review = [ Committer("Gyuyoung Kim", ["gyuyoung.kim@samsung.com", "gyuyoung.kim@webkit.org"], "gyuyoung"), Committer("Hans Wennborg", "hans@chromium.org", "hwennborg"), Committer("Hayato Ito", "hayato@chromium.org", "hayato"), + Committer("Hironori Bono", "hbono@chromium.org", "hbono"), Committer("Helder Correia", "helder@sencha.com", "helder"), Committer("Hin-Chung Lam", ["hclam@google.com", "hclam@chromium.org"]), Committer("Igor Trindade Oliveira", ["igor.oliveira@webkit.org", "igor.o@sisa.samsung.com"], "igoroliveira"), diff --git a/Tools/Scripts/webkitpy/layout_tests/read_checksum_from_png.py b/Tools/Scripts/webkitpy/common/read_checksum_from_png.py index 70a0502b7..70a0502b7 100644 --- a/Tools/Scripts/webkitpy/layout_tests/read_checksum_from_png.py +++ b/Tools/Scripts/webkitpy/common/read_checksum_from_png.py diff --git a/Tools/Scripts/webkitpy/layout_tests/read_checksum_from_png_unittest.py b/Tools/Scripts/webkitpy/common/read_checksum_from_png_unittest.py index 7375741ac..defbbf806 100644 --- a/Tools/Scripts/webkitpy/layout_tests/read_checksum_from_png_unittest.py +++ b/Tools/Scripts/webkitpy/common/read_checksum_from_png_unittest.py @@ -24,7 +24,7 @@ import StringIO import unittest -from webkitpy.layout_tests import read_checksum_from_png +from webkitpy.common import read_checksum_from_png class ReadChecksumFromPngTest(unittest.TestCase): diff --git a/Tools/Scripts/webkitpy/common/system/crashlogs.py b/Tools/Scripts/webkitpy/common/system/crashlogs.py index 0dd37d255..270ca81ed 100644 --- a/Tools/Scripts/webkitpy/common/system/crashlogs.py +++ b/Tools/Scripts/webkitpy/common/system/crashlogs.py @@ -56,15 +56,18 @@ class CrashLogs(object): first_line_regex = re.compile(r'^Process:\s+(?P<process_name>.*) \[(?P<pid>\d+)\]$') errors = '' for path in reversed(sorted(logs)): - if not newer_than or self._host.filesystem.mtime(path) > newer_than: - try: + try: + if not newer_than or self._host.filesystem.mtime(path) > newer_than: f = self._host.filesystem.read_text_file(path) match = first_line_regex.match(f[0:f.find('\n')]) if match and match.group('process_name') == process_name and (pid is None or int(match.group('pid')) == pid): return errors + f - except IOError, e: - if include_errors: - errors += "ERROR: Failed to read '%s': %s\n" % (path, str(e)) + except IOError, e: + if include_errors: + errors += "ERROR: Failed to read '%s': %s\n" % (path, str(e)) + except OSError, e: + if include_errors: + errors += "ERROR: Failed to read '%s': %s\n" % (path, str(e)) if include_errors and errors: return errors diff --git a/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py b/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py index d93feec0e..1f5c40a09 100644 --- a/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py +++ b/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py @@ -75,6 +75,7 @@ class CrashLogsTest(unittest.TestCase): else: self.assertEqual(a.splitlines(), b.splitlines()) + def test_find_log_darwin(self): if not SystemHost().platform.is_mac(): return @@ -105,8 +106,17 @@ class CrashLogsTest(unittest.TestCase): self.assertEqual(log, None) def bad_read(path): - raise IOError('No such file or directory') + raise IOError('IOError: No such file or directory') + + def bad_mtime(path): + raise OSError('OSError: No such file or directory') filesystem.read_text_file = bad_read log = crash_logs.find_newest_log("DumpRenderTree", 28531, include_errors=True) - self.assertTrue('No such file or directory' in log) + self.assertTrue('IOError: No such file or directory' in log) + + filesystem = MockFileSystem(files) + crash_logs = CrashLogs(MockSystemHost(filesystem=filesystem)) + filesystem.mtime = bad_mtime + log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0, include_errors=True) + self.assertTrue('OSError: No such file or directory' in log) diff --git a/Tools/Scripts/webkitpy/common/system/executive.py b/Tools/Scripts/webkitpy/common/system/executive.py index 43dcbca1b..8759c719a 100644 --- a/Tools/Scripts/webkitpy/common/system/executive.py +++ b/Tools/Scripts/webkitpy/common/system/executive.py @@ -451,3 +451,15 @@ class Executive(object): def popen(self, *args, **kwargs): return subprocess.Popen(*args, **kwargs) + + def run_in_parallel(self, command_lines_and_cwds, processes=None): + """Runs a list of (cmd_line list, cwd string) tuples in parallel and returns a list of (retcode, stdout, stderr) tuples.""" + return multiprocessing.Pool(processes=processes).map(_run_command_thunk, command_lines_and_cwds) + + +def _run_command_thunk(cmd_line_and_cwd): + # Note that this needs to be a bare module (and hence Picklable) method to work with multiprocessing.Pool. + (cmd_line, cwd) = cmd_line_and_cwd + proc = subprocess.Popen(cmd_line, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = proc.communicate() + return (proc.returncode, stdout, stderr) diff --git a/Tools/Scripts/webkitpy/common/system/executive_mock.py b/Tools/Scripts/webkitpy/common/system/executive_mock.py index d57a5c480..b0db48ca3 100644 --- a/Tools/Scripts/webkitpy/common/system/executive_mock.py +++ b/Tools/Scripts/webkitpy/common/system/executive_mock.py @@ -108,6 +108,11 @@ class MockExecutive(object): self._proc = MockProcess() return self._proc + def run_in_parallel(self, commands): + command_outputs = [] + for cmd_line, cwd in commands: + command_outputs.append([0, self.run_command(cmd_line, cwd=cwd), '']) + return command_outputs class MockExecutive2(object): @staticmethod diff --git a/Tools/Scripts/webkitpy/common/system/executive_unittest.py b/Tools/Scripts/webkitpy/common/system/executive_unittest.py index c63ff3555..466e2ec02 100644 --- a/Tools/Scripts/webkitpy/common/system/executive_unittest.py +++ b/Tools/Scripts/webkitpy/common/system/executive_unittest.py @@ -31,6 +31,7 @@ import os import signal import subprocess import sys +import time import unittest # Since we execute this script directly as part of the unit tests, we need to ensure @@ -216,6 +217,18 @@ class ExecutiveTest(unittest.TestCase): pids = executive.running_pids() self.assertTrue(os.getpid() in pids) + def test_run_in_parallel(self): + NUM_PROCESSES = 4 + DELAY_SECS = 0.25 + cmd_line = [sys.executable, '-c', 'import time; time.sleep(%f); print "hello"' % DELAY_SECS] + cwd = os.getcwd() + commands = [tuple([cmd_line, cwd])] * NUM_PROCESSES + start = time.time() + command_outputs = Executive().run_in_parallel(commands, processes=NUM_PROCESSES) + done = time.time() + self.assertTrue(done - start < NUM_PROCESSES * DELAY_SECS) + self.assertEquals([output[1] for output in command_outputs], ["hello\n"] * NUM_PROCESSES) + def main(platform, stdin, stdout, cmd, args): if platform == 'win32' and hasattr(stdout, 'fileno'): diff --git a/Tools/Scripts/webkitpy/common/system/filesystem_mock.py b/Tools/Scripts/webkitpy/common/system/filesystem_mock.py index d4a955080..a4eb695bf 100644 --- a/Tools/Scripts/webkitpy/common/system/filesystem_mock.py +++ b/Tools/Scripts/webkitpy/common/system/filesystem_mock.py @@ -47,6 +47,7 @@ class MockFileSystem(object): """ self.files = files or {} self.written_files = {} + self.last_tmpdir = None self._sep = '/' self.current_tmpno = 0 self.cwd = cwd @@ -233,7 +234,8 @@ class MockFileSystem(object): dir = self.sep + '__im_tmp' curno = self.current_tmpno self.current_tmpno += 1 - return self.join(dir, "%s_%u_%s" % (prefix, curno, suffix)) + self.last_tmpdir = self.join(dir, '%s_%u_%s' % (prefix, curno, suffix)) + return self.last_tmpdir def mkdtemp(self, **kwargs): class TemporaryDirectory(object): diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py index 047377c74..e762cfda0 100644 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py +++ b/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py @@ -46,6 +46,7 @@ import time from webkitpy.layout_tests.controllers import manager_worker_broker from webkitpy.layout_tests.controllers import worker +from webkitpy.layout_tests.controllers.test_result_writer import TestResultWriter from webkitpy.layout_tests.layout_package import json_layout_results_generator from webkitpy.layout_tests.layout_package import json_results_generator from webkitpy.layout_tests.models import test_expectations @@ -106,6 +107,7 @@ def use_trac_links_in_results_html(port_obj): # Use existence of builder_name as a proxy for knowing we're on a bot. return port_obj.get_option("builder_name") + # FIXME: This should be on the Manager class (since that's the only caller) # or split off from Manager onto another helper class, but should not be a free function. # Most likely this should be made into its own class, and this super-long function @@ -909,6 +911,10 @@ class Manager(object): end_time = time.time() + # Some crash logs can take a long time to be written out so look + # for new logs after the test run finishes. + self._look_for_new_crash_logs(result_summary, start_time) + self._look_for_new_crash_logs(retry_summary, start_time) self._clean_up_run() self._print_timing_statistics(end_time - start_time, thread_timings, test_timings, individual_test_timings, result_summary) @@ -970,6 +976,29 @@ class Manager(object): _log.debug("cleaning up port") self._port.clean_up_test_run() + def _look_for_new_crash_logs(self, result_summary, start_time): + """Since crash logs can take a long time to be written out if the system is + under stress do a second pass at the end of the test run. + + result_summary: the results of the test run + start_time: time the tests started at. We're looking for crash + logs after that time. + """ + crashed_processes = [] + for test, result in result_summary.unexpected_results.iteritems(): + if (result.type != test_expectations.CRASH): + continue + for failure in result.failures: + if not isinstance(failure, test_failures.FailureCrash): + continue + crashed_processes.append([test, failure.process_name, failure.pid]) + + crash_logs = self._port.look_for_new_crash_logs(crashed_processes, start_time) + if crash_logs: + for test, crash_log in crash_logs.iteritems(): + writer = TestResultWriter(self._port._filesystem, self._port, self._port.results_directory(), test) + writer.write_crash_log(crash_log) + def update_summary(self, result_summary): """Update the summary and print results with any completed tests.""" while True: diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py b/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py index 63e18ac8a..3ddab8ec3 100644 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py @@ -32,6 +32,7 @@ import StringIO import sys +import time import unittest from webkitpy.common.system.filesystem_mock import MockFileSystem @@ -326,6 +327,21 @@ class ManagerTest(unittest.TestCase): manager = get_manager_with_tests(['http\\tests\\mime']) self.assertTrue(manager.needs_servers()) + def test_look_for_new_crash_logs(self): + def get_manager_with_tests(test_names): + host = MockHost() + port = host.port_factory.get('test-mac-leopard') + manager = Manager(port, options=MockOptions(test_list=None, http=True), printer=Mock()) + manager.collect_tests(test_names) + return manager + host = MockHost() + port = host.port_factory.get('test-mac-leopard') + tests = ['failures/expected/crash.html'] + expectations = test_expectations.TestExpectations(port, tests) + rs = result_summary.ResultSummary(expectations, tests) + manager = get_manager_with_tests(tests) + manager._look_for_new_crash_logs(rs, time.time()) + class NaturalCompareTest(unittest.TestCase): def assert_cmp(self, x, y, result): diff --git a/Tools/Scripts/webkitpy/layout_tests/port/base.py b/Tools/Scripts/webkitpy/layout_tests/port/base.py index 64ad13686..c0e13dfcb 100755 --- a/Tools/Scripts/webkitpy/layout_tests/port/base.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/base.py @@ -36,13 +36,13 @@ import errno import os import re +from webkitpy.common import find_files +from webkitpy.common import read_checksum_from_png from webkitpy.common.memoized import memoized from webkitpy.common.system import path -from webkitpy.common import find_files from webkitpy.common.system import logutils from webkitpy.common.system.executive import ScriptError from webkitpy.common.system.systemhost import SystemHost -from webkitpy.layout_tests import read_checksum_from_png from webkitpy.layout_tests.models.test_configuration import TestConfiguration from webkitpy.layout_tests.port import config as port_config from webkitpy.layout_tests.port import driver @@ -907,7 +907,6 @@ class Port(object): # where turnk isn't checked out as a whole. return [('webkit', self.layout_tests_dir())] - _WDIFF_DEL = '##WDIFF_DEL##' _WDIFF_ADD = '##WDIFF_ADD##' _WDIFF_END = '##WDIFF_END##' @@ -1085,6 +1084,9 @@ class Port(object): '\n'.join(('STDOUT: ' + l) for l in stdout_lines), '\n'.join(('STDERR: ' + l) for l in stderr_lines)) + def look_for_new_crash_logs(self, crashed_processes, start_time): + pass + def sample_process(self, name, pid): pass diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium.py index cb68f1460..9db4cb570 100755 --- a/Tools/Scripts/webkitpy/layout_tests/port/chromium.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium.py @@ -327,9 +327,12 @@ class ChromiumPort(Port): (filetype, filepath)) return (self._filesystem.read_text_file(filepath) or '') else: - _log.warning( - "%s test_expectations overrides file '%s' does not exist" % - (filetype, filepath)) + # FIXME: This allows this to work with mock checkouts; + # This probably shouldn't be used with a mock checkout, though. + if not 'mock-checkout' in filepath: + _log.warning( + "%s test_expectations overrides file '%s' does not exist" % + (filetype, filepath)) return '' def test_expectations_overrides(self): diff --git a/Tools/Scripts/webkitpy/layout_tests/port/mac.py b/Tools/Scripts/webkitpy/layout_tests/port/mac.py index 855217682..fa57cc3f7 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/mac.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/mac.py @@ -41,6 +41,7 @@ from webkitpy.layout_tests.port.leakdetector import LeakDetector _log = logging.getLogger(__name__) + class MacPort(ApplePort): port_name = "mac" @@ -177,7 +178,7 @@ class MacPort(ApplePort): def release_http_lock(self): pass - def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None): + def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None, wait_for_log=True): # Note that we do slow-spin here and wait, since it appears the time # ReportCrash takes to actually write and flush the file varies when there are # lots of simultaneous crashes going on. @@ -192,14 +193,34 @@ class MacPort(ApplePort): deadline = now + 5 * int(self.get_option('child_processes', 1)) while not crash_log and now <= deadline: crash_log = crash_logs.find_newest_log(name, pid, include_errors=True, newer_than=newer_than) + if not wait_for_log: + break if not crash_log or not [line for line in crash_log.splitlines() if not line.startswith('ERROR')]: sleep_fn(0.1) now = time_fn() + if not crash_log: - crash_log = 'no crash log found for %s:%d' % (name, pid) - _log.warning(crash_log) + return None return crash_log + def look_for_new_crash_logs(self, crashed_processes, start_time): + """Since crash logs can take a long time to be written out if the system is + under stress do a second pass at the end of the test run. + + crashes: test_name -> pid, process_name tuple of crashed process + start_time: time the tests started at. We're looking for crash + logs after that time. + """ + crash_logs = {} + for (test_name, process_name, pid) in crashed_processes: + # Passing None for output. This is a second pass after the test finished so + # if the output had any loggine we would have already collected it. + crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False) + if not crash_log: + continue + crash_logs[test_name] = crash_log + return crash_logs + def sample_process(self, name, pid): try: hang_report = self._filesystem.join(self.results_directory(), "%s-%s.sample.txt" % (name, pid)) diff --git a/Tools/Scripts/webkitpy/layout_tests/port/qt.py b/Tools/Scripts/webkitpy/layout_tests/port/qt.py index de93bf47f..520575952 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/qt.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/qt.py @@ -111,10 +111,13 @@ class QtPort(WebKitPort): def baseline_search_path(self): search_paths = [] - if self.get_option('webkit_test_runner'): - search_paths.append(self._wk2_port_name()) - search_paths.append(self.name()) version = self.qt_version() + if '5.0' in version: + if self.get_option('webkit_test_runner'): + search_paths.append('qt-5.0-wk2') + else: + search_paths.append('qt-5.0-wk1') + search_paths.append(self.name()) if '4.8' in version: search_paths.append('qt-4.8') elif version: diff --git a/Tools/Scripts/webkitpy/layout_tests/port/qt_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/qt_unittest.py index 0cc694780..7252b9833 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/qt_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/qt_unittest.py @@ -72,6 +72,10 @@ class QtPortTest(port_testcase.PortTestCase): self._assert_search_path(['qt-5.0-wk2', 'qt-win', 'qt-5.0', 'qt'], 'win', use_webkit2=True, qt_version='5.0') self._assert_search_path(['qt-5.0-wk2', 'qt-linux', 'qt-5.0', 'qt'], 'linux', use_webkit2=True, qt_version='5.0') + self._assert_search_path(['qt-5.0-wk1', 'qt-mac', 'qt-5.0', 'qt'], 'mac', use_webkit2=False, qt_version='5.0') + self._assert_search_path(['qt-5.0-wk1', 'qt-win', 'qt-5.0', 'qt'], 'win', use_webkit2=False, qt_version='5.0') + self._assert_search_path(['qt-5.0-wk1', 'qt-linux', 'qt-5.0', 'qt'], 'linux', use_webkit2=False, qt_version='5.0') + def test_show_results_html_file(self): port = self.make_port() port._executive = MockExecutive(should_log=True) diff --git a/Tools/Scripts/webkitpy/layout_tests/port/webkit.py b/Tools/Scripts/webkitpy/layout_tests/port/webkit.py index d798039ac..879c79abf 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/webkit.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/webkit.py @@ -441,7 +441,7 @@ class WebKitDriver(Driver): def __init__(self, port, worker_number, pixel_tests, no_timeout=False): Driver.__init__(self, port, worker_number, pixel_tests, no_timeout) - self._driver_tempdir = port._filesystem.mkdtemp(prefix='%s-' % self._port.driver_name()) + self._driver_tempdir = None # WebKitTestRunner can report back subprocess crashes by printing # "#CRASHED - PROCESSNAME". Since those can happen at any time # and ServerProcess won't be aware of them (since the actual tool @@ -449,6 +449,10 @@ class WebKitDriver(Driver): self._crashed_process_name = None self._crashed_pid = None + # WebKitTestRunner can report back subprocesses that became unresponsive + # This could mean they crashed. + self._subprocess_was_unresponsive = False + # stderr reading is scoped on a per-test (not per-block) basis, so we store the accumulated # stderr output, as well as if we've seen #EOF on this driver instance. # FIXME: We should probably remove _read_first_block and _read_optional_image_block and @@ -457,10 +461,9 @@ class WebKitDriver(Driver): self.err_seen_eof = False self._server_process = None - # FIXME: This may be unsafe, as python does not guarentee any ordering of __del__ calls - # I believe it's possible that self._port or self._port._filesystem may already be destroyed. def __del__(self): - self._port._filesystem.rmtree(str(self._driver_tempdir)) + assert(self._server_process is None) + assert(self._driver_tempdir is None) def cmd_line(self, pixel_tests, per_test_args): cmd = self._command_wrapper(self._port.get_option('wrapper')) @@ -485,6 +488,7 @@ class WebKitDriver(Driver): return cmd def _start(self, pixel_tests, per_test_args): + self._driver_tempdir = self._port._filesystem.mkdtemp(prefix='%s-' % self._port.driver_name()) server_name = self._port.driver_name() environment = self._port.setup_environ_for_server(server_name) environment['DYLD_LIBRARY_PATH'] = self._port._build_path() @@ -513,7 +517,8 @@ class WebKitDriver(Driver): # See http://trac.webkit.org/changeset/65537. self._crashed_process_name = self._server_process.name() self._crashed_pid = self._server_process.pid() - elif error_line.startswith("#CRASHED - WebProcess"): + elif (error_line.startswith("#CRASHED - WebProcess") + or error_line.startswith("#PROCESS UNRESPONSIVE - WebProcess")): # WebKitTestRunner uses this to report that the WebProcess subprocess crashed. pid = None m = re.search('pid (\d+)', error_line) @@ -523,11 +528,16 @@ class WebKitDriver(Driver): self._crashed_pid = pid # FIXME: delete this after we're sure this code is working :) _log.debug('WebProcess crash, pid = %s, error_line = %s' % (str(pid), error_line)) + if error_line.startswith("#PROCESS UNRESPONSIVE - WebProcess"): + self._subprocess_was_unresponsive = True return True return self.has_crashed() def _command_from_driver_input(self, driver_input): - if self.is_http_test(driver_input.test_name): + # FIXME: performance tests pass in full URLs instead of test names. + if driver_input.test_name.startswith('http://') or driver_input.test_name.startswith('https://'): + command = driver_input.test_name + elif self.is_http_test(driver_input.test_name): command = self.test_to_uri(driver_input.test_name) else: command = self._port.abspath_for_test(driver_input.test_name) @@ -573,11 +583,18 @@ class WebKitDriver(Driver): # FIXME: We may need to also read stderr until the process dies? self.error_from_test += self._server_process.pop_all_buffered_stderr() - crash_log = '' + crash_log = None if self.has_crashed(): crash_log = self._port._get_crash_log(self._crashed_process_name, self._crashed_pid, text, self.error_from_test, newer_than=start_time) + # If we don't find a crash log use a placeholder error message instead. + if not crash_log: + crash_log = 'no crash log found for %s:%d.' % (self._crashed_process_name, self._crashed_pid) + # If we were unresponsive append a message informing there may not have been a crash. + if self._subprocess_was_unresponsive: + crash_log += ' Process failed to become responsive before timing out.' + timeout = self._server_process.timed_out if timeout: # DRT doesn't have a built in timer to abort the test, so we might as well @@ -668,6 +685,10 @@ class WebKitDriver(Driver): self._server_process.stop() self._server_process = None + if self._driver_tempdir: + self._port._filesystem.rmtree(str(self._driver_tempdir)) + self._driver_tempdir = None + class ContentBlock(object): def __init__(self): diff --git a/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py index 09916ba4e..33e422866 100755 --- a/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py @@ -277,6 +277,7 @@ class WebKitDriverTest(unittest.TestCase): self.assertEquals(content_block.content_type, 'my_type') self.assertEquals(content_block.encoding, 'none') self.assertEquals(content_block.content_hash, 'foobar') + driver._server_process = None def test_read_binary_block(self): port = TestWebKitPort() @@ -294,6 +295,7 @@ class WebKitDriverTest(unittest.TestCase): self.assertEquals(content_block.content_hash, 'actual') self.assertEquals(content_block.content, '12345678') self.assertEquals(content_block.decoded_content, '12345678') + driver._server_process = None def test_no_timeout(self): port = TestWebKitPort() @@ -317,10 +319,15 @@ class WebKitDriverTest(unittest.TestCase): def has_crashed(self): return self.crashed - def assert_crash(driver, error_line, crashed, name, pid): + def stop(self): + pass + + def assert_crash(driver, error_line, crashed, name, pid, unresponsive=False): self.assertEquals(driver._check_for_driver_crash(error_line), crashed) self.assertEquals(driver._crashed_process_name, name) self.assertEquals(driver._crashed_pid, pid) + self.assertEquals(driver._subprocess_was_unresponsive, unresponsive) + driver.stop() driver._server_process = FakeServerProcess(False) assert_crash(driver, '', False, None, None) @@ -328,19 +335,44 @@ class WebKitDriverTest(unittest.TestCase): driver._crashed_process_name = None driver._crashed_pid = None driver._server_process = FakeServerProcess(False) + driver._subprocess_was_unresponsive = False assert_crash(driver, '#CRASHED\n', True, 'FakeServerProcess', 1234) driver._crashed_process_name = None driver._crashed_pid = None driver._server_process = FakeServerProcess(False) + driver._subprocess_was_unresponsive = False assert_crash(driver, '#CRASHED - WebProcess\n', True, 'WebProcess', None) driver._crashed_process_name = None driver._crashed_pid = None driver._server_process = FakeServerProcess(False) + driver._subprocess_was_unresponsive = False assert_crash(driver, '#CRASHED - WebProcess (pid 8675)\n', True, 'WebProcess', 8675) + + driver._crashed_process_name = None + driver._crashed_pid = None + driver._server_process = FakeServerProcess(False) + driver._subprocess_was_unresponsive = False + assert_crash(driver, '#PROCESS UNRESPONSIVE - WebProcess (pid 8675)\n', True, 'WebProcess', 8675, True) driver._crashed_process_name = None driver._crashed_pid = None driver._server_process = FakeServerProcess(True) + driver._subprocess_was_unresponsive = False assert_crash(driver, '', True, 'FakeServerProcess', 1234) + + def test_creating_a_port_does_not_write_to_the_filesystem(self): + port = TestWebKitPort() + driver = WebKitDriver(port, 0, pixel_tests=True) + self.assertEquals(port._filesystem.written_files, {}) + self.assertEquals(port._filesystem.last_tmpdir, None) + + def test_stop_cleans_up_properly(self): + port = TestWebKitPort() + driver = WebKitDriver(port, 0, pixel_tests=True) + driver.start(True, []) + last_tmpdir = port._filesystem.last_tmpdir + self.assertNotEquals(last_tmpdir, None) + driver.stop() + self.assertFalse(port._filesystem.isdir(last_tmpdir)) diff --git a/Tools/Scripts/webkitpy/performance_tests/perftest.py b/Tools/Scripts/webkitpy/performance_tests/perftest.py index a81c47880..20d3d5838 100644 --- a/Tools/Scripts/webkitpy/performance_tests/perftest.py +++ b/Tools/Scripts/webkitpy/performance_tests/perftest.py @@ -28,18 +28,30 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import errno import logging import math import re +import os +import signal +import socket +import subprocess +import time +# Import for auto-install +import webkitpy.thirdparty.autoinstalled.webpagereplay.replay + +from webkitpy.layout_tests.controllers.test_result_writer import TestResultWriter from webkitpy.layout_tests.port.driver import DriverInput +from webkitpy.layout_tests.port.driver import DriverOutput _log = logging.getLogger(__name__) class PerfTest(object): - def __init__(self, test_name, path_or_url): + def __init__(self, port, test_name, path_or_url): + self._port = port self._test_name = test_name self._path_or_url = path_or_url @@ -49,12 +61,18 @@ class PerfTest(object): def path_or_url(self): return self._path_or_url - def run(self, driver, timeout_ms): - output = driver.run_test(DriverInput(self.path_or_url(), timeout_ms, None, False)) + def prepare(self, time_out_ms): + return True + + def run(self, driver, time_out_ms): + output = self.run_single(driver, self.path_or_url(), time_out_ms) if self.run_failed(output): return None return self.parse_output(output) + def run_single(self, driver, path_or_url, time_out_ms, should_run_pixel_test=False): + return driver.run_test(DriverInput(path_or_url, time_out_ms, image_hash=None, should_run_pixel_test=should_run_pixel_test)) + def run_failed(self, output): if output.text == None or output.error: pass @@ -137,8 +155,8 @@ class PerfTest(object): class ChromiumStylePerfTest(PerfTest): _chromium_style_result_regex = re.compile(r'^RESULT\s+(?P<name>[^=]+)\s*=\s+(?P<value>\d+(\.\d+)?)\s*(?P<unit>\w+)$') - def __init__(self, test_name, path_or_url): - super(ChromiumStylePerfTest, self).__init__(test_name, path_or_url) + def __init__(self, port, test_name, path_or_url): + super(ChromiumStylePerfTest, self).__init__(port, test_name, path_or_url) def parse_output(self, output): test_failed = False @@ -157,15 +175,15 @@ class ChromiumStylePerfTest(PerfTest): class PageLoadingPerfTest(PerfTest): - def __init__(self, test_name, path_or_url): - super(PageLoadingPerfTest, self).__init__(test_name, path_or_url) + def __init__(self, port, test_name, path_or_url): + super(PageLoadingPerfTest, self).__init__(port, test_name, path_or_url) - def run(self, driver, timeout_ms): + def run(self, driver, time_out_ms): test_times = [] for i in range(0, 20): - output = driver.run_test(DriverInput(self.path_or_url(), timeout_ms, None, False)) - if self.run_failed(output): + output = self.run_single(driver, self.path_or_url(), time_out_ms) + if not output or self.run_failed(output): return None if i == 0: continue @@ -194,16 +212,130 @@ class PageLoadingPerfTest(PerfTest): return {self.test_name(): results} +class ReplayServer(object): + def __init__(self, archive, record): + self._process = None + + # FIXME: Should error if local proxy isn't set to forward requests to localhost:8080 and localhost:8413 + + replay_path = webkitpy.thirdparty.autoinstalled.webpagereplay.replay.__file__ + args = ['python', replay_path, '--no-dns_forwarding', '--port', '8080', '--ssl_port', '8413', '--use_closest_match', '--log_level', 'warning'] + if record: + args.append('--record') + args.append(archive) + + self._process = subprocess.Popen(args) + + def wait_until_ready(self): + for i in range(0, 10): + try: + connection = socket.create_connection(('localhost', '8080'), timeout=1) + connection.close() + return True + except socket.error: + time.sleep(1) + continue + return False + + def stop(self): + if self._process: + self._process.send_signal(signal.SIGINT) + self._process.wait() + self._process = None + + def __del__(self): + self.stop() + + +class ReplayPerfTest(PageLoadingPerfTest): + def __init__(self, port, test_name, path_or_url): + super(ReplayPerfTest, self).__init__(port, test_name, path_or_url) + + def _start_replay_server(self, archive, record): + try: + return ReplayServer(archive, record) + except OSError as error: + if error.errno == errno.ENOENT: + _log.error("Replay tests require web-page-replay.") + else: + raise error + + def prepare(self, time_out_ms): + filesystem = self._port.host.filesystem + path_without_ext = filesystem.splitext(self.path_or_url())[0] + + self._archive_path = filesystem.join(path_without_ext + '.wpr') + self._expected_image_path = filesystem.join(path_without_ext + '-expected.png') + self._url = filesystem.read_text_file(self.path_or_url()).split('\n')[0] + + if filesystem.isfile(self._archive_path) and filesystem.isfile(self._expected_image_path): + _log.info("Replay ready for %s" % self._archive_path) + return True + + _log.info("Preparing replay for %s" % self.test_name()) + + driver = self._port.create_driver(worker_number=1, no_timeout=True) + try: + output = self.run_single(driver, self._url, time_out_ms, record=True) + finally: + driver.stop() + + if not output or not filesystem.isfile(self._archive_path): + _log.error("Failed to prepare a replay for %s" % self.test_name()) + return False + + _log.info("Prepared replay for %s" % self.test_name()) + + return True + + def run_single(self, driver, url, time_out_ms, record=False): + server = self._start_replay_server(self._archive_path, record) + if not server: + _log.error("Web page replay didn't start.") + return None + + try: + if not server.wait_until_ready(): + _log.error("Web page replay didn't start.") + return None + + super(ReplayPerfTest, self).run_single(driver, "about:blank", time_out_ms) + _log.debug("Loading the page") + + output = super(ReplayPerfTest, self).run_single(driver, self._url, time_out_ms, should_run_pixel_test=True) + if self.run_failed(output): + return None + + if not output.image: + _log.error("Loading the page did not generate image results") + _log.error(output.text) + return None + + filesystem = self._port.host.filesystem + dirname = filesystem.dirname(url) + filename = filesystem.split(url)[1] + writer = TestResultWriter(filesystem, self._port, dirname, filename) + if record: + writer.write_image_files(actual_image=None, expected_image=output.image) + else: + writer.write_image_files(actual_image=output.image, expected_image=None) + + return output + finally: + server.stop() + + class PerfTestFactory(object): _pattern_map = [ - (re.compile('^inspector/'), ChromiumStylePerfTest), - (re.compile('^PageLoad/'), PageLoadingPerfTest), + (re.compile(r'^inspector/'), ChromiumStylePerfTest), + (re.compile(r'^PageLoad/'), PageLoadingPerfTest), + (re.compile(r'(.+)\.replay$'), ReplayPerfTest), ] @classmethod - def create_perf_test(cls, test_name, path): + def create_perf_test(cls, port, test_name, path): for (pattern, test_class) in cls._pattern_map: if pattern.match(test_name): - return test_class(test_name, path) - return PerfTest(test_name, path) + return test_class(port, test_name, path) + return PerfTest(port, test_name, path) diff --git a/Tools/Scripts/webkitpy/performance_tests/perftest_unittest.py b/Tools/Scripts/webkitpy/performance_tests/perftest_unittest.py index 21efd2c3c..078f08a46 100755 --- a/Tools/Scripts/webkitpy/performance_tests/perftest_unittest.py +++ b/Tools/Scripts/webkitpy/performance_tests/perftest_unittest.py @@ -31,12 +31,16 @@ import StringIO import math import unittest +from webkitpy.common.host_mock import MockHost from webkitpy.common.system.outputcapture import OutputCapture from webkitpy.layout_tests.port.driver import DriverOutput +from webkitpy.layout_tests.port.test import TestDriver +from webkitpy.layout_tests.port.test import TestPort from webkitpy.performance_tests.perftest import ChromiumStylePerfTest from webkitpy.performance_tests.perftest import PageLoadingPerfTest from webkitpy.performance_tests.perftest import PerfTest from webkitpy.performance_tests.perftest import PerfTestFactory +from webkitpy.performance_tests.perftest import ReplayPerfTest class MainTest(unittest.TestCase): @@ -53,7 +57,7 @@ class MainTest(unittest.TestCase): output_capture = OutputCapture() output_capture.capture_output() try: - test = PerfTest('some-test', '/path/some-dir/some-test') + test = PerfTest(None, 'some-test', '/path/some-dir/some-test') self.assertEqual(test.parse_output(output), {'some-test': {'avg': 1100.0, 'median': 1101.0, 'min': 1080.0, 'max': 1120.0, 'stdev': 11.0, 'unit': 'ms'}}) finally: @@ -77,7 +81,7 @@ class MainTest(unittest.TestCase): output_capture = OutputCapture() output_capture.capture_output() try: - test = PerfTest('some-test', '/path/some-dir/some-test') + test = PerfTest(None, 'some-test', '/path/some-dir/some-test') self.assertEqual(test.parse_output(output), None) finally: actual_stdout, actual_stderr, actual_logs = output_capture.restore_output() @@ -101,7 +105,7 @@ class TestPageLoadingPerfTest(unittest.TestCase): return DriverOutput('some output', image=None, image_hash=None, audio=None, test_time=self._values[self._index - 1]) def test_run(self): - test = PageLoadingPerfTest('some-test', '/path/some-dir/some-test') + test = PageLoadingPerfTest(None, 'some-test', '/path/some-dir/some-test') driver = TestPageLoadingPerfTest.MockDriver([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]) output_capture = OutputCapture() output_capture.capture_output() @@ -118,7 +122,7 @@ class TestPageLoadingPerfTest(unittest.TestCase): output_capture = OutputCapture() output_capture.capture_output() try: - test = PageLoadingPerfTest('some-test', '/path/some-dir/some-test') + test = PageLoadingPerfTest(None, 'some-test', '/path/some-dir/some-test') driver = TestPageLoadingPerfTest.MockDriver([1, 2, 3, 4, 5, 6, 7, 'some error', 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]) self.assertEqual(test.run(driver, None), None) finally: @@ -128,17 +132,192 @@ class TestPageLoadingPerfTest(unittest.TestCase): self.assertEqual(actual_logs, 'error: some-test\nsome error\n') +class TestReplayPerfTest(unittest.TestCase): + + class ReplayTestPort(TestPort): + def __init__(self, custom_run_test=None): + + class ReplayTestDriver(TestDriver): + def run_test(self, text_input): + return custom_run_test(text_input) if custom_run_test else None + + self._custom_driver_class = ReplayTestDriver + super(self.__class__, self).__init__(host=MockHost()) + + def _driver_class(self): + return self._custom_driver_class + + class MockReplayServer(object): + def __init__(self, wait_until_ready=True): + self.wait_until_ready = lambda: wait_until_ready + + def stop(self): + pass + + def _add_file(self, port, dirname, filename, content=True): + port.host.filesystem.maybe_make_directory(dirname) + port.host.filesystem.files[port.host.filesystem.join(dirname, filename)] = content + + def _setup_test(self, run_test=None): + test_port = self.ReplayTestPort(run_test) + self._add_file(test_port, '/path/some-dir', 'some-test.replay', 'http://some-test/') + test = ReplayPerfTest(test_port, 'some-test.replay', '/path/some-dir/some-test.replay') + test._start_replay_server = lambda archive, record: self.__class__.MockReplayServer() + return test, test_port + + def test_run_single(self): + output_capture = OutputCapture() + output_capture.capture_output() + + loaded_pages = [] + + def run_test(test_input): + if test_input.test_name != "about:blank": + self.assertEqual(test_input.test_name, 'http://some-test/') + loaded_pages.append(test_input) + self._add_file(port, '/path/some-dir', 'some-test.wpr', 'wpr content') + return DriverOutput('actual text', 'actual image', 'actual checksum', + audio=None, crash=False, timeout=False, error=False) + + test, port = self._setup_test(run_test) + test._archive_path = '/path/some-dir/some-test.wpr' + test._url = 'http://some-test/' + + try: + driver = port.create_driver(worker_number=1, no_timeout=True) + self.assertTrue(test.run_single(driver, '/path/some-dir/some-test.replay', time_out_ms=100)) + finally: + actual_stdout, actual_stderr, actual_logs = output_capture.restore_output() + + self.assertEqual(len(loaded_pages), 2) + self.assertEqual(loaded_pages[0].test_name, 'about:blank') + self.assertEqual(loaded_pages[1].test_name, 'http://some-test/') + self.assertEqual(actual_stdout, '') + self.assertEqual(actual_stderr, '') + self.assertEqual(actual_logs, '') + + def test_run_single_fails_without_webpagereplay(self): + output_capture = OutputCapture() + output_capture.capture_output() + + test, port = self._setup_test() + test._start_replay_server = lambda archive, record: None + test._archive_path = '/path/some-dir.wpr' + test._url = 'http://some-test/' + + try: + driver = port.create_driver(worker_number=1, no_timeout=True) + self.assertEqual(test.run_single(driver, '/path/some-dir/some-test.replay', time_out_ms=100), None) + finally: + actual_stdout, actual_stderr, actual_logs = output_capture.restore_output() + self.assertEqual(actual_stdout, '') + self.assertEqual(actual_stderr, '') + self.assertEqual(actual_logs, "Web page replay didn't start.\n") + + def test_prepare_fails_when_wait_until_ready_fails(self): + output_capture = OutputCapture() + output_capture.capture_output() + + test, port = self._setup_test() + test._start_replay_server = lambda archive, record: self.__class__.MockReplayServer(wait_until_ready=False) + test._archive_path = '/path/some-dir.wpr' + test._url = 'http://some-test/' + + try: + driver = port.create_driver(worker_number=1, no_timeout=True) + self.assertEqual(test.run_single(driver, '/path/some-dir/some-test.replay', time_out_ms=100), None) + finally: + actual_stdout, actual_stderr, actual_logs = output_capture.restore_output() + + self.assertEqual(actual_stdout, '') + self.assertEqual(actual_stderr, '') + self.assertEqual(actual_logs, "Web page replay didn't start.\n") + + def test_run_single_fails_when_output_has_error(self): + output_capture = OutputCapture() + output_capture.capture_output() + + loaded_pages = [] + + def run_test(test_input): + loaded_pages.append(test_input) + self._add_file(port, '/path/some-dir', 'some-test.wpr', 'wpr content') + return DriverOutput('actual text', 'actual image', 'actual checksum', + audio=None, crash=False, timeout=False, error='some error') + + test, port = self._setup_test(run_test) + test._archive_path = '/path/some-dir.wpr' + test._url = 'http://some-test/' + + try: + driver = port.create_driver(worker_number=1, no_timeout=True) + self.assertEqual(test.run_single(driver, '/path/some-dir/some-test.replay', time_out_ms=100), None) + finally: + actual_stdout, actual_stderr, actual_logs = output_capture.restore_output() + + self.assertEqual(len(loaded_pages), 2) + self.assertEqual(loaded_pages[0].test_name, 'about:blank') + self.assertEqual(loaded_pages[1].test_name, 'http://some-test/') + self.assertEqual(actual_stdout, '') + self.assertEqual(actual_stderr, '') + self.assertEqual(actual_logs, 'error: some-test.replay\nsome error\n') + + def test_prepare(self): + output_capture = OutputCapture() + output_capture.capture_output() + + def run_test(test_input): + self._add_file(port, '/path/some-dir', 'some-test.wpr', 'wpr content') + return DriverOutput('actual text', 'actual image', 'actual checksum', + audio=None, crash=False, timeout=False, error=False) + + test, port = self._setup_test(run_test) + + try: + self.assertEqual(test.prepare(time_out_ms=100), True) + finally: + actual_stdout, actual_stderr, actual_logs = output_capture.restore_output() + + self.assertEqual(actual_stdout, '') + self.assertEqual(actual_stderr, '') + self.assertEqual(actual_logs, 'Preparing replay for some-test.replay\nPrepared replay for some-test.replay\n') + + def test_prepare_calls_run_single(self): + output_capture = OutputCapture() + output_capture.capture_output() + called = [False] + + def run_single(driver, url, time_out_ms, record): + self.assertTrue(record) + self.assertEqual(url, 'http://some-test/') + called[0] = True + return False + + test, port = self._setup_test() + test.run_single = run_single + + try: + self.assertEqual(test.prepare(time_out_ms=100), False) + finally: + actual_stdout, actual_stderr, actual_logs = output_capture.restore_output() + self.assertTrue(called[0]) + self.assertEqual(test._archive_path, '/path/some-dir/some-test.wpr') + self.assertEqual(test._url, 'http://some-test/') + self.assertEqual(actual_stdout, '') + self.assertEqual(actual_stderr, '') + self.assertEqual(actual_logs, "Preparing replay for some-test.replay\nFailed to prepare a replay for some-test.replay\n") + class TestPerfTestFactory(unittest.TestCase): def test_regular_test(self): - test = PerfTestFactory.create_perf_test('some-dir/some-test', '/path/some-dir/some-test') + test = PerfTestFactory.create_perf_test(None, 'some-dir/some-test', '/path/some-dir/some-test') self.assertEqual(test.__class__, PerfTest) def test_inspector_test(self): - test = PerfTestFactory.create_perf_test('inspector/some-test', '/path/inspector/some-test') + test = PerfTestFactory.create_perf_test(None, 'inspector/some-test', '/path/inspector/some-test') self.assertEqual(test.__class__, ChromiumStylePerfTest) def test_page_loading_test(self): - test = PerfTestFactory.create_perf_test('PageLoad/some-test', '/path/PageLoad/some-test') + test = PerfTestFactory.create_perf_test(None, 'PageLoad/some-test', '/path/PageLoad/some-test') self.assertEqual(test.__class__, PageLoadingPerfTest) diff --git a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner.py b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner.py index b4c29490a..9a3757128 100644 --- a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner.py +++ b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner.py @@ -41,6 +41,7 @@ from webkitpy.common.host import Host from webkitpy.common.net.file_uploader import FileUploader from webkitpy.layout_tests.views import printing from webkitpy.performance_tests.perftest import PerfTestFactory +from webkitpy.performance_tests.perftest import ReplayPerfTest _log = logging.getLogger(__name__) @@ -51,6 +52,7 @@ class PerfTestsRunner(object): _EXIT_CODE_BAD_BUILD = -1 _EXIT_CODE_BAD_JSON = -2 _EXIT_CODE_FAILED_UPLOADING = -3 + _EXIT_CODE_BAD_PREPARATION = -4 def __init__(self, args=None, port=None): self._options, self._args = PerfTestsRunner._parse_args(args) @@ -90,21 +92,27 @@ class PerfTestsRunner(object): optparse.make_option("--pause-before-testing", dest="pause_before_testing", action="store_true", default=False, help="Pause before running the tests to let user attach a performance monitor."), optparse.make_option("--output-json-path", - help="Filename of the JSON file that summaries the results"), + help="Filename of the JSON file that summaries the results."), optparse.make_option("--source-json-path", - help="Path to a JSON file to be merged into the JSON file when --output-json-path is present"), + help="Path to a JSON file to be merged into the JSON file when --output-json-path is present."), optparse.make_option("--test-results-server", - help="Upload the generated JSON file to the specified server when --output-json-path is present"), + help="Upload the generated JSON file to the specified server when --output-json-path is present."), optparse.make_option("--webkit-test-runner", "-2", action="store_true", help="Use WebKitTestRunner rather than DumpRenderTree."), + optparse.make_option("--replay", dest="replay", action="store_true", default=False, + help="Run replay tests."), ] return optparse.OptionParser(option_list=(perf_option_list)).parse_args(args) def _collect_tests(self): """Return the list of tests found.""" + test_extensions = ['.html', '.svg'] + if self._options.replay: + test_extensions.append('.replay') + def _is_test_file(filesystem, dirname, filename): - return filesystem.splitext(filename)[1] in ['.html', '.svg'] + return filesystem.splitext(filename)[1] in test_extensions filesystem = self._host.filesystem @@ -122,7 +130,8 @@ class PerfTestsRunner(object): relative_path = self._port.relative_perf_test_filename(path).replace('\\', '/') if self._port.skips_perf_test(relative_path): continue - tests.append(PerfTestFactory.create_perf_test(relative_path, path)) + test = PerfTestFactory.create_perf_test(self._port, relative_path, path) + tests.append(test) return tests @@ -131,10 +140,13 @@ class PerfTestsRunner(object): _log.error("Build not up to date for %s" % self._port._path_to_driver()) return self._EXIT_CODE_BAD_BUILD - # We wrap any parts of the run that are slow or likely to raise exceptions - # in a try/finally to ensure that we clean up the logging configuration. - unexpected = -1 tests = self._collect_tests() + _log.info("Running %d tests" % len(tests)) + + for test in tests: + if not test.prepare(self._options.time_out_ms): + return self._EXIT_CODE_BAD_PREPARATION + unexpected = self._run_tests_set(sorted(list(tests), key=lambda test: test.test_name()), self._port) options = self._options diff --git a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py index be925c953..8e1eb57ff 100755 --- a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py +++ b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py @@ -120,12 +120,12 @@ max 1120 runner._host.filesystem.maybe_make_directory(runner._base_path, 'inspector') runner._host.filesystem.maybe_make_directory(runner._base_path, 'Bindings') runner._host.filesystem.maybe_make_directory(runner._base_path, 'Parser') - return runner + return runner, test_port def run_test(self, test_name): - runner = self.create_runner() + runner, port = self.create_runner() driver = MainTest.TestDriver() - return runner._run_single_test(ChromiumStylePerfTest(test_name, runner._host.filesystem.join('some-dir', test_name)), driver) + return runner._run_single_test(ChromiumStylePerfTest(port, test_name, runner._host.filesystem.join('some-dir', test_name)), driver) def test_run_passing_test(self): self.assertTrue(self.run_test('pass.html')) @@ -152,19 +152,19 @@ max 1120 path = filesystem.join(runner._base_path, test) dirname = filesystem.dirname(path) if test.startswith('inspector/'): - tests.append(ChromiumStylePerfTest(test, path)) + tests.append(ChromiumStylePerfTest(runner._port, test, path)) else: - tests.append(PerfTest(test, path)) + tests.append(PerfTest(runner._port, test, path)) return tests def test_run_test_set(self): - runner = self.create_runner() + runner, port = self.create_runner() tests = self._tests_for_runner(runner, ['inspector/pass.html', 'inspector/silent.html', 'inspector/failed.html', 'inspector/tonguey.html', 'inspector/timeout.html', 'inspector/crash.html']) output = OutputCapture() output.capture_output() try: - unexpected_result_count = runner._run_tests_set(tests, runner._port) + unexpected_result_count = runner._run_tests_set(tests, port) finally: stdout, stderr, log = output.restore_output() self.assertEqual(unexpected_result_count, len(tests) - 1) @@ -178,11 +178,11 @@ max 1120 def stop(self): TestDriverWithStopCount.stop_count += 1 - runner = self.create_runner(driver_class=TestDriverWithStopCount) + runner, port = self.create_runner(driver_class=TestDriverWithStopCount) tests = self._tests_for_runner(runner, ['inspector/pass.html', 'inspector/silent.html', 'inspector/failed.html', 'inspector/tonguey.html', 'inspector/timeout.html', 'inspector/crash.html']) - unexpected_result_count = runner._run_tests_set(tests, runner._port) + unexpected_result_count = runner._run_tests_set(tests, port) self.assertEqual(TestDriverWithStopCount.stop_count, 6) @@ -193,13 +193,13 @@ max 1120 def start(self): TestDriverWithStartCount.start_count += 1 - runner = self.create_runner(args=["--pause-before-testing"], driver_class=TestDriverWithStartCount) + runner, port = self.create_runner(args=["--pause-before-testing"], driver_class=TestDriverWithStartCount) tests = self._tests_for_runner(runner, ['inspector/pass.html']) output = OutputCapture() output.capture_output() try: - unexpected_result_count = runner._run_tests_set(tests, runner._port) + unexpected_result_count = runner._run_tests_set(tests, port) self.assertEqual(TestDriverWithStartCount.start_count, 1) finally: stdout, stderr, log = output.restore_output() @@ -207,12 +207,12 @@ max 1120 self.assertEqual(log, "Running inspector/pass.html (1 of 1)\nRESULT group_name: test_name= 42 ms\n\n") def test_run_test_set_for_parser_tests(self): - runner = self.create_runner() + runner, port = self.create_runner() tests = self._tests_for_runner(runner, ['Bindings/event-target-wrapper.html', 'Parser/some-parser.html']) output = OutputCapture() output.capture_output() try: - unexpected_result_count = runner._run_tests_set(tests, runner._port) + unexpected_result_count = runner._run_tests_set(tests, port) finally: stdout, stderr, log = output.restore_output() self.assertEqual(unexpected_result_count, 0) @@ -226,9 +226,9 @@ max 1120 '', ''])) def test_run_test_set_with_json_output(self): - runner = self.create_runner(args=['--output-json-path=/mock-checkout/output.json']) - runner._host.filesystem.files[runner._base_path + '/inspector/pass.html'] = True - runner._host.filesystem.files[runner._base_path + '/Bindings/event-target-wrapper.html'] = True + runner, port = self.create_runner(args=['--output-json-path=/mock-checkout/output.json']) + port.host.filesystem.files[runner._base_path + '/inspector/pass.html'] = True + port.host.filesystem.files[runner._base_path + '/Bindings/event-target-wrapper.html'] = True runner._timestamp = 123456789 output_capture = OutputCapture() output_capture.capture_output() @@ -238,7 +238,8 @@ max 1120 stdout, stderr, logs = output_capture.restore_output() self.assertEqual(logs, - '\n'.join(['Running Bindings/event-target-wrapper.html (1 of 2)', + '\n'.join(['Running 2 tests', + 'Running Bindings/event-target-wrapper.html (1 of 2)', 'RESULT Bindings: event-target-wrapper= 1489.05 ms', 'median= 1487.0 ms, stdev= 14.46 ms, min= 1471.0 ms, max= 1510.0 ms', '', @@ -246,17 +247,17 @@ max 1120 'RESULT group_name: test_name= 42 ms', '', ''])) - self.assertEqual(json.loads(runner._host.filesystem.files['/mock-checkout/output.json']), { + self.assertEqual(json.loads(port.host.filesystem.files['/mock-checkout/output.json']), { "timestamp": 123456789, "results": {"Bindings/event-target-wrapper": {"max": 1510, "avg": 1489.05, "median": 1487, "min": 1471, "stdev": 14.46, "unit": "ms"}, "inspector/pass.html:group_name:test_name": 42}, "webkit-revision": 5678}) def test_run_test_set_with_json_source(self): - runner = self.create_runner(args=['--output-json-path=/mock-checkout/output.json', '--source-json-path=/mock-checkout/source.json']) - runner._host.filesystem.files['/mock-checkout/source.json'] = '{"key": "value"}' - runner._host.filesystem.files[runner._base_path + '/inspector/pass.html'] = True - runner._host.filesystem.files[runner._base_path + '/Bindings/event-target-wrapper.html'] = True + runner, port = self.create_runner(args=['--output-json-path=/mock-checkout/output.json', '--source-json-path=/mock-checkout/source.json']) + port.host.filesystem.files['/mock-checkout/source.json'] = '{"key": "value"}' + port.host.filesystem.files[runner._base_path + '/inspector/pass.html'] = True + port.host.filesystem.files[runner._base_path + '/Bindings/event-target-wrapper.html'] = True runner._timestamp = 123456789 output_capture = OutputCapture() output_capture.capture_output() @@ -265,7 +266,8 @@ max 1120 finally: stdout, stderr, logs = output_capture.restore_output() - self.assertEqual(logs, '\n'.join(['Running Bindings/event-target-wrapper.html (1 of 2)', + self.assertEqual(logs, '\n'.join(['Running 2 tests', + 'Running Bindings/event-target-wrapper.html (1 of 2)', 'RESULT Bindings: event-target-wrapper= 1489.05 ms', 'median= 1487.0 ms, stdev= 14.46 ms, min= 1471.0 ms, max= 1510.0 ms', '', @@ -273,7 +275,7 @@ max 1120 'RESULT group_name: test_name= 42 ms', '', ''])) - self.assertEqual(json.loads(runner._host.filesystem.files['/mock-checkout/output.json']), { + self.assertEqual(json.loads(port.host.filesystem.files['/mock-checkout/output.json']), { "timestamp": 123456789, "results": {"Bindings/event-target-wrapper": {"max": 1510, "avg": 1489.05, "median": 1487, "min": 1471, "stdev": 14.46, "unit": "ms"}, "inspector/pass.html:group_name:test_name": 42}, @@ -281,16 +283,16 @@ max 1120 "key": "value"}) def test_run_test_set_with_multiple_repositories(self): - runner = self.create_runner(args=['--output-json-path=/mock-checkout/output.json']) - runner._host.filesystem.files[runner._base_path + '/inspector/pass.html'] = True + runner, port = self.create_runner(args=['--output-json-path=/mock-checkout/output.json']) + port.host.filesystem.files[runner._base_path + '/inspector/pass.html'] = True runner._timestamp = 123456789 - runner._port.repository_paths = lambda: [('webkit', '/mock-checkout'), ('some', '/mock-checkout/some')] + port.repository_paths = lambda: [('webkit', '/mock-checkout'), ('some', '/mock-checkout/some')] self.assertEqual(runner.run(), 0) - self.assertEqual(json.loads(runner._host.filesystem.files['/mock-checkout/output.json']), { + self.assertEqual(json.loads(port.host.filesystem.files['/mock-checkout/output.json']), { "timestamp": 123456789, "results": {"inspector/pass.html:group_name:test_name": 42.0}, "webkit-revision": 5678, "some-revision": 5678}) def test_run_with_upload_json(self): - runner = self.create_runner(args=['--output-json-path=/mock-checkout/output.json', + runner, port = self.create_runner(args=['--output-json-path=/mock-checkout/output.json', '--test-results-server', 'some.host', '--platform', 'platform1', '--builder-name', 'builder1', '--build-number', '123']) upload_json_is_called = [False] upload_json_returns_true = True @@ -302,26 +304,26 @@ max 1120 return upload_json_returns_true runner._upload_json = mock_upload_json - runner._host.filesystem.files['/mock-checkout/source.json'] = '{"key": "value"}' - runner._host.filesystem.files[runner._base_path + '/inspector/pass.html'] = True - runner._host.filesystem.files[runner._base_path + '/Bindings/event-target-wrapper.html'] = True + port.host.filesystem.files['/mock-checkout/source.json'] = '{"key": "value"}' + port.host.filesystem.files[runner._base_path + '/inspector/pass.html'] = True + port.host.filesystem.files[runner._base_path + '/Bindings/event-target-wrapper.html'] = True runner._timestamp = 123456789 self.assertEqual(runner.run(), 0) self.assertEqual(upload_json_is_called[0], True) - generated_json = json.loads(runner._host.filesystem.files['/mock-checkout/output.json']) + generated_json = json.loads(port.host.filesystem.files['/mock-checkout/output.json']) self.assertEqual(generated_json['platform'], 'platform1') self.assertEqual(generated_json['builder-name'], 'builder1') self.assertEqual(generated_json['build-number'], 123) upload_json_returns_true = False - runner = self.create_runner(args=['--output-json-path=/mock-checkout/output.json', + runner, port = self.create_runner(args=['--output-json-path=/mock-checkout/output.json', '--test-results-server', 'some.host', '--platform', 'platform1', '--builder-name', 'builder1', '--build-number', '123']) runner._upload_json = mock_upload_json self.assertEqual(runner.run(), -3) def test_upload_json(self): - runner = self.create_runner() - runner._host.filesystem.files['/mock-checkout/some.json'] = 'some content' + runner, port = self.create_runner() + port.host.filesystem.files['/mock-checkout/some.json'] = 'some content' called = [] upload_single_text_file_throws = False @@ -334,7 +336,7 @@ max 1120 called.append('FileUploader') def upload_single_text_file(mock, filesystem, content_type, filename): - self.assertEqual(filesystem, runner._host.filesystem) + self.assertEqual(filesystem, port.host.filesystem) self.assertEqual(content_type, 'application/json') self.assertEqual(filename, 'some.json') called.append('upload_single_text_file') @@ -358,59 +360,64 @@ max 1120 runner._upload_json('some.host', 'some.json', MockFileUploader) self.assertEqual(called, ['FileUploader', 'upload_single_text_file']) + def _add_file(self, runner, dirname, filename, content=True): + dirname = runner._host.filesystem.join(runner._base_path, dirname) if dirname else runner._base_path + runner._host.filesystem.maybe_make_directory(dirname) + runner._host.filesystem.files[runner._host.filesystem.join(dirname, filename)] = content + def test_collect_tests(self): - runner = self.create_runner() - filename = runner._host.filesystem.join(runner._base_path, 'inspector', 'a_file.html') - runner._host.filesystem.files[filename] = 'a content' + runner, port = self.create_runner() + self._add_file(runner, 'inspector', 'a_file.html', 'a content') tests = runner._collect_tests() self.assertEqual(len(tests), 1) def _collect_tests_and_sort_test_name(self, runner): return sorted([test.test_name() for test in runner._collect_tests()]) - def test_collect_tests(self): - runner = self.create_runner(args=['PerformanceTests/test1.html', 'test2.html']) + def test_collect_tests_with_multile_files(self): + runner, port = self.create_runner(args=['PerformanceTests/test1.html', 'test2.html']) def add_file(filename): - runner._host.filesystem.files[runner._host.filesystem.join(runner._base_path, filename)] = 'some content' + port.host.filesystem.files[runner._host.filesystem.join(runner._base_path, filename)] = 'some content' add_file('test1.html') add_file('test2.html') add_file('test3.html') - runner._host.filesystem.chdir(runner._port.perf_tests_dir()[:runner._port.perf_tests_dir().rfind(runner._host.filesystem.sep)]) + port.host.filesystem.chdir(runner._port.perf_tests_dir()[:runner._port.perf_tests_dir().rfind(runner._host.filesystem.sep)]) self.assertEqual(self._collect_tests_and_sort_test_name(runner), ['test1.html', 'test2.html']) def test_collect_tests_with_skipped_list(self): - runner = self.create_runner() - - def add_file(dirname, filename, content=True): - dirname = runner._host.filesystem.join(runner._base_path, dirname) if dirname else runner._base_path - runner._host.filesystem.maybe_make_directory(dirname) - runner._host.filesystem.files[runner._host.filesystem.join(dirname, filename)] = content - - add_file('inspector', 'test1.html') - add_file('inspector', 'unsupported_test1.html') - add_file('inspector', 'test2.html') - add_file('inspector/resources', 'resource_file.html') - add_file('unsupported', 'unsupported_test2.html') - runner._port.skipped_perf_tests = lambda: ['inspector/unsupported_test1.html', 'unsupported'] + runner, port = self.create_runner() + + self._add_file(runner, 'inspector', 'test1.html') + self._add_file(runner, 'inspector', 'unsupported_test1.html') + self._add_file(runner, 'inspector', 'test2.html') + self._add_file(runner, 'inspector/resources', 'resource_file.html') + self._add_file(runner, 'unsupported', 'unsupported_test2.html') + port.skipped_perf_tests = lambda: ['inspector/unsupported_test1.html', 'unsupported'] self.assertEqual(self._collect_tests_and_sort_test_name(runner), ['inspector/test1.html', 'inspector/test2.html']) def test_collect_tests_with_page_load_svg(self): - runner = self.create_runner() + runner, port = self.create_runner() + self._add_file(runner, 'PageLoad', 'some-svg-test.svg') + tests = runner._collect_tests() + self.assertEqual(len(tests), 1) + self.assertEqual(tests[0].__class__.__name__, 'PageLoadingPerfTest') - def add_file(dirname, filename, content=True): - dirname = runner._host.filesystem.join(runner._base_path, dirname) if dirname else runner._base_path - runner._host.filesystem.maybe_make_directory(dirname) - runner._host.filesystem.files[runner._host.filesystem.join(dirname, filename)] = content + def test_collect_tests_should_ignore_replay_tests_by_default(self): + runner, port = self.create_runner() + self._add_file(runner, 'Replay', 'www.webkit.org.replay') + self.assertEqual(runner._collect_tests(), []) - add_file('PageLoad', 'some-svg-test.svg') + def test_collect_tests_with_replay_tests(self): + runner, port = self.create_runner(args=['--replay']) + self._add_file(runner, 'Replay', 'www.webkit.org.replay') tests = runner._collect_tests() self.assertEqual(len(tests), 1) - self.assertEqual(tests[0].__class__.__name__, 'PageLoadingPerfTest') + self.assertEqual(tests[0].__class__.__name__, 'ReplayPerfTest') def test_parse_args(self): - runner = self.create_runner() + runner, port = self.create_runner() options, args = PerfTestsRunner._parse_args([ '--build-directory=folder42', '--platform=platform42', diff --git a/Tools/Scripts/webkitpy/style/checkers/png.py b/Tools/Scripts/webkitpy/style/checkers/png.py index e0b79e27e..30b7a1439 100644 --- a/Tools/Scripts/webkitpy/style/checkers/png.py +++ b/Tools/Scripts/webkitpy/style/checkers/png.py @@ -27,10 +27,10 @@ import os import re +from webkitpy.common import read_checksum_from_png from webkitpy.common.system.systemhost import SystemHost from webkitpy.common.checkout.scm.detection import SCMDetector - class PNGChecker(object): """Check svn:mime-type for checking style""" @@ -48,6 +48,11 @@ class PNGChecker(object): config_file_path = "" detection = self._detector.display_name() + if self._fs.exists(self._file_path) and self._file_path.endswith("-expected.png"): + with self._fs.open_binary_file_for_reading(self._file_path) as filehandle: + if not read_checksum_from_png.read_checksum(filehandle): + self._handle_style_error(0, 'image/png', 5, "Image lacks a checksum. Generate pngs using run-webkit-tests to ensure they have a checksum.") + if detection == "git": config_file_path = self._config_file_path() there_is_enable_line = False diff --git a/Tools/Scripts/webkitpy/style/checkers/png_unittest.py b/Tools/Scripts/webkitpy/style/checkers/png_unittest.py index ae46641a2..764c28591 100644 --- a/Tools/Scripts/webkitpy/style/checkers/png_unittest.py +++ b/Tools/Scripts/webkitpy/style/checkers/png_unittest.py @@ -113,6 +113,22 @@ class PNGCheckerTest(unittest.TestCase): checker.check() self.assertEquals(len(errors), 1) + file_path = "foo.png" + fs.write_binary_file(file_path, "Dummy binary data") + scm = MockSCMDetector('git') + errors = [] + checker = PNGChecker(file_path, mock_handle_style_error, scm, MockSystemHost(os_name='linux', filesystem=fs)) + checker.check() + self.assertEquals(len(errors), 1) + + file_path = "foo-expected.png" + fs.write_binary_file(file_path, "Dummy binary data") + scm = MockSCMDetector('git') + errors = [] + checker = PNGChecker(file_path, mock_handle_style_error, scm, MockSystemHost(os_name='linux', filesystem=fs)) + checker.check() + self.assertEquals(len(errors), 2) + self.assertEquals(errors[0], (0, 'image/png', 5, 'Image lacks a checksum. Generate pngs using run-webkit-tests to ensure they have a checksum.')) if __name__ == '__main__': unittest.main() diff --git a/Tools/Scripts/webkitpy/thirdparty/__init__.py b/Tools/Scripts/webkitpy/thirdparty/__init__.py index 0df0cf7b6..26245bacc 100644 --- a/Tools/Scripts/webkitpy/thirdparty/__init__.py +++ b/Tools/Scripts/webkitpy/thirdparty/__init__.py @@ -82,6 +82,8 @@ class AutoinstallImportHook(object): self._install_irc() elif '.buildbot' in fullname: self._install_buildbot() + elif '.webpagereplay' in fullname: + self._install_webpagereplay() def _install_mechanize(self): self._install("http://pypi.python.org/packages/source/m/mechanize/mechanize-0.2.5.tar.gz", @@ -126,6 +128,15 @@ class AutoinstallImportHook(object): installer.install(url="http://downloads.sourceforge.net/project/python-irclib/python-irclib/0.4.8/python-irclib-0.4.8.zip", url_subpath="ircbot.py") + def _install_webpagereplay(self): + if not self._fs.exists(self._fs.join(_AUTOINSTALLED_DIR, "webpagereplay")): + self._install("http://web-page-replay.googlecode.com/files/webpagereplay-1.1.1.tar.gz", "webpagereplay-1.1.1") + self._fs.move(self._fs.join(_AUTOINSTALLED_DIR, "webpagereplay-1.1.1"), self._fs.join(_AUTOINSTALLED_DIR, "webpagereplay")) + + init_path = self._fs.join(_AUTOINSTALLED_DIR, "webpagereplay", "__init__.py") + if not self._fs.exists(init_path): + self._fs.write_text_file(init_path, "") + def _install(self, url, url_subpath): installer = AutoInstaller(target_dir=_AUTOINSTALLED_DIR) installer.install(url=url, url_subpath=url_subpath) diff --git a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py index 30409783f..5a184f19e 100644 --- a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py +++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py @@ -26,6 +26,8 @@ # (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 json +import logging import optparse import os.path import re @@ -51,16 +53,19 @@ from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand _baseline_suffix_list = ['png', 'wav', 'txt'] +_log = logging.getLogger(__name__) + # FIXME: Should TestResultWriter know how to compute this string? def _baseline_name(fs, test_name, suffix): return fs.splitext(test_name)[0] + TestResultWriter.FILENAME_SUFFIX_EXPECTED + "." + suffix class AbstractRebaseliningCommand(AbstractDeclarativeCommand): - def __init__(self): - options = [ + def __init__(self, options=None): + options = options or [] + options.extend([ optparse.make_option('--suffixes', default=','.join(_baseline_suffix_list), action='store', - help='file types to rebaseline')] + help='file types to rebaseline')]) AbstractDeclarativeCommand.__init__(self, options=options) self._baseline_suffix_list = _baseline_suffix_list @@ -70,6 +75,14 @@ class RebaselineTest(AbstractRebaseliningCommand): help_text = "Rebaseline a single test from a buildbot. (Currently works only with build.chromium.org buildbots.)" argument_names = "BUILDER_NAME TEST_NAME [PLATFORMS_TO_MOVE_EXISTING_BASELINES_TO]" + def __init__(self): + options = [ + optparse.make_option("--print-scm-changes", action="store_true", help="Print modifcations to the scm (as a json dict) rather than actually modifying the scm"), + ] + AbstractRebaseliningCommand.__init__(self, options=options) + self._print_scm_changes = False + self._scm_changes = {} + def _results_url(self, builder_name): # FIXME: Generalize this command to work with non-build.chromium.org builders. builder = self._tool.chromium_buildbot().builder_with_name(builder_name) @@ -89,12 +102,12 @@ class RebaselineTest(AbstractRebaseliningCommand): port = self._tool.port_factory.get(platform) old_baseline = port.expected_filename(test_name, "." + suffix) if not self._tool.filesystem.exists(old_baseline): - print("No existing baseline for %s." % test_name) + _log.info("No existing baseline for %s." % test_name) continue new_baseline = self._tool.filesystem.join(port.baseline_path(), self._file_name_for_expected_result(test_name, suffix)) if self._tool.filesystem.exists(new_baseline): - print("Existing baseline at %s, not copying over it." % new_baseline) + _log.info("Existing baseline at %s, not copying over it." % new_baseline) continue old_baselines.append(old_baseline) @@ -104,11 +117,11 @@ class RebaselineTest(AbstractRebaseliningCommand): old_baseline = old_baselines[i] new_baseline = new_baselines[i] - print("Copying baseline from %s to %s." % (old_baseline, new_baseline)) + _log.info("Copying baseline from %s to %s." % (old_baseline, new_baseline)) self._tool.filesystem.maybe_make_directory(self._tool.filesystem.dirname(new_baseline)) self._tool.filesystem.copyfile(old_baseline, new_baseline) if not self._tool.scm().exists(new_baseline): - self._tool.scm().add(new_baseline) + self._add_to_scm(new_baseline) def _save_baseline(self, data, target_baseline): if not data: @@ -117,7 +130,13 @@ class RebaselineTest(AbstractRebaseliningCommand): filesystem.maybe_make_directory(filesystem.dirname(target_baseline)) filesystem.write_binary_file(target_baseline, data) if not self._tool.scm().exists(target_baseline): - self._tool.scm().add(target_baseline) + self._add_to_scm(target_baseline) + + def _add_to_scm(self, path): + if self._print_scm_changes: + self._scm_changes['add'].append(path) + else: + self._tool.scm().add(path) def _update_expectations_file(self, builder_name, test_name): port = self._tool.port_factory.get_from_builder_name(builder_name) @@ -148,7 +167,7 @@ class RebaselineTest(AbstractRebaseliningCommand): if platforms_to_move_existing_baselines_to: self._copy_existing_baseline(platforms_to_move_existing_baselines_to, test_name, suffix) - print "Retrieving %s." % source_baseline + _log.info("Retrieving %s." % source_baseline) self._save_baseline(self._tool.web.get_binary(source_baseline, convert_404_to_None=True), target_baseline) def _rebaseline_test_and_update_expectations(self, builder_name, test_name, platforms_to_move_existing_baselines_to): @@ -158,12 +177,16 @@ class RebaselineTest(AbstractRebaseliningCommand): def execute(self, options, args, tool): self._baseline_suffix_list = options.suffixes.split(',') + self._print_scm_changes = options.print_scm_changes + self._scm_changes = {'add': [], 'delete': []} if len(args) > 2: platforms_to_move_existing_baselines_to = args[2:] else: platforms_to_move_existing_baselines_to = None self._rebaseline_test_and_update_expectations(args[0], args[1], platforms_to_move_existing_baselines_to) + if self._print_scm_changes: + print json.dumps(self._scm_changes) class OptimizeBaselines(AbstractRebaseliningCommand): @@ -257,10 +280,10 @@ class RebaselineExpectations(AbstractDeclarativeCommand): builder_name = builders.builder_name_for_port_name(port_name) if not builder_name: return - print "Retrieving results for %s from %s." % (port_name, builder_name) + _log.info("Retrieving results for %s from %s." % (port_name, builder_name)) for test_name in self._tests_to_rebaseline(self._tool.port_factory.get(port_name)): self._touched_test_names.add(test_name) - print " %s" % test_name + _log.info(" %s" % test_name) # FIXME: need to extract the correct list of suffixes here. self._run_webkit_patch(['rebaseline-test', builder_name, test_name]) @@ -273,7 +296,7 @@ class RebaselineExpectations(AbstractDeclarativeCommand): if not options.optimize: return for test_name in self._touched_test_names: - print "Optimizing baselines for %s." % test_name + _log.info("Optimizing baselines for %s." % test_name) self._run_webkit_patch(['optimize-baselines', test_name]) @@ -285,7 +308,7 @@ class Rebaseline(AbstractDeclarativeCommand): def _builder_to_pull_from(self): 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))) + _log.info("%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) # FIXME: prompt_with_list should really take a set of objects and a set of names and then return the object. @@ -315,7 +338,7 @@ class Rebaseline(AbstractDeclarativeCommand): results_url = self._results_url_for_test(build, test) # Port operates with absolute paths. expected_file = port.expected_filename(test, '.txt') - print test + _log.info(test) self._replace_expectation_with_remote_result(expected_file, results_url) # FIXME: We should handle new results too. diff --git a/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py b/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py index 46d9ed47b..f8d9dfc1b 100644 --- a/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py +++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py @@ -55,11 +55,11 @@ BUGA DEBUG : fast/css/large-list-of-rules-crash.html = TEXT tool.filesystem.write_text_file(os.path.join(lion_port.layout_tests_dir(), "fast/css/large-list-of-rules-crash.html"), "Dummy test contents") tool.filesystem.write_text_file(os.path.join(lion_port.layout_tests_dir(), "userscripts/another-test.html"), "Dummy test contents") - expected_stdout = """Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.png. + expected_logs = """Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.png. Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.wav. Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.txt. """ - OutputCapture().assert_outputs(self, command._rebaseline_test_and_update_expectations, ["Webkit Mac10.7", "userscripts/another-test.html", None], expected_stdout=expected_stdout) + OutputCapture().assert_outputs(self, command._rebaseline_test_and_update_expectations, ["Webkit Mac10.7", "userscripts/another-test.html", None], expected_logs=expected_logs) new_expectations = tool.filesystem.read_text_file(lion_port.path_to_test_expectations_file()) self.assertEqual(new_expectations, """BUGB MAC LINUX XP DEBUG : fast/dom/Window/window-postmessage-clone-really-deep-array.html = PASS @@ -75,11 +75,11 @@ BUGA DEBUG : fast/css/large-list-of-rules-crash.html = TEXT tool.filesystem.write_text_file(lion_port.path_to_test_expectations_file(), "BUGX MAC : userscripts/another-test.html = IMAGE\nBUGZ LINUX : userscripts/another-test.html = IMAGE\n") tool.filesystem.write_text_file(os.path.join(lion_port.layout_tests_dir(), "userscripts/another-test.html"), "Dummy test contents") - expected_stdout = """Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.png. + expected_logs = """Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.png. Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.wav. Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.txt. """ - OutputCapture().assert_outputs(self, command._rebaseline_test_and_update_expectations, ["Webkit Mac10.7", "userscripts/another-test.html", None], expected_stdout=expected_stdout) + OutputCapture().assert_outputs(self, command._rebaseline_test_and_update_expectations, ["Webkit Mac10.7", "userscripts/another-test.html", None], expected_logs=expected_logs) new_expectations = tool.filesystem.read_text_file(lion_port.path_to_test_expectations_file()) self.assertEqual(new_expectations, "BUGX LEOPARD SNOWLEOPARD : userscripts/another-test.html = IMAGE\nBUGZ LINUX : userscripts/another-test.html = IMAGE\n") @@ -87,8 +87,18 @@ Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-resu def test_rebaseline_test(self): command = RebaselineTest() command.bind_to_tool(MockTool()) - expected_stdout = "Retrieving http://example.com/f/builders/Webkit Linux/results/layout-test-results/userscripts/another-test-actual.txt.\n" - OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Linux", "userscripts/another-test.html", None, "txt"], expected_stdout=expected_stdout) + expected_logs = "Retrieving http://example.com/f/builders/Webkit Linux/results/layout-test-results/userscripts/another-test-actual.txt.\n" + OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Linux", "userscripts/another-test.html", None, "txt"], expected_logs=expected_logs) + + def test_rebaseline_test_and_print_scm_changes(self): + command = RebaselineTest() + command.bind_to_tool(MockTool()) + expected_logs = "Retrieving http://example.com/f/builders/Webkit Linux/results/layout-test-results/userscripts/another-test-actual.txt.\n" + command._print_scm_changes = True + command._scm_changes = {'add': [], 'delete': []} + command._tool._scm.exists = lambda x: False + OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Linux", "userscripts/another-test.html", None, "txt"], expected_logs=expected_logs) + self.assertEquals(command._scm_changes, {'add': ['/mock-checkout/LayoutTests/platform/chromium-linux/userscripts/another-test-expected.txt'], 'delete': []}) def test_rebaseline_and_copy_test(self): command = RebaselineTest() @@ -98,20 +108,20 @@ Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-resu lion_port = tool.port_factory.get_from_builder_name("Webkit Mac10.7") tool.filesystem.write_text_file(os.path.join(lion_port.layout_tests_dir(), "userscripts/another-test-expected.txt"), "Dummy expected result") - expected_stdout = """Copying baseline from /mock-checkout/LayoutTests/userscripts/another-test-expected.txt to /mock-checkout/LayoutTests/platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt. + expected_logs = """Copying baseline from /mock-checkout/LayoutTests/userscripts/another-test-expected.txt to /mock-checkout/LayoutTests/platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt. Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.txt. """ - OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt"], expected_stdout=expected_stdout) + OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt"], expected_logs=expected_logs) def test_rebaseline_and_copy_test_no_existing_result(self): command = RebaselineTest() tool = MockTool() command.bind_to_tool(tool) - expected_stdout = """No existing baseline for userscripts/another-test.html. + expected_logs = """No existing baseline for userscripts/another-test.html. Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.txt. """ - OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt"], expected_stdout=expected_stdout) + OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt"], expected_logs=expected_logs) def test_rebaseline_and_copy_test_with_lion_result(self): command = RebaselineTest() @@ -121,11 +131,11 @@ Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-resu lion_port = tool.port_factory.get_from_builder_name("Webkit Mac10.7") tool.filesystem.write_text_file(os.path.join(lion_port.baseline_path(), "userscripts/another-test-expected.txt"), "Dummy expected result") - expected_stdout = """Copying baseline from /mock-checkout/LayoutTests/platform/chromium-mac/userscripts/another-test-expected.txt to /mock-checkout/LayoutTests/platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt. + expected_logs = """Copying baseline from /mock-checkout/LayoutTests/platform/chromium-mac/userscripts/another-test-expected.txt to /mock-checkout/LayoutTests/platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt. Copying baseline from /mock-checkout/LayoutTests/platform/chromium-mac/userscripts/another-test-expected.txt to /mock-checkout/LayoutTests/platform/chromium-mac-leopard/userscripts/another-test-expected.txt. Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.txt. """ - OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard", "chromium-mac-leopard"], "txt"], expected_stdout=expected_stdout) + OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard", "chromium-mac-leopard"], "txt"], expected_logs=expected_logs) def test_rebaseline_and_copy_no_overwrite_test(self): command = RebaselineTest() @@ -138,10 +148,10 @@ Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-resu snowleopard_port = tool.port_factory.get_from_builder_name("Webkit Mac10.6") tool.filesystem.write_text_file(os.path.join(snowleopard_port.baseline_path(), "userscripts/another-test-expected.txt"), "Dummy expected result") - expected_stdout = """Existing baseline at /mock-checkout/LayoutTests/platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt, not copying over it. + expected_logs = """Existing baseline at /mock-checkout/LayoutTests/platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt, not copying over it. Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-results/userscripts/another-test-actual.txt. """ - OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt"], expected_stdout=expected_stdout) + OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt"], expected_logs=expected_logs) def test_rebaseline_expectations(self): command = RebaselineExpectations() @@ -155,7 +165,7 @@ Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-resu # Don't enable logging until after we create the mock expectation files as some Port.__init__'s run subcommands. tool.executive = MockExecutive(should_log=True) - expected_stdout = """Retrieving results for chromium-linux-x86 from Webkit Linux 32. + expected_logs = """Retrieving results for chromium-linux-x86 from Webkit Linux 32. userscripts/another-test.html userscripts/images.svg Retrieving results for chromium-linux-x86_64 from Webkit Linux. @@ -200,9 +210,9 @@ MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Win', 'userscripts/images. """ command._tests_to_rebaseline = lambda port: ['userscripts/another-test.html', 'userscripts/images.svg'] - OutputCapture().assert_outputs(self, command.execute, [MockOptions(optimize=False), [], tool], expected_stdout=expected_stdout, expected_stderr=expected_stderr) + OutputCapture().assert_outputs(self, command.execute, [MockOptions(optimize=False), [], tool], expected_logs=expected_logs, expected_stderr=expected_stderr) - expected_stdout_with_optimize = expected_stdout + ( + expected_logs_with_optimize = expected_logs + ( "Optimizing baselines for userscripts/another-test.html.\n" "Optimizing baselines for userscripts/images.svg.\n") expected_stderr_with_optimize = expected_stderr + ( @@ -210,4 +220,4 @@ MOCK run_command: ['echo', 'rebaseline-test', 'Webkit Win', 'userscripts/images. "MOCK run_command: ['echo', 'optimize-baselines', 'userscripts/images.svg'], cwd=/mock-checkout\n") command._tests_to_rebaseline = lambda port: ['userscripts/another-test.html', 'userscripts/images.svg'] - OutputCapture().assert_outputs(self, command.execute, [MockOptions(optimize=True), [], tool], expected_stdout=expected_stdout_with_optimize, expected_stderr=expected_stderr_with_optimize) + OutputCapture().assert_outputs(self, command.execute, [MockOptions(optimize=True), [], tool], expected_logs=expected_logs_with_optimize, expected_stderr=expected_stderr_with_optimize) diff --git a/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py b/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py index 09660f609..369070982 100644 --- a/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py +++ b/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py @@ -23,6 +23,8 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import BaseHTTPServer +import logging +import json import os from webkitpy.common.memoized import memoized @@ -33,6 +35,9 @@ from webkitpy.layout_tests.models.test_configuration import TestConfigurationCon from webkitpy.layout_tests.port import builders +_log = logging.getLogger(__name__) + + class BuildCoverageExtrapolator(object): def __init__(self, test_configuration_converter): self._test_configuration_converter = test_configuration_converter @@ -171,15 +176,43 @@ class GardeningHTTPRequestHandler(ReflectionHandler): builders_to_fallback_paths[builder] = fallback_path return builders_to_fallback_paths.keys() - def rebaselineall(self): - # FIXME: Optimize this to run in parallel, cache zips, etc. - test_list = self._read_entity_body_as_json() + def _rebaseline_commands(self, test_list): + path_to_webkit_patch = self.server.tool.path() + cwd = self.server.tool.scm().checkout_root + commands = [] + for test in test_list: + for builder in self._builders_to_fetch_from(test_list[test]): + suffixes = ','.join(test_list[test][builder]) + cmd_line = [path_to_webkit_patch, 'rebaseline-test', '--print-scm-changes', '--suffixes', suffixes, builder, test] + commands.append(tuple([cmd_line, cwd])) + return commands + + def _files_to_add(self, command_results): + files_to_add = set() + for output in [result[1] for result in command_results]: + try: + files_to_add.update(json.loads(output)['add']) + except ValueError, e: + _log.warning('"%s" is not a JSON object, ignoring' % output) + + return list(files_to_add) + + def _optimize_baselines(self, test_list): + # We don't run this in parallel because modifying the SCM in parallel is unreliable. for test in test_list: all_suffixes = set() - builders = self._builders_to_fetch_from(test_list[test]) - for builder in builders: - suffixes = test_list[test][builder] - all_suffixes.update(suffixes) - self._run_webkit_patch(['rebaseline-test', '--suffixes', ','.join(suffixes), builder, test]) + for builder in self._builders_to_fetch_from(test_list[test]): + all_suffixes.update(test_list[test][builder]) self._run_webkit_patch(['optimize-baselines', '--suffixes', ','.join(all_suffixes), test]) + + def rebaselineall(self): + test_list = self._read_entity_body_as_json() + + commands = self._rebaseline_commands(test_list) + command_results = self.server.tool.executive.run_in_parallel(commands) + + files_to_add = self._files_to_add(command_results) + self.server.tool.scm().add_list(list(files_to_add)) + + self._optimize_baselines(test_list) self._serve_text('success') diff --git a/Tools/Scripts/webkitpy/tool/servers/gardeningserver_unittest.py b/Tools/Scripts/webkitpy/tool/servers/gardeningserver_unittest.py index e1798f65e..dcecb500c 100644 --- a/Tools/Scripts/webkitpy/tool/servers/gardeningserver_unittest.py +++ b/Tools/Scripts/webkitpy/tool/servers/gardeningserver_unittest.py @@ -27,6 +27,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json +import sys import unittest from webkitpy.common.system.outputcapture import OutputCapture @@ -170,8 +171,8 @@ class GardeningExpectationsUpdaterTest(unittest.TestCase): class GardeningServerTest(unittest.TestCase): - def _post_to_path(self, path, body=None, expected_stderr=None, expected_stdout=None): - handler = TestGardeningHTTPRequestHandler(MockServer()) + def _post_to_path(self, path, body=None, expected_stderr=None, expected_stdout=None, server=None): + handler = TestGardeningHTTPRequestHandler(server or MockServer()) handler.path = path handler.body = body OutputCapture().assert_outputs(self, handler.do_POST, expected_stderr=expected_stderr, expected_stdout=expected_stdout) @@ -186,9 +187,18 @@ class GardeningServerTest(unittest.TestCase): "MOCK builder": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])}, "MOCK builder (Debug)": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier", "debug"])}, } - expected_stderr = "MOCK run_command: ['echo', 'rebaseline-test', '--suffixes', u'%s', u'%s', u'user-scripts/another-test.html'], cwd=/mock-checkout\nMOCK run_command: ['echo', 'optimize-baselines', '--suffixes', u'%s', u'user-scripts/another-test.html'], cwd=/mock-checkout\n" + expected_stderr = "MOCK run_command: ['echo', 'rebaseline-test', '--print-scm-changes', '--suffixes', u'%s', u'%s', u'user-scripts/another-test.html'], cwd=/mock-checkout\nMOCK run_command: ['echo', 'optimize-baselines', '--suffixes', u'%s', u'user-scripts/another-test.html'], cwd=/mock-checkout\n" expected_stdout = "== Begin Response ==\nsuccess\n== End Response ==\n" - self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder": ["txt","png"]}}', expected_stderr=expected_stderr % ('txt,png', 'MOCK builder', 'txt,png'), expected_stdout=expected_stdout) + server = MockServer() + + self.output = ['{"add": [], "delete": []}', ''] + + def run_command(args, cwd=None, **kwargs): + print >> sys.stderr, "MOCK run_command: %s, cwd=%s" % (args, cwd) + return self.output.pop(0) + + server.tool.executive.run_command = run_command + self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder": ["txt","png"]}}', expected_stderr=expected_stderr % ('txt,png', 'MOCK builder', 'txt,png'), expected_stdout=expected_stdout, server=server) self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder (Debug)": ["txt","png"]}}', expected_stderr=expected_stderr % ('txt,png', 'MOCK builder (Debug)', 'txt,png'), expected_stdout=expected_stdout) diff --git a/Tools/TestWebKitAPI/Configurations/Base.xcconfig b/Tools/TestWebKitAPI/Configurations/Base.xcconfig index c321d194a..5f5094f34 100644 --- a/Tools/TestWebKitAPI/Configurations/Base.xcconfig +++ b/Tools/TestWebKitAPI/Configurations/Base.xcconfig @@ -23,6 +23,7 @@ #include "CompilerVersion.xcconfig" +CLANG_WARN_CXX0X_EXTENSIONS = NO; HEADER_SEARCH_PATHS = ${BUILT_PRODUCTS_DIR}/usr/local/include $(WEBCORE_PRIVATE_HEADERS_DIR)/ForwardingHeaders $(WEBCORE_PRIVATE_HEADERS_DIR)/icu; FRAMEWORK_SEARCH_PATHS = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks; GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) ENABLE_DASHBOARD_SUPPORT WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST GTEST_HAS_TR1_TUPLE=0; diff --git a/Tools/WebKitTestRunner/Configurations/Base.xcconfig b/Tools/WebKitTestRunner/Configurations/Base.xcconfig index ab87999e9..4015b3e31 100644 --- a/Tools/WebKitTestRunner/Configurations/Base.xcconfig +++ b/Tools/WebKitTestRunner/Configurations/Base.xcconfig @@ -23,6 +23,7 @@ #include "CompilerVersion.xcconfig" +CLANG_WARN_CXX0X_EXTENSIONS = NO; HEADER_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR)/usr/local/include $(WEBCORE_PRIVATE_HEADERS_DIR)/ForwardingHeaders ${SRCROOT}/../../Source/JavaScriptCore/icu $(NEXT_ROOT)/usr/local/include/WebCoreTestSupport; FRAMEWORK_SEARCH_PATHS = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks; GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) ENABLE_DASHBOARD_SUPPORT WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST; diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl index 5e52ee8ba..819ea4600 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl +++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl @@ -54,6 +54,7 @@ module WTR { void setAllowUniversalAccessFromFileURLs(in boolean value); void setAllowFileAccessFromFileURLs(in boolean value); void setFrameFlatteningEnabled(in boolean value); + void setPluginsEnabled(in boolean value); void setGeolocationPermission(in boolean value); void setJavaScriptCanAccessClipboard(in boolean value); void setPrivateBrowsingEnabled(in boolean value); diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp index 05d4ea687..c9c3fec3d 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp +++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp @@ -230,7 +230,7 @@ void InjectedBundle::beginTesting(WKDictionaryRef settings) m_layoutTestController->setShouldDumpFrameLoadCallbacks(booleanForKey(settings, "DumpFrameLoadDelegates")); - page()->reset(); + page()->prepare(); WKBundleClearAllDatabases(m_bundle); WKBundleClearApplicationCache(m_bundle); @@ -260,7 +260,9 @@ void InjectedBundle::done() WKBundlePostMessage(m_bundle, doneMessageName.get(), doneMessageBody.get()); closeOtherPages(); - + + page()->resetAfterTest(); + m_state = Idle; } diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp index 57d2e1496..dc2ad3d39 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp +++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp @@ -330,7 +330,7 @@ void InjectedBundlePage::stopLoading() WKBundlePageStopLoading(m_page); } -void InjectedBundlePage::reset() +void InjectedBundlePage::prepare() { WKBundlePageClearMainFrameName(m_page); @@ -347,6 +347,17 @@ void InjectedBundlePage::reset() WKBundlePageSetTracksRepaints(m_page, false); } +void InjectedBundlePage::resetAfterTest() +{ + WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page); + JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); +#if PLATFORM(QT) + DumpRenderTreeSupportQt::injectInternalsObject(context); +#else + WebCoreTestSupport::resetInternalsObject(context); +#endif +} + // Loader Client Callbacks // String output must be identical to -[WebFrame _drt_descriptionSuitableForTestResult]. diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h index bce8ac038..4e1fce171 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h +++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h @@ -42,7 +42,8 @@ public: void stopLoading(); - void reset(); + void prepare(); + void resetAfterTest(); void dumpBackForwardList(); diff --git a/Tools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp b/Tools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp index 250fa5c95..cca4de681 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp +++ b/Tools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp @@ -371,6 +371,11 @@ void LayoutTestController::setFrameFlatteningEnabled(bool enabled) WKBundleSetFrameFlatteningEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); } +void LayoutTestController::setPluginsEnabled(bool enabled) +{ + WKBundleSetPluginsEnabled(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); +} + void LayoutTestController::setGeolocationPermission(bool enabled) { WKBundleSetGeolocationPermission(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), enabled); @@ -478,13 +483,6 @@ void LayoutTestController::evaluateInWebInspector(long callID, JSStringRef scrip #endif // ENABLE(INSPECTOR) } -void LayoutTestController::setJavaScriptProfilingEnabled(bool enabled) -{ -#if ENABLE(INSPECTOR) - WKBundleInspectorSetJavaScriptProfilingEnabled(WKBundlePageGetInspector(InjectedBundle::shared().page()->page()), enabled); -#endif // ENABLE(INSPECTOR) -} - typedef WTF::HashMap<unsigned, WKRetainPtr<WKBundleScriptWorldRef> > WorldMap; static WorldMap& worldMap() { diff --git a/Tools/WebKitTestRunner/InjectedBundle/LayoutTestController.h b/Tools/WebKitTestRunner/InjectedBundle/LayoutTestController.h index 8ca09f61a..945a6609e 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/LayoutTestController.h +++ b/Tools/WebKitTestRunner/InjectedBundle/LayoutTestController.h @@ -88,6 +88,7 @@ public: void setAllowUniversalAccessFromFileURLs(bool); void setAllowFileAccessFromFileURLs(bool); void setFrameFlatteningEnabled(bool); + void setPluginsEnabled(bool); void setGeolocationPermission(bool); void setJavaScriptCanAccessClipboard(bool); void setPrivateBrowsingEnabled(bool); @@ -174,7 +175,6 @@ public: void showWebInspector(); void closeWebInspector(); void evaluateInWebInspector(long callId, JSStringRef script); - void setJavaScriptProfilingEnabled(bool); void setPOSIXLocale(JSStringRef); diff --git a/Tools/WebKitTestRunner/InjectedBundle/qt/LayoutTestControllerQt.cpp b/Tools/WebKitTestRunner/InjectedBundle/qt/LayoutTestControllerQt.cpp index 72d04878a..5de8ae71a 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/qt/LayoutTestControllerQt.cpp +++ b/Tools/WebKitTestRunner/InjectedBundle/qt/LayoutTestControllerQt.cpp @@ -64,9 +64,7 @@ void LayoutTestController::platformInitialize() // which makes the use of QFontDatabase unnecessary. // See https://bugs.webkit.org/show_bug.cgi?id=53427 QWebSettings::clearMemoryCaches(); -#if !(QT_VERSION <= QT_VERSION_CHECK(4, 6, 2)) QFontDatabase::removeAllApplicationFonts(); -#endif activateFonts(); QObject::connect(&m_waitToDumpWatchdogTimer, SIGNAL(timeout()), WatchdogTimerHelper::instance(), SLOT(timerFired())); } diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp index a7c3b6a05..ffdc2cc66 100644 --- a/Tools/WebKitTestRunner/TestController.cpp +++ b/Tools/WebKitTestRunner/TestController.cpp @@ -49,7 +49,7 @@ namespace WTR { static const double defaultLongTimeout = 30; -static const double defaultShortTimeout = 5; +static const double defaultShortTimeout = 15; static const double defaultNoTimeout = -1; static WKURLRef blankURL() @@ -498,9 +498,9 @@ bool TestController::runTest(const char* test) if (!resetStateToConsistentValues()) { #if PLATFORM(MAC) pid_t pid = WKPageGetProcessIdentifier(m_mainWebView->page()); - fprintf(stderr, "#CRASHED - WebProcess (pid %ld)\n", static_cast<long>(pid)); + fprintf(stderr, "#PROCESS UNRESPONSIVE - WebProcess (pid %ld)\n", static_cast<long>(pid)); #else - fputs("#CRASHED - WebProcess\n", stderr); + fputs("#PROCESS UNRESPONSIVE - WebProcess\n", stderr); #endif fflush(stderr); return false; diff --git a/Tools/qmake/config.tests/libpng/libpng.pro b/Tools/qmake/config.tests/libpng/libpng.pro index d35b5dae6..23a39a971 100644 --- a/Tools/qmake/config.tests/libpng/libpng.pro +++ b/Tools/qmake/config.tests/libpng/libpng.pro @@ -1,3 +1,3 @@ SOURCES = libpng.cpp OBJECTS_DIR = obj -LIBS += -lpng12 +LIBS += -lpng diff --git a/Tools/qmake/mkspecs/features/default_post.prf b/Tools/qmake/mkspecs/features/default_post.prf index c37d71b62..78c93d7c0 100644 --- a/Tools/qmake/mkspecs/features/default_post.prf +++ b/Tools/qmake/mkspecs/features/default_post.prf @@ -21,6 +21,8 @@ isEmpty(OBJECTS_DIR): OBJECTS_DIR = obj/$$activeBuildConfig() DEFINES += \ BUILDING_QT__=1 +haveQt(5): DEFINES += HAVE_QT5=1 + CONFIG(release, debug|release): DEFINES *= NDEBUG CONFIG += depend_includepath diff --git a/Tools/qmake/mkspecs/features/features.pri b/Tools/qmake/mkspecs/features/features.pri index b5191701d..4de5c64cb 100644 --- a/Tools/qmake/mkspecs/features/features.pri +++ b/Tools/qmake/mkspecs/features/features.pri @@ -22,6 +22,7 @@ FEATURE_DEFAULTS = \ ENABLE_CSS_EXCLUSIONS=1 \ ENABLE_CSS_FILTERS=1 \ ENABLE_CSS_GRID_LAYOUT=0 \ + ENABLE_CSS_IMAGE_RESOLUTION=0 \ ENABLE_CSS_REGIONS=1 \ ENABLE_CSS_SHADERS=0 \ ENABLE_CSS_VARIABLES=0 \ diff --git a/Tools/qmake/mkspecs/features/unix/default_post.prf b/Tools/qmake/mkspecs/features/unix/default_post.prf index 3fc5c25f9..0064b3e46 100644 --- a/Tools/qmake/mkspecs/features/unix/default_post.prf +++ b/Tools/qmake/mkspecs/features/unix/default_post.prf @@ -18,9 +18,7 @@ linux-g++* { greaterThan(QT_GCC_MAJOR_VERSION, 3):greaterThan(QT_GCC_MINOR_VERSION, 5) { !contains(QMAKE_CXXFLAGS, -std=(c|gnu)\\+\\+(0x|11)) { # We need to deactivate those warnings because some names conflicts with upcoming c++0x types (e.g.nullptr). - QMAKE_CFLAGS_WARN_ON += -Wno-c++0x-compat QMAKE_CXXFLAGS_WARN_ON += -Wno-c++0x-compat - QMAKE_CFLAGS += -Wno-c++0x-compat QMAKE_CXXFLAGS += -Wno-c++0x-compat } } |
