diff options
Diffstat (limited to 'WebKitTools')
170 files changed, 5344 insertions, 1187 deletions
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json index 91a13e7..71c20f0 100644 --- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json +++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/config.json @@ -110,8 +110,8 @@ "platform": "win", "configuration": "debug", "architectures": ["i386"], "slavenames": ["apple-windows-4", "apple-windows-6", "test-slave"] }, - { "name": "Windows Debug (WebKit2 Tests)", "type": "TestWebKit2", "builddir": "win-debug-tests-wk2", - "platform": "win", "configuration": "debug", "architectures": ["i386"], + { "name": "Windows Release (WebKit2 Tests)", "type": "TestWebKit2", "builddir": "win-release-tests-wk2", + "platform": "win", "configuration": "release", "architectures": ["i386"], "slavenames": ["apple-windows-7", "test-slave"] }, { diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg index 47af8d2..5c44525 100644 --- a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg +++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg @@ -251,6 +251,7 @@ class NewRunWebKitTests(RunWebKitTests): "--verbose", "--results-directory", "layout-test-results", "--builder-name", WithProperties("%(buildername)s"), "--build-number", WithProperties("%(buildnumber)s"), + "--master-name", "webkit.org", "--test-results-server", "test-results.appspot.com", WithProperties("--%(configuration)s"), "--use-drt"] diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog index d138f3d..1c7d1bf 100644 --- a/WebKitTools/ChangeLog +++ b/WebKitTools/ChangeLog @@ -1,3 +1,2085 @@ +2010-10-29 Andreas Kling <kling@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QtTestBrowser: Add keyboard shortcut to toggle full screen (F11) + https://bugs.webkit.org/show_bug.cgi?id=48695 + + * QtTestBrowser/launcherwindow.cpp: + (LauncherWindow::createChrome): + +2010-10-29 Andreas Kling <kling@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QtTestBrowser: Fix uninitialized read in FpsTimer + https://bugs.webkit.org/show_bug.cgi?id=48675 + + FpsTimer::m_timer was never initialized and passed to QObject::killTimer() + on startup with in -graphicsbased mode. + + * QtTestBrowser/fpstimer.cpp: + (FpsTimer::FpsTimer): + (FpsTimer::numFrames): + (FpsTimer::stop): + (FpsTimer::timerEvent): + * QtTestBrowser/fpstimer.h: + +2010-10-29 Dirk Pranke <dpranke@chromium.org> + + Reviewed by Tony Chang. + + new-run-webkit-tests: change TestResults to be serializable + + In preparation for changing new-run-webkit-tests from + multithreaded to multiprocess, we need to make sure the data + going between the threads is easily serialized over a socket. + + This change adds serialization/pickling for the TestResults and + TestFailure objects (using cPickle). + + The TestFailure objects included a "has_wdiff" flag for Text + results, but the flag wasn't being used, so I've removed it, + simplifying the state to basically a set of enum objects with + associated methods. + + https://bugs.webkit.org/show_bug.cgi?id=48616 + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py: + * Scripts/webkitpy/layout_tests/layout_package/test_failures.py: + * Scripts/webkitpy/layout_tests/layout_package/test_failures_unittest.py: + * Scripts/webkitpy/layout_tests/layout_package/test_results.py: Added. + * Scripts/webkitpy/layout_tests/layout_package/test_results_unittest.py:Added. + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + * Scripts/webkitpy/layout_tests/test_types/text_diff.py: + +2010-10-29 Dirk Pranke <dpranke@chromium.org> + + Reviewed by Ojan Vafai. + + new-run-webkit-tests: need to provide separate dashboard results for GPU tests + https://bugs.webkit.org/show_bug.cgi?id=48687 + + Modify the steps to upload the JSON files to the dashboards so + that the GPU tests don't conflict with the regular tests on a + port. We do this by modifying the --builder-name parameter to + append " - GPU", which should cause the app to treat the results + as a completely new builder. This is a little non-obvious, but + keeps us from having to restructure the app. + + * Scripts/webkitpy/layout_tests/port/chromium_gpu.py: + * Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-10-29 Ojan Vafai <ojan@chromium.org> + + Reviewed by Tony Chang. + + [chromium] add debug logging to help diagnose flakiness dashboard issues + https://bugs.webkit.org/show_bug.cgi?id=48657 + + The appengine app thinks it's getting empty files uploaded. Add some logging + to see if new-run-webkit-tests agrees. + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-10-29 Dimitri Glazkov <dglazkov@chromium.org> + + Reviewed by Ojan Vafai. + + [Chromium/DRT] Add master-name flag to new-run-webkit-tests. + https://bugs.webkit.org/show_bug.cgi?id=48649 + + * BuildSlaveSupport/build.webkit.org-config/master.cfg: Added flag. + +2010-10-29 Nicolas Dufresne <nicolas.dufresne@collabora.co.uk> + + Reviewed by Martin Robinson. + + Enable popup window in GtkLauncher + https://bugs.webkit.org/show_bug.cgi?id=48335 + + The GtkLauncher application does not support opening new window when + a link with "target=_blank" is clicked or similar call to + window.open(). Instead, GtkLauncher does nothing which breaks + navigation of some websites. + + * GtkLauncher/main.c: + (activate_uri_entry_cb): + (update_title): + (link_hover_cb): + (notify_title_cb): + (notify_load_status_cb): + (notify_progress_cb): + (destroy_cb): + (go_back_cb): + (go_forward_cb): + (create_web_view_cb): + (web_view_ready_cb): + (close_web_view_cb): + (create_browser): + (create_statusbar): + (create_toolbar): + (create_window): + (main): + +2010-10-29 Adam Roben <aroben@apple.com> + + Teach check-webkit-style about WebKit2's idiosyncracies + + Fixes <http://webkit.org/b/48638> Style bot complains about a number + of WebKit2 conventions + + Reviewed by Anders Carlsson. + + * Scripts/webkitpy/style/checker.py: Excluded some rules for various + WebKit2-related files. Also updated the excluded rules for + WebKitAPITest to match the current code. + +2010-10-29 Csaba Osztrogonác <ossy@webkit.org> + + Reviewed by Adam Roben and David Kilzer. + + Fix and cleanup of build systems + https://bugs.webkit.org/show_bug.cgi?id=48342 + + * Scripts/build-webkit: + - Remove unnecessary ENABLE_SANDBOX option. + - Add ENABLE_FULLSCREEN_API option. + +2010-10-28 Adam Roben <aroben@apple.com> + + Switch the Windows WebKit2 bot to the Release configuration + + We only have one machine testing WebKit2 on Windows right now, and + Debug is just too slow for it to keep up. + + Fixes (hopefully!) <http://webkit.org/b/48615> Windows WebKit2 bot is + always way behind + + Reviewed by Jon Honeycutt. + + * BuildSlaveSupport/build.webkit.org-config/config.json: + +2010-10-29 Leandro Gracia Gil <leandrogracia@google.com> + + Reviewed by Jeremy Orlow. + + Added a second parameter to setMockSpeechInputResult for + the language used in speech input. + https://bugs.webkit.org/show_bug.cgi?id=47089 + + * DumpRenderTree/LayoutTestController.cpp: + (setMockSpeechInputResultCallback): + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/qt/LayoutTestControllerQt.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/qt/LayoutTestControllerQt.h: + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setMockSpeechInputResult): + (LayoutTestController::pageSizeAndMarginsInPixels): + +2010-10-28 Ojan Vafai <ojan@chromium.org> + + Reviewed by Tony Chang. + + [chromium] add a result-small.json file for the test dashboard + https://bugs.webkit.org/show_bug.cgi?id=48547 + + Output both a results.json file and a results-small.json file. + The dashboard will load results-small.json by default so it loads faster. + + * TestResultServer/model/jsonresults.py: + * TestResultServer/model/jsonresults_unittest.py: + Added a bunch of sys.path hackery. Unforunately, this uses hardcoded + paths. That obviously needs to be fixed, but at least this way it + clearly documents what paths are necessary. + +2010-10-28 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + webkit-patch upload calls changed_files more often than it should + https://bugs.webkit.org/show_bug.cgi?id=48567 + + Passing changed_files around everywhere isn't a very elegant solution + but it's the one we have for the moment. I think keeping an explicit + cache on Checkout (or making StepState() a real class) is a better + long-term option. + + Previously bug_id_for_this_commit was calling changed_files and the + result was never getting cached on the state. Now we're explicitly + caching the result on the state and passing that to the bug_id_for_this_commit call. + + I looked into building unit tests for this. Doing so would require + using a real Checkout object with a MockSCM and overriding the appropriate + calls on SCM to count how often we're stating the file system. + That's a useful set of tests to build for a separate change. + + * Scripts/webkitpy/common/checkout/api.py: + * Scripts/webkitpy/tool/commands/download.py: + * Scripts/webkitpy/tool/commands/upload.py: + * Scripts/webkitpy/tool/mocktool.py: + +2010-10-28 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + Make suggest-reviewers slightly faster + https://bugs.webkit.org/show_bug.cgi?id=48562 + + Add @memoized to one more common call. + + * Scripts/webkitpy/common/checkout/api.py: + +2010-10-28 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + webkit-patch suggest-reviewers -g 260550a6e30b7bf34f16bdb4a5396cf26264fc1c is still very slow + https://bugs.webkit.org/show_bug.cgi?id=48536 + + This patch makes it about 40 seconds faster, but it still + takes 1:40. This will require more refinement. + + The suggested reviewers list appears to be the same. + + I think the next step may be to have it stop the search after + 5 reviewers are found. We never want to suggest 30 people. + + * Scripts/webkitpy/common/checkout/scm.py: + - Using --remove-empty to theoretically stop lookups past + when a file is removed. I'm not entirely clear that the option + does what it says it does. Example: + git log --pretty=format:%H -5 --remove-empty -- /Projects/WebKit/WebCore/platform/wx/SearchPopupMenuWx.h + returns only one commit + vs. + git log --pretty=format:%H -5 -- /Projects/WebKit/WebCore/platform/wx/SearchPopupMenuWx.h + which returns 5. I was not aware that wx files were ever removed from the repository? + +2010-10-28 Kinuko Yasuda <kinuko@chromium.org> + + Reviewed by David Levin. + + [Chromium] Support FileSystem in chromium DRT + https://bugs.webkit.org/show_bug.cgi?id=47643 + + * DumpRenderTree/chromium/WebViewHost.cpp: + (WebViewHost::openFileSystem): Added. + * DumpRenderTree/chromium/WebViewHost.h: + (WebViewHost::openFileSystem): Added. + +2010-10-28 Sam Weinig <sam@webkit.org> + + Reviewed by Anders Carlsson. + + WKURLRefs should be allowed to be null + <rdar://problem/8575621> + https://bugs.webkit.org/show_bug.cgi?id=48535 + + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: + * TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp: + (TestWebKitAPI::didStartProvisionalLoadForFrame): + (TestWebKitAPI::didCommitLoadForFrame): + (TestWebKitAPI::didFinishLoadForFrame): + Test that URLs are null pointers when unset. + +2010-10-28 Chris Fleizach <cfleizach@apple.com> + + Reviewed by Adele Peterson. + + AX: multi select group option does not handle setting of AXSelectedChildren correctly + https://bugs.webkit.org/show_bug.cgi?id=48464 + + Add support for querying information about selected children to DRT, including: + selectedChildAtIndex + selectedChildrenCount + setSelectedChild + + * DumpRenderTree/AccessibilityUIElement.cpp: + (selectedChildAtIndexCallback): + (setSelectedChildCallback): + (selectedChildrenCountCallback): + (AccessibilityUIElement::setSelectedChild): + (AccessibilityUIElement::selectedChildrenCount): + (AccessibilityUIElement::selectedChildAtIndex): + (AccessibilityUIElement::getJSClass): + * DumpRenderTree/AccessibilityUIElement.h: + * DumpRenderTree/mac/AccessibilityUIElementMac.mm: + (AccessibilityUIElement::selectedChildAtIndex): + (AccessibilityUIElement::selectedChildrenCount): + (AccessibilityUIElement::setSelectedChild): + +2010-10-27 Sam Weinig <sam@webkit.org> + + Reviewed by Anders Carlsson. + + Add WebKit2 API for window feature getter/setters + <rdar://problem/8590373> + https://bugs.webkit.org/show_bug.cgi?id=48496 + + * MiniBrowser/mac/BrowserWindowController.m: + (-[BrowserWindowController awakeFromNib]): + * MiniBrowser/win/BrowserView.cpp: + (BrowserView::create): + * WebKitTestRunner/TestController.cpp: + (WTR::createOtherPage): + (WTR::TestController::initialize): + +2010-10-28 Søren Gjesse <sgjesse@chromium.org> + + Reviewed by Tony Chang. + + Added support for the DumpRenderTree flags --multiple-loads and --js-flags to the Python test runner. + https://bugs.webkit.org/show_bug.cgi?id=48236 + + * Scripts/webkitpy/layout_tests/port/chromium.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-10-28 Sergio Villar Senin <svillar@igalia.com> + + Reviewed by Martin Robinson. + + [GTK] WebKitWebFrame's load-status is not properly notified to the tests + https://bugs.webkit.org/show_bug.cgi?id=48048 + + DRT now listens to WebKitWebFrame load-status signals for each + created frame instead of the load-status signal of the + WebKitWebView that only notifies about changes in the main frame. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (webViewLoadFinished): + (webFrameLoadStatusNotified): + (frameCreatedCallback): + (createWebView): + (main): + +2010-10-28 Tony Chang <tony@chromium.org> + + Reviewed by Kent Tamura. + + [chromium] fix textInputController.{selectedRange,markedRange} + https://bugs.webkit.org/show_bug.cgi?id=48487 + + * DumpRenderTree/chromium/TextInputController.cpp: + (TextInputController::markedRange): Return arrays of ints, rather than a string + (TextInputController::selectedRange): Ditto. + +2010-10-27 Ojan Vafai <ojan@chromium.org> + + Reviewed by Tony Chang. + + [chromium] add a master-name flag to new-run-webkit-tests + https://bugs.webkit.org/show_bug.cgi?id=48488 + + The test results server now allows adding a master name to + the uploaded files. This lets us distinguish bots that have + the same name, but are on different masters. + + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-10-28 Adam Roben <aroben@apple.com> + + Don't append a newline to the test output if the frame has no document + element in WebKitTestRunner + + Fixes <http://webkit.org/b/48526> Extra trailing newline when running + plugins/document-open.html in WebKitTestRunner + + Reviewed by Anders Carlsson. + + * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp: + (WTR::toJS): Added. Turns a UTF-8 C string into a JSStringRef. + (WTR::hasDocumentElement): Added. Uses the JSC API to figure out + whether the frame has a document element. + (WTR::dumpFrameText): Match DRT by bailing (rather than appending an + empty string and a newline) if the frame has no document element. + +2010-10-28 Adam Roben <aroben@apple.com> + + Skip npn-invalidate-rect-invalidates-window.html on headless XP + machines + + TestNetscapePlugIn never receives a WM_PAINT message on headless XP + machines, so this test times out. Fixing the test is covered by + <http://webkit.org/b/48333>. + + * Scripts/old-run-webkit-tests: Skip + npn-invalidate-rect-invalidates-window.html on Windows if accelerated + compositing support is disabled, which likely means we're on a headless + XP machine. + +2010-10-28 Kimmo Kinnunen <kimmok@iki.fi> + + Adding myself as a committer. + + * Scripts/webkitpy/common/config/committers.py: + +2010-10-27 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + webkit-patch suggest-reviewers -g 260550a6e30b7bf34f16bdb4a5396cf26264fc1c is very slow + https://bugs.webkit.org/show_bug.cgi?id=48500 + + This doesn't fix the problem, but it makes things slightly better. + Each git svn find-rev call takes about .25 seconds on my desktop. + This patch uses a new memoized class to avoid those calls when possible. + + The real slowness is still git log on some files, like: + git log --pretty=format:%H -5 -- /Projects/WebKit/WebCore/platform/wx/SearchPopupMenuWx.h + I'm not yet sure how to make the pathological git logs better. + + * Scripts/webkitpy/common/checkout/scm.py: + * Scripts/webkitpy/common/memoized.py: Added. + * Scripts/webkitpy/common/memoized_unittest.py: Added. + +2010-10-27 Eric Seidel <eric@webkit.org> + + Reviewed by Ojan Vafai. + + EWS bots should not use --quiet when running build-webkit + https://bugs.webkit.org/show_bug.cgi?id=48482 + + --quiet is only correct when the sub-process does the error reporting. + In the case of _can_build() the parent process is reporting the error. + We'd like the full build log at queues.webkit.org so someone can look + at the log and understand why the EWS is failing to build trunk. + + * Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py: + * Scripts/webkitpy/tool/commands/earlywarningsystem.py: + * Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py: + * Scripts/webkitpy/tool/mocktool.py: + +2010-10-27 Brian Weinstein <bweinstein@apple.com> + + More Windows build fixage. Rename a variable that was named string. + + * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp: + (WTR::hasPrefix): + +2010-10-27 Ojan Vafai <ojan@chromium.org> + + Reviewed by Dimitri Glazkov. + + [chromium] Make the test results server store which master the bot is on + https://bugs.webkit.org/show_bug.cgi?id=48478 + + The chromium bots recently changed so that there are multiple slaves with + the same name on different masters. Up till now, the test results server + assumed slave names were unique. Adds a master field to the file in order + to distinguish. + + Also, for files that currently lack a master or testtype, set them appropriately. + + * TestResultServer/handlers/testfilehandler.py: + * TestResultServer/index.yaml: + * TestResultServer/model/jsonresults.py: + * TestResultServer/model/testfile.py: + * TestResultServer/templates/showfilelist.html: + * TestResultServer/templates/uploadform.html: + +2010-10-26 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + WebKitTestRunner needs to support layoutTestController.dumpBackForwardList + https://bugs.webkit.org/show_bug.cgi?id=42322 + rdar://problem/8193631 + + WebKitTestRunner needs to support layoutTestController.clearBackForwardList + https://bugs.webkit.org/show_bug.cgi?id=42333 + rdar://problem/8193643 + + * WebKitTestRunner/Configurations/InjectedBundle.xcconfig: + Renamed the product to WebKitTestRunnerInjectedBundle to avoid + name conflicts in the build directory. + + * WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl: + Added dumpBackForwardList and clearBackForwardList. + + * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: + (WTR::InjectedBundle::InjectedBundle): Removed initialization of m_mainPage. + (WTR::InjectedBundle::didCreatePage): Removed unneeded underscore. + (WTR::InjectedBundle::willDestroyPage): Ditto. + (WTR::InjectedBundle::didReceiveMessage): Ditto. + (WTR::InjectedBundle::initialize): Ditto. + (WTR::InjectedBundle::didCreatePage): Changed code to use m_pages + instead of m_mainPage and m_otherPages. + (WTR::InjectedBundle::willDestroyPage): Ditto. + (WTR::InjectedBundle::page): Ditto. + (WTR::InjectedBundle::beginTesting): Ditto. + (WTR::InjectedBundle::done): Ditto. + (WTR::InjectedBundle::closeOtherPages): Ditto. + (WTR::InjectedBundle::dumpBackForwardListsForAllPages): Added. + + * WebKitTestRunner/InjectedBundle/InjectedBundle.h: Changed + page function to longer be inline, and pageCount function + to use m_pages. Added dumpBackForwardListsForAllPages, and + removed some underscores. Replaced m_mainPage and m_otherPageas + with m_pages. + + * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp: + (WTR::adoptWK): Added. + (WTR::hasPrefix): Added. + (WTR::InjectedBundlePage::reset): Added code to set up + m_previousTestBackForwardListItem. + (WTR::InjectedBundlePage::dump): Added code to call + dumpBackForwardListsForAllPages. + (WTR::compareByTargetName): Added. + (WTR::dumpBackForwardListItem): Added. + (WTR::InjectedBundlePage::dumpBackForwardList): Added. + + * WebKitTestRunner/InjectedBundle/InjectedBundlePage.h: Added + dumpBackForwardList and m_previousTestBackForwardListItem. + + * WebKitTestRunner/InjectedBundle/LayoutTestController.cpp: + (WTR::LayoutTestController::LayoutTestController): Initialize + m_shouldDumpBackForwardListsForAllWindows to false. + (WTR::LayoutTestController::clearBackForwardList): Added. + + * WebKitTestRunner/InjectedBundle/LayoutTestController.h: + Added dumpBackForwardList, clearBackForwardList, + shouldDumpBackForwardListsForAllWindows, and + m_shouldDumpBackForwardListsForAllWindows. + + * WebKitTestRunner/TestController.cpp: + (WTR::TestController::initialize): Set up + didReceiveSynchronousMessageFromInjectedBundle. + (WTR::TestController::didReceiveSynchronousMessageFromInjectedBundle): + Added. + * WebKitTestRunner/TestController.h: Ditto. + + * WebKitTestRunner/TestInvocation.cpp: + (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): + Added. + * WebKitTestRunner/TestInvocation.h: Ditto. + + * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj: + Renamed bundle to WebKitTestRunnerInjectedBundle (see above). + * WebKitTestRunner/mac/TestControllerMac.mm: + (WTR::TestController::initializeInjectedBundlePath): Ditto. + +2010-10-27 Chris Rogers <crogers@google.com> + + Reviewed by Chris Marrin. + + Add ENABLE_WEB_AUDIO feature enable flag (initially disabled) to build-webkit + https://bugs.webkit.org/show_bug.cgi?id=48279 + + * Scripts/build-webkit: + +2010-10-27 Eric Seidel <eric@webkit.org> + + Unreviewed. + + build-webkit should collect Visual Studio Express logs and display them + https://bugs.webkit.org/show_bug.cgi?id=39199 + + It turns out my previous patch wasn't actually working on the win-ews + machine. So I've fixed my mistakes from before. + + * Scripts/build-webkit: + - Windows VSE builds change the CWD while building. Why? Who knows. + * Scripts/print-vse-failure-logs: + - windows VSE builds don't use Debug/Release as I expected, so I've + moved off of --configuration to --top-level and added the /obj + optimization while I was there. + +2010-10-27 Dimitri Glazkov <dglazkov@chromium.org> + + Unreviewed, rolling out r70674. + http://trac.webkit.org/changeset/70674 + https://bugs.webkit.org/show_bug.cgi?id=48053 + + Broke Chromium Windows build. + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-10-25 Tony Chang <tony@chromium.org> + + Reviewed by Anders Carlsson. + + compile TestNetscapePlugIn on chromium linux + https://bugs.webkit.org/show_bug.cgi?id=48274 + + * DumpRenderTree/TestNetscapePlugIn/main.cpp: + (NP_Initialize): On Linux, plugin funcs are set in initialize. + (NPP_New): Mark the plugin as windowless. + (NPP_GetValue): Handle mime type values. + (NP_GetMIMEDescription): + (NP_GetValue): + * DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npapi.h: define TRUE and FALSE, which are in webkit's npapi.h. + * DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npfunctions.h: Pull in npapi.h to get TRUE/FALSE (matches webkit's npfunctions.h) + +2010-10-27 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Anders Carlsson. + + Remove contentSizeChanged callbacks as it is no longer + part of the public UIClient. + + Make WKPageContentsSizeChangedCallback be a private API + https://bugs.webkit.org/show_bug.cgi?id=48409 + + * MiniBrowser/mac/BrowserWindowController.m: + (-[BrowserWindowController awakeFromNib]): + * MiniBrowser/win/BrowserView.cpp: + (BrowserView::create): + * WebKitTestRunner/TestController.cpp: + (WTR::createOtherPage): + (WTR::TestController::initialize): + +2010-10-27 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Ojan Vafai. + + Make http locking default in NRWT. + https://bugs.webkit.org/show_bug.cgi?id=48053 + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-10-27 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Tony Chang. + + [NRWT] Fix http lock on Windows platform + https://bugs.webkit.org/show_bug.cgi?id=48321 + + * Scripts/webkitpy/layout_tests/port/http_lock.py: + +2010-10-27 Satish Sampath <satish@chromium.org> + + Unreviewed, rolling out r70665. + http://trac.webkit.org/changeset/70665 + https://bugs.webkit.org/show_bug.cgi?id=47089 + + Need to address Alexey's review comments. + + * DumpRenderTree/LayoutTestController.cpp: + (setMockSpeechInputResultCallback): + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/qt/LayoutTestControllerQt.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/qt/LayoutTestControllerQt.h: + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setMockSpeechInputResult): + +2010-10-27 Leandro Gracia Gil <leandrogracia@google.com> + + Reviewed by Jeremy Orlow. + + Added a second parameter to setMockSpeechInputResult for + the language used in speech input. + https://bugs.webkit.org/show_bug.cgi?id=47089 + + * DumpRenderTree/LayoutTestController.cpp: + (setMockSpeechInputResultCallback): + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/qt/LayoutTestControllerQt.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/qt/LayoutTestControllerQt.h: + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setMockSpeechInputResult): + (LayoutTestController::pageSizeAndMarginsInPixels): + +2010-10-27 Adam Roben <aroben@apple.com> + + Reset TestNetscapePlugIn's NPP_GetValue pointer when + NullNPPGetValuePointer finishes running + + Fixes <http://webkit.org/b/48435> REGRESSION (r70655): Many plugins + tests are failing on Qt + + Reviewed by Anders Carlsson. + + * DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp: + (PluginTest::NPP_Destroy): + * DumpRenderTree/TestNetscapePlugIn/PluginTest.h: + Added a do-nothing NPP_Destroy implementation. + + * DumpRenderTree/TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp: + (NullNPPGetValuePointer::NullNPPGetValuePointer): Save the original + NPP_GetValue pointer in m_originalNPPGetValuePointer so we can restore + it later. + (NullNPPGetValuePointer::NPP_Destroy): Added. Restores the original + NPP_GetValue pointer so it can be used in other tests. + + * DumpRenderTree/TestNetscapePlugIn/main.cpp: + (NPP_Destroy): + * DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp: + (webkit_test_plugin_destroy_instance): + Call through to the PluginTest when NPP_Destroy is called. + +2010-10-26 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Adam Roben. + + WebKit2 shouldn't try to send an empty user agent + https://bugs.webkit.org/show_bug.cgi?id=48397 + + Add a test that when we set our custom user agent to an empty string, we don't send + an empty user agent. + + * TestWebKitAPI/Tests/WebKit2/PreventEmptyUserAgent.cpp: Added. + (TestWebKitAPI::didRunJavaScript): Make sure that the result of navigator.userAgent isn't empty. + (TestWebKitAPI::TEST): Set our custom user agent to the empty string, and run navigator.userAgent. + + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: Add the new file. + * TestWebKitAPI/win/TestWebKitAPI.vcproj: Ditto. + +2010-10-27 Adam Roben <aroben@apple.com> + + Check in file I forgot in r70653 + + * DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp: + (NP_Initialize): Save the NPPluginFuncs struct the browser passed to us + so we can be naughty and modify it later. + +2010-10-27 Adam Roben <aroben@apple.com> + + Test that WebKit doesn't crash if the plugin passes 0 for its + NPP_GetValue pointer + + Test for <http://webkit.org/b/48433> Crash in + NetscapePlugin::shouldLoadSrcURL when using Shockwave Director 10.3 in + WebKit2 on Windows + + Reviewed by Eric Carlson. + + * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: + * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj: + * DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro: + * GNUmakefile.am: + Added NullNPPGetValuePointer.cpp. + + * DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp: + * DumpRenderTree/TestNetscapePlugIn/PluginObject.h: + Set up a place to store the NPPluginFuncs struct the browser passed to us. + + * DumpRenderTree/TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp: Added. + (NullNPPGetValuePointer::NullNPPGetValuePointer): Null out the + NPP_GetValue pointer we passed to the browser to simulate a plugin that + doesn't implement NPP_GetValue. + (NullNPPGetValuePointer::NPP_GetValue): Print an error message. If this + function is called, it means that WebKit has changed in a way that + makes this test invalid. + + * DumpRenderTree/TestNetscapePlugIn/main.cpp: + (NP_GetEntryPoints): Save the NPPluginFuncs struct the browser passed + to us so we can be naughty and modify it later. + +2010-10-27 Ademar de Souza Reis Jr <ademar.reis@openbossa.org> + + Reviewed by Andreas Kling. + + Remove references to ancient QGVLauncher and QtLauncher + https://bugs.webkit.org/show_bug.cgi?id=48430 + + QtTestBrowser substitutes both and has checks enabled. + + * Scripts/webkitpy/style/checker.py: remove references + * Scripts/webkitpy/style/checker_unittest.py: ditto + +2010-10-27 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Ojan Vafai. + + [NRWT] Don't use image hash when it's no need in single test mode. + https://bugs.webkit.org/show_bug.cgi?id=48326 + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + +2010-10-27 David Kilzer <ddkilzer@apple.com> + + Fix leak of CFMutableDictionaryRef in createXMLStringFromWebArchiveData() + + Reviewed by Adam Roben. + + Follow-up fix for: <https://bugs.webkit.org/show_bug.cgi?id=48278> + + * DumpRenderTree/cf/WebArchiveDumpSupport.cpp: + (createXMLStringFromWebArchiveData): Use RetainPtr<> to fix a + leak introduced in r70613. + +2010-10-27 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Csaba Osztrogonác. + + [NRWT] Add platform specific baseline search paths for Qt port + https://bugs.webkit.org/show_bug.cgi?id=48428 + + * Scripts/webkitpy/layout_tests/port/qt.py: + +2010-10-27 Adam Roben <aroben@apple.com> + + Catch exceptions when checking if we're inside a git working directory + + Fixes <http://webkit.org/b/48420> REGRESSION (r70562): test-webkitpy + fails on systems without git installed + + Reviewed by Anders Carlsson. + + * Scripts/webkitpy/common/net/credentials.py: + (Credentials._credentials_from_git): Put the call to + Git.in_working_directory inside the try/except since it, too, attempts + to execute git and thus will throw on systems that don't have git + installed. + +2010-10-27 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by David Kilzer. + + Convert DumpRenderTree webarchive code to CoreFoundation + https://bugs.webkit.org/show_bug.cgi?id=48278 + + CFPropertyListCreateWithData and CFPropertyListCreateData are only available in 10.6+. + Replace CFPropertyListCreateWithData by a combination of CFReadStreamCreateWithBytesNoCopy and CFPropertyListCreateFromStream. + Replace CFPropertyListCreateData by CFPropertyListCreateXMLData. + + These changes are wrapped in BUILDING_ON_LEOPARD, as the methods are deprecated on 10.6+. + + * DumpRenderTree/cf/WebArchiveDumpSupport.cpp: + (createXMLStringFromWebArchiveData): + +2010-10-26 Antonio Gomes <agomes@rim.com> + + Reviewed by Martin Robinson. + + Remove the absolute path used to include DumpRenderTreeSupportGtk.h from LayoutTestController.h + + It turns out this is rather unneeded since WebKitTools/GNUMakefile.am has WebKit/gtk/ in its include + path, and then we can just do #include "WebCoreSupport/DumpRenderTreeSupportGtk.h" + + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + +2010-10-26 David Kilzer <ddkilzer@apple.com> + + Rename WebArchiveDumpSupport.mm to WebArchiveDumpSupport.cpp + + Reviewed by Adam Roben. + + Part 4 of 4: <http://webkit.org/b/48278> Convert DumpRenderTree webarchive code to CoreFoundation + + * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: + Updated for file moves and renames. + * DumpRenderTree/cf/WebArchiveDumpSupport.cpp: Renamed from DumpRenderTree/mac/WebArchiveDumpSupport.mm. + * DumpRenderTree/cf/WebArchiveDumpSupport.h: Renamed from DumpRenderTree/mac/WebArchiveDumpSupport.h. + +2010-10-26 David Kilzer <ddkilzer@apple.com> + + Convert WebArchiveDumpSupport.mm from NS objects to CF types + + Reviewed by Adam Roben. + + Part 3 of 4: <http://webkit.org/b/48278> Convert DumpRenderTree webarchive code to CoreFoundation + + In order to share WebArchive code between the Mac and Windows + ports, the code in WebArchiveDumpSupport.mm was converted from + Cocoa to C++ using CoreFoundation (CF) types. + + * DumpRenderTree/mac/DumpRenderTree.mm: + (dump): Renamed serializeWebArchiveToXML() to + createXMLStringFromWebArchiveData() and added HardAutorelease() + to prevent leaks. + * DumpRenderTree/mac/WebArchiveDumpSupport.h: + (createXMLStringFromWebArchiveData): Renamed from + serializeWebArchiveToXML(). Changed to use CF types. + (createCFURLResponseFromResponseData): Renamed from + unarchiveNSURLResponseFromResponseData(). Changed to use CF + types for its parameter and return type. + * DumpRenderTree/mac/WebArchiveDumpSupport.mm: Replaced use of + NS objects with CF types. It will be renamed to *.cpp in a + future commit. + (convertMIMEType): Changed to use case-insensitive string + comparisons. + (convertWebResourceDataToString): + (normalizeHTTPResponseHeaderFields): + (normalizeWebResourceURL): + (convertWebResourceResponseToDictionary): + (compareResourceURLs): + (createXMLStringFromWebArchiveData): + * DumpRenderTree/mac/WebArchiveDumpSupportMac.mm: + (createCFURLResponseFromResponseData): Renamed from + unarchiveNSURLResponseFromResponseData(). Changed to use CF + types for its parameter and return type. + +2010-10-26 David Kilzer <ddkilzer@apple.com> + + Extract use of NSKeyedUnarchiver from WebArchiveDumpSupport.mm + + Reviewed by Adam Roben. + + Part 2 of 4: <http://webkit.org/b/48278> Convert DumpRenderTree webarchive code to CoreFoundation + + There is no equivalent to NSKeyedUnarchiver in CoreFoundation, + so extract it into a platform-specific source file. + + * DumpRenderTree/mac/WebArchiveDumpSupport.h: + (unarchiveNSURLResponseFromResponseData): Added declaration. + * DumpRenderTree/mac/WebArchiveDumpSupport.mm: + (convertWebResourceResponseToDictionary): Extracted code to + unarchiveNSURLResponseFromResponseData() in + WebArchiveDumpSupportMac.mm. Updated logic to return early if + nil is returned from unarchiveNSURLResponseFromResponseData(). + * DumpRenderTree/mac/WebArchiveDumpSupportMac.mm: + (unarchiveNSURLResponseFromResponseData): Added. Extracted + code from convertWebResourceResponseToDictionary() in + WebArchiveDumpSupport.mm. + +2010-10-26 David Kilzer <ddkilzer@apple.com> + + Extract call to -[WebHTMLRepresentation supportedNonImageMIMETypes] from WebArchiveDumpSupport.mm + + Reviewed by Adam Roben. + + Part 1 of 4: <http://webkit.org/b/48278> Convert DumpRenderTree webarchive code to CoreFoundation + + The call to -[WebHTMLRepresentation supportedNonImageMIMETypes] + is not cross-platform between Mac and Windows, so extract it + into a platform-specific source file. + + * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: Added + WebArchiveDumpSupportMac.mm to the project. + * DumpRenderTree/mac/WebArchiveDumpSupport.h: + (supportedNonImageMIMETypes): Added declaration. + * DumpRenderTree/mac/WebArchiveDumpSupport.mm: + (convertWebResourceDataToString): Replaced call to + -[WebHTMLRepresentation supportedNonImageMIMETypes] with + supportedNonImageMIMETypes(). + * DumpRenderTree/mac/WebArchiveDumpSupportMac.mm: Added. + (supportedNonImageMIMETypes): Added. Extracted from + WebArchiveDumpSupport.mm. + +2010-10-26 Antonio Gomes <agomes@rim.com> + + Reviewed by Martin Robinson. + + [GTK] Implement DumpRenderTreeSupportGtk (similarly to DumpRenderTreeSupportQt idea) + https://bugs.webkit.org/show_bug.cgi?id=48199 + + Implements support to WebKitTabToLinksPreferenceKey through LayoutTestController::overridePreference. + The corresponding DumpRenderTreeSupportGtk method is called in the DRT context only. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): + (createWebView): + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::overridePreference): + +2010-10-26 Ariya Hidayat <ariya@sencha.com> + + Unreviewed, change the order of my emails for bugzilla autocompletion. + + * Scripts/webkitpy/common/config/committers.py: + +2010-10-26 Eric Seidel <eric@webkit.org> + + Reviewed by David Kilzer. + + build-webkit should collect Visual Studio Express logs and display them + https://bugs.webkit.org/show_bug.cgi?id=39199 + + * Scripts/build-webkit: + * Scripts/print-vse-failure-logs: Added. + * Scripts/webkitdirs.pm: + +2010-10-26 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/48224> build-webkit: add support for --meter-tag switch + + Reviewed by Csaba Osztrogonác. + + * Scripts/build-webkit: Added support for --meter-tag switch. + It should have been added with r60820. + +2010-10-26 Ademar de Souza Reis Jr. <ademar.reis@openbossa.org> + + Reviewed by Dumitru Daniliuc. + + check-webkit-style fails on operator+=, operator-=, ... methods + https://bugs.webkit.org/show_bug.cgi?id=48258 + + * Scripts/webkitpy/style/checkers/cpp.py: Added exceptions + * Scripts/webkitpy/style/checkers/cpp_unittest.py: Added unit-tests + +2010-10-26 Ojan Vafai <ojan@chromium.org> + + Reviewed by Tony Chang. + + remove DEFER support from new-run-webkit-tests + https://bugs.webkit.org/show_bug.cgi?id=48387 + + DEFER was needed when we were trying to ship Chrome beta. + Now it's just extra complication. + + * Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py: + * Scripts/webkitpy/layout_tests/layout_package/test_expectations.py: + * Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py: + * Scripts/webkitpy/layout_tests/port/chromium_unittest.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + * Scripts/webkitpy/style/checkers/test_expectations_unittest.py: + +2010-10-26 Eric Seidel <eric@webkit.org> + + Unreviewed. Adding import with_statement to fix python 2.5. + + Teach webkit-patch how to read credentials from the environment + https://bugs.webkit.org/show_bug.cgi?id=48275 + + * Scripts/webkitpy/common/net/credentials_unittest.py: + - import with_statement to fix python 2.5. + +2010-10-26 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Sam Weinig. + + https://bugs.webkit.org/show_bug.cgi?id=48375 + <rdar://problem/8392724> Need delegate calls in PageLoaderClient to indicate if we have + loaded insecure content + + Updated for WebKit2 changes. + + * MiniBrowser/mac/BrowserWindowController.m: + (didDisplayInsecureContentForFrame): + (didRunInsecureContentForFrame): + (-[BrowserWindowController awakeFromNib]): + * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp: + (WTR::InjectedBundlePage::InjectedBundlePage): + (WTR::InjectedBundlePage::didDisplayInsecureContentForFrame): + (WTR::InjectedBundlePage::didRunInsecureContentForFrame): + * WebKitTestRunner/InjectedBundle/InjectedBundlePage.h: + * WebKitTestRunner/TestController.cpp: + (WTR::TestController::initialize): + +2010-10-26 Adam Roben <aroben@apple.com> + + Clear up confusion between "3D rendering" and "accelerated compositing" + + WebKit has no software-based 3D rendering implementation, so 3D + rendering can only be enabled when accelerated compositing is. But DRT + was falsely reporting that 3D rendering was available on machines that + don't support accelerated compositing, leading to much confusion. + + Reviewed by Darin Adler. + + Fixes <http://webkit.org/b/48370> REGRESSION (r70540): Many + transforms/3d tests are failing on the XP bots + + * DumpRenderTree/win/DumpRenderTree.cpp: + (main): When ENABLE(3D_RENDERING) is turned on, only report that 3D + rendering is available when acclerated compositing is also available. + + * Scripts/old-run-webkit-tests: Skip tests that use the + -webkit-transform-3d media query when 3D rendering is disabled, + rather than when accelerated compositing is disabled. + +2010-10-26 Eric Seidel <eric@webkit.org> + + Reviewed by Ojan Vafai. + + Remove rietveld code now that it's unused + https://bugs.webkit.org/show_bug.cgi?id=48359 + + Was cool that we added this support, but now that it's + not used it makes little sense to keep it around. + We can always restore this code from SVN if we need it. + + * Scripts/webkitpy/common/config/__init__.py: + * Scripts/webkitpy/common/net/bugzilla.py: + * Scripts/webkitpy/common/net/bugzilla_unittest.py: + * Scripts/webkitpy/common/net/rietveld.py: Removed. + * Scripts/webkitpy/common/net/rietveld_unittest.py: Removed. + * Scripts/webkitpy/thirdparty/__init__.py: + * Scripts/webkitpy/tool/commands/download.py: + * Scripts/webkitpy/tool/commands/download_unittest.py: + * Scripts/webkitpy/tool/commands/queues.py: + * Scripts/webkitpy/tool/commands/queues_unittest.py: + * Scripts/webkitpy/tool/main.py: + * Scripts/webkitpy/tool/mocktool.py: + * Scripts/webkitpy/tool/steps/__init__.py: + * Scripts/webkitpy/tool/steps/postcodereview.py: Removed. + +2010-10-26 Anders Carlsson <andersca@apple.com> + + Reviewed by Sam Weinig. + + pageDidScroll callback should be on the UI process client rather than (or in addition to) the web process client + https://bugs.webkit.org/show_bug.cgi?id=48366 + <rdar://problem/8595202> + + * MiniBrowser/mac/BrowserWindowController.m: + (-[BrowserWindowController awakeFromNib]): + * WebKitTestRunner/TestController.cpp: + (WTR::createOtherPage): + (WTR::TestController::initialize): + +2010-10-26 Eric Seidel <eric@webkit.org> + + Reviewed by Tony Chang. + + Teach webkit-patch how to read credentials from the environment + https://bugs.webkit.org/show_bug.cgi?id=48275 + + This makes it possible for svn users to have their bugzilla credentials + stored in their environment instead of typing them every time. + + We need this for making it easy to run the win-ews bot (which currently + uses svn instead of git). + + * Scripts/webkitpy/common/net/credentials.py: + * Scripts/webkitpy/common/net/credentials_unittest.py: + +2010-10-26 Kenichi Ishibashi <bashi@google.com> + + Reviewed by Kent Tamura. + + Input Method inserts conversion candidates unexpectedly + https://bugs.webkit.org/show_bug.cgi?id=46868 + + Adds setComposition() to TextInputController to make DRT emulate + an input method behavior. + + * DumpRenderTree/chromium/TextInputController.cpp: + (TextInputController::TextInputController): + (TextInputController::setComposition): Added. + * DumpRenderTree/chromium/TextInputController.h: + +2010-10-26 Simon Fraser <simon.fraser@apple.com> + + Reviewed by Sam Weinig. + + Support layoutTestController.layerTreeAsText in WebKitTestRunner + https://bugs.webkit.org/show_bug.cgi?id=42145 + + Implement layerTreeAsText() in WebKitTestRunner. + + * WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl: + * WebKitTestRunner/InjectedBundle/LayoutTestController.cpp: + (WTR::LayoutTestController::layerTreeAsText): + * WebKitTestRunner/InjectedBundle/LayoutTestController.h: + +2010-10-26 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + webkit-patch rollout produces incorrect patch when using svn move + https://bugs.webkit.org/show_bug.cgi?id=48244 + + We need to flush our caches when we modify the working copy. + + * Scripts/webkitpy/tool/steps/revertrevision.py: + +2010-10-26 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + commit-queue flaky test message can list the same author more than once + https://bugs.webkit.org/show_bug.cgi?id=48268 + + tonikitoo reported to me over IRC this morning that he's seen + the commit-queue report flaky tests with author lists like: + "adam, adam and adam", suggesting we're not uniquing authors + before writing the message. + + I fixed the uniquing and added a bunch more unit testing. + + * Scripts/webkitpy/tool/commands/queues.py: + * Scripts/webkitpy/tool/commands/queues_unittest.py: + * Scripts/webkitpy/tool/mocktool.py: + +2010-10-26 Adam Roben <aroben@apple.com> + + Pull in the FeatureDefines*.vsprops files when building DRT + + This ensures that various ENABLE() macros will get set correctly. + (Prior to r70320 we were picking up the ENABLE(3D_RENDERING) flag + through wtf/Platform.h.) + + Fixes <http://webkit.org/b/48343> REGRESSION (r70320): DumpRenderTree + says 3D_RENDERING is disabled even when it is enabled + + Reviewed by Ada Chan. + + * DumpRenderTree/win/DumpRenderTree.vcproj: Added + FeaturesDefines*.vsprops to all configurations. + + * DumpRenderTree/win/DumpRenderTreeWin.h: Touched to force a rebuild. + +2010-10-26 Søren Gjesse <sgjesse@chromium.org> + + Reviewed by Dimitri Glazkov. + + Added options --multiple-loads and --js-flags to chromium DumpRenderTree. The option --multiple-loads=X + is used to have DumpRenderTree load each test it runs X times. To be able to have more fine-grained control + of how the JavaScript engine behaves for each load the flag --js-flags can specify a list of flag-sets like this + + --js-flags="--xxx,--noxxx --yyy,--noyyy" + + First load will run with --xxx, the second with --yyy and the third without any (the 'no' prefix is handled by + V8 to turn off the flag). + + The changes to the Python test runner will be in a separate change. + + + * DumpRenderTree/chromium/DumpRenderTree.cpp: + (runTest): + (main): + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::TestShell): + (TestShell::runFileTest): + (TestShell::testFinished): + * DumpRenderTree/chromium/TestShell.h: + (TestShell::loadCount): + (TestShell::setLoadCount): + (TestShell::javaScriptFlagsForLoad): + (TestShell::setJavaScriptFlags): + (TestShell::setDumpWhenFinished): + +2010-10-26 Adam Roben <aroben@apple.com> + + Skip more tests that depend on accelerated compositing when accelerated + compositing is disabled + + Fixes <http://webkit.org/b/48329> Some tests fail when accelerated + compositing is disabled + + Reviewed by John Sullivan. + + * Scripts/old-run-webkit-tests: Added more tests to skip when + accelerated compositing is disable. The tests all have output that + changes depending on whether accelerated compositing is enabled. + +2010-10-25 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + webkit-patch should clean up svn locks when passed --force-clean + https://bugs.webkit.org/show_bug.cgi?id=48269 + + * Scripts/webkitpy/common/checkout/scm.py: + +2010-10-25 Anders Carlsson <andersca@apple.com> + + Reviewed by Adam Roben. + + Add a pageDidScroll BundleUIClient callback + https://bugs.webkit.org/show_bug.cgi?id=48260 + <rdar://problem/8531159> + + * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp: + (WTR::InjectedBundlePage::InjectedBundlePage): + +2010-10-25 Johnny Ding <jnd@chromium.org> + + Reviewed by Tony Chang. + + Dump the gesture status of frame in frame load callbacks in DumpRenderTree + by adding a new method dumpUserGestureInFrameLoadCallbacks. + Now only dump the gesture status in "DidStartProvisionalLoad" callback. + https://bugs.webkit.org/show_bug.cgi?id=47849 + + * DumpRenderTree/LayoutTestController.cpp: + (LayoutTestController::LayoutTestController): + (dumpUserGestureInFrameLoadCallbacksCallback): + (LayoutTestController::staticFunctions): + * DumpRenderTree/LayoutTestController.h: + (LayoutTestController::dumpUserGestureInFrameLoadCallbacks): + (LayoutTestController::setDumpUserGestureInFrameLoadCallbacks): + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::LayoutTestController): + (LayoutTestController::dumpUserGestureInFrameLoadCallbacks): + (LayoutTestController::reset): + * DumpRenderTree/chromium/LayoutTestController.h: + (LayoutTestController::shouldDumpUserGestureInFrameLoadCallbacks): + (LayoutTestController::setShouldDumpUserGestureInFrameLoadCallbacks): + * DumpRenderTree/chromium/TestShell.h: + (TestShell::shouldDumpUserGestureInFrameLoadCallbacks): + * DumpRenderTree/chromium/WebViewHost.cpp: + (WebViewHost::didStartProvisionalLoad): + (WebViewHost::printFrameUserGestureStatus): + * DumpRenderTree/chromium/WebViewHost.h: + * DumpRenderTree/mac/FrameLoadDelegate.mm: + (-[WebFrame _drt_printFrameUserGestureStatus]): + (-[FrameLoadDelegate webView:didStartProvisionalLoadForFrame:]): + (-[FrameLoadDelegate webView:didCommitLoadForFrame:]): + (-[FrameLoadDelegate webView:didFailProvisionalLoadWithError:forFrame:]): + (-[FrameLoadDelegate webView:didFinishLoadForFrame:]): + (-[FrameLoadDelegate webView:didFailLoadWithError:forFrame:]): + (-[FrameLoadDelegate webView:windowScriptObjectAvailable:]): + (-[FrameLoadDelegate webView:didReceiveTitle:forFrame:]): + * DumpRenderTree/qt/LayoutTestControllerQt.cpp: + (LayoutTestController::reset): + (LayoutTestController::dumpUserGestureInFrameLoadCallbacks): + * DumpRenderTree/qt/LayoutTestControllerQt.h: + +2010-10-25 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r70442. + http://trac.webkit.org/changeset/70442 + https://bugs.webkit.org/show_bug.cgi?id=48248 + + http locking doesn't work on Windows (Requested by Ossy on + #webkit). + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-10-25 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Ojan Vafai. + + Make http locking default in NRWT. + https://bugs.webkit.org/show_bug.cgi?id=48053 + + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + +2010-10-25 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/48185> build-webkit: add support for --progress-tag switch + (Re-landing r70413 after Qt minimal buildfix: r70440.) + + Reviewed by Kenneth Rohde Christiansen. + + * Scripts/build-webkit: Added support for --progress-tag switch. + It should have been added with r57051. + +2010-10-24 Adam Barth <abarth@webkit.org> + + Reviewed by David Kilzer. + + webkit-patch upload fails when the patch removes a file + https://bugs.webkit.org/show_bug.cgi?id=48187 + + We need to use "--" to separate file names from the rest of the + command. + + * Scripts/webkitpy/common/checkout/scm.py: + +2010-10-24 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r70413. + http://trac.webkit.org/changeset/70413 + https://bugs.webkit.org/show_bug.cgi?id=48210 + + It broke Qt minimal build (Requested by Ossy on #webkit). + + * Scripts/build-webkit: + +2010-10-24 Yi Shen <yi.4.shen@nokia.com> + + Reviewed by Andreas Kling. + + [Qt][QtTestBrowser] Toggle use of QGraphicsView messes up the menu + https://bugs.webkit.org/show_bug.cgi?id=48141 + + * QtTestBrowser/launcherwindow.cpp: + (LauncherWindow::init): + (LauncherWindow::initializeView): + (LauncherWindow::toggleWebView): + +2010-10-24 Daniel Bates <dbates@rim.com> + + Reviewed by David Kilzer. + + Fix Perl uninitialized warnings in VCSUtils::svnStatus() + and VCSUtils::removeEOL(). + https://bugs.webkit.org/show_bug.cgi?id=48196 + + VCSUtils::svnStatus() concatenates the output of svn status with + a new line character and svn status may return no output (say for + a file that has not been added, deleted, or modified). We should + only concatenate the output of svn status if there is some. + + Also, VCSUtils::removeEOL() should ensure that its argument + is initialized before performing a string substitution. + + * Scripts/VCSUtils.pm: + - Modified removeEOL() to return "" if its argument is undefined. + - Exported removeEOL() so that it can be tested. + * Scripts/webkitperl/VCSUtils_unittest/removeEOL.pl: Added. + +2010-10-24 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/48185> build-webkit: add support for --progress-tag switch + + Reviewed by Kenneth Rohde Christiansen. + + * Scripts/build-webkit: Added support for --progress-tag switch. + It should have been added with r57051. + +2010-10-24 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/48184> build-webkit: reformat support variables for better maintainability + + Reviewed by Daniel Bates. + + * Scripts/build-webkit: Alphabetized the @features array based + on the name of the feature. Reformatted the list of support + variables so that they match the order of @features, and so that + each has its own line. This makes it easy to add new variables + in the correct order. + +2010-10-23 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + EWS never removes invalid patch ids + https://bugs.webkit.org/show_bug.cgi?id=48173 + + This is just sticking another finger in the dam. + However this adds more unit testing which will help + us make sure we're always releasing patches once we + redesign the release_patch API and call these from + a more central place. + + * Scripts/webkitpy/tool/commands/queues.py: + * Scripts/webkitpy/tool/commands/queues_unittest.py: + * Scripts/webkitpy/tool/mocktool.py: + - Added the ability to request invalid patches. + Log a warning message to make sure we don't ever have + tests use invalid patch fetches by mistake. + +2010-10-23 Dan Bernstein <mitz@apple.com> + + Build fix. Add stub implementations for required NSDraggingInfo methods. + + * DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm: + (-[DumpRenderTreeDraggingInfo draggingFormation]): + (-[DumpRenderTreeDraggingInfo setDraggingFormation:]): + (-[DumpRenderTreeDraggingInfo animatesToDestination]): + (-[DumpRenderTreeDraggingInfo setAnimatesToDestination:]): + (-[DumpRenderTreeDraggingInfo numberOfValidItemsForDrop]): + (-[DumpRenderTreeDraggingInfo setNumberOfValidItemsForDrop:]): + (-[DumpRenderTreeDraggingInfo enumerateDraggingItemsWithOptions:forView:classes:searchOptions:usingBlock:]): + +2010-10-23 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/48186> Remove unneeded WebHTMLRepresentationInternal.h header + + Reviewed by Sam Weinig. + + The only method defined in WebHTMLRepresentationInternal.h is + also defined in WebHTMLRepresentation.h, so use that instead. + + * DumpRenderTree/mac/InternalHeaders/WebKit/WebHTMLRepresentationInternal.h: Removed. + * DumpRenderTree/mac/WebArchiveDumpSupport.mm: Switched to use + WebHTMLRepresentation.h. + +2010-10-23 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r70367. + http://trac.webkit.org/changeset/70367 + https://bugs.webkit.org/show_bug.cgi?id=48176 + + It made 8-10 tests crash on Qt bot (Requested by Ossy on + #webkit). + + * DumpRenderTree/LayoutTestController.cpp: + (setCustomPolicyDelegateCallback): + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setCustomPolicyDelegate): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setCustomPolicyDelegate): + * DumpRenderTree/mac/PolicyDelegate.h: + * DumpRenderTree/mac/PolicyDelegate.mm: + (-[PolicyDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]): + (-[PolicyDelegate setPermissive:]): + (-[PolicyDelegate setControllerToNotifyDone:]): + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setCustomPolicyDelegate): + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setCustomPolicyDelegate): + +2010-10-22 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + EWS never releases patches which fail to apply + https://bugs.webkit.org/show_bug.cgi?id=48171 + + * Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py: + * Scripts/webkitpy/tool/commands/queues.py: + +2010-10-22 Eric Seidel <eric@webkit.org> + + Unreviewed. + + Make the EWS queues restart themselves more often. + This matches the commit-queue. + + * EWSTools/start-queue.sh: + +2010-10-22 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + commit-queue should not pass --quiet to subcommands now that the parent command does the reporting + https://bugs.webkit.org/show_bug.cgi?id=48165 + + * Scripts/webkitpy/tool/bot/commitqueuetask.py: + * Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py: + * Scripts/webkitpy/tool/commands/queues_unittest.py: + +2010-10-22 Mario Sanchez Prada <msanchez@igalia.com> + + Adding myself as a committer. + + * Scripts/webkitpy/common/config/committers.py: + +2010-10-20 Anders Carlsson <andersca@apple.com> + + Reviewed by Adam Barth and Darin Adler. + + Using the decidePolicyForMIMEType delegate message in an asynchronous manner does not work + https://bugs.webkit.org/show_bug.cgi?id=48014 + <rdar://problem/8202716> + + * DumpRenderTree/LayoutTestController.cpp: + (setCustomPolicyDelegateCallback): + Add callIgnoreInDecidePolicyForMIMETypeAfterOneSecond argument. + + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setCustomPolicyDelegate): + Add callIgnoreInDecidePolicyForMIMETypeAfterOneSecond argument. + + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setCustomPolicyDelegate): + Add callIgnoreInDecidePolicyForMIMETypeAfterOneSecond argument. + + * DumpRenderTree/mac/PolicyDelegate.h: + * DumpRenderTree/mac/PolicyDelegate.mm: + (-[PolicyDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]): + If _callIgnoreInDecidePolicyForMIMETypeAfterOneSecond is true, call [listener ignore] after one second. + + (-[PolicyDelegate setCallIgnoreInDecidePolicyForMIMETypeAfterOneSecond:]): + Update _callIgnoreInDecidePolicyForMIMETypeAfterOneSecond. + + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setCustomPolicyDelegate): + Add callIgnoreInDecidePolicyForMIMETypeAfterOneSecond argument. + + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setCustomPolicyDelegate): + Add callIgnoreInDecidePolicyForMIMETypeAfterOneSecond argument. + +2010-10-22 Sam Weinig <sam@webkit.org> + + Reviewed by Anders Carlsson. + + Rename the InjectedBundle for TestWebKitAPI to InjectedBundleTestWebKitAPI.bundle + + * TestWebKitAPI/Configurations/InjectedBundle.xcconfig: + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: + * TestWebKitAPI/mac/PlatformUtilitiesMac.mm: + (TestWebKitAPI::Util::createInjectedBundlePath): + +2010-10-22 Dirk Pranke <dpranke@chromium.org> + + Reviewed by Eric Seidel. + + test-webkitpy fails when passed -v (or any other option) + + Fix port/base_unittest to pass an explicit list of arguments + rather than accidentally picking up sys.argv. + + https://bugs.webkit.org/show_bug.cgi?id=48071 + + * Scripts/webkitpy/layout_tests/port/base_unittest.py: + +2010-10-22 Brian Weinstein <bweinstein@apple.com> + + Windows build fix. Update the createNewPage callback to account for the new + arguments. + + * MiniBrowser/win/BrowserView.cpp: + (createNewPage): + +2010-10-22 Sam Weinig <sam@webkit.org> + + Reviewed by Anders Carlsson. + + WebKit2 needs to pass the current event modifier flags when requesting a new window + https://bugs.webkit.org/show_bug.cgi?id=48140 + + * MiniBrowser/mac/BrowserWindowController.m: + (createNewPage): + * WebKitTestRunner/TestController.cpp: + (WTR::createOtherPage): + Update for new signature for the WKPageCreateNewPageCallback. + +2010-10-22 Eric Seidel <eric@webkit.org> + + Unreviewed. Just adding a test case. + + The style-queue was not recognizing new patches. It turns + out I had fixed this in an earlier change, but just not + deployed to queues.webkit.org. As part of investigating why it + was broken, I wrote a test for my previous change which I'm now landing. + + * QueueStatusServer/model/queues_unittest.py: + +2010-10-22 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + EWS does not need to process obsolete patches + https://bugs.webkit.org/show_bug.cgi?id=48093 + + This was an easy change, but to test it I had to pipe + real Attachment objects into the queue testing system. + Doing so revealed a whole bunch of bugs in our unit tests, + which I fixed as part of this patch. + + * Scripts/webkitpy/tool/commands/earlywarningsystem.py: + - This is the actual code change. This will not reduce the + backlog in the EWS queues much, but it will make rejections + much quicker for obsolete patches or closed bugs. + * Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py: + - Test my new code. + - Used a real attachment object and got rid of MockPatch + - Shared code between the mac-ews and cr-mac-ews tests. + * Scripts/webkitpy/tool/commands/queues_unittest.py: + - Can't use MockPatch anymore. + - Removing MockPatch found more bugs here! + * Scripts/webkitpy/tool/commands/queuestest.py: + * Scripts/webkitpy/tool/commands/sheriffbot_unittest.py: + * Scripts/webkitpy/tool/mocktool.py: + - MockBugzilla should not be a "Mock" object. Right now tool.bugs() + is allowed, but wrong. Making it not a Mock will make tool.bugs() correctly fail. + +2010-10-22 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r70301. + http://trac.webkit.org/changeset/70301 + https://bugs.webkit.org/show_bug.cgi?id=48126 + + "Lang attribute layout tests failing" (Requested by satish on + #webkit). + + * DumpRenderTree/LayoutTestController.cpp: + (setMockSpeechInputResultCallback): + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/qt/LayoutTestControllerQt.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/qt/LayoutTestControllerQt.h: + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setMockSpeechInputResult): + +2010-10-22 Leandro Gracia Gil <leandrogracia@google.com> + + Reviewed by Jeremy Orlow. + + Added a second parameter to setMockSpeechInputResult for + the language used in speech input. + https://bugs.webkit.org/show_bug.cgi?id=47089 + + * DumpRenderTree/LayoutTestController.cpp: + (setMockSpeechInputResultCallback): + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/qt/LayoutTestControllerQt.h: + * DumpRenderTree/qt/LayoutTestControllerQt.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setMockSpeechInputResult): + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setMockSpeechInputResult): + +2010-10-21 MORITA Hajime <morrita@google.com> + + Reviewed by Kent Tamura. + + [Win][DRT] should have LayoutTestController.hasSpellingMarker() + https://bugs.webkit.org/show_bug.cgi?id=47885 + + - Implemented LayoutTestController.hasSpellingMarker(), + - Added fake spellcheck implementation. + + * DumpRenderTree/win/DumpRenderTree.cpp: + (main): + * DumpRenderTree/win/EditingDelegate.cpp: + (indexOfFirstWordCharacter): + (wordLength): + (EditingDelegate::checkSpellingOfString): + * DumpRenderTree/win/EditingDelegate.h: + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::hasSpellingMarker): + +2010-10-21 Mihai Parparita <mihaip@chromium.org> + + Unreviewed. Re-enable test that was mistakenly disabled by r67974. + + * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py: + +2010-10-21 Mihai Parparita <mihaip@chromium.org> + + Unreviewed fix for rebaseline-chromium-webkit-tests. + + Port.diff_image no longer has a tolerance parameter. Also, use + get_option('tolerance') which is safer if the options object doesn't + define a tolerance attribute (it doesn't for the one used in + rebaseline_chromium_webkit_tests). + + * Scripts/webkitpy/layout_tests/port/port_testcase.py: + * Scripts/webkitpy/layout_tests/port/webkit.py: + * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py: + +2010-10-21 Mihai Parparita <mihaip@chromium.org> + + Reviewed by Ojan Vafai. + + Add support for --tolerance in NRWT + https://bugs.webkit.org/show_bug.cgi?id=47959 + + Add support for the --tolerance flag in NRWT. The Port.diff_image + signature shouldn't need a tolerance parameter (it's not set per test), + just have ports that use it (currently only WebKitPort) read it from + the options object. + + * Scripts/webkitpy/layout_tests/port/chromium.py: + * Scripts/webkitpy/layout_tests/port/port_testcase.py: + * Scripts/webkitpy/layout_tests/port/test.py: + * Scripts/webkitpy/layout_tests/port/webkit.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py: + +2010-10-21 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + Add --suggest-reviewers option to upload to auto-suggest reviewers for your patch + https://bugs.webkit.org/show_bug.cgi?id=48088 + + This is a first-pass. Works, but we'll eventually + turn this on by default, refine the suggestion algorithm + and possibly move it to a different place in the upload step order. + + * Scripts/webkitpy/common/checkout/api.py: + * Scripts/webkitpy/tool/commands/download_unittest.py: + * Scripts/webkitpy/tool/commands/upload.py: + * Scripts/webkitpy/tool/commands/upload_unittest.py: + * Scripts/webkitpy/tool/mocktool.py: + * Scripts/webkitpy/tool/steps/__init__.py: + * Scripts/webkitpy/tool/steps/options.py: + +2010-10-21 Mario Sanchez Prada <msanchez@igalia.com> + + Reviewed by Chris Fleizach. + + [GTK] Segfault while testing accessibility/iframe-bastardization.html + https://bugs.webkit.org/show_bug.cgi?id=30123 + + Check m_element before actually using it to get the parent. + + * DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp: + (AccessibilityUIElement::parentElement): Add an extra check to + make sure m_element points to a valid value before actually using + it to get the parent. Also, assert ATK_IS_OBJECT(m_element). + +2010-10-21 Anders Carlsson <andersca@apple.com> + + Reviewed by Adam Roben. + + Crash evaluating JavaScript string that throws an exception + https://bugs.webkit.org/show_bug.cgi?id=48092 + <rdar://problem/8487657> + + Add a test that evaluates a JavaScript string that throws an exception and check that + the callback is called. + + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: + * TestWebKitAPI/Tests/WebKit2/EvaluateJavaScript.cpp: Added. + (TestWebKitAPI::didRunJavaScript): + (TestWebKitAPI::WebKit2_EvaluateJavaScript): + * TestWebKitAPI/win/TestWebKitAPI.vcproj: + +2010-10-21 Adam Roben <aroben@apple.com> + + Test that the plugin's HWND is invalidated when NPN_InvalidateRect is + called + + Test for <http://webkit.org/b/48086> <rdar://problem/8482944> + Silverlight doesn't repaint in WebKit2 + + Reviewed by Anders Carlsson. + + * DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp: + (PluginTest::NPN_InvalidateRect): Added. Calls through to the browser. + (executeScript): Added. Asks the browser to evaluate the script. + + (PluginTest::waitUntilDone): + (PluginTest::notifyDone): + Added. Calls through to layoutTestController. + + * DumpRenderTree/TestNetscapePlugIn/PluginTest.h: Added + * NPN_InvalidateRect and waitUntilDone/notifyDone. + + * DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp: Added. + (TemporaryWindowMover::moveSucceeded): + (TemporaryWindowMover::TemporaryWindowMover): + (TemporaryWindowMover::~TemporaryWindowMover): + This class moves a window on-screen and shows it, then moves it back and hides it. + + (NPNInvalidateRectInvalidatesWindow::NPNInvalidateRectInvalidatesWindow): + Initialize our members. + (NPNInvalidateRectInvalidatesWindow::~NPNInvalidateRectInvalidatesWindow): + Delete our window mover if it hasn't been deleted already. + (NPNInvalidateRectInvalidatesWindow::NPP_SetWindow): Subclass the + plugin HWND and move the test harness window on screen. + (NPNInvalidateRectInvalidatesWindow::wndProc): Call through to onPaint + when we get a WM_PAINT message. + (NPNInvalidateRectInvalidatesWindow::onPaint): Do the test and tell + LayoutTestController we're done. + (NPNInvalidateRectInvalidatesWindow::testInvalidateRect): Validate + ourselves, invalidate our lower-right quadrant via NPN_InvalidateRect, + then check that our HWND's invalid region is the rect that we + invalidated. + + * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj: + * Added NPNInvalidateRectInvalidatesWindow. + +2010-10-21 Daniel Bates <dbates@rim.com> + + Add Git-support to do-file-rename + https://bugs.webkit.org/show_bug.cgi?id=48015 + + Fix tools. Export function scmMoveOrRenameFile so that it can be called from + do-file-rename and do-webcore-rename. I inadvertently left this out of the patch. + + * Scripts/VCSUtils.pm: + +2010-10-21 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + mac-ews is not properly releasing patches + https://bugs.webkit.org/show_bug.cgi?id=48076 + + mac-ews overrides process_work_item, so it was not calling + release_work_item like the default process_work_item would. + To fix this I made all the status-reporting methods just + release the patch. I expect we'll iterate on this design further. + + * Scripts/webkitpy/common/net/statusserver.py: + * Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py: + * Scripts/webkitpy/tool/commands/queues.py: + * Scripts/webkitpy/tool/commands/queues_unittest.py: + +2010-10-18 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Gustavo Noronha Silva. + + [GTK] mathml flaky tests after adding SystemFonts to the theme + https://bugs.webkit.org/show_bug.cgi?id=47727 + + The Fontconfig setup in the GTK+ now specifically checks for and + loads the STIX fonts for MathML tests. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (initializeFonts): Add hooks for loading the STIX fonts specifically. + +2010-10-20 Adam Roben <aroben@apple.com> + + Test that the UI client gets notified when WKView receives a WM_CLOSE + message + + Test for <http://webkit.org/b/48044> <rdar://problem/8488446> Pressing + Ctrl+W when viewing a full-page PDF destroys the WKView but doesn't + close its parent window + + Reviewed by Jon Honeycutt. + + * TestWebKitAPI/Tests/WebKit2/win/WMCloseCallsUIClientClose.cpp: Added. + (TestWebKitAPI::close): Record that this function was called. + (TestWebKitAPI::WebKit2_WMCloseCallsUIClientClose): Create a WKView, + send it a WM_CLOSE message, and test that the UI client's close + callback got called. Note that this will hang if the bug is + reintroduced; <http://webkit.org/b/48043> covers making TestWebKitAPI + able to handle hangs. + + * TestWebKitAPI/win/TestWebKitAPI.vcproj: Added the new test. + +2010-10-20 Adam Roben <aroben@apple.com> + + Make prepare-ChangeLog much faster when using git + + This change also seems to make it detect renames better in some cases. + + Fixes <http://webkit.org/b/48040> prepare-ChangeLog is slow when using + git + + Reviewed by David Kilzer. + + * Scripts/prepare-ChangeLog: + (statusCommand): + (createPatchCommand): + Use "-M -C" instead of "-C -C -M" to tell git-diff to detect renames + and copies. The two "-C"s were making it read many more files than were + necessary. + +2010-10-21 Sam Weinig <sam@webkit.org> + + Reviewed by Adam Roben. + + Null frame passed when running alert from UserScript run at document start + <rdar://problem/8573809> + https://bugs.webkit.org/show_bug.cgi?id=48036 + + * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: + * TestWebKitAPI/InjectedBundleController.cpp: + (TestWebKitAPI::InjectedBundleController::didReceiveMessage): + (TestWebKitAPI::InjectedBundleController::initializeTestNamed): + * TestWebKitAPI/InjectedBundleController.h: + * TestWebKitAPI/InjectedBundleTest.h: + (TestWebKitAPI::InjectedBundleTest::initialize): + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: + * TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash.cpp: Added. + (TestWebKitAPI::runJavaScriptAlert): + (TestWebKitAPI::TEST): + * TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp: Added. + (TestWebKitAPI::DocumentStartUserScriptAlertCrashTest::DocumentStartUserScriptAlertCrashTest): + (TestWebKitAPI::DocumentStartUserScriptAlertCrashTest::initialize): + Add test for invoking an alert during a UserScript run at document start. + +2010-10-21 Andreas Kling <kling@webkit.org> + + Reviewed by Adam Roben. + + TestNetscapePlugIn: Actually call NPP_SetWindow on Unix + + We were just returning NPERR_NO_ERROR previously. + + * DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp: + (webkit_test_plugin_set_window): + +2010-10-21 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/48051> Move macros from DumpRenderTreeMac.h to config.h + + Reviewed by Adam Roben. + + * DumpRenderTree/config.h: Moved macros to here... + * DumpRenderTree/mac/DumpRenderTreeMac.h: ...from here. + Addresses a FIXME comment from r28419. + +2010-10-21 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/48047> Fix warnings found by check-Xcode-source-file-types + + Reviewed by Adam Roben. + + Fixes the following warnings: + + WARNING: Incorrect file type 'sourcecode.cpp.objcpp' for file 'PixelDumpSupport.cpp'. + WARNING: Incorrect file type 'sourcecode.cpp.objcpp' for file 'LayoutTestController.cpp'. + WARNING: Incorrect file type 'sourcecode.cpp.objcpp' for file 'WorkQueue.cpp'. + WARNING: Incorrect file type 'sourcecode.cpp.objcpp' for file 'cg/PixelDumpSupportCG.cpp'. + WARNING: Incorrect file type 'sourcecode.cpp.objcpp' for file 'GCController.cpp'. + 5 issues found for WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj. + + * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: + Removed explicit file type for *.cpp files above to make them + match other C++ source files. This exposed the fact that + DumpRenderTreeMac.h was not safe to include in C++ source, which + caused PixelDumpSupport.cpp and PixelDumpSupportCG.cpp to fail + to build. + * DumpRenderTree/PixelDumpSupport.cpp: Adjusted header order. + * DumpRenderTree/mac/DumpRenderTreeMac.h: Made safe to include + in C++ source files. Included CoreFoundation/CoreFoundation.h + to make sure all CF types were defined. Removed CFStringRef + typedef. + +2010-10-21 Adam Roben <aroben@apple.com> + + Attempt to fix plugins/pass-different-npp-struct.html on GTK. + + See <http://webkit.org/b/47690>. + + * GNUmakefile.am: Added PassDifferentNPPStruct.cpp. + +2010-10-21 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Csaba Osztrogonác. + + [NRWT] Set ImageDiff path on Qt port + https://bugs.webkit.org/show_bug.cgi?id=48052 + + * Scripts/webkitpy/layout_tests/port/qt.py: + +2010-10-21 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Don't CC authors of flaky tests + https://bugs.webkit.org/show_bug.cgi?id=48038 + + Some authors found this too annoying. We'll look for another way to + close the flaky test loop. + + * Scripts/webkitpy/tool/commands/queues.py: + * Scripts/webkitpy/tool/commands/queues_unittest.py: + +2010-10-21 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + commit-queue should run run-webkit-tests with --no-new-test-results + https://bugs.webkit.org/show_bug.cgi?id=47998 + + * Scripts/webkitpy/tool/steps/runtests.py: + * Scripts/webkitpy/tool/steps/steps_unittest.py: + +2010-10-21 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu> + + Reviewed by Ojan Vafai. + + [NRWT] Get child process number from an environment variable + https://bugs.webkit.org/show_bug.cgi?id=47981 + + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + 2010-10-20 David Kilzer <ddkilzer@apple.com> <http://webkit.org/b/47754> New script to verify explicit source file types in Xcode project files @@ -30,8 +2112,8 @@ Reviewed by Adam Roben. - https://bugs.webkit.org/show_bug.cgi?id=48027 Add ability to test injected bundle API using TestWebKitAPI + https://bugs.webkit.org/show_bug.cgi?id=48027 * TestWebKitAPI/InjectedBundleController.cpp: Added. * TestWebKitAPI/InjectedBundleController.h: Added. @@ -218,7 +2300,7 @@ * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: (LayoutTestController::setMockSpeechInputResult): -2010-10-19 Leandro Gracia Gil <leandrogracia@google.com> +2010-10-20 Leandro Gracia Gil <leandrogracia@google.com> Reviewed by Jeremy Orlow. diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp index 52d238d..87be335 100644 --- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp +++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp @@ -204,6 +204,15 @@ static JSValueRef childAtIndexCallback(JSContextRef context, JSObjectRef functio return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->getChildAtIndex(indexNumber)); } +static JSValueRef selectedChildAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + int indexNumber = -1; + if (argumentCount == 1) + indexNumber = JSValueToNumber(context, arguments[0], exception); + + return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->selectedChildAtIndex(indexNumber)); +} + static JSValueRef linkedUIElementAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { int indexNumber = -1; @@ -260,6 +269,17 @@ static JSValueRef isEqualCallback(JSContextRef context, JSObjectRef function, JS return JSValueMakeBoolean(context, toAXElement(thisObject)->isEqual(toAXElement(otherElement))); } +static JSValueRef setSelectedChildCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + JSObjectRef element = 0; + if (argumentCount == 1) + element = JSValueToObject(context, arguments[0], exception); + + toAXElement(thisObject)->setSelectedChild(toAXElement(element)); + + return JSValueMakeUndefined(context); +} + static JSValueRef elementAtPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { int x = 0; @@ -695,6 +715,11 @@ static JSValueRef speakCallback(JSContextRef context, JSObjectRef thisObject, JS return JSValueMakeString(context, speakString.get()); } +static JSValueRef selectedChildrenCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + return JSValueMakeNumber(context, toAXElement(thisObject)->selectedChildrenCount()); +} + static JSValueRef getHasPopupCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*) { return JSValueMakeBoolean(context, toAXElement(thisObject)->hasPopup()); @@ -757,6 +782,9 @@ static JSValueRef removeNotificationListenerCallback(JSContextRef context, JSObj #if !PLATFORM(MAC) JSStringRef AccessibilityUIElement::speak() { return 0; } JSStringRef AccessibilityUIElement::rangeForLine(int line) { return 0; } +void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement*) const { } +unsigned AccessibilityUIElement::selectedChildrenCount() const { return 0; } +AccessibilityUIElement AccessibilityUIElement::selectedChildAtIndex(unsigned) const { return 0; } #endif #if !SUPPORTS_AX_TEXTMARKERS @@ -860,6 +888,7 @@ JSClassRef AccessibilityUIElement::getJSClass() { "ariaDropEffects", getARIADropEffectsCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "isIgnored", isIgnoredCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "speak", speakCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "selectedChildrenCount", selectedChildrenCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { 0, 0, 0, 0 } }; @@ -920,6 +949,8 @@ JSClassRef AccessibilityUIElement::getJSClass() { "accessibilityElementForTextMarker", accessibilityElementForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "textMarkerRangeLength", textMarkerRangeLengthCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "textMarkerForPoint", textMarkerForPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setSelectedChild", setSelectedChildCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "selectedChildAtIndex", selectedChildAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { 0, 0, 0 } }; diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h index 9311dfd..3120e65 100644 --- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h +++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h @@ -130,9 +130,14 @@ public: JSStringRef selectedTextRange(); bool isEnabled(); bool isRequired() const; + bool isSelected() const; bool isSelectable() const; bool isMultiSelectable() const; + void setSelectedChild(AccessibilityUIElement*) const; + unsigned selectedChildrenCount() const; + AccessibilityUIElement selectedChildAtIndex(unsigned) const; + bool isExpanded() const; bool isChecked() const; bool isVisible() const; diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj index 51d8e7f..bf0aebf 100644 --- a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj +++ b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj @@ -48,7 +48,8 @@ 29CFBA2E12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29CFBA2D12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm */; }; 3713EDE2115BE19300705720 /* ColorBits-A.png in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 3713EDDF115BE16F00705720 /* ColorBits-A.png */; }; 3713EDE3115BE19300705720 /* ColorBits.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 3713EDE0115BE16F00705720 /* ColorBits.ttf */; }; - 4437730E125CBC3600AAE02C /* WebArchiveDumpSupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = 44A997830FCDE86400580F10 /* WebArchiveDumpSupport.mm */; }; + 440590711268453800CFD48D /* WebArchiveDumpSupportMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 440590701268453800CFD48D /* WebArchiveDumpSupportMac.mm */; }; + 4437730E125CBC3600AAE02C /* WebArchiveDumpSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 44A997830FCDE86400580F10 /* WebArchiveDumpSupport.cpp */; }; 4437730F125CBC4D00AAE02C /* WebArchiveDumpSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 44A997820FCDE86400580F10 /* WebArchiveDumpSupport.h */; }; 5185F6B210714E07007AA393 /* HistoryDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5185F69F10714A57007AA393 /* HistoryDelegate.mm */; }; 5185F6B310714E12007AA393 /* HistoryDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5185F69E10714A57007AA393 /* HistoryDelegate.h */; }; @@ -131,6 +132,7 @@ BCD08B710E1059D200A7D0C1 /* AccessibilityControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */; }; BCF6C6500C98E9C000AC063E /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF6C64F0C98E9C000AC063E /* GCController.cpp */; }; C06F9ABC1267A7060058E1F6 /* PassDifferentNPPStruct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C06F9ABB1267A7060058E1F6 /* PassDifferentNPPStruct.cpp */; }; + C0EC3C9C12787F0500939164 /* NullNPPGetValuePointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */; }; E1B7816511AF31B7007E1BC2 /* MockGeolocationProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */; }; E1B7816711AF31C3007E1BC2 /* MockGeolocationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = E1B7808511AF1643007E1BC2 /* MockGeolocationProvider.h */; }; /* End PBXBuildFile section */ @@ -223,11 +225,12 @@ 375F09770DAC3CB600C8B4E5 /* WebKitWeightWatcher700.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher700.ttf; path = fonts/WebKitWeightWatcher700.ttf; sourceTree = "<group>"; }; 375F09780DAC3CB600C8B4E5 /* WebKitWeightWatcher800.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher800.ttf; path = fonts/WebKitWeightWatcher800.ttf; sourceTree = "<group>"; }; 375F09790DAC3CB600C8B4E5 /* WebKitWeightWatcher900.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher900.ttf; path = fonts/WebKitWeightWatcher900.ttf; sourceTree = "<group>"; }; - 44A997820FCDE86400580F10 /* WebArchiveDumpSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebArchiveDumpSupport.h; path = mac/WebArchiveDumpSupport.h; sourceTree = "<group>"; }; - 44A997830FCDE86400580F10 /* WebArchiveDumpSupport.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebArchiveDumpSupport.mm; path = mac/WebArchiveDumpSupport.mm; sourceTree = "<group>"; }; + 440590701268453800CFD48D /* WebArchiveDumpSupportMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebArchiveDumpSupportMac.mm; path = mac/WebArchiveDumpSupportMac.mm; sourceTree = "<group>"; }; + 44A997820FCDE86400580F10 /* WebArchiveDumpSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebArchiveDumpSupport.h; path = cf/WebArchiveDumpSupport.h; sourceTree = "<group>"; }; + 44A997830FCDE86400580F10 /* WebArchiveDumpSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebArchiveDumpSupport.cpp; path = cf/WebArchiveDumpSupport.cpp; sourceTree = "<group>"; }; 5185F69E10714A57007AA393 /* HistoryDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryDelegate.h; path = mac/HistoryDelegate.h; sourceTree = "<group>"; }; 5185F69F10714A57007AA393 /* HistoryDelegate.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = HistoryDelegate.mm; path = mac/HistoryDelegate.mm; sourceTree = "<group>"; }; - 8465E2C60FFA8DF2003B8342 /* PixelDumpSupport.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = PixelDumpSupport.cpp; sourceTree = "<group>"; }; + 8465E2C60FFA8DF2003B8342 /* PixelDumpSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PixelDumpSupport.cpp; sourceTree = "<group>"; }; 9335435F03D75502008635CE /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 933BF5A90F93FA5C000F0441 /* PlainTextController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlainTextController.h; path = mac/PlainTextController.h; sourceTree = "<group>"; }; 933BF5AA0F93FA5C000F0441 /* PlainTextController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PlainTextController.mm; path = mac/PlainTextController.mm; sourceTree = "<group>"; }; @@ -247,14 +250,14 @@ AE8257EF08D22389000507AB /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; }; B5A7526708AF4A4A00138E45 /* ImageDiff */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ImageDiff; sourceTree = BUILT_PRODUCTS_DIR; }; B5A752A108AF5D1F00138E45 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; }; - BC0131D80C9772010087317D /* LayoutTestController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = LayoutTestController.cpp; sourceTree = "<group>"; }; + BC0131D80C9772010087317D /* LayoutTestController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutTestController.cpp; sourceTree = "<group>"; }; BC0131D90C9772010087317D /* LayoutTestController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LayoutTestController.h; sourceTree = "<group>"; }; BC0E24DE0E2D9451001B6BC2 /* AccessibilityUIElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityUIElement.h; sourceTree = "<group>"; }; BC0E24DF0E2D9451001B6BC2 /* AccessibilityUIElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityUIElement.cpp; sourceTree = "<group>"; }; BC0E26140E2DA4C6001B6BC2 /* AccessibilityUIElementMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityUIElementMac.mm; path = mac/AccessibilityUIElementMac.mm; sourceTree = "<group>"; }; BC4741290D038A4C0072B006 /* JavaScriptThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptThreading.h; sourceTree = "<group>"; }; BC4741400D038A570072B006 /* JavaScriptThreadingPthreads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JavaScriptThreadingPthreads.cpp; path = pthreads/JavaScriptThreadingPthreads.cpp; sourceTree = "<group>"; }; - BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = WorkQueue.cpp; sourceTree = "<group>"; }; + BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = WorkQueue.cpp; sourceTree = "<group>"; }; BC9D90220C97472E0099A4A3 /* WorkQueue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WorkQueue.h; sourceTree = "<group>"; }; BC9D90230C97472E0099A4A3 /* WorkQueueItem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WorkQueueItem.h; sourceTree = "<group>"; }; BCA18B210C9B014B00114369 /* GCControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = GCControllerMac.mm; path = mac/GCControllerMac.mm; sourceTree = "<group>"; }; @@ -293,7 +296,7 @@ BCB282F40CFA7450007E533E /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = DebugRelease.xcconfig; path = mac/Configurations/DebugRelease.xcconfig; sourceTree = "<group>"; }; BCB283D80CFA7AFD007E533E /* ImageDiff.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = ImageDiff.xcconfig; path = mac/Configurations/ImageDiff.xcconfig; sourceTree = "<group>"; }; BCB283DE0CFA7C20007E533E /* TestNetscapePlugIn.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = TestNetscapePlugIn.xcconfig; path = mac/Configurations/TestNetscapePlugIn.xcconfig; sourceTree = "<group>"; }; - BCB284880CFA8202007E533E /* PixelDumpSupportCG.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; name = PixelDumpSupportCG.cpp; path = cg/PixelDumpSupportCG.cpp; sourceTree = "<group>"; }; + BCB284880CFA8202007E533E /* PixelDumpSupportCG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PixelDumpSupportCG.cpp; path = cg/PixelDumpSupportCG.cpp; sourceTree = "<group>"; }; BCB284890CFA8202007E533E /* PixelDumpSupportCG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PixelDumpSupportCG.h; path = cg/PixelDumpSupportCG.h; sourceTree = "<group>"; }; BCB2848A0CFA820F007E533E /* PixelDumpSupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PixelDumpSupport.h; sourceTree = "<group>"; }; BCB2848C0CFA8221007E533E /* PixelDumpSupportMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = PixelDumpSupportMac.mm; path = mac/PixelDumpSupportMac.mm; sourceTree = "<group>"; }; @@ -302,8 +305,9 @@ BCD08A580E10496B00A7D0C1 /* AccessibilityController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityController.h; sourceTree = "<group>"; }; BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityController.cpp; sourceTree = "<group>"; }; BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityControllerMac.mm; path = mac/AccessibilityControllerMac.mm; sourceTree = "<group>"; }; - BCF6C64F0C98E9C000AC063E /* GCController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = GCController.cpp; sourceTree = "<group>"; }; + BCF6C64F0C98E9C000AC063E /* GCController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GCController.cpp; sourceTree = "<group>"; }; C06F9ABB1267A7060058E1F6 /* PassDifferentNPPStruct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PassDifferentNPPStruct.cpp; sourceTree = "<group>"; }; + C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullNPPGetValuePointer.cpp; sourceTree = "<group>"; }; E1B7808511AF1643007E1BC2 /* MockGeolocationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MockGeolocationProvider.h; path = mac/MockGeolocationProvider.h; sourceTree = "<group>"; }; E1B7808711AF1669007E1BC2 /* MockGeolocationProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MockGeolocationProvider.mm; path = mac/MockGeolocationProvider.mm; sourceTree = "<group>"; }; /* End PBXFileReference section */ @@ -365,7 +369,8 @@ A8D79CE80FC28B2C004AC8FE /* DumpRenderTreeFileDraggingSource.h */, A8D79CE90FC28B2C004AC8FE /* DumpRenderTreeFileDraggingSource.m */, 44A997820FCDE86400580F10 /* WebArchiveDumpSupport.h */, - 44A997830FCDE86400580F10 /* WebArchiveDumpSupport.mm */, + 44A997830FCDE86400580F10 /* WebArchiveDumpSupport.cpp */, + 440590701268453800CFD48D /* WebArchiveDumpSupportMac.mm */, BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */, BC9D90220C97472E0099A4A3 /* WorkQueue.h */, BC9D90230C97472E0099A4A3 /* WorkQueueItem.h */, @@ -459,6 +464,7 @@ 1A215A7511F26072008AD0F5 /* DocumentOpenInDestroyStream.cpp */, 1A24BAA8120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp */, 1AC77DCE120605B6005C19EF /* NPRuntimeRemoveProperty.cpp */, + C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */, C06F9ABB1267A7060058E1F6 /* PassDifferentNPPStruct.cpp */, 1AD9D2FD12028409001A70D1 /* PluginScriptableNPObjectInvokeDefault.cpp */, ); @@ -697,7 +703,14 @@ isa = PBXProject; buildConfigurationList = 149C29C308902C6D008A9EFC /* Build configuration list for PBXProject "DumpRenderTree" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 08FB7794FE84155DC02AAC07 /* DumpRenderTree */; productRefGroup = 9340995508540CAF007F3BC8 /* Products */; projectDirPath = ""; @@ -737,6 +750,7 @@ 1AC77DCF120605B6005C19EF /* NPRuntimeRemoveProperty.cpp in Sources */, 1A24BAA9120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp in Sources */, C06F9ABC1267A7060058E1F6 /* PassDifferentNPPStruct.cpp in Sources */, + C0EC3C9C12787F0500939164 /* NullNPPGetValuePointer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -775,7 +789,8 @@ BCA18B680C9B08C200114369 /* ResourceLoadDelegate.mm in Sources */, BCA18B490C9B02C400114369 /* TextInputController.m in Sources */, BCA18B6A0C9B08C200114369 /* UIDelegate.mm in Sources */, - 4437730E125CBC3600AAE02C /* WebArchiveDumpSupport.mm in Sources */, + 4437730E125CBC3600AAE02C /* WebArchiveDumpSupport.cpp in Sources */, + 440590711268453800CFD48D /* WebArchiveDumpSupportMac.mm in Sources */, BC9D90240C97472E0099A4A3 /* WorkQueue.cpp in Sources */, BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */, 5185F6B210714E07007AA393 /* HistoryDelegate.mm in Sources */, diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/LayoutTestController.cpp index b5cc874..9619389 100644 --- a/WebKitTools/DumpRenderTree/LayoutTestController.cpp +++ b/WebKitTools/DumpRenderTree/LayoutTestController.cpp @@ -51,6 +51,7 @@ LayoutTestController::LayoutTestController(const std::string& testPathOrURL, con , m_dumpDatabaseCallbacks(false) , m_dumpEditingCallbacks(false) , m_dumpFrameLoadCallbacks(false) + , m_dumpUserGestureInFrameLoadCallbacks(false) , m_dumpHistoryDelegateCallbacks(false) , m_dumpResourceLoadCallbacks(false) , m_dumpResourceResponseMIMETypes(false) @@ -167,6 +168,13 @@ static JSValueRef dumpFrameLoadCallbacksCallback(JSContextRef context, JSObjectR return JSValueMakeUndefined(context); } +static JSValueRef dumpUserGestureInFrameLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setDumpUserGestureInFrameLoadCallbacks(true); + return JSValueMakeUndefined(context); +} + static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); @@ -1070,14 +1078,17 @@ static JSValueRef setMockGeolocationErrorCallback(JSContextRef context, JSObject static JSValueRef setMockSpeechInputResultCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { - if (argumentCount < 1) + if (argumentCount < 2) return JSValueMakeUndefined(context); JSRetainPtr<JSStringRef> result(Adopt, JSValueToStringCopy(context, arguments[0], exception)); ASSERT(!*exception); + JSRetainPtr<JSStringRef> language(Adopt, JSValueToStringCopy(context, arguments[1], exception)); + ASSERT(!*exception); + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); - controller->setMockSpeechInputResult(result.get()); + controller->setMockSpeechInputResult(result.get(), language.get()); return JSValueMakeUndefined(context); } @@ -1889,6 +1900,7 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "dumpUserGestureInFrameLoadCallbacks", dumpUserGestureInFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpResourceResponseMIMETypes", dumpResourceResponseMIMETypesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.h b/WebKitTools/DumpRenderTree/LayoutTestController.h index 689e114..b61860b 100644 --- a/WebKitTools/DumpRenderTree/LayoutTestController.h +++ b/WebKitTools/DumpRenderTree/LayoutTestController.h @@ -94,7 +94,7 @@ public: void setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma); void setMockGeolocationError(int code, JSStringRef message); void setMockGeolocationPosition(double latitude, double longitude, double accuracy); - void setMockSpeechInputResult(JSStringRef result); + void setMockSpeechInputResult(JSStringRef result, JSStringRef language); void setPersistentUserStyleSheetLocation(JSStringRef path); void setPluginsEnabled(bool flag); void setPopupBlockingEnabled(bool flag); @@ -154,6 +154,9 @@ public: bool dumpFrameLoadCallbacks() const { return m_dumpFrameLoadCallbacks; } void setDumpFrameLoadCallbacks(bool dumpFrameLoadCallbacks) { m_dumpFrameLoadCallbacks = dumpFrameLoadCallbacks; } + + bool dumpUserGestureInFrameLoadCallbacks() const { return m_dumpUserGestureInFrameLoadCallbacks; } + void setDumpUserGestureInFrameLoadCallbacks(bool dumpUserGestureInFrameLoadCallbacks) { m_dumpUserGestureInFrameLoadCallbacks = dumpUserGestureInFrameLoadCallbacks; } bool dumpHistoryDelegateCallbacks() const { return m_dumpHistoryDelegateCallbacks; } void setDumpHistoryDelegateCallbacks(bool dumpHistoryDelegateCallbacks) { m_dumpHistoryDelegateCallbacks = dumpHistoryDelegateCallbacks; } @@ -311,6 +314,7 @@ private: bool m_dumpDatabaseCallbacks; bool m_dumpEditingCallbacks; bool m_dumpFrameLoadCallbacks; + bool m_dumpUserGestureInFrameLoadCallbacks; bool m_dumpHistoryDelegateCallbacks; bool m_dumpResourceLoadCallbacks; bool m_dumpResourceResponseMIMETypes; diff --git a/WebKitTools/DumpRenderTree/PixelDumpSupport.cpp b/WebKitTools/DumpRenderTree/PixelDumpSupport.cpp index b5a5146..352eaaa 100644 --- a/WebKitTools/DumpRenderTree/PixelDumpSupport.cpp +++ b/WebKitTools/DumpRenderTree/PixelDumpSupport.cpp @@ -27,9 +27,10 @@ */ #include "config.h" +#include "PixelDumpSupport.h" + #include "DumpRenderTree.h" #include "LayoutTestController.h" -#include "PixelDumpSupport.h" #include <cstdio> #include <wtf/Assertions.h> #include <wtf/RefPtr.h> diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp index 1df1c76..db73a9d 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp @@ -103,6 +103,7 @@ static NPObject* pluginAllocate(NPP npp, NPClass*); static void pluginDeallocate(NPObject*); NPNetscapeFuncs* browser; +NPPluginFuncs* pluginFunctions; static NPClass pluginClass = { NP_CLASS_STRUCT_VERSION, diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h index 6c30578..99d5bf6 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h @@ -38,6 +38,7 @@ class PluginTest; extern NPNetscapeFuncs *browser; +extern NPPluginFuncs* pluginFunctions; typedef struct { NPObject header; diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp index d435a2e..e41e6e5 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp @@ -26,6 +26,7 @@ #include "PluginTest.h" #include <assert.h> +#include <string.h> using namespace std; extern NPNetscapeFuncs *browser; @@ -49,6 +50,11 @@ PluginTest::~PluginTest() { } +NPError PluginTest::NPP_Destroy(NPSavedData**) +{ + return NPERR_NO_ERROR; +} + NPError PluginTest::NPP_DestroyStream(NPStream *stream, NPReason reason) { return NPERR_NO_ERROR; @@ -65,6 +71,11 @@ NPError PluginTest::NPP_SetWindow(NPP, NPWindow*) return NPERR_NO_ERROR; } +void PluginTest::NPN_InvalidateRect(NPRect* invalidRect) +{ + browser->invalidaterect(m_npp, invalidRect); +} + NPIdentifier PluginTest::NPN_GetStringIdentifier(const NPUTF8 *name) { return browser->getstringidentifier(name); @@ -90,6 +101,30 @@ bool PluginTest::NPN_RemoveProperty(NPObject* npObject, NPIdentifier propertyNam return browser->removeproperty(m_npp, npObject, propertyName); } +static void executeScript(NPP npp, const char* script) +{ + NPObject* windowScriptObject; + browser->getvalue(npp, NPNVWindowNPObject, &windowScriptObject); + + NPString npScript; + npScript.UTF8Characters = script; + npScript.UTF8Length = strlen(script); + + NPVariant browserResult; + browser->evaluate(npp, windowScriptObject, &npScript, &browserResult); + browser->releasevariantvalue(&browserResult); +} + +void PluginTest::waitUntilDone() +{ + executeScript(m_npp, "layoutTestController.waitUntilDone()"); +} + +void PluginTest::notifyDone() +{ + executeScript(m_npp, "layoutTestController.notifyDone()"); +} + void PluginTest::registerCreateTestFunction(const string& identifier, CreateTestFunction createTestFunction) { assert(!createTestFunctions().count(identifier)); diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h index cbc7934..0497764 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h @@ -55,11 +55,13 @@ public: virtual ~PluginTest(); // NPP functions. + virtual NPError NPP_Destroy(NPSavedData**); virtual NPError NPP_DestroyStream(NPStream* stream, NPReason reason); virtual NPError NPP_GetValue(NPPVariable, void* value); virtual NPError NPP_SetWindow(NPP, NPWindow*); // NPN functions. + void NPN_InvalidateRect(NPRect* invalidRect); NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name); NPIdentifier NPN_GetIntIdentifier(int32_t intid); NPError NPN_GetValue(NPNVariable, void* value); @@ -88,6 +90,9 @@ protected: const std::string& identifier() const { return m_identifier; } + void waitUntilDone(); + void notifyDone(); + // NPObject helper template. template<typename T> struct Object : NPObject { public: diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp new file mode 100644 index 0000000..9e4e976 --- /dev/null +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PluginTest.h" + +#include "PluginObject.h" + +using namespace std; + +// Passing null for our NPP_GetValue function pointer should not crash. + +class NullNPPGetValuePointer : public PluginTest { +public: + NullNPPGetValuePointer(NPP, const string& identifier); + +private: + virtual NPError NPP_Destroy(NPSavedData**); + virtual NPError NPP_GetValue(NPPVariable, void* value); + + NPP_GetValueProcPtr m_originalNPPGetValuePointer; +}; + +static PluginTest::Register<NullNPPGetValuePointer> registrar("null-npp-getvalue-pointer"); + +NullNPPGetValuePointer::NullNPPGetValuePointer(NPP npp, const string& identifier) + : PluginTest(npp, identifier) + , m_originalNPPGetValuePointer(pluginFunctions->getvalue) +{ + // Be sneaky and null out the getvalue pointer the browser is holding. This simulates a plugin + // that doesn't implement NPP_GetValue (like Shockwave Director 10.3 on Windows). Note that if + // WebKit copies the NPPluginFuncs struct this technique will have no effect and WebKit will + // call into our NPP_GetValue implementation. + pluginFunctions->getvalue = 0; +} + +NPError NullNPPGetValuePointer::NPP_Destroy(NPSavedData**) +{ + // Set the NPP_GetValue pointer back the way it was before we mucked with it so we don't mess + // up future uses of the plugin module. + pluginFunctions->getvalue = m_originalNPPGetValuePointer; + return NPERR_NO_ERROR; +} + +NPError NullNPPGetValuePointer::NPP_GetValue(NPPVariable, void*) +{ + pluginLog(m_npp, "NPP_GetValue was called but should not have been. Maybe WebKit copied the NPPluginFuncs struct, which would invalidate this test."); + return NPERR_GENERIC_ERROR; +} diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp new file mode 100644 index 0000000..90ea54d --- /dev/null +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/win/NPNInvalidateRectInvalidatesWindow.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PluginTest.h" + +#include "PluginObject.h" + +using namespace std; + +// NPN_InvalidateRect should invalidate the plugin's HWND. + +static const wchar_t instancePointerProperty[] = L"org.webkit.TestNetscapePlugin.NPNInvalidateRectInvalidatesWindow.InstancePointer"; + +class TemporaryWindowMover { +public: + TemporaryWindowMover(HWND); + ~TemporaryWindowMover(); + + bool moveSucceeded() const { return m_moveSucceeded; } + +private: + static const UINT standardSetWindowPosFlags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER; + bool m_moveSucceeded; + HWND m_window; + RECT m_savedWindowRect; +}; + +TemporaryWindowMover::TemporaryWindowMover(HWND window) + : m_window(window) +{ + m_moveSucceeded = false; + + if (!::GetWindowRect(m_window, &m_savedWindowRect)) + return; + + if (!::SetWindowPos(m_window, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | standardSetWindowPosFlags)) + return; + + m_moveSucceeded = true; +}; + +TemporaryWindowMover::~TemporaryWindowMover() +{ + if (!m_moveSucceeded) + return; + + ::SetWindowPos(m_window, 0, m_savedWindowRect.left, m_savedWindowRect.top, 0, 0, SWP_HIDEWINDOW | standardSetWindowPosFlags); +} + +class NPNInvalidateRectInvalidatesWindow : public PluginTest { +public: + NPNInvalidateRectInvalidatesWindow(NPP, const string& identifier); + ~NPNInvalidateRectInvalidatesWindow(); + +private: + static LRESULT CALLBACK wndProc(HWND, UINT message, WPARAM, LPARAM); + + void onPaint(); + void testInvalidateRect(); + + virtual NPError NPP_SetWindow(NPP, NPWindow*); + + HWND m_window; + WNDPROC m_originalWndProc; + TemporaryWindowMover* m_windowMover; +}; + +NPNInvalidateRectInvalidatesWindow::NPNInvalidateRectInvalidatesWindow(NPP npp, const string& identifier) + : PluginTest(npp, identifier) + , m_window(0) + , m_originalWndProc(0) + , m_windowMover(0) +{ +} + +NPNInvalidateRectInvalidatesWindow::~NPNInvalidateRectInvalidatesWindow() +{ + delete m_windowMover; +} + +NPError NPNInvalidateRectInvalidatesWindow::NPP_SetWindow(NPP instance, NPWindow* window) +{ + HWND newWindow = reinterpret_cast<HWND>(window->window); + if (newWindow == m_window) + return NPERR_NO_ERROR; + + if (m_window) { + ::RemovePropW(m_window, instancePointerProperty); + ::SetWindowLongPtr(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_originalWndProc)); + m_originalWndProc = 0; + } + + m_window = newWindow; + if (!m_window) + return NPERR_NO_ERROR; + + m_originalWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtrW(m_window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wndProc))); + ::SetPropW(m_window, instancePointerProperty, this); + + // The test harness's window (the one that contains the WebView) is off-screen and hidden. + // We need to move it on-screen and make it visible in order for the plugin's window to + // accumulate an update region when the DWM is disabled. + + HWND testHarnessWindow = ::GetAncestor(m_window, GA_ROOT); + if (!testHarnessWindow) { + pluginLog(instance, "Failed to get test harness window"); + return NPERR_GENERIC_ERROR; + } + + m_windowMover = new TemporaryWindowMover(testHarnessWindow); + if (!m_windowMover->moveSucceeded()) { + pluginLog(instance, "Failed to move test harness window on-screen"); + return NPERR_GENERIC_ERROR; + } + + // Wait until we receive a WM_PAINT message to ensure that the window is on-screen before we do + // the NPN_InvalidateRect test. + waitUntilDone(); + return NPERR_NO_ERROR; +} + +LRESULT NPNInvalidateRectInvalidatesWindow::wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + NPNInvalidateRectInvalidatesWindow* instance = reinterpret_cast<NPNInvalidateRectInvalidatesWindow*>(::GetPropW(hwnd, instancePointerProperty)); + + if (message == WM_PAINT) + instance->onPaint(); + + return ::CallWindowProcW(instance->m_originalWndProc, hwnd, message, wParam, lParam); +} + +void NPNInvalidateRectInvalidatesWindow::onPaint() +{ + testInvalidateRect(); + notifyDone(); + delete m_windowMover; + m_windowMover = 0; +} + +void NPNInvalidateRectInvalidatesWindow::testInvalidateRect() +{ + RECT clientRect; + if (!::GetClientRect(m_window, &clientRect)) { + pluginLog(m_npp, "::GetClientRect failed"); + return; + } + + if (::IsRectEmpty(&clientRect)) { + pluginLog(m_npp, "Plugin's HWND has not been sized when NPP_SetWindow is called"); + return; + } + + // Clear the invalid region. + if (!::ValidateRect(m_window, 0)) { + pluginLog(m_npp, "::ValidateRect failed"); + return; + } + + // Invalidate our lower-right quadrant. + NPRect rectToInvalidate; + rectToInvalidate.left = (clientRect.right - clientRect.left) / 2; + rectToInvalidate.top = (clientRect.bottom - clientRect.top) / 2; + rectToInvalidate.right = clientRect.right; + rectToInvalidate.bottom = clientRect.bottom; + NPN_InvalidateRect(&rectToInvalidate); + + RECT invalidRect; + if (!::GetUpdateRect(m_window, &invalidRect, FALSE)) { + pluginLog(m_npp, "::GetUpdateRect failed"); + return; + } + + if (invalidRect.left != rectToInvalidate.left || invalidRect.top != rectToInvalidate.top || invalidRect.right != rectToInvalidate.right || invalidRect.bottom != rectToInvalidate.bottom) { + pluginLog(m_npp, "Expected invalid rect {left=%u, top=%u, right=%u, bottom=%u}, but got {left=%d, top=%d, right=%d, bottom=%d}", rectToInvalidate.left, rectToInvalidate.top, rectToInvalidate.right, rectToInvalidate.bottom, invalidRect.left, invalidRect.top, invalidRect.right, invalidRect.bottom); + return; + } + + pluginLog(m_npp, "Plugin's HWND has been invalidated as expected"); +} + +static PluginTest::Register<NPNInvalidateRectInvalidatesWindow> registrar("npn-invalidate-rect-invalidates-window"); diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp index e240c42..e5246c4 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/main.cpp @@ -26,6 +26,7 @@ #include "PluginObject.h" #include "PluginTest.h" +#include <cstdlib> #include <string> #if !defined(NP_NO_CARBON) && defined(QD_HEADERS_ARE_PRIVATE) && QD_HEADERS_ARE_PRIVATE @@ -54,9 +55,17 @@ static inline int strcasecmp(const char* s1, const char* s2) #define STDCALL #endif +extern "C" { +NPError STDCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs); +} + // Entry points extern "C" -NPError STDCALL NP_Initialize(NPNetscapeFuncs *browserFuncs) +NPError STDCALL NP_Initialize(NPNetscapeFuncs *browserFuncs +#ifdef XP_UNIX + , NPPluginFuncs *pluginFuncs +#endif + ) { initializeWasCalled = true; @@ -67,7 +76,12 @@ NPError STDCALL NP_Initialize(NPNetscapeFuncs *browserFuncs) #endif browser = browserFuncs; + +#ifdef XP_UNIX + return NP_GetEntryPoints(pluginFuncs); +#else return NPERR_NO_ERROR; +#endif } extern "C" @@ -81,6 +95,8 @@ NPError STDCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) CRASH(); #endif + pluginFunctions = pluginFuncs; + pluginFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; pluginFuncs->size = sizeof(pluginFuncs); pluginFuncs->newp = NPP_New; @@ -246,7 +262,12 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc obj->pluginTest = PluginTest::create(instance, testIdentifier); +#ifdef XP_UNIX + // On Unix, plugins only get events if they are windowless. + return browser->setvalue(instance, NPPVpluginWindowBool, 0); +#else return NPERR_NO_ERROR; +#endif } NPError NPP_Destroy(NPP instance, NPSavedData **save) @@ -281,6 +302,8 @@ NPError NPP_Destroy(NPP instance, NPSavedData **save) CFRelease(obj->coreAnimationLayer); #endif + obj->pluginTest->NPP_Destroy(save); + browser->releaseobject(&obj->header); } return NPERR_NO_ERROR; @@ -574,6 +597,17 @@ void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyD NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) { +#ifdef XP_UNIX + if (variable == NPPVpluginNameString) { + *((char **)value) = const_cast<char*>("WebKit Test PlugIn"); + return NPERR_NO_ERROR; + } + if (variable == NPPVpluginDescriptionString) { + *((char **)value) = const_cast<char*>("Simple Netscape plug-in that handles test content for WebKit"); + return NPERR_NO_ERROR; + } +#endif + PluginObject* obj = static_cast<PluginObject*>(instance->pdata); // First, check if the PluginTest object supports getting this value. @@ -598,7 +632,7 @@ NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) return NPERR_NO_ERROR; } #endif - + return NPERR_GENERIC_ERROR; } @@ -614,3 +648,17 @@ NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) return NPERR_GENERIC_ERROR; } } + +#ifdef XP_UNIX +extern "C" +const char* NP_GetMIMEDescription(void) +{ + return "application/x-webkit-test-netscape:testnetscape:test netscape content"; +} + +extern "C" +NPError NP_GetValue(NPP instance, NPPVariable variable, void* value) +{ + return NPP_GetValue(instance, variable, value); +} +#endif diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj index cdd7729..74042bc 100644 --- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj +++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj @@ -383,6 +383,10 @@ >
</File>
<File
+ RelativePath="..\Tests\NullNPPGetValuePointer.cpp"
+ >
+ </File>
+ <File
RelativePath="..\Tests\PassDifferentNPPStruct.cpp"
>
</File>
@@ -398,6 +402,10 @@ >
</File>
<File
+ RelativePath="..\Tests\win\NPNInvalidateRectInvalidatesWindow.cpp"
+ >
+ </File>
+ <File
RelativePath="..\Tests\win\WindowGeometryInitializedBeforeSetWindow.cpp"
>
</File>
diff --git a/WebKitTools/DumpRenderTree/cf/WebArchiveDumpSupport.cpp b/WebKitTools/DumpRenderTree/cf/WebArchiveDumpSupport.cpp new file mode 100644 index 0000000..4d77454 --- /dev/null +++ b/WebKitTools/DumpRenderTree/cf/WebArchiveDumpSupport.cpp @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "WebArchiveDumpSupport.h" + +#import <CoreFoundation/CoreFoundation.h> +#import <CFNetwork/CFNetwork.h> +#import <wtf/RetainPtr.h> + +extern "C" { + +CFURLRef CFURLResponseGetURL(CFURLResponseRef response); +CFStringRef CFURLResponseGetMIMEType(CFURLResponseRef response); +CFStringRef CFURLResponseGetTextEncodingName(CFURLResponseRef response); +SInt64 CFURLResponseGetExpectedContentLength(CFURLResponseRef response); +CFHTTPMessageRef CFURLResponseGetHTTPResponse(CFURLResponseRef response); + +CFTypeID CFURLResponseGetTypeID(void); + +} + +static void convertMIMEType(CFMutableStringRef mimeType) +{ +#ifdef BUILDING_ON_LEOPARD + // Workaround for <rdar://problem/5539824> on Leopard + if (CFStringCompare(mimeType, CFSTR("text/xml"), kCFCompareAnchored | kCFCompareCaseInsensitive) == kCFCompareEqualTo) + CFStringReplaceAll(mimeType, CFSTR("application/xml")); +#endif + // Workaround for <rdar://problem/6234318> with Dashcode 2.0 + if (CFStringCompare(mimeType, CFSTR("application/x-javascript"), kCFCompareAnchored | kCFCompareCaseInsensitive) == kCFCompareEqualTo) + CFStringReplaceAll(mimeType, CFSTR("text/javascript")); +} + +static void convertWebResourceDataToString(CFMutableDictionaryRef resource) +{ + CFMutableStringRef mimeType = (CFMutableStringRef)CFDictionaryGetValue(resource, CFSTR("WebResourceMIMEType")); + CFStringLowercase(mimeType, CFLocaleGetSystem()); + convertMIMEType(mimeType); + + CFArrayRef supportedMIMETypes = supportedNonImageMIMETypes(); + if (CFStringHasPrefix(mimeType, CFSTR("text/")) || CFArrayContainsValue(supportedMIMETypes, CFRangeMake(0, CFArrayGetCount(supportedMIMETypes)), mimeType)) { + CFStringRef textEncodingName = static_cast<CFStringRef>(CFDictionaryGetValue(resource, CFSTR("WebResourceTextEncodingName"))); + CFStringEncoding stringEncoding; + if (textEncodingName && CFStringGetLength(textEncodingName)) + stringEncoding = CFStringConvertIANACharSetNameToEncoding(textEncodingName); + else + stringEncoding = kCFStringEncodingUTF8; + + CFDataRef data = static_cast<CFDataRef>(CFDictionaryGetValue(resource, CFSTR("WebResourceData"))); + RetainPtr<CFStringRef> dataAsString(AdoptCF, CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, data, stringEncoding)); + if (dataAsString) + CFDictionarySetValue(resource, CFSTR("WebResourceData"), dataAsString.get()); + } +} + +static void normalizeHTTPResponseHeaderFields(CFMutableDictionaryRef fields) +{ + // Normalize headers + if (CFDictionaryContainsKey(fields, CFSTR("Date"))) + CFDictionarySetValue(fields, CFSTR("Date"), CFSTR("Sun, 16 Nov 2008 17:00:00 GMT")); + if (CFDictionaryContainsKey(fields, CFSTR("Last-Modified"))) + CFDictionarySetValue(fields, CFSTR("Last-Modified"), CFSTR("Sun, 16 Nov 2008 16:55:00 GMT")); + if (CFDictionaryContainsKey(fields, CFSTR("Etag"))) + CFDictionarySetValue(fields, CFSTR("Etag"), CFSTR("\"301925-21-45c7d72d3e780\"")); + if (CFDictionaryContainsKey(fields, CFSTR("Server"))) + CFDictionarySetValue(fields, CFSTR("Server"), CFSTR("Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.7l PHP/5.2.6")); + + // Remove headers + CFDictionaryRemoveValue(fields, CFSTR("Connection")); + CFDictionaryRemoveValue(fields, CFSTR("Keep-Alive")); +} + +static void normalizeWebResourceURL(CFMutableStringRef webResourceURL) +{ + static CFIndex fileUrlLength = CFStringGetLength(CFSTR("file://")); + CFRange layoutTestsWebArchivePathRange = CFStringFind(webResourceURL, CFSTR("/LayoutTests/"), kCFCompareBackwards); + if (layoutTestsWebArchivePathRange.location == kCFNotFound) + return; + CFRange currentWorkingDirectoryRange = CFRangeMake(fileUrlLength, layoutTestsWebArchivePathRange.location - fileUrlLength); + CFStringReplace(webResourceURL, currentWorkingDirectoryRange, CFSTR("")); +} + +static void convertWebResourceResponseToDictionary(CFMutableDictionaryRef propertyList) +{ + CFDataRef responseData = static_cast<CFDataRef>(CFDictionaryGetValue(propertyList, CFSTR("WebResourceResponse"))); // WebResourceResponseKey in WebResource.m + if (CFGetTypeID(responseData) != CFDataGetTypeID()) + return; + + RetainPtr<CFURLResponseRef> response(AdoptCF, createCFURLResponseFromResponseData(responseData)); + if (!response) + return; + + RetainPtr<CFMutableDictionaryRef> responseDictionary(AdoptCF, CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + + RetainPtr<CFMutableStringRef> urlString(AdoptCF, CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFURLGetString(CFURLResponseGetURL(response.get())))); + normalizeWebResourceURL(urlString.get()); + CFDictionarySetValue(responseDictionary.get(), CFSTR("URL"), urlString.get()); + + RetainPtr<CFMutableStringRef> mimeTypeString(AdoptCF, CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFURLResponseGetMIMEType(response.get()))); + convertMIMEType(mimeTypeString.get()); + CFDictionarySetValue(responseDictionary.get(), CFSTR("MIMEType"), mimeTypeString.get()); + + CFStringRef textEncodingName = CFURLResponseGetTextEncodingName(response.get()); + if (textEncodingName) + CFDictionarySetValue(responseDictionary.get(), CFSTR("textEncodingName"), textEncodingName); + + SInt64 expectedContentLength = CFURLResponseGetExpectedContentLength(response.get()); + RetainPtr<CFNumberRef> expectedContentLengthNumber(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &expectedContentLength)); + CFDictionarySetValue(responseDictionary.get(), CFSTR("expectedContentLength"), expectedContentLengthNumber.get()); + + if (CFHTTPMessageRef httpMessage = CFURLResponseGetHTTPResponse(response.get())) { + RetainPtr<CFDictionaryRef> allHeaders(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpMessage)); + RetainPtr<CFMutableDictionaryRef> allHeaderFields(AdoptCF, CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, allHeaders.get())); + normalizeHTTPResponseHeaderFields(allHeaderFields.get()); + CFDictionarySetValue(responseDictionary.get(), CFSTR("allHeaderFields"), allHeaderFields.get()); + + CFIndex statusCode = CFHTTPMessageGetResponseStatusCode(httpMessage); + RetainPtr<CFNumberRef> statusCodeNumber(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &statusCode)); + CFDictionarySetValue(responseDictionary.get(), CFSTR("statusCode"), statusCodeNumber.get()); + } + + CFDictionarySetValue(propertyList, CFSTR("WebResourceResponse"), responseDictionary.get()); +} + +static CFComparisonResult compareResourceURLs(const void *val1, const void *val2, void *context) +{ + CFStringRef url1 = static_cast<CFStringRef>(CFDictionaryGetValue(static_cast<CFDictionaryRef>(val1), CFSTR("WebResourceURL"))); + CFStringRef url2 = static_cast<CFStringRef>(CFDictionaryGetValue(static_cast<CFDictionaryRef>(val2), CFSTR("WebResourceURL"))); + + return CFStringCompare(url1, url2, kCFCompareAnchored); +} + +CFStringRef createXMLStringFromWebArchiveData(CFDataRef webArchiveData) +{ + CFErrorRef error = 0; + CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0; + +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) + CFIndex bytesCount = CFDataGetLength(webArchiveData); + RetainPtr<CFReadStreamRef> readStream(AdoptCF, CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(webArchiveData), bytesCount, kCFAllocatorNull)); + CFReadStreamOpen(readStream.get()); + RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, (CFMutableDictionaryRef)CFPropertyListCreateFromStream(kCFAllocatorDefault, readStream.get(), bytesCount, kCFPropertyListMutableContainersAndLeaves, &format, 0)); + CFReadStreamClose(readStream.get()); +#else + RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, (CFMutableDictionaryRef)CFPropertyListCreateWithData(kCFAllocatorDefault, webArchiveData, kCFPropertyListMutableContainersAndLeaves, &format, &error)); +#endif + + if (!propertyList) { + if (error) + return CFErrorCopyDescription(error); + return static_cast<CFStringRef>(CFRetain(CFSTR("An unknown error occurred converting data to property list."))); + } + + RetainPtr<CFMutableArrayRef> resources(AdoptCF, CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); + CFArrayAppendValue(resources.get(), propertyList.get()); + + while (CFArrayGetCount(resources.get())) { + RetainPtr<CFMutableDictionaryRef> resourcePropertyList = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(resources.get(), 0); + CFArrayRemoveValueAtIndex(resources.get(), 0); + + CFMutableDictionaryRef mainResource = (CFMutableDictionaryRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebMainResource")); + normalizeWebResourceURL((CFMutableStringRef)CFDictionaryGetValue(mainResource, CFSTR("WebResourceURL"))); + convertWebResourceDataToString(mainResource); + + // Add subframeArchives to list for processing + CFMutableArrayRef subframeArchives = (CFMutableArrayRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebSubframeArchives")); // WebSubframeArchivesKey in WebArchive.m + if (subframeArchives) + CFArrayAppendArray(resources.get(), subframeArchives, CFRangeMake(0, CFArrayGetCount(subframeArchives))); + + CFMutableArrayRef subresources = (CFMutableArrayRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebSubresources")); // WebSubresourcesKey in WebArchive.m + if (!subresources) + continue; + + CFIndex subresourcesCount = CFArrayGetCount(subresources); + for (CFIndex i = 0; i < subresourcesCount; ++i) { + CFMutableDictionaryRef subresourcePropertyList = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(subresources, i); + normalizeWebResourceURL((CFMutableStringRef)CFDictionaryGetValue(subresourcePropertyList, CFSTR("WebResourceURL"))); + convertWebResourceResponseToDictionary(subresourcePropertyList); + convertWebResourceDataToString(subresourcePropertyList); + } + + // Sort the subresources so they're always in a predictable order for the dump + CFArraySortValues(subresources, CFRangeMake(0, CFArrayGetCount(subresources)), compareResourceURLs, 0); + } + + error = 0; + +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) + RetainPtr<CFDataRef> xmlData(AdoptCF, CFPropertyListCreateXMLData(kCFAllocatorDefault, propertyList.get())); +#else + RetainPtr<CFDataRef> xmlData(AdoptCF, CFPropertyListCreateData(kCFAllocatorDefault, propertyList.get(), kCFPropertyListXMLFormat_v1_0, 0, &error)); +#endif + + if (!xmlData) { + if (error) + return CFErrorCopyDescription(error); + return static_cast<CFStringRef>(CFRetain(CFSTR("An unknown error occurred converting property list to data."))); + } + + RetainPtr<CFStringRef> xmlString(AdoptCF, CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, xmlData.get(), kCFStringEncodingUTF8)); + RetainPtr<CFMutableStringRef> string(AdoptCF, CFStringCreateMutableCopy(kCFAllocatorDefault, 0, xmlString.get())); + + // Replace "Apple Computer" with "Apple" in the DTD declaration. + CFStringFindAndReplace(string.get(), CFSTR("-//Apple Computer//"), CFSTR("-//Apple//"), CFRangeMake(0, CFStringGetLength(string.get())), 0); + + return string.releaseRef(); +} diff --git a/WebKitTools/DumpRenderTree/mac/WebArchiveDumpSupport.h b/WebKitTools/DumpRenderTree/cf/WebArchiveDumpSupport.h index 8654dd5..08d9c45 100644 --- a/WebKitTools/DumpRenderTree/mac/WebArchiveDumpSupport.h +++ b/WebKitTools/DumpRenderTree/cf/WebArchiveDumpSupport.h @@ -26,9 +26,16 @@ #ifndef WebArchiveDumpSupport_h #define WebArchiveDumpSupport_h -@class NSString; -@class WebArchive; +#include <CoreFoundation/CoreFoundation.h> -NSString *serializeWebArchiveToXML(WebArchive *webArchive); +typedef struct _CFURLResponse* CFURLResponseRef; + +CFStringRef createXMLStringFromWebArchiveData(CFDataRef webArchiveData); + +#pragma mark - +#pragma mark Platform-specific methods + +CFURLResponseRef createCFURLResponseFromResponseData(CFDataRef responseData); +CFArrayRef supportedNonImageMIMETypes(); #endif /* WebArchiveDumpSupport_h */ diff --git a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp index 72c0c3c..3bbba98 100644 --- a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp @@ -32,6 +32,7 @@ #include "TestShell.h" #include "webkit/support/webkit_support.h" +#include <v8/include/v8.h> #include <wtf/Vector.h> using namespace std; @@ -51,6 +52,9 @@ static const char optionCheckLayoutTestSystemDeps[] = "--check-layout-test-sys-d static const char optionEnableAcceleratedCompositing[] = "--enable-accelerated-compositing"; static const char optionEnableAccelerated2DCanvas[] = "--enable-accelerated-2d-canvas"; +static const char optionMultipleLoads[] = "--multiple-loads="; +static const char optionJavaScriptFlags[] = "--js-flags="; + static void runTest(TestShell& shell, TestParams& params, const string& testName, bool testShellMode) { int oldTimeoutMsec = shell.layoutTestTimeout(); @@ -78,8 +82,14 @@ static void runTest(TestShell& shell, TestParams& params, const string& testName } params.testUrl = webkit_support::CreateURLForPathOrURL(pathOrURL); webkit_support::SetCurrentDirectoryForFileURL(params.testUrl); - shell.resetTestController(); - shell.runFileTest(params); + for (int i = 0; i < shell.loadCount(); i++) { + string javaScriptFlags = shell.javaScriptFlagsForLoad(i); + v8::V8::SetFlagsFromString(javaScriptFlags.data(), static_cast<int>(javaScriptFlags.size())); + bool isLastLoad = (i == (shell.loadCount() - 1)); + shell.setDumpWhenFinished(isLastLoad); + shell.resetTestController(); + shell.runFileTest(params); + } shell.setLayoutTestTimeout(oldTimeoutMsec); } @@ -96,6 +106,8 @@ int main(int argc, char* argv[]) bool startupDialog = false; bool acceleratedCompositingEnabled = false; bool accelerated2DCanvasEnabled = false; + int loadCount = 1; + string javaScriptFlags; for (int i = 1; i < argc; ++i) { string argument(argv[i]); if (argument == "-") @@ -120,7 +132,12 @@ int main(int argc, char* argv[]) acceleratedCompositingEnabled = true; else if (argument == optionEnableAccelerated2DCanvas) accelerated2DCanvasEnabled = true; - else if (argument.size() && argument[0] == '-') + else if (!argument.find(optionMultipleLoads)) { + string multipleLoadsStr = argument.substr(strlen(optionMultipleLoads)); + loadCount = atoi(multipleLoadsStr.c_str()); + } else if (!argument.find(optionJavaScriptFlags)) { + javaScriptFlags = argument.substr(strlen(optionJavaScriptFlags)); + } else if (argument.size() && argument[0] == '-') fprintf(stderr, "Unknown option: %s\n", argv[i]); else tests.append(argument); @@ -129,6 +146,30 @@ int main(int argc, char* argv[]) fprintf(stderr, "--pixel-tests with --test-shell requires a file name.\n"); return EXIT_FAILURE; } + if (loadCount < 1) { + fprintf(stderr, "--multiple-loads requires a positive numeric argument.\n"); + return EXIT_FAILURE; + } + + // The test runner might send a quoted string which needs to be unquoted before further processing. + if (javaScriptFlags.length() > 1 && javaScriptFlags[0] == '"' && javaScriptFlags[javaScriptFlags.length() - 1] == '"') + javaScriptFlags = javaScriptFlags.substr(1, javaScriptFlags.length() - 2); + // Split the JavaScript flags into a list. + Vector<string> flagsList; + size_t start = 0; + while (true) { + size_t commaPos = javaScriptFlags.find_first_of(',', start); + string flags; + if (commaPos == string::npos) + flags = javaScriptFlags.substr(start, javaScriptFlags.length() - start); + else { + flags = javaScriptFlags.substr(start, commaPos - start); + start = commaPos + 1; + } + flagsList.append(flags); + if (commaPos == string::npos) + break; + } if (startupDialog) openStartupDialog(); @@ -138,6 +179,8 @@ int main(int argc, char* argv[]) shell.setAllowExternalPages(allowExternalPages); shell.setAcceleratedCompositingEnabled(acceleratedCompositingEnabled); shell.setAccelerated2dCanvasEnabled(accelerated2DCanvasEnabled); + shell.setLoadCount(loadCount); + shell.setJavaScriptFlags(flagsList); if (serverMode && !tests.size()) { params.printSeparators = true; char testString[2048]; // 2048 is the same as the sizes of other platforms. diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp index 82fd085..d713b04 100644 --- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp +++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp @@ -94,6 +94,7 @@ LayoutTestController::LayoutTestController(TestShell* shell) bindMethod("dumpDatabaseCallbacks", &LayoutTestController::dumpDatabaseCallbacks); bindMethod("dumpEditingCallbacks", &LayoutTestController::dumpEditingCallbacks); bindMethod("dumpFrameLoadCallbacks", &LayoutTestController::dumpFrameLoadCallbacks); + bindMethod("dumpUserGestureInFrameLoadCallbacks", &LayoutTestController::dumpUserGestureInFrameLoadCallbacks); bindMethod("dumpResourceLoadCallbacks", &LayoutTestController::dumpResourceLoadCallbacks); bindMethod("dumpResourceResponseMIMETypes", &LayoutTestController::dumpResourceResponseMIMETypes); bindMethod("dumpSelectionRect", &LayoutTestController::dumpSelectionRect); @@ -288,6 +289,12 @@ void LayoutTestController::dumpFrameLoadCallbacks(const CppArgumentList&, CppVar result->setNull(); } +void LayoutTestController::dumpUserGestureInFrameLoadCallbacks(const CppArgumentList&, CppVariant* result) +{ + m_dumpUserGestureInFrameLoadCallbacks = true; + result->setNull(); +} + void LayoutTestController::dumpResourceLoadCallbacks(const CppArgumentList&, CppVariant* result) { m_dumpResourceLoadCallbacks = true; @@ -522,6 +529,7 @@ void LayoutTestController::reset() m_dumpAsText = false; m_dumpEditingCallbacks = false; m_dumpFrameLoadCallbacks = false; + m_dumpUserGestureInFrameLoadCallbacks = false; m_dumpResourceLoadCallbacks = false; m_dumpResourceResponseMIMETypes = false; m_dumpBackForwardList = false; @@ -1526,10 +1534,10 @@ void LayoutTestController::abortModal(const CppArgumentList& arguments, CppVaria void LayoutTestController::setMockSpeechInputResult(const CppArgumentList& arguments, CppVariant* result) { result->setNull(); - if (arguments.size() < 1 || !arguments[0].isString()) + if (arguments.size() < 2 || !arguments[0].isString() || !arguments[1].isString()) return; - m_speechInputControllerMock->setMockRecognitionResult(cppVariantToWebString(arguments[0])); + m_speechInputControllerMock->setMockRecognitionResult(cppVariantToWebString(arguments[0]), cppVariantToWebString(arguments[1])); } WebKit::WebSpeechInputController* LayoutTestController::speechInputController(WebKit::WebSpeechInputListener* listener) diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h index ae1a7a2..fc16827 100644 --- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h +++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h @@ -88,6 +88,11 @@ public: // ignores any that may be present. void dumpFrameLoadCallbacks(const CppArgumentList&, CppVariant*); + // This function sets a flag that tells the test_shell to print a line of + // user gesture status text for some frame load callbacks. It takes no + // arguments, and ignores any that may be present. + void dumpUserGestureInFrameLoadCallbacks(const CppArgumentList&, CppVariant*); + // This function sets a flag that tells the test_shell to print out a text // representation of the back/forward list. It ignores all arguments. void dumpBackForwardList(const CppArgumentList&, CppVariant*); @@ -340,6 +345,8 @@ public: bool shouldDumpEditingCallbacks() { return m_dumpEditingCallbacks; } bool shouldDumpFrameLoadCallbacks() { return m_dumpFrameLoadCallbacks; } void setShouldDumpFrameLoadCallbacks(bool value) { m_dumpFrameLoadCallbacks = value; } + bool shouldDumpUserGestureInFrameLoadCallbacks() { return m_dumpUserGestureInFrameLoadCallbacks; } + void setShouldDumpUserGestureInFrameLoadCallbacks(bool value) { m_dumpUserGestureInFrameLoadCallbacks = value; } bool shouldDumpResourceLoadCallbacks() {return m_dumpResourceLoadCallbacks; } void setShouldDumpResourceResponseMIMETypes(bool value) { m_dumpResourceResponseMIMETypes = value; } bool shouldDumpResourceResponseMIMETypes() {return m_dumpResourceResponseMIMETypes; } @@ -460,6 +467,10 @@ private: // load callback. bool m_dumpFrameLoadCallbacks; + // If true, the test_shell will output a line of the user gesture status + // text for some frame load callbacks. + bool m_dumpUserGestureInFrameLoadCallbacks; + // If true, the test_shell will output a descriptive line for each resource // load callback. bool m_dumpResourceLoadCallbacks; diff --git a/WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npapi.h b/WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npapi.h index 49f72a6..9fa3fff 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npapi.h +++ b/WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npapi.h @@ -1 +1,9 @@ #include "bindings/npapi.h" + +// These are defined in WebCore/brdige/npapi.h and we need them on Linux/Win. +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef TRUE +#define TRUE (1) +#endif diff --git a/WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npfunctions.h b/WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npfunctions.h index 61588ca..59ae666 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npfunctions.h +++ b/WebKitTools/DumpRenderTree/chromium/TestNetscapePlugIn/ForwardingHeaders/WebKit/npfunctions.h @@ -1,3 +1,4 @@ +#include "npapi.h" #include "bindings/npfunctions.h" // Non-standard event types can be passed to HandleEvent. diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp index 0b27c78..9bb0192 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp +++ b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp @@ -86,9 +86,12 @@ TestShell::TestShell(bool testShellMode) , m_allowExternalPages(false) , m_acceleratedCompositingEnabled(false) , m_accelerated2dCanvasEnabled(false) + , m_loadCount(1) + , m_dumpWhenFinished(true) { WebRuntimeFeatures::enableGeolocation(true); WebRuntimeFeatures::enableIndexedDatabase(true); + WebRuntimeFeatures::enableFileSystem(true); m_accessibilityController.set(new AccessibilityController(this)); m_layoutTestController.set(new LayoutTestController(this)); m_eventSender.set(new EventSender(this)); @@ -181,7 +184,8 @@ void TestShell::runFileTest(const TestParams& params) if (inspectorTestMode) showDevTools(); - m_printer->handleTestHeader(testUrl.c_str()); + if (m_dumpWhenFinished) + m_printer->handleTestHeader(testUrl.c_str()); loadURL(m_params.testUrl); m_testIsPreparing = false; @@ -270,7 +274,8 @@ void TestShell::testFinished() if (!m_testIsPending) return; m_testIsPending = false; - dump(); + if (m_dumpWhenFinished) + dump(); webkit_support::QuitMessageLoop(); } diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.h b/WebKitTools/DumpRenderTree/chromium/TestShell.h index a15d9ec..ca06812 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShell.h +++ b/WebKitTools/DumpRenderTree/chromium/TestShell.h @@ -67,7 +67,7 @@ struct TestParams { bool dumpPixels; bool printSeparators; WebKit::WebURL testUrl; - // Resultant image file name. Reqruired only if the test_shell mode. + // Resultant image file name. Required only if the test_shell mode. std::string pixelFileName; std::string pixelHash; @@ -109,6 +109,7 @@ public: void setFocus(WebKit::WebWidget*, bool enable); bool shouldDumpFrameLoadCallbacks() const { return (m_testIsPreparing || m_testIsPending) && layoutTestController()->shouldDumpFrameLoadCallbacks(); } + bool shouldDumpUserGestureInFrameLoadCallbacks() const { return (m_testIsPreparing || m_testIsPending) && layoutTestController()->shouldDumpUserGestureInFrameLoadCallbacks(); } bool shouldDumpResourceLoadCallbacks() const { return (m_testIsPreparing || m_testIsPending) && layoutTestController()->shouldDumpResourceLoadCallbacks(); } bool shouldDumpResourceResponseMIMETypes() const { return (m_testIsPreparing || m_testIsPending) && layoutTestController()->shouldDumpResourceResponseMIMETypes(); } void setIsLoading(bool flag) { m_isLoading = flag; } @@ -136,6 +137,20 @@ public: int layoutTestTimeoutForWatchDog() { return layoutTestTimeout() + 1000; } void setLayoutTestTimeout(int timeout) { m_timeout = timeout; } + // Number of times to load each URL. + int loadCount() { return m_loadCount; } + void setLoadCount(int loadCount) { m_loadCount = loadCount; } + + // The JavaScript flags are specified as a vector of strings. Each element of the vector is full flags string + // which can contain multiple flags (e.g. "--xxx --yyy"). With multiple load testing it is possible to specify + // separate sets of flags to each load. + std::string javaScriptFlagsForLoad(size_t load) { return (load >= 0 && load < m_javaScriptFlags.size()) ? m_javaScriptFlags[load] : ""; } + void setJavaScriptFlags(Vector<std::string> javaScriptFlags) { m_javaScriptFlags = javaScriptFlags; } + + // Set whether to dump when the loaded page has finished processing. This is used with multiple load + // testing where we only want to have the output from the last load. + void setDumpWhenFinished(bool dumpWhenFinished) { m_dumpWhenFinished = dumpWhenFinished; } + WebViewHost* createWebView(); WebViewHost* createNewWindow(const WebKit::WebURL&); void closeWindow(WebViewHost*); @@ -182,6 +197,10 @@ private: bool m_acceleratedCompositingEnabled; bool m_accelerated2dCanvasEnabled; WebPreferences m_prefs; + int m_loadCount; + Vector<std::string> m_javaScriptFlags; + bool m_dumpWhenFinished; + // List of all windows in this process. // The main window should be put into windowList[0]. diff --git a/WebKitTools/DumpRenderTree/chromium/TextInputController.cpp b/WebKitTools/DumpRenderTree/chromium/TextInputController.cpp index 7af4e9f..3603840 100644 --- a/WebKitTools/DumpRenderTree/chromium/TextInputController.cpp +++ b/WebKitTools/DumpRenderTree/chromium/TextInputController.cpp @@ -33,15 +33,16 @@ #include "TestShell.h" #include "WebBindings.h" +#include "WebCompositionUnderline.h" #include "WebFrame.h" #include "WebRange.h" #include "WebString.h" +#include "WebVector.h" #include "WebView.h" #include <wtf/StringExtras.h> #include <string> using namespace WebKit; -using namespace std; TestShell* TextInputController::testShell = 0; @@ -66,6 +67,7 @@ TextInputController::TextInputController(TestShell* shell) bindMethod("substringFromRange", &TextInputController::substringFromRange); bindMethod("unmarkText", &TextInputController::unmarkText); bindMethod("validAttributesForMarkedText", &TextInputController::validAttributesForMarkedText); + bindMethod("setComposition", &TextInputController::setComposition); } WebFrame* TextInputController::getMainFrame() @@ -167,9 +169,10 @@ void TextInputController::markedRange(const CppArgumentList&, CppVariant* result return; WebRange range = mainFrame->markedRange(); - char buffer[30]; - snprintf(buffer, 30, "%d,%d", range.startOffset(), range.endOffset()); - result->set(string(buffer)); + Vector<int> intArray(2); + intArray[0] = range.startOffset(); + intArray[1] = range.endOffset(); + result->set(WebBindings::makeIntArray(intArray)); } void TextInputController::selectedRange(const CppArgumentList&, CppVariant* result) @@ -181,9 +184,10 @@ void TextInputController::selectedRange(const CppArgumentList&, CppVariant* resu return; WebRange range = mainFrame->selectionRange(); - char buffer[30]; - snprintf(buffer, 30, "%d,%d", range.startOffset(), range.endOffset()); - result->set(string(buffer)); + Vector<int> intArray(2); + intArray[0] = range.startOffset(); + intArray[1] = range.endOffset(); + result->set(WebBindings::makeIntArray(intArray)); } void TextInputController::firstRectForCharacterRange(const CppArgumentList& arguments, CppVariant* result) @@ -232,3 +236,27 @@ void TextInputController::makeAttributedString(const CppArgumentList&, CppVarian // FIXME: Implement this. result->setNull(); } + +void TextInputController::setComposition(const CppArgumentList& arguments, CppVariant* result) +{ + result->setNull(); + + WebView* view = getMainFrame() ? getMainFrame()->view() : 0; + if (!view) + return; + + if (arguments.size() < 1) + return; + + // Sends a keydown event with key code = 0xE5 to emulate input method behavior. + WebKeyboardEvent keyDown; + keyDown.type = WebInputEvent::RawKeyDown; + keyDown.modifiers = 0; + keyDown.windowsKeyCode = 0xE5; // VKEY_PROCESSKEY + keyDown.setKeyIdentifierFromWindowsKeyCode(); + view->handleInputEvent(keyDown); + + WebVector<WebCompositionUnderline> underlines; + WebString text(WebString::fromUTF8(arguments[0].toString())); + view->setComposition(text, underlines, 0, text.length()); +} diff --git a/WebKitTools/DumpRenderTree/chromium/TextInputController.h b/WebKitTools/DumpRenderTree/chromium/TextInputController.h index 9896be5..3a3907f 100644 --- a/WebKitTools/DumpRenderTree/chromium/TextInputController.h +++ b/WebKitTools/DumpRenderTree/chromium/TextInputController.h @@ -61,6 +61,7 @@ public: void characterIndexForPoint(const CppArgumentList&, CppVariant*); void validAttributesForMarkedText(const CppArgumentList&, CppVariant*); void makeAttributedString(const CppArgumentList&, CppVariant*); + void setComposition(const CppArgumentList&, CppVariant*); private: // Returns the test shell's main WebFrame. diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp index ab8dbf0..847e7dc 100644 --- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp +++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp @@ -813,6 +813,8 @@ void WebViewHost::didCreateDataSource(WebFrame*, WebDataSource* ds) void WebViewHost::didStartProvisionalLoad(WebFrame* frame) { + if (m_shell->shouldDumpUserGestureInFrameLoadCallbacks()) + printFrameUserGestureStatus(frame, " - in didStartProvisionalLoadForFrame\n"); if (m_shell->shouldDumpFrameLoadCallbacks()) { printFrameDescription(frame); fputs(" - didStartProvisionalLoadForFrame\n", stdout); @@ -1051,6 +1053,11 @@ bool WebViewHost::allowScript(WebFrame*, bool enabledPerSettings) return enabledPerSettings; } +void WebViewHost::openFileSystem(WebFrame* frame, WebFileSystem::Type type, long long size, bool create, WebFileSystemCallbacks* callbacks) +{ + webkit_support::OpenFileSystem(frame, type, size, create, callbacks); +} + // Public functions ----------------------------------------------------------- WebViewHost::WebViewHost(TestShell* shell) @@ -1305,6 +1312,12 @@ void WebViewHost::printFrameDescription(WebFrame* webframe) printf("frame \"%s\"", name8.c_str()); } +void WebViewHost::printFrameUserGestureStatus(WebFrame* webframe, const char* msg) +{ + bool isUserGesture = webframe->isProcessingUserGesture(); + printf("Frame with user gesture \"%s\"%s", isUserGesture ? "true" : "false", msg); +} + void WebViewHost::printResourceDescription(unsigned identifier) { ResourceMap::iterator it = m_resourceIdentifierMap.find(identifier); diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h index 429d3ab..1380ebd 100644 --- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h +++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h @@ -192,6 +192,7 @@ class WebViewHost : public WebKit::WebViewClient, public WebKit::WebFrameClient, virtual void didDisplayInsecureContent(WebKit::WebFrame*); virtual void didRunInsecureContent(WebKit::WebFrame*, const WebKit::WebSecurityOrigin&); virtual bool allowScript(WebKit::WebFrame*, bool enabledPerSettings); + virtual void openFileSystem(WebKit::WebFrame*, WebKit::WebFileSystem::Type, long long size, bool create, WebKit::WebFileSystemCallbacks*); private: LayoutTestController* layoutTestController() const; @@ -220,6 +221,9 @@ private: // Dumping a frame to the console. void printFrameDescription(WebKit::WebFrame*); + // Dumping the user gesture status to the console. + void printFrameUserGestureStatus(WebKit::WebFrame*, const char*); + bool hasWindow() const { return m_hasWindow; } void resetScrollRect(); void discardBackingStore(); diff --git a/WebKitTools/DumpRenderTree/config.h b/WebKitTools/DumpRenderTree/config.h index 33dee6d..55e2dc1 100644 --- a/WebKitTools/DumpRenderTree/config.h +++ b/WebKitTools/DumpRenderTree/config.h @@ -40,6 +40,18 @@ #define WEBKIT_EXPORTDATA #endif +#if PLATFORM(MAC) +#define WTF_PLATFORM_CF 1 + +#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 +#define BUILDING_ON_TIGER 1 +#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 +#define BUILDING_ON_LEOPARD 1 +#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 +#define BUILDING_ON_SNOW_LEOPARD 1 +#endif +#endif // PLATFORM(MAC) + #if PLATFORM(WIN) #define WTF_PLATFORM_CF 1 #if defined(WIN_CAIRO) diff --git a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp index d39ff1e..8493f1a 100644 --- a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp @@ -174,9 +174,12 @@ AccessibilityUIElement AccessibilityUIElement::titleUIElement() AccessibilityUIElement AccessibilityUIElement::parentElement() { - ASSERT(m_element); - AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element)); + if (!m_element) + return 0; + ASSERT(ATK_IS_OBJECT(m_element)); + + AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element)); return parent ? AccessibilityUIElement(parent) : 0; } diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp index e115683..1c851d7 100644 --- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -38,6 +38,7 @@ #include "GOwnPtr.h" #include "LayoutTestController.h" #include "PixelDumpSupport.h" +#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" #include "WorkQueue.h" #include "WorkQueueItem.h" #include <JavaScriptCore/JavaScript.h> @@ -199,6 +200,16 @@ static void initializeFonts(const char* testURL = 0) "/usr/share/fonts/dejavu/DejaVuSans.ttf", }, { "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf", "/usr/share/fonts/dejavu/DejaVuSerif.ttf", }, + + // MathML tests require the STIX fonts. + { "/usr/share/fonts/opentype/stix/STIXGeneral.otf", + "/usr/share/fonts/stix/STIXGeneral.otf" }, + { "/usr/share/fonts/opentype/stix/STIXGeneralBolIta.otf", + "/usr/share/fonts/stix/STIXGeneralBolIta.otf" }, + { "/usr/share/fonts/opentype/stix/STIXGeneralBol.otf", + "/usr/share/fonts/stix/STIXGeneralBol.otf" }, + { "/usr/share/fonts/opentype/stix/STIXGeneralItalic.otf", + "/usr/share/fonts/stix/STIXGeneralItalic.otf" } }; // TODO: Some tests use Lucida. We should load these as well, once it becomes @@ -433,6 +444,8 @@ static void resetDefaultsToConsistentValues() #endif setlocale(LC_ALL, ""); + + DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(true); } static bool useLongRunningServerMode(int argc, char *argv[]) @@ -714,24 +727,8 @@ static char* getFrameNameSuitableForTestResult(WebKitWebView* view, WebKitWebFra return frameName; } -static void webViewLoadCommitted(WebKitWebView* view, WebKitWebFrame* frame, void*) -{ - if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) { - char* frameName = getFrameNameSuitableForTestResult(view, frame); - printf("%s - didCommitLoadForFrame\n", frameName); - g_free(frameName); - } -} - - static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*) { - if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) { - char* frameName = getFrameNameSuitableForTestResult(view, frame); - printf("%s - didFinishLoadForFrame\n", frameName); - g_free(frameName); - } - if (frame != topLoadingFrame) return; @@ -967,23 +964,43 @@ static WebKitWebView* webInspectorInspectWebView(WebKitWebInspector*, gpointer d return WEBKIT_WEB_VIEW(webView); } -static void webViewLoadStatusNotified(WebKitWebView* view, gpointer user_data) +static void webFrameLoadStatusNotified(WebKitWebFrame* frame, gpointer user_data) { - WebKitLoadStatus loadStatus = webkit_web_view_get_load_status(view); + WebKitLoadStatus loadStatus = webkit_web_frame_get_load_status(frame); if (gLayoutTestController->dumpFrameLoadCallbacks()) { - if (loadStatus == WEBKIT_LOAD_PROVISIONAL) { - char* frameName = getFrameNameSuitableForTestResult(view, mainFrame); - printf("%s - didStartProvisionalLoadForFrame\n", frameName); - g_free(frameName); + GOwnPtr<char> frameName(getFrameNameSuitableForTestResult(webkit_web_frame_get_web_view(frame), frame)); + + switch (loadStatus) { + case WEBKIT_LOAD_PROVISIONAL: + if (!done) + printf("%s - didStartProvisionalLoadForFrame\n", frameName.get()); + break; + case WEBKIT_LOAD_COMMITTED: + if (!done) + printf("%s - didCommitLoadForFrame\n", frameName.get()); + break; + case WEBKIT_LOAD_FINISHED: + if (frame != topLoadingFrame || !done) + printf("%s - didFinishLoadForFrame\n", frameName.get()); + break; + default: + break; } } } +static void frameCreatedCallback(WebKitWebView* webView, WebKitWebFrame* webFrame, gpointer user_data) +{ + g_signal_connect(webFrame, "notify::load-status", G_CALLBACK(webFrameLoadStatusNotified), NULL); +} + static WebKitWebView* createWebView() { WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + DumpRenderTreeSupportGtk::setDumpRenderTreeModeEnabled(true); + // From bug 11756: Use a frame group name for all WebViews created by // DumpRenderTree to allow testing of cross-page frame lookup. webkit_web_view_set_group_name(view, "org.webkit.gtk.DumpRenderTree"); @@ -991,7 +1008,6 @@ static WebKitWebView* createWebView() g_object_connect(G_OBJECT(view), "signal::load-started", webViewLoadStarted, 0, "signal::load-finished", webViewLoadFinished, 0, - "signal::load-committed", webViewLoadCommitted, 0, "signal::window-object-cleared", webViewWindowObjectCleared, 0, "signal::console-message", webViewConsoleMessage, 0, "signal::script-alert", webViewScriptAlert, 0, @@ -1009,13 +1025,10 @@ static WebKitWebView* createWebView() "signal::drag-begin", dragBeginCallback, 0, "signal::drag-end", dragEndCallback, 0, "signal::drag-failed", dragFailedCallback, 0, + "signal::frame-created", frameCreatedCallback, 0, NULL); - g_signal_connect(view, - "notify::load-status", G_CALLBACK(webViewLoadStatusNotified), - NULL); - WebKitWebInspector* inspector = webkit_web_view_get_inspector(view); g_object_connect(G_OBJECT(inspector), "signal::inspect-web-view", webInspectorInspectWebView, 0, @@ -1028,6 +1041,10 @@ static WebKitWebView* createWebView() webkit_web_view_set_settings(view, settings); } + // frame-created is not issued for main frame. That's why we must do this here + WebKitWebFrame* frame = webkit_web_view_get_main_frame(view); + g_signal_connect(frame, "notify::load-status", G_CALLBACK(webFrameLoadStatusNotified), NULL); + return view; } diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index 181ef9f..688b3f8 100644 --- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -34,6 +34,7 @@ #include "LayoutTestController.h" #include "DumpRenderTree.h" +#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" #include "WorkQueue.h" #include "WorkQueueItem.h" #include <JavaScriptCore/JSRetainPtr.h> @@ -500,7 +501,7 @@ void LayoutTestController::setGeolocationPermission(bool allow) setGeolocationPermissionCommon(allow); } -void LayoutTestController::setMockSpeechInputResult(JSStringRef result) +void LayoutTestController::setMockSpeechInputResult(JSStringRef result, JSStringRef language) { // FIXME: Implement for speech input layout tests. // See https://bugs.webkit.org/show_bug.cgi?id=39485. @@ -683,10 +684,13 @@ void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value else if (g_str_equal(originalName.get(), "WebKitUsesPageCachePreferenceKey")) propertyName = "enable-page-cache"; else if (g_str_equal(originalName.get(), "WebKitPluginsEnabled")) - propertyName = "enable-plugins"; + propertyName = "enable-plugins"; else if (g_str_equal(originalName.get(), "WebKitHyperlinkAuditingEnabled")) - propertyName = "enable-hyperlink-auditing"; - else { + propertyName = "enable-hyperlink-auditing"; + else if (g_str_equal(originalName.get(), "WebKitTabToLinksPreferenceKey")) { + DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(!g_ascii_strcasecmp(valueAsString.get(), "true") || !g_ascii_strcasecmp(valueAsString.get(), "1")); + return; + } else { fprintf(stderr, "LayoutTestController::overridePreference tried to override " "unknown preference '%s'.\n", originalName.get()); return; diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm index 2ca5755..e27ee0e 100644 --- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm +++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm @@ -381,6 +381,26 @@ AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned inde return 0; } +AccessibilityUIElement AccessibilityUIElement::selectedChildAtIndex(unsigned index) const +{ + BEGIN_AX_OBJC_EXCEPTIONS + NSArray* array = [m_element accessibilityAttributeValue:NSAccessibilitySelectedChildrenAttribute]; + if (index < [array count]) + return [array objectAtIndex:index]; + END_AX_OBJC_EXCEPTIONS + + return 0; +} + +unsigned AccessibilityUIElement::selectedChildrenCount() const +{ + BEGIN_AX_OBJC_EXCEPTIONS + return [m_element accessibilityArrayAttributeCount:NSAccessibilitySelectedChildrenAttribute]; + END_AX_OBJC_EXCEPTIONS + + return 0; +} + AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index) { BEGIN_AX_OBJC_EXCEPTIONS @@ -1103,6 +1123,14 @@ void AccessibilityUIElement::press() END_AX_OBJC_EXCEPTIONS } +void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const +{ + BEGIN_AX_OBJC_EXCEPTIONS + NSArray* array = [NSArray arrayWithObject:element->platformUIElement()]; + [m_element accessibilitySetValue:array forAttribute:NSAccessibilitySelectedChildrenAttribute]; + END_AX_OBJC_EXCEPTIONS +} + JSStringRef AccessibilityUIElement::accessibilityValue() const { // FIXME: implement diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm index 68765f6..efdf54a 100644 --- a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm +++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm @@ -54,6 +54,7 @@ #import "WorkQueueItem.h" #import <Carbon/Carbon.h> #import <CoreFoundation/CoreFoundation.h> +#import <WebCore/FoundationExtras.h> #import <WebKit/DOMElement.h> #import <WebKit/DOMExtensions.h> #import <WebKit/DOMRange.h> @@ -920,11 +921,11 @@ void dump() resultMimeType = @"application/pdf"; } else if (gLayoutTestController->dumpDOMAsWebArchive()) { WebArchive *webArchive = [[mainFrame DOMDocument] webArchive]; - resultString = serializeWebArchiveToXML(webArchive); + resultString = HardAutorelease(createXMLStringFromWebArchiveData((CFDataRef)[webArchive data])); resultMimeType = @"application/x-webarchive"; } else if (gLayoutTestController->dumpSourceAsWebArchive()) { WebArchive *webArchive = [[mainFrame dataSource] webArchive]; - resultString = serializeWebArchiveToXML(webArchive); + resultString = HardAutorelease(createXMLStringFromWebArchiveData((CFDataRef)[webArchive data])); resultMimeType = @"application/x-webarchive"; } else { sizeWebViewForCurrentTest(); diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm index 02280a1..8eded66 100644 --- a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm +++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm @@ -105,5 +105,42 @@ return nil; } +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +- (NSDraggingFormation)draggingFormation +{ + return NSDraggingFormationDefault; +} + +- (void)setDraggingFormation:(NSDraggingFormation)formation +{ + // Ignored. +} + +- (BOOL)animatesToDestination +{ + return NO; +} + +- (void)setAnimatesToDestination:(BOOL)flag +{ + // Ignored. +} + +- (NSInteger)numberOfValidItemsForDrop +{ + return 1; +} + +- (void)setNumberOfValidItemsForDrop:(NSInteger)number +{ + // Ignored. +} + +- (void)enumerateDraggingItemsWithOptions:(NSEnumerationOptions)enumOpts forView:(NSView *)view classes:(NSArray *)classArray searchOptions:(NSDictionary *)searchOptions usingBlock:(void (^)(NSDraggingItem *draggingItem, NSInteger idx, BOOL *stop))block +{ + // Ignored. +} +#endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + @end diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h index 5c93ee9..36c5eac 100644 --- a/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h +++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTreeMac.h @@ -29,25 +29,23 @@ #ifndef DumpRenderTreeMac_h #define DumpRenderTreeMac_h -// FIXME: we should add a config.h file for DumpRenderTree. -#define WTF_PLATFORM_CF 1 - -#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 -#define BUILDING_ON_TIGER 1 -#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 -#define BUILDING_ON_LEOPARD 1 -#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 -#define BUILDING_ON_SNOW_LEOPARD 1 -#endif +#include <CoreFoundation/CoreFoundation.h> +#ifdef __OBJC__ @class DumpRenderTreeDraggingInfo; @class NavigationController; @class PolicyDelegate; @class WebFrame; @class WebScriptWorld; @class WebView; - -typedef const struct __CFString* CFStringRef; +#else +class DumpRenderTreeDraggingInfo; +class NavigationController; +class PolicyDelegate; +class WebFrame; +class WebScriptWorld; +class WebView; +#endif extern CFMutableArrayRef openWindowsRef; extern CFMutableSetRef disallowedURLs; diff --git a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm index 963eae7..a36982c 100644 --- a/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm +++ b/WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm @@ -50,6 +50,7 @@ #import <WebKit/WebNSURLExtras.h> #import <WebKit/WebScriptWorld.h> #import <WebKit/WebSecurityOriginPrivate.h> +#import <WebKit/WebViewPrivate.h> #import <wtf/Assertions.h> @interface NSURL (DRTExtras) @@ -89,6 +90,12 @@ return @"frame (anonymous)"; } } + +- (NSString *)_drt_printFrameUserGestureStatus +{ + BOOL isUserGesture = [[self webView] _isProcessingUserGesture]; + return [NSString stringWithFormat:@"Frame with user gesture \"%@\"", isUserGesture ? @"true" : @"false"]; +} @end @implementation FrameLoadDelegate @@ -146,7 +153,12 @@ NSString *string = [NSString stringWithFormat:@"%@ - didStartProvisionalLoadForFrame", [frame _drt_descriptionSuitableForTestResult]]; printf ("%s\n", [string UTF8String]); } - + + if (!done && gLayoutTestController->dumpUserGestureInFrameLoadCallbacks()) { + NSString *string = [NSString stringWithFormat:@"%@ - in didStartProvisionalLoadForFrame", [frame _drt_printFrameUserGestureStatus]]; + printf ("%s\n", [string UTF8String]); + } + ASSERT([frame provisionalDataSource]); // Make sure we only set this once per test. If it gets cleared, and then set again, we might // end up doing two dumps for one test. @@ -166,7 +178,7 @@ NSString *string = [NSString stringWithFormat:@"%@ - didCommitLoadForFrame", [frame _drt_descriptionSuitableForTestResult]]; printf ("%s\n", [string UTF8String]); } - + ASSERT(![frame provisionalDataSource]); ASSERT([frame dataSource]); @@ -190,7 +202,7 @@ ASSERT_NOT_REACHED(); return; } - + ASSERT([frame provisionalDataSource]); [self webView:sender locationChangeDone:error forDataSource:[frame provisionalDataSource]]; } @@ -204,7 +216,7 @@ NSString *string = [NSString stringWithFormat:@"%@ - didFinishLoadForFrame", [frame _drt_descriptionSuitableForTestResult]]; printf ("%s\n", [string UTF8String]); } - + // FIXME: This call to displayIfNeeded can be removed when <rdar://problem/5092361> is fixed. // After that is fixed, we will reenable painting after WebCore is done loading the document, // and this call will no longer be needed. @@ -220,7 +232,7 @@ NSString *string = [NSString stringWithFormat:@"%@ - didFailLoadWithError", [frame _drt_descriptionSuitableForTestResult]]; printf ("%s\n", [string UTF8String]); } - + ASSERT(![frame provisionalDataSource]); ASSERT([frame dataSource]); @@ -233,7 +245,7 @@ NSString *string = [NSString stringWithFormat:@"?? - windowScriptObjectAvailable"]; printf ("%s\n", [string UTF8String]); } - + ASSERT_NOT_REACHED(); } @@ -314,7 +326,7 @@ NSString *string = [NSString stringWithFormat:@"%@ - didReceiveTitle: %@", [frame _drt_descriptionSuitableForTestResult], title]; printf ("%s\n", [string UTF8String]); } - + if (gLayoutTestController->dumpTitleChanges()) printf("TITLE CHANGED: %s\n", [title UTF8String]); } diff --git a/WebKitTools/DumpRenderTree/mac/InternalHeaders/WebKit/WebHTMLRepresentationInternal.h b/WebKitTools/DumpRenderTree/mac/InternalHeaders/WebKit/WebHTMLRepresentationInternal.h deleted file mode 100644 index b3d421d..0000000 --- a/WebKitTools/DumpRenderTree/mac/InternalHeaders/WebKit/WebHTMLRepresentationInternal.h +++ /dev/null @@ -1 +0,0 @@ -#include "../../../../WebKit/mac/WebView/WebHTMLRepresentationInternal.h" diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm index c5d5a90..150b6f9 100644 --- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm +++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm @@ -371,7 +371,7 @@ void LayoutTestController::setGeolocationPermission(bool allow) [[[mainFrame webView] UIDelegate] didSetMockGeolocationPermission]; } -void LayoutTestController::setMockSpeechInputResult(JSStringRef result) +void LayoutTestController::setMockSpeechInputResult(JSStringRef result, JSStringRef language) { // FIXME: Implement for speech input layout tests. // See https://bugs.webkit.org/show_bug.cgi?id=39485. diff --git a/WebKitTools/DumpRenderTree/mac/WebArchiveDumpSupport.mm b/WebKitTools/DumpRenderTree/mac/WebArchiveDumpSupport.mm deleted file mode 100644 index 7c52c6a..0000000 --- a/WebKitTools/DumpRenderTree/mac/WebArchiveDumpSupport.mm +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "WebArchiveDumpSupport.h" - -#import <Foundation/Foundation.h> -#import <WebKit/WebArchive.h> -#import <WebKit/WebHTMLRepresentationInternal.h> - -static void convertMIMEType(NSMutableString *mimeType) -{ -#ifdef BUILDING_ON_LEOPARD - // Workaround for <rdar://problem/5539824> on Leopard - if ([mimeType isEqualToString:@"text/xml"]) - [mimeType setString:@"application/xml"]; -#endif - // Workaround for <rdar://problem/6234318> with Dashcode 2.0 - if ([mimeType isEqualToString:@"application/x-javascript"]) - [mimeType setString:@"text/javascript"]; -} - -static void convertWebResourceDataToString(NSMutableDictionary *resource) -{ - NSMutableString *mimeType = [resource objectForKey:@"WebResourceMIMEType"]; - convertMIMEType(mimeType); - - if ([mimeType hasPrefix:@"text/"] || [[WebHTMLRepresentation supportedNonImageMIMETypes] containsObject:mimeType]) { - NSString *textEncodingName = [resource objectForKey:@"WebResourceTextEncodingName"]; - NSStringEncoding stringEncoding; - if ([textEncodingName length] > 0) - stringEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)textEncodingName)); - else - stringEncoding = NSUTF8StringEncoding; - - NSData *data = [resource objectForKey:@"WebResourceData"]; - NSString *dataAsString = [[NSString alloc] initWithData:data encoding:stringEncoding]; - if (dataAsString) - [resource setObject:dataAsString forKey:@"WebResourceData"]; - [dataAsString release]; - } -} - -static void normalizeHTTPResponseHeaderFields(NSMutableDictionary *fields) -{ - // Normalize headers - if ([fields objectForKey:@"Date"]) - [fields setObject:@"Sun, 16 Nov 2008 17:00:00 GMT" forKey:@"Date"]; - if ([fields objectForKey:@"Last-Modified"]) - [fields setObject:@"Sun, 16 Nov 2008 16:55:00 GMT" forKey:@"Last-Modified"]; - if ([fields objectForKey:@"Etag"]) - [fields setObject:@"\"301925-21-45c7d72d3e780\"" forKey:@"Etag"]; - if ([fields objectForKey:@"Server"]) - [fields setObject:@"Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.7l PHP/5.2.6" forKey:@"Server"]; - - // Remove headers - if ([fields objectForKey:@"Connection"]) - [fields removeObjectForKey:@"Connection"]; - if ([fields objectForKey:@"Keep-Alive"]) - [fields removeObjectForKey:@"Keep-Alive"]; -} - -static void normalizeWebResourceURL(NSMutableString *webResourceURL) -{ - static int fileUrlLength = [(NSString *)@"file://" length]; - NSRange layoutTestsWebArchivePathRange = [webResourceURL rangeOfString:@"/LayoutTests/" options:NSBackwardsSearch]; - if (layoutTestsWebArchivePathRange.location == NSNotFound) - return; - NSRange currentWorkingDirectoryRange = NSMakeRange(fileUrlLength, layoutTestsWebArchivePathRange.location - fileUrlLength); - [webResourceURL replaceCharactersInRange:currentWorkingDirectoryRange withString:@""]; -} - -static void convertWebResourceResponseToDictionary(NSMutableDictionary *propertyList) -{ - NSURLResponse *response = nil; - NSData *responseData = [propertyList objectForKey:@"WebResourceResponse"]; // WebResourceResponseKey in WebResource.m - if ([responseData isKindOfClass:[NSData class]]) { - // Decode NSURLResponse - NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData]; - response = [unarchiver decodeObjectForKey:@"WebResourceResponse"]; // WebResourceResponseKey in WebResource.m - [unarchiver finishDecoding]; - [unarchiver release]; - } - - NSMutableDictionary *responseDictionary = [[NSMutableDictionary alloc] init]; - - NSMutableString *urlString = [[[response URL] description] mutableCopy]; - normalizeWebResourceURL(urlString); - [responseDictionary setObject:urlString forKey:@"URL"]; - [urlString release]; - - NSMutableString *mimeTypeString = [[response MIMEType] mutableCopy]; - convertMIMEType(mimeTypeString); - [responseDictionary setObject:mimeTypeString forKey:@"MIMEType"]; - [mimeTypeString release]; - - NSString *textEncodingName = [response textEncodingName]; - if (textEncodingName) - [responseDictionary setObject:textEncodingName forKey:@"textEncodingName"]; - [responseDictionary setObject:[NSNumber numberWithLongLong:[response expectedContentLength]] forKey:@"expectedContentLength"]; - - if ([response isKindOfClass:[NSHTTPURLResponse class]]) { - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; - - NSMutableDictionary *allHeaderFields = [[httpResponse allHeaderFields] mutableCopy]; - normalizeHTTPResponseHeaderFields(allHeaderFields); - [responseDictionary setObject:allHeaderFields forKey:@"allHeaderFields"]; - [allHeaderFields release]; - - [responseDictionary setObject:[NSNumber numberWithInt:[httpResponse statusCode]] forKey:@"statusCode"]; - } - - [propertyList setObject:responseDictionary forKey:@"WebResourceResponse"]; - [responseDictionary release]; -} - -static NSInteger compareResourceURLs(id resource1, id resource2, void *context) -{ - NSString *url1 = [resource1 objectForKey:@"WebResourceURL"]; - NSString *url2 = [resource2 objectForKey:@"WebResourceURL"]; - - return [url1 compare:url2]; -} - -NSString *serializeWebArchiveToXML(WebArchive *webArchive) -{ - NSString *errorString; - NSMutableDictionary *propertyList = [NSPropertyListSerialization propertyListFromData:[webArchive data] - mutabilityOption:NSPropertyListMutableContainersAndLeaves - format:NULL - errorDescription:&errorString]; - if (!propertyList) - return errorString; - - NSMutableArray *resources = [NSMutableArray arrayWithCapacity:1]; - [resources addObject:propertyList]; - - while ([resources count]) { - NSMutableDictionary *resourcePropertyList = [resources objectAtIndex:0]; - [resources removeObjectAtIndex:0]; - - NSMutableDictionary *mainResource = [resourcePropertyList objectForKey:@"WebMainResource"]; - normalizeWebResourceURL([mainResource objectForKey:@"WebResourceURL"]); - convertWebResourceDataToString(mainResource); - - // Add subframeArchives to list for processing - NSMutableArray *subframeArchives = [resourcePropertyList objectForKey:@"WebSubframeArchives"]; // WebSubframeArchivesKey in WebArchive.m - if (subframeArchives) - [resources addObjectsFromArray:subframeArchives]; - - NSMutableArray *subresources = [resourcePropertyList objectForKey:@"WebSubresources"]; // WebSubresourcesKey in WebArchive.m - NSEnumerator *enumerator = [subresources objectEnumerator]; - NSMutableDictionary *subresourcePropertyList; - while ((subresourcePropertyList = [enumerator nextObject])) { - normalizeWebResourceURL([subresourcePropertyList objectForKey:@"WebResourceURL"]); - convertWebResourceResponseToDictionary(subresourcePropertyList); - convertWebResourceDataToString(subresourcePropertyList); - } - - // Sort the subresources so they're always in a predictable order for the dump - if (NSArray *sortedSubresources = [subresources sortedArrayUsingFunction:compareResourceURLs context:nil]) - [resourcePropertyList setObject:sortedSubresources forKey:@"WebSubresources"]; - } - - NSData *xmlData = [NSPropertyListSerialization dataFromPropertyList:propertyList - format:NSPropertyListXMLFormat_v1_0 - errorDescription:&errorString]; - if (!xmlData) - return errorString; - - NSMutableString *string = [[[NSMutableString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding] autorelease]; - - // Replace "Apple Computer" with "Apple" in the DTD declaration. - NSRange range = [string rangeOfString:@"-//Apple Computer//"]; - if (range.location != NSNotFound) - [string replaceCharactersInRange:range withString:@"-//Apple//"]; - - return string; -} diff --git a/WebKitTools/DumpRenderTree/mac/WebArchiveDumpSupportMac.mm b/WebKitTools/DumpRenderTree/mac/WebArchiveDumpSupportMac.mm new file mode 100644 index 0000000..c273087 --- /dev/null +++ b/WebKitTools/DumpRenderTree/mac/WebArchiveDumpSupportMac.mm @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "WebArchiveDumpSupport.h" + +#import <CFNetwork/CFHTTPMessage.h> +#import <Foundation/Foundation.h> +#import <WebKit/WebHTMLRepresentation.h> +#import <wtf/RetainPtr.h> + +extern "C" { + +enum CFURLCacheStoragePolicy { + kCFURLCacheStorageAllowed = 0, + kCFURLCacheStorageAllowedInMemoryOnly = 1, + kCFURLCacheStorageNotAllowed = 2 +}; +typedef enum CFURLCacheStoragePolicy CFURLCacheStoragePolicy; + +extern const CFStringRef kCFHTTPVersion1_1; + +CFURLResponseRef CFURLResponseCreate(CFAllocatorRef alloc, CFURLRef URL, CFStringRef mimeType, SInt64 expectedContentLength, CFStringRef textEncodingName, CFURLCacheStoragePolicy recommendedPolicy); +CFURLResponseRef CFURLResponseCreateWithHTTPResponse(CFAllocatorRef alloc, CFURLRef URL, CFHTTPMessageRef httpResponse, CFURLCacheStoragePolicy recommendedPolicy); +void CFURLResponseSetExpectedContentLength(CFURLResponseRef response, SInt64 length); +void CFURLResponseSetMIMEType(CFURLResponseRef response, CFStringRef mimeType); + +} + +CFURLResponseRef createCFURLResponseFromResponseData(CFDataRef responseData) +{ + // Decode NSURLResponse + RetainPtr<NSKeyedUnarchiver> unarchiver(AdoptNS, [[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)responseData]); + NSURLResponse *response = [unarchiver.get() decodeObjectForKey:@"WebResourceResponse"]; // WebResourceResponseKey in WebResource.m + [unarchiver.get() finishDecoding]; + + if (![response isKindOfClass:[NSHTTPURLResponse class]]) + return CFURLResponseCreate(kCFAllocatorDefault, (CFURLRef)[response URL], (CFStringRef)[response MIMEType], [response expectedContentLength], (CFStringRef)[response textEncodingName], kCFURLCacheStorageAllowed); + + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + + // NSURLResponse is not toll-free bridged to CFURLResponse. + RetainPtr<CFHTTPMessageRef> httpMessage(AdoptCF, CFHTTPMessageCreateResponse(kCFAllocatorDefault, [httpResponse statusCode], 0, kCFHTTPVersion1_1)); + + NSDictionary *headerFields = [httpResponse allHeaderFields]; + for (NSString *headerField in [headerFields keyEnumerator]) + CFHTTPMessageSetHeaderFieldValue(httpMessage.get(), (CFStringRef)headerField, (CFStringRef)[headerFields objectForKey:headerField]); + + return CFURLResponseCreateWithHTTPResponse(kCFAllocatorDefault, (CFURLRef)[response URL], httpMessage.get(), kCFURLCacheStorageAllowed); +} + +CFArrayRef supportedNonImageMIMETypes() +{ + return (CFArrayRef)[WebHTMLRepresentation supportedNonImageMIMETypes]; +} diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp index d36a074..f99ec4f 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp @@ -73,6 +73,7 @@ void LayoutTestController::reset() DumpRenderTreeSupportQt::dumpEditingCallbacks(false); DumpRenderTreeSupportQt::dumpFrameLoader(false); + DumpRenderTreeSupportQt::dumpUserGestureInFrameLoader(false); DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(false); DumpRenderTreeSupportQt::dumpResourceResponseMIMETypes(false); DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(true); @@ -246,6 +247,11 @@ void LayoutTestController::dumpFrameLoadCallbacks() DumpRenderTreeSupportQt::dumpFrameLoader(true); } +void LayoutTestController::dumpUserGestureInFrameLoadCallbacks() +{ + DumpRenderTreeSupportQt::dumpUserGestureInFrameLoader(true); +} + void LayoutTestController::dumpResourceLoadCallbacks() { DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(true); @@ -759,7 +765,7 @@ void LayoutTestController::setMockGeolocationPosition(double latitude, double lo DumpRenderTreeSupportQt::setMockGeolocationPosition(latitude, longitude, accuracy); } -void LayoutTestController::setMockSpeechInputResult(const QString& result) +void LayoutTestController::setMockSpeechInputResult(const QString& result, const QString& language) { // FIXME: Implement for speech input layout tests. // See https://bugs.webkit.org/show_bug.cgi?id=39485. diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h index 3684946..11d72e4 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h @@ -106,6 +106,7 @@ public slots: void handleErrorPages() { m_handleErrorPages = true; } void dumpEditingCallbacks(); void dumpFrameLoadCallbacks(); + void dumpUserGestureInFrameLoadCallbacks(); void dumpResourceLoadCallbacks(); void dumpResourceResponseMIMETypes(); void dumpHistoryCallbacks(); @@ -215,7 +216,7 @@ public slots: bool isGeolocationPermissionSet() const { return m_isGeolocationPermissionSet; } bool geolocationPermission() const { return m_geolocationPermission; } - void setMockSpeechInputResult(const QString& result); + void setMockSpeechInputResult(const QString& result, const QString& language); // Empty stub method to keep parity with object model exposed by global LayoutTestController. void abortModal() {} diff --git a/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro b/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro index 740ebb8..b958025 100644 --- a/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro +++ b/WebKitTools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro @@ -31,6 +31,7 @@ SOURCES = PluginObject.cpp \ Tests/DocumentOpenInDestroyStream.cpp \ Tests/NPRuntimeObjectFromDestroyedPlugin.cpp \ Tests/NPRuntimeRemoveProperty.cpp \ + Tests/NullNPPGetValuePointer.cpp \ Tests/PassDifferentNPPStruct.cpp \ Tests/PluginScriptableNPObjectInvokeDefault.cpp diff --git a/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp b/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp index 8c4e98d..14bb8ef 100644 --- a/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp +++ b/WebKitTools/DumpRenderTree/unix/TestNetscapePlugin/TestNetscapePlugin.cpp @@ -105,7 +105,7 @@ webkit_test_plugin_new_instance(NPMIMEType /*mimetype*/, } static NPError -webkit_test_plugin_destroy_instance(NPP instance, NPSavedData** /*save*/) +webkit_test_plugin_destroy_instance(NPP instance, NPSavedData** save) { PluginObject* obj = static_cast<PluginObject*>(instance->pdata); if (obj) { @@ -129,6 +129,8 @@ webkit_test_plugin_destroy_instance(NPP instance, NPSavedData** /*save*/) if (obj->onSetWindow) free(obj->onSetWindow); + obj->pluginTest->NPP_Destroy(save); + browser->releaseobject(&obj->header); } @@ -157,7 +159,7 @@ webkit_test_plugin_set_window(NPP instance, NPWindow *window) } - return NPERR_NO_ERROR; + return obj->pluginTest->NPP_SetWindow(instance, window); } static void executeScript(const PluginObject* obj, const char* script) @@ -386,6 +388,7 @@ NP_Initialize (NPNetscapeFuncs *aMozillaVTable, NPPluginFuncs *aPluginVTable) return NPERR_INVALID_FUNCTABLE_ERROR; browser = aMozillaVTable; + pluginFunctions = aPluginVTable; aPluginVTable->size = sizeof (NPPluginFuncs); aPluginVTable->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp index 67e5d4b..5138562 100644 --- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp @@ -1302,15 +1302,19 @@ int main(int argc, char* argv[]) standardPreferences->setJavaScriptEnabled(TRUE); standardPreferences->setDefaultFontSize(16); standardPreferences->setAcceleratedCompositingEnabled(true); + standardPreferences->setContinuousSpellCheckingEnabled(TRUE); if (printSupportedFeatures) { BOOL acceleratedCompositingAvailable; standardPreferences->acceleratedCompositingEnabled(&acceleratedCompositingAvailable); - BOOL threeDRenderingAvailable = + #if ENABLE(3D_RENDERING) - true; + // In theory, we could have a software-based 3D rendering implementation that we use when + // hardware-acceleration is not available. But we don't have any such software + // implementation, so 3D rendering is only available when hardware-acceleration is. + BOOL threeDRenderingAvailable = acceleratedCompositingAvailable; #else - false; + BOOL threeDRenderingAvailable = FALSE; #endif printf("SupportedFeatures:%s %s\n", acceleratedCompositingAvailable ? "AcceleratedCompositing" : "", threeDRenderingAvailable ? "3DRendering" : ""); diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj index 1cba86a..2f4908f 100644 --- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj +++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj @@ -18,7 +18,7 @@ <Configuration
Name="Debug|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops"
CharacterSet="1"
>
<Tool
@@ -91,7 +91,7 @@ <Configuration
Name="Release|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -165,7 +165,7 @@ <Configuration
Name="Debug_Internal|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops"
CharacterSet="1"
>
<Tool
@@ -237,7 +237,7 @@ <Configuration
Name="Debug_Cairo|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops;$(WebKitLibrariesDir)\tools\vsprops\WinCairo.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops;$(WebKitLibrariesDir)\tools\vsprops\WinCairo.vsprops"
CharacterSet="1"
>
<Tool
@@ -310,7 +310,7 @@ <Configuration
Name="Release_Cairo|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;$(WebKitLibrariesDir)\tools\vsprops\WinCairo.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;$(WebKitLibrariesDir)\tools\vsprops\WinCairo.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -384,7 +384,7 @@ <Configuration
Name="Debug_All|Win32"
ConfigurationType="1"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
CharacterSet="1"
>
<Tool
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h index e3497c9..27edaa6 100644 --- a/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h +++ b/WebKitTools/DumpRenderTree/win/DumpRenderTreeWin.h @@ -12,7 +12,7 @@ * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED diff --git a/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp b/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp index 32c02bd..71859cb 100644 --- a/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp +++ b/WebKitTools/DumpRenderTree/win/EditingDelegate.cpp @@ -353,3 +353,72 @@ HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeSelection( } return S_OK; } + +static int indexOfFirstWordCharacter(const TCHAR* text) +{ + const TCHAR* cursor = text; + while (*cursor && !isalpha(*cursor)) + ++cursor; + return *cursor ? (cursor - text) : -1; +}; + +static int wordLength(const TCHAR* text) +{ + const TCHAR* cursor = text; + while (*cursor && isalpha(*cursor)) + ++cursor; + return cursor - text; +}; + +HRESULT STDMETHODCALLTYPE EditingDelegate::checkSpellingOfString( + /* [in] */ IWebView* view, + /* [in] */ LPCTSTR text, + /* [in] */ int length, + /* [out] */ int* misspellingLocation, + /* [out] */ int* misspellingLength) +{ + static const TCHAR* misspelledWords[] = { + // These words are known misspelled words in webkit tests. + // If there are other misspelled words in webkit tests, please add them in + // this array. + TEXT("foo"), + TEXT("Foo"), + TEXT("baz"), + TEXT("fo"), + TEXT("LibertyF"), + TEXT("chello"), + TEXT("xxxtestxxx"), + TEXT("XXxxx"), + TEXT("Textx"), + TEXT("blockquoted"), + TEXT("asd"), + TEXT("Lorem"), + TEXT("Nunc"), + TEXT("Curabitur"), + TEXT("eu"), + TEXT("adlj"), + TEXT("adaasj"), + TEXT("sdklj"), + TEXT("jlkds"), + TEXT("jsaada"), + TEXT("jlda"), + TEXT("zz"), + TEXT("contentEditable"), + 0, + }; + + wstring textString(text, length); + int wordStart = indexOfFirstWordCharacter(textString.c_str()); + if (-1 == wordStart) + return S_OK; + wstring word = textString.substr(wordStart, wordLength(textString.c_str() + wordStart)); + for (size_t i = 0; misspelledWords[i]; ++i) { + if (word == misspelledWords[i]) { + *misspellingLocation = wordStart; + *misspellingLength = word.size(); + break; + } + } + + return S_OK; +} diff --git a/WebKitTools/DumpRenderTree/win/EditingDelegate.h b/WebKitTools/DumpRenderTree/win/EditingDelegate.h index 6dba675..7b7f418 100644 --- a/WebKitTools/DumpRenderTree/win/EditingDelegate.h +++ b/WebKitTools/DumpRenderTree/win/EditingDelegate.h @@ -127,7 +127,7 @@ public: /* [in] */ LPCTSTR text, /* [in] */ int length, /* [out] */ int *misspellingLocation, - /* [out] */ int *misspellingLength) { return E_NOTIMPL; } + /* [out] */ int *misspellingLength); virtual HRESULT STDMETHODCALLTYPE checkGrammarOfString( /* [in] */ IWebView *view, diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp index d2140d1..d7c41e0 100644 --- a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp +++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp @@ -405,7 +405,7 @@ void LayoutTestController::setGeolocationPermission(bool allow) setGeolocationPermissionCommon(allow); } -void LayoutTestController::setMockSpeechInputResult(JSStringRef result) +void LayoutTestController::setMockSpeechInputResult(JSStringRef result, JSStringRef language) { // FIXME: Implement for speech input layout tests. // See https://bugs.webkit.org/show_bug.cgi?id=39485. @@ -1391,8 +1391,13 @@ void LayoutTestController::abortModal() { } -bool LayoutTestController::hasSpellingMarker(int, int) +bool LayoutTestController::hasSpellingMarker(int from, int length) { - // FIXME: Implement this. - return false; + COMPtr<IWebFramePrivate> framePrivate(Query, frame); + if (!framePrivate) + return false; + BOOL ret = FALSE; + if (FAILED(framePrivate->hasSpellingMarker(from, length, &ret))) + return false; + return ret; } diff --git a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp index eefc587..32614c1 100644 --- a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp +++ b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp @@ -320,7 +320,7 @@ void LayoutTestController::setGeolocationPermission(bool allow) setGeolocationPermissionCommon(allow); } -void LayoutTestController::setMockSpeechInputResult(JSStringRef result) +void LayoutTestController::setMockSpeechInputResult(JSStringRef result, JSStringRef language) { // FIXME: Implement for speech input layout tests. // See https://bugs.webkit.org/show_bug.cgi?id=39485. @@ -528,4 +528,3 @@ JSRetainPtr<JSStringRef> LayoutTestController::pageSizeAndMarginsInPixels(int pa // FIXME: Implement return 0; } - diff --git a/WebKitTools/EWSTools/start-queue.sh b/WebKitTools/EWSTools/start-queue.sh index 1e0403f..7835e74 100755 --- a/WebKitTools/EWSTools/start-queue.sh +++ b/WebKitTools/EWSTools/start-queue.sh @@ -33,5 +33,5 @@ do git reset --hard git clean -f git svn rebase - ./WebKitTools/Scripts/webkit-patch $1 --no-confirm --exit-after-iteration 100 + ./WebKitTools/Scripts/webkit-patch $1 --no-confirm --exit-after-iteration 10 done diff --git a/WebKitTools/GNUmakefile.am b/WebKitTools/GNUmakefile.am index 5257ece..2700869 100644 --- a/WebKitTools/GNUmakefile.am +++ b/WebKitTools/GNUmakefile.am @@ -169,6 +169,8 @@ TestNetscapePlugin_libtestnetscapeplugin_la_SOURCES = \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/DocumentOpenInDestroyStream.cpp \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NPRuntimeObjectFromDestroyedPlugin.cpp \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NPRuntimeRemoveProperty.cpp \ + WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/NullNPPGetValuePointer.cpp \ + WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/PassDifferentNPPStruct.cpp \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/Tests/PluginScriptableNPObjectInvokeDefault.cpp \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp \ WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h \ diff --git a/WebKitTools/GtkLauncher/main.c b/WebKitTools/GtkLauncher/main.c index 17ed40f..4abee08 100644 --- a/WebKitTools/GtkLauncher/main.c +++ b/WebKitTools/GtkLauncher/main.c @@ -27,26 +27,24 @@ #include <gtk/gtk.h> #include <webkit/webkit.h> -static GtkWidget* main_window; -static GtkWidget* uri_entry; -static GtkStatusbar* main_statusbar; -static WebKitWebView* web_view; -static gchar* main_title; -static gdouble load_progress; -static guint status_context_id; +static gint window_count = 0; + +static GtkWidget* create_window (WebKitWebView** out_web_view); static void activate_uri_entry_cb (GtkWidget* entry, gpointer data) { + WebKitWebView *web_view = g_object_get_data (G_OBJECT (entry), "web-view"); const gchar* uri = gtk_entry_get_text (GTK_ENTRY (entry)); g_assert (uri); webkit_web_view_load_uri (web_view, uri); } static void -update_title (GtkWindow* window) +update_title (GtkWindow* window, WebKitWebView* web_view) { - GString* string = g_string_new (main_title); + GString *string = g_string_new (webkit_web_view_get_title(web_view)); + gdouble load_progress = webkit_web_view_get_progress (web_view) * 100; g_string_append (string, " - WebKit Launcher"); if (load_progress < 100) g_string_append_printf (string, " (%f%%)", load_progress); @@ -56,25 +54,24 @@ update_title (GtkWindow* window) } static void -link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpointer data) +link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, GtkStatusbar* statusbar) { + guint status_context_id = + GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (statusbar), "link-hover-context")); /* underflow is allowed */ - gtk_statusbar_pop (main_statusbar, status_context_id); + gtk_statusbar_pop (statusbar, status_context_id); if (link) - gtk_statusbar_push (main_statusbar, status_context_id, link); + gtk_statusbar_push (statusbar, status_context_id, link); } static void -notify_title_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +notify_title_cb (WebKitWebView* web_view, GParamSpec* pspec, GtkWidget* window) { - if (main_title) - g_free (main_title); - main_title = g_strdup (webkit_web_view_get_title(web_view)); - update_title (GTK_WINDOW (main_window)); + update_title (GTK_WINDOW (window), web_view); } static void -notify_load_status_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +notify_load_status_cb (WebKitWebView* web_view, GParamSpec* pspec, GtkWidget* uri_entry) { if (webkit_web_view_get_load_status (web_view) == WEBKIT_LOAD_COMMITTED) { WebKitWebFrame* frame = webkit_web_view_get_main_frame (web_view); @@ -85,43 +82,68 @@ notify_load_status_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data } static void -notify_progress_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data) +notify_progress_cb (WebKitWebView* web_view, GParamSpec* pspec, GtkWidget* window) { - load_progress = webkit_web_view_get_progress (web_view) * 100; - update_title (GTK_WINDOW (main_window)); + update_title (GTK_WINDOW (window), web_view); } static void -destroy_cb (GtkWidget* widget, gpointer data) +destroy_cb (GtkWidget* widget, GtkWidget* window) { - gtk_main_quit (); + if (g_atomic_int_dec_and_test (&window_count)) + gtk_main_quit (); } static void -go_back_cb (GtkWidget* widget, gpointer data) +go_back_cb (GtkWidget* widget, WebKitWebView* web_view) { webkit_web_view_go_back (web_view); } static void -go_forward_cb (GtkWidget* widget, gpointer data) +go_forward_cb (GtkWidget* widget, WebKitWebView* web_view) { webkit_web_view_go_forward (web_view); } +static WebKitWebView* +create_web_view_cb (WebKitWebView* web_view, WebKitWebFrame* web_frame, GtkWidget* window) +{ + WebKitWebView *new_web_view; + create_window (&new_web_view); + return new_web_view; +} + +static gboolean +web_view_ready_cb (WebKitWebView* web_view, GtkWidget* window) +{ + gtk_widget_grab_focus (GTK_WIDGET (web_view)); + gtk_widget_show_all (window); + return FALSE; +} + +static gboolean +close_web_view_cb (WebKitWebView* web_view, GtkWidget* window) +{ + gtk_widget_destroy (window); + return TRUE; +} + static GtkWidget* -create_browser () +create_browser (GtkWidget* window, GtkWidget* uri_entry, GtkWidget* statusbar, WebKitWebView* web_view) { GtkWidget* scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ()); gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (web_view)); - g_signal_connect (web_view, "notify::title", G_CALLBACK (notify_title_cb), web_view); - g_signal_connect (web_view, "notify::load-status", G_CALLBACK (notify_load_status_cb), web_view); - g_signal_connect (web_view, "notify::progress", G_CALLBACK (notify_progress_cb), web_view); - g_signal_connect (web_view, "hovering-over-link", G_CALLBACK (link_hover_cb), web_view); + g_signal_connect (web_view, "notify::title", G_CALLBACK (notify_title_cb), window); + g_signal_connect (web_view, "notify::load-status", G_CALLBACK (notify_load_status_cb), uri_entry); + g_signal_connect (web_view, "notify::progress", G_CALLBACK (notify_progress_cb), window); + g_signal_connect (web_view, "hovering-over-link", G_CALLBACK (link_hover_cb), statusbar); + g_signal_connect (web_view, "create-web-view", G_CALLBACK (create_web_view_cb), window); + g_signal_connect (web_view, "web-view-ready", G_CALLBACK (web_view_ready_cb), window); + g_signal_connect (web_view, "close-web-view", G_CALLBACK (close_web_view_cb), window); return scrolled_window; } @@ -129,14 +151,16 @@ create_browser () static GtkWidget* create_statusbar () { - main_statusbar = GTK_STATUSBAR (gtk_statusbar_new ()); - status_context_id = gtk_statusbar_get_context_id (main_statusbar, "Link Hover"); + GtkStatusbar *statusbar = GTK_STATUSBAR (gtk_statusbar_new ()); + guint status_context_id = gtk_statusbar_get_context_id (statusbar, "Link Hover"); + g_object_set_data (G_OBJECT (statusbar), "link-hover-context", + GUINT_TO_POINTER(status_context_id)); - return (GtkWidget*)main_statusbar; + return GTK_WIDGET (statusbar); } static GtkWidget* -create_toolbar () +create_toolbar (GtkWidget* uri_entry, WebKitWebView* web_view) { GtkWidget* toolbar = gtk_toolbar_new (); @@ -151,23 +175,23 @@ create_toolbar () /* the back button */ item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK); - g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_back_cb), NULL); + g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_back_cb), web_view); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); /* The forward button */ item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD); - g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_forward_cb), NULL); + g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_forward_cb), web_view); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); /* The URL entry */ item = gtk_tool_item_new (); gtk_tool_item_set_expand (item, TRUE); - uri_entry = gtk_entry_new (); gtk_container_add (GTK_CONTAINER (item), uri_entry); g_signal_connect (G_OBJECT (uri_entry), "activate", G_CALLBACK (activate_uri_entry_cb), NULL); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); /* The go button */ + g_object_set_data (G_OBJECT (uri_entry), "web-view", web_view); item = gtk_tool_button_new_from_stock (GTK_STOCK_OK); g_signal_connect_swapped (G_OBJECT (item), "clicked", G_CALLBACK (activate_uri_entry_cb), (gpointer)uri_entry); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); @@ -176,13 +200,36 @@ create_toolbar () } static GtkWidget* -create_window () +create_window (WebKitWebView** out_web_view) { - GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + WebKitWebView *web_view; + GtkWidget *vbox; + GtkWidget *window; + GtkWidget *uri_entry; + GtkWidget *statusbar; + + g_atomic_int_inc (&window_count); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), 800, 600); gtk_widget_set_name (window, "GtkLauncher"); + + web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ()); + uri_entry = gtk_entry_new (); + + vbox = gtk_vbox_new (FALSE, 0); + statusbar = create_statusbar (web_view); + gtk_box_pack_start (GTK_BOX (vbox), create_toolbar (uri_entry, web_view), FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), create_browser (window, uri_entry, statusbar, web_view), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), statusbar, FALSE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (window), vbox); + g_signal_connect (window, "destroy", G_CALLBACK (destroy_cb), NULL); + if (out_web_view) + *out_web_view = web_view; + return window; } @@ -201,17 +248,14 @@ static gchar* filenameToURL(const char* filename) int main (int argc, char* argv[]) { + WebKitWebView *web_view; + GtkWidget *main_window; + gtk_init (&argc, &argv); if (!g_thread_supported ()) g_thread_init (NULL); - GtkWidget* vbox = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), create_toolbar (), FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), create_browser (), TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), create_statusbar (), FALSE, FALSE, 0); - - main_window = create_window (); - gtk_container_add (GTK_CONTAINER (main_window), vbox); + main_window = create_window (&web_view); gchar *uri = (gchar*) (argc > 1 ? argv[1] : "http://www.google.com/"); gchar *fileURL = filenameToURL(uri); diff --git a/WebKitTools/MiniBrowser/mac/BrowserWindowController.m b/WebKitTools/MiniBrowser/mac/BrowserWindowController.m index 6fad41a..4f2b63f 100644 --- a/WebKitTools/MiniBrowser/mac/BrowserWindowController.m +++ b/WebKitTools/MiniBrowser/mac/BrowserWindowController.m @@ -305,6 +305,16 @@ static void didRemoveFrameFromHierarchy(WKPageRef page, WKFrameRef frame, WKType LOG(@"didRemoveFrameFromHierarchy"); } +static void didDisplayInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) +{ + LOG(@"didDisplayInsecureContentForFrame"); +} + +static void didRunInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) +{ + LOG(@"didRunInsecureContentForFrame"); +} + static void didStartProgress(WKPageRef page, const void *clientInfo) { [(BrowserWindowController *)clientInfo didStartProgress]; @@ -361,7 +371,7 @@ static void decidePolicyForMIMEType(WKPageRef page, WKStringRef MIMEType, WKURLR #pragma mark UI Client Callbacks -static WKPageRef createNewPage(WKPageRef page, const void* clientInfo) +static WKPageRef createNewPage(WKPageRef page, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton button, const void* clientInfo) { LOG(@"createNewPage"); BrowserWindowController *controller = [[BrowserWindowController alloc] initWithPageNamespace:WKPageGetPageNamespace(page)]; @@ -479,11 +489,6 @@ static void mouseDidMoveOverElement(WKPageRef page, WKEventModifiers modifiers, LOG(@"mouseDidMoveOverElement"); } -static void contentsSizeChanged(WKPageRef page, int width, int height, WKFrameRef frame, const void *clientInfo) -{ - LOG(@"contentsSizeChanged"); -} - static WKRect getWindowFrame(WKPageRef page, const void* clientInfo) { NSRect rect = [[(BrowserWindowController *)clientInfo window] frame]; @@ -547,6 +552,8 @@ static bool runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKF didFirstLayoutForFrame, didFirstVisuallyNonEmptyLayoutForFrame, didRemoveFrameFromHierarchy, + didDisplayInsecureContentForFrame, + didRunInsecureContentForFrame, didStartProgress, didChangeProgress, didFinishProgress, @@ -577,12 +584,20 @@ static bool runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKF runJavaScriptPrompt, setStatusText, mouseDidMoveOverElement, - contentsSizeChanged, 0, /* didNotHandleKeyEvent */ + 0, /* toolbarsAreVisible */ + 0, /* setToolbarsAreVisible */ + 0, /* menuBarIsVisible */ + 0, /* setMenuBarIsVisible */ + 0, /* statusBarIsVisible */ + 0, /* setStatusBarIsVisible */ + 0, /* isResizable */ + 0, /* setIsResizable */ getWindowFrame, setWindowFrame, runBeforeUnloadConfirmPanel, - 0 /* didDraw */ + 0, /* didDraw */ + 0 /* pageDidScroll */ }; WKPageSetPageUIClient(_webView.pageRef, &uiClient); } diff --git a/WebKitTools/MiniBrowser/win/BrowserView.cpp b/WebKitTools/MiniBrowser/win/BrowserView.cpp index 76848fa..b182740 100644 --- a/WebKitTools/MiniBrowser/win/BrowserView.cpp +++ b/WebKitTools/MiniBrowser/win/BrowserView.cpp @@ -39,7 +39,7 @@ BrowserView::BrowserView() // UI Client Callbacks -static WKPageRef createNewPage(WKPageRef page, const void* clientInfo) +static WKPageRef createNewPage(WKPageRef page, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void* clientInfo) { BrowserWindow* browserWindow = BrowserWindow::create(); browserWindow->createWindow(0, 0, 800, 600); @@ -78,10 +78,6 @@ static void mouseDidMoveOverElement(WKPageRef page, WKEventModifiers modifiers, { } -static void contentsSizeChanged(WKPageRef page, int width, int height, WKFrameRef frame, const void *clientInfo) -{ -} - void BrowserView::create(RECT webViewRect, BrowserWindow* parentWindow) { assert(!m_webView); @@ -109,8 +105,20 @@ void BrowserView::create(RECT webViewRect, BrowserWindow* parentWindow) runJavaScriptPrompt, setStatusText, mouseDidMoveOverElement, - contentsSizeChanged, - 0 /* didNotHandleKeyEvent */ + 0, /* didNotHandleKeyEvent */ + 0, /* toolbarsAreVisible */ + 0, /* setToolbarsAreVisible */ + 0, /* menuBarIsVisible */ + 0, /* setMenuBarIsVisible */ + 0, /* statusBarIsVisible */ + 0, /* setStatusBarIsVisible */ + 0, /* isResizable */ + 0, /* setIsResizable */ + 0, /* getWindowFrame */ + 0, /* setWindowFrame */ + 0, /* runBeforeUnloadConfirmPanel */ + 0, /* didDraw */ + 0 /* pageDidScroll */ }; WKPageSetPageUIClient(WKViewGetPage(m_webView), &uiClient); diff --git a/WebKitTools/QtTestBrowser/fpstimer.cpp b/WebKitTools/QtTestBrowser/fpstimer.cpp index 3b72cef..eae3d9c 100644 --- a/WebKitTools/QtTestBrowser/fpstimer.cpp +++ b/WebKitTools/QtTestBrowser/fpstimer.cpp @@ -37,11 +37,12 @@ #define FPS_MEASURE_INTERVAL 1000 / 60 FpsTimer::FpsTimer(QObject* parent) - : QObject(parent) + : QObject(parent) + , m_timer(0) { } -int FpsTimer::numFrames(int spanMillis) +int FpsTimer::numFrames(int spanMillis) const { const QTime now = QTime::currentTime(); @@ -63,13 +64,15 @@ void FpsTimer::start() void FpsTimer::stop() { + if (!m_timer) + return; killTimer(m_timer); m_frames.clear(); } void FpsTimer::timerEvent(QTimerEvent* event) { - if (event->timerId() != m_timer) + if (event->timerId() != m_timer) return; m_frames.append(QTime::currentTime()); if (m_frames.length() > MAX_FRAMES_SAVED) diff --git a/WebKitTools/QtTestBrowser/fpstimer.h b/WebKitTools/QtTestBrowser/fpstimer.h index accecd2..eed1198 100644 --- a/WebKitTools/QtTestBrowser/fpstimer.h +++ b/WebKitTools/QtTestBrowser/fpstimer.h @@ -37,7 +37,7 @@ class FpsTimer : public QObject { public: FpsTimer(QObject* parent = 0); - int numFrames(int spanMillis = 1000); + int numFrames(int spanMillis = 1000) const; public Q_SLOTS: void start(); diff --git a/WebKitTools/QtTestBrowser/launcherwindow.cpp b/WebKitTools/QtTestBrowser/launcherwindow.cpp index df29f11..e5e49be 100644 --- a/WebKitTools/QtTestBrowser/launcherwindow.cpp +++ b/WebKitTools/QtTestBrowser/launcherwindow.cpp @@ -70,28 +70,14 @@ void LauncherWindow::init() resize(800, 600); #endif - initializeView(); - - connect(page(), SIGNAL(loadStarted()), this, SLOT(loadStarted())); - connect(page(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); - connect(page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), - this, SLOT(showLinkHover(const QString&, const QString&))); - connect(this, SIGNAL(enteredFullScreenMode(bool)), this, SLOT(toggleFullScreenMode(bool))); - - applyPrefs(); - m_inspector = new WebInspector(splitter); #ifndef QT_NO_PROPERTIES if (!m_windowOptions.inspectorUrl.isEmpty()) m_inspector->setProperty("_q_inspectorUrl", m_windowOptions.inspectorUrl); #endif - m_inspector->setPage(page()); m_inspector->hide(); connect(this, SIGNAL(destroyed()), m_inspector, SLOT(deleteLater())); - if (m_windowOptions.remoteInspectorPort) - page()->setProperty("_q_webInspectorServerPort", m_windowOptions.remoteInspectorPort); - // the zoom values are chosen to be like in Mozilla Firefox 3 if (!m_zoomLevels.count()) { m_zoomLevels << 30 << 50 << 67 << 80 << 90; @@ -100,6 +86,8 @@ void LauncherWindow::init() } grabZoomKeys(true); + + initializeView(); } void LauncherWindow::initializeView() @@ -132,10 +120,24 @@ void LauncherWindow::initializeView() m_view = view; } + m_touchMocking = false; + + connect(page(), SIGNAL(loadStarted()), this, SLOT(loadStarted())); + connect(page(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); + connect(page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), + this, SLOT(showLinkHover(const QString&, const QString&))); + connect(this, SIGNAL(enteredFullScreenMode(bool)), this, SLOT(toggleFullScreenMode(bool))); + + applyPrefs(); + + m_inspector->setPage(page()); + m_inspector->hide(); + + if (m_windowOptions.remoteInspectorPort) + page()->setProperty("_q_webInspectorServerPort", m_windowOptions.remoteInspectorPort); + if (url.isValid()) page()->mainFrame()->load(url); - - m_touchMocking = false; } void LauncherWindow::applyPrefs() @@ -213,6 +215,7 @@ void LauncherWindow::createChrome() QMenu* windowMenu = menuBar()->addMenu("&Window"); QAction* toggleFullScreen = windowMenu->addAction("Toggle FullScreen", this, SIGNAL(enteredFullScreenMode(bool))); + toggleFullScreen->setShortcut(Qt::Key_F11); toggleFullScreen->setCheckable(true); toggleFullScreen->setChecked(false); // When exit fullscreen mode by clicking on the exit area (bottom right corner) we must @@ -672,6 +675,8 @@ void LauncherWindow::toggleWebView(bool graphicsBased) { m_windowOptions.useGraphicsView = graphicsBased; initializeView(); + menuBar()->clear(); + createChrome(); } void LauncherWindow::toggleAcceleratedCompositing(bool toggle) diff --git a/WebKitTools/QueueStatusServer/model/queues_unittest.py b/WebKitTools/QueueStatusServer/model/queues_unittest.py index 33070a8..cfa7fcd 100644 --- a/WebKitTools/QueueStatusServer/model/queues_unittest.py +++ b/WebKitTools/QueueStatusServer/model/queues_unittest.py @@ -68,6 +68,13 @@ class QueueTest(unittest.TestCase): self._assert_name_with_underscores("chromium-ews", "chromium_ews") self._assert_name_with_underscores("commit-queue", "commit_queue") + def test_style_queue_is_ews(self): + # For now we treat the style-queue as an EWS since most users would + # describe it as such. If is_ews() ever needs to mean "builds the patch" + # or similar, then we will need to adjust all callers. + self.assertTrue(Queue("style-queue").is_ews()) + self.assertTrue("style-queue" in map(Queue.name, Queue.all_ews())) + if __name__ == '__main__': unittest.main() diff --git a/WebKitTools/Scripts/VCSUtils.pm b/WebKitTools/Scripts/VCSUtils.pm index 8d7e766..faed7ed 100644 --- a/WebKitTools/Scripts/VCSUtils.pm +++ b/WebKitTools/Scripts/VCSUtils.pm @@ -68,7 +68,9 @@ BEGIN { &parsePatch &pathRelativeToSVNRepositoryRootForPath &prepareParsedPatch + &removeEOL &runPatchCommand + &scmMoveOrRenameFile &scmToggleExecutableBit &setChangeLogDateAndReviewer &svnRevisionForDirectory @@ -412,6 +414,7 @@ sub canonicalizePath($) sub removeEOL($) { my ($line) = @_; + return "" unless $line; $line =~ s/[\r\n]+$//g; return $line; diff --git a/WebKitTools/Scripts/build-webkit b/WebKitTools/Scripts/build-webkit index e7f9d1f..da336fe 100755 --- a/WebKitTools/Scripts/build-webkit +++ b/WebKitTools/Scripts/build-webkit @@ -1,6 +1,6 @@ #!/usr/bin/perl -w -# Copyright (C) 2005, 2006 Apple Inc. All rights reserved. +# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. # Copyright (C) 2009 Google Inc. All rights reserved. # Copyright (C) 2010 moiji-mobile.com All rights reserved. # @@ -57,27 +57,69 @@ my $prefixPath; my $makeArgs; my $startTime = time(); -my ($linkPrefetchSupport, $accelerated2dCanvasSupport, $threeDCanvasSupport, $threeDRenderingSupport, $channelMessagingSupport, $clientBasedGeolocationSupport, $databaseSupport, $datagridSupport, $datalistSupport, - $domStorageSupport, $eventsourceSupport, $filtersSupport, $geolocationSupport, $iconDatabaseSupport, $imageResizerSupport, $indexedDatabaseSupport, $inputSpeechSupport, - $javaScriptDebuggerSupport, $mathmlSupport, $offlineWebApplicationSupport, $rubySupport, $systemMallocSupport, $sandboxSupport, $sharedWorkersSupport, - $svgSupport, $svgAnimationSupport, $svgAsImageSupport, $svgDOMObjCBindingsSupport, $svgFontsSupport, - $svgForeignObjectSupport, $svgUseSupport, $videoSupport, $webSocketsSupport, $webTimingSupport, $wmlSupport, $wcssSupport, $xhtmlmpSupport, $workersSupport, - $xpathSupport, $xsltSupport, $coverageSupport, $notificationsSupport, $blobSupport, $tiledBackingStoreSupport, - $fileWriterSupport, $fileSystemSupport, $directoryUploadSupport, $deviceOrientationSupport); +my ( + $threeDCanvasSupport, + $threeDRenderingSupport, + $accelerated2dCanvasSupport, + $blobSupport, + $channelMessagingSupport, + $clientBasedGeolocationSupport, + $coverageSupport, + $databaseSupport, + $datagridSupport, + $datalistSupport, + $deviceOrientationSupport, + $directoryUploadSupport, + $domStorageSupport, + $eventsourceSupport, + $fileSystemSupport, + $filtersSupport, + $fullscreenAPISupport, + $geolocationSupport, + $iconDatabaseSupport, + $imageResizerSupport, + $indexedDatabaseSupport, + $inputSpeechSupport, + $javaScriptDebuggerSupport, + $linkPrefetchSupport, + $mathmlSupport, + $meterTagSupport, + $notificationsSupport, + $offlineWebApplicationSupport, + $progressTagSupport, + $rubySupport, + $sharedWorkersSupport, + $svgSupport, + $svgAnimationSupport, + $svgAsImageSupport, + $svgDOMObjCBindingsSupport, + $svgFontsSupport, + $svgForeignObjectSupport, + $svgUseSupport, + $systemMallocSupport, + $tiledBackingStoreSupport, + $videoSupport, + $wcssSupport, + $webAudioSupport, + $webSocketsSupport, + $webTimingSupport, + $wmlSupport, + $workersSupport, + $xhtmlmpSupport, + $xpathSupport, + $xsltSupport, +); my @features = ( - { option => "link-prefetch", desc => "Toggle pre fetching support", - define => "ENABLE_LINK_PREFETCH", default => 0, value => \$linkPrefetchSupport }, - - { option => "accelerated-2d-canvas", desc => "Toggle accelerated 2D canvas support", - define => "ENABLE_ACCELERATED_2D_CANVAS", default => 0, value => \$accelerated2dCanvasSupport }, - { option => "3d-canvas", desc => "Toggle 3D canvas support", define => "ENABLE_3D_CANVAS", default => (isAppleMacWebKit() && !isTiger() && !isLeopard()), value => \$threeDCanvasSupport }, { option => "3d-rendering", desc => "Toggle 3D rendering support", define => "ENABLE_3D_RENDERING", default => (isAppleMacWebKit() && !isTiger()), value => \$threeDRenderingSupport }, + { option => "accelerated-2d-canvas", desc => "Toggle accelerated 2D canvas support", + define => "ENABLE_ACCELERATED_2D_CANVAS", default => 0, value => \$accelerated2dCanvasSupport }, + { option => "blob", desc => "Toggle Blob support", define => "ENABLE_BLOB", default => (isAppleMacWebKit()), value => \$blobSupport }, @@ -95,10 +137,13 @@ my @features = ( { option => "datagrid", desc => "Toggle Datagrid Support", define => "ENABLE_DATAGRID", default => 0, value => \$datagridSupport }, - + { option => "datalist", desc => "Toggle HTML5 datalist support", define => "ENABLE_DATALIST", default => 1, value => \$datalistSupport }, - + + { option => "device-orientation", desc => "Toggle DeviceOrientation support", + define => "ENABLE_DEVICE_ORIENTATION", default => 0, value => \$deviceOrientationSupport }, + { option => "directory-upload", desc => "Toogle Directory upload support", define => "ENABLE_DIRECTORY_UPLOAD", default => 0, value => \$directoryUploadSupport }, @@ -108,15 +153,21 @@ my @features = ( { option => "eventsource", desc => "Toggle server-sent events support", define => "ENABLE_EVENTSOURCE", default => 1, value => \$eventsourceSupport }, + { option => "file-system", desc => "Toggle FileSystem support", + define => "ENABLE_FILE_SYSTEM", default => 0, value => \$fileSystemSupport }, + { option => "filters", desc => "Toggle Filters support", define => "ENABLE_FILTERS", default => (isAppleWebKit() || isGtk() || isQt() || isEfl()), value => \$filtersSupport }, + { option => "fullscreen-api", desc => "Toggle Fullscreen API support", + define => "ENABLE_FULLSCREEN_API", default => isAppleMacWebKit(), value => \$fullscreenAPISupport }, + { option => "geolocation", desc => "Toggle Geolocation support", define => "ENABLE_GEOLOCATION", default => (isAppleWebKit() || isGtk()), value => \$geolocationSupport }, { option => "icon-database", desc => "Toggle Icon database support", define => "ENABLE_ICONDATABASE", default => 1, value => \$iconDatabaseSupport }, - + { option => "image-resizer", desc => "Toggle Image Resizer API support", define => "ENABLE_IMAGE_RESIZER", default => 0, value => \$imageResizerSupport }, @@ -129,24 +180,30 @@ my @features = ( { option => "javascript-debugger", desc => "Toggle JavaScript Debugger/Profiler support", define => "ENABLE_JAVASCRIPT_DEBUGGER", default => 1, value => \$javaScriptDebuggerSupport }, + { option => "link-prefetch", desc => "Toggle pre fetching support", + define => "ENABLE_LINK_PREFETCH", default => 0, value => \$linkPrefetchSupport }, + { option => "mathml", desc => "Toggle MathML support", define => "ENABLE_MATHML", default => 1, value => \$mathmlSupport }, + { option => "meter-tag", desc => "Meter Tag support", + define => "ENABLE_METER_TAG", default => !isGtk() && !isAppleWinWebKit(), value => \$meterTagSupport }, + { option => "notifications", desc => "Toggle Desktop Notifications Support", define => "ENABLE_NOTIFICATIONS", default => 0, value => \$notificationsSupport }, { option => "offline-web-applications", desc => "Toggle Offline Web Application Support", define => "ENABLE_OFFLINE_WEB_APPLICATIONS", default => 1, value => \$offlineWebApplicationSupport }, + { option => "progress-tag", desc => "Progress Tag support", + define => "ENABLE_PROGRESS_TAG", default => 1, value => \$progressTagSupport }, + { option => "ruby", desc => "Toggle HTML5 Ruby support", define => "ENABLE_RUBY", default => 1, value => \$rubySupport }, { option => "system-malloc", desc => "Toggle system allocator instead of TCmalloc", define => "USE_SYSTEM_MALLOC", default => 0, value => \$systemMallocSupport }, - { option => "sandbox", desc => "Toggle HTML5 Sandboxed iframe support", - define => "ENABLE_SANDBOX", default => 1, value => \$sandboxSupport }, - { option => "shared-workers", desc => "Toggle SharedWorkers support", define => "ENABLE_SHARED_WORKERS", default => (isAppleWebKit() || isGtk()), value => \$sharedWorkersSupport }, @@ -177,6 +234,12 @@ my @features = ( { option => "video", desc => "Toggle Video support", define => "ENABLE_VIDEO", default => (isAppleWebKit() || isGtk()), value => \$videoSupport }, + { option => "wcss", desc => "Toggle WCSS support", + define => "ENABLE_WCSS", default => 0, value => \$wcssSupport }, + + { option => "web-audio", desc => "Toggle Web Audio support", + define => "ENABLE_WEB_AUDIO", default => 0, value=> \$webAudioSupport }, + { option => "web-sockets", desc => "Toggle Web Sockets support", define => "ENABLE_WEB_SOCKETS", default => 1, value=> \$webSocketsSupport }, @@ -186,26 +249,17 @@ my @features = ( { option => "wml", desc => "Toggle WML support", define => "ENABLE_WML", default => 0, value => \$wmlSupport }, - { option => "xhtmlmp", desc => "Toggle XHTML-MP support", - define => "ENABLE_XHTMLMP", default => 0, value => \$xhtmlmpSupport }, - - { option => "wcss", desc => "Toggle WCSS support", - define => "ENABLE_WCSS", default => 0, value => \$wcssSupport }, - { option => "workers", desc => "Toggle Web Workers support", define => "ENABLE_WORKERS", default => (isAppleWebKit() || isGtk()), value => \$workersSupport }, + { option => "xhtmlmp", desc => "Toggle XHTML-MP support", + define => "ENABLE_XHTMLMP", default => 0, value => \$xhtmlmpSupport }, + { option => "xpath", desc => "Toggle XPath support", define => "ENABLE_XPATH", default => 1, value => \$xpathSupport }, { option => "xslt", desc => "Toggle XSLT support", define => "ENABLE_XSLT", default => 1, value => \$xsltSupport }, - - { option => "file-system", desc => "Toggle FileSystem support", - define => "ENABLE_FILE_SYSTEM", default => 0, value => \$fileSystemSupport }, - - { option => "device-orientation", desc => "Toggle DeviceOrientation support", - define => "ENABLE_DEVICE_ORIENTATION", default => 0, value => \$deviceOrientationSupport }, ); # Update defaults from Qt's project file @@ -473,18 +527,24 @@ for my $dir (@projects) { $result = buildVisualStudioProject("win/WebKit.vcproj/WebKit.sln", $clean); } } + # Various build* calls above may change the CWD. + chdirWebKit(); if (exitStatus($result)) { + my $scriptDir = relativeScriptsDir(); + if (usingVisualStudioExpress()) { + # Visual Studio Express is so lame it can't stdout build failures. + # So we find its logs and dump them to the console ourselves. + system(File::Spec->catfile($scriptDir, "print-vse-failure-logs")); + } if (isAppleWinWebKit()) { print "\n\n===== BUILD FAILED ======\n\n"; - my $scriptDir = relativeScriptsDir(); print "Please ensure you have run $scriptDir/update-webkit to install dependencies.\n\n"; my $baseProductDir = baseProductDir(); print "You can view build errors by checking the BuildLog.htm files located at:\n$baseProductDir/obj/<project>/<config>.\n"; } exit exitStatus($result); } - chdirWebKit(); } # Don't report the "WebKit is now built" message after a clean operation. diff --git a/WebKitTools/Scripts/old-run-webkit-tests b/WebKitTools/Scripts/old-run-webkit-tests index a468b4d..e40b3ad 100755 --- a/WebKitTools/Scripts/old-run-webkit-tests +++ b/WebKitTools/Scripts/old-run-webkit-tests @@ -527,11 +527,37 @@ if (isCygwin()) { if (!$hasAcceleratedCompositing) { $ignoredDirectories{'compositing'} = 1; + + # This test has slightly different floating-point rounding when accelerated + # compositing is enabled. + $ignoredFiles{'svg/custom/use-on-symbol-inside-pattern.svg'} = 1; + + if (isAppleWebKit()) { + # In Apple's ports, the default controls for <video> contain a "full + # screen" button only if accelerated compositing is enabled. + $ignoredFiles{'media/controls-after-reload.html'} = 1; + $ignoredFiles{'media/controls-drag-timebar.html'} = 1; + $ignoredFiles{'media/controls-strict.html'} = 1; + $ignoredFiles{'media/controls-styling.html'} = 1; + $ignoredFiles{'media/video-controls-rendering.html'} = 1; + $ignoredFiles{'media/video-display-toggle.html'} = 1; + $ignoredFiles{'media/video-no-audio.html'} = 1; + } + + # Here we're using !$hasAcceleratedCompositing as a proxy for "is a headless XP machine" (like + # our test slaves). Headless XP machines can neither support accelerated compositing nor pass + # this test, so skipping the test here is expedient, if a little sloppy. See + # <http://webkit.org/b/48333>. + $ignoredFiles{'platform/win/plugins/npn-invalidate-rect-invalidates-window.html'} = 1 if isAppleWinWebKit(); } if (!$has3DRendering) { $ignoredDirectories{'animations/3d'} = 1; $ignoredDirectories{'transforms/3d'} = 1; + + # These tests use the -webkit-transform-3d media query. + $ignoredFiles{'fast/media/mq-transform-02.html'} = 1; + $ignoredFiles{'fast/media/mq-transform-03.html'} = 1; } if (!checkWebCoreFeatureSupport("3D Canvas", 0)) { diff --git a/WebKitTools/Scripts/prepare-ChangeLog b/WebKitTools/Scripts/prepare-ChangeLog index 608c9ce..ad84e4f 100755 --- a/WebKitTools/Scripts/prepare-ChangeLog +++ b/WebKitTools/Scripts/prepare-ChangeLog @@ -1302,7 +1302,7 @@ sub statusCommand(@) if ($isSVN) { $command = "$SVN stat $filesString"; } elsif ($isGit) { - $command = "$GIT diff -r --name-status -C -C -M " . diffFromToString(); + $command = "$GIT diff -r --name-status -M -C " . diffFromToString(); $command .= " -- $filesString" unless $gitCommit; } @@ -1317,7 +1317,7 @@ sub createPatchCommand($) if ($isSVN) { $command = "'$FindBin::Bin/svn-create-patch' $changedFilesString"; } elsif ($isGit) { - $command = "$GIT diff -C -C -M " . diffFromToString(); + $command = "$GIT diff -M -C " . diffFromToString(); $command .= " -- $changedFilesString" unless $gitCommit; } diff --git a/WebKitTools/Scripts/print-vse-failure-logs b/WebKitTools/Scripts/print-vse-failure-logs new file mode 100755 index 0000000..cec806e --- /dev/null +++ b/WebKitTools/Scripts/print-vse-failure-logs @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# Copyright (c) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# This is a very simple script designed to crawl the build directory +# for visual studio express build logs and print them to stdout. + +from __future__ import with_statement + +import codecs +import os.path +import os + +from webkitpy.common.system.executive import Executive + + +# This is just enough to make the win-ews bot useable. Others who +# actually use Windows should feel encouraged to improve this class, +# including just printing the text instead of the raw html. +class PrintVisualStudioExpressLogs(object): + def __init__(self): + self._executive = Executive() + + def _find_buildlogs(self, build_directory): + build_log_paths = [] + for dirpath, dirnames, filenames in os.walk(build_directory): + for file_name in filenames: + if file_name == "BuildLog.htm": + file_path = os.path.join(dirpath, file_name) + build_log_paths.append(file_path) + return build_log_paths + + def _obj_directory(self): + scripts_directory = os.path.dirname(__file__) + build_directory_script_path = os.path.join(scripts_directory, "webkit-build-directory") + # FIXME: ports/webkit.py should provide the build directory in a nice API. + # NOTE: The windows VSE build does not seem to use different directories + # for Debug and Release. + build_directory = self._executive.run_command([build_directory_script_path, "--top-level"]).rstrip() + return os.path.join(build_directory, "obj") + + def main(self): + obj_directory = self._obj_directory() + build_log_paths = self._find_buildlogs(obj_directory) + + print "Found %s Visual Studio Express Build Logs:\n%s" % (len(build_log_paths), "\n".join(build_log_paths)) + + for build_log_path in build_log_paths: + print "%s:\n" % build_log_path + with codecs.open(build_log_path, "r", "utf-16") as build_log: + print build_log.read() + + +if __name__ == '__main__': + PrintVisualStudioExpressLogs().main() diff --git a/WebKitTools/Scripts/webkitdirs.pm b/WebKitTools/Scripts/webkitdirs.pm index fa85667..2c1d8da 100644 --- a/WebKitTools/Scripts/webkitdirs.pm +++ b/WebKitTools/Scripts/webkitdirs.pm @@ -1186,6 +1186,12 @@ sub buildXCodeProject($$@) return system "xcodebuild", "-project", "$project.xcodeproj", @extraOptions; } +sub usingVisualStudioExpress() +{ + determineConfigurationForVisualStudio(); + return $willUseVCExpressWhenBuilding; +} + sub buildVisualStudioProject { my ($project, $clean) = @_; diff --git a/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/removeEOL.pl b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/removeEOL.pl new file mode 100644 index 0000000..8bd8e90 --- /dev/null +++ b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/removeEOL.pl @@ -0,0 +1,56 @@ +#!/usr/bin/perl +# +# Copyright (C) Research In Motion Limited 2010. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Research In Motion Limited nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Unit tests of VCSUtils::removeEOL(). + +use Test::Simple tests => 5; +use VCSUtils; + +my $title; + +# New test +$title = "removeEOL: Undefined argument."; +ok(removeEOL(undef) eq ""); + +# New test +$title = "removeEOL: Line with Windows line ending."; +ok(removeEOL("This line ends with a Windows line ending.\r\n") eq "This line ends with a Windows line ending."); + +# New test +$title = "removeEOL: Line with Unix line ending."; +ok(removeEOL("This line ends with a Unix line ending.\n") eq "This line ends with a Unix line ending."); + +# New test +$title = "removeEOL: Line with Mac line ending."; +ok(removeEOL("This line ends with a Mac line ending.\r") eq "This line ends with a Mac line ending."); + +# New test +$title = "removeEOL: Line with a mix of line endings."; +ok(removeEOL("This line contains a mix of line endings.\r\n\r\n\r\r\n\n\n\n") eq "This line contains a mix of line endings."); diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/__init__.py b/WebKitTools/Scripts/webkitpy/common/checkout/__init__.py index ef65bee..597dcbd 100644 --- a/WebKitTools/Scripts/webkitpy/common/checkout/__init__.py +++ b/WebKitTools/Scripts/webkitpy/common/checkout/__init__.py @@ -1 +1,3 @@ # Required for Python to search this directory for module files + +from api import Checkout diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/api.py b/WebKitTools/Scripts/webkitpy/common/checkout/api.py index 72cad8d..dbe1e84 100644 --- a/WebKitTools/Scripts/webkitpy/common/checkout/api.py +++ b/WebKitTools/Scripts/webkitpy/common/checkout/api.py @@ -32,6 +32,7 @@ import StringIO from webkitpy.common.checkout.changelog import ChangeLog from webkitpy.common.checkout.commitinfo import CommitInfo from webkitpy.common.checkout.scm import CommitMessage +from webkitpy.common.memoized import memoized from webkitpy.common.net.bugzilla import parse_bug_id from webkitpy.common.system.executive import Executive, run_command, ScriptError from webkitpy.common.system.deprecated_logging import log @@ -59,6 +60,7 @@ class Checkout(object): changed_files = self._scm.changed_files_for_revision(revision) return [self._latest_entry_for_changelog_at_revision(path, revision) for path in changed_files if self._is_path_to_changelog(path)] + @memoized def commit_info_for_revision(self, revision): committer_email = self._scm.committer_email_for_revision(revision) changelog_entries = self.changelog_entries_for_revision(revision) @@ -98,8 +100,8 @@ class Checkout(object): def modified_non_changelogs(self, git_commit, changed_files=None): return self._modified_files_matching_predicate(git_commit, lambda path: not self._is_path_to_changelog(path), changed_files=changed_files) - def commit_message_for_this_commit(self, git_commit): - changelog_paths = self.modified_changelogs(git_commit) + def commit_message_for_this_commit(self, git_commit, changed_files=None): + changelog_paths = self.modified_changelogs(git_commit, changed_files) if not len(changelog_paths): raise ScriptError(message="Found no modified ChangeLogs, cannot create a commit message.\n" "All changes require a ChangeLog. See:\n" @@ -120,16 +122,16 @@ class Checkout(object): revisions = set(sum(map(self._scm.revisions_changing_file, paths), [])) return set(map(self.commit_info_for_revision, revisions)) - def suggested_reviewers(self, git_commit): - changed_files = self.modified_non_changelogs(git_commit) + def suggested_reviewers(self, git_commit, changed_files=None): + changed_files = self.modified_non_changelogs(git_commit, changed_files) commit_infos = self.recent_commit_infos_for_files(changed_files) reviewers = [commit_info.reviewer() for commit_info in commit_infos if commit_info.reviewer()] reviewers.extend([commit_info.author() for commit_info in commit_infos if commit_info.author() and commit_info.author().can_review]) return sorted(set(reviewers)) - def bug_id_for_this_commit(self, git_commit): + def bug_id_for_this_commit(self, git_commit, changed_files=None): try: - return parse_bug_id(self.commit_message_for_this_commit(git_commit).message()) + return parse_bug_id(self.commit_message_for_this_commit(git_commit, changed_files).message()) except ScriptError, e: pass # We might not have ChangeLogs. diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py b/WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py index d7bd95e..1f97abd 100644 --- a/WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py +++ b/WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py @@ -114,7 +114,7 @@ class CommitMessageForThisCommitTest(unittest.TestCase): # ChangeLog is difficult to mock at current. def test_commit_message_for_this_commit(self): checkout = Checkout(None) - checkout.modified_changelogs = lambda git_commit: ["ChangeLog1", "ChangeLog2"] + checkout.modified_changelogs = lambda git_commit, changed_files=None: ["ChangeLog1", "ChangeLog2"] output = OutputCapture() expected_stderr = "Parsing ChangeLog: ChangeLog1\nParsing ChangeLog: ChangeLog2\n" commit_message = output.assert_outputs(self, checkout.commit_message_for_this_commit, @@ -163,7 +163,7 @@ class CheckoutTest(unittest.TestCase): def test_bug_id_for_this_commit(self): scm = Mock() checkout = Checkout(scm) - checkout.commit_message_for_this_commit = lambda git_commit: CommitMessage(ChangeLogEntry(_changelog1entry1).contents().splitlines()) + checkout.commit_message_for_this_commit = lambda git_commit, changed_files=None: CommitMessage(ChangeLogEntry(_changelog1entry1).contents().splitlines()) self.assertEqual(checkout.bug_id_for_this_commit(git_commit=None), 36629) def test_modified_changelogs(self): diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py index 4bd9ed6..9b602c3 100644 --- a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py +++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py @@ -36,6 +36,7 @@ import shutil from webkitpy.common.system.executive import Executive, run_command, ScriptError from webkitpy.common.system.deprecated_logging import error, log +from webkitpy.common.memoized import memoized def find_checkout_root(): @@ -319,7 +320,6 @@ class SVN(SCM): def __init__(self, cwd): SCM.__init__(self, cwd) - self.cached_version = None self._bogus_dir = None @staticmethod @@ -369,16 +369,20 @@ class SVN(SCM): find_output = self.run(find_args, cwd=home_directory, error_handler=Executive.ignore_error).rstrip() return find_output and os.path.isfile(os.path.join(home_directory, find_output)) + @memoized def svn_version(self): - if not self.cached_version: - self.cached_version = self.run(['svn', '--version', '--quiet']) - - return self.cached_version + return self.run(['svn', '--version', '--quiet']) def working_directory_is_clean(self): return self.run(["svn", "diff"], cwd=self.checkout_root, decode_output=False) == "" def clean_working_directory(self): + # Make sure there are no locks lying around from a previously aborted svn invocation. + # This is slightly dangerous, as it's possible the user is running another svn process + # on this checkout at the same time. However, it's much more likely that we're running + # under windows and svn just sucks (or the user interrupted svn and it failed to clean up). + self.run(["svn", "cleanup"], cwd=self.checkout_root) + # svn revert -R is not as awesome as git reset --hard. # It will leave added files around, causing later svn update # calls to fail on the bots. We make this mirror git reset --hard @@ -432,6 +436,7 @@ class SVN(SCM): def revisions_changing_file(self, path, limit=5): revisions = [] + # svn log will exit(1) (and thus self.run will raise) if the path does not exist. log_command = ['svn', 'log', '--quiet', '--limit=%s' % limit, path] for line in self.run(log_command, cwd=self.checkout_root).splitlines(): match = re.search('^r(?P<revision>\d+) ', line) @@ -565,6 +570,7 @@ class SVN(SCM): dir, base = os.path.split(path) return self.run(['svn', 'pget', pname, base], cwd=dir).encode('utf-8').rstrip("\n") + # All git-specific logic should go here. class Git(SCM): def __init__(self, cwd): @@ -667,7 +673,8 @@ class Git(SCM): return self._changes_files_for_commit(commit_id) def revisions_changing_file(self, path, limit=5): - commit_ids = self.run(["git", "log", "--pretty=format:%H", "-%s" % limit, path]).splitlines() + # git rev-list head --remove-empty --limit=5 -- path would be equivalent. + commit_ids = self.run(["git", "log", "--remove-empty", "--pretty=format:%H", "-%s" % limit, "--", path]).splitlines() return filter(lambda revision: revision, map(self.svn_revision_from_git_commit, commit_ids)) def conflicted_files(self): @@ -696,21 +703,29 @@ class Git(SCM): # FIXME: This should probably use cwd=self.checkout_root return self.run(['git', 'diff', '--binary', "--no-ext-diff", "--full-index", "-M", self.merge_base(git_commit), "--"] + changed_files, decode_output=False) - @classmethod - def git_commit_from_svn_revision(cls, revision): - # FIXME: This should probably use cwd=self.checkout_root - git_commit = run_command(['git', 'svn', 'find-rev', 'r%s' % revision]).rstrip() - # git svn find-rev always exits 0, even when the revision is not found. - if not git_commit: - raise ScriptError(message='Failed to find git commit for revision %s, your checkout likely needs an update.' % revision) - return git_commit + def _run_git_svn_find_rev(self, arg): + # git svn find-rev always exits 0, even when the revision or commit is not found. + return self.run(['git', 'svn', 'find-rev', arg], cwd=self.checkout_root).rstrip() - def svn_revision_from_git_commit(self, commit_id): + def _string_to_int_or_none(self, string): try: - return int(self.run(['git', 'svn', 'find-rev', commit_id]).rstrip()) + return int(string) except ValueError, e: return None + @memoized + def git_commit_from_svn_revision(self, svn_revision): + git_commit = self._run_git_svn_find_rev('r%s' % svn_revision) + if not git_commit: + # FIXME: Alternatively we could offer to update the checkout? Or return None? + raise ScriptError(message='Failed to find git commit for revision %s, your checkout likely needs an update.' % svn_revision) + return git_commit + + @memoized + def svn_revision_from_git_commit(self, git_commit): + svn_revision = self._run_git_svn_find_rev(git_commit) + return self._string_to_int_or_none(svn_revision) + def contents_at_revision(self, path, revision): """Returns a byte array (str()) containing the contents of path @ revision in the repository.""" diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py index 4aa5279..8af9ad5 100644 --- a/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py +++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py @@ -760,6 +760,15 @@ Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA== self.do_test_diff_for_file() self.assertFalse(os.path.exists(self.bogus_dir)) + def test_svn_lock(self): + svn_root_lock_path = ".svn/lock" + write_into_file_at_path(svn_root_lock_path, "", "utf-8") + # webkit-patch uses a Checkout object and runs update-webkit, just use svn update here. + self.assertRaises(ScriptError, run_command, ['svn', 'update']) + self.scm.clean_working_directory() + self.assertFalse(os.path.exists(svn_root_lock_path)) + run_command(['svn', 'update']) # Should succeed and not raise. + class GitTest(SCMTest): diff --git a/WebKitTools/Scripts/webkitpy/common/config/__init__.py b/WebKitTools/Scripts/webkitpy/common/config/__init__.py index 62d129e..ef65bee 100644 --- a/WebKitTools/Scripts/webkitpy/common/config/__init__.py +++ b/WebKitTools/Scripts/webkitpy/common/config/__init__.py @@ -1,6 +1 @@ # Required for Python to search this directory for module files - -import re - -codereview_server_host = "wkrietveld.appspot.com" -codereview_server_url = "https://%s/" % codereview_server_host diff --git a/WebKitTools/Scripts/webkitpy/common/config/committers.py b/WebKitTools/Scripts/webkitpy/common/config/committers.py index f768cf9..71d764c 100644 --- a/WebKitTools/Scripts/webkitpy/common/config/committers.py +++ b/WebKitTools/Scripts/webkitpy/common/config/committers.py @@ -137,6 +137,7 @@ committers_unable_to_review = [ Committer("Keishi Hattori", "keishi@webkit.org", "keishi"), Committer("Kelly Norton", "knorton@google.com"), Committer("Kent Hansen", "kent.hansen@nokia.com", "khansen"), + Committer("Kimmo Kinnunen", ["kimmo.t.kinnunen@nokia.com", "kimmok@iki.fi", "ktkinnun@webkit.org"], "kimmok"), Committer("Kinuko Yasuda", "kinuko@chromium.org", "kinuko"), Committer("Krzysztof Kowalczyk", "kkowalczyk@gmail.com"), Committer("Kwang Yul Seo", ["kwangyul.seo@gmail.com", "skyul@company100.net", "kseo@webkit.org"], "kwangseo"), @@ -146,6 +147,7 @@ committers_unable_to_review = [ Committer("Luiz Agostini", ["luiz@webkit.org", "luiz.agostini@openbossa.org"], "lca"), Committer("Mads Ager", "ager@chromium.org"), Committer("Marcus Voltis Bulach", "bulach@chromium.org"), + Committer("Mario Sanchez Prada", ["msanchez@igalia.com", "mario@webkit.org"]), Committer("Matt Delaney", "mdelaney@apple.com"), Committer("Matt Lilek", ["webkit@mattlilek.com", "pewtermoose@webkit.org"]), Committer("Matt Perry", "mpcomplete@chromium.org"), @@ -213,7 +215,7 @@ reviewers_list = [ Reviewer("Andreas Kling", ["kling@webkit.org", "andreas.kling@nokia.com"], "kling"), Reviewer("Antonio Gomes", ["tonikitoo@webkit.org", "agomes@rim.com"], "tonikitoo"), Reviewer("Antti Koivisto", ["koivisto@iki.fi", "antti@apple.com", "antti.j.koivisto@nokia.com"], "anttik"), - Reviewer("Ariya Hidayat", ["ariya@sencha.com", "ariya.hidayat@gmail.com", "ariya@webkit.org"], "ariya"), + Reviewer("Ariya Hidayat", ["ariya.hidayat@gmail.com", "ariya@sencha.com", "ariya@webkit.org"], "ariya"), Reviewer("Beth Dakin", "bdakin@apple.com", "dethbakin"), Reviewer("Brady Eidson", "beidson@apple.com", "bradee-oh"), Reviewer("Cameron Zwarich", ["zwarich@apple.com", "cwzwarich@apple.com", "cwzwarich@webkit.org"]), diff --git a/WebKitTools/Scripts/webkitpy/common/memoized.py b/WebKitTools/Scripts/webkitpy/common/memoized.py new file mode 100644 index 0000000..dc844a5 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/common/memoized.py @@ -0,0 +1,55 @@ +# Copyright (c) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Python does not (yet) seem to provide automatic memoization. So we've +# written a small decorator to do so. + +import functools + + +class memoized(object): + def __init__(self, function): + self._function = function + self._results_cache = {} + + def __call__(self, *args): + try: + return self._results_cache[args] + except KeyError: + # If we didn't find the args in our cache, call and save the results. + result = self._function(*args) + self._results_cache[args] = result + return result + # FIXME: We may need to handle TypeError here in the case + # that "args" is not a valid dictionary key. + + # Use python "descriptor" protocol __get__ to appear + # invisible during property access. + def __get__(self, instance, owner): + # Return a function partial with obj already bound as self. + return functools.partial(self.__call__, instance) diff --git a/WebKitTools/Scripts/webkitpy/common/memoized_unittest.py b/WebKitTools/Scripts/webkitpy/common/memoized_unittest.py new file mode 100644 index 0000000..dd7c793 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/common/memoized_unittest.py @@ -0,0 +1,65 @@ +# Copyright (c) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import unittest + +from webkitpy.common.memoized import memoized + + +class _TestObject(object): + def __init__(self): + self.callCount = 0 + + @memoized + def memoized_add(self, argument): + """testing docstring""" + self.callCount += 1 + if argument is None: + return None # Avoid the TypeError from None + 1 + return argument + 1 + + +class MemoizedTest(unittest.TestCase): + def test_caching(self): + test = _TestObject() + test.callCount = 0 + self.assertEqual(test.memoized_add(1), 2) + self.assertEqual(test.callCount, 1) + self.assertEqual(test.memoized_add(1), 2) + self.assertEqual(test.callCount, 1) + + # Validate that callCount is working as expected. + self.assertEqual(test.memoized_add(2), 3) + self.assertEqual(test.callCount, 2) + + def test_tearoff(self): + test = _TestObject() + # Make sure that get()/tear-offs work: + tearoff = test.memoized_add + self.assertEqual(tearoff(4), 5) + self.assertEqual(test.callCount, 1) diff --git a/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py b/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py index 94519a7..1cc8e2e 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py +++ b/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py @@ -113,9 +113,6 @@ class Attachment(object): def commit_queue(self): return self._attachment_dictionary.get("commit-queue") - def in_rietveld(self): - return self._attachment_dictionary.get("in-rietveld") - def url(self): # FIXME: This should just return # self._bugzilla().attachment_url_for_id(self.id()). scm_unittest.py @@ -221,9 +218,6 @@ class Bug(object): # a valid committer. return filter(lambda patch: patch.committer(), patches) - def in_rietveld_queue_patches(self): - return [patch for patch in self.patches() if patch.in_rietveld() == None] - # A container for all of the logic for making and parsing buzilla queries. class BugzillaQueries(object): @@ -287,16 +281,6 @@ class BugzillaQueries(object): return sum([self._fetch_bug(bug_id).commit_queued_patches() for bug_id in self.fetch_bug_ids_from_commit_queue()], []) - def fetch_first_patch_from_rietveld_queue(self): - # rietveld-queue processes all patches that don't have in-rietveld set. - query_url = "buglist.cgi?query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&field0-0-0=flagtypes.name&type0-0-0=notsubstring&value0-0-0=in-rietveld&field0-1-0=attachments.ispatch&type0-1-0=equals&value0-1-0=1&order=Last+Changed&field0-2-0=attachments.isobsolete&type0-2-0=equals&value0-2-0=0" - bugs = self._fetch_bug_ids_advanced_query(query_url) - if not len(bugs): - return None - - patches = self._fetch_bug(bugs[0]).in_rietveld_queue_patches() - return patches[0] if len(patches) else None - def _fetch_bug_ids_from_review_queue(self): review_queue_url = "buglist.cgi?query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&field0-0-0=flagtypes.name&type0-0-0=equals&value0-0-0=review?" return self._fetch_bug_ids_advanced_query(review_queue_url) @@ -502,8 +486,6 @@ class Bugzilla(object): self._parse_attachment_flag( element, 'review', attachment, 'reviewer_email') self._parse_attachment_flag( - element, 'in-rietveld', attachment, 'rietveld_uploader_email') - self._parse_attachment_flag( element, 'commit-queue', attachment, 'committer_email') return attachment @@ -591,11 +573,12 @@ class Bugzilla(object): self.authenticated = True return + credentials = Credentials(self.bug_server_host, git_prefix="bugzilla") + attempts = 0 while not self.authenticated: attempts += 1 - (username, password) = Credentials( - self.bug_server_host, git_prefix="bugzilla").read_credentials() + username, password = credentials.read_credentials() log("Logging in as %s..." % username) self.browser.open(self.bug_server_url + @@ -766,8 +749,6 @@ class Bugzilla(object): return self.browser.find_control(type='select', nr=0) elif flag_name == "commit-queue": return self.browser.find_control(type='select', nr=1) - elif flag_name == "in-rietveld": - return self.browser.find_control(type='select', nr=2) raise Exception("Don't know how to find flag named \"%s\"" % flag_name) def clear_attachment_flags(self, diff --git a/WebKitTools/Scripts/webkitpy/common/net/bugzilla_unittest.py b/WebKitTools/Scripts/webkitpy/common/net/bugzilla_unittest.py index 3a454d6..df1fcf6 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/bugzilla_unittest.py +++ b/WebKitTools/Scripts/webkitpy/common/net/bugzilla_unittest.py @@ -83,11 +83,6 @@ class BugzillaTest(unittest.TestCase): status="+" setter="two@test.com" /> - <flag name="in-rietveld" - id="17933" - status="+" - setter="three@test.com" - /> </attachment> ''' _expected_example_attachment_parsing = { @@ -103,8 +98,6 @@ class BugzillaTest(unittest.TestCase): 'reviewer_email' : 'one@test.com', 'commit-queue' : '+', 'committer_email' : 'two@test.com', - 'in-rietveld': '+', - 'rietveld_uploader_email': 'three@test.com', 'attacher_email' : 'christian.plesner.hansen@gmail.com', } diff --git a/WebKitTools/Scripts/webkitpy/common/net/credentials.py b/WebKitTools/Scripts/webkitpy/common/net/credentials.py index 1c3e6c0..30480b3 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/credentials.py +++ b/WebKitTools/Scripts/webkitpy/common/net/credentials.py @@ -48,6 +48,7 @@ except ImportError: class Credentials(object): + _environ_prefix = "webkit_bugzilla_" def __init__(self, host, git_prefix=None, executive=None, cwd=os.getcwd(), keyring=keyring): @@ -58,8 +59,17 @@ class Credentials(object): self._keyring = keyring def _credentials_from_git(self): - return [Git.read_git_config(self.git_prefix + "username"), - Git.read_git_config(self.git_prefix + "password")] + try: + if not Git.in_working_directory(self.cwd): + return (None, None) + return (Git.read_git_config(self.git_prefix + "username"), + Git.read_git_config(self.git_prefix + "password")) + except OSError, e: + # Catch and ignore OSError exceptions such as "no such file + # or directory" (OSError errno 2), which imply that the Git + # command cannot be found/is not installed. + pass + return (None, None) def _keychain_value_with_label(self, label, source_text): match = re.search("%s\"(?P<value>.+)\"" % label, @@ -110,21 +120,28 @@ class Credentials(object): else: return [None, None] - def read_credentials(self): - username = None - password = None + def _read_environ(self, key): + environ_key = self._environ_prefix + key + return os.environ.get(environ_key.upper()) - try: - if Git.in_working_directory(self.cwd): - (username, password) = self._credentials_from_git() - except OSError, e: - # Catch and ignore OSError exceptions such as "no such file - # or directory" (OSError errno 2), which imply that the Git - # command cannot be found/is not installed. - pass + def _credentials_from_environment(self): + return (self._read_environ("username"), self._read_environ("password")) + + def _offer_to_store_credentials_in_keyring(self, username, password): + if not self._keyring: + return + if not User().confirm("Store password in system keyring?", User.DEFAULT_NO): + return + self._keyring.set_password(self.host, username, password) + def read_credentials(self): + username, password = self._credentials_from_environment() + # FIXME: We don't currently support pulling the username from one + # source and the password from a separate source. + if not username or not password: + username, password = self._credentials_from_git() if not username or not password: - (username, password) = self._credentials_from_keychain(username) + username, password = self._credentials_from_keychain(username) if username and not password and self._keyring: password = self._keyring.get_password(self.host, username) @@ -132,13 +149,7 @@ class Credentials(object): if not username: username = User.prompt("%s login: " % self.host) if not password: - password = getpass.getpass("%s password for %s: " % (self.host, - username)) + password = getpass.getpass("%s password for %s: " % (self.host, username)) + self._offer_to_store_credentials_in_keyring(username, password) - if self._keyring: - store_password = User().confirm( - "Store password in system keyring?", User.DEFAULT_NO) - if store_password: - self._keyring.set_password(self.host, username, password) - - return [username, password] + return (username, password) diff --git a/WebKitTools/Scripts/webkitpy/common/net/credentials_unittest.py b/WebKitTools/Scripts/webkitpy/common/net/credentials_unittest.py index d30291b..6f2d909 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/credentials_unittest.py +++ b/WebKitTools/Scripts/webkitpy/common/net/credentials_unittest.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. +from __future__ import with_statement + import os import tempfile import unittest @@ -34,6 +36,21 @@ from webkitpy.common.system.executive import Executive from webkitpy.common.system.outputcapture import OutputCapture from webkitpy.thirdparty.mock import Mock + +# FIXME: Other unit tests probably want this class. +class _TemporaryDirectory(object): + def __init__(self, **kwargs): + self._kwargs = kwargs + self._directory_path = None + + def __enter__(self): + self._directory_path = tempfile.mkdtemp(**self._kwargs) + return self._directory_path + + def __exit__(self, type, value, traceback): + os.rmdir(self._directory_path) + + class CredentialsTest(unittest.TestCase): example_security_output = """keychain: "/Users/test/Library/Keychains/login.keychain" class: "inet" @@ -101,40 +118,59 @@ password: "SECRETSAUCE" self._assert_security_call() self._assert_security_call(username="foo") + def test_credentials_from_environment(self): + executive_mock = Mock() + credentials = Credentials("example.com", executive=executive_mock) + + saved_environ = os.environ.copy() + os.environ['WEBKIT_BUGZILLA_USERNAME'] = "foo" + os.environ['WEBKIT_BUGZILLA_PASSWORD'] = "bar" + username, password = credentials._credentials_from_environment() + self.assertEquals(username, "foo") + self.assertEquals(password, "bar") + os.environ = saved_environ + def test_read_credentials_without_git_repo(self): + # FIXME: This should share more code with test_keyring_without_git_repo class FakeCredentials(Credentials): def _is_mac_os_x(self): return True + def _credentials_from_keychain(self, username): - return ["test@webkit.org", "SECRETSAUCE"] + return ("test@webkit.org", "SECRETSAUCE") + + def _credentials_from_environment(self): + return (None, None) + + with _TemporaryDirectory(suffix="not_a_git_repo") as temp_dir_path: + credentials = FakeCredentials("bugs.webkit.org", cwd=temp_dir_path) + # FIXME: Using read_credentials here seems too broad as higher-priority + # credential source could be affected by the user's environment. + self.assertEqual(credentials.read_credentials(), ("test@webkit.org", "SECRETSAUCE")) - temp_dir_path = tempfile.mkdtemp(suffix="not_a_git_repo") - credentials = FakeCredentials("bugs.webkit.org", cwd=temp_dir_path) - self.assertEqual(credentials.read_credentials(), ["test@webkit.org", "SECRETSAUCE"]) - os.rmdir(temp_dir_path) def test_keyring_without_git_repo(self): + # FIXME: This should share more code with test_read_credentials_without_git_repo class MockKeyring(object): def get_password(self, host, username): return "NOMNOMNOM" class FakeCredentials(Credentials): - def __init__(self, cwd): - Credentials.__init__(self, "fake.hostname", cwd=cwd, - keyring=MockKeyring()) - def _is_mac_os_x(self): return True def _credentials_from_keychain(self, username): return ("test@webkit.org", None) - temp_dir_path = tempfile.mkdtemp(suffix="not_a_git_repo") - credentials = FakeCredentials(temp_dir_path) - try: - self.assertEqual(credentials.read_credentials(), ["test@webkit.org", "NOMNOMNOM"]) - finally: - os.rmdir(temp_dir_path) + def _credentials_from_environment(self): + return (None, None) + + with _TemporaryDirectory(suffix="not_a_git_repo") as temp_dir_path: + credentials = FakeCredentials("fake.hostname", cwd=temp_dir_path, keyring=MockKeyring()) + # FIXME: Using read_credentials here seems too broad as higher-priority + # credential source could be affected by the user's environment. + self.assertEqual(credentials.read_credentials(), ("test@webkit.org", "NOMNOMNOM")) + if __name__ == '__main__': unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/common/net/rietveld.py b/WebKitTools/Scripts/webkitpy/common/net/rietveld.py deleted file mode 100644 index b9a0821..0000000 --- a/WebKitTools/Scripts/webkitpy/common/net/rietveld.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (c) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import logging -import os -import re -import stat - -import webkitpy.common.config as config -from webkitpy.common.system.deprecated_logging import log -from webkitpy.common.system.executive import ScriptError -import webkitpy.thirdparty.autoinstalled.rietveld.upload as upload - - -class Rietveld(object): - def __init__(self, executive, dryrun=False): - self.dryrun = dryrun - self._executive = executive - - def url_for_issue(self, codereview_issue): - if not codereview_issue: - return None - return "%s%s" % (config.codereview_server_url, codereview_issue) - - def post(self, diff, patch_id, codereview_issue, message=None, cc=None): - if not message: - raise ScriptError("Rietveld requires a message.") - - # Rietveld has a 100 character limit on message length. - if len(message) > 100: - message = message[:100] - - args = [ - # First argument is empty string to mimic sys.argv. - "", - "--assume_yes", - "--server=%s" % config.codereview_server_host, - "--message=%s" % message, - "--webkit_patch_id=%s" % patch_id, - ] - if codereview_issue: - args.append("--issue=%s" % codereview_issue) - if cc: - args.append("--cc=%s" % cc) - - if self.dryrun: - log("Would have run %s" % args) - return - - # Use RealMain instead of calling upload from the commandline so that - # we can pass in the diff ourselves. Otherwise, upload will just use - # git diff for git checkouts, which doesn't respect --git-commit. - issue, patchset = upload.RealMain(args, data=diff) - return issue diff --git a/WebKitTools/Scripts/webkitpy/common/net/statusserver.py b/WebKitTools/Scripts/webkitpy/common/net/statusserver.py index 3d03dcd..64dd77b 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/statusserver.py +++ b/WebKitTools/Scripts/webkitpy/common/net/statusserver.py @@ -127,7 +127,7 @@ class StatusServer: self._browser.submit() def release_work_item(self, queue_name, patch): - _log.debug("Releasing work item %s from %s" % (patch.id(), queue_name)) + _log.info("Releasing work item %s from %s" % (patch.id(), queue_name)) return NetworkTransaction(convert_404_to_None=True).run(lambda: self._post_release_work_item(queue_name, patch)) def update_work_items(self, queue_name, work_items): diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py index e0fd1b6..3e3ba0b 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py @@ -51,6 +51,7 @@ import time import traceback import test_failures +import test_results _log = logging.getLogger("webkitpy.layout_tests.layout_package." "dump_render_tree_thread") @@ -133,8 +134,8 @@ def _process_output(port, options, test_info, test_types, test_args, time.time() - start_diff_time) total_time_for_all_diffs = time.time() - start_diff_time - return TestResult(test_info.filename, failures, test_run_time, - total_time_for_all_diffs, time_for_diffs) + return test_results.TestResult(test_info.filename, failures, test_run_time, + total_time_for_all_diffs, time_for_diffs) def _pad_timeout(timeout): @@ -152,16 +153,11 @@ def _milliseconds_to_seconds(msecs): return float(msecs) / 1000.0 -class TestResult(object): - - def __init__(self, filename, failures, test_run_time, - total_time_for_all_diffs, time_for_diffs): - self.failures = failures - self.filename = filename - self.test_run_time = test_run_time - self.time_for_diffs = time_for_diffs - self.total_time_for_all_diffs = total_time_for_all_diffs - self.type = test_failures.determine_result_type(failures) +def _image_hash(test_info, test_args, options): + """Returns the image hash of the test if it's needed, otherwise None.""" + if (test_args.new_baseline or test_args.reset_results or not options.pixel_tests): + return None + return test_info.image_hash() class SingleTestThread(threading.Thread): @@ -196,10 +192,11 @@ class SingleTestThread(threading.Thread): self._driver = self._port.create_driver(self._test_args.png_path, self._options) self._driver.start() + image_hash = _image_hash(test_info, self._test_args, self._options) start = time.time() crash, timeout, actual_checksum, output, error = \ self._driver.run_test(test_info.uri.strip(), test_info.timeout, - test_info.image_hash()) + image_hash) end = time.time() self._test_result = _process_output(self._port, self._options, test_info, self._test_types, self._test_args, @@ -256,8 +253,8 @@ class TestShellThread(WatchableThread): options: command line options argument from optparse filename_list_queue: A thread safe Queue class that contains lists of tuples of (filename, uri) pairs. - result_queue: A thread safe Queue class that will contain tuples of - (test, failure lists) for the test results. + result_queue: A thread safe Queue class that will contain + serialized TestResult objects. test_types: A list of TestType objects to run the test output against. test_args: A TestArguments object to pass to each TestType. @@ -441,7 +438,7 @@ class TestShellThread(WatchableThread): else: _log.debug("%s %s passed" % (self.getName(), self._port.relative_test_filename(filename))) - self._result_queue.put(result) + self._result_queue.put(result.dumps()) if batch_size > 0 and batch_count > batch_size: # Bounce the shell and reset count. @@ -497,9 +494,8 @@ class TestShellThread(WatchableThread): failures = [] _log.error('Cannot get results of test: %s' % test_info.filename) - result = TestResult(test_info.filename, failures=[], - test_run_time=0, total_time_for_all_diffs=0, - time_for_diffs=0) + result = test_results.TestResult(test_info.filename, failures=[], + test_run_time=0, total_time_for_all_diffs=0, time_for_diffs=0) return result @@ -509,20 +505,14 @@ class TestShellThread(WatchableThread): Args: test_info: Object containing the test filename, uri and timeout - Returns: - A list of TestFailure objects describing the error. - + Returns: a TestResult object. """ self._ensure_dump_render_tree_is_running() # The pixel_hash is used to avoid doing an image dump if the # checksums match, so it should be set to a blank value if we # are generating a new baseline. (Otherwise, an image from a # previous run will be copied into the baseline.) - image_hash = test_info.image_hash() - if (image_hash and - (self._test_args.new_baseline or self._test_args.reset_results or - not self._options.pixel_tests)): - image_hash = "" + image_hash = _image_hash(test_info, self._test_args, self._options) start = time.time() thread_timeout = _milliseconds_to_seconds( diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py index c6c3066..1cf88ef 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py @@ -42,7 +42,6 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGeneratorBase # Additional JSON fields. WONTFIX = "wontfixCounts" - DEFERRED = "deferredCounts" # Note that we omit test_expectations.FAIL from this list because # it should never show up (it's a legacy input expectation, never @@ -167,9 +166,6 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGeneratorBase len(self._expectations.get_tests_with_timeline( test_expectations.NOW)), self.ALL_FIXABLE_COUNT) self._insert_item_into_raw_list(results_for_builder, - self._get_failure_summary_entry(test_expectations.DEFER), - self.DEFERRED) - self._insert_item_into_raw_list(results_for_builder, self._get_failure_summary_entry(test_expectations.WONTFIX), self.WONTFIX) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py index 0344aa7..9a0f4ee 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py @@ -40,7 +40,7 @@ from webkitpy.common import array_stream from webkitpy.common.system import logtesting from webkitpy.layout_tests import port from webkitpy.layout_tests.layout_package import printing -from webkitpy.layout_tests.layout_package import dump_render_tree_thread +from webkitpy.layout_tests.layout_package import test_results from webkitpy.layout_tests.layout_package import test_expectations from webkitpy.layout_tests.layout_package import test_failures from webkitpy.layout_tests import run_webkit_tests @@ -141,9 +141,9 @@ class Testprinter(unittest.TestCase): elif result_type == test_expectations.CRASH: failures = [test_failures.FailureCrash()] path = os.path.join(self._port.layout_tests_dir(), test) - return dump_render_tree_thread.TestResult(path, failures, run_time, - total_time_for_all_diffs=0, - time_for_diffs=0) + return test_results.TestResult(path, failures, run_time, + total_time_for_all_diffs=0, + time_for_diffs=0) def get_result_summary(self, tests, expectations_str): test_paths = [os.path.join(self._port.layout_tests_dir(), test) for diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py index 508a6ad..67873a8 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py @@ -43,7 +43,7 @@ _log = logging.getLogger("webkitpy.layout_tests.layout_package." # Test expectation and modifier constants. (PASS, FAIL, TEXT, IMAGE, IMAGE_PLUS_TEXT, TIMEOUT, CRASH, SKIP, WONTFIX, - DEFER, SLOW, REBASELINE, MISSING, FLAKY, NOW, NONE) = range(16) + SLOW, REBASELINE, MISSING, FLAKY, NOW, NONE) = range(15) # Test expectation file update action constants (NO_CHANGE, REMOVE_TEST, REMOVE_PLATFORM, ADD_PLATFORMS_EXCEPT_THIS) = range(4) @@ -228,12 +228,11 @@ class TestExpectationsFile: DEBUG : LayoutTests/fast/js/no-good.js = TIMEOUT PASS DEBUG SKIP : LayoutTests/fast/js/no-good.js = TIMEOUT PASS LINUX DEBUG SKIP : LayoutTests/fast/js/no-good.js = TIMEOUT PASS - DEFER LINUX WIN : LayoutTests/fast/js/no-good.js = TIMEOUT PASS + LINUX WIN : LayoutTests/fast/js/no-good.js = TIMEOUT PASS SKIP: Doesn't run the test. SLOW: The test takes a long time to run, but does not timeout indefinitely. WONTFIX: For tests that we never intend to pass on a given platform. - DEFER: Test does not count in our statistics for the current release. DEBUG: Expectations apply only to the debug build. RELEASE: Expectations apply only to release build. LINUX/WIN/WIN-XP/WIN-VISTA/WIN-7/MAC: Expectations apply only to these @@ -241,7 +240,6 @@ class TestExpectationsFile: Notes: -A test cannot be both SLOW and TIMEOUT - -A test cannot be both DEFER and WONTFIX -A test should only be one of IMAGE, TEXT, IMAGE+TEXT, or FAIL. FAIL is a migratory state that currently means either IMAGE, TEXT, or IMAGE+TEXT. Once we have finished migrating the expectations, we will @@ -249,7 +247,7 @@ class TestExpectationsFile: identifier. -A test can be included twice, but not via the same path. -If a test is included twice, then the more precise path wins. - -CRASH tests cannot be DEFER or WONTFIX + -CRASH tests cannot be WONTFIX """ EXPECTATIONS = {'pass': PASS, @@ -282,14 +280,12 @@ class TestExpectationsFile: MODIFIERS = {'skip': SKIP, 'wontfix': WONTFIX, - 'defer': DEFER, 'slow': SLOW, 'rebaseline': REBASELINE, 'none': NONE} TIMELINES = {'wontfix': WONTFIX, - 'now': NOW, - 'defer': DEFER} + 'now': NOW} RESULT_TYPES = {'skip': SKIP, 'pass': PASS, @@ -621,10 +617,6 @@ class TestExpectationsFile: if not self._is_debug_mode and 'release' not in options: return False - if 'wontfix' in options and 'defer' in options: - self._add_error(lineno, 'Test cannot be both DEFER and WONTFIX.', - test_and_expectations) - if self._is_lint_mode and 'rebaseline' in options: self._add_error(lineno, 'REBASELINE should only be used for running rebaseline.py. ' @@ -773,8 +765,6 @@ class TestExpectationsFile: if 'wontfix' in modifiers: self._timeline_to_tests[WONTFIX].add(test) - elif 'defer' in modifiers: - self._timeline_to_tests[DEFER].add(test) else: self._timeline_to_tests[NOW].add(test) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py index 2e1b6ec..55eaf99 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py @@ -134,17 +134,12 @@ class TestExpectationsTest(Base): self.get_test('failures/expected/text.html')), set([TEXT, CRASH])) - def test_defer(self): - self.parse_exp('BUGX DEFER : failures/expected/text.html = TEXT') - self.assertEqual(self._exp.get_options( - self.get_test('failures/expected/text.html')), ['bugx', 'defer']) - def test_precedence(self): # This tests handling precedence of specific lines over directories # and tests expectations covering entire directories. exp_str = """ BUGX : failures/expected/text.html = TEXT -BUGX DEFER : failures/expected = IMAGE +BUGX WONTFIX : failures/expected = IMAGE """ self.parse_exp(exp_str) self.assert_exp('failures/expected/text.html', TEXT) @@ -227,11 +222,6 @@ BUGX DEFER : failures/expected = IMAGE self.assertRaises(SyntaxError, self.parse_exp, 'BUG_TEST SLOW : failures/expected/timeout.html = TIMEOUT') - def test_semantic_wontfix_defer(self): - # A test cannot be WONTFIX and DEFER. - self.assertRaises(SyntaxError, self.parse_exp, - 'BUG_TEST WONTFIX DEFER : failures/expected/text.html = TEXT') - def test_semantic_rebaseline(self): # Can't lint a file w/ 'REBASELINE' in it. self.assertRaises(SyntaxError, self.parse_exp, diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py index 340d075..6d55761 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures.py @@ -32,6 +32,8 @@ import os import test_expectations +import cPickle + def determine_result_type(failure_list): """Takes a set of test_failures and returns which result type best fits @@ -71,10 +73,25 @@ class TestFailure(object): """Abstract base class that defines the failure interface.""" @staticmethod + def loads(s): + """Creates a TestFailure object from the specified string.""" + return cPickle.loads(s) + + @staticmethod def message(): """Returns a string describing the failure in more detail.""" raise NotImplementedError + def __eq__(self, other): + return self.__class__.__name__ == other.__class__.__name__ + + def __ne__(self, other): + return self.__class__.__name__ != other.__class__.__name__ + + def dumps(self): + """Returns the string/JSON representation of a TestFailure.""" + return cPickle.dumps(self) + def result_html_output(self, filename): """Returns an HTML string to be included on the results.html page.""" raise NotImplementedError @@ -112,7 +129,7 @@ class FailureWithType(TestFailure): TestFailure.__init__(self) # Filename suffixes used by ResultHtmlOutput. - OUT_FILENAMES = [] + OUT_FILENAMES = () def output_links(self, filename, out_names): """Returns a string holding all applicable output file links. @@ -128,6 +145,10 @@ class FailureWithType(TestFailure): # FIXME: Seems like a bad idea to separate the display name data # from the path data by hard-coding the display name here # and passing in the path information via out_names. + # + # FIXME: Also, we don't know for sure that these files exist, + # and we shouldn't be creating links to files that don't exist + # (for example, if we don't actually have wdiff output). links = [''] uris = [self.relative_output_filename(filename, fn) for fn in out_names] @@ -170,7 +191,7 @@ class FailureCrash(TestFailure): return "Test shell crashed" def result_html_output(self, filename): - # TODO(tc): create a link to the minidump file + # FIXME: create a link to the minidump file stack = self.relative_output_filename(filename, "-stack.txt") return "<strong>%s</strong> <a href=%s>stack</a>" % (self.message(), stack) @@ -181,7 +202,7 @@ class FailureCrash(TestFailure): class FailureMissingResult(FailureWithType): """Expected result was missing.""" - OUT_FILENAMES = ["-actual.txt"] + OUT_FILENAMES = ("-actual.txt",) @staticmethod def message(): @@ -196,14 +217,8 @@ class FailureTextMismatch(FailureWithType): """Text diff output failed.""" # Filename suffixes used by ResultHtmlOutput. # FIXME: Why don't we use the constants from TestTypeBase here? - OUT_FILENAMES = ["-actual.txt", "-expected.txt", "-diff.txt"] - OUT_FILENAMES_WDIFF = ["-actual.txt", "-expected.txt", "-diff.txt", - "-wdiff.html", "-pretty-diff.html"] - - def __init__(self, has_wdiff): - FailureWithType.__init__(self) - if has_wdiff: - self.OUT_FILENAMES = self.OUT_FILENAMES_WDIFF + OUT_FILENAMES = ("-actual.txt", "-expected.txt", "-diff.txt", + "-wdiff.html", "-pretty-diff.html") @staticmethod def message(): @@ -214,7 +229,6 @@ class FailureMissingImageHash(FailureWithType): """Actual result hash was missing.""" # Chrome doesn't know to display a .checksum file as text, so don't bother # putting in a link to the actual result. - OUT_FILENAMES = [] @staticmethod def message(): @@ -226,7 +240,7 @@ class FailureMissingImageHash(FailureWithType): class FailureMissingImage(FailureWithType): """Actual result image was missing.""" - OUT_FILENAMES = ["-actual.png"] + OUT_FILENAMES = ("-actual.png",) @staticmethod def message(): @@ -239,7 +253,7 @@ class FailureMissingImage(FailureWithType): class FailureImageHashMismatch(FailureWithType): """Image hashes didn't match.""" - OUT_FILENAMES = ["-actual.png", "-expected.png", "-diff.png"] + OUT_FILENAMES = ("-actual.png", "-expected.png", "-diff.png") @staticmethod def message(): @@ -252,7 +266,6 @@ class FailureImageHashIncorrect(FailureWithType): """Actual result hash is incorrect.""" # Chrome doesn't know to display a .checksum file as text, so don't bother # putting in a link to the actual result. - OUT_FILENAMES = [] @staticmethod def message(): @@ -260,3 +273,10 @@ class FailureImageHashIncorrect(FailureWithType): def result_html_output(self, filename): return "<strong>%s</strong>" % self.message() + +# Convenient collection of all failure classes for anything that might +# need to enumerate over them all. +ALL_FAILURE_CLASSES = (FailureTimeout, FailureCrash, FailureMissingResult, + FailureTextMismatch, FailureMissingImageHash, + FailureMissingImage, FailureImageHashMismatch, + FailureImageHashIncorrect) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures_unittest.py index 92fe276..3e3528d 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_failures_unittest.py @@ -28,13 +28,26 @@ """"Tests code paths not covered by the regular unit tests.""" -from webkitpy.layout_tests.layout_package.test_failures import * import unittest +from webkitpy.layout_tests.layout_package.test_failures import * + + class Test(unittest.TestCase): def assertResultHtml(self, failure_obj): self.assertNotEqual(failure_obj.result_html_output('foo'), None) + def assert_loads(self, cls): + failure_obj = cls() + s = failure_obj.dumps() + new_failure_obj = TestFailure.loads(s) + self.assertTrue(isinstance(new_failure_obj, cls)) + + self.assertEqual(failure_obj, new_failure_obj) + + # Also test that != is implemented. + self.assertFalse(failure_obj != new_failure_obj) + def test_crash(self): self.assertResultHtml(FailureCrash()) @@ -63,6 +76,9 @@ class Test(unittest.TestCase): self.assertRaises(NotImplementedError, failure_obj.result_html_output, "foo.txt") + def test_loads(self): + for c in ALL_FAILURE_CLASSES: + self.assert_loads(c) if __name__ == '__main__': unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_results.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_results.py new file mode 100644 index 0000000..2417fb7 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_results.py @@ -0,0 +1,61 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import cPickle + +import test_failures + + +class TestResult(object): + """Data object containing the results of a single test.""" + + @staticmethod + def loads(str): + return cPickle.loads(str) + + def __init__(self, filename, failures, test_run_time, + total_time_for_all_diffs, time_for_diffs): + self.failures = failures + self.filename = filename + self.test_run_time = test_run_time + self.time_for_diffs = time_for_diffs + self.total_time_for_all_diffs = total_time_for_all_diffs + self.type = test_failures.determine_result_type(failures) + + def __eq__(self, other): + return (self.filename == other.filename and + self.failures == other.failures and + self.test_run_time == other.test_run_time and + self.time_for_diffs == other.time_for_diffs and + self.total_time_for_all_diffs == other.total_time_for_all_diffs) + + def __ne__(self, other): + return not (self == other) + + def dumps(self): + return cPickle.dumps(self) diff --git a/WebKitTools/Scripts/webkitpy/common/net/rietveld_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_results_unittest.py index 9c5a29e..5921666 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/rietveld_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_results_unittest.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010 Google Inc. All rights reserved. +# Copyright (C) 2010 Google Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -28,12 +28,25 @@ import unittest -from webkitpy.common.net.rietveld import Rietveld -from webkitpy.thirdparty.mock import Mock +from test_results import TestResult -class RietveldTest(unittest.TestCase): - def test_url_for_issue(self): - rietveld = Rietveld(Mock()) - self.assertEqual(rietveld.url_for_issue(34223), - "https://wkrietveld.appspot.com/34223") +class Test(unittest.TestCase): + def test_loads(self): + result = TestResult(filename='foo', + failures=[], + test_run_time=1.1, + total_time_for_all_diffs=0.5, + time_for_diffs=0.5) + s = result.dumps() + new_result = TestResult.loads(s) + self.assertTrue(isinstance(new_result, TestResult)) + + self.assertEqual(new_result, result) + + # Also check that != is implemented. + self.assertFalse(new_result != result) + + +if __name__ == '__main__': + unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py index 93f8808..ee868e8 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py @@ -250,7 +250,7 @@ class PortTest(unittest.TestCase): abspath_to_uri(test_file)) def test_get_option__set(self): - options, args = optparse.OptionParser().parse_args() + options, args = optparse.OptionParser().parse_args([]) options.foo = 'bar' port = base.Port(options=options) self.assertEqual(port.get_option('foo'), 'bar') @@ -269,7 +269,7 @@ class PortTest(unittest.TestCase): self.assertEqual(port.get_option('foo'), 'bar') def test_set_option_default__set(self): - options, args = optparse.OptionParser().parse_args() + options, args = optparse.OptionParser().parse_args([]) options.foo = 'bar' port = base.Port(options=options) # This call should have no effect. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py index 4d17b51..f93f9a8 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py @@ -135,7 +135,7 @@ class ChromiumPort(base.Port): override_step, logging) def diff_image(self, expected_contents, actual_contents, - diff_filename=None, tolerance=0): + diff_filename=None): executable = self._path_to_image_diff() tempdir = tempfile.mkdtemp() @@ -385,6 +385,12 @@ class ChromiumDriver(base.Driver): if self._port.get_option('gp_fault_error_box'): driver_args.append('--gp-fault-error-box') + if self._options.js_flags is not None: + driver_args.append('--js-flags="' + self._options.js_flags + '"') + + if self._options.multiple_loads is not None and self._options.multiple_loads > 0: + driver_args.append('--multiple-loads=' + str(self._options.multiple_loads)) + if self._port.get_option('accelerated_compositing'): driver_args.append('--enable-accelerated-compositing') diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py index 95c716e..5d28fae 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py @@ -69,6 +69,8 @@ def _set_gpu_options(options): options.accelerated_compositing = True if options.accelerated_2d_canvas is None: options.accelerated_2d_canvas = True + if options.builder_name is not None: + options.builder_name = options.builder_name + ' - GPU' def _gpu_overrides(port): diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py index 7a13b1c..88524fc 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py @@ -44,10 +44,12 @@ class ChromiumGpuTest(unittest.TestCase): def assertOverridesWorked(self, port_name): # test that we got the right port mock_options = mocktool.MockOptions(accelerated_compositing=None, - accelerated_2d_canvas=None) + accelerated_2d_canvas=None, + builder_name='foo') port = chromium_gpu.get(port_name=port_name, options=mock_options) self.assertTrue(port._options.accelerated_compositing) self.assertTrue(port._options.accelerated_2d_canvas) + self.assertEqual(port._options.builder_name, 'foo - GPU') # we use startswith() instead of Equal to gloss over platform versions. self.assertTrue(port.name().startswith(port_name)) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py index cb45430..92a31fb 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py @@ -121,7 +121,7 @@ class ChromiumPortTest(unittest.TestCase): fake_test = os.path.join(port.layout_tests_dir(), "fast/js/not-good.js") port.test_expectations = lambda: """BUG_TEST SKIP : fast/js/not-good.js = TEXT -DEFER LINUX WIN : fast/js/very-good.js = TIMEOUT PASS""" +LINUX WIN : fast/js/very-good.js = TIMEOUT PASS""" port.test_expectations_overrides = lambda: '' port.tests = lambda paths: set() port.path_exists = lambda test: True diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py index 81db32c..36f3c6b 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py @@ -51,7 +51,7 @@ class ChromiumWinTest(unittest.TestCase): def test_setup_environ_for_server(self): port = chromium_win.ChromiumWinPort() - port._executive = mocktool.MockExecute(True) + port._executive = mocktool.MockExecutive(should_log=True) port.path_from_chromium_base = self._mock_path_from_chromium_base output = outputcapture.OutputCapture() orig_environ = os.environ.copy() @@ -63,7 +63,7 @@ class ChromiumWinTest(unittest.TestCase): sys.platform = "win32" port = chromium_win.ChromiumWinPort( options=ChromiumWinTest.RegisterCygwinOption()) - port._executive = mocktool.MockExecute(True) + port._executive = mocktool.MockExecutive(should_log=True) port.path_from_chromium_base = self._mock_path_from_chromium_base setup_mount = self._mock_path_from_chromium_base("third_party", "cygwin", diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py index 73200a0..b2615a3 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py @@ -71,13 +71,15 @@ class HttpLock(object): return self._extract_lock_number(lock_list[-1]) + 1 def _check_pid(self, current_pid): - """Return True if pid is alive, otherwise return False.""" - try: - os.kill(current_pid, 0) - except OSError: - return False - else: - return True + """Return True if pid is alive, otherwise return False. + FIXME: os.kill() doesn't work on Windows for checking if + a pid is alive, so always return True""" + if sys.platform in ('darwin', 'linux2'): + try: + os.kill(current_pid, 0) + except OSError: + return False + return True def _curent_lock_pid(self): """Return with the current lock pid. If the lock is not valid @@ -89,9 +91,7 @@ class HttpLock(object): current_lock_file = open(lock_list[0], 'r') current_pid = current_lock_file.readline() current_lock_file.close() - if not (current_pid and - sys.platform in ('darwin', 'linux2') and - self._check_pid(int(current_pid))): + if not (current_pid and self._check_pid(int(current_pid))): os.unlink(lock_list[0]) return except IOError, OSError: @@ -104,9 +104,7 @@ class HttpLock(object): numbers are sequential.""" while(True): try: - sequential_guard_lock = os.open(self._guard_lock_file, - os.O_CREAT | os.O_NONBLOCK | os.O_EXCL) - + sequential_guard_lock = os.open(self._guard_lock_file, os.O_CREAT | os.O_EXCL) self._process_lock_file_name = (self._lock_file_path_prefix + str(self._next_lock_number())) lock_file = open(self._process_lock_file_name, 'w') diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py index 4c8fa0a..af94acc 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py @@ -31,6 +31,7 @@ import logging import os import signal +import sys import webkit @@ -46,6 +47,17 @@ class QtPort(WebKitPort): kwargs.setdefault('port_name', 'qt') WebKitPort.__init__(self, **kwargs) + def baseline_search_path(self): + port_names = [] + if sys.platform == 'linux2': + port_names.append("qt-linux") + elif sys.platform in ('win32', 'cygwin'): + port_names.append("qt-win") + elif sys.platform == 'darwin': + port_names.append("qt-mac") + port_names.append("qt") + return map(self._webkit_baseline_path, port_names) + def _tests_for_other_platforms(self): # FIXME: This list could be dynamic based on platform name and # pushed into base.Port. @@ -92,6 +104,9 @@ class QtPort(WebKitPort): def _path_to_driver(self): return self._build_path('bin/DumpRenderTree') + def _path_to_image_diff(self): + return self._build_path('bin/ImageDiff') + def _path_to_webcore_library(self): return self._build_path('lib/libQtWebKit.so') diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py index 3691c5a..ff4086c 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py @@ -137,7 +137,7 @@ class TestPort(base.Port): return True def diff_image(self, expected_contents, actual_contents, - diff_filename=None, tolerance=0): + diff_filename=None): diffed = actual_contents != expected_contents if diffed and diff_filename: with codecs.open(diff_filename, "w", "utf-8") as diff_fh: diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py index c940f1e..0d0d3e0 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py @@ -122,22 +122,25 @@ class WebKitPort(base.Port): return True def diff_image(self, expected_contents, actual_contents, - diff_filename=None, tolerance=0.1): + diff_filename=None): """Return True if the two files are different. Also write a delta image of the two images into |diff_filename| if it is not None.""" - # FIXME: either expose the tolerance argument as a command-line - # parameter, or make it go away and always use exact matches. - # Handle the case where the test didn't actually generate an image. if not actual_contents: return True - sp = self._diff_image_request(expected_contents, actual_contents, - tolerance) + sp = self._diff_image_request(expected_contents, actual_contents) return self._diff_image_reply(sp, diff_filename) - def _diff_image_request(self, expected_contents, actual_contents, tolerance): + def _diff_image_request(self, expected_contents, actual_contents): + # FIXME: use self.get_option('tolerance') and + # self.set_option_default('tolerance', 0.1) once that behaves correctly + # with default values. + if self.get_option('tolerance') is not None: + tolerance = self.get_option('tolerance') + else: + tolerance = 0.1 command = [self._path_to_image_diff(), '--tolerance', str(tolerance)] sp = server_process.ServerProcess(self, 'ImageDiff', command) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py index a47370d..434058e 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py @@ -496,7 +496,7 @@ class Rebaseliner(object): """ if is_image: - return self._port.diff_image(output1, output2, None, 0) + return self._port.diff_image(output1, output2, None) else: return self._port.compare_text(output1, output2) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py index ef33a47..8db31a6 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests_unittest.py @@ -110,7 +110,6 @@ class TestRebaseliner(unittest.TestCase): is_image=False)) def test_diff_baselines_png(self): - return rebaseliner = self.make_rebaseliner() image = rebaseliner._port.expected_image( os.path.join(rebaseliner._port.layout_tests_dir(), diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py index 9cc7895..704180c 100755 --- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py @@ -69,6 +69,7 @@ from layout_package import json_layout_results_generator from layout_package import printing from layout_package import test_expectations from layout_package import test_failures +from layout_package import test_results from layout_package import test_results_uploader from test_types import image_diff from test_types import text_diff @@ -457,7 +458,7 @@ class TestRunner: # subtracted out of self._test_files, above), but we stub out the # results here so the statistics can remain accurate. for test in skip_chunk: - result = dump_render_tree_thread.TestResult(test, + result = test_results.TestResult(test, failures=[], test_run_time=0, total_time_for_all_diffs=0, time_for_diffs=0) result.type = test_expectations.SKIP @@ -852,7 +853,7 @@ class TestRunner: """Update the summary and print results with any completed tests.""" while True: try: - result = self._result_queue.get_nowait() + result = test_results.TestResult.loads(self._result_queue.get_nowait()) except Queue.Empty: return @@ -950,7 +951,12 @@ class TestRunner: _log.info("Uploading JSON files for builder: %s", self._options.builder_name) - attrs = [("builder", self._options.builder_name)] + attrs = [("builder", self._options.builder_name), ("testtype", "layout-tests")] + # FIXME: master_name should be required if test_results_server is set. + # Throw an error if master_name isn't set. + if self._options.master_name: + attrs.append(("master", self._options.master_name)) + json_files = ["expectations.json"] if self._options.upload_full_results: json_files.append("results.json") @@ -960,6 +966,13 @@ class TestRunner: files = [(file, os.path.join(self._options.results_directory, file)) for file in json_files] + # FIXME: Remove this. This is temporary debug logging. + if self._options.builder_name.startswith("Webkit Linux"): + for filename in files: + _log.debug(filename[1]) + with codecs.open(filename[1], "r") as results_file: + _log.debug("%s:\n%s" % (filename[0], results_file.read())) + uploader = test_results_uploader.TestResultsUploader( self._options.test_results_server) try: @@ -1011,16 +1024,13 @@ class TestRunner: tests = self._expectations.get_tests_with_result_type(result_type) now = result_summary.tests_by_timeline[test_expectations.NOW] wontfix = result_summary.tests_by_timeline[test_expectations.WONTFIX] - defer = result_summary.tests_by_timeline[test_expectations.DEFER] # We use a fancy format string in order to print the data out in a # nicely-aligned table. - fmtstr = ("Expect: %%5d %%-8s (%%%dd now, %%%dd defer, %%%dd wontfix)" - % (self._num_digits(now), self._num_digits(defer), - self._num_digits(wontfix))) + fmtstr = ("Expect: %%5d %%-8s (%%%dd now, %%%dd wontfix)" + % (self._num_digits(now), self._num_digits(wontfix))) self._printer.print_expected(fmtstr % - (len(tests), result_type_str, len(tests & now), - len(tests & defer), len(tests & wontfix))) + (len(tests), result_type_str, len(tests & now), len(tests & wontfix))) def _num_digits(self, num): """Returns the number of digits needed to represent the length of a @@ -1241,12 +1251,7 @@ class TestRunner: (passed, total, pct_passed)) self._printer.print_actual("") self._print_result_summary_entry(result_summary, - test_expectations.NOW, "Tests to be fixed for the current release") - - self._printer.print_actual("") - self._print_result_summary_entry(result_summary, - test_expectations.DEFER, - "Tests we'll fix in the future if they fail (DEFER)") + test_expectations.NOW, "Tests to be fixed") self._printer.print_actual("") self._print_result_summary_entry(result_summary, @@ -1301,7 +1306,8 @@ class TestRunner: page += u"<p><a href='%s'>%s</a><br />\n" % (test_url, test_name) test_failures = failures.get(test_file, []) for failure in test_failures: - page += u" %s<br/>" % failure.result_html_output(test_name) + page += (u" %s<br/>" % + failure.result_html_output(test_name)) page += "</p>\n" page += "</body></html>\n" return page @@ -1436,7 +1442,8 @@ def _set_up_derived_options(port_obj, options): if not options.child_processes: # FIXME: Investigate perf/flakiness impact of using cpu_count + 1. - options.child_processes = str(port_obj.default_child_processes()) + options.child_processes = os.environ.get("WEBKIT_TEST_CHILD_PROCESSES", + str(port_obj.default_child_processes())) if not options.configuration: options.configuration = port_obj.default_configuration() @@ -1515,6 +1522,10 @@ def parse_args(args=None): default=False, help="create a dialog on DumpRenderTree startup"), optparse.make_option("--gp-fault-error-box", action="store_true", default=False, help="enable Windows GP fault error box"), + optparse.make_option("--multiple-loads", + type="int", help="turn on multiple loads of each test"), + optparse.make_option("--js-flags", + type="string", help="JavaScript flags to pass to tests"), optparse.make_option("--nocheck-sys-deps", action="store_true", default=False, help="Don't check the system dependencies (themes)"), @@ -1561,8 +1572,9 @@ def parse_args(args=None): dest="pixel_tests", help="Enable pixel-to-pixel PNG comparisons"), optparse.make_option("--no-pixel-tests", action="store_false", dest="pixel_tests", help="Disable pixel-to-pixel PNG comparisons"), - # old-run-webkit-tests allows a specific tolerance: --tolerance t - # Ignore image differences less than this percentage (default: 0.1) + optparse.make_option("--tolerance", + help="Ignore image differences less than this percentage (some " + "ports may ignore this option)", type="float"), optparse.make_option("--results-directory", default="layout-test-results", help="Output results directory source dir, relative to Debug or " @@ -1686,6 +1698,7 @@ def parse_args(args=None): # FIXME: Move these into json_results_generator.py results_json_options = [ + optparse.make_option("--master-name", help="The name of the buildbot master."), optparse.make_option("--builder-name", default="DUMMY_BUILDER_NAME", help=("The name of the builder shown on the waterfall running " "this script e.g. WebKit.")), diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py index a716cec..0f09ffa 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py @@ -48,6 +48,7 @@ from webkitpy.common.system import user from webkitpy.layout_tests import port from webkitpy.layout_tests import run_webkit_tests from webkitpy.layout_tests.layout_package import dump_render_tree_thread +from webkitpy.layout_tests.port.test import TestPort from webkitpy.thirdparty.mock import Mock @@ -260,6 +261,31 @@ class MainTest(unittest.TestCase): tests_included=True) self.assertEqual(user.url, '/tmp/foo/results.html') + def test_tolerance(self): + class ImageDiffTestPort(TestPort): + def diff_image(self, expected_contents, actual_contents, + diff_filename=None): + self.tolerance_used_for_diff_image = self._options.tolerance + return True + + def get_port_for_run(args): + options, parsed_args = run_webkit_tests.parse_args(args) + test_port = ImageDiffTestPort(options=options, user=MockUser()) + passing_run(args=args, port_obj=test_port, tests_included=True) + return test_port + + base_args = ['--pixel-tests', 'failures/expected/*'] + + # If we pass in an explicit tolerance argument, then that will be used. + test_port = get_port_for_run(base_args + ['--tolerance', '.1']) + self.assertEqual(0.1, test_port.tolerance_used_for_diff_image) + test_port = get_port_for_run(base_args + ['--tolerance', '0']) + self.assertEqual(0, test_port.tolerance_used_for_diff_image) + + # Otherwise the port's default tolerance behavior (including ignoring it) + # should be used. + test_port = get_port_for_run(base_args) + self.assertEqual(None, test_port.tolerance_used_for_diff_image) def _mocked_open(original_open, file_list): diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py index b1f621e..4c32f0d 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py @@ -89,6 +89,6 @@ class TestTextDiff(test_type_base.TestTypeBase): if expected == '': failures.append(test_failures.FailureMissingResult()) else: - failures.append(test_failures.FailureTextMismatch(True)) + failures.append(test_failures.FailureTextMismatch()) return failures diff --git a/WebKitTools/Scripts/webkitpy/style/checker.py b/WebKitTools/Scripts/webkitpy/style/checker.py index e0c956f..11e3e33 100644 --- a/WebKitTools/Scripts/webkitpy/style/checker.py +++ b/WebKitTools/Scripts/webkitpy/style/checker.py @@ -116,9 +116,9 @@ _PATH_RULES_SPECIFIER = [ # API and therefore do not follow the same header including # discipline as WebCore. (["WebKitTools/WebKitAPITest/", - "WebKit/qt/QGVLauncher/"], + "WebKitTools/TestWebKitAPI/"], ["-build/include", - "-readability/streams"]), + "-readability/naming"]), ([# The EFL APIs use EFL naming style, which includes # both lower-cased and camel-cased, underscore-sparated # values. @@ -148,6 +148,24 @@ _PATH_RULES_SPECIFIER = [ "/JavaScriptCore/assembler/"], ["-readability/naming"]), + # WebKit2 rules: + # WebKit2 doesn't use config.h, and certain directories have other + # idiosyncracies. + ([# NPAPI has function names with underscores. + "WebKit2/WebProcess/Plugins/Netscape"], + ["-build/include_order", + "-readability/naming"]), + ([# The WebKit2 C API has names with underscores and whitespace-aligned + # struct members. + "WebKit2/UIProcess/API/C/", + "WebKit2/WebProcess/InjectedBundle/API/c/"], + ["-build/include_order", + "-readability/naming", + "-whitespace/declaration"]), + ([# Nothing in WebKit2 uses config.h. + "WebKit2/"], + ["-build/include_order"]), + # For third-party Python code, keep only the following checks-- # # No tabs: to avoid having to set the SVN allow-tabs property. diff --git a/WebKitTools/Scripts/webkitpy/style/checker_unittest.py b/WebKitTools/Scripts/webkitpy/style/checker_unittest.py index 5254275..43d24fe 100755 --- a/WebKitTools/Scripts/webkitpy/style/checker_unittest.py +++ b/WebKitTools/Scripts/webkitpy/style/checker_unittest.py @@ -213,11 +213,6 @@ class GlobalVariablesTest(unittest.TestCase): "build/include") assertNoCheck("WebKitTools/WebKitAPITest/main.cpp", "build/include") - assertNoCheck("WebKit/qt/QGVLauncher/main.cpp", - "build/include") - assertNoCheck("WebKit/qt/QGVLauncher/main.cpp", - "readability/streams") - assertCheck("random_path.cpp", "readability/naming") assertNoCheck("WebKit/gtk/webkit/webkit.h", diff --git a/WebKitTools/Scripts/webkitpy/style/checkers/cpp.py b/WebKitTools/Scripts/webkitpy/style/checkers/cpp.py index 7c1cb3e..cd9e6ae 100644 --- a/WebKitTools/Scripts/webkitpy/style/checkers/cpp.py +++ b/WebKitTools/Scripts/webkitpy/style/checkers/cpp.py @@ -1293,7 +1293,7 @@ def check_spacing(file_extension, clean_lines, line_number, error): line = clean_lines.elided[line_number] # get rid of comments and strings # Don't try to do spacing checks for operator methods - line = sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line) + line = sub(r'operator(==|!=|<|<<|<=|>=|>>|>|\+=|-=|\*=|/=|%=|&=|\|=|^=|<<=|>>=)\(', 'operator\(', line) # Don't try to do spacing checks for #include or #import statements at # minimum because it messes up checks for spacing around / if match(r'\s*#\s*(?:include|import)', line): diff --git a/WebKitTools/Scripts/webkitpy/style/checkers/cpp_unittest.py b/WebKitTools/Scripts/webkitpy/style/checkers/cpp_unittest.py index 071ce50..6d5c24b 100644 --- a/WebKitTools/Scripts/webkitpy/style/checkers/cpp_unittest.py +++ b/WebKitTools/Scripts/webkitpy/style/checkers/cpp_unittest.py @@ -1313,6 +1313,19 @@ class CppStyleTest(CppStyleTestBase): self.assert_multi_line_lint('#include "config.h"\n#import <foo/bar.h>\n', '') + def test_operator_methods(self): + self.assert_lint('String operator+(const String&, const String&);', '') + self.assert_lint('bool operator==(const String&, const String&);', '') + self.assert_lint('String& operator-=(const String&, const String&);', '') + self.assert_lint('String& operator+=(const String&, const String&);', '') + self.assert_lint('String& operator*=(const String&, const String&);', '') + self.assert_lint('String& operator%=(const String&, const String&);', '') + self.assert_lint('String& operator&=(const String&, const String&);', '') + self.assert_lint('String& operator<<=(const String&, const String&);', '') + self.assert_lint('String& operator>>=(const String&, const String&);', '') + self.assert_lint('String& operator|=(const String&, const String&);', '') + self.assert_lint('String& operator^=(const String&, const String&);', '') + def test_spacing_before_last_semicolon(self): self.assert_lint('call_function() ;', 'Extra space before last semicolon. If this should be an ' diff --git a/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py b/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py index 747b8b4..31f0b40 100644 --- a/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py +++ b/WebKitTools/Scripts/webkitpy/style/checkers/test_expectations_unittest.py @@ -111,7 +111,7 @@ class TestExpectationsTestCase(unittest.TestCase): ["BUG1234 DEBUG MAC : passes/text.html = TIMEOUT PASS"], "") self.assert_lines_lint( - ["SLOW DEFER BUG1234 : passes/text.html = PASS"], + ["SLOW BUG1234 : passes/text.html = PASS"], "") self.assert_lines_lint( ["WONTFIX SKIP : passes/text.html = TIMEOUT"], @@ -126,10 +126,6 @@ class TestExpectationsTestCase(unittest.TestCase): ["SKIP : passes/text.html = PASS"], "Test lacks BUG modifier. " "passes/text.html [test/expectations] [2]") - self.assert_lines_lint( - ["WONTFIX DEFER : passes/text.html = PASS"], - "Test cannot be both DEFER and WONTFIX. " - "passes/text.html [test/expectations] [5]") def test_expectation_errors(self): self.assert_lines_lint( diff --git a/WebKitTools/Scripts/webkitpy/thirdparty/__init__.py b/WebKitTools/Scripts/webkitpy/thirdparty/__init__.py index 7eac1cb..c2249c2 100644 --- a/WebKitTools/Scripts/webkitpy/thirdparty/__init__.py +++ b/WebKitTools/Scripts/webkitpy/thirdparty/__init__.py @@ -77,12 +77,6 @@ installer.install(url="http://pypi.python.org/packages/source/p/pep8/pep8-0.5.0. installer.install(url="http://www.adambarth.com/webkit/eliza", target_name="eliza.py") -rietveld_dir = os.path.join(autoinstalled_dir, "rietveld") -installer = AutoInstaller(target_dir=rietveld_dir) -installer.install(url="http://webkit-rietveld.googlecode.com/svn/trunk/upload_v26/upload.py", - target_name="upload.py") - - # Since irclib and ircbot are two top-level packages, we need to import # them separately. We group them into an irc package for better # organization purposes. diff --git a/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask.py b/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask.py index 02e203c..ea12702 100644 --- a/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask.py +++ b/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask.py @@ -85,7 +85,6 @@ class CommitQueueTask(object): "apply-attachment", "--force-clean", "--non-interactive", - "--quiet", self._patch.id(), ], "Applied patch", @@ -97,7 +96,6 @@ class CommitQueueTask(object): "--no-clean", "--no-update", "--build-style=both", - "--quiet", ], "Built patch", "Patch does not build") @@ -108,7 +106,6 @@ class CommitQueueTask(object): "--force-clean", "--no-update", "--build-style=both", - "--quiet", ], "Able to build without patch", "Unable to build without patch") @@ -120,7 +117,6 @@ class CommitQueueTask(object): "--no-update", # Notice that we don't pass --build, which means we won't build! "--test", - "--quiet", "--non-interactive", ], "Passed tests", @@ -133,7 +129,6 @@ class CommitQueueTask(object): "--no-update", "--build", "--test", - "--quiet", "--non-interactive", ], "Able to pass tests without patch", @@ -146,11 +141,11 @@ class CommitQueueTask(object): return results.failing_tests() def _land(self): + # Unclear if this should pass --quiet or not. If --parent-command always does the reporting, then it should. return self._run_command([ "land-attachment", "--force-clean", "--ignore-builders", - "--quiet", "--non-interactive", "--parent-command=commit-queue", self._patch.id(), diff --git a/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py b/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py index 6fa0667..15a4a6b 100644 --- a/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/bot/commitqueuetask_unittest.py @@ -75,13 +75,13 @@ class CommitQueueTaskTest(unittest.TestCase): def test_success_case(self): commit_queue = MockCommitQueue([]) - expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', 197] command_passed: success_message='Applied patch' patch='197' -run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both', '--quiet'] +run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both'] command_passed: success_message='Built patch' patch='197' -run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'] command_passed: success_message='Passed tests' patch='197' -run_webkit_patch: ['land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197] +run_webkit_patch: ['land-attachment', '--force-clean', '--ignore-builders', '--non-interactive', '--parent-command=commit-queue', 197] command_passed: success_message='Landed patch' patch='197' """ self._run_through_task(commit_queue, expected_stderr) @@ -90,7 +90,7 @@ command_passed: success_message='Landed patch' patch='197' commit_queue = MockCommitQueue([ ScriptError("MOCK apply failure"), ]) - expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', 197] command_failed: failure_message='Patch does not apply' script_error='MOCK apply failure' patch='197' """ self._run_through_task(commit_queue, expected_stderr, ScriptError) @@ -100,11 +100,11 @@ command_failed: failure_message='Patch does not apply' script_error='MOCK apply None, ScriptError("MOCK build failure"), ]) - expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', 197] command_passed: success_message='Applied patch' patch='197' -run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both', '--quiet'] +run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both'] command_failed: failure_message='Patch does not build' script_error='MOCK build failure' patch='197' -run_webkit_patch: ['build', '--force-clean', '--no-update', '--build-style=both', '--quiet'] +run_webkit_patch: ['build', '--force-clean', '--no-update', '--build-style=both'] command_passed: success_message='Able to build without patch' patch='197' """ self._run_through_task(commit_queue, expected_stderr, ScriptError) @@ -115,11 +115,11 @@ command_passed: success_message='Able to build without patch' patch='197' ScriptError("MOCK build failure"), ScriptError("MOCK clean build failure"), ]) - expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', 197] command_passed: success_message='Applied patch' patch='197' -run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both', '--quiet'] +run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both'] command_failed: failure_message='Patch does not build' script_error='MOCK build failure' patch='197' -run_webkit_patch: ['build', '--force-clean', '--no-update', '--build-style=both', '--quiet'] +run_webkit_patch: ['build', '--force-clean', '--no-update', '--build-style=both'] command_failed: failure_message='Unable to build without patch' script_error='MOCK clean build failure' patch='197' """ self._run_through_task(commit_queue, expected_stderr) @@ -130,16 +130,16 @@ command_failed: failure_message='Unable to build without patch' script_error='MO None, ScriptError("MOCK tests failure"), ]) - expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', 197] command_passed: success_message='Applied patch' patch='197' -run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both', '--quiet'] +run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both'] command_passed: success_message='Built patch' patch='197' -run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'] command_failed: failure_message='Patch does not pass tests' script_error='MOCK tests failure' patch='197' -run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'] command_passed: success_message='Passed tests' patch='197' report_flaky_tests: patch='197' flaky_tests='None' -run_webkit_patch: ['land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197] +run_webkit_patch: ['land-attachment', '--force-clean', '--ignore-builders', '--non-interactive', '--parent-command=commit-queue', 197] command_passed: success_message='Landed patch' patch='197' """ self._run_through_task(commit_queue, expected_stderr) @@ -151,15 +151,15 @@ command_passed: success_message='Landed patch' patch='197' ScriptError("MOCK test failure"), ScriptError("MOCK test failure again"), ]) - expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', 197] command_passed: success_message='Applied patch' patch='197' -run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both', '--quiet'] +run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both'] command_passed: success_message='Built patch' patch='197' -run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'] command_failed: failure_message='Patch does not pass tests' script_error='MOCK test failure' patch='197' -run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'] command_failed: failure_message='Patch does not pass tests' script_error='MOCK test failure again' patch='197' -run_webkit_patch: ['build-and-test', '--force-clean', '--no-update', '--build', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--force-clean', '--no-update', '--build', '--test', '--non-interactive'] command_passed: success_message='Able to pass tests without patch' patch='197' """ self._run_through_task(commit_queue, expected_stderr, ScriptError) @@ -172,15 +172,15 @@ command_passed: success_message='Able to pass tests without patch' patch='197' ScriptError("MOCK test failure again"), ScriptError("MOCK clean test failure"), ]) - expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', 197] command_passed: success_message='Applied patch' patch='197' -run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both', '--quiet'] +run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both'] command_passed: success_message='Built patch' patch='197' -run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'] command_failed: failure_message='Patch does not pass tests' script_error='MOCK test failure' patch='197' -run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'] command_failed: failure_message='Patch does not pass tests' script_error='MOCK test failure again' patch='197' -run_webkit_patch: ['build-and-test', '--force-clean', '--no-update', '--build', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--force-clean', '--no-update', '--build', '--test', '--non-interactive'] command_failed: failure_message='Unable to pass tests without patch (tree is red?)' script_error='MOCK clean test failure' patch='197' """ self._run_through_task(commit_queue, expected_stderr) @@ -192,13 +192,13 @@ command_failed: failure_message='Unable to pass tests without patch (tree is red None, ScriptError("MOCK land failure"), ]) - expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + expected_stderr = """run_webkit_patch: ['apply-attachment', '--force-clean', '--non-interactive', 197] command_passed: success_message='Applied patch' patch='197' -run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both', '--quiet'] +run_webkit_patch: ['build', '--no-clean', '--no-update', '--build-style=both'] command_passed: success_message='Built patch' patch='197' -run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] +run_webkit_patch: ['build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'] command_passed: success_message='Passed tests' patch='197' -run_webkit_patch: ['land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197] +run_webkit_patch: ['land-attachment', '--force-clean', '--ignore-builders', '--non-interactive', '--parent-command=commit-queue', 197] command_failed: failure_message='Unable to land patch' script_error='MOCK land failure' patch='197' """ self._run_through_task(commit_queue, expected_stderr, ScriptError) diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/download.py b/WebKitTools/Scripts/webkitpy/tool/commands/download.py index ed5c604..541c9c4 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/download.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/download.py @@ -106,8 +106,10 @@ land will NOT build and run the tests before committing, but you can use the --b If a bug id is provided, or one can be found in the ChangeLog land will update the bug after committing.""" def _prepare_state(self, options, args, tool): + changed_files = self._tool.scm().changed_files(options.git_commit) return { - "bug_id": (args and args[0]) or tool.checkout().bug_id_for_this_commit(options.git_commit), + "changed_files": changed_files, + "bug_id": (args and args[0]) or tool.checkout().bug_id_for_this_commit(options.git_commit, changed_files), } @@ -221,18 +223,6 @@ class BuildAndTestAttachment(AbstractPatchSequencingCommand, ProcessAttachmentsM ] -class PostAttachmentToRietveld(AbstractPatchSequencingCommand, ProcessAttachmentsMixin): - name = "post-attachment-to-rietveld" - help_text = "Uploads a bugzilla attachment to rietveld" - arguments_names = "ATTACHMENTID" - main_steps = [ - steps.CleanWorkingDirectory, - steps.Update, - steps.ApplyPatch, - steps.PostCodeReview, - ] - - class AbstractPatchApplyingCommand(AbstractPatchSequencingCommand): prepare_steps = [ steps.EnsureLocalCommitIfNeeded, diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/download_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/download_unittest.py index 6af1f64..bfca139 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/download_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/download_unittest.py @@ -118,10 +118,6 @@ class DownloadCommandsTest(CommandsTest): expected_stderr = "Processing 1 patch from 1 bug.\nUpdating working directory\nProcessing patch 197 from bug 42.\nBuilding WebKit\n" self.assert_execute_outputs(BuildAttachment(), [197], options=self._default_options(), expected_stderr=expected_stderr) - def test_post_attachment_to_rietveld(self): - expected_stderr = "Processing 1 patch from 1 bug.\nUpdating working directory\nProcessing patch 197 from bug 42.\nMOCK: Uploading patch to rietveld\nMOCK setting flag 'in-rietveld' to '+' on attachment '197' with comment 'None' and additional comment 'None'\n" - self.assert_execute_outputs(PostAttachmentToRietveld(), [197], options=self._default_options(), expected_stderr=expected_stderr) - def test_land_attachment(self): # FIXME: This expected result is imperfect, notice how it's seeing the same patch as still there after it thought it would have cleared the flags. expected_stderr = """Processing 1 patch from 1 bug. @@ -186,5 +182,6 @@ where ATTACHMENT_ID is the ID of this attachment. def test_rollout(self): expected_stderr = "Preparing rollout for bug 42.\nUpdating working directory\nRunning prepare-ChangeLog\nMOCK: user.open_url: file://...\nBuilding WebKit\n" - self.assert_execute_outputs(Rollout(), [852, "Reason"], options=self._default_options(), expected_stderr=expected_stderr) + expected_stdout = "Was that diff correct?\n" + self.assert_execute_outputs(Rollout(), [852, "Reason"], options=self._default_options(), expected_stdout=expected_stdout, expected_stderr=expected_stderr) diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem.py b/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem.py index 5ec468e..3b53d1a 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem.py @@ -50,8 +50,7 @@ class AbstractEarlyWarningSystem(AbstractReviewQueue): self.port.flag(), "--build-style=%s" % self._build_style, "--force-clean", - "--no-update", - "--quiet"]) + "--no-update"]) return True except ScriptError, e: failure_log = self._log_from_script_error_for_upload(e) @@ -81,6 +80,14 @@ class AbstractEarlyWarningSystem(AbstractReviewQueue): raise def review_patch(self, patch): + if patch.is_obsolete(): + self._did_error(patch, "%s does not process obsolete patches." % self.name) + return False + + if patch.bug().is_closed(): + self._did_error(patch, "%s does not process patches on closed bugs." % self.name) + return False + if not self._build(patch, first_run=True): if not self._can_build(): return False diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py index c400f81..830e11c 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py @@ -29,15 +29,54 @@ import os from webkitpy.thirdparty.mock import Mock +from webkitpy.common.system.outputcapture import OutputCapture +from webkitpy.tool.bot.queueengine import QueueEngine from webkitpy.tool.commands.earlywarningsystem import * from webkitpy.tool.commands.queuestest import QueuesTest +from webkitpy.tool.mocktool import MockTool, MockOptions + + +class AbstractEarlyWarningSystemTest(QueuesTest): + def test_can_build(self): + # Needed to define port_name, used in AbstractEarlyWarningSystem.__init__ + class TestEWS(AbstractEarlyWarningSystem): + port_name = "win" # Needs to be a port which port/factory understands. + + queue = TestEWS() + queue.bind_to_tool(MockTool(log_executive=True)) + queue._options = MockOptions(port=None) + expected_stderr = "MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--port=win', '--build-style=release', '--force-clean', '--no-update']\n" + OutputCapture().assert_outputs(self, queue._can_build, [], expected_stderr=expected_stderr) + + def mock_run_webkit_patch(args): + raise ScriptError("MOCK script error") + + queue.run_webkit_patch = mock_run_webkit_patch + expected_stderr = "MOCK: update_status: None Unable to perform a build\n" + OutputCapture().assert_outputs(self, queue._can_build, [], expected_stderr=expected_stderr) + + # FIXME: This belongs on an AbstractReviewQueueTest object in queues_unittest.py + def test_subprocess_handled_error(self): + queue = AbstractReviewQueue() + queue.bind_to_tool(MockTool()) + + def mock_review_patch(patch): + raise ScriptError('MOCK script error', exit_code=QueueEngine.handled_error_code) + + queue.review_patch = mock_review_patch + mock_patch = queue._tool.bugs.fetch_attachment(197) + expected_stderr = "MOCK: release_work_item: None 197\n" + OutputCapture().assert_outputs(self, queue.process_work_item, [mock_patch], expected_stderr=expected_stderr, expected_exception=ScriptError) + class EarlyWarningSytemTest(QueuesTest): def test_failed_builds(self): ews = ChromiumLinuxEWS() + ews.bind_to_tool(MockTool()) ews._build = lambda patch, first_run=False: False ews._can_build = lambda: True - ews.review_patch(Mock()) + mock_patch = ews._tool.bugs.fetch_attachment(197) + ews.review_patch(mock_patch) def _default_expected_stderr(self, ews): string_replacemnts = { @@ -46,20 +85,29 @@ class EarlyWarningSytemTest(QueuesTest): "watchers": ews.watchers, } expected_stderr = { - "begin_work_queue": self._default_begin_work_queue_stderr(ews.name, os.getcwd()), # FIXME: Use of os.getcwd() is wrong, should be scm.checkout_root + "begin_work_queue": self._default_begin_work_queue_stderr(ews.name, ews._tool.scm().checkout_root), "handle_unexpected_error": "Mock error message\n", "next_work_item": "", "process_work_item": "MOCK: update_status: %(name)s Pass\nMOCK: release_work_item: %(name)s 197\n" % string_replacemnts, - "handle_script_error": "MOCK: update_status: %(name)s ScriptError error message\nMOCK bug comment: bug_id=142, cc=%(watchers)s\n--- Begin comment ---\nAttachment 197 did not build on %(port)s:\nBuild output: http://dummy_url\n--- End comment ---\n\n" % string_replacemnts, + "handle_script_error": "MOCK: update_status: %(name)s ScriptError error message\nMOCK bug comment: bug_id=42, cc=%(watchers)s\n--- Begin comment ---\nAttachment 197 did not build on %(port)s:\nBuild output: http://dummy_url\n--- End comment ---\n\n" % string_replacemnts, } return expected_stderr def _test_ews(self, ews): + ews.bind_to_tool(MockTool()) expected_exceptions = { "handle_script_error": SystemExit, } self.assert_queue_outputs(ews, expected_stderr=self._default_expected_stderr(ews), expected_exceptions=expected_exceptions) + def _test_committer_only_ews(self, ews): + ews.bind_to_tool(MockTool()) + expected_stderr = self._default_expected_stderr(ews) + string_replacemnts = {"name": ews.name} + expected_stderr["process_work_item"] = "MOCK: update_status: %(name)s Error: %(name)s cannot process patches from non-committers :(\nMOCK: release_work_item: %(name)s 197\n" % string_replacemnts + expected_exceptions = {"handle_script_error": SystemExit} + self.assert_queue_outputs(ews, expected_stderr=expected_stderr, expected_exceptions=expected_exceptions) + # FIXME: If all EWSes are going to output the same text, we # could test them all in one method with a for loop over an array. def test_chromium_linux_ews(self): @@ -78,19 +126,7 @@ class EarlyWarningSytemTest(QueuesTest): self._test_ews(EflEWS()) def test_mac_ews(self): - ews = MacEWS() - expected_stderr = self._default_expected_stderr(ews) - expected_stderr["process_work_item"] = "MOCK: update_status: mac-ews Error: mac-ews cannot process patches from non-committers :(\n" - expected_exceptions = { - "handle_script_error": SystemExit, - } - self.assert_queue_outputs(ews, expected_stderr=expected_stderr, expected_exceptions=expected_exceptions) + self._test_committer_only_ews(MacEWS()) def test_chromium_mac_ews(self): - ews = ChromiumMacEWS() - expected_stderr = self._default_expected_stderr(ews) - expected_stderr["process_work_item"] = "MOCK: update_status: cr-mac-ews Error: cr-mac-ews cannot process patches from non-committers :(\n" - expected_exceptions = { - "handle_script_error": SystemExit, - } - self.assert_queue_outputs(ews, expected_stderr=expected_stderr, expected_exceptions=expected_exceptions) + self._test_committer_only_ews(ChromiumMacEWS()) diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queues.py b/WebKitTools/Scripts/webkitpy/tool/commands/queues.py index 7b3002a..6b4213b 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/queues.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/queues.py @@ -38,7 +38,7 @@ from datetime import datetime from optparse import make_option from StringIO import StringIO -from webkitpy.common.net.bugzilla import CommitterValidator +from webkitpy.common.net.bugzilla import CommitterValidator, Attachment from webkitpy.common.net.layouttestresults import path_for_layout_test, LayoutTestResults from webkitpy.common.net.statusserver import StatusServer from webkitpy.common.system.executive import ScriptError @@ -47,7 +47,7 @@ from webkitpy.tool.commands.stepsequence import StepSequenceErrorHandler from webkitpy.tool.bot.commitqueuetask import CommitQueueTask, CommitQueueTaskDelegate from webkitpy.tool.bot.feeders import CommitQueueFeeder, EWSFeeder from webkitpy.tool.bot.queueengine import QueueEngine, QueueEngineDelegate -from webkitpy.tool.grammar import pluralize +from webkitpy.tool.grammar import pluralize, join_with_separators from webkitpy.tool.multicommandtool import Command, TryAgain @@ -87,6 +87,11 @@ class AbstractQueue(Command, QueueEngineDelegate): if self._options.port: webkit_patch_args += ["--port=%s" % self._options.port] webkit_patch_args.extend(args) + # FIXME: There is probably no reason to use run_and_throw_if_fail anymore. + # run_and_throw_if_fail was invented to support tee'd output + # (where we write both to a log file and to the console at once), + # but the queues don't need live-progress, a dump-of-output at the + # end should be sufficient. return self._tool.executive.run_and_throw_if_fail(webkit_patch_args) def _log_directory(self): @@ -196,24 +201,40 @@ class AbstractPatchQueue(AbstractQueue): def _update_status(self, message, patch=None, results_file=None): return self._tool.status_server.update_status(self.name, message, patch, results_file) - def _fetch_next_work_item(self): - return self._tool.status_server.next_work_item(self.name) + def _next_patch(self): + patch_id = self._tool.status_server.next_work_item(self.name) + if not patch_id: + return None + patch = self._tool.bugs.fetch_attachment(patch_id) + if not patch: + # FIXME: Using a fake patch because release_work_item has the wrong API. + # We also don't really need to release the lock (although that's fine), + # mostly we just need to remove this bogus patch from our queue. + # If for some reason bugzilla is just down, then it will be re-fed later. + patch = Attachment({'id': patch_id}, None) + self._release_work_item(patch) + return None + return patch def _release_work_item(self, patch): self._tool.status_server.release_work_item(self.name, patch) def _did_pass(self, patch): self._update_status(self._pass_status, patch) + self._release_work_item(patch) def _did_fail(self, patch): self._update_status(self._fail_status, patch) + self._release_work_item(patch) def _did_retry(self, patch): self._update_status(self._retry_status, patch) + self._release_work_item(patch) def _did_error(self, patch, reason): message = "%s: %s" % (self._error_status, reason) self._update_status(message, patch) + self._release_work_item(patch) def work_item_log_path(self, patch): return os.path.join(self._log_directory(), "%s.log" % patch.bug_id()) @@ -229,10 +250,7 @@ class CommitQueue(AbstractPatchQueue, StepSequenceErrorHandler, CommitQueueTaskD self.committer_validator = CommitterValidator(self._tool.bugs) def next_work_item(self): - patch_id = self._fetch_next_work_item() - if not patch_id: - return None - return self._tool.bugs.fetch_attachment(patch_id) + return self._next_patch() def should_proceed_with_work_item(self, patch): patch_text = "rollout patch" if patch.is_rollout() else "patch" @@ -251,7 +269,6 @@ class CommitQueue(AbstractPatchQueue, StepSequenceErrorHandler, CommitQueueTaskD validator = CommitterValidator(self._tool.bugs) validator.reject_patch_from_commit_queue(patch.id(), self._error_message_for_bug(task.failure_status_id, e)) self._did_fail(patch) - self._release_work_item(patch) def _error_message_for_bug(self, status_id, script_error): if not script_error.output: @@ -297,13 +314,17 @@ class CommitQueue(AbstractPatchQueue, StepSequenceErrorHandler, CommitQueueTaskD def _author_emails_for_tests(self, flaky_tests): test_paths = map(path_for_layout_test, flaky_tests) commit_infos = self._tool.checkout().recent_commit_infos_for_files(test_paths) - return [commit_info.author().bugzilla_email() for commit_info in commit_infos if commit_info.author()] + return set([commit_info.author().bugzilla_email() for commit_info in commit_infos if commit_info.author()]) def report_flaky_tests(self, patch, flaky_tests): - authors = self._author_emails_for_tests(flaky_tests) - cc_explaination = " The author(s) of the test(s) have been CCed on this bug." if authors else "" - message = "The %s encountered the following flaky tests while processing attachment %s:\n\n%s\n\nPlease file bugs against the tests.%s The commit-queue is continuing to process your patch." % (self.name, patch.id(), "\n".join(flaky_tests), cc_explaination) - self._tool.bugs.post_comment_to_bug(patch.bug_id(), message, cc=authors) + message = "The %s encountered the following flaky tests while processing attachment %s:" % (self.name, patch.id()) + message += "\n\n%s\n\n" % ("\n".join(flaky_tests)) + message += "Please file bugs against the tests. " + author_emails = self._author_emails_for_tests(flaky_tests) + if author_emails: + message += "These tests were authored by %s. " % (join_with_separators(sorted(author_emails))) + message += "The commit-queue is continuing to process your patch." + self._tool.bugs.post_comment_to_bug(patch.bug_id(), message) # StepSequenceErrorHandler methods @@ -327,52 +348,6 @@ class CommitQueue(AbstractPatchQueue, StepSequenceErrorHandler, CommitQueueTaskD raise TryAgain() -# FIXME: All the Rietveld code is no longer used and should be deleted. -class RietveldUploadQueue(AbstractPatchQueue, StepSequenceErrorHandler): - name = "rietveld-upload-queue" - - def __init__(self): - AbstractPatchQueue.__init__(self) - - # AbstractPatchQueue methods - - def next_work_item(self): - patch_id = self._tool.bugs.queries.fetch_first_patch_from_rietveld_queue() - if patch_id: - return patch_id - self._update_status("Empty queue") - - def should_proceed_with_work_item(self, patch): - self._update_status("Uploading patch", patch) - return True - - def process_work_item(self, patch): - try: - self.run_webkit_patch(["post-attachment-to-rietveld", "--force-clean", "--non-interactive", "--parent-command=rietveld-upload-queue", patch.id()]) - self._did_pass(patch) - return True - except ScriptError, e: - if e.exit_code != QueueEngine.handled_error_code: - self._did_fail(patch) - raise e - - @classmethod - def _reject_patch(cls, tool, patch_id): - tool.bugs.set_flag_on_attachment(patch_id, "in-rietveld", "-") - - def handle_unexpected_error(self, patch, message): - log(message) - self._reject_patch(self._tool, patch.id()) - - # StepSequenceErrorHandler methods - - @classmethod - def handle_script_error(cls, tool, state, script_error): - log(script_error.message_with_output()) - cls._update_status_for_script_error(tool, state, script_error) - cls._reject_patch(tool, state["patch"].id()) - - class AbstractReviewQueue(AbstractPatchQueue, StepSequenceErrorHandler): """This is the base-class for the EWS queues and the style-queue.""" def __init__(self, options=None): @@ -387,10 +362,7 @@ class AbstractReviewQueue(AbstractPatchQueue, StepSequenceErrorHandler): AbstractPatchQueue.begin_work_queue(self) def next_work_item(self): - patch_id = self._fetch_next_work_item() - if not patch_id: - return None - return self._tool.bugs.fetch_attachment(patch_id) + return self._next_patch() def should_proceed_with_work_item(self, patch): raise NotImplementedError("subclasses must implement") @@ -404,9 +376,11 @@ class AbstractReviewQueue(AbstractPatchQueue, StepSequenceErrorHandler): except ScriptError, e: if e.exit_code != QueueEngine.handled_error_code: self._did_fail(patch) + else: + # The subprocess handled the error, but won't have released the patch, so we do. + # FIXME: We need to simplify the rules by which _release_work_item is called. + self._release_work_item(patch) raise e - finally: - self._release_work_item(patch) def handle_unexpected_error(self, patch, message): log(message) diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py index b37b5dc..b45db7b 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py @@ -29,12 +29,13 @@ import os from webkitpy.common.checkout.scm import CheckoutNeedsUpdate +from webkitpy.common.config.committers import Committer from webkitpy.common.net.bugzilla import Attachment from webkitpy.common.system.outputcapture import OutputCapture from webkitpy.thirdparty.mock import Mock from webkitpy.tool.commands.commandtest import CommandsTest from webkitpy.tool.commands.queues import * -from webkitpy.tool.commands.queuestest import QueuesTest, MockPatch +from webkitpy.tool.commands.queuestest import QueuesTest from webkitpy.tool.commands.stepsequence import StepSequence from webkitpy.tool.mocktool import MockTool, MockSCM, MockStatusServer @@ -51,11 +52,6 @@ class TestFeederQueue(FeederQueue): _sleep_duration = 0 -class MockRolloutPatch(MockPatch): - def is_rollout(self): - return True - - class AbstractQueueTest(CommandsTest): def test_log_directory(self): self.assertEquals(TestQueue()._log_directory(), "test-queue-logs") @@ -144,15 +140,19 @@ MOCK: submit_to_ews: 103 class AbstractPatchQueueTest(CommandsTest): - def test_fetch_next_work_item(self): + def test_next_patch(self): queue = AbstractPatchQueue() tool = MockTool() queue.bind_to_tool(tool) queue._options = Mock() queue._options.port = None - self.assertEquals(queue._fetch_next_work_item(), None) - tool.status_server = MockStatusServer(work_items=[2, 1, 3]) - self.assertEquals(queue._fetch_next_work_item(), 2) + self.assertEquals(queue._next_patch(), None) + tool.status_server = MockStatusServer(work_items=[2, 197]) + expected_stdout = "MOCK: fetch_attachment: 2 is not a known attachment id\n" # A mock-only message to prevent us from making mistakes. + expected_stderr = "MOCK: release_work_item: None 2\n" + patch_id = OutputCapture().assert_outputs(self, queue._next_patch, [], expected_stdout=expected_stdout, expected_stderr=expected_stderr) + self.assertEquals(patch_id, None) # 2 is an invalid patch id + self.assertEquals(queue._next_patch().id(), 197) class NeedsUpdateSequence(StepSequence): @@ -198,6 +198,19 @@ class SecondThoughtsCommitQueue(CommitQueue): return Attachment(attachment_dictionary, None) +# Creating fake CommitInfos is a pain, so we use a mock one here. +class MockCommitInfo(object): + def __init__(self, author_email): + self._author_email = author_email + + def author(self): + # It's definitely possible to have commits with authors who + # are not in our committers.py list. + if not self._author_email: + return None + return Committer("Mock Committer", self._author_email) + + class CommitQueueTest(QueuesTest): def test_commit_queue(self): expected_stderr = { @@ -209,6 +222,7 @@ MOCK: update_status: commit-queue Built patch MOCK: update_status: commit-queue Passed tests MOCK: update_status: commit-queue Landed patch MOCK: update_status: commit-queue Pass +MOCK: release_work_item: commit-queue 197 """, "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'Mock error message'\n", "handle_script_error": "ScriptError error message\n", @@ -243,15 +257,16 @@ MOCK: release_work_item: commit-queue 197 "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root), "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing patch\n", "next_work_item": "", - "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--force-clean', '--non-interactive', 197] MOCK: update_status: commit-queue Applied patch -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--no-clean', '--no-update', '--build-style=both', '--quiet'] +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--no-clean', '--no-update', '--build-style=both'] MOCK: update_status: commit-queue Built patch -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'] MOCK: update_status: commit-queue Passed tests -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197] +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--ignore-builders', '--non-interactive', '--parent-command=commit-queue', 197] MOCK: update_status: commit-queue Landed patch MOCK: update_status: commit-queue Pass +MOCK: release_work_item: commit-queue 197 """, "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'Mock error message'\n", "handle_script_error": "ScriptError error message\n", @@ -261,22 +276,22 @@ MOCK: update_status: commit-queue Pass def test_rollout_lands(self): tool = MockTool(log_executive=True) tool.buildbot.light_tree_on_fire() - rollout_patch = MockRolloutPatch() + rollout_patch = tool.bugs.fetch_attachment(106) # _patch6, a rollout patch. + assert(rollout_patch.is_rollout()) expected_stderr = { "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue", MockSCM.fake_checkout_root), "should_proceed_with_work_item": "MOCK: update_status: commit-queue Processing rollout patch\n", "next_work_item": "", - "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--force-clean', '--non-interactive', '--quiet', 197] + "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--force-clean', '--non-interactive', 106] MOCK: update_status: commit-queue Applied patch -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--no-clean', '--no-update', '--build-style=both', '--quiet'] +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--no-clean', '--no-update', '--build-style=both'] MOCK: update_status: commit-queue Built patch -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test', '--no-clean', '--no-update', '--test', '--quiet', '--non-interactive'] -MOCK: update_status: commit-queue Passed tests -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--ignore-builders', '--quiet', '--non-interactive', '--parent-command=commit-queue', 197] +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--ignore-builders', '--non-interactive', '--parent-command=commit-queue', 106] MOCK: update_status: commit-queue Landed patch MOCK: update_status: commit-queue Pass +MOCK: release_work_item: commit-queue 106 """, - "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '197' with comment 'Rejecting patch 197 from commit-queue.' and additional comment 'Mock error message'\n", + "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '106' with comment 'Rejecting patch 106 from commit-queue.' and additional comment 'Mock error message'\n", "handle_script_error": "ScriptError error message\n", } self.assert_queue_outputs(CommitQueue(), tool=tool, work_item=rollout_patch, expected_stderr=expected_stderr) @@ -307,23 +322,36 @@ MOCK: update_status: commit-queue Passed tests MOCK: update_status: commit-queue Retry MOCK: release_work_item: commit-queue 197 """ - OutputCapture().assert_outputs(self, queue.process_work_item, [MockPatch()], expected_stderr=expected_stderr) + OutputCapture().assert_outputs(self, queue.process_work_item, [QueuesTest.mock_work_item], expected_stderr=expected_stderr) + + def _assert_emails_for_tests(self, emails): + queue = CommitQueue() + tool = MockTool() + queue.bind_to_tool(tool) + commit_infos = [MockCommitInfo(email) for email in emails] + tool.checkout().recent_commit_infos_for_files = lambda paths: set(commit_infos) + self.assertEqual(queue._author_emails_for_tests([]), set(emails)) + + def test_author_emails_for_tests(self): + self._assert_emails_for_tests([]) + self._assert_emails_for_tests(["test1@test.com", "test1@test.com"]) + self._assert_emails_for_tests(["test1@test.com", "test2@test.com"]) def test_report_flaky_tests(self): queue = CommitQueue() queue.bind_to_tool(MockTool()) - expected_stderr = """MOCK bug comment: bug_id=142, cc=['abarth@webkit.org'] + expected_stderr = """MOCK bug comment: bug_id=42, cc=None --- Begin comment --- The commit-queue encountered the following flaky tests while processing attachment 197: foo/bar.html bar/baz.html -Please file bugs against the tests. The author(s) of the test(s) have been CCed on this bug. The commit-queue is continuing to process your patch. +Please file bugs against the tests. These tests were authored by abarth@webkit.org. The commit-queue is continuing to process your patch. --- End comment --- """ - OutputCapture().assert_outputs(self, queue.report_flaky_tests, [MockPatch(), ["foo/bar.html", "bar/baz.html"]], expected_stderr=expected_stderr) + OutputCapture().assert_outputs(self, queue.report_flaky_tests, [QueuesTest.mock_work_item, ["foo/bar.html", "bar/baz.html"]], expected_stderr=expected_stderr) def test_layout_test_results(self): queue = CommitQueue() @@ -333,17 +361,6 @@ Please file bugs against the tests. The author(s) of the test(s) have been CCed queue._read_file_contents = lambda path: "" self.assertEquals(queue.layout_test_results(), None) -class RietveldUploadQueueTest(QueuesTest): - def test_rietveld_upload_queue(self): - expected_stderr = { - "begin_work_queue": self._default_begin_work_queue_stderr("rietveld-upload-queue", MockSCM.fake_checkout_root), - "should_proceed_with_work_item": "MOCK: update_status: rietveld-upload-queue Uploading patch\n", - "process_work_item": "MOCK: update_status: rietveld-upload-queue Pass\n", - "handle_unexpected_error": "Mock error message\nMOCK setting flag 'in-rietveld' to '-' on attachment '197' with comment 'None' and additional comment 'None'\n", - "handle_script_error": "ScriptError error message\nMOCK: update_status: rietveld-upload-queue ScriptError error message\nMOCK setting flag 'in-rietveld' to '-' on attachment '197' with comment 'None' and additional comment 'None'\n", - } - self.assert_queue_outputs(RietveldUploadQueue(), expected_stderr=expected_stderr) - class StyleQueueTest(QueuesTest): def test_style_queue(self): @@ -353,7 +370,7 @@ class StyleQueueTest(QueuesTest): "should_proceed_with_work_item": "MOCK: update_status: style-queue Checking style\n", "process_work_item": "MOCK: update_status: style-queue Pass\nMOCK: release_work_item: style-queue 197\n", "handle_unexpected_error": "Mock error message\n", - "handle_script_error": "MOCK: update_status: style-queue ScriptError error message\nMOCK bug comment: bug_id=142, cc=[]\n--- Begin comment ---\nAttachment 197 did not pass style-queue:\n\nScriptError error message\n\nIf any of these errors are false positives, please file a bug against check-webkit-style.\n--- End comment ---\n\n", + "handle_script_error": "MOCK: update_status: style-queue ScriptError error message\nMOCK bug comment: bug_id=42, cc=[]\n--- Begin comment ---\nAttachment 197 did not pass style-queue:\n\nScriptError error message\n\nIf any of these errors are false positives, please file a bug against check-webkit-style.\n--- End comment ---\n\n", } expected_exceptions = { "handle_script_error": SystemExit, diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queuestest.py b/WebKitTools/Scripts/webkitpy/tool/commands/queuestest.py index 379d380..6455617 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/queuestest.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/queuestest.py @@ -44,25 +44,9 @@ class MockQueueEngine(object): pass -class MockPatch(): - def id(self): - return 197 - - def bug_id(self): - return 142 - - def is_rollout(self): - return False - - class QueuesTest(unittest.TestCase): - # Ids match patch1 in mocktool.py - mock_work_item = Attachment({ - "id": 197, - "bug_id": 142, - "name": "Patch", - "attacher_email": "adam@example.com", - }, None) + # This is _patch1 in mocktool.py + mock_work_item = MockTool().bugs.fetch_attachment(197) def assert_outputs(self, func, func_name, args, expected_stdout, expected_stderr, expected_exceptions): exception = None @@ -108,4 +92,4 @@ class QueuesTest(unittest.TestCase): self.assert_outputs(queue.handle_unexpected_error, "handle_unexpected_error", [work_item, "Mock error message"], expected_stdout, expected_stderr, expected_exceptions) # Should we have a different function for testing StepSequenceErrorHandlers? if isinstance(queue, StepSequenceErrorHandler): - self.assert_outputs(queue.handle_script_error, "handle_script_error", [tool, {"patch": MockPatch()}, ScriptError(message="ScriptError error message", script_args="MockErrorCommand")], expected_stdout, expected_stderr, expected_exceptions) + self.assert_outputs(queue.handle_script_error, "handle_script_error", [tool, {"patch": self.mock_work_item}, ScriptError(message="ScriptError error message", script_args="MockErrorCommand")], expected_stdout, expected_stderr, expected_exceptions) diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot_unittest.py index 32eb016..4db463e 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/sheriffbot_unittest.py @@ -38,9 +38,10 @@ class SheriffBotTest(QueuesTest): builder2 = MockBuilder("Builder2") def test_sheriff_bot(self): - mock_work_item = MockFailureMap(MockTool().buildbot) + tool = MockTool() + mock_work_item = MockFailureMap(tool.buildbot) expected_stderr = { - "begin_work_queue": self._default_begin_work_queue_stderr("sheriff-bot", os.getcwd()), + "begin_work_queue": self._default_begin_work_queue_stderr("sheriff-bot", tool.scm().checkout_root), "next_work_item": "", "process_work_item": """MOCK: irc.post: abarth, darin, eseidel: http://trac.webkit.org/changeset/29837 might have broken Builder1 MOCK bug comment: bug_id=42, cc=['abarth@webkit.org', 'eric@webkit.org'] diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py index 107d8db..ed91f5a 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py @@ -152,7 +152,9 @@ class AbstractPatchUploadingCommand(AbstractSequencedCommand): # Perfer a bug id passed as an argument over a bug url in the diff (i.e. ChangeLogs). bug_id = args and args[0] if not bug_id: - bug_id = tool.checkout().bug_id_for_this_commit(options.git_commit) + changed_files = self._tool.scm().changed_files(options.git_commit) + state["changed_files"] = changed_files + bug_id = tool.checkout().bug_id_for_this_commit(options.git_commit, changed_files) return bug_id def _prepare_state(self, options, args, tool): @@ -171,6 +173,7 @@ class Post(AbstractPatchUploadingCommand): steps.CheckStyle, steps.ConfirmDiff, steps.ObsoletePatches, + steps.SuggestReviewers, steps.PostDiff, ] @@ -219,6 +222,7 @@ class Upload(AbstractPatchUploadingCommand): steps.EditChangeLog, steps.ConfirmDiff, steps.ObsoletePatches, + steps.SuggestReviewers, steps.PostDiff, ] long_help = """upload uploads the current diff to bugs.webkit.org. diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/upload_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/upload_unittest.py index 0d096b6..bd1fbd6 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/upload_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/upload_unittest.py @@ -58,6 +58,7 @@ class UploadCommandsTest(CommandsTest): options.description = "MOCK description" options.request_commit = False options.review = True + options.suggest_reviewers = False expected_stderr = """Running check-webkit-style MOCK: user.open_url: file://... Obsoleting 2 old patches on bug 42 @@ -67,7 +68,8 @@ None -- End comment -- MOCK: user.open_url: http://example.com/42 """ - self.assert_execute_outputs(Post(), [42], options=options, expected_stderr=expected_stderr) + expected_stdout = "Was that diff correct?\n" + self.assert_execute_outputs(Post(), [42], options=options, expected_stdout=expected_stdout, expected_stderr=expected_stderr) def test_land_safely(self): expected_stderr = "Obsoleting 2 old patches on bug 42\nMOCK add_patch_to_bug: bug_id=42, description=Patch for landing, mark_for_review=False, mark_for_commit_queue=False, mark_for_landing=True\n-- Begin comment --\nNone\n-- End comment --\n" @@ -88,6 +90,7 @@ MOCK: user.open_url: http://example.com/42 options.description = "MOCK description" options.request_commit = False options.review = True + options.suggest_reviewers = False expected_stderr = """Running check-webkit-style MOCK: user.open_url: file://... Obsoleting 2 old patches on bug 42 @@ -97,7 +100,8 @@ None -- End comment -- MOCK: user.open_url: http://example.com/42 """ - self.assert_execute_outputs(Upload(), [42], options=options, expected_stderr=expected_stderr) + expected_stdout = "Was that diff correct?\n" + self.assert_execute_outputs(Upload(), [42], options=options, expected_stdout=expected_stdout, expected_stderr=expected_stderr) def test_mark_bug_fixed(self): tool = MockTool() @@ -106,7 +110,8 @@ MOCK: user.open_url: http://example.com/42 options.bug_id = 42 options.comment = "MOCK comment" expected_stderr = "Bug: <http://example.com/42> Bug with two r+'d and cq+'d patches, one of which has an invalid commit-queue setter.\nRevision: 9876\nMOCK: user.open_url: http://example.com/42\nAdding comment to Bug 42.\nMOCK bug comment: bug_id=42, cc=None\n--- Begin comment ---\nMOCK comment\n\nCommitted r9876: <http://trac.webkit.org/changeset/9876>\n--- End comment ---\n\n" - self.assert_execute_outputs(MarkBugFixed(), [], expected_stderr=expected_stderr, tool=tool, options=options) + expected_stdout = "Is this correct?\n" + self.assert_execute_outputs(MarkBugFixed(), [], expected_stdout=expected_stdout, expected_stderr=expected_stderr, tool=tool, options=options) def test_edit_changelog(self): self.assert_execute_outputs(EditChangeLogs(), []) diff --git a/WebKitTools/Scripts/webkitpy/tool/main.py b/WebKitTools/Scripts/webkitpy/tool/main.py index ce6666e..e0862c5 100755 --- a/WebKitTools/Scripts/webkitpy/tool/main.py +++ b/WebKitTools/Scripts/webkitpy/tool/main.py @@ -37,7 +37,6 @@ from webkitpy.common.checkout.scm import default_scm from webkitpy.common.config.ports import WebKitPort from webkitpy.common.net.bugzilla import Bugzilla from webkitpy.common.net.buildbot import BuildBot -from webkitpy.common.net.rietveld import Rietveld from webkitpy.common.net.irc.ircproxy import IRCProxy from webkitpy.common.system.executive import Executive from webkitpy.common.system.user import User @@ -79,7 +78,6 @@ class WebKitPatch(MultiCommandTool): self._scm = None self._checkout = None self.status_server = StatusServer() - self.codereview = Rietveld(self.executive) self.port_factory = port.factory def scm(self): @@ -126,7 +124,6 @@ class WebKitPatch(MultiCommandTool): if options.dry_run: self.scm().dryrun = True self.bugs.dryrun = True - self.codereview.dryrun = True if options.status_host: self.status_server.set_host(options.status_host) if options.bot_id: diff --git a/WebKitTools/Scripts/webkitpy/tool/mocktool.py b/WebKitTools/Scripts/webkitpy/tool/mocktool.py index 05b30dd..af232d9 100644 --- a/WebKitTools/Scripts/webkitpy/tool/mocktool.py +++ b/WebKitTools/Scripts/webkitpy/tool/mocktool.py @@ -33,7 +33,6 @@ from webkitpy.common.config.committers import CommitterList, Reviewer from webkitpy.common.checkout.commitinfo import CommitInfo from webkitpy.common.checkout.scm import CommitMessage from webkitpy.common.net.bugzilla import Bug, Attachment -from webkitpy.common.net.rietveld import Rietveld from webkitpy.thirdparty.mock import Mock from webkitpy.common.system.deprecated_logging import log @@ -86,7 +85,6 @@ _patch3 = { "name": "Patch3", "is_obsolete": False, "is_patch": True, - "in-rietveld": "?", "review": "?", "attacher_email": "eric@webkit.org", } @@ -113,7 +111,6 @@ _patch5 = { "name": "Patch5", "is_obsolete": False, "is_patch": True, - "in-rietveld": "?", "review": "+", "reviewer_email": "foo@bar.com", "attacher_email": "eric@webkit.org", @@ -127,7 +124,6 @@ _patch6 = { # Valid committer, but no reviewer. "name": "ROLLOUT of r3489", "is_obsolete": False, "is_patch": True, - "in-rietveld": "-", "commit-queue": "+", "committer_email": "foo@bar.com", "attacher_email": "eric@webkit.org", @@ -141,7 +137,6 @@ _patch7 = { # Valid review, patch is marked obsolete. "name": "Patch7", "is_obsolete": True, "is_patch": True, - "in-rietveld": "+", "review": "+", "reviewer_email": "foo@bar.com", "attacher_email": "eric@webkit.org", @@ -192,6 +187,7 @@ _bug4 = { } +# FIXME: This should not inherit from Mock class MockBugzillaQueries(Mock): def __init__(self, bugzilla): @@ -229,18 +225,14 @@ class MockBugzillaQueries(Mock): def fetch_patches_from_pending_commit_list(self): return sum([bug.reviewed_patches() for bug in self._all_bugs()], []) - def fetch_first_patch_from_rietveld_queue(self): - for bug in self._all_bugs(): - patches = bug.in_rietveld_queue_patches() - if len(patches): - return patches[0] - raise Exception('No patches in the rietveld queue') + +_mock_reviewer = Reviewer("Foo Bar", "foo@bar.com") + # FIXME: Bugzilla is the wrong Mock-point. Once we have a BugzillaNetwork # class we should mock that instead. # Most of this class is just copy/paste from Bugzilla. - - +# FIXME: This should not inherit from Mock class MockBugzilla(Mock): bug_server_url = "http://example.com" @@ -258,7 +250,7 @@ class MockBugzilla(Mock): def __init__(self): Mock.__init__(self) self.queries = MockBugzillaQueries(self) - self.committers = CommitterList(reviewers=[Reviewer("Foo Bar", "foo@bar.com")]) + self.committers = CommitterList(reviewers=[_mock_reviewer]) self._override_patch = None def create_bug(self, @@ -288,8 +280,10 @@ class MockBugzilla(Mock): if self._override_patch: return self._override_patch - # This could be changed to .get() if we wish to allow failed lookups. - attachment_dictionary = self.attachment_cache[attachment_id] + attachment_dictionary = self.attachment_cache.get(attachment_id) + if not attachment_dictionary: + print "MOCK: fetch_attachment: %s is not a known attachment id" % attachment_id + return None bug = self.fetch_bug(attachment_dictionary["bug_id"]) for attachment in bug.attachments(include_obsolete=True): if attachment.id() == int(attachment_id): @@ -418,6 +412,7 @@ class MockBuildBot(object): return MockFailureMap(self) +# FIXME: This should not inherit from Mock class MockSCM(Mock): fake_checkout_root = os.path.realpath("/tmp") # realpath is needed to allow for Mac OS X's /private/tmp @@ -480,7 +475,7 @@ class MockCheckout(object): # that LandDiff will try to actually read the patch from disk! return [] - def commit_message_for_this_commit(self, git_commit): + def commit_message_for_this_commit(self, git_commit, changed_files=None): commit_message = Mock() commit_message.message = lambda:"This is a fake commit message that is at least 50 characters." return commit_message @@ -491,6 +486,9 @@ class MockCheckout(object): def apply_reverse_diff(self, revision): pass + def suggested_reviewers(self, git_commit, changed_files=None): + return [_mock_reviewer] + class MockUser(object): @@ -508,6 +506,7 @@ class MockUser(object): pass def confirm(self, message=None, default='y'): + print message return default == 'y' def can_open_url(self): @@ -545,7 +544,7 @@ class MockStatusServer(object): def next_work_item(self, queue_name): if not self._work_items: return None - return self._work_items[0] + return self._work_items.pop(0) def release_work_item(self, queue_name, patch): log("MOCK: release_work_item: %s %s" % (queue_name, patch.id())) @@ -568,7 +567,8 @@ class MockStatusServer(object): return "http://dummy_url" -class MockExecute(Mock): +# FIXME: This should not inherit from Mock +class MockExecutive(Mock): def __init__(self, should_log): self._should_log = should_log @@ -603,47 +603,37 @@ class MockOptions(object): self.__dict__[key] = value -class MockRietveld(): - - def __init__(self, executive, dryrun=False): - pass - - def post(self, diff, patch_id, codereview_issue, message=None, cc=None): - log("MOCK: Uploading patch to rietveld") - - -class MockTestPort1(): +class MockTestPort1(object): def skips_layout_test(self, test_name): return test_name in ["media/foo/bar.html", "foo"] -class MockTestPort2(): +class MockTestPort2(object): def skips_layout_test(self, test_name): return test_name == "media/foo/bar.html" -class MockPortFactory(): +class MockPortFactory(object): def get_all(self, options=None): return {"test_port1": MockTestPort1(), "test_port2": MockTestPort2()} -class MockTool(): +class MockTool(object): def __init__(self, log_executive=False): self.wakeup_event = threading.Event() self.bugs = MockBugzilla() self.buildbot = MockBuildBot() - self.executive = MockExecute(should_log=log_executive) + self.executive = MockExecutive(should_log=log_executive) self._irc = None self.user = MockUser() self._scm = MockSCM() self._checkout = MockCheckout() self.status_server = MockStatusServer() self.irc_password = "MOCK irc password" - self.codereview = MockRietveld(self.executive) self.port_factory = MockPortFactory() def scm(self): diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/__init__.py b/WebKitTools/Scripts/webkitpy/tool/steps/__init__.py index d59cdc5..64d9d05 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/__init__.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/__init__.py @@ -44,7 +44,6 @@ from webkitpy.tool.steps.ensurebuildersaregreen import EnsureBuildersAreGreen from webkitpy.tool.steps.ensurelocalcommitifneeded import EnsureLocalCommitIfNeeded from webkitpy.tool.steps.obsoletepatches import ObsoletePatches from webkitpy.tool.steps.options import Options -from webkitpy.tool.steps.postcodereview import PostCodeReview from webkitpy.tool.steps.postdiff import PostDiff from webkitpy.tool.steps.postdiffforcommit import PostDiffForCommit from webkitpy.tool.steps.postdiffforrevert import PostDiffForRevert @@ -54,6 +53,7 @@ from webkitpy.tool.steps.promptforbugortitle import PromptForBugOrTitle from webkitpy.tool.steps.reopenbugafterrollout import ReopenBugAfterRollout from webkitpy.tool.steps.revertrevision import RevertRevision from webkitpy.tool.steps.runtests import RunTests +from webkitpy.tool.steps.suggestreviewers import SuggestReviewers from webkitpy.tool.steps.updatechangelogswithreviewer import UpdateChangeLogsWithReviewer from webkitpy.tool.steps.update import Update from webkitpy.tool.steps.validatereviewer import ValidateReviewer diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/options.py b/WebKitTools/Scripts/webkitpy/tool/steps/options.py index 835fdba..4f17dd3 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/options.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/options.py @@ -54,5 +54,6 @@ class Options(object): request_commit = make_option("--request-commit", action="store_true", dest="request_commit", default=False, help="Mark the patch as needing auto-commit after review.") review = make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review.") reviewer = make_option("-r", "--reviewer", action="store", type="string", dest="reviewer", help="Update ChangeLogs to say Reviewed by REVIEWER.") + suggest_reviewers = make_option("--suggest-reviewers", action="store_true", default=False, help="Offer to CC appropriate reviewers.") test = make_option("--test", action="store_true", dest="test", default=False, help="Run run-webkit-tests before committing.") update = make_option("--no-update", action="store_false", dest="update", default=True, help="Don't update the working directory.") diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/revertrevision.py b/WebKitTools/Scripts/webkitpy/tool/steps/revertrevision.py index 81b6bcb..bbb794c 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/revertrevision.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/revertrevision.py @@ -32,3 +32,4 @@ from webkitpy.tool.steps.abstractstep import AbstractStep class RevertRevision(AbstractStep): def run(self, state): self._tool.checkout().apply_reverse_diff(state["revision"]) + self.did_modify_checkout(state) diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py b/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py index dcbfc44..282e381 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py @@ -57,6 +57,7 @@ class RunTests(AbstractStep): log("Running run-webkit-tests") args = self._tool.port().run_webkit_tests_command() if self._options.non_interactive: + args.append("--no-new-test-results") args.append("--no-launch-safari") args.append("--exit-after-n-failures=1") args.append("--wait-for-httpd") diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py b/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py index 7eb8e3a..eabb656 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py @@ -87,6 +87,6 @@ MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/test-webkitperl'] Running JavaScriptCore tests MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/run-javascriptcore-tests'] Running run-webkit-tests -MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/run-webkit-tests', '--no-launch-safari', '--exit-after-n-failures=1', '--wait-for-httpd', '--ignore-tests', 'compositing,media', '--quiet'] +MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/run-webkit-tests', '--no-new-test-results', '--no-launch-safari', '--exit-after-n-failures=1', '--wait-for-httpd', '--ignore-tests', 'compositing,media', '--quiet'] """ OutputCapture().assert_outputs(self, step.run, [{}], expected_stderr=expected_stderr) diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/postcodereview.py b/WebKitTools/Scripts/webkitpy/tool/steps/suggestreviewers.py index d2f79f3..76bef35 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/postcodereview.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/suggestreviewers.py @@ -30,41 +30,22 @@ from webkitpy.tool.steps.abstractstep import AbstractStep from webkitpy.tool.steps.options import Options -class PostCodeReview(AbstractStep): +class SuggestReviewers(AbstractStep): @classmethod def options(cls): return AbstractStep.options() + [ - Options.cc, - Options.description, + Options.git_commit, + Options.suggest_reviewers, ] def run(self, state): - patch = state.get("patch") - bug_id = patch.bug_id() - title = patch.name() + if not self._options.suggest_reviewers: + return - # If the issue already exists, then the message becomes the label - # of the new patch. Otherwise, it becomes the title of the whole - # issue. - if title: - # This is the common case for the the first "upload" command. - message = title - elif bug_id: - # This is the common case for the "post" command and - # subsequent runs of the "upload" command. - message = "Code review for %s" % self._tool.bugs.bug_url_for_bug_id(bug_id) - else: - # Unreachable with our current commands, but we might hit - # this case if we support bug-less code reviews. - message = "Code review" - - # Use the bug ID as the rietveld issue number. This means rietveld code reviews - # when there are multiple different patches on a bug will be a bit wonky, but - # webkit-patch assumes one-patch-per-bug. - created_issue = self._tool.codereview.post(diff=self.cached_lookup(state, "diff"), - message=message, - codereview_issue=bug_id, - cc=self._options.cc, - patch_id=patch.id()) - - self._tool.bugs.set_flag_on_attachment(patch.id(), 'in-rietveld', '+') + reviewers = self._tool.checkout().suggested_reviewers(self._options.git_commit, self._changed_files(state)) + print "The following reviewers have recently modified files in your patch:" + print "\n".join([reviewer.full_name for reviewer in reviewers]) + if not self._tool.user.confirm("Would you like to CC them?"): + return + reviewer_emails = [reviewer.bugzilla_email() for reviewer in reviewers] + self._tool.bugs.add_cc_to_bug(state['bug_id'], reviewer_emails) diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/suggestreviewers_unittest.py b/WebKitTools/Scripts/webkitpy/tool/steps/suggestreviewers_unittest.py new file mode 100644 index 0000000..0c86535 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/tool/steps/suggestreviewers_unittest.py @@ -0,0 +1,45 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import unittest + +from webkitpy.common.system.outputcapture import OutputCapture +from webkitpy.tool.mocktool import MockOptions, MockTool +from webkitpy.tool.steps.suggestreviewers import SuggestReviewers + + +class SuggestReviewersTest(unittest.TestCase): + def test_disabled(self): + step = SuggestReviewers(MockTool(), MockOptions(suggest_reviewers=False)) + OutputCapture().assert_outputs(self, step.run, [{}]) + + def test_basic(self): + capture = OutputCapture() + step = SuggestReviewers(MockTool(), MockOptions(suggest_reviewers=True, git_commit=None)) + expected_stdout = "The following reviewers have recently modified files in your patch:\nFoo Bar\nWould you like to CC them?\n" + capture.assert_outputs(self, step.run, [{"bug_id": "123"}], expected_stdout=expected_stdout) diff --git a/WebKitTools/TestResultServer/handlers/testfilehandler.py b/WebKitTools/TestResultServer/handlers/testfilehandler.py index 4d1320f..d817890 100644 --- a/WebKitTools/TestResultServer/handlers/testfilehandler.py +++ b/WebKitTools/TestResultServer/handlers/testfilehandler.py @@ -36,6 +36,7 @@ from google.appengine.ext.webapp import template from model.jsonresults import JsonResults from model.testfile import TestFile +PARAM_MASTER = "master" PARAM_BUILDER = "builder" PARAM_DIR = "dir" PARAM_FILE = "file" @@ -51,25 +52,26 @@ class DeleteFile(webapp.RequestHandler): def get(self): key = self.request.get(PARAM_KEY) + master = self.request.get(PARAM_MASTER) builder = self.request.get(PARAM_BUILDER) test_type = self.request.get(PARAM_TEST_TYPE) name = self.request.get(PARAM_NAME) logging.debug( - "Deleting File, builder: %s, test_type: %s, name: %s, key: %s.", - builder, test_type, name, key) + "Deleting File, master: %s, builder: %s, test_type: %s, name: %s, key: %s.", + master, builder, test_type, name, key) - TestFile.delete_file(key, builder, test_type, name, 100) + TestFile.delete_file(key, master, builder, test_type, name, 100) # Display file list after deleting the file. - self.redirect("/testfile?builder=%s&testtype=%s&name=%s" - % (builder, test_type, name)) + self.redirect("/testfile?master=%s&builder=%s&testtype=%s&name=%s" + % (master, builder, test_type, name)) class GetFile(webapp.RequestHandler): """Get file content or list of files for given builder and name.""" - def _get_file_list(self, builder, test_type, name): + def _get_file_list(self, master, builder, test_type, name): """Get and display a list of files that matches builder and file name. Args: @@ -79,15 +81,16 @@ class GetFile(webapp.RequestHandler): """ files = TestFile.get_files( - builder, test_type, name, load_data=False, limit=100) + master, builder, test_type, name, load_data=False, limit=100) if not files: - logging.info("File not found, builder: %s, test_type: %s, name: %s.", - builder, test_type, name) + logging.info("File not found, master: %s, builder: %s, test_type: %s, name: %s.", + master, builder, test_type, name) self.response.out.write("File not found") return template_values = { "admin": users.is_current_user_admin(), + "master": master, "builder": builder, "test_type": test_type, "name": name, @@ -96,7 +99,7 @@ class GetFile(webapp.RequestHandler): self.response.out.write(template.render("templates/showfilelist.html", template_values)) - def _get_file_content(self, builder, test_type, name): + def _get_file_content(self, master, builder, test_type, name): """Return content of the file that matches builder and file name. Args: @@ -106,15 +109,15 @@ class GetFile(webapp.RequestHandler): """ files = TestFile.get_files( - builder, test_type, name, load_data=True, limit=1) + master, builder, test_type, name, load_data=True, limit=1) if not files: - logging.info("File not found, builder: %s, test_type: %s, name: %s.", - builder, test_type, name) + logging.info("File not found, master %s, builder: %s, test_type: %s, name: %s.", + master, builder, test_type, name) return None return files[0].data - def _get_test_list_json(self, builder, test_type): + def _get_test_list_json(self, master, builder, test_type): """Return json file with test name list only, do not include test results and other non-test-data . @@ -123,13 +126,14 @@ class GetFile(webapp.RequestHandler): test_type: type of test results. """ - json = self._get_file_content(builder, test_type, "results.json") + json = self._get_file_content(master, builder, test_type, "results.json") if not json: return None return JsonResults.get_test_list(builder, json) def get(self): + master = self.request.get(PARAM_MASTER) builder = self.request.get(PARAM_BUILDER) test_type = self.request.get(PARAM_TEST_TYPE) name = self.request.get(PARAM_NAME) @@ -137,19 +141,19 @@ class GetFile(webapp.RequestHandler): test_list_json = self.request.get(PARAM_TEST_LIST_JSON) logging.debug( - "Getting files, builder: %s, test_type: %s, name: %s.", - builder, test_type, name) + "Getting files, master %s, builder: %s, test_type: %s, name: %s.", + master, builder, test_type, name) # If parameter "dir" is specified or there is no builder or filename # specified in the request, return list of files, otherwise, return # file content. if dir or not builder or not name: - return self._get_file_list(builder, test_type, name) + return self._get_file_list(master, builder, test_type, name) if name == "results.json" and test_list_json: - json = self._get_test_list_json(builder, test_type) + json = self._get_test_list_json(master, builder, test_type) else: - json = self._get_file_content(builder, test_type, name) + json = self._get_file_content(master, builder, test_type, name) if json: self.response.headers["Content-Type"] = "text/plain; charset=utf-8" @@ -170,12 +174,13 @@ class Upload(webapp.RequestHandler): self.response.out.write("FAIL: missing builder parameter.") return + master = self.request.get(PARAM_MASTER) test_type = self.request.get(PARAM_TEST_TYPE) incremental = self.request.get(PARAM_INCREMENTAL) logging.debug( - "Processing upload request, builder: %s, test_type: %s.", - builder, test_type) + "Processing upload request, master: %s, builder: %s, test_type: %s.", + master, builder, test_type) # There are two possible types of each file_params in the request: # one file item or a list of file items. @@ -193,15 +198,15 @@ class Upload(webapp.RequestHandler): if ((incremental and filename == "results.json") or (filename == "incremental_results.json")): # Merge incremental json results. - saved_file = JsonResults.update(builder, test_type, file.value) + saved_file = JsonResults.update(master, builder, test_type, file.value) else: saved_file = TestFile.update( - builder, test_type, file.filename, file.value) + master, builder, test_type, file.filename, file.value) if not saved_file: errors.append( - "Upload failed, builder: %s, test_type: %s, name: %s." % - (builder, test_type, file.filename)) + "Upload failed, master: %s, builder: %s, test_type: %s, name: %s." % + (master, builder, test_type, file.filename)) if errors: messages = "FAIL: " + "; ".join(errors) diff --git a/WebKitTools/TestResultServer/index.yaml b/WebKitTools/TestResultServer/index.yaml index 50284dc..a7d3e48 100644 --- a/WebKitTools/TestResultServer/index.yaml +++ b/WebKitTools/TestResultServer/index.yaml @@ -25,6 +25,15 @@ indexes: - kind: TestFile properties: - name: builder + - name: master + - name: name + - name: test_type + - name: date + direction: desc + +- kind: TestFile + properties: + - name: builder - name: name - name: date direction: desc @@ -39,6 +48,12 @@ indexes: - kind: TestFile properties: + - name: master + - name: date + direction: desc + +- kind: TestFile + properties: - name: name - name: date direction: desc diff --git a/WebKitTools/TestResultServer/model/jsonresults.py b/WebKitTools/TestResultServer/model/jsonresults.py index 4520e96..97b277a 100755 --- a/WebKitTools/TestResultServer/model/jsonresults.py +++ b/WebKitTools/TestResultServer/model/jsonresults.py @@ -33,6 +33,7 @@ import logging from model.testfile import TestFile JSON_RESULTS_FILE = "results.json" +JSON_RESULTS_FILE_SMALL = "results-small.json" JSON_RESULTS_PREFIX = "ADD_RESULTS(" JSON_RESULTS_SUFFIX = ");" JSON_RESULTS_VERSION_KEY = "version" @@ -45,6 +46,7 @@ JSON_RESULTS_NO_DATA = "N" JSON_RESULTS_MIN_TIME = 1 JSON_RESULTS_VERSION = 3 JSON_RESULTS_MAX_BUILDS = 1500 +JSON_RESULTS_MAX_BUILDS_SMALL = 200 class JsonResults(object): @@ -106,7 +108,7 @@ class JsonResults(object): return None @classmethod - def _merge_json(cls, aggregated_json, incremental_json): + def _merge_json(cls, aggregated_json, incremental_json, num_runs): """Merge incremental json into aggregated json results. Args: @@ -120,19 +122,19 @@ class JsonResults(object): # Merge non tests property data. # Tests properties are merged in _merge_tests. - if not cls._merge_non_test_data(aggregated_json, incremental_json): + if not cls._merge_non_test_data(aggregated_json, incremental_json, num_runs): return False # Merge tests results and times incremental_tests = incremental_json[JSON_RESULTS_TESTS] if incremental_tests: aggregated_tests = aggregated_json[JSON_RESULTS_TESTS] - cls._merge_tests(aggregated_tests, incremental_tests) + cls._merge_tests(aggregated_tests, incremental_tests, num_runs) return True @classmethod - def _merge_non_test_data(cls, aggregated_json, incremental_json): + def _merge_non_test_data(cls, aggregated_json, incremental_json, num_runs): """Merge incremental non tests property data into aggregated json results. Args: @@ -173,13 +175,13 @@ class JsonResults(object): return False # Merge this build into aggreagated results. - cls._merge_one_build(aggregated_json, incremental_json, index) + cls._merge_one_build(aggregated_json, incremental_json, index, num_runs) return True @classmethod def _merge_one_build(cls, aggregated_json, incremental_json, - incremental_index): + incremental_index, num_runs): """Merge one build of incremental json into aggregated json results. Args: @@ -198,12 +200,12 @@ class JsonResults(object): aggregated_json[key].insert( 0, incremental_json[key][incremental_index]) aggregated_json[key] = \ - aggregated_json[key][:JSON_RESULTS_MAX_BUILDS] + aggregated_json[key][:num_runs] else: aggregated_json[key] = incremental_json[key] @classmethod - def _merge_tests(cls, aggregated_json, incremental_json): + def _merge_tests(cls, aggregated_json, incremental_json, num_runs): """Merge "tests" properties:results, times. Args: @@ -225,15 +227,15 @@ class JsonResults(object): times = [[1, 0]] cls._insert_item_run_length_encoded( - results, aggregated_test[JSON_RESULTS_RESULTS]) + results, aggregated_test[JSON_RESULTS_RESULTS], num_runs) cls._insert_item_run_length_encoded( - times, aggregated_test[JSON_RESULTS_TIMES]) + times, aggregated_test[JSON_RESULTS_TIMES], num_runs) cls._normalize_results_json(test_name, aggregated_json) else: aggregated_json[test_name] = incremental_json[test_name] @classmethod - def _insert_item_run_length_encoded(cls, incremental_item, aggregated_item): + def _insert_item_run_length_encoded(cls, incremental_item, aggregated_item, num_runs): """Inserts the incremental run-length encoded results into the aggregated run-length encoded results. @@ -245,7 +247,7 @@ class JsonResults(object): for item in incremental_item: if len(aggregated_item) and item[1] == aggregated_item[0][1]: aggregated_item[0][0] = min( - aggregated_item[0][0] + item[0], JSON_RESULTS_MAX_BUILDS) + aggregated_item[0][0] + item[0], num_runs) else: aggregated_item.insert(0, item) @@ -340,7 +342,7 @@ class JsonResults(object): return True @classmethod - def merge(cls, builder, aggregated, incremental, sort_keys=False): + def merge(cls, builder, aggregated, incremental, num_runs, sort_keys=False): """Merge incremental json file data with aggregated json file data. Args: @@ -378,9 +380,7 @@ class JsonResults(object): logging.info("Merging json results...") try: - if not cls._merge_json( - aggregated_json[builder], - incremental_json[builder]): + if not cls._merge_json(aggregated_json[builder], incremental_json[builder], num_runs): return None except Exception, err: logging.error("Failed to merge json results: %s", str(err)) @@ -391,37 +391,48 @@ class JsonResults(object): return cls._generate_file_data(aggregated_json, sort_keys) @classmethod - def update(cls, builder, test_type, incremental): + def update(cls, master, builder, test_type, incremental): """Update datastore json file data by merging it with incremental json - file. + file. Writes the large file and a small file. The small file just stores + fewer runs. Args: + master: master name. builder: builder name. test_type: type of test results. incremental: incremental json file data to merge. Returns: - TestFile object if update succeeds or + Large TestFile object if update succeeds or None on failure. """ + small_file = cls.update_file(master, builder, test_type, incremental, JSON_RESULTS_FILE_SMALL, JSON_RESULTS_MAX_BUILDS_SMALL) + large_file = cls.update_file(master, builder, test_type, incremental, JSON_RESULTS_FILE, JSON_RESULTS_MAX_BUILDS) - files = TestFile.get_files(builder, test_type, JSON_RESULTS_FILE) + if small_file and large_file: + return large_file + return None + + @classmethod + def update_file(cls, master, builder, test_type, incremental, filename, num_runs): + files = TestFile.get_files(master, builder, test_type, filename) if files: file = files[0] - new_results = cls.merge(builder, file.data, incremental) + new_results = cls.merge(builder, file.data, incremental, num_runs) else: # Use the incremental data if there is no aggregated file to merge. - file = TestFile() + file = TestFile() + file.master = master file.builder = builder file.test_type = test_type - file.name = JSON_RESULTS_FILE + file.name = filename new_results = incremental logging.info("No existing json results, incremental json is saved.") - if not new_results: - return None - - if not file.save(new_results): + if not new_results or not file.save(new_results): + logging.info( + "Update failed, master: %s, builder: %s, test_type: %s, name: %s." % + (master, builder, test_type, filename)) return None return file diff --git a/WebKitTools/TestResultServer/model/jsonresults_unittest.py b/WebKitTools/TestResultServer/model/jsonresults_unittest.py index 15b659b..c70b90c 100755 --- a/WebKitTools/TestResultServer/model/jsonresults_unittest.py +++ b/WebKitTools/TestResultServer/model/jsonresults_unittest.py @@ -26,10 +26,14 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import jsonresults +try: + import jsonresults + from jsonresults import JsonResults +except ImportError: + print "ERROR: Add the TestResultServer, google_appengine and yaml/lib directories to your PYTHONPATH" + import unittest -from jsonresults import JsonResults JSON_RESULTS_TEMPLATE = ( '{"Webkit":{' @@ -118,7 +122,8 @@ class JsonResultsTest(unittest.TestCase): aggregated_results = self._make_test_json(aggregated_data) incremental_results = self._make_test_json(incremental_data) merged_results = JsonResults.merge(self._builder, - aggregated_results, incremental_results, sort_keys=True) + aggregated_results, incremental_results, jsonresults.JSON_RESULTS_MAX_BUILDS, + sort_keys=True) if expected_data: expected_results = self._make_test_json(expected_data) diff --git a/WebKitTools/TestResultServer/model/testfile.py b/WebKitTools/TestResultServer/model/testfile.py index ce92b65..e600c99 100644 --- a/WebKitTools/TestResultServer/model/testfile.py +++ b/WebKitTools/TestResultServer/model/testfile.py @@ -35,11 +35,12 @@ from model.datastorefile import DataStoreFile class TestFile(DataStoreFile): + master = db.StringProperty() builder = db.StringProperty() test_type = db.StringProperty() @classmethod - def delete_file(cls, key, builder, test_type, name, limit): + def delete_file(cls, key, master, builder, test_type, name, limit): if key: file = db.get(key) if not file: @@ -48,10 +49,10 @@ class TestFile(DataStoreFile): file._delete_all() else: - files = cls.get_files(builder, test_type, name, limit) + files = cls.get_files(master, builder, test_type, name, limit) if not files: logging.warning( - "File not found, builder: %s, test_type:%s, name: %s.", + "File not found, master: %s, builder: %s, test_type:%s, name: %s.", builder, test_type, name) return False @@ -61,8 +62,10 @@ class TestFile(DataStoreFile): return True @classmethod - def get_files(cls, builder, test_type, name, load_data=True, limit=1): + def get_files(cls, master, builder, test_type, name, load_data=True, limit=1): query = TestFile.all() + if master: + query = query.filter("master =", master) if builder: query = query.filter("builder =", builder) if test_type: @@ -78,8 +81,9 @@ class TestFile(DataStoreFile): return files @classmethod - def add_file(cls, builder, test_type, name, data): + def add_file(cls, master, builder, test_type, name, data): file = TestFile() + file.master = master file.builder = builder file.test_type = test_type file.name = name @@ -88,24 +92,24 @@ class TestFile(DataStoreFile): return None logging.info( - "File saved, builder: %s, test_type: %s, name: %s, key: %s.", - builder, test_type, file.name, str(file.data_keys)) + "File saved, master: %s, builder: %s, test_type: %s, name: %s, key: %s.", + master, builder, test_type, file.name, str(file.data_keys)) return file @classmethod - def update(cls, builder, test_type, name, data): - files = cls.get_files(builder, test_type, name) + def update(cls, master, builder, test_type, name, data): + files = cls.get_files(master, builder, test_type, name) if not files: - return cls.add_file(builder, test_type, name, data) + return cls.add_file(master, builder, test_type, name, data) file = files[0] if not file.save(data): return None logging.info( - "File replaced, builder: %s, test_type: %s, name: %s, data key: %s.", - builder, test_type, file.name, str(file.data_keys)) + "File replaced, master: %s, builder: %s, test_type: %s, name: %s, data key: %s.", + master, builder, test_type, file.name, str(file.data_keys)) return file diff --git a/WebKitTools/TestResultServer/templates/showfilelist.html b/WebKitTools/TestResultServer/templates/showfilelist.html index fa72b7f..d292fe2 100644 --- a/WebKitTools/TestResultServer/templates/showfilelist.html +++ b/WebKitTools/TestResultServer/templates/showfilelist.html @@ -13,6 +13,7 @@ <div> <table> <tr> + <th>Master</th> <th>Builder</th> <th>Test Type</th> <th>File</th> @@ -22,6 +23,10 @@ {% endif %} {% for file in files %} <tr>{% if file.builder and file.name %} + <td><a href="/testfile?master={{ file.master }}" > + {{ file.master }} + </a> + </td> <td><a href="/testfile?builder={{ file.builder }}" > {{ file.builder }} </a> diff --git a/WebKitTools/TestResultServer/templates/uploadform.html b/WebKitTools/TestResultServer/templates/uploadform.html index 3506c9c..9974a24 100644 --- a/WebKitTools/TestResultServer/templates/uploadform.html +++ b/WebKitTools/TestResultServer/templates/uploadform.html @@ -10,12 +10,16 @@ <br> <table> <tr> + <td class=label><label>Master:</label></td> + <td><input class=inputtext type="text" name="master" placeholder="Chromium"/></td> + </tr> + <tr> <td class=label><label>Builder:</label></td> - <td><input class=inputtext type="text" name="builder" value="Webkit"/></td> + <td><input class=inputtext type="text" name="builder" placeholder="Webkit"/></td> </tr> <tr> <td class=label><label>Test Type:</label></td> - <td><input class=inputtext type="text" name="testtype" value=""/></td> + <td><input class=inputtext type="text" name="testtype" placeholder="layout-tests"/></td> </tr> </table> <br> diff --git a/WebKitTools/TestWebKitAPI/Configurations/InjectedBundle.xcconfig b/WebKitTools/TestWebKitAPI/Configurations/InjectedBundle.xcconfig index 4d3d1ee..6bf31b2 100644 --- a/WebKitTools/TestWebKitAPI/Configurations/InjectedBundle.xcconfig +++ b/WebKitTools/TestWebKitAPI/Configurations/InjectedBundle.xcconfig @@ -21,4 +21,4 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -PRODUCT_NAME = InjectedBundle +PRODUCT_NAME = InjectedBundleTestWebKitAPI diff --git a/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp b/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp index dc563ac..2674801 100644 --- a/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp +++ b/WebKitTools/TestWebKitAPI/InjectedBundleController.cpp @@ -81,7 +81,7 @@ void InjectedBundleController::didReceiveMessage(WKBundleRef bundle, WKStringRef assert(WKGetTypeID(messageBody) == WKStringGetTypeID()); WKStringRef messageBodyString = static_cast<WKStringRef>(messageBody); - self->initializeTestNamed(Util::toSTD(messageBodyString)); + self->initializeTestNamed(bundle, Util::toSTD(messageBodyString)); return; } @@ -98,7 +98,7 @@ void InjectedBundleController::dumpTestNames() printf("%s\n", (*it).first.c_str()); } -void InjectedBundleController::initializeTestNamed(const std::string& identifier) +void InjectedBundleController::initializeTestNamed(WKBundleRef bundle, const std::string& identifier) { CreateInjectedBundleTestFunction createTestFunction = m_createInjectedBundleTestFunctions[identifier]; if (!createTestFunction) { @@ -107,7 +107,7 @@ void InjectedBundleController::initializeTestNamed(const std::string& identifier } m_currentTest = createTestFunction(identifier); - m_currentTest->initialize(); + m_currentTest->initialize(bundle); } void InjectedBundleController::registerCreateInjectedBundleTestFunction(const std::string& identifier, CreateInjectedBundleTestFunction function) diff --git a/WebKitTools/TestWebKitAPI/InjectedBundleController.h b/WebKitTools/TestWebKitAPI/InjectedBundleController.h index 89e2c5e..8b45fff 100644 --- a/WebKitTools/TestWebKitAPI/InjectedBundleController.h +++ b/WebKitTools/TestWebKitAPI/InjectedBundleController.h @@ -41,7 +41,7 @@ public: void initialize(WKBundleRef); void dumpTestNames(); - void initializeTestNamed(const std::string&); + void initializeTestNamed(WKBundleRef bundle, const std::string&); typedef InjectedBundleTest* (*CreateInjectedBundleTestFunction)(const std::string&); void registerCreateInjectedBundleTestFunction(const std::string&, CreateInjectedBundleTestFunction); diff --git a/WebKitTools/TestWebKitAPI/InjectedBundleTest.h b/WebKitTools/TestWebKitAPI/InjectedBundleTest.h index f3812ef..b0224f2 100644 --- a/WebKitTools/TestWebKitAPI/InjectedBundleTest.h +++ b/WebKitTools/TestWebKitAPI/InjectedBundleTest.h @@ -34,7 +34,7 @@ class InjectedBundleTest { public: virtual ~InjectedBundleTest() { } - virtual void initialize() { } + virtual void initialize(WKBundleRef) { } virtual void didCreatePage(WKBundleRef, WKBundlePageRef) { } virtual void willDestroyPage(WKBundleRef, WKBundlePageRef) { } diff --git a/WebKitTools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/WebKitTools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj index fa967b7..ef55b28 100644 --- a/WebKitTools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj +++ b/WebKitTools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 1A02C84F125D4A8400E3F4BD /* Find.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A02C84E125D4A8400E3F4BD /* Find.cpp */; }; 1A02C870125D4CFD00E3F4BD /* find.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1A02C84B125D4A5E00E3F4BD /* find.html */; }; + 1A5FEFDD1270E2A3000E2921 /* EvaluateJavaScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5FEFDC1270E2A3000E2921 /* EvaluateJavaScript.cpp */; }; + 333B9CE21277F23100FEFCE3 /* PreventEmptyUserAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */; }; BC131885117114B600B69727 /* PlatformUtilitiesMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC131884117114B600B69727 /* PlatformUtilitiesMac.mm */; }; BC131A9B1171316900B69727 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC131A9A1171316900B69727 /* main.mm */; }; BC131AA9117131FC00B69727 /* TestsController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC131AA8117131FC00B69727 /* TestsController.cpp */; }; @@ -30,6 +32,8 @@ BC90995E12567BC100083756 /* WKString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC90995D12567BC100083756 /* WKString.cpp */; }; BC9099941256ACF100083756 /* WKStringJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9099931256ACF100083756 /* WKStringJSString.cpp */; }; BCA61DB511700EFD00460D1E /* WebKit2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCA61DB411700EFD00460D1E /* WebKit2.framework */; }; + BCB68040126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB6803F126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp */; }; + BCB68042126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB68041126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp */; }; BCB9E9F111235BDE00A137E0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCB9E9F011235BDE00A137E0 /* Cocoa.framework */; }; BCBD3710125AA2EB00D2C29F /* FrameMIMETypeHTML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCBD370F125AA2EB00D2C29F /* FrameMIMETypeHTML.cpp */; }; BCBD3737125ABBEB00D2C29F /* icon.png in Copy Resources */ = {isa = PBXBuildFile; fileRef = BCBD372E125ABBE600D2C29F /* icon.png */; }; @@ -45,7 +49,7 @@ isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = BC57597F126E74AF006F0F12 /* InjectedBundle */; + remoteGlobalIDString = BC57597F126E74AF006F0F12; remoteInfo = InjectedBundle; }; /* End PBXContainerItemProxy section */ @@ -79,6 +83,8 @@ /* Begin PBXFileReference section */ 1A02C84B125D4A5E00E3F4BD /* find.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = find.html; sourceTree = "<group>"; }; 1A02C84E125D4A8400E3F4BD /* Find.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Find.cpp; sourceTree = "<group>"; }; + 1A5FEFDC1270E2A3000E2921 /* EvaluateJavaScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EvaluateJavaScript.cpp; sourceTree = "<group>"; }; + 333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreventEmptyUserAgent.cpp; sourceTree = "<group>"; }; 8DD76FA10486AA7600D96B5E /* TestWebKitAPI */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TestWebKitAPI; sourceTree = BUILT_PRODUCTS_DIR; }; BC131883117114A800B69727 /* PlatformUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformUtilities.h; sourceTree = "<group>"; }; BC131884117114B600B69727 /* PlatformUtilitiesMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformUtilitiesMac.mm; sourceTree = "<group>"; }; @@ -86,7 +92,7 @@ BC131A9E1171317C00B69727 /* TestWebKitAPIPrefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestWebKitAPIPrefix.h; sourceTree = "<group>"; }; BC131AA8117131FC00B69727 /* TestsController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = TestsController.cpp; sourceTree = "<group>"; }; BC575946126E7351006F0F12 /* InjectedBundleMain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleMain.cpp; sourceTree = "<group>"; }; - BC575980126E74AF006F0F12 /* InjectedBundle.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InjectedBundle.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + BC575980126E74AF006F0F12 /* InjectedBundleTestWebKitAPI.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InjectedBundleTestWebKitAPI.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; BC575981126E74AF006F0F12 /* InjectedBundle-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "InjectedBundle-Info.plist"; sourceTree = "<group>"; }; BC575A9E126E75FB006F0F12 /* InjectedBundleTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundleTest.h; sourceTree = "<group>"; }; BC575A9F126E7657006F0F12 /* InjectedBundleController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundleController.h; sourceTree = "<group>"; }; @@ -107,6 +113,8 @@ BC90995D12567BC100083756 /* WKString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKString.cpp; sourceTree = "<group>"; }; BC9099931256ACF100083756 /* WKStringJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKStringJSString.cpp; sourceTree = "<group>"; }; BCA61DB411700EFD00460D1E /* WebKit2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit2.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BCB6803F126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentStartUserScriptAlertCrash.cpp; sourceTree = "<group>"; }; + BCB68041126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentStartUserScriptAlertCrash_Bundle.cpp; sourceTree = "<group>"; }; BCB9E7C711234E3A00A137E0 /* TestsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestsController.h; sourceTree = "<group>"; }; BCB9E7FA112359A300A137E0 /* Test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Test.h; sourceTree = "<group>"; }; BCB9E9F011235BDE00A137E0 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; @@ -188,7 +196,7 @@ isa = PBXGroup; children = ( 8DD76FA10486AA7600D96B5E /* TestWebKitAPI */, - BC575980126E74AF006F0F12 /* InjectedBundle.bundle */, + BC575980126E74AF006F0F12 /* InjectedBundleTestWebKitAPI.bundle */, ); name = Products; sourceTree = "<group>"; @@ -219,16 +227,20 @@ isa = PBXGroup; children = ( BC90977B125571AE00083756 /* Resources */, + 1A5FEFDC1270E2A3000E2921 /* EvaluateJavaScript.cpp */, 1A02C84E125D4A8400E3F4BD /* Find.cpp */, BCBD370F125AA2EB00D2C29F /* FrameMIMETypeHTML.cpp */, BCBD3760125ABCFE00D2C29F /* FrameMIMETypePNG.cpp */, BC909779125571AB00083756 /* PageLoadBasic.cpp */, + 333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */, C02B77F1126612140026BF0F /* SpacebarScrolling.cpp */, BC90995D12567BC100083756 /* WKString.cpp */, BC9099931256ACF100083756 /* WKStringJSString.cpp */, BCC8B95A12611F4700DE46A4 /* FailedLoad.cpp */, BC575AAC126E83B9006F0F12 /* InjectedBundleBasic.cpp */, BC575AAF126E83C8006F0F12 /* InjectedBundleBasic_Bundle.cpp */, + BCB6803F126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp */, + BCB68041126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp */, ); path = WebKit2; sourceTree = "<group>"; @@ -244,8 +256,8 @@ BC90977B125571AE00083756 /* Resources */ = { isa = PBXGroup; children = ( - BCBD372E125ABBE600D2C29F /* icon.png */, 1A02C84B125D4A5E00E3F4BD /* find.html */, + BCBD372E125ABBE600D2C29F /* icon.png */, BC909778125571AB00083756 /* simple.html */, C02B7882126615410026BF0F /* spacebar-scrolling.html */, ); @@ -294,9 +306,9 @@ productReference = 8DD76FA10486AA7600D96B5E /* TestWebKitAPI */; productType = "com.apple.product-type.tool"; }; - BC57597F126E74AF006F0F12 /* InjectedBundle */ = { + BC57597F126E74AF006F0F12 /* InjectedBundleTestWebKitAPI */ = { isa = PBXNativeTarget; - buildConfigurationList = BC575986126E74AF006F0F12 /* Build configuration list for PBXNativeTarget "InjectedBundle" */; + buildConfigurationList = BC575986126E74AF006F0F12 /* Build configuration list for PBXNativeTarget "InjectedBundleTestWebKitAPI" */; buildPhases = ( BC57597C126E74AF006F0F12 /* Resources */, BC57597D126E74AF006F0F12 /* Sources */, @@ -306,9 +318,9 @@ ); dependencies = ( ); - name = InjectedBundle; + name = InjectedBundleTestWebKitAPI; productName = InjectedBundle; - productReference = BC575980126E74AF006F0F12 /* InjectedBundle.bundle */; + productReference = BC575980126E74AF006F0F12 /* InjectedBundleTestWebKitAPI.bundle */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -331,7 +343,7 @@ projectRoot = ""; targets = ( 8DD76F960486AA7600D96B5E /* TestWebKitAPI */, - BC57597F126E74AF006F0F12 /* InjectedBundle */, + BC57597F126E74AF006F0F12 /* InjectedBundleTestWebKitAPI */, ); }; /* End PBXProject section */ @@ -366,6 +378,9 @@ C02B77F2126612140026BF0F /* SpacebarScrolling.cpp in Sources */, BC575AAD126E83B9006F0F12 /* InjectedBundleBasic.cpp in Sources */, BC575BC0126F5752006F0F12 /* PlatformUtilities.cpp in Sources */, + BCB68040126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp in Sources */, + 1A5FEFDD1270E2A3000E2921 /* EvaluateJavaScript.cpp in Sources */, + 333B9CE21277F23100FEFCE3 /* PreventEmptyUserAgent.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -378,6 +393,7 @@ BC575AB0126E83C8006F0F12 /* InjectedBundleBasic_Bundle.cpp in Sources */, BC575BD9126F58E2006F0F12 /* PlatformUtilities.cpp in Sources */, BC575BE0126F590D006F0F12 /* PlatformUtilitiesMac.mm in Sources */, + BCB68042126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -386,7 +402,7 @@ /* Begin PBXTargetDependency section */ BC575A96126E74E7006F0F12 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BC57597F126E74AF006F0F12 /* InjectedBundle */; + target = BC57597F126E74AF006F0F12 /* InjectedBundleTestWebKitAPI */; targetProxy = BC575A95126E74E7006F0F12 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -458,7 +474,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - BC575986126E74AF006F0F12 /* Build configuration list for PBXNativeTarget "InjectedBundle" */ = { + BC575986126E74AF006F0F12 /* Build configuration list for PBXNativeTarget "InjectedBundleTestWebKitAPI" */ = { isa = XCConfigurationList; buildConfigurations = ( BC575984126E74AF006F0F12 /* Debug */, diff --git a/WebKitTools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash.cpp b/WebKitTools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash.cpp new file mode 100644 index 0000000..5e0655e --- /dev/null +++ b/WebKitTools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Test.h" + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include <WebKit2/WebKit2.h> +#include <WebKit2/WKRetainPtr.h> + +namespace TestWebKitAPI { + +static bool done; + +static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo) +{ + TEST_ASSERT(frame); + TEST_ASSERT(WKFrameGetPage(frame) == page); + TEST_ASSERT(WKStringIsEqualToUTF8CString(alertText, "an alert")); + + done = true; +} + +TEST(WebKit2, DocumentStartUserScriptAlertCrashTest) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextForInjectedBundleTest("DocumentStartUserScriptAlertCrashTest")); + WKRetainPtr<WKPageNamespaceRef> pageNamespace(AdoptWK, WKPageNamespaceCreate(context.get())); + PlatformWebView webView(pageNamespace.get()); + + WKPageUIClient uiClient; + memset(&uiClient, 0, sizeof(uiClient)); + uiClient.version = 0; + uiClient.clientInfo = 0; + uiClient.runJavaScriptAlert = runJavaScriptAlert; + WKPageSetPageUIClient(webView.page(), &uiClient); + + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&done); +} + +} // namespace TestWebKitAPI diff --git a/WebKitTools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp b/WebKitTools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp new file mode 100644 index 0000000..a96bef2 --- /dev/null +++ b/WebKitTools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "InjectedBundleTest.h" +#include <WebKit2/WebKit2.h> +#include <WebKit2/WKBundlePrivate.h> +#include <WebKit2/WKBundleScriptWorld.h> +#include <WebKit2/WKRetainPtr.h> + +namespace TestWebKitAPI { + +class DocumentStartUserScriptAlertCrashTest : public InjectedBundleTest { +public: + DocumentStartUserScriptAlertCrashTest(const std::string& identifier) + : InjectedBundleTest(identifier) + { + } + + virtual void initialize(WKBundleRef bundle) + { + WKRetainPtr<WKStringRef> source(AdoptWK, WKStringCreateWithUTF8CString("alert('an alert');")); + WKBundleAddUserScript(bundle, WKBundleScriptWorldNormalWorld(), source.get(), 0, 0, 0, kWKInjectAtDocumentStart, kWKInjectInAllFrames); + } +}; + +static InjectedBundleTest::Register<DocumentStartUserScriptAlertCrashTest> registrar("DocumentStartUserScriptAlertCrashTest"); + +} // namespace TestWebKitAPI diff --git a/WebKitTools/TestWebKitAPI/Tests/WebKit2/EvaluateJavaScript.cpp b/WebKitTools/TestWebKitAPI/Tests/WebKit2/EvaluateJavaScript.cpp new file mode 100644 index 0000000..bbdece3 --- /dev/null +++ b/WebKitTools/TestWebKitAPI/Tests/WebKit2/EvaluateJavaScript.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Test.h" + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include <WebKit2/WKRetainPtr.h> +#include <WebKit2/WebKit2.h> + +namespace TestWebKitAPI { + +static bool testDone; + +static void didRunJavaScript(WKStringRef resultString, WKErrorRef error, void* context) +{ + TEST_ASSERT(context == reinterpret_cast<void*>(0x1234578)); + TEST_ASSERT(WKStringIsEmpty(resultString)); + + // FIXME: We should also check the error, but right now it's always null. + // Assert that it's null so we can revisit when this changes. + TEST_ASSERT(!error); + + testDone = true; +} + +TEST(WebKit2, EvaluateJavaScriptThatThrowsAnException) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + WKRetainPtr<WKPageNamespaceRef> pageNamespace(AdoptWK, WKPageNamespaceCreate(context.get())); + PlatformWebView webView(pageNamespace.get()); + + WKRetainPtr<WKStringRef> javaScriptString(AdoptWK, WKStringCreateWithUTF8CString("throw 'Hello'")); + WKPageRunJavaScriptInMainFrame(webView.page(), javaScriptString.get(), reinterpret_cast<void*>(0x1234578), didRunJavaScript); + + Util::run(&testDone); +} + +} // namespace TestWebKitAPI diff --git a/WebKitTools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp b/WebKitTools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp index a0b4058..c3af543 100644 --- a/WebKitTools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp +++ b/WebKitTools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp @@ -52,8 +52,13 @@ static void didStartProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WK State* state = reinterpret_cast<State*>(const_cast<void*>(clientInfo)); TEST_ASSERT(state->didDecidePolicyForNavigationAction); TEST_ASSERT(!state->didCommitLoadForFrame); + + // The commited URL should be null. + TEST_ASSERT(!WKFrameCopyURL(frame)); + TEST_ASSERT(!state->didStartProvisionalLoadForFrame); + state->didStartProvisionalLoadForFrame = true; } @@ -63,6 +68,9 @@ static void didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef us TEST_ASSERT(state->didDecidePolicyForNavigationAction); TEST_ASSERT(state->didStartProvisionalLoadForFrame); + // The provisional URL should be null. + TEST_ASSERT(!WKFrameCopyProvisionalURL(frame)); + state->didCommitLoadForFrame = true; } @@ -73,6 +81,9 @@ static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef us TEST_ASSERT(state->didStartProvisionalLoadForFrame); TEST_ASSERT(state->didCommitLoadForFrame); + // The provisional URL should be null. + TEST_ASSERT(!WKFrameCopyProvisionalURL(frame)); + test1Done = true; } diff --git a/WebKitTools/TestWebKitAPI/Tests/WebKit2/PreventEmptyUserAgent.cpp b/WebKitTools/TestWebKitAPI/Tests/WebKit2/PreventEmptyUserAgent.cpp new file mode 100644 index 0000000..af3ed12 --- /dev/null +++ b/WebKitTools/TestWebKitAPI/Tests/WebKit2/PreventEmptyUserAgent.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Test.h" + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include <WebKit2/WKRetainPtr.h> +#include <WebKit2/WebKit2.h> + +namespace TestWebKitAPI { + +static bool testDone; + +static void didRunJavaScript(WKStringRef resultString, WKErrorRef error, void* context) +{ + TEST_ASSERT(context == reinterpret_cast<void*>(0x1234578)); + + // Make sure that the result of navigator.userAgent isn't empty, even if we set the custom + // user agent to the empty string. + TEST_ASSERT(!WKStringIsEmpty(resultString)); + + testDone = true; +} + +TEST(WebKit2, PreventEmptyUserAgent) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + WKRetainPtr<WKPageNamespaceRef> pageNamespace(AdoptWK, WKPageNamespaceCreate(context.get())); + PlatformWebView webView(pageNamespace.get()); + + WKPageSetCustomUserAgent(webView.page(), WKStringCreateWithUTF8CString("")); + WKRetainPtr<WKStringRef> javaScriptString(AdoptWK, WKStringCreateWithUTF8CString("navigator.userAgent")); + WKPageRunJavaScriptInMainFrame(webView.page(), javaScriptString.get(), reinterpret_cast<void*>(0x1234578), didRunJavaScript); + + Util::run(&testDone); +} + +} // namespace TestWebKitAPI diff --git a/WebKitTools/TestWebKitAPI/Tests/WebKit2/win/WMCloseCallsUIClientClose.cpp b/WebKitTools/TestWebKitAPI/Tests/WebKit2/win/WMCloseCallsUIClientClose.cpp new file mode 100644 index 0000000..a019f08 --- /dev/null +++ b/WebKitTools/TestWebKitAPI/Tests/WebKit2/win/WMCloseCallsUIClientClose.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Test.h" + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include <WebKit2/WKRetainPtr.h> + +namespace TestWebKitAPI { + +static bool didReceiveClose; + +static void close(WKPageRef, const void*) +{ + didReceiveClose = true; +} + +TEST(WebKit2, WMCloseCallsUIClientClose) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + WKRetainPtr<WKPageNamespaceRef> pageNamespace(AdoptWK, WKPageNamespaceCreate(context.get())); + + PlatformWebView webView(pageNamespace.get()); + + WKPageUIClient uiClient; + memset(&uiClient, 0, sizeof(uiClient)); + + uiClient.close = close; + WKPageSetPageUIClient(webView.page(), &uiClient); + + ::SendMessageW(WKViewGetWindow(webView.platformView()), WM_CLOSE, 0, 0); + + Util::run(&didReceiveClose); +} + +} // namespace TestWebKitAPI diff --git a/WebKitTools/TestWebKitAPI/mac/PlatformUtilitiesMac.mm b/WebKitTools/TestWebKitAPI/mac/PlatformUtilitiesMac.mm index a9552fd..474278f 100644 --- a/WebKitTools/TestWebKitAPI/mac/PlatformUtilitiesMac.mm +++ b/WebKitTools/TestWebKitAPI/mac/PlatformUtilitiesMac.mm @@ -41,7 +41,7 @@ void run(bool* done) WKStringRef createInjectedBundlePath() { - NSString *nsString = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"InjectedBundle.bundle"]; + NSString *nsString = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"InjectedBundleTestWebKitAPI.bundle"]; return WKStringCreateWithCFString((CFStringRef)nsString); } diff --git a/WebKitTools/TestWebKitAPI/win/TestWebKitAPI.vcproj b/WebKitTools/TestWebKitAPI/win/TestWebKitAPI.vcproj index 44bf963..2e7bbe4 100644 --- a/WebKitTools/TestWebKitAPI/win/TestWebKitAPI.vcproj +++ b/WebKitTools/TestWebKitAPI/win/TestWebKitAPI.vcproj @@ -417,6 +417,10 @@ Name="WebKit2"
>
<File
+ RelativePath="..\Tests\WebKit2\EvaluateJavaScript.cpp"
+ >
+ </File>
+ <File
RelativePath="..\Tests\WebKit2\FailedLoad.cpp"
>
</File>
@@ -445,6 +449,10 @@ >
</File>
<File
+ RelativePath="..\Tests\WebKit2\PreventEmptyUserAgent.cpp"
+ >
+ </File>
+ <File
RelativePath="..\Tests\WebKit2\simple.html"
>
</File>
@@ -471,6 +479,10 @@ RelativePath="..\Tests\WebKit2\win\AltKeyGeneratesWMSysCommand.cpp"
>
</File>
+ <File
+ RelativePath="..\Tests\WebKit2\win\WMCloseCallsUIClientClose.cpp"
+ >
+ </File>
</Filter>
</Filter>
<Filter
diff --git a/WebKitTools/WebKitTestRunner/Configurations/InjectedBundle.xcconfig b/WebKitTools/WebKitTestRunner/Configurations/InjectedBundle.xcconfig index 4d3d1ee..dcf4be0 100644 --- a/WebKitTools/WebKitTestRunner/Configurations/InjectedBundle.xcconfig +++ b/WebKitTools/WebKitTestRunner/Configurations/InjectedBundle.xcconfig @@ -21,4 +21,4 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -PRODUCT_NAME = InjectedBundle +PRODUCT_NAME = WebKitTestRunnerInjectedBundle diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl b/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl index f3c5e88..a0e36ad 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl @@ -33,6 +33,7 @@ module WTR { void notifyDone(); // Other dumping. + void dumpBackForwardList(); void dumpChildFrameScrollPositions(); void dumpEditingCallbacks(); void dumpSelectionRect(); @@ -45,14 +46,15 @@ module WTR { void setCanOpenWindows(in boolean value); void setCloseRemainingWindowsWhenComplete(in boolean value); void setXSSAuditorEnabled(in boolean value); - unsigned long windowCount(); // Special DOM functions. + void clearBackForwardList(); object computedStyleIncludingVisitedInfo(in object element); DOMString counterValueForElementById(in DOMString elementId); - DOMString markerTextForListItem(in object element); void execCommand(in DOMString name, in DOMString argument); boolean isCommandEnabled(in DOMString name); + DOMString markerTextForListItem(in object element); + unsigned long windowCount(); // Repaint testing. void testRepaint(); @@ -66,6 +68,9 @@ module WTR { // UserContent testing. void addUserScript(in DOMString source, in boolean runAtStart, in boolean allFrames); void addUserStyleSheet(in DOMString source, in boolean allFrames); + + // Compositing testing. + DOMString layerTreeAsText(); }; } diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp index af8bb69..6bc1802 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp @@ -27,6 +27,7 @@ #include "ActivateFonts.h" #include "InjectedBundlePage.h" +#include "StringFunctions.h" #include <WebKit2/WKBundle.h> #include <WebKit2/WKBundlePage.h> #include <WebKit2/WKBundlePagePrivate.h> @@ -46,22 +47,21 @@ InjectedBundle& InjectedBundle::shared() InjectedBundle::InjectedBundle() : m_bundle(0) - , m_mainPage(0) , m_state(Idle) { } -void InjectedBundle::_didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo) +void InjectedBundle::didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo) { static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didCreatePage(page); } -void InjectedBundle::_willDestroyPage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo) +void InjectedBundle::willDestroyPage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo) { static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->willDestroyPage(page); } -void InjectedBundle::_didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo) +void InjectedBundle::didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo) { static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didReceiveMessage(messageName, messageBody); } @@ -73,9 +73,9 @@ void InjectedBundle::initialize(WKBundleRef bundle) WKBundleClient client = { 0, this, - _didCreatePage, - _willDestroyPage, - _didReceiveMessage + didCreatePage, + willDestroyPage, + didReceiveMessage }; WKBundleSetClient(m_bundle, &client); @@ -85,20 +85,25 @@ void InjectedBundle::initialize(WKBundleRef bundle) void InjectedBundle::didCreatePage(WKBundlePageRef page) { - // FIXME: we really need the main page ref to be sent over from the ui process - OwnPtr<InjectedBundlePage> pageWrapper = adoptPtr(new InjectedBundlePage(page)); - if (!m_mainPage) - m_mainPage = pageWrapper.release(); - else - m_otherPages.add(page, pageWrapper.leakPtr()); + m_pages.append(adoptPtr(new InjectedBundlePage(page))); } void InjectedBundle::willDestroyPage(WKBundlePageRef page) { - if (m_mainPage && m_mainPage->page() == page) - m_mainPage.clear(); - else - delete m_otherPages.take(page); + size_t size = m_pages.size(); + for (size_t i = 0; i < size; ++i) { + if (m_pages[i]->page() == page) { + m_pages.remove(i); + break; + } + } +} + +InjectedBundlePage* InjectedBundle::page() const +{ + // It might be better to have the UI process send over a reference to the main + // page instead of just assuming it's the first one. + return m_pages[0].get(); } void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody) @@ -134,14 +139,14 @@ void InjectedBundle::beginTesting() WKBundleRemoveAllUserContent(m_bundle); - m_mainPage->reset(); + page()->reset(); } void InjectedBundle::done() { m_state = Stopping; - m_mainPage->stopLoading(); + page()->stopLoading(); WKRetainPtr<WKStringRef> doneMessageName(AdoptWK, WKStringCreateWithUTF8CString("Done")); WKRetainPtr<WKStringRef> doneMessageBody(AdoptWK, WKStringCreateWithUTF8CString(m_outputStream.str().c_str())); @@ -153,10 +158,20 @@ void InjectedBundle::done() void InjectedBundle::closeOtherPages() { - Vector<WKBundlePageRef> pages; - copyKeysToVector(m_otherPages, pages); - for (size_t i = 0; i < pages.size(); ++i) - WKBundlePageClose(pages[i]); + Vector<WKBundlePageRef> pagesToClose; + size_t size = m_pages.size(); + for (size_t i = 1; i < size; ++i) + pagesToClose.append(m_pages[i]->page()); + size = pagesToClose.size(); + for (size_t i = 0; i < size; ++i) + WKBundlePageClose(pagesToClose[i]); +} + +void InjectedBundle::dumpBackForwardListsForAllPages() +{ + size_t size = m_pages.size(); + for (size_t i = 0; i < size; ++i) + m_pages[i]->dumpBackForwardList(); } } // namespace WTR diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h index 6c5c69e..2c6d14b 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundle.h @@ -30,9 +30,9 @@ #include "GCController.h" #include "LayoutTestController.h" #include <WebKit2/WKBase.h> -#include <wtf/HashMap.h> #include <wtf/OwnPtr.h> #include <wtf/RefPtr.h> +#include <wtf/Vector.h> #include <sstream> @@ -53,10 +53,12 @@ public: GCController* gcController() { return m_gcController.get(); } EventSendingController* eventSendingController() { return m_eventSendingController.get(); } - InjectedBundlePage* page() { return m_mainPage.get(); } - size_t pageCount() { return !!m_mainPage + m_otherPages.size(); } + InjectedBundlePage* page() const; + size_t pageCount() const { return m_pages.size(); } void closeOtherPages(); + void dumpBackForwardListsForAllPages(); + void done(); std::ostringstream& os() { return m_outputStream; } @@ -66,19 +68,18 @@ private: InjectedBundle(); ~InjectedBundle(); - static void _didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo); - static void _willDestroyPage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo); - static void _didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo); + static void didCreatePage(WKBundleRef, WKBundlePageRef, const void* clientInfo); + static void willDestroyPage(WKBundleRef, WKBundlePageRef, const void* clientInfo); + static void didReceiveMessage(WKBundleRef, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo); - void didCreatePage(WKBundlePageRef page); - void willDestroyPage(WKBundlePageRef page); + void didCreatePage(WKBundlePageRef); + void willDestroyPage(WKBundlePageRef); void didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody); void beginTesting(); WKBundleRef m_bundle; - HashMap<WKBundlePageRef, InjectedBundlePage*> m_otherPages; - OwnPtr<InjectedBundlePage> m_mainPage; + Vector<OwnPtr<InjectedBundlePage> > m_pages; RefPtr<LayoutTestController> m_layoutTestController; RefPtr<GCController> m_gcController; diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp index 22af6ff..d852dd2 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp @@ -30,6 +30,9 @@ #include <cmath> #include <JavaScriptCore/JSRetainPtr.h> #include <WebKit2/WKArray.h> +#include <WebKit2/WKBundle.h> +#include <WebKit2/WKBundleBackForwardList.h> +#include <WebKit2/WKBundleBackForwardListItem.h> #include <WebKit2/WKBundleFrame.h> #include <WebKit2/WKBundleFramePrivate.h> #include <WebKit2/WKBundlePagePrivate.h> @@ -38,6 +41,16 @@ using namespace std; namespace WTR { +template<typename T> static inline WKRetainPtr<T> adoptWK(T item) +{ + return WKRetainPtr<T>(AdoptWK, item); +} + +static bool hasPrefix(const string& searchString, const string& prefix) +{ + return searchString.length() >= prefix.length() && searchString.substr(0, prefix.length()) == prefix; +} + static JSValueRef propertyValue(JSContextRef context, JSObjectRef object, const char* propertyName) { if (!object) @@ -171,13 +184,13 @@ InjectedBundlePage::InjectedBundlePage(WKBundlePageRef page) 0, 0, 0, + didDisplayInsecureContentForFrame, + didRunInsecureContentForFrame, didClearWindowForFrame, didCancelClientRedirectForFrame, willPerformClientRedirectForFrame, didChangeLocationWithinPageForFrame, - didHandleOnloadEventsForFrame, - didDisplayInsecureContentForFrame, - didRunInsecureContentForFrame + didHandleOnloadEventsForFrame }; WKBundlePageSetLoaderClient(m_page, &loaderClient); @@ -189,7 +202,8 @@ InjectedBundlePage::InjectedBundlePage(WKBundlePageRef page) willRunJavaScriptAlert, willRunJavaScriptConfirm, willRunJavaScriptPrompt, - 0 /*mouseDidMoveOverElement*/ + 0, /*mouseDidMoveOverElement*/ + 0, /*pageDidScroll*/ }; WKBundlePageSetUIClient(m_page, &uiClient); @@ -227,6 +241,8 @@ void InjectedBundlePage::reset() WKBundlePageSetPageZoomFactor(m_page, 1); WKBundlePageSetTextZoomFactor(m_page, 1); + + m_previousTestBackForwardListItem = adoptWK(WKBundleBackForwardListCopyItemAtIndex(WKBundlePageGetBackForwardList(m_page), 0)); } // Loader Client Callbacks @@ -296,12 +312,12 @@ void InjectedBundlePage::didHandleOnloadEventsForFrame(WKBundlePageRef page, WKB static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didHandleOnloadEventsForFrame(frame); } -void InjectedBundlePage::didDisplayInsecureContentForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void* clientInfo) +void InjectedBundlePage::didDisplayInsecureContentForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef*, const void* clientInfo) { static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didDisplayInsecureContentForFrame(frame); } -void InjectedBundlePage::didRunInsecureContentForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void* clientInfo) +void InjectedBundlePage::didRunInsecureContentForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef*, const void* clientInfo) { static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didRunInsecureContentForFrame(frame); } @@ -361,8 +377,38 @@ void InjectedBundlePage::dumpAllFrameScrollPositions() dumpDescendantFrameScrollPositions(frame); } +static JSRetainPtr<JSStringRef> toJS(const char* string) +{ + return JSRetainPtr<JSStringRef>(Adopt, JSStringCreateWithUTF8CString(string)); +} + +static bool hasDocumentElement(WKBundleFrameRef frame) +{ + JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); + JSObjectRef globalObject = JSContextGetGlobalObject(context); + + JSValueRef documentValue = JSObjectGetProperty(context, globalObject, toJS("document").get(), 0); + if (!documentValue) + return false; + + ASSERT(JSValueIsObject(context, documentValue)); + JSObjectRef document = JSValueToObject(context, documentValue, 0); + + JSValueRef documentElementValue = JSObjectGetProperty(context, document, toJS("documentElement").get(), 0); + if (!documentElementValue) + return false; + + return JSValueToBoolean(context, documentElementValue); +} + static void dumpFrameText(WKBundleFrameRef frame) { + // If the frame doesn't have a document element, its inner text will be an empty string, so + // we'll end up just appending a single newline below. But DumpRenderTree doesn't append + // anything in this case, so we shouldn't either. + if (!hasDocumentElement(frame)) + return; + WKRetainPtr<WKStringRef> text(AdoptWK, WKBundleFrameCopyInnerText(frame)); InjectedBundle::shared().os() << text << "\n"; } @@ -412,6 +458,9 @@ void InjectedBundlePage::dump() else if (InjectedBundle::shared().layoutTestController()->shouldDumpMainFrameScrollPosition()) dumpFrameScrollPosition(WKBundlePageGetMainFrame(m_page)); + if (InjectedBundle::shared().layoutTestController()->shouldDumpBackForwardListsForAllWindows()) + InjectedBundle::shared().dumpBackForwardListsForAllPages(); + InjectedBundle::shared().done(); } @@ -764,4 +813,89 @@ void InjectedBundlePage::didChangeSelection(WKStringRef notificationName) InjectedBundle::shared().os() << "EDITING DELEGATE: webViewDidChangeSelection:" << notificationName << "\n"; } +static bool compareByTargetName(WKBundleBackForwardListItemRef item1, WKBundleBackForwardListItemRef item2) +{ + return toSTD(adoptWK(WKBundleBackForwardListItemCopyTarget(item1))) < toSTD(adoptWK(WKBundleBackForwardListItemCopyTarget(item2))); +} + +static void dumpBackForwardListItem(WKBundleBackForwardListItemRef item, unsigned indent, bool isCurrentItem) +{ + unsigned column = 0; + if (isCurrentItem) { + InjectedBundle::shared().os() << "curr->"; + column = 6; + } + for (unsigned i = column; i < indent; i++) + InjectedBundle::shared().os() << ' '; + + string url = toSTD(adoptWK(WKURLCopyString(adoptWK(WKBundleBackForwardListItemCopyURL(item)).get()))); + if (hasPrefix(url, "file:")) { + string directoryName = "/LayoutTests/"; + size_t start = url.find(directoryName); + if (start == string::npos) + start = 0; + else + start += directoryName.size(); + InjectedBundle::shared().os() << "(file test):" << url.substr(start); + } else + InjectedBundle::shared().os() << url; + + string target = toSTD(adoptWK(WKBundleBackForwardListItemCopyTarget(item))); + if (target.length()) + InjectedBundle::shared().os() << " (in frame \"" << target << "\")"; + + // FIXME: Need WKBackForwardListItemIsTargetItem. + if (WKBundleBackForwardListItemIsTargetItem(item)) + InjectedBundle::shared().os() << " **nav target**"; + + InjectedBundle::shared().os() << '\n'; + + if (WKRetainPtr<WKArrayRef> kids = adoptWK(WKBundleBackForwardListItemCopyChildren(item))) { + // Sort to eliminate arbitrary result ordering which defeats reproducible testing. + size_t size = WKArrayGetSize(kids.get()); + Vector<WKBundleBackForwardListItemRef> sortedKids(size); + for (size_t i = 0; i < size; ++i) + sortedKids[i] = static_cast<WKBundleBackForwardListItemRef>(WKArrayGetItemAtIndex(kids.get(), i)); + stable_sort(sortedKids.begin(), sortedKids.end(), compareByTargetName); + for (size_t i = 0; i < size; ++i) + dumpBackForwardListItem(sortedKids[i], indent + 4, false); + } +} + +void InjectedBundlePage::dumpBackForwardList() +{ + InjectedBundle::shared().os() << "\n============== Back Forward List ==============\n"; + + WKBundleBackForwardListRef list = WKBundlePageGetBackForwardList(m_page); + + // Print out all items in the list after m_previousTestBackForwardListItem. + // Gather items from the end of the list, then print them out from oldest to newest. + Vector<WKRetainPtr<WKBundleBackForwardListItemRef> > itemsToPrint; + for (unsigned i = WKBundleBackForwardListGetForwardListCount(list); i; --i) { + WKRetainPtr<WKBundleBackForwardListItemRef> item = adoptWK(WKBundleBackForwardListCopyItemAtIndex(list, i)); + // Something is wrong if the item from the last test is in the forward part of the list. + ASSERT(!WKBundleBackForwardListItemIsSame(item.get(), m_previousTestBackForwardListItem.get())); + itemsToPrint.append(item); + } + + ASSERT(!WKBundleBackForwardListItemIsSame(adoptWK(WKBundleBackForwardListCopyItemAtIndex(list, 0)).get(), m_previousTestBackForwardListItem.get())); + + itemsToPrint.append(adoptWK(WKBundleBackForwardListCopyItemAtIndex(list, 0))); + + int currentItemIndex = itemsToPrint.size() - 1; + + int backListCount = WKBundleBackForwardListGetBackListCount(list); + for (int i = -1; i >= -backListCount; --i) { + WKRetainPtr<WKBundleBackForwardListItemRef> item = adoptWK(WKBundleBackForwardListCopyItemAtIndex(list, i)); + if (WKBundleBackForwardListItemIsSame(item.get(), m_previousTestBackForwardListItem.get())) + break; + itemsToPrint.append(item); + } + + for (int i = itemsToPrint.size() - 1; i >= 0; i--) + dumpBackForwardListItem(itemsToPrint[i].get(), 8, i == currentItemIndex); + + InjectedBundle::shared().os() << "===============================================\n"; +} + } // namespace WTR diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h index 737ad18..b95744f9 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h @@ -45,6 +45,8 @@ public: void reset(); + void dumpBackForwardList(); + private: // Loader Client static void didStartProvisionalLoadForFrame(WKBundlePageRef, WKBundleFrameRef, WKTypeRef*, const void*); @@ -60,8 +62,8 @@ private: static void willPerformClientRedirectForFrame(WKBundlePageRef, WKBundleFrameRef, WKURLRef url, double delay, double date, const void*); static void didChangeLocationWithinPageForFrame(WKBundlePageRef, WKBundleFrameRef, const void*); static void didHandleOnloadEventsForFrame(WKBundlePageRef, WKBundleFrameRef, const void*); - static void didDisplayInsecureContentForFrame(WKBundlePageRef, WKBundleFrameRef, const void*); - static void didRunInsecureContentForFrame(WKBundlePageRef, WKBundleFrameRef, const void*); + static void didDisplayInsecureContentForFrame(WKBundlePageRef, WKBundleFrameRef, WKTypeRef*, const void*); + static void didRunInsecureContentForFrame(WKBundlePageRef, WKBundleFrameRef, WKTypeRef*, const void*); void didStartProvisionalLoadForFrame(WKBundleFrameRef); void didReceiveServerRedirectForProvisionalLoadForFrame(WKBundleFrameRef); void didFailProvisionalLoadWithErrorForFrame(WKBundleFrameRef, WKErrorRef); @@ -119,6 +121,7 @@ private: WKBundlePageRef m_page; WKRetainPtr<WKBundleScriptWorldRef> m_world; + WKRetainPtr<WKBundleBackForwardListItemRef> m_previousTestBackForwardListItem; bool m_isLoading; }; diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp index f8cbd4f..e828c46 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.cpp @@ -29,6 +29,7 @@ #include "InjectedBundlePage.h" #include "JSLayoutTestController.h" #include "StringFunctions.h" +#include <WebKit2/WKBundleBackForwardList.h> #include <WebKit2/WKBundleFrame.h> #include <WebKit2/WKBundleFramePrivate.h> #include <WebKit2/WKBundlePagePrivate.h> @@ -85,6 +86,7 @@ PassRefPtr<LayoutTestController> LayoutTestController::create() LayoutTestController::LayoutTestController() : m_whatToDump(RenderTree) , m_shouldDumpAllFrameScrollPositions(false) + , m_shouldDumpBackForwardListsForAllWindows(false) , m_shouldAllowEditing(true) , m_shouldCloseExtraWindows(false) , m_dumpEditingCallbacks(false) @@ -148,6 +150,13 @@ bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef anima return WKBundleFramePauseAnimationOnElementWithId(mainFrame, toWK(animationName).get(), toWK(elementId).get(), time); } +JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const +{ + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); + WKRetainPtr<WKStringRef> text(AdoptWK, WKBundleFrameCopyLayerTreeAsText(mainFrame)); + return toJS(text); +} + void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart, bool allFrames) { WKRetainPtr<WKStringRef> sourceWK = toWK(source); @@ -233,6 +242,11 @@ unsigned LayoutTestController::windowCount() return InjectedBundle::shared().pageCount(); } +void LayoutTestController::clearBackForwardList() +{ + WKBundleBackForwardListClear(WKBundlePageGetBackForwardList(InjectedBundle::shared().page()->page())); +} + // Object Creation void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception) diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h index c892ba0..dfafb55 100644 --- a/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h +++ b/WebKitTools/WebKitTestRunner/InjectedBundle/LayoutTestController.h @@ -60,6 +60,7 @@ public: void notifyDone(); // Other dumping. + void dumpBackForwardList() { m_shouldDumpBackForwardListsForAllWindows = true; } void dumpChildFrameScrollPositions() { m_shouldDumpAllFrameScrollPositions = true; } void dumpEditingCallbacks() { m_dumpEditingCallbacks = true; } void dumpSelectionRect() { } // Will need to do something when we support pixel tests. @@ -72,14 +73,15 @@ public: void setCanOpenWindows(bool); void setCloseRemainingWindowsWhenComplete(bool value) { m_shouldCloseExtraWindows = value; } void setXSSAuditorEnabled(bool); - unsigned windowCount(); // Special DOM functions. JSValueRef computedStyleIncludingVisitedInfo(JSValueRef element); JSRetainPtr<JSStringRef> counterValueForElementById(JSStringRef elementId); - JSRetainPtr<JSStringRef> markerTextForListItem(JSValueRef element); + void clearBackForwardList(); void execCommand(JSStringRef name, JSStringRef argument); bool isCommandEnabled(JSStringRef name); + JSRetainPtr<JSStringRef> markerTextForListItem(JSValueRef element); + unsigned windowCount(); // Repaint testing. void testRepaint() { m_testRepaint = true; } @@ -90,6 +92,9 @@ public: unsigned numberOfActiveAnimations() const; bool pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId); + // Compositing testing. + JSRetainPtr<JSStringRef> layerTreeAsText() const; + // UserContent testing. void addUserScript(JSStringRef source, bool runAtStart, bool allFrames); void addUserStyleSheet(JSStringRef source, bool allFrames); @@ -98,9 +103,9 @@ public: WhatToDump whatToDump() const { return m_whatToDump; } bool shouldDumpAllFrameScrollPositions() const { return m_shouldDumpAllFrameScrollPositions; } + bool shouldDumpBackForwardListsForAllWindows() const { return m_shouldDumpBackForwardListsForAllWindows; } bool shouldDumpEditingCallbacks() const { return m_dumpEditingCallbacks; } bool shouldDumpMainFrameScrollPosition() const { return m_whatToDump == RenderTree; } - bool shouldDumpStatusCallbacks() const { return m_dumpStatusCallbacks; } bool shouldDumpTitleChanges() const { return m_dumpTitleChanges; } @@ -122,6 +127,7 @@ private: WhatToDump m_whatToDump; bool m_shouldDumpAllFrameScrollPositions; + bool m_shouldDumpBackForwardListsForAllWindows; bool m_shouldAllowEditing; bool m_shouldCloseExtraWindows; diff --git a/WebKitTools/WebKitTestRunner/TestController.cpp b/WebKitTools/WebKitTestRunner/TestController.cpp index aff8798..c88062a 100644 --- a/WebKitTools/WebKitTestRunner/TestController.cpp +++ b/WebKitTools/WebKitTestRunner/TestController.cpp @@ -98,7 +98,7 @@ static void closeOtherPage(WKPageRef page, const void* clientInfo) delete view; } -static WKPageRef createOtherPage(WKPageRef oldPage, const void*) +static WKPageRef createOtherPage(WKPageRef oldPage, WKDictionaryRef, WKEventModifiers, WKEventMouseButton, const void*) { PlatformWebView* view = new PlatformWebView(WKPageGetPageNamespace(oldPage)); WKPageRef newPage = view->page(); @@ -116,12 +116,20 @@ static WKPageRef createOtherPage(WKPageRef oldPage, const void*) 0, // runJavaScriptPrompt 0, // setStatusText 0, // mouseDidMoveOverElement - 0, // contentsSizeChanged 0, // didNotHandleKeyEvent + 0, // toolbarsAreVisible + 0, // setToolbarsAreVisible + 0, // menuBarIsVisible + 0, // setMenuBarIsVisible + 0, // statusBarIsVisible + 0, // setStatusBarIsVisible + 0, // isResizable + 0, // setIsResizable getWindowFrameOtherPage, setWindowFrameOtherPage, 0, // runBeforeUnloadConfirmPanel - 0 // didDraw + 0, // didDraw + 0 // pageDidScroll }; WKPageSetPageUIClient(newPage, &otherPageUIClient); @@ -181,7 +189,7 @@ void TestController::initialize(int argc, const char* argv[]) 0, this, didReceiveMessageFromInjectedBundle, - 0 + didReceiveSynchronousMessageFromInjectedBundle }; WKContextSetInjectedBundleClient(m_context.get(), &injectedBundleClient); @@ -201,12 +209,20 @@ void TestController::initialize(int argc, const char* argv[]) 0, // runJavaScriptPrompt 0, // setStatusText 0, // mouseDidMoveOverElement - 0, // contentsSizeChanged 0, // didNotHandleKeyEvent + 0, // toolbarsAreVisible + 0, // setToolbarsAreVisible + 0, // menuBarIsVisible + 0, // setMenuBarIsVisible + 0, // statusBarIsVisible + 0, // setStatusBarIsVisible + 0, // isResizable + 0, // setIsResizable getWindowFrameMainPage, setWindowFrameMainPage, 0, // runBeforeUnloadConfirmPanel - 0 // didDraw + 0, // didDraw + 0 // pageDidScroll }; WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient); @@ -224,6 +240,8 @@ void TestController::initialize(int argc, const char* argv[]) 0, // didFirstLayoutForFrame 0, // didFirstVisuallyNonEmptyLayoutForFrame 0, // didRemoveFrameFromHierarchy + 0, // didDisplayInsecureContentForFrame + 0, // didRunInsecureContentForFrame 0, // didStartProgress 0, // didChangeProgress 0, // didFinishProgress @@ -312,11 +330,21 @@ void TestController::didReceiveMessageFromInjectedBundle(WKContextRef context, W static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveMessageFromInjectedBundle(messageName, messageBody); } +void TestController::didReceiveSynchronousMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void* clientInfo) +{ + *returnData = static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody).leakRef(); +} + void TestController::didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody) { m_currentInvocation->didReceiveMessageFromInjectedBundle(messageName, messageBody); } +WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody) +{ + return m_currentInvocation->didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody); +} + // WKPageLoaderClient void TestController::didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef, const void* clientInfo) diff --git a/WebKitTools/WebKitTestRunner/TestController.h b/WebKitTools/WebKitTestRunner/TestController.h index a9e6ab3..b12f1b2 100644 --- a/WebKitTools/WebKitTestRunner/TestController.h +++ b/WebKitTools/WebKitTestRunner/TestController.h @@ -71,8 +71,10 @@ private: void resetStateToConsistentValues(); // WKContextInjectedBundleClient - static void didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void*); + static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*); + static void didReceiveSynchronousMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void*); void didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody); + WKRetainPtr<WKTypeRef> didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody); // WKPageLoaderClient static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void*); diff --git a/WebKitTools/WebKitTestRunner/TestInvocation.cpp b/WebKitTools/WebKitTestRunner/TestInvocation.cpp index c1bf894..04a56f1 100644 --- a/WebKitTools/WebKitTestRunner/TestInvocation.cpp +++ b/WebKitTools/WebKitTestRunner/TestInvocation.cpp @@ -182,4 +182,10 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName ASSERT_NOT_REACHED(); } +WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedBundle(WKStringRef /*messageName*/, WKTypeRef /*messageBody*/) +{ + ASSERT_NOT_REACHED(); + return 0; +} + } // namespace WTR diff --git a/WebKitTools/WebKitTestRunner/TestInvocation.h b/WebKitTools/WebKitTestRunner/TestInvocation.h index 1b33e49..fec1f7a 100644 --- a/WebKitTools/WebKitTestRunner/TestInvocation.h +++ b/WebKitTools/WebKitTestRunner/TestInvocation.h @@ -38,6 +38,7 @@ public: void invoke(); void didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody); + WKRetainPtr<WKTypeRef> didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody); private: void dump(const char*); diff --git a/WebKitTools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj b/WebKitTools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj index 599e09e..a15fe41 100644 --- a/WebKitTools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj +++ b/WebKitTools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj @@ -95,7 +95,7 @@ BC14E4E8120E03D800826C0C /* JSGCController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSGCController.cpp; path = DerivedSources/WebKitTestRunner/JSGCController.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; BC14E4E9120E03D800826C0C /* JSGCController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSGCController.h; path = DerivedSources/WebKitTestRunner/JSGCController.h; sourceTree = BUILT_PRODUCTS_DIR; }; BC25184611D15767002EBC01 /* InjectedBundleMain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleMain.cpp; sourceTree = "<group>"; }; - BC25186211D15D54002EBC01 /* InjectedBundle.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InjectedBundle.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + BC25186211D15D54002EBC01 /* WebKitTestRunnerInjectedBundle.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WebKitTestRunnerInjectedBundle.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; BC25186311D15D54002EBC01 /* InjectedBundle-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "InjectedBundle-Info.plist"; sourceTree = "<group>"; }; BC25197111D15E61002EBC01 /* InjectedBundle.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = InjectedBundle.xcconfig; sourceTree = "<group>"; }; BC251A1711D16774002EBC01 /* WebKitTestRunnerPrefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitTestRunnerPrefix.h; sourceTree = "<group>"; }; @@ -203,7 +203,7 @@ isa = PBXGroup; children = ( 8DD76FA10486AA7600D96B5E /* WebKitTestRunner */, - BC25186211D15D54002EBC01 /* InjectedBundle.bundle */, + BC25186211D15D54002EBC01 /* WebKitTestRunnerInjectedBundle.bundle */, ); name = Products; sourceTree = "<group>"; @@ -343,9 +343,9 @@ productReference = 8DD76FA10486AA7600D96B5E /* WebKitTestRunner */; productType = "com.apple.product-type.tool"; }; - BC25186111D15D54002EBC01 /* InjectedBundle */ = { + BC25186111D15D54002EBC01 /* WebKitTestRunnerInjectedBundle */ = { isa = PBXNativeTarget; - buildConfigurationList = BC25186611D15D55002EBC01 /* Build configuration list for PBXNativeTarget "InjectedBundle" */; + buildConfigurationList = BC25186611D15D55002EBC01 /* Build configuration list for PBXNativeTarget "WebKitTestRunnerInjectedBundle" */; buildPhases = ( BC25185E11D15D54002EBC01 /* Resources */, BC25185F11D15D54002EBC01 /* Sources */, @@ -356,9 +356,9 @@ dependencies = ( BC952ED711F3C38B003398B4 /* PBXTargetDependency */, ); - name = InjectedBundle; + name = WebKitTestRunnerInjectedBundle; productName = InjectedBundle; - productReference = BC25186211D15D54002EBC01 /* InjectedBundle.bundle */; + productReference = BC25186211D15D54002EBC01 /* WebKitTestRunnerInjectedBundle.bundle */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ @@ -381,7 +381,7 @@ projectRoot = ""; targets = ( 8DD76F960486AA7600D96B5E /* WebKitTestRunner */, - BC25186111D15D54002EBC01 /* InjectedBundle */, + BC25186111D15D54002EBC01 /* WebKitTestRunnerInjectedBundle */, BC952D7711F3BF5D003398B4 /* Derived Sources */, ); }; @@ -462,7 +462,7 @@ /* Begin PBXTargetDependency section */ BC25194211D15D94002EBC01 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BC25186111D15D54002EBC01 /* InjectedBundle */; + target = BC25186111D15D54002EBC01 /* WebKitTestRunnerInjectedBundle */; targetProxy = BC25194111D15D94002EBC01 /* PBXContainerItemProxy */; }; BC952ED711F3C38B003398B4 /* PBXTargetDependency */ = { @@ -558,7 +558,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - BC25186611D15D55002EBC01 /* Build configuration list for PBXNativeTarget "InjectedBundle" */ = { + BC25186611D15D55002EBC01 /* Build configuration list for PBXNativeTarget "WebKitTestRunnerInjectedBundle" */ = { isa = XCConfigurationList; buildConfigurations = ( BC25186411D15D55002EBC01 /* Debug */, diff --git a/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm b/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm index dbe35e2..be9aa33 100644 --- a/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm +++ b/WebKitTools/WebKitTestRunner/mac/TestControllerMac.mm @@ -36,7 +36,7 @@ void TestController::platformInitialize() void TestController::initializeInjectedBundlePath() { - NSString *nsBundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"InjectedBundle.bundle"]; + NSString *nsBundlePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"WebKitTestRunnerInjectedBundle.bundle"]; m_injectedBundlePath.adopt(WKStringCreateWithCFString((CFStringRef)nsBundlePath)); } |