diff options
author | Steve Block <steveblock@google.com> | 2010-05-26 10:11:43 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-05-27 11:14:42 +0100 |
commit | e78cbe89e6f337f2f1fe40315be88f742b547151 (patch) | |
tree | d778000b84a04f24bbad50c7fa66244365e960e9 /WebKitTools | |
parent | 7b582e96e4e909ed7dba1e07153d20fbddaec3f7 (diff) | |
download | external_webkit-e78cbe89e6f337f2f1fe40315be88f742b547151.zip external_webkit-e78cbe89e6f337f2f1fe40315be88f742b547151.tar.gz external_webkit-e78cbe89e6f337f2f1fe40315be88f742b547151.tar.bz2 |
Merge WebKit at r60074: Initial merge by git
Change-Id: I18a2dc5439e36c928351ea829d8fb4e39b062fc7
Diffstat (limited to 'WebKitTools')
102 files changed, 2254 insertions, 297 deletions
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog index 3596d14..f48e031 100644 --- a/WebKitTools/ChangeLog +++ b/WebKitTools/ChangeLog @@ -1,3 +1,668 @@ +2010-05-24 Eric Seidel <eric@webkit.org> + + Reviewed by Chris Jerdonek. + + webkit-patch needs --verbose flag to enable DEBUG logging + https://bugs.webkit.org/show_bug.cgi?id=39208 + + I also added some code to print out how long commands take to run. + + * Scripts/webkit-patch: + - Add hackish -v/--verbose parsing (similar to check-webkit-style) + * Scripts/webkitpy/common/system/executive.py: + - Log how long commands take to run. + * Scripts/webkitpy/tool/main.py: + - Add -v/--verbose option to global options. + +2010-05-23 Eric Seidel <eric@webkit.org> + + Reviewed by Daniel Bates. + + Split PatchReader out into its own file + https://bugs.webkit.org/show_bug.cgi?id=39576 + + This is in preparation for making check-webkit-style + support being passed paths to patch files on the command line. + + * Scripts/check-webkit-style: + * Scripts/webkitpy/style/checker.py: + * Scripts/webkitpy/style/checker_unittest.py: + * Scripts/webkitpy/style/patchreader.py: Added. + * Scripts/webkitpy/style/patchreader_unittest.py: Added. + * Scripts/webkitpy/style_references.py: + +2010-05-23 Adam Barth <abarth@webkit.org> + + Reviewed by Daniel Bates. + + webkit-patch should let you add a comment when uploading a patch + https://bugs.webkit.org/show_bug.cgi?id=39552 + + As requested by Dan "the man" Bates. + + * Scripts/webkitpy/tool/steps/options.py: + * Scripts/webkitpy/tool/steps/postdiff.py: + +2010-05-23 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + webkit-patch should assign newly created bugs to their creator + https://bugs.webkit.org/show_bug.cgi?id=39548 + + As requested on webkit-dev. + + * Scripts/webkitpy/common/net/bugzilla.py: + +2010-05-23 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Hide prepare and post commands for webkit-patch + https://bugs.webkit.org/show_bug.cgi?id=39539 + + It turns out these commands aren't very popular and they confuse new + users. They'll still be there for advanced users, however. + + * Scripts/webkitpy/tool/commands/upload.py: + +2010-05-23 Jesus Sanchez-Palencia <jesus@webkit.org> + + Reviewed by Laszlo Gombos. + + [Qt] QtTestBrowser has two graphicsview options that aren't enabled correctly + https://bugs.webkit.org/show_bug.cgi?id=39491 + + Making toggleResizesToContents and toggleTiledBackingStore checkable when + QtTestBrowser is started on graphics view mode. + + * QtTestBrowser/main.cpp: + (LauncherWindow::createChrome): + +2010-05-23 Jesus Sanchez-Palencia <jesus@webkit.org> + + Reviewed by Laszlo Gombos. + + [Qt] QtTestBrowser is still called QtLauncher in the code + https://bugs.webkit.org/show_bug.cgi?id=39488 + + Finish the name change of QtLauncher to QtTestBrowser. + + * QtTestBrowser/main.cpp: + (LauncherApplication::LauncherApplication): + (LauncherApplication::handleUserOptions): + * QtTestBrowser/mainwindow.cpp: + (MainWindow::MainWindow): + * QtTestBrowser/useragentlist.txt: + +2010-05-23 Marcus Bulach <bulach@chromium.org> + + Reviewed by Kent Tamura. + + [chromium] Adds Geolocation support to DumpRenderTree. + https://bugs.webkit.org/show_bug.cgi?id=39440 + + Existing LayoutTests/fast/dom/Geolocation/* should pass. + + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::LayoutTestController): + (LayoutTestController::setGeolocationPermission): + (LayoutTestController::setMockGeolocationPosition): + (LayoutTestController::setMockGeolocationError): + * DumpRenderTree/chromium/LayoutTestController.h: + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::TestShell): + * DumpRenderTree/chromium/WebViewHost.cpp: + (WebViewHost::geolocationService): + * DumpRenderTree/chromium/WebViewHost.h: + +2010-05-22 Adam Barth <abarth@webkit.org> + + Unreviewed. + + Re-order Yong's email addresses because his gmail account is the one he + uses for bugs.webkit.org. + + * Scripts/webkitpy/common/config/committers.py: + +2010-05-22 Daniel Bates <dbates@rim.com> + + Reviewed by Chris Jerdonek. + + Add infrastructure to parse SVN property changes + https://bugs.webkit.org/show_bug.cgi?id=38885 + + Adds function VCSUtils::parseSvnDiffFooter to parse an SVN footer + that consists of one or more properties. + + Note, the first line of an SVN footer begins with "Property changes on". + + * Scripts/VCSUtils.pm: + - Added function parseSvnDiffFooter. Will use this function + towards resolving Bug #39409 <https://bugs.webkit.org/show_bug.cgi?id=39409>. + - Removed FIXME comment above function parseSvnProperty, since + it is being used by parseSvnDiffFooter. + * Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl: Added. + - Added unit tests. + +2010-05-22 Eric Seidel <eric@webkit.org> + + Unreviewed, fixing test results only. + + Disable compositing tests on the commit-queue as a workaround for bug 38912 + https://bugs.webkit.org/show_bug.cgi?id=39067 + + * Scripts/webkitpy/tool/steps/steps_unittest.py: + - Update test results after my previous change. + +2010-05-22 Eric Seidel <eric@webkit.org> + + Unreviewed. + + Disable compositing tests on the commit-queue as a workaround for bug 38912 + https://bugs.webkit.org/show_bug.cgi?id=39067 + + * Scripts/webkitpy/tool/steps/runtests.py: + - Disable all of compositing, not just compositing/iframes + +2010-05-22 Kent Tamura <tkent@chromium.org> + + Reviewed by Dimitri Glazkov. + + [DRT/Chromium] Link resources and load Ahem font for Windows + https://bugs.webkit.org/show_bug.cgi?id=39473 + + * DumpRenderTree/chromium/DumpRenderTree.cpp: + (main): Call platformInit(). + * DumpRenderTree/chromium/TestShell.h: + Declare platformInit(). It is not related to TestShell class, but the + implementation of paltformInit() is placed at TestShell*.{cpp,mm}. + * DumpRenderTree/chromium/TestShellGtk.cpp: + (platformInit): + * DumpRenderTree/chromium/TestShellMac.mm: + (platformInit): + * DumpRenderTree/chromium/TestShellWin.cpp: + (platformInit): + - Make stdout/stderr binary mode + - Load Ahem font + +2010-05-21 Eric Seidel <eric@webkit.org> + + Unreviewed, EWS build fix only. + + QueueStatusServer returns 500 error when EWS bots post empty queues + https://bugs.webkit.org/show_bug.cgi?id=39523 + + Mac python seems to have some built-in timezone support + however other python installs don't. So we need to ignore + timezones in our parsing. + + Date parsing is tested by existing unit tests. + + * QueueStatusServer/handlers/updateworkitems.py: + - Fix typo causing exception on server. + * Scripts/webkitpy/common/net/bugzilla.py: + - Fix exception due to python's lack of timezone support. + +2010-05-21 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + QueueStatusServer returns 500 error when EWS bots post empty queues + https://bugs.webkit.org/show_bug.cgi?id=39523 + + updateworkitems handler was raising an exception because + int() couldn't convert "" to a number. + + I attempted to unit test this but we don't yet have a system by + which to load unit tests for appengine classes which depend on + google.appengine libraries which are not in the python default install. + + We'll need to write a wrapper script to load those into the python path + and then run the unit test files. + + * QueueStatusServer/handlers/statusbubble.py: + - Hide cr-win-ews since we're not currently running this bot. + * QueueStatusServer/handlers/updateworkitems.py: + - Fix the parsing logic to be able to understand "". + * Scripts/webkitpy/common/net/statusserver.py: + - Only log the work items posted to the server to the debug log channel. + +2010-05-21 Eric Seidel <eric@webkit.org> + + Unreviewed, fixing the commit-queue to run again. + + Make the EWSes report queue position in white bubbles + https://bugs.webkit.org/show_bug.cgi?id=39519 + + * Scripts/webkitpy/common/net/statusserver.py: + - Fix exception in _post_work_items_to_server when passed + integers. Unfortunately we have no good way to mock + the Browser object yet, and after several attempts I was + not able to create a good one, so no tests. :( + +2010-05-14 Ojan Vafai <ojan@chromium.org> + + Reviewed by Eric Seidel. + + webkit-patch land --squash commits too much if branch is not up to date + https://bugs.webkit.org/show_bug.cgi?id=38852 + + * Scripts/webkitpy/common/checkout/scm.py: + * Scripts/webkitpy/common/checkout/scm_unittest.py: + +2010-05-21 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + Make the EWSes report queue position in white bubbles + https://bugs.webkit.org/show_bug.cgi?id=39519 + + This also fixes sorting of commit-queue patches + to be in order of patch attachment. + https://bugs.webkit.org/show_bug.cgi?id=33395 + + This makes the various Queues post what patches they are about to process + so that we can display a list of patches on status server pages, as well + as report queue position in status bubbles. + + This is the first step towards creating a control-channel for the queues. + Next step will be to have them read back the patches in order from the server + and finally we will add the ability for the server to control that order. + + * Scripts/webkitpy/common/net/bugzilla.py: + - Teach bugzilla how to parse attach_date for attachments. + * Scripts/webkitpy/common/net/bugzilla_unittest.py: + - Test that we're parsing dates correctly. + This may have timezone issues for non-PST contributers, unsure. + * Scripts/webkitpy/common/net/statusserver.py: + - Post work items to the status server for display. + * Scripts/webkitpy/tool/bot/patchcollection.py: + - Call StatusServer.update_work_items + * Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py: + - Update unit test results now that we're posting work item list. + * Scripts/webkitpy/tool/commands/queues.py: + - Call StatusSever.update_work_items + - Sort patches so that the server's list understands + that the commit-queue gives priority to rollout patches. + - I also fixed patch sorting per bug 33395 while I was here. + * Scripts/webkitpy/tool/commands/queues_unittest.py: + - Update results after update_work_items changes. + - Test attachment sorting. + * Scripts/webkitpy/tool/mocktool.py: + - Add mock for update_work_items + +2010-05-21 Robin Cao <robin.cao@torchmobile.com.cn> + + Reviewed by Adam Roben. + + fast/dom/HTMLObjectElement/children-changed.html times out on Windows run-webkit-tests + https://bugs.webkit.org/show_bug.cgi?id=31315 + + * DumpRenderTree/win/FrameLoadDelegate.cpp: + (FrameLoadDelegate::didFailProvisionalLoadWithError): Need to invoke locationChangeDone here as mac port does. + +2010-05-20 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Dan Bernstein. + + <rdar://problem/7848154> Remove the dependency on Foundation's private __COCOA_FORMAL_PROTOCOLS_2__ define. + + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + +2010-05-20 Tony Gentilcore <tonyg@chromium.org> + + Reviewed by Daniel Bates. + + Look in /proc/registry64 for the Platform SDK on 64-bit Windows. + https://bugs.webkit.org/show_bug.cgi?id=39296 + + The build-webkit script failed for me on Vista 64. A web search turned + up this blog post with a patch that worked for me: + http://www.nicholaswilson.me.uk/2010/04/hacking-webkit-fail/ + + * Scripts/webkitdirs.pm: + +2010-05-20 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + ThreadedMessageQueue should use with_statement for exception safety + https://bugs.webkit.org/show_bug.cgi?id=39233 + + * Scripts/webkitpy/common/thread/threadedmessagequeue.py: + +2010-05-20 Diego Gonzalez <diegohcg@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QtTestBrowser does not support websites which requires HTTP Authentication via dialogs + https://bugs.webkit.org/show_bug.cgi?id=38456 + + * QtTestBrowser/webpage.cpp: + (WebPage::WebPage): + (WebPage::authenticationRequired): + * QtTestBrowser/webpage.h: + +2010-05-20 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Eric Seidel. + + editingBehavior settings needs to be set back to a reasonable default between tests + https://bugs.webkit.org/show_bug.cgi?id=39433 + + For now, hard code the default setting during reset, so that the serialized + version of the setting stays in sync with expectations. + + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetDefaultsToConsistentValues): Reset editing behavior to the appropriate platform default. + * DumpRenderTree/win/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): Ditto. + +2010-05-20 Brent Fulgham <bfulgham@webkit.org> + + Build fix. No review. + + The WebKitAPITest targets do not use the "_debug" suffix needed + by the WinCairo port. Added Debug_Cairo target to correct this. + + * WebKitAPITest/WebKitAPITest.vcproj: + +2010-05-20 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Ojan Vafai. + + editing/selection/extend-selection-after-double-click.html crashes on the Leopard Intel release bot + https://bugs.webkit.org/show_bug.cgi?id=39431 + + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setEditingBehavior): + Prevent a double-free by not having this variable be in the auto-release pool. + +2010-05-20 Martin Robinson <mrobinson@webkit.org> + + Reviewed by Ojan Vafai. + + Expose the editing behavior setting in DRT to test all editing code paths + https://bugs.webkit.org/show_bug.cgi?id=38603 + + * DumpRenderTree/LayoutTestController.cpp: + (setEditingBehaviorCallback): Added. + (LayoutTestController::staticFunctions): Expose the setEditingBehaviorCallback function. + * DumpRenderTree/LayoutTestController.h: + * DumpRenderTree/chromium/LayoutTestController.cpp: Add callback method for setting editing behavior. + * DumpRenderTree/chromium/LayoutTestController.h: Declaration for this method. + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::setEditingBehavior): Implementation of editing behavior control. + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + (LayoutTestController::setEditingBehavior): Ditto + * DumpRenderTree/qt/LayoutTestControllerQt.cpp: + (LayoutTestController::setEditingBehavior): Added stub implementation of editing behavior control. + * DumpRenderTree/qt/LayoutTestControllerQt.h: + (LayoutTestController::setEditingBehavior): Add slot for controlling editor behavior. + * DumpRenderTree/win/LayoutTestControllerWin.cpp: + (LayoutTestController::setEditingBehavior): Implementation of editing behavior control. + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setEditingBehavior): Added stub implementation of editing behavior control. + +2010-05-20 Kent Tamura <tkent@chromium.org> + + Reviewed by Eric Seidel. + + [DRT/Chromium] Increase the time out value + https://bugs.webkit.org/show_bug.cgi?id=39203 + + Change the time out value of Chromium DRT to 30 seconds, which is + the same as other ports. + If a DRT process exits before new-run-webkit-tests detects time + out, new-run-webkit-tests assumes the DRT process crashed. + + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::layoutTestTimeout): + Change the time out value from 10 seconds to 30 seconds. + +2010-05-20 Chris Evans <cevans@google.com> + + Unreviewed. + + Marking myself as a committer. + + * Scripts/webkitpy/common/config/committers.py: Add cevans@google.com. + +2010-05-20 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbo. + + [Qt] Weekly binary builds on Mac OS X don't work when launched in the Finder + https://bugs.webkit.org/show_bug.cgi?id=37273 + + * QtTestBrowser/QtTestBrowser.pro: Build QtLauncher as bundle in package builds + +2010-05-20 Fumitoshi Ukai <ukai@chromium.org> + + Unreviewed fix for websocket test failures. + + * Scripts/new-run-webkit-websocketserver: + options is named parameter for factory.get(). + +2010-05-20 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Shinichiro Hamaji. + + Chromium: Add --chromium option to new-run-webkit-websocketserver + https://bugs.webkit.org/show_bug.cgi?id=37664 + + Missed to pass options to factory.get() in r59595 + + * Scripts/new-run-webkit-websocketserver: + Pass options to factory.get(). + +2010-05-19 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Roben. + + WinEWS should build Debug instead of Release + https://bugs.webkit.org/show_bug.cgi?id=39242 + + This is a workaround for + https://bugs.webkit.org/show_bug.cgi?id=39197 + Adam Roben and Brian Weinstein believe this may + also make building faster since Debug builds + take less time to link. + + * Scripts/webkitpy/tool/commands/earlywarningsystem.py: + +2010-05-19 Dirk Pranke <dpranke@chromium.org> + + Unreviewed, build fix. + + * DumpRenderTree/chromium/NotificationPresenter.cpp: + (NotificationPresenter::show): + +2010-05-19 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + user.py throws exception when readline module is missing + https://bugs.webkit.org/show_bug.cgi?id=39239 + + * Scripts/webkitpy/common/system/user.py: + - The error handling path requires the "sys" module, + so added an import sys at the top of the file. + +2010-05-18 Kent Tamura <tkent@chromium.org> + + Reviewed by Dimitri Glazkov. + + [DRT/Chromium] Fix a repaint issue and textarea tests + https://bugs.webkit.org/show_bug.cgi?id=39054 + + * DumpRenderTree/chromium/WebViewHost.cpp: + (WebViewHost::canvas): Remove m_paintRect initialization in canvas(). + This line updated m_paintRect unexpectedly during paintRect(). + We don't need to initialize m_paintRect because show() does it. + +2010-05-18 Tony Chang <tony@chromium.org> + + Reviewed by Kent Tamura. + + [chromium] new-run-webkit-tests --use-drt should run on Linux + https://bugs.webkit.org/show_bug.cgi?id=37845 + + * Scripts/webkitpy/layout_tests/port/chromium.py: + * Scripts/webkitpy/layout_tests/port/chromium_linux.py: + * Scripts/webkitpy/layout_tests/port/chromium_mac.py: + * Scripts/webkitpy/layout_tests/port/chromium_unittest.py: + * Scripts/webkitpy/layout_tests/port/chromium_win.py: + +2010-05-18 Kent Tamura <tkent@chromium.org> + + Reviewed by Dimitri Glazkov. + + [DRT/Chromium] Fix some initialization/reset issues + https://bugs.webkit.org/show_bug.cgi?id=39281 + + * DumpRenderTree/chromium/LayoutTestController.cpp: + (LayoutTestController::reset): Reset m_userStyleSheetLocation. + * DumpRenderTree/chromium/LayoutTestController.h: + Remove unused variable, m_workQueueFrozen. + (LayoutTestController::WorkQueue::WorkQueue): Initialize m_frozen. + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::resetTestController): Reset WebSettings too. + +2010-05-18 Dirk Pranke <dpranke@chromium.org> + + Reviewed by Ojan Vafai. + + new-run-webkit-tests: implement '--reset-results' flag to complement + the '--new-baseline' flag. '--new-baseline' will always write the + results into the platform directory; '--reset-results' will update the + existing baseline wherever it happens to be. Both sets of behavior + are useful in different circumstances. + + https://bugs.webkit.org/show_bug.cgi?id=38879 + + * Scripts/webkitpy/layout_tests/data/image/canvas-bg.html: Added. + * Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.checksum: Added. + * Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.png: Added. + * Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.txt: Added. + * Scripts/webkitpy/layout_tests/data/image/canvas-zoom.html: Added. + * Scripts/webkitpy/layout_tests/data/misc/crash-expected.txt: Added. + * Scripts/webkitpy/layout_tests/data/misc/crash.html: Added. + * Scripts/webkitpy/layout_tests/data/misc/missing-expectation.html: Added. + * Scripts/webkitpy/layout_tests/data/misc/passing-expected.txt: Added. + * Scripts/webkitpy/layout_tests/data/misc/passing.html: Added. + * Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.checksum: Added. + * Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.png: Added. + * Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.txt: Added. + * Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt: Added. + * Scripts/webkitpy/layout_tests/data/text/article-element-expected.txt: Added. + * Scripts/webkitpy/layout_tests/data/text/article-element.html: Added. + * Scripts/webkitpy/layout_tests/layout_package/test_expectations_unittest.py: + * Scripts/webkitpy/layout_tests/port/test.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py: + * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py: + * Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py: + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + * Scripts/webkitpy/layout_tests/test_types/image_diff.py: + * Scripts/webkitpy/layout_tests/test_types/test_type_base.py: + * Scripts/webkitpy/layout_tests/test_types/text_diff.py: + * Scripts/webkitpy/layout_tests/port/test.py: + * Scripts/webkitpy/layout_tests/port/dryrun.py: + +2010-05-18 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Roben. + + Add an --html5-parser option to DumpRenderTree to allow testing the new HTML5Lexer + https://bugs.webkit.org/show_bug.cgi?id=39311 + + This flag allows us to run the new HTML5Lexer code. + Right now all documents parse as empty documents, but + now that we're able to run the code we can fix that. + + Once we're able to lex a few basic documents I'll add + an --html5-parser flag to run-webkit-tests so that we test + running all of the layout tests with the HTML5 parser. + + * DumpRenderTree/mac/DumpRenderTree.mm: + (resetDefaultsToConsistentValues): + (initializeGlobalsFromCommandLineOptions): + +2010-05-08 Robert Hogan <robert@roberthogan.net> + + Reviewed by Simon Hausmann. + + [Qt] Fix http/tests/xmlhttprequest/cross-origin-no-authorization.html + and http/tests/xmlhttprequest/cross-origin-authorization.html + + QHttpNetworkRequest adds Authorization and Cookie headers to XHRs + without knowing if this is valid behaviour or not. In order to allow + Qt to decide whether Cookie/Authorization headers should be added + to an XHR QtWebKit needs to use an attribute added to QNetworkRequest. + These new attributes are: QNetworkRequest::CookieLoadControlAttribute, + QNetworkRequest::CookieSaveControlAttribute,and + QNetworkRequest::AuthenticationReuseControlAttribute. + + In order to properly support the tests, Qt's DRT needs to use one + NetworkAccessManager for all pages. This allows it to use cached + credentials where appropriate. + + The tests now pass when run individually but there seems to be a problem with + leaking the results of requests across tests when run with the others in + http/tests. This will be addressed in a separate patch. + + https://bugs.webkit.org/show_bug.cgi?id=32967 + + + * DumpRenderTree/qt/DumpRenderTreeQt.cpp: + (WebCore::WebPage::WebPage): + (WebCore::DumpRenderTree::DumpRenderTree): + * DumpRenderTree/qt/DumpRenderTreeQt.h: + + +2010-05-18 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Eric Seidel. + + run_webkit_tests_unittest fails on SnowLeopard + https://bugs.webkit.org/show_bug.cgi?id=39279 + + * Scripts/webkitpy/layout_tests/port/base.py: + Return copy of os.environ. + * Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py: + Check os.environ was not modified. + +2010-05-18 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Eric Seidel. + + Chromium: new-run-webkit-httpd fails to setup_mount + https://bugs.webkit.org/show_bug.cgi?id=39257 + + * Scripts/webkitpy/common/system/executive.py: + Assert type of args in run_command. + * Scripts/webkitpy/common/system/executive_unittest.py: + Add test_run_command_args_type + * Scripts/webkitpy/layout_tests/port/chromium_win.py: + Executive.run_command takes array for command line. + * Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py: + Test if setup_environ_for_server() run setup_mount.bat. + +2010-05-17 Kent Tamura <tkent@chromium.org> + + Reviewed by David Levin. + + Chromium Windows build system does not rebuild correctly when + enabling/disabling a feature + https://bugs.webkit.org/show_bug.cgi?id=38926 + + Add a workaround of this issue. + + * Scripts/update-webkit: + Chromium-Windows only: If WebKit/chromium/features.gyp has been + updated, remove WebKit/chromium/Debug and WebKit/chromium/Release. + 2010-05-17 Sheriff Bot <webkit.review.bot@gmail.com> Unreviewed, rolling out r59631. diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/LayoutTestController.cpp index f564afa..b96a9c9 100644 --- a/WebKitTools/DumpRenderTree/LayoutTestController.cpp +++ b/WebKitTools/DumpRenderTree/LayoutTestController.cpp @@ -31,6 +31,7 @@ #include "WorkQueue.h" #include "WorkQueueItem.h" +#include <cstring> #include <JavaScriptCore/JSContextRef.h> #include <JavaScriptCore/JSObjectRef.h> #include <JavaScriptCore/JSRetainPtr.h> @@ -1453,6 +1454,33 @@ static JSValueRef authenticateSessionCallback(JSContextRef context, JSObjectRef, return JSValueMakeUndefined(context); } +static JSValueRef setEditingBehaviorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // The editing behavior string. + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> editingBehavior(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + + size_t maxLength = JSStringGetMaximumUTF8CStringSize(editingBehavior.get()); + char* behaviorBuffer = new char[maxLength + 1]; + JSStringGetUTF8CString(editingBehavior.get(), behaviorBuffer, maxLength); + + if (strcmp(behaviorBuffer, "mac") && strcmp(behaviorBuffer, "win")) { + JSRetainPtr<JSStringRef> invalidArgument(JSStringCreateWithUTF8CString("Passed invalid editing behavior. Must be 'mac' or 'win'.")); + *exception = JSValueMakeString(context, invalidArgument.get()); + return JSValueMakeUndefined(context); + } + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setEditingBehavior(behaviorBuffer); + + delete [] behaviorBuffer; + + return JSValueMakeUndefined(context); +} + // Static Values static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) @@ -1602,6 +1630,7 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setDomainRelaxationForbiddenForURLScheme", setDomainRelaxationForbiddenForURLSchemeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setEditingBehavior", setEditingBehaviorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setFrameFlatteningEnabled", setFrameFlatteningEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setGeolocationPermission", setGeolocationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setHandlesAuthenticationChallenges", setHandlesAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.h b/WebKitTools/DumpRenderTree/LayoutTestController.h index c6da2ff..8ff38d1 100644 --- a/WebKitTools/DumpRenderTree/LayoutTestController.h +++ b/WebKitTools/DumpRenderTree/LayoutTestController.h @@ -99,6 +99,7 @@ public: void setFrameFlatteningEnabled(bool enable); void setSpatialNavigationEnabled(bool enable); void setScrollbarPolicy(JSStringRef orientation, JSStringRef policy); + void setEditingBehavior(const char* editingBehavior); void waitForPolicyDelegate(); size_t webHistoryItemCount(); diff --git a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp index a964518..8f292ed 100644 --- a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp @@ -36,6 +36,8 @@ using namespace std; +void platformInit(); + static const char optionComplexText[] = "--complex-text"; static const char optionDumpAllPixels[] = "--dump-all-pixels"; static const char optionNotree[] = "--notree"; @@ -59,6 +61,7 @@ static void runTest(TestShell& shell, TestParams& params, const string& testName int main(int argc, char* argv[]) { webkit_support::SetUpTestEnvironment(); + platformInit(); TestParams params; Vector<string> tests; diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp index 4413ff2..b4e3764 100644 --- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp +++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp @@ -39,6 +39,7 @@ #include "public/WebConsoleMessage.h" #include "public/WebDocument.h" #include "public/WebFrame.h" +#include "public/WebGeolocationServiceMock.h" #include "public/WebInputElement.h" #include "public/WebKit.h" #include "public/WebNotificationPresenter.h" @@ -159,6 +160,11 @@ LayoutTestController::LayoutTestController(TestShell* shell) bindMethod("setTimelineProfilingEnabled", &LayoutTestController::setTimelineProfilingEnabled); bindMethod("evaluateInWebInspector", &LayoutTestController::evaluateInWebInspector); bindMethod("forceRedSelectionColors", &LayoutTestController::forceRedSelectionColors); + bindMethod("setEditingBehavior", &LayoutTestController::setEditingBehavior); + + bindMethod("setGeolocationPermission", &LayoutTestController::setGeolocationPermission); + bindMethod("setMockGeolocationPosition", &LayoutTestController::setMockGeolocationPosition); + bindMethod("setMockGeolocationError", &LayoutTestController::setMockGeolocationError); // The fallback method is called when an unknown method is invoked. bindFallbackMethod(&LayoutTestController::fallbackMethod); @@ -477,6 +483,7 @@ void LayoutTestController::reset() m_stopProvisionalFrameLoads = false; m_globalFlag.set(false); m_webHistoryItemCount.set(0); + m_userStyleSheetLocation = WebURL(); webkit_support::SetAcceptAllCookies(false); WebSecurityPolicy::resetOriginAccessWhitelists(); @@ -852,7 +859,7 @@ void LayoutTestController::grantDesktopNotificationPermission(const CppArgumentL result->set(false); return; } - m_shell->notificationPresenter()->grantPermission(WebString::fromUTF8(arguments[0].toString())); + m_shell->notificationPresenter()->grantPermission(cppVariantToWebString(arguments[0])); result->set(true); } @@ -955,7 +962,7 @@ void LayoutTestController::setXSSAuditorEnabled(const CppArgumentList& arguments void LayoutTestController::evaluateScriptInIsolatedWorld(const CppArgumentList& arguments, CppVariant* result) { if (arguments.size() >= 2 && arguments[0].isNumber() && arguments[1].isString()) { - WebScriptSource source(WebString::fromUTF8(arguments[1].toString())); + WebScriptSource source(cppVariantToWebString(arguments[1])); // This relies on the iframe focusing itself when it loads. This is a bit // sketchy, but it seems to be what other tests do. m_shell->webView()->focusedFrame()->executeScriptInIsolatedWorld(arguments[0].toInt32(), &source, 1, 1); @@ -1110,8 +1117,8 @@ void LayoutTestController::addOriginAccessWhitelistEntry(const CppArgumentList& WebSecurityPolicy::addOriginAccessWhitelistEntry( url, - WebString::fromUTF8(arguments[1].toString()), - WebString::fromUTF8(arguments[2].toString()), + cppVariantToWebString(arguments[1]), + cppVariantToWebString(arguments[2]), arguments[3].toBoolean()); } @@ -1129,8 +1136,8 @@ void LayoutTestController::removeOriginAccessWhitelistEntry(const CppArgumentLis WebSecurityPolicy::removeOriginAccessWhitelistEntry( url, - WebString::fromUTF8(arguments[1].toString()), - WebString::fromUTF8(arguments[2].toString()), + cppVariantToWebString(arguments[1]), + cppVariantToWebString(arguments[2]), arguments[3].toBoolean()); } @@ -1261,7 +1268,7 @@ void LayoutTestController::addUserScript(const CppArgumentList& arguments, CppVa result->setNull(); if (arguments.size() < 2 || !arguments[0].isString() || !arguments[1].isBool()) return; - m_shell->webView()->addUserScript(WebString::fromUTF8(arguments[0].toString()), arguments[1].toBoolean()); + m_shell->webView()->addUserScript(cppVariantToWebString(arguments[0]), arguments[1].toBoolean()); } void LayoutTestController::addUserStyleSheet(const CppArgumentList& arguments, CppVariant* result) @@ -1269,5 +1276,41 @@ void LayoutTestController::addUserStyleSheet(const CppArgumentList& arguments, C result->setNull(); if (arguments.size() < 1 || !arguments[0].isString()) return; - m_shell->webView()->addUserStyleSheet(WebString::fromUTF8(arguments[0].toString())); + m_shell->webView()->addUserStyleSheet(cppVariantToWebString(arguments[0])); +} + +void LayoutTestController::setEditingBehavior(const CppArgumentList& arguments, CppVariant* results) +{ + WebSettings* settings = m_shell->webView()->settings(); + string key = arguments[0].toString(); + if (key == "mac") + settings->setEditingBehavior(WebSettings::EditingBehaviorMac); + else if (key == "win") + settings->setEditingBehavior(WebSettings::EditingBehaviorWin); + else + logErrorToConsole("Passed invalid editing behavior. Should be 'mac' or 'win'."); +} + +void LayoutTestController::setGeolocationPermission(const CppArgumentList& arguments, CppVariant* result) +{ + result->setNull(); + if (arguments.size() < 1 || !arguments[0].isBool()) + return; + WebGeolocationServiceMock::setMockGeolocationPermission(arguments[0].toBoolean()); +} + +void LayoutTestController::setMockGeolocationPosition(const CppArgumentList& arguments, CppVariant* result) +{ + result->setNull(); + if (arguments.size() < 3 || !arguments[0].isNumber() || !arguments[1].isNumber() || !arguments[2].isNumber()) + return; + WebGeolocationServiceMock::setMockGeolocationPosition(arguments[0].toDouble(), arguments[1].toDouble(), arguments[2].toDouble()); +} + +void LayoutTestController::setMockGeolocationError(const CppArgumentList& arguments, CppVariant* result) +{ + result->setNull(); + if (arguments.size() < 2 || !arguments[0].isInt32() || !arguments[1].isString()) + return; + WebGeolocationServiceMock::setMockGeolocationError(arguments[0].toInt32(), cppVariantToWebString(arguments[1])); } diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h index e7a48e2..0e66087 100644 --- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h +++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h @@ -209,6 +209,8 @@ public: // Grants permission for desktop notifications to an origin void grantDesktopNotificationPermission(const CppArgumentList&, CppVariant*); + void setEditingBehavior(const CppArgumentList&, CppVariant*); + // The following are only stubs. TODO(pamg): Implement any of these that // are needed to pass the layout tests. void dumpAsWebArchive(const CppArgumentList&, CppVariant*); @@ -279,6 +281,11 @@ public: void addUserScript(const CppArgumentList&, CppVariant*); void addUserStyleSheet(const CppArgumentList&, CppVariant*); + // Geolocation related functions. + void setGeolocationPermission(const CppArgumentList&, CppVariant*); + void setMockGeolocationPosition(const CppArgumentList&, CppVariant*); + void setMockGeolocationError(const CppArgumentList&, CppVariant*); + public: // The following methods are not exposed to JavaScript. void setWorkQueueFrozen(bool frozen) { m_workQueue.setFrozen(frozen); } @@ -331,7 +338,7 @@ private: // queueScript. class WorkQueue { public: - WorkQueue(LayoutTestController* controller) : m_controller(controller) {} + WorkQueue(LayoutTestController* controller) : m_frozen(false), m_controller(controller) {} virtual ~WorkQueue(); void processWorkSoon(); @@ -441,10 +448,6 @@ private: // If true, don't dump output until notifyDone is called. bool m_waitUntilDone; - // To prevent infinite loops, only the first page of a test can add to a - // work queue (since we may well come back to that same page). - bool m_workQueueFrozen; - WorkQueue m_workQueue; CppVariant m_globalFlag; diff --git a/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp b/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp index 86903be..501b513 100644 --- a/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp +++ b/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp @@ -52,23 +52,11 @@ void NotificationPresenter::grantPermission(const WebString& origin) // The output from all these methods matches what DumpRenderTree produces. bool NotificationPresenter::show(const WebNotification& notification) { - if (!notification.replaceId().isEmpty()) { - String replaceId(notification.replaceId().data(), notification.replaceId().length()); - if (m_replacements.find(replaceId) != m_replacements.end()) - printf("REPLACING NOTIFICATION %s\n", - m_replacements.find(replaceId)->second.utf8().data()); - - WebString identifier = notification.isHTML() ? - notification.url().spec().utf16() : notification.title(); - m_replacements.set(replaceId, String(identifier.data(), identifier.length())); - } - if (notification.isHTML()) { printf("DESKTOP NOTIFICATION: contents at %s\n", notification.url().spec().data()); } else { - printf("DESKTOP NOTIFICATION:%s icon %s, title %s, text %s\n", - notification.dir() == "rtl" ? "(RTL)" : "", + printf("DESKTOP NOTIFICATION: icon %s, title %s, text %s\n", notification.iconURL().isEmpty() ? "" : notification.iconURL().spec().data(), notification.title().isEmpty() ? "" : diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp index 24a895a..29bd596 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp +++ b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp @@ -80,6 +80,7 @@ TestShell::TestShell() , m_testIsPreparing(false) , m_focusedWidget(0) { + WebRuntimeFeatures::enableGeolocation(true); m_accessibilityController.set(new AccessibilityController(this)); m_layoutTestController.set(new LayoutTestController(this)); m_eventSender.set(new EventSender(this)); @@ -211,6 +212,7 @@ void TestShell::resizeWindowForTest(WebViewHost* window, const WebURL& url) void TestShell::resetTestController() { + resetWebSettings(*webView()); m_accessibilityController->reset(); m_layoutTestController->reset(); m_eventSender->reset(); @@ -565,7 +567,11 @@ void TestShell::bindJSObjectsToWindow(WebFrame* frame) int TestShell::layoutTestTimeout() { - return 10 * 1000; + // 30 second is the same as the value in Mac DRT. + // If we use a value smaller than the timeout value of + // (new-)run-webkit-tests, (new-)run-webkit-tests misunderstands that a + // timed-out DRT process was crashed. + return 30 * 1000; } WebViewHost* TestShell::createWebView() diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.h b/WebKitTools/DumpRenderTree/chromium/TestShell.h index 283cbd4..6dd0198 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShell.h +++ b/WebKitTools/DumpRenderTree/chromium/TestShell.h @@ -153,3 +153,5 @@ private: HANDLE m_finishedEvent; #endif }; + +void platformInit(); diff --git a/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp b/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp index d71881a..e31ca0a 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp +++ b/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp @@ -62,3 +62,7 @@ void TestShell::waitTestFinished() alarm(0); signal(SIGALRM, SIG_DFL); } + +void platformInit() +{ +} diff --git a/WebKitTools/DumpRenderTree/chromium/TestShellMac.mm b/WebKitTools/DumpRenderTree/chromium/TestShellMac.mm index ec8dbac..218b6d0 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShellMac.mm +++ b/WebKitTools/DumpRenderTree/chromium/TestShellMac.mm @@ -123,3 +123,7 @@ void TestShell::waitTestFinished() [thread cancel]; [thread release]; } + +void platformInit() +{ +} diff --git a/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp b/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp index 2d806a2..e0e0af1 100644 --- a/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp +++ b/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp @@ -32,7 +32,11 @@ #include "TestShell.h" #include "webkit/support/webkit_support.h" +#include <fcntl.h> +#include <io.h> #include <process.h> +#include <shlwapi.h> +#include <sys/stat.h> // Default timeout in ms for file page loads when in layout test mode. const int kDefaultFileTestTimeoutMillisecs = 10 * 1000; @@ -98,3 +102,47 @@ void TestShell::waitTestFinished() // Wait to join the watchdog thread. (up to 1s, then quit) WaitForSingleObject(threadHandle, 1000); } + +void platformInit() +{ + // Set stdout/stderr binary mode. + _setmode(_fileno(stdout), _O_BINARY); + _setmode(_fileno(stderr), _O_BINARY); + + // Load Ahem font. + // AHEM____.TTF is copied to the directory of DumpRenderTree.exe by WebKit.gyp. + WCHAR path[_MAX_PATH]; + if (!::GetModuleFileName(0, path, _MAX_PATH)) { + fprintf(stderr, "Can't get the module path.\n"); + exit(1); + } + ::PathRemoveFileSpec(path); + wcscat_s(path, _MAX_PATH, L"/AHEM____.TTF"); + struct _stat ahemStat; + if (_wstat(path, &ahemStat) == -1) { + fprintf(stderr, "Can't access: '%S'\n", path); + exit(1); + } + + FILE* fp = _wfopen(path, L"rb"); + if (!fp) { + _wperror(path); + exit(1); + } + size_t size = ahemStat.st_size; + char* fontBuffer = new char[size]; + if (fread(fontBuffer, 1, size, fp) != size) { + fprintf(stderr, "Can't read the font: '%S'\n", path); + fclose(fp); + exit(1); + } + fclose(fp); + DWORD numFonts = 1; + HANDLE fontHandle = ::AddFontMemResourceEx(fontBuffer, size, 0, &numFonts); + delete[] fontBuffer; // OS owns a copy of the buffer. + if (!fontHandle) { + fprintf(stderr, "Failed to register Ahem font: '%S'\n", path); + exit(1); + } + // We don't need to release the font explicitly. +} diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp index 4761b1a..eb44c2a 100644 --- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp +++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp @@ -42,6 +42,7 @@ #include "public/WebDataSource.h" #include "public/WebDragData.h" #include "public/WebFrame.h" +#include "public/WebGeolocationServiceMock.h" #include "public/WebHistoryItem.h" #include "public/WebNode.h" #include "public/WebRange.h" @@ -527,6 +528,13 @@ WebNotificationPresenter* WebViewHost::notificationPresenter() return m_shell->notificationPresenter(); } +WebKit::WebGeolocationService* WebViewHost::geolocationService() +{ + if (!m_geolocationServiceMock.get()) + m_geolocationServiceMock.set(new WebGeolocationServiceMock); + return m_geolocationServiceMock.get(); +} + // WebWidgetClient ----------------------------------------------------------- void WebViewHost::didInvalidateRect(const WebRect& rect) @@ -1321,7 +1329,6 @@ PlatformCanvas* WebViewHost::canvas() return m_canvas.get(); WebSize widgetSize = webWidget()->size(); resetScrollRect(); - m_paintRect = WebRect(0, 0, widgetSize.width, widgetSize.height); m_canvas.set(new PlatformCanvas(widgetSize.width, widgetSize.height, true)); return m_canvas.get(); } diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h index 5227b28..8fb9d04 100644 --- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h +++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h @@ -45,6 +45,7 @@ class LayoutTestController; class TestShell; namespace WebKit { class WebFrame; +class WebGeolocationServiceMock; class WebURL; struct WebRect; struct WebURLError; @@ -125,6 +126,7 @@ class WebViewHost : public WebKit::WebViewClient, public WebKit::WebFrameClient, virtual int historyForwardListCount(); virtual void focusAccessibilityObject(const WebKit::WebAccessibilityObject&); virtual WebKit::WebNotificationPresenter* notificationPresenter(); + virtual WebKit::WebGeolocationService* geolocationService(); // WebKit::WebWidgetClient virtual void didInvalidateRect(const WebKit::WebRect&); @@ -278,6 +280,9 @@ private: WebKit::WebRect m_paintRect; bool m_isPainting; + // Geolocation + OwnPtr<WebKit::WebGeolocationServiceMock> m_geolocationServiceMock; + OwnPtr<TestNavigationController*> m_navigationController; }; diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index 4ffab88..e8b8627 100644 --- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -39,6 +39,7 @@ #include <JavaScriptCore/JSRetainPtr.h> #include <JavaScriptCore/JSStringRef.h> +#include <cstring> #include <iostream> #include <sstream> #include <stdio.h> @@ -693,3 +694,14 @@ JSRetainPtr<JSStringRef> LayoutTestController::markerTextForListItem(JSContextRe void LayoutTestController::authenticateSession(JSStringRef, JSStringRef, JSStringRef) { } + +void LayoutTestController::setEditingBehavior(const char* editingBehavior) +{ + WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); + WebKitWebSettings* settings = webkit_web_view_get_settings(webView); + + if (!strcmp(editingBehavior, "win")) + g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_WINDOWS, NULL); + if (!strcmp(editingBehavior, "mac")) + g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_MAC, NULL); +} diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm index 6572a8e..8fd5298 100644 --- a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm +++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm @@ -135,6 +135,7 @@ static int dumpPixels; static int threaded; static int dumpTree = YES; static int forceComplexText; +static int useHTML5Parser; static BOOL printSeparators; static RetainPtr<CFStringRef> persistentUserStyleSheetLocation; @@ -440,6 +441,7 @@ static void resetDefaultsToConsistentValues() [preferences setDeveloperExtrasEnabled:NO]; [preferences setLoadsImagesAutomatically:YES]; [preferences setFrameFlatteningEnabled:NO]; + [preferences setEditingBehavior:WebKitEditingMacBehavior]; if (persistentUserStyleSheetLocation) { [preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]]; [preferences setUserStyleSheetEnabled:YES]; @@ -451,6 +453,7 @@ static void resetDefaultsToConsistentValues() [preferences setUsesPageCache:NO]; [preferences setAcceleratedCompositingEnabled:YES]; [preferences setWebGLEnabled:NO]; + [preferences setHTML5ParserEnabled:useHTML5Parser]; [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain]; @@ -557,6 +560,7 @@ static void initializeGlobalsFromCommandLineOptions(int argc, const char *argv[] {"tree", no_argument, &dumpTree, YES}, {"threaded", no_argument, &threaded, YES}, {"complex-text", no_argument, &forceComplexText, YES}, + {"html5-parser", no_argument, &useHTML5Parser, YES}, {NULL, 0, NULL, 0} }; diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm index 44aea81..898235b 100644 --- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm +++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm @@ -66,10 +66,6 @@ #import <wtf/HashMap.h> #import <wtf/RetainPtr.h> -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) -#include <Foundation/NSPrivateDecls.h> -#endif - @interface CommandValidationTarget : NSObject <NSValidatedUserInterfaceItem> { SEL _action; @@ -762,7 +758,7 @@ void LayoutTestController::setWebViewEditable(bool editable) #ifndef BUILDING_ON_TIGER static NSString *SynchronousLoaderRunLoopMode = @"DumpRenderTreeSynchronousLoaderRunLoopMode"; -#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) || !defined(__COCOA_FORMAL_PROTOCOLS_2__) +#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) @protocol NSURLConnectionDelegate <NSObject> @end #endif @@ -849,3 +845,13 @@ void LayoutTestController::authenticateSession(JSStringRef url, JSStringRef user [SynchronousLoader makeRequest:request withUsername:(NSString *)usernameCF.get() password:(NSString *)passwordCF.get()]; #endif } + +void LayoutTestController::setEditingBehavior(const char* editingBehavior) +{ + NSString* editingBehaviorNS = [[NSString alloc] initWithUTF8String:editingBehavior]; + if ([editingBehaviorNS isEqualToString:@"mac"]) + [[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingMacBehavior]; + if ([editingBehaviorNS isEqualToString:@"win"]) + [[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingWinBehavior]; + [editingBehaviorNS release]; +} diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp index f9caca6..f119dd0 100644 --- a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp +++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.cpp @@ -156,7 +156,7 @@ WebPage::WebPage(QObject* parent, DumpRenderTree* drt) connect(this, SIGNAL(geometryChangeRequested(const QRect &)), this, SLOT(setViewGeometry(const QRect & ))); - setNetworkAccessManager(new NetworkAccessManager(this)); + setNetworkAccessManager(m_drt->networkAccessManager()); setPluginFactory(new TestPlugin(this)); } @@ -346,6 +346,7 @@ DumpRenderTree::DumpRenderTree() QWebSettings::enablePersistentStorage(m_persistentStoragePath); + m_networkAccessManager = new NetworkAccessManager(this); // create our primary testing page/view. m_mainView = new QWebView(0); m_mainView->resize(QSize(LayoutTestController::maxViewWidth, LayoutTestController::maxViewHeight)); diff --git a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h index e6449b7..ad41e3a 100644 --- a/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h +++ b/WebKitTools/DumpRenderTree/qt/DumpRenderTreeQt.h @@ -61,6 +61,7 @@ class GCController; namespace WebCore { class WebPage; +class NetworkAccessManager; class DumpRenderTree : public QObject { Q_OBJECT @@ -87,6 +88,7 @@ public: EventSender *eventSender() const { return m_eventSender; } TextInputController *textInputController() const { return m_textInputController; } QString persistentStoragePath() const { return m_persistentStoragePath; } + NetworkAccessManager *networkAccessManager() const { return m_networkAccessManager; } QWebPage *createWindow(); int windowCount() const; @@ -95,7 +97,6 @@ public: WebPage *webPage() const { return m_page; } - #if defined(Q_WS_X11) static void initializeFonts(); #endif @@ -136,6 +137,7 @@ private: EventSender *m_eventSender; TextInputController *m_textInputController; GCController* m_gcController; + NetworkAccessManager* m_networkAccessManager; QFile *m_stdin; diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp index 1fadd61..9616835 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp @@ -638,5 +638,10 @@ void LayoutTestController::setIconDatabaseEnabled(bool enable) QWebSettings::setIconDatabasePath(QString()); } +void LayoutTestController::setEditingBehavior(const QString& editingBehavior) +{ + // FIXME: Implement. +} + const unsigned LayoutTestController::maxViewWidth = 800; const unsigned LayoutTestController::maxViewHeight = 600; diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h index 1359a6f..5fb40b6 100644 --- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h +++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h @@ -193,6 +193,8 @@ public slots: // Simulate a request an embedding application could make, populating per-session credential storage. void authenticateSession(const QString& url, const QString& username, const QString& password); + void setEditingBehavior(const QString& editingBehavior); + private slots: void processWork(); diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp index dfa4de0..b22f342 100644 --- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp @@ -787,6 +787,7 @@ static void resetDefaultsToConsistentValues(IWebPreferences* preferences) preferences->setTabsToLinks(FALSE); preferences->setShouldPrintBackgrounds(TRUE); preferences->setLoadsImagesAutomatically(TRUE); + preferences->setEditingBehavior(WebKitEditingWinBehavior); if (persistentUserStyleSheetLocation) { Vector<wchar_t> urlCharacters(CFStringGetLength(persistentUserStyleSheetLocation.get())); diff --git a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp index 9b9e3c1..a84e0f3 100644 --- a/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp +++ b/WebKitTools/DumpRenderTree/win/FrameLoadDelegate.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -146,6 +147,7 @@ HRESULT STDMETHODCALLTYPE FrameLoadDelegate::didFailProvisionalLoadWithError( if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) printf("%s - didFailProvisionalLoadWithError\n", descriptionSuitableForTestResult(frame).c_str()); + locationChangeDone(error, frame); return S_OK; } diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp index 112b355..c70b517 100644 --- a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp +++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp @@ -1267,3 +1267,20 @@ void LayoutTestController::setWebViewEditable(bool) void LayoutTestController::authenticateSession(JSStringRef, JSStringRef, JSStringRef) { } + +void LayoutTestController::setEditingBehavior(const char* editingBehavior) +{ + COMPtr<IWebView> webView; + if (FAILED(frame->webView(&webView))) + return; + + COMPtr<IWebPreferences> preferences; + if (FAILED(webView->preferences(&preferences))) + return; + + string behaviorString(editingBehavior); + if (behaviorString == "mac") + preferences->setEditingBehavior(WebKitEditingMacBehavior); + if (behaviorString == "win") + preferences->setEditingBehavior(WebKitEditingWinBehavior); +} diff --git a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp index bc157be..d34e40a 100644 --- a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp +++ b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp @@ -446,3 +446,8 @@ JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef, void LayoutTestController::authenticateSession(JSStringRef, JSStringRef, JSStringRef) { } + +void LayoutTestController::setEditingBehavior(JSStringRef editingBehavior) +{ + // FIXME: Implement +} diff --git a/WebKitTools/QtTestBrowser/QtTestBrowser.pro b/WebKitTools/QtTestBrowser/QtTestBrowser.pro index 4c4d83f..fa16c82 100644 --- a/WebKitTools/QtTestBrowser/QtTestBrowser.pro +++ b/WebKitTools/QtTestBrowser/QtTestBrowser.pro @@ -20,13 +20,13 @@ HEADERS += \ webview.h \ fpstimer.h \ -CONFIG -= app_bundle CONFIG += uitools isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../.. include(../../WebKit.pri) DESTDIR = $$OUTPUT_DIR/bin +!CONFIG(standalone_package): CONFIG -= app_bundle QT += network macx:QT+=xml diff --git a/WebKitTools/QtTestBrowser/main.cpp b/WebKitTools/QtTestBrowser/main.cpp index 49c08d9..ca3bf7a 100644 --- a/WebKitTools/QtTestBrowser/main.cpp +++ b/WebKitTools/QtTestBrowser/main.cpp @@ -883,13 +883,13 @@ void LauncherWindow::createChrome() QAction* toggleResizesToContents = graphicsViewMenu->addAction("Toggle Resizes To Contents Mode", this, SLOT(toggleResizesToContents(bool))); toggleResizesToContents->setCheckable(true); toggleResizesToContents->setChecked(false); - toggleResizesToContents->setEnabled(false); + toggleResizesToContents->setEnabled(isGraphicsBased()); toggleResizesToContents->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool))); QAction* toggleTiledBackingStore = graphicsViewMenu->addAction("Toggle Tiled Backing Store", this, SLOT(toggleTiledBackingStore(bool))); toggleTiledBackingStore->setCheckable(true); toggleTiledBackingStore->setChecked(false); - toggleTiledBackingStore->setEnabled(false); + toggleTiledBackingStore->setEnabled(isGraphicsBased()); toggleTiledBackingStore->connect(toggleGraphicsView, SIGNAL(toggled(bool)), SLOT(setEnabled(bool))); QAction* spatialNavigationAction = toolsMenu->addAction("Toggle Spatial Navigation", this, SLOT(toggleSpatialNavigation(bool))); @@ -1063,7 +1063,7 @@ LauncherApplication::LauncherApplication(int& argc, char** argv) { // To allow QWebInspector's configuration persistence setOrganizationName("Nokia"); - setApplicationName("QtLauncher"); + setApplicationName("QtTestBrowser"); setApplicationVersion("0.1"); applyDefaultSettings(); @@ -1082,7 +1082,7 @@ void LauncherApplication::handleUserOptions() { QStringList args = arguments(); QFileInfo program(args.at(0)); - QString programName("QtLauncher"); + QString programName("QtTestBrowser"); if (program.exists()) programName = program.baseName(); diff --git a/WebKitTools/QtTestBrowser/mainwindow.cpp b/WebKitTools/QtTestBrowser/mainwindow.cpp index aa6aa26..941ef79 100644 --- a/WebKitTools/QtTestBrowser/mainwindow.cpp +++ b/WebKitTools/QtTestBrowser/mainwindow.cpp @@ -39,7 +39,7 @@ MainWindow::MainWindow(const QString& url) : m_page(new WebPage(this)) { setAttribute(Qt::WA_DeleteOnClose); - if (qgetenv("QTLAUNCHER_USE_ARGB_VISUALS").toInt() == 1) + if (qgetenv("QTTESTBROWSER_USE_ARGB_VISUALS").toInt() == 1) setAttribute(Qt::WA_TranslucentBackground); buildUI(); diff --git a/WebKitTools/QtTestBrowser/useragentlist.txt b/WebKitTools/QtTestBrowser/useragentlist.txt index ca53693..b4b00f6 100644 --- a/WebKitTools/QtTestBrowser/useragentlist.txt +++ b/WebKitTools/QtTestBrowser/useragentlist.txt @@ -1,5 +1,5 @@ -Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/533.3 (KHTML, like Gecko) QtLauncher/0.1 Safari/533.3 -Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0; en-GB) AppleWebKit/533.3 (KHTML, like Gecko) QtLauncher/0.1 Mobile Safari/533.3 +Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/533.3 (KHTML, like Gecko) QtTestBrowser/0.1 Safari/533.3 +Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0; en-GB) AppleWebKit/533.3 (KHTML, like Gecko) QtTestBrowser/0.1 Mobile Safari/533.3 Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/125.2 (KHTML, like Gecko) Safari/125.8 Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2 Mozilla/5.0 (iPhone; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10 diff --git a/WebKitTools/QtTestBrowser/webpage.cpp b/WebKitTools/QtTestBrowser/webpage.cpp index 624a66f..2a3aae6 100644 --- a/WebKitTools/QtTestBrowser/webpage.cpp +++ b/WebKitTools/QtTestBrowser/webpage.cpp @@ -32,8 +32,10 @@ #include "webpage.h" +#include <QAuthenticator> #include <QDesktopServices> #include <QtGui> +#include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkProxy> @@ -43,6 +45,9 @@ WebPage::WebPage(QObject* parent) , m_interruptingJavaScriptEnabled(false) { applyProxy(); + + connect(networkAccessManager(), SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), + this, SLOT(authenticationRequired(QNetworkReply*, QAuthenticator*))); } void WebPage::applyProxy() @@ -118,3 +123,42 @@ bool WebPage::shouldInterruptJavaScript() return false; return QWebPage::shouldInterruptJavaScript(); } + +void WebPage::authenticationRequired(QNetworkReply* reply, QAuthenticator* authenticator) +{ + QDialog* dialog = new QDialog(QApplication::activeWindow()); + dialog->setWindowTitle("HTTP Authentication"); + + QGridLayout* layout = new QGridLayout(dialog); + dialog->setLayout(layout); + + QLabel* messageLabel = new QLabel(dialog); + messageLabel->setWordWrap(true); + QString messageStr = QString("Enter with username and password for: %1"); + messageLabel->setText(messageStr.arg(reply->url().toString())); + layout->addWidget(messageLabel, 0, 1); + + QLabel* userLabel = new QLabel("Username:", dialog); + layout->addWidget(userLabel, 1, 0); + QLineEdit* userInput = new QLineEdit(dialog); + layout->addWidget(userInput, 1, 1); + + QLabel* passLabel = new QLabel("Password:", dialog); + layout->addWidget(passLabel, 2, 0); + QLineEdit* passInput = new QLineEdit(dialog); + passInput->setEchoMode(QLineEdit::Password); + layout->addWidget(passInput, 2, 1); + + QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok + | QDialogButtonBox::Cancel, Qt::Horizontal, dialog); + connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); + layout->addWidget(buttonBox, 3, 1); + + if (dialog->exec() == QDialog::Accepted) { + authenticator->setUser(userInput->text()); + authenticator->setPassword(passInput->text()); + } + + delete dialog; +} diff --git a/WebKitTools/QtTestBrowser/webpage.h b/WebKitTools/QtTestBrowser/webpage.h index 061deb5..03cde43 100644 --- a/WebKitTools/QtTestBrowser/webpage.h +++ b/WebKitTools/QtTestBrowser/webpage.h @@ -56,6 +56,7 @@ public slots: void openUrlInDefaultBrowser(const QUrl& url = QUrl()); void setUserAgent(const QString& ua) { m_userAgent = ua; } bool shouldInterruptJavaScript(); + void authenticationRequired(QNetworkReply*, QAuthenticator*); private: void applyProxy(); diff --git a/WebKitTools/QueueStatusServer/handlers/statusbubble.py b/WebKitTools/QueueStatusServer/handlers/statusbubble.py index 0e2b8de..bfbe958 100644 --- a/WebKitTools/QueueStatusServer/handlers/statusbubble.py +++ b/WebKitTools/QueueStatusServer/handlers/statusbubble.py @@ -42,7 +42,6 @@ class StatusBubble(webapp.RequestHandler): _queues_to_display = [ ["style", "style-queue"], ["cr-linux", "chromium-ews"], - ["cr-win", "cr-win-ews"], ["gtk", "gtk-ews"], ["qt", "qt-ews"], ["mac", "mac-ews"], diff --git a/WebKitTools/QueueStatusServer/handlers/updateworkitems.py b/WebKitTools/QueueStatusServer/handlers/updateworkitems.py index b58e743..f91beb4 100644 --- a/WebKitTools/QueueStatusServer/handlers/updateworkitems.py +++ b/WebKitTools/QueueStatusServer/handlers/updateworkitems.py @@ -42,23 +42,32 @@ class UpdateWorkItems(UpdateBase): def _work_items_for_queue(self, queue_name): if queue_name not in queues: - self.response.set_status(500) - return + self.response.out.write("\"%s\" is not in queues %s" % (queue_name, queues)) + return None work_items = WorkItems.all().filter("queue_name =", queue_name).get() if not work_items: work_items = WorkItems() work_items.queue_name = queue_name return work_items + def _parse_work_items_string(self, items_string): + # Our parsing could be much more robust. + item_strings = items_string.split(" ") if items_string else [] + return map(int, item_strings) + def _work_items_from_request(self): queue_name = self.request.get("queue_name") work_items = self._work_items_for_queue(queue_name) + if not work_items: + return None items_string = self.request.get("work_items") - # Our parsing could be much more robust. - work_items.item_ids = map(int, items_string.split(" ")) + work_items.item_ids = self._parse_work_items_string(items_string) work_items.date = datetime.now() return work_items def post(self): work_items = self._work_items_from_request() + if not work_items: + self.response.set_status(500) + return work_items.put() diff --git a/WebKitTools/Scripts/VCSUtils.pm b/WebKitTools/Scripts/VCSUtils.pm index 41bbf40..24911ab 100644 --- a/WebKitTools/Scripts/VCSUtils.pm +++ b/WebKitTools/Scripts/VCSUtils.pm @@ -838,6 +838,81 @@ sub parseDiff($$) return (\@diffHashRefs, $line); } +# Parse an SVN property change diff from the given file handle, and advance +# the handle so the last line read is the first line after this diff. +# +# For the case of an SVN binary diff, the binary contents will follow the +# the property changes. +# +# This subroutine dies if the first line does not begin with "Property changes on" +# or if the separator line that follows this line is missing. +# +# Args: +# $fileHandle: advanced so the last line read from the handle is the first +# line of the footer to parse. This line begins with +# "Property changes on". +# $line: the line last read from $fileHandle. +# +# Returns ($propertyHashRef, $lastReadLine): +# $propertyHashRef: a hash reference representing an SVN diff footer. +# propertyPath: the path of the target file. +# executableBitDelta: the value 1 or -1 if the executable bit was added or +# removed from the target file, respectively. +# $lastReadLine: the line last read from $fileHandle. +# +# FIXME: This method is unused as of (05/22/2010). We will call this function +# as part of parsing a diff. See <https://bugs.webkit.org/show_bug.cgi?id=39409>. +sub parseSvnDiffProperties($$) +{ + my ($fileHandle, $line) = @_; + + $_ = $line; + + my $svnFooterDiffStartRegEx = qr#Property changes on: ([^\r\n]+)#; # $1 is normally the same as the index path. + + my %footer; + if (/$svnFooterDiffStartRegEx/) { + $footer{propertyPath} = $1; + } else { + die("Failed to find start of SVN property change, \"Property changes on \": \"$_\""); + } + + # We advance $fileHandle two lines so that the next line that + # we process is $svnPropertyStartRegEx in a well-formed footer. + # A well-formed footer has the form: + # Property changes on: FileA + # ___________________________________________________________________ + # Added: svn:executable + # + * + $_ = <$fileHandle>; # Not defined if end-of-file reached. + my $separator = "_" x 67; + if (defined($_) && /^$separator[\r\n]+$/) { + $_ = <$fileHandle>; + } else { + die("Failed to find separator line: \"$_\"."); + } + + # FIXME: We should expand this to support other SVN properties + # (e.g. return a hash of property key-values that represents + # all properties). + # + # Notice, we keep processing until we hit end-of-file or some + # line that does not resemble $svnPropertyStartRegEx, such as + # the empty line that precedes the start of the binary contents + # of a patch, or the start of the next diff (e.g. "Index:"). + my $propertyHashRef; + while (defined($_) && /$svnPropertyStartRegEx/) { + ($propertyHashRef, $_) = parseSvnProperty($fileHandle, $_); + if ($propertyHashRef->{name} eq "svn:executable") { + # Notice, for SVN properties, propertyChangeDelta is always non-zero + # because a property can only be added or removed. + $footer{executableBitDelta} = $propertyHashRef->{propertyChangeDelta}; + } + } + + return(\%footer, $_); +} + # Parse the next SVN property from the given file handle, and advance the handle so the last # line read is the first line after the property. # @@ -861,9 +936,6 @@ sub parseDiff($$) # propertyChangeDelta: the value 1 or -1 if the property was added or # removed, respectively. # $lastReadLine: the line last read from $fileHandle. -# -# FIXME: This method is unused as of (05/16/2010). We will call this function -# as part of parsing a SVN footer. See <https://bugs.webkit.org/show_bug.cgi?id=38885>. sub parseSvnProperty($$) { my ($fileHandle, $line) = @_; diff --git a/WebKitTools/Scripts/check-webkit-style b/WebKitTools/Scripts/check-webkit-style index f74c3bd..19d3762 100755 --- a/WebKitTools/Scripts/check-webkit-style +++ b/WebKitTools/Scripts/check-webkit-style @@ -50,7 +50,7 @@ import sys from webkitpy.style_references import detect_checkout import webkitpy.style.checker as checker -from webkitpy.style.checker import PatchReader +from webkitpy.style.patchreader import PatchReader from webkitpy.style.checker import StyleProcessor from webkitpy.style.filereader import TextFileReader from webkitpy.style.main import change_directory diff --git a/WebKitTools/Scripts/new-run-webkit-websocketserver b/WebKitTools/Scripts/new-run-webkit-websocketserver index 4f6deaa..3350582 100644 --- a/WebKitTools/Scripts/new-run-webkit-websocketserver +++ b/WebKitTools/Scripts/new-run-webkit-websocketserver @@ -91,7 +91,7 @@ def main(): if options.pidfile: kwds['pidfile'] = options.pidfile - port_obj = factory.get() + port_obj = factory.get(options=options) pywebsocket = websocket_server.PyWebSocket(port_obj, options.output_dir, **kwds) log_level = logging.WARN diff --git a/WebKitTools/Scripts/update-webkit b/WebKitTools/Scripts/update-webkit index 7602c41..3fc2efd 100755 --- a/WebKitTools/Scripts/update-webkit +++ b/WebKitTools/Scripts/update-webkit @@ -33,6 +33,7 @@ use strict; use FindBin; use lib $FindBin::Bin; use File::Basename; +use File::Path; use File::Spec; use Getopt::Long; use VCSUtils; @@ -67,6 +68,8 @@ __END__ exit 1; } +my $startTime = time(); + my @svnOptions = (); push @svnOptions, '-q' if $quiet; @@ -83,6 +86,13 @@ if (-d "../Internal") { runSvnUpdate() if $isSVN; runGitUpdate() if $isGit; } elsif (isChromium()) { + # Workaround for https://bugs.webkit.org/show_bug.cgi?id=38926 + # We should remove the following "if" block when we find a right fix. + if ((isCygwin() || isWindows()) && (stat("WebKit/chromium/features.gypi"))[9] >= $startTime) { + print "features.gypi has been updated. Cleaning the build directories.\n"; + rmtree(["WebKit/chromium/Debug", "WebKit/chromium/Release"]); + } + system("perl", "WebKitTools/Scripts/update-webkit-chromium") == 0 or die $!; } elsif (isAppleWinWebKit()) { system("perl", "WebKitTools/Scripts/update-webkit-auxiliary-libs") == 0 or die; diff --git a/WebKitTools/Scripts/webkit-patch b/WebKitTools/Scripts/webkit-patch index e0170ed..8300b9f 100755 --- a/WebKitTools/Scripts/webkit-patch +++ b/WebKitTools/Scripts/webkit-patch @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (c) 2009, Google Inc. All rights reserved. +# Copyright (c) 2010 Google Inc. All rights reserved. # Copyright (c) 2009 Apple Inc. All rights reserved. # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) # @@ -31,6 +31,7 @@ # # A tool for automating dealing with bugzilla, posting patches, committing patches, etc. +import logging import os import sys @@ -39,7 +40,14 @@ import webkitpy.python24.versioning as versioning def main(): - configure_logging() + # This is a hack to let us enable DEBUG logging as early as possible. + # Note this can't be ternary as versioning.check_version() + # hasn't run yet and this python might be older than 2.5. + if set(["-v", "--verbose"]).intersection(set(sys.argv)): + logging_level = logging.DEBUG + else: + logging_level = logging.INFO + configure_logging(logging_level=logging_level) versioning.check_version() diff --git a/WebKitTools/Scripts/webkitdirs.pm b/WebKitTools/Scripts/webkitdirs.pm index c512009..ca17757 100644 --- a/WebKitTools/Scripts/webkitdirs.pm +++ b/WebKitTools/Scripts/webkitdirs.pm @@ -1051,12 +1051,16 @@ sub setupCygwinEnv() sub dieIfWindowsPlatformSDKNotInstalled { - my $windowsPlatformSDKRegistryEntry = "/proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/InstalledSDKs/D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1"; + my $registry32Path = "/proc/registry/"; + my $registry64Path = "/proc/registry64/"; + my $windowsPlatformSDKRegistryEntry = "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/InstalledSDKs/D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1"; - return if -e $windowsPlatformSDKRegistryEntry; + # FIXME: It would be better to detect whether we are using 32- or 64-bit Windows + # and only check the appropriate entry. But for now we just blindly check both. + return if (-e $registry32Path . $windowsPlatformSDKRegistryEntry) || (-e $registry64Path . $windowsPlatformSDKRegistryEntry); print "*************************************************************\n"; - print "Cannot find '$windowsPlatformSDKRegistryEntry'.\n"; + print "Cannot find registry entry '$windowsPlatformSDKRegistryEntry'.\n"; print "Please download and install the Microsoft Windows Server 2003 R2\n"; print "Platform SDK from <http://www.microsoft.com/downloads/details.aspx?\n"; print "familyid=0baf2b35-c656-4969-ace8-e4c0c0716adb&displaylang=en>.\n\n"; diff --git a/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl new file mode 100644 index 0000000..e305484 --- /dev/null +++ b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl @@ -0,0 +1,348 @@ +#!/usr/bin/perl -w +# +# Copyright (C) Research in Motion Limited 2010. All Rights Reserved. +# Copyright (C) 2010 Chris Jerdonek (chris.jerdonek@gmail.com) +# +# 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 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. +# +# 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 parseSvnDiffProperties(). + +use strict; +use warnings; + +use Test::More; +use VCSUtils; + +my @testCaseHashRefs = ( +#### +# Simple test cases +## +{ + # New test + diffName => "simple: add svn:executable", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: svn:executable + + * +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => 1, +}, +undef], + expectedNextLine => undef, +}, +{ + # New test + diffName => "simple: delete svn:executable", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Deleted: svn:executable + - * +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => -1, +}, +undef], + expectedNextLine => undef, +}, +{ + # New test + diffName => "simple: delete svn:executable using SVN 1.4 syntax", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Name: svn:executable + - * +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => -1, +}, +undef], + expectedNextLine => undef, +}, +#### +# Property value followed by empty line and start of next diff +## +{ + # New test + diffName => "add svn:executable, followed by empty line and start of next diff", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: svn:executable + + * + +Index: Makefile.shared +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => 1, +}, +"\n"], + expectedNextLine => "Index: Makefile.shared\n", +}, +{ + # New test + diffName => "add svn:executable, followed by empty line and start of next property diff", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: svn:executable + + * + +Property changes on: Makefile.shared +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => 1, +}, +"\n"], + expectedNextLine => "Property changes on: Makefile.shared\n", +}, +#### +# Property value followed by empty line and start of the binary contents +## +{ + # New test + diffName => "add svn:executable, followed by empty line and start of binary contents", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: svn:executable + + * + +Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA== +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => 1, +}, +"\n"], + expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\n", +}, +{ + # New test + diffName => "custom property followed by svn:executable, empty line and start of binary contents", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: documentation + + This is an example sentence. +Added: svn:executable + + * + +Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA== +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => 1, +}, +"\n"], + expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\n", +}, +#### +# Successive properties +## +{ + # New test + diffName => "svn:executable followed by custom property", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: svn:executable + + * +Added: documentation + + This is an example sentence. +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => 1, +}, +undef], + expectedNextLine => undef, +}, +{ + # New test + diffName => "custom property followed by svn:executable", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: documentation + + This is an example sentence. +Added: svn:executable + + * +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => 1, +}, +undef], + expectedNextLine => undef, +}, +#### +# Successive properties followed by empty line and start of next diff +## +{ + # New test + diffName => "custom property followed by svn:executable, empty line and start of next property diff", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: documentation + + This is an example sentence. +Added: svn:executable + + * + +Property changes on: Makefile.shared +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => 1, +}, +"\n"], + expectedNextLine => "Property changes on: Makefile.shared\n", +}, +{ + # New test + diffName => "custom property followed by svn:executable, empty line and start of next index diff", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: documentation + + This is an example sentence. +Added: svn:executable + + * + +Index: Makefile.shared +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => 1, +}, +"\n"], + expectedNextLine => "Index: Makefile.shared\n", +}, +#### +# Custom properties +## +# FIXME: We do not support anything other than the svn:executable property. +# We should add support for handling other properties. +{ + # New test + diffName => "simple: custom property", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Name: documentation + + This is an example sentence. +END + expectedReturn => [ +{ + propertyPath => "FileA", +}, +undef], + expectedNextLine => undef, +}, +{ + # New test + diffName => "custom property followed by custom property", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: copyright + + Copyright (C) Research in Motion Limited 2010. All Rights Reserved. +Added: documentation + + This is an example sentence. +END + expectedReturn => [ +{ + propertyPath => "FileA", +}, +undef], + expectedNextLine => undef, +}, +#### +# Malformed property diffs +## +# We shouldn't encounter such diffs in practice. +{ + # New test + diffName => "svn:executable followed by custom property and svn:executable", + inputText => <<'END', +Property changes on: FileA +___________________________________________________________________ +Added: svn:executable + + * +Added: documentation + + This is an example sentence. +Deleted: svn:executable + - * +END + expectedReturn => [ +{ + propertyPath => "FileA", + executableBitDelta => -1, +}, +undef], + expectedNextLine => undef, +}, +); + +my $testCasesCount = @testCaseHashRefs; +plan(tests => 2 * $testCasesCount); # Total number of assertions. + +foreach my $testCase (@testCaseHashRefs) { + my $testNameStart = "parseSvnDiffProperties(): $testCase->{diffName}: comparing"; + + my $fileHandle; + open($fileHandle, "<", \$testCase->{inputText}); + my $line = <$fileHandle>; + + my @got = VCSUtils::parseSvnDiffProperties($fileHandle, $line); + my $expectedReturn = $testCase->{expectedReturn}; + + is_deeply(\@got, $expectedReturn, "$testNameStart return value."); + + my $gotNextLine = <$fileHandle>; + is($gotNextLine, $testCase->{expectedNextLine}, "$testNameStart next read line."); +} diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py index ac9c42e..e68ccfa 100644 --- a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py +++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py @@ -584,25 +584,32 @@ class Git(SCM): def revert_files(self, file_paths): self.run(['git', 'checkout', 'HEAD'] + file_paths) + def _get_squash_error_message(self, num_local_commits): + working_directory_message = "" if self.working_directory_is_clean() else " and working copy changes" + return ("""There are %s local commits%s. Do one of the following: + 1) Use --squash or --no-squash + 2) git config webkit-patch.squash true/false + """ % (num_local_commits, working_directory_message)) + def should_squash(self, squash): - if squash is not None: - # Squash is specified on the command-line. - return squash - - config_squash = Git.read_git_config('webkit-patch.squash') - if (config_squash and config_squash is not ""): - return config_squash.lower() == "true" - - # Only raise an error if there are actually multiple commits to squash. - num_local_commits = len(self.local_commits()) - if num_local_commits > 1 or num_local_commits > 0 and not self.working_directory_is_clean(): - working_directory_message = "" if self.working_directory_is_clean() else " and working copy changes" - raise ScriptError(message="""There are %s local commits%s. Do one of the following: -1) Use --squash or --no-squash -2) git config webkit-patch.squash true/false -""" % (num_local_commits, working_directory_message)) - - return None + if squash is None: + config_squash = Git.read_git_config('webkit-patch.squash') + if (config_squash and config_squash is not ""): + squash = config_squash.lower() == "true" + else: + # Only raise an error if there are actually multiple commits to squash. + num_local_commits = len(self.local_commits()) + if num_local_commits > 1 or (num_local_commits > 0 and not self.working_directory_is_clean()): + raise ScriptError(message=self._get_squash_error_message(num_local_commits)) + + if squash and self._svn_branch_has_extra_commits(): + raise ScriptError(message="Cannot use --squash when HEAD is not fully merged/rebased to %s. " + "This branch needs to be synced first." % self.svn_branch_name()) + + return squash + + def _svn_branch_has_extra_commits(self): + return len(run_command(['git', 'rev-list', '--max-count=1', self.svn_branch_name(), '^head'])) def commit_with_message(self, message, username=None, git_commit=None, squash=None): # Username is ignored during Git commits. diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py index 5a2c094..b6ae388 100644 --- a/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py +++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py @@ -875,6 +875,12 @@ class GitTest(SCMTest): self.assertTrue(re.search(r'test_file_commit2', svn_log)) self.assertTrue(re.search(r'test_file_commit1', svn_log)) + def test_commit_with_message_not_synced_squash(self): + run_command(['git', 'checkout', '-b', 'my-branch', 'trunk~3']) + self._two_local_commits() + scm = detect_scm_system(self.git_checkout_path) + self.assertRaises(ScriptError, scm.commit_with_message, "another test commit", squash=True) + def test_reverse_diff(self): self._shared_test_reverse_diff() @@ -937,6 +943,12 @@ class GitTest(SCMTest): self.assertTrue(re.search(r'test_file_commit2', patch)) self.assertTrue(re.search(r'test_file_commit1', patch)) + def test_create_patch_not_synced_squash(self): + run_command(['git', 'checkout', '-b', 'my-branch', 'trunk~3']) + self._two_local_commits() + scm = detect_scm_system(self.git_checkout_path) + self.assertRaises(ScriptError, scm.create_patch, squash=True) + def test_create_binary_patch(self): # Create a git binary patch and check the contents. scm = detect_scm_system(self.git_checkout_path) @@ -1016,6 +1028,12 @@ class GitTest(SCMTest): self.assertTrue('test_file_commit2' in files) self.assertTrue('test_file_commit1' in files) + def test_changed_files_not_synced_squash(self): + run_command(['git', 'checkout', '-b', 'my-branch', 'trunk~3']) + self._two_local_commits() + scm = detect_scm_system(self.git_checkout_path) + self.assertRaises(ScriptError, scm.changed_files, squash=True) + def test_changed_files(self): self._shared_test_changed_files() diff --git a/WebKitTools/Scripts/webkitpy/common/config/committers.py b/WebKitTools/Scripts/webkitpy/common/config/committers.py index c33d2a6..02f1aed 100644 --- a/WebKitTools/Scripts/webkitpy/common/config/committers.py +++ b/WebKitTools/Scripts/webkitpy/common/config/committers.py @@ -85,6 +85,7 @@ committers_unable_to_review = [ Committer("Cameron McCormack", "cam@webkit.org", "heycam"), Committer("Carol Szabo", "carol.szabo@nokia.com"), Committer("Chang Shu", "Chang.Shu@nokia.com"), + Committer("Chris Evans", "cevans@google.com"), Committer("Chris Fleizach", "cfleizach@apple.com"), Committer("Chris Marrin", "cmarrin@apple.com", "cmarrin"), Committer("Chris Petersen", "cpetersen@apple.com", "cpetersen"), @@ -163,7 +164,7 @@ committers_unable_to_review = [ Committer("Xiaomei Ji", "xji@chromium.org", "xji"), Committer("Yael Aharon", "yael.aharon@nokia.com"), Committer("Yaar Schnitman", ["yaar@chromium.org", "yaar@google.com"]), - Committer("Yong Li", ["yong.li@torchmobile.com", "yong.li.webkit@gmail.com"], "yong"), + Committer("Yong Li", ["yong.li.webkit@gmail.com", "yong.li@torchmobile.com"], "yong"), Committer("Yongjun Zhang", "yongjun.zhang@nokia.com"), Committer("Yuzo Fujishima", "yuzo@google.com", "yuzo"), Committer("Zoltan Herczeg", "zherczeg@webkit.org", "zherczeg"), diff --git a/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py b/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py index 074a021..26d3652 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py +++ b/WebKitTools/Scripts/webkitpy/common/net/bugzilla.py @@ -104,6 +104,9 @@ class Attachment(object): def name(self): return self._attachment_dictionary.get("name") + def attach_date(self): + return self._attachment_dictionary.get("attach_date") + def review(self): return self._attachment_dictionary.get("review") @@ -430,6 +433,7 @@ class Bugzilla(object): attachment[flag_name] = flag['status'] if flag['status'] == '+': attachment[result_key] = flag['setter'] + # Sadly show_bug.cgi?ctype=xml does not expose the flag modification date. def _string_contents(self, soup): # WebKit's bugzilla instance uses UTF-8. @@ -439,8 +443,23 @@ class Bugzilla(object): # convert from NavigableString to a real unicode() object using unicode(). return unicode(soup.string) - def _parse_attachment_element(self, element, bug_id): + # Example: 2010-01-20 14:31 PST + # FIXME: Some bugzilla dates seem to have seconds in them? + # Python does not support timezones out of the box. + # Assume that bugzilla always uses PST (which is true for bugs.webkit.org) + _bugzilla_date_format = "%Y-%m-%d %H:%M" + + @classmethod + def _parse_date(cls, date_string): + (date, time, time_zone) = date_string.split(" ") + # Ignore the timezone because python doesn't understand timezones out of the box. + date_string = "%s %s" % (date, time) + return datetime.strptime(date_string, cls._bugzilla_date_format) + def _date_contents(self, soup): + return self._parse_date(self._string_contents(soup)) + + def _parse_attachment_element(self, element, bug_id): attachment = {} attachment['bug_id'] = bug_id attachment['is_obsolete'] = (element.has_key('isobsolete') and element['isobsolete'] == "1") @@ -448,6 +467,7 @@ class Bugzilla(object): attachment['id'] = int(element.find('attachid').string) # FIXME: No need to parse out the url here. attachment['url'] = self.attachment_url_for_id(attachment['id']) + attachment["attach_date"] = self._date_contents(element.find("date")) attachment['name'] = self._string_contents(element.find('desc')) attachment['attacher_email'] = self._string_contents(element.find('attacher')) attachment['type'] = self._string_contents(element.find('type')) @@ -564,6 +584,7 @@ class Bugzilla(object): raise Exception(errorMessage) else: self.authenticated = True + self.username = username def _fill_attachment_form(self, description, @@ -657,6 +678,7 @@ class Bugzilla(object): patch_description=None, cc=None, blocked=None, + assignee=None, mark_for_review=False, mark_for_commit_queue=False): self.authenticate() @@ -679,6 +701,10 @@ class Bugzilla(object): self.browser["cc"] = cc if blocked: self.browser["blocked"] = unicode(blocked) + if assignee == None: + assignee = self.username + if assignee: + self.browser["assigned_to"] = assignee self.browser["short_desc"] = bug_title self.browser["comment"] = bug_description diff --git a/WebKitTools/Scripts/webkitpy/common/net/bugzilla_unittest.py b/WebKitTools/Scripts/webkitpy/common/net/bugzilla_unittest.py index 62a0746..ce992e7 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/bugzilla_unittest.py +++ b/WebKitTools/Scripts/webkitpy/common/net/bugzilla_unittest.py @@ -28,6 +28,8 @@ import unittest +import datetime + from webkitpy.common.config.committers import CommitterList, Reviewer, Committer from webkitpy.common.net.bugzilla import Bugzilla, BugzillaQueries, parse_bug_id, CommitterValidator, Bug from webkitpy.common.system.outputcapture import OutputCapture @@ -97,6 +99,7 @@ class BugzillaTest(unittest.TestCase): </attachment> ''' _expected_example_attachment_parsing = { + 'attach_date': datetime.datetime(2009, 07, 29, 10, 23), 'bug_id' : 100, 'is_obsolete' : True, 'is_patch' : True, @@ -204,6 +207,7 @@ ZEZpbmlzaExvYWRXaXRoUmVhc29uOnJlYXNvbl07Cit9CisKIEBlbmQKIAogI2VuZGlmCg== "reporter_email" : "eric@webkit.org", "assigned_to_email" : "webkit-unassigned@lists.webkit.org", "attachments" : [{ + "attach_date": datetime.datetime(2009, 12, 27, 23, 51), 'name': u'Patch', 'url' : "https://bugs.webkit.org/attachment.cgi?id=45548", 'is_obsolete': False, diff --git a/WebKitTools/Scripts/webkitpy/common/net/statusserver.py b/WebKitTools/Scripts/webkitpy/common/net/statusserver.py index d9b52a2..0bd68d1 100644 --- a/WebKitTools/Scripts/webkitpy/common/net/statusserver.py +++ b/WebKitTools/Scripts/webkitpy/common/net/statusserver.py @@ -31,9 +31,13 @@ from webkitpy.common.system.deprecated_logging import log from webkitpy.thirdparty.autoinstalled.mechanize import Browser from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup +import logging import urllib2 +_log = logging.getLogger("webkitpy.common.net.statusserver") + + class StatusServer: default_host = "webkit-commit-queue.appspot.com" @@ -83,6 +87,19 @@ class StatusServer: self.browser["broken_bot"] = broken_bot return self.browser.submit().read() + def _post_work_items_to_server(self, queue_name, work_items): + update_work_items_url = "%s/update-work-items" % self.url + self.browser.open(update_work_items_url) + self.browser.select_form(name="update_work_items") + self.browser["queue_name"] = queue_name + work_items = map(unicode, work_items) # .join expects strings + self.browser["work_items"] = " ".join(work_items) + return self.browser.submit().read() + + def update_work_items(self, queue_name, work_items): + _log.debug("Recording work items: %s for %s" % (work_items, queue_name)) + return NetworkTransaction().run(lambda: self._post_work_items_to_server(queue_name, work_items)) + def update_status(self, queue_name, status, patch=None, results_file=None): log(status) return NetworkTransaction().run(lambda: self._post_status_to_server(queue_name, status, patch, results_file)) diff --git a/WebKitTools/Scripts/webkitpy/common/system/executive.py b/WebKitTools/Scripts/webkitpy/common/system/executive.py index c7a7aec..9c5889b 100644 --- a/WebKitTools/Scripts/webkitpy/common/system/executive.py +++ b/WebKitTools/Scripts/webkitpy/common/system/executive.py @@ -41,6 +41,7 @@ import StringIO import signal import subprocess import sys +import time from webkitpy.common.system.deprecated_logging import tee @@ -255,6 +256,18 @@ class Executive(object): input = input.encode("utf-8") return (subprocess.PIPE, input) + def _command_for_printing(self, args): + """Returns a print-ready string representing command args. + The string should be copy/paste ready for execution in a shell.""" + escaped_args = [] + for arg in args: + if isinstance(arg, unicode): + # Escape any non-ascii characters for easy copy/paste + arg = arg.encode("unicode_escape") + # FIXME: Do we need to fix quotes here? + escaped_args.append(arg) + return " ".join(escaped_args) + # FIXME: run_and_throw_if_fail should be merged into this method. def run_command(self, args, @@ -265,6 +278,8 @@ class Executive(object): return_stderr=True, decode_output=True): """Popen wrapper for convenience and to work around python bugs.""" + assert(isinstance(args, list) or isinstance(args, tuple)) + start_time = time.time() args = map(unicode, args) # Popen will throw an exception if args are non-strings (like int()) stdin, string_to_communicate = self._compute_stdin(input) stderr = subprocess.STDOUT if return_stderr else None @@ -283,6 +298,8 @@ class Executive(object): # http://bugs.python.org/issue1731717 exit_code = process.wait() + _log.debug('"%s" took %.2fs' % (self._command_for_printing(args), time.time() - start_time)) + if return_exit_code: return exit_code diff --git a/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py b/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py index 30468ce..32f8f51 100644 --- a/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py +++ b/WebKitTools/Scripts/webkitpy/common/system/executive_unittest.py @@ -32,7 +32,7 @@ import subprocess import sys import unittest -from webkitpy.common.system.executive import Executive, run_command +from webkitpy.common.system.executive import Executive, run_command, ScriptError class ExecutiveTest(unittest.TestCase): @@ -42,6 +42,13 @@ class ExecutiveTest(unittest.TestCase): run_command(["foo_bar_command_blah"], error_handler=Executive.ignore_error, return_exit_code=True) self.failUnlessRaises(OSError, run_bad_command) + def test_run_command_args_type(self): + executive = Executive() + self.assertRaises(AssertionError, executive.run_command, "echo") + self.assertRaises(AssertionError, executive.run_command, u"echo") + executive.run_command(["echo", "foo"]) + executive.run_command(("echo", "foo")) + def test_run_command_with_unicode(self): """Validate that it is safe to pass unicode() objects to Executive.run* methods, and they will return unicode() diff --git a/WebKitTools/Scripts/webkitpy/common/system/user.py b/WebKitTools/Scripts/webkitpy/common/system/user.py index edce93d..4fa2fa3 100644 --- a/WebKitTools/Scripts/webkitpy/common/system/user.py +++ b/WebKitTools/Scripts/webkitpy/common/system/user.py @@ -30,6 +30,7 @@ import logging import os import shlex import subprocess +import sys import webbrowser diff --git a/WebKitTools/Scripts/webkitpy/common/thread/threadedmessagequeue.py b/WebKitTools/Scripts/webkitpy/common/thread/threadedmessagequeue.py index 6cb6f8c..17b6277 100644 --- a/WebKitTools/Scripts/webkitpy/common/thread/threadedmessagequeue.py +++ b/WebKitTools/Scripts/webkitpy/common/thread/threadedmessagequeue.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 threading @@ -36,20 +38,17 @@ class ThreadedMessageQueue(object): self._lock = threading.Lock() def post(self, message): - self._lock.acquire() - self._messages.append(message) - self._lock.release() + with self._lock: + self._messages.append(message) def stop(self): - self._lock.acquire() - self._is_running = False - self._lock.release() + with self._lock: + self._is_running = False def take_all(self): - self._lock.acquire() - messages = self._messages - is_running = self._is_running - self._messages = [] - self._lock.release() + with self._lock: + messages = self._messages + is_running = self._is_running + self._messages = [] return (messages, is_running) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-bg.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-bg.html new file mode 100644 index 0000000..2022676 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-bg.html @@ -0,0 +1,22 @@ +<html> + <head> + <style> + div { background: -webkit-canvas(squares); width:600px; height:600px; border:2px solid black } + </style> + + <script type="application/x-javascript"> +function draw(w, h) { + var ctx = document.getCSSCanvasContext("2d", "squares", w, h); + + ctx.fillStyle = "rgb(200,0,0)"; + ctx.fillRect (10, 10, 55, 50); + + ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; + ctx.fillRect (30, 30, 55, 50); +} + </script> + </head> + <body onload="draw(300, 300)"> + <div></div> + </body> +</html>
\ No newline at end of file diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.checksum b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.checksum new file mode 100644 index 0000000..7373fe2 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.checksum @@ -0,0 +1 @@ +afa0f2d246120c180005d67d47636b92
\ No newline at end of file diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.png Binary files differnew file mode 100644 index 0000000..44952b4 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.png diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.txt new file mode 100644 index 0000000..288458d --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom-expected.txt @@ -0,0 +1,22 @@ +layer at (0,0) size 800x600 + RenderView at (0,0) size 800x600 +layer at (0,0) size 800x600 + RenderBlock {HTML} at (0,0) size 800x600 + RenderBody {BODY} at (8,8) size 784x584 + RenderBlock {P} at (0,0) size 784x18 + RenderText {#text} at (0,0) size 624x18 + text run at (0,0) width 624: "These should be four green hollow boxes with dimensions 600x300, 100x300, 600x100, 100x100." + RenderBlock (anonymous) at (0,34) size 784x420 + RenderHTMLCanvas {CANVAS} at (0,0) size 606x306 [border: (3px solid #008000)] + RenderText {#text} at (606,292) size 4x18 + text run at (606,292) width 4: " " + RenderText {#text} at (0,0) size 0x0 + RenderHTMLCanvas {CANVAS} at (610,0) size 106x306 [border: (3px solid #008000)] + RenderText {#text} at (0,0) size 0x0 + RenderText {#text} at (0,0) size 0x0 + RenderHTMLCanvas {CANVAS} at (0,310) size 606x106 [border: (3px solid #008000)] + RenderText {#text} at (606,402) size 4x18 + text run at (606,402) width 4: " " + RenderText {#text} at (0,0) size 0x0 + RenderHTMLCanvas {CANVAS} at (610,310) size 106x106 [border: (3px solid #008000)] + RenderText {#text} at (0,0) size 0x0 diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom.html new file mode 100644 index 0000000..4dabce1 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/image/canvas-zoom.html @@ -0,0 +1,15 @@ +<style> + canvas { border: solid green; + zoom: 2; } +</style> +<p> + These should be four green hollow boxes with dimensions 600x300, 100x300, 600x100, 100x100. +</p> +<!-- 300x150 --> +<canvas id="canvas"></canvas> +<!-- 50x150 --> +<canvas id="canvas" width="50"></canvas> +<!-- 300x50 --> +<canvas id="canvas" height="50"></canvas> +<!-- 50x50 --> +<canvas id="canvas" width="50" height="50"></canvas> diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/crash-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/crash-expected.txt new file mode 100644 index 0000000..521c3f5 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/crash-expected.txt @@ -0,0 +1 @@ +This test is expected to crash. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/crash.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/crash.html new file mode 100644 index 0000000..b9820d6 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/crash.html @@ -0,0 +1,5 @@ +<html> +<body> +This test is expected to crash. +</body> +</html> diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/missing-expectation.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/missing-expectation.html new file mode 100644 index 0000000..1f00b50 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/missing-expectation.html @@ -0,0 +1,5 @@ +<html> +<body> +This test intentionally doesn't have an expected result checked in. +</body> +</html> diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/passing-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/passing-expected.txt new file mode 100644 index 0000000..26bd316 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/passing-expected.txt @@ -0,0 +1 @@ +This test is expected to pass. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/passing.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/passing.html new file mode 100644 index 0000000..db7e3de --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/misc/passing.html @@ -0,0 +1,5 @@ +<html> +<body> +This test is expected to pass. +</body> +</html> diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.checksum b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.checksum new file mode 100644 index 0000000..4cd8dac --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.checksum @@ -0,0 +1 @@ +790b681a41697634fcf2a2587afb89c6
\ No newline at end of file diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.png b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.png Binary files differnew file mode 100644 index 0000000..3d00450 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.png diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.txt new file mode 100644 index 0000000..2411c0a --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/image/canvas-bg-expected.txt @@ -0,0 +1,6 @@ +layer at (0,0) size 785x620 + RenderView at (0,0) size 785x600 +layer at (0,0) size 785x620 + RenderBlock {HTML} at (0,0) size 785x620 + RenderBody {BODY} at (8,8) size 769x604 + RenderBlock {DIV} at (0,0) size 604x604 [border: (2px solid #000000)] diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt new file mode 100644 index 0000000..b78a01c --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt @@ -0,0 +1 @@ +WONTFIX : misc/missing-expectation.html = MISSING PASS diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/text/article-element-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/text/article-element-expected.txt new file mode 100644 index 0000000..f60ac38 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/text/article-element-expected.txt @@ -0,0 +1,20 @@ +Various tests for the article element. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +<article> closes <p>: +PASS article1.parentNode.nodeName == "p" is false +<p> does not close <article>: +PASS p1.parentNode.nodeName is "ARTICLE" +<article> can be nested inside <article>: +PASS article3.parentNode.id is "article2" +Residual style: +PASS getWeight("article4") is "bold" +PASS getWeight("span1") is "bold" +FormatBlock: +PASS document.getElementById("span2").parentNode.nodeName is "ARTICLE" +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/text/article-element.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/text/article-element.html new file mode 100644 index 0000000..c0f4547 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/text/article-element.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<html> +<head> +<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css"> +<script src="../../fast/js/resources/js-test-pre.js"></script> +</head> +<body> +<p id="description"></p> +<div id="console"></div> +<script src="script-tests/article-element.js"></script> +<script src="../../fast/js/resources/js-test-post.js"></script> +</body> +</html> 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 6957fcd..09f9ac7 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 @@ -425,7 +425,8 @@ class TestShellThread(threading.Thread): # 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: + if (image_hash and + (self._test_args.new_baseline or self._test_args.reset_results)): image_hash = "" start = time.time() crash, timeout, actual_checksum, output, error = \ 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 dba1194..3804210 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py @@ -239,6 +239,8 @@ class Testprinter(unittest.TestCase): def test_print_test_result(self): result = get_result('foo.html') printer, err, out = self.get_printer(['--print', 'nothing']) + result = get_result(os.path.join(self._port.layout_tests_dir(), + 'foo.html')) printer.print_test_result(result, expected=False, exp_str='', got_str='') self.assertTrue(err.empty()) 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 d11f3e2..cf3c560 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 @@ -98,19 +98,18 @@ class TestExpectationsTest(unittest.TestCase): return os.path.join(self._port.layout_tests_dir(), test_name) def get_basic_tests(self): - return [self.get_test('fast/html/article-element.html'), - self.get_test('fast/html/header-element.html'), - self.get_test('fast/html/keygen.html'), - self.get_test('fast/html/tab-order.html'), - self.get_test('fast/events/space-scroll-event.html'), - self.get_test('fast/events/tab-imagemap.html')] + return [self.get_test('text/article-element.html'), + self.get_test('image/canvas-bg.html'), + self.get_test('image/canvas-zoom.html'), + self.get_test('misc/crash.html'), + self.get_test('misc/passing.html')] def get_basic_expectations(self): return """ -BUG_TEST : fast/html/article-element.html = TEXT -BUG_TEST SKIP : fast/html/keygen.html = CRASH -BUG_TEST REBASELINE : fast/htmltab-order.html = MISSING -BUG_TEST : fast/events = IMAGE +BUG_TEST : text/article-element.html = TEXT +BUG_TEST SKIP : misc/crash.html = CRASH +BUG_TEST REBASELINE : misc/missing-expectation.html = MISSING +BUG_TEST : image = IMAGE """ def parse_exp(self, expectations, overrides=None): @@ -128,42 +127,42 @@ BUG_TEST : fast/events = IMAGE set([result])) def test_basic(self): - self.parse_exp(self.get_basic_expectations()) - self.assert_exp('fast/html/article-element.html', TEXT) - self.assert_exp('fast/events/tab-imagemap.html', IMAGE) - self.assert_exp('fast/html/header-element.html', PASS) + self.parse_exp(self.get_basic_expectations()) + self.assert_exp('text/article-element.html', TEXT) + self.assert_exp('image/canvas-zoom.html', IMAGE) + self.assert_exp('misc/passing.html', PASS) def test_duplicates(self): - self.assertRaises(SyntaxError, self.parse_exp, """ -BUG_TEST : fast/html/article-element.html = TEXT -BUG_TEST : fast/html/article-element.html = IMAGE""") - self.assertRaises(SyntaxError, self.parse_exp, - self.get_basic_expectations(), """ -BUG_TEST : fast/html/article-element.html = TEXT -BUG_TEST : fast/html/article-element.html = IMAGE""") + self.assertRaises(SyntaxError, self.parse_exp, """ +BUG_TEST : text/article-element.html = TEXT +BUG_TEST : text/article-element.html = IMAGE""") + self.assertRaises(SyntaxError, self.parse_exp, + self.get_basic_expectations(), """ +BUG_TEST : text/article-element.html = TEXT +BUG_TEST : text/article-element.html = IMAGE""") def test_overrides(self): - self.parse_exp(self.get_basic_expectations(), """ -BUG_OVERRIDE : fast/html/article-element.html = IMAGE""") - self.assert_exp('fast/html/article-element.html', IMAGE) + self.parse_exp(self.get_basic_expectations(), """ +BUG_OVERRIDE : text/article-element.html = IMAGE""") + self.assert_exp('text/article-element.html', IMAGE) def test_matches_an_expected_result(self): - def match(test, result, pixel_tests_enabled): - return self._exp.matches_an_expected_result( - self.get_test(test), result, pixel_tests_enabled) + def match(test, result, pixel_tests_enabled): + return self._exp.matches_an_expected_result( + self.get_test(test), result, pixel_tests_enabled) - self.parse_exp(self.get_basic_expectations()) - self.assertTrue(match('fast/html/article-element.html', TEXT, True)) - self.assertTrue(match('fast/html/article-element.html', TEXT, False)) - self.assertFalse(match('fast/html/article-element.html', CRASH, True)) - self.assertFalse(match('fast/html/article-element.html', CRASH, False)) + self.parse_exp(self.get_basic_expectations()) + self.assertTrue(match('text/article-element.html', TEXT, True)) + self.assertTrue(match('text/article-element.html', TEXT, False)) + self.assertFalse(match('text/article-element.html', CRASH, True)) + self.assertFalse(match('text/article-element.html', CRASH, False)) - self.assertTrue(match('fast/events/tab-imagemap.html', IMAGE, True)) - self.assertTrue(match('fast/events/tab-imagemap.html', PASS, False)) + self.assertTrue(match('image/canvas-bg.html', IMAGE, True)) + self.assertTrue(match('image/canvas-bg.html', PASS, False)) - self.assertTrue(match('fast/html/keygen.html', SKIP, False)) - self.assertTrue(match('fast/html/tab-order.html', PASS, False)) + self.assertTrue(match('misc/crash.html', SKIP, False)) + self.assertTrue(match('misc/passing.html', PASS, False)) if __name__ == '__main__': unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py index a4cbe42..782c87c 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py @@ -423,7 +423,7 @@ class Port(object): Returns: Operating-system's environment. """ - return os.environ + return os.environ.copy() def show_html_results_file(self, results_filename): """This routine should display the HTML file pointed at by diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py index bcbd498..b715f7b 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py @@ -158,9 +158,8 @@ class ChromiumPort(base.Port): return self.path_from_chromium_base('webkit', self._options.configuration, self._options.results_directory) except AssertionError: - return self.path_from_webkit_base('WebKit', 'chromium', - 'xcodebuild', self._options.configuration, - self._options.results_directory) + return self._build_path(self._options.configuration, + self._options.results_directory) def setup_test_run(self): # Delete the disk cache if any to ensure a clean test run. @@ -273,6 +272,12 @@ class ChromiumPort(base.Port): platform = self.name() return self.path_from_webkit_base('LayoutTests', 'platform', platform) + def _path_to_image_diff(self): + binary_name = 'image_diff' + if self._options.use_drt: + binary_name = 'ImageDiff' + return self._build_path(self._options.configuration, binary_name) + class ChromiumDriver(base.Driver): """Abstract interface for test_shell.""" diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py index 979e225..0818d51 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py @@ -81,11 +81,15 @@ class ChromiumLinuxPort(chromium.ChromiumPort): # def _build_path(self, *comps): - base = self.path_from_chromium_base() + if self._options.use_drt: + base = os.path.join(self.path_from_webkit_base(), 'WebKit', + 'chromium') + else: + base = self.path_from_chromium_base() if os.path.exists(os.path.join(base, 'sconsbuild')): - return self.path_from_chromium_base('sconsbuild', *comps) + return os.path.join(base, 'sconsbuild', *comps) else: - return self.path_from_chromium_base('out', *comps) + return os.path.join(base, 'out', *comps) def _check_apache_install(self): result = chromium.check_file_exists(self._path_to_apache(), @@ -147,14 +151,14 @@ class ChromiumLinuxPort(chromium.ChromiumPort): def _path_to_driver(self, configuration=None): if not configuration: configuration = self._options.configuration - return self._build_path(configuration, 'test_shell') + binary_name = 'test_shell' + if self._options.use_drt: + binary_name = 'DumpRenderTree' + return self._build_path(configuration, binary_name) def _path_to_helper(self): return None - def _path_to_image_diff(self): - return self._build_path(self._options.configuration, 'image_diff') - def _path_to_wdiff(self): if self._is_redhat_based(): return '/usr/bin/dwdiff' diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py index ba67a3e..aa3ac8d 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py @@ -150,12 +150,6 @@ class ChromiumMacPort(chromium.ChromiumPort): binary_name = 'LayoutTestHelper' return self._build_path(self._options.configuration, binary_name) - def _path_to_image_diff(self): - binary_name = 'image_diff' - if self._options.use_drt: - binary_name = 'ImageDiff' - return self._build_path(self._options.configuration, binary_name) - def _path_to_wdiff(self): return 'wdiff' diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py index 95d6378..a32eafd 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py @@ -27,6 +27,9 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import chromium +import chromium_linux +import chromium_mac +import chromium_win import unittest import StringIO @@ -78,3 +81,17 @@ class ChromiumDriverTest(unittest.TestCase): raise IOError self.driver._proc.stdout.readline = mock_readline self._assert_write_command_and_read_line(expected_crash=True) + + def test_path_to_image_diff(self): + class MockOptions: + def __init__(self): + self.use_drt = True + + port = chromium_linux.ChromiumLinuxPort('test-port', options=MockOptions()) + self.assertTrue(port._path_to_image_diff().endswith( + '/out/Release/ImageDiff')) + port = chromium_mac.ChromiumMacPort('test-port', options=MockOptions()) + self.assertTrue(port._path_to_image_diff().endswith( + '/xcodebuild/Release/ImageDiff')) + # FIXME: Figure out how this is going to work on Windows. + #port = chromium_win.ChromiumWinPort('test-port', options=MockOptions()) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py index ad78e61..3b11429 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py @@ -64,7 +64,7 @@ class ChromiumWinPort(chromium.ChromiumPort): setup_mount = self.path_from_chromium_base("third_party", "cygwin", "setup_mount.bat") - self._executive.run_command(setup_mount) + self._executive.run_command([setup_mount]) return env def baseline_search_path(self): @@ -117,6 +117,9 @@ class ChromiumWinPort(chromium.ChromiumPort): # def _build_path(self, *comps): + if self._options.use_drt: + return os.path.join(self.path_from_webkit_base(), 'WebKit', + 'chromium', *comps) p = self.path_from_chromium_base('webkit', *comps) if os.path.exists(p): return p diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py new file mode 100644 index 0000000..81db32c --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py @@ -0,0 +1,74 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys +import unittest +import chromium_win +from webkitpy.common.system import outputcapture +from webkitpy.tool import mocktool + + +class ChromiumWinTest(unittest.TestCase): + + class RegisterCygwinOption(object): + def __init__(self): + self.register_cygwin = True + + def setUp(self): + self.orig_platform = sys.platform + + def tearDown(self): + sys.platform = self.orig_platform + + def _mock_path_from_chromium_base(self, *comps): + return os.path.join("/chromium/src", *comps) + + def test_setup_environ_for_server(self): + port = chromium_win.ChromiumWinPort() + port._executive = mocktool.MockExecute(True) + port.path_from_chromium_base = self._mock_path_from_chromium_base + output = outputcapture.OutputCapture() + orig_environ = os.environ.copy() + env = output.assert_outputs(self, port.setup_environ_for_server) + self.assertEqual(orig_environ["PATH"], os.environ["PATH"]) + self.assertNotEqual(env["PATH"], os.environ["PATH"]) + + def test_setup_environ_for_server_register_cygwin(self): + sys.platform = "win32" + port = chromium_win.ChromiumWinPort( + options=ChromiumWinTest.RegisterCygwinOption()) + port._executive = mocktool.MockExecute(True) + port.path_from_chromium_base = self._mock_path_from_chromium_base + setup_mount = self._mock_path_from_chromium_base("third_party", + "cygwin", + "setup_mount.bat") + expected_stderr = "MOCK run_command: %s\n" % [setup_mount] + output = outputcapture.OutputCapture() + output.assert_outputs(self, port.setup_environ_for_server, + expected_stderr=expected_stderr) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py index 2c92865..e01bd2f 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py @@ -143,7 +143,7 @@ class DryrunDriver(base.Driver): text_filename = self._port.expected_filename(test_name, '.txt') text_output = _read_file(text_filename) - if image_hash: + if image_hash is not None: image_filename = self._port.expected_filename(test_name, '.png') image = _read_file(image_filename, 'rb') if self._image_path: diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py index 5d563cd..e6d4c99 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py @@ -28,7 +28,9 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Dummy Port implementation used for testing.""" +from __future__ import with_statement +import codecs import os import time @@ -45,9 +47,8 @@ class TestPort(base.Port): return ('test',) def baseline_path(self): - curdir = os.path.abspath(__file__) - self.topdir = curdir[0:curdir.index("WebKitTools")] - return os.path.join(self.topdir, 'LayoutTests', 'platform', 'test') + return os.path.join(self.layout_tests_dir(), 'platform', + self.name()) def baseline_search_path(self): return [self.baseline_path()] @@ -66,12 +67,9 @@ class TestPort(base.Port): expected_filename, actual_filename): return '' - def relative_test_filename(self, filename): - return filename - - def expected_filename(self, filename, suffix): - (basename, ext) = os.path.splitext(filename) - return basename + '.' + suffix + def layout_tests_dir(self): + return self.path_from_webkit_base('WebKitTools', 'Scripts', + 'webkitpy', 'layout_tests', 'data') def name(self): return self._name @@ -79,6 +77,11 @@ class TestPort(base.Port): def options(self): return self._options + def path_to_test_expectations_file(self): + return self.path_from_webkit_base('WebKitTools', 'Scripts', + 'webkitpy', 'layout_tests', 'data', 'platform', 'test', + 'test_expectations.txt') + def results_directory(self): return '/tmp/' + self._options.results_directory @@ -104,7 +107,13 @@ class TestPort(base.Port): pass def test_expectations(self): - return '' + """Returns the test expectations for this port. + + Basically this string should contain the equivalent of a + test_expectations file. See test_expectations.py for more details.""" + expectations_path = self.path_to_test_expectations_file() + with codecs.open(expectations_path, "r", "utf-8") as file: + return file.read() def test_base_platform_names(self): return ('test',) @@ -129,6 +138,7 @@ class TestDriver(base.Driver): self._driver_options = test_driver_options self._image_path = image_path self._port = port + self._image_written = False def poll(self): return True @@ -137,6 +147,15 @@ class TestDriver(base.Driver): return 0 def run_test(self, uri, timeoutms, image_hash): + if not self._image_written and self._port._options.pixel_tests: + with open(self._image_path, "w") as f: + f.write("bad png file from TestDriver") + self._image_written = True + + # We special-case this because we can't fake an image hash for a + # missing expectation. + if uri.find('misc/missing-expectation') != -1: + return (False, False, 'deadbeefdeadbeefdeadbeefdeadbeef', '', None) return (False, False, image_hash, '', None) def start(self): diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py index 148174d..6d5543d 100755 --- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py @@ -575,6 +575,7 @@ class TestRunner: test_args.png_path = png_path test_args.new_baseline = self._options.new_baseline + test_args.reset_results = self._options.reset_results test_args.show_sources = self._options.sources @@ -1521,6 +1522,9 @@ def parse_args(args=None): default=False, help="Save all generated results as new baselines " "into the platform directory, overwriting whatever's " "already there."), + optparse.make_option("--reset-results", action="store_true", + default=False, help="Reset any existing baselines to the " + "generated results"), optparse.make_option("--no-show-results", action="store_false", default=True, dest="show_results", help="Don't launch a browser with results after the tests " 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 e050cba..1c751d6 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py @@ -29,6 +29,7 @@ """Unit tests for run_webkit_tests.""" +import codecs import os import sys import unittest @@ -62,39 +63,99 @@ def logging_run(args): class MainTest(unittest.TestCase): def test_fast(self): + self.assertTrue(passing_run(['--platform', 'test'])) + self.assertTrue(passing_run(['--platform', 'test', '--run-singly'])) self.assertTrue(passing_run(['--platform', 'test', - 'fast/html'])) - self.assertTrue(passing_run(['--platform', 'test', - '--run-singly', - 'fast/html'])) - self.assertTrue(passing_run(['--platform', 'test', - 'fast/html/article-element.html'])) + 'text/article-element.html'])) self.assertTrue(passing_run(['--platform', 'test', '--child-processes', '1', - '--print', 'unexpected', - 'fast/html'])) + '--print', 'unexpected'])) def test_child_processes(self): (res, buildbot_output, regular_output) = logging_run( ['--platform', 'test', '--print', 'config', '--child-processes', - '1', 'fast/html']) + '1']) self.assertTrue('Running one DumpRenderTree\n' in regular_output.get()) (res, buildbot_output, regular_output) = logging_run( ['--platform', 'test', '--print', 'config', '--child-processes', - '2', 'fast/html']) + '2']) self.assertTrue('Running 2 DumpRenderTrees in parallel\n' in regular_output.get()) def test_last_results(self): - passing_run(['--platform', 'test', 'fast/html']) + passing_run(['--platform', 'test']) (res, buildbot_output, regular_output) = logging_run( ['--platform', 'test', '--print-last-failures']) self.assertEqual(regular_output.get(), ['\n\n']) self.assertEqual(buildbot_output.get(), []) +def _mocked_open(original_open, file_list): + def _wrapper(name, mode, encoding): + if name.find("-expected.") != -1 and mode == "w": + # we don't want to actually write new baselines, so stub these out + name.replace('\\', '/') + file_list.append(name) + return original_open(os.devnull, mode, encoding) + return original_open(name, mode, encoding) + return _wrapper + + +class RebaselineTest(unittest.TestCase): + def assertBaselines(self, file_list, file): + "assert that the file_list contains the baselines.""" + for ext in [".txt", ".png", ".checksum"]: + baseline = file + "-expected" + ext + self.assertTrue(any(f.find(baseline) != -1 for f in file_list)) + + def test_reset_results(self): + file_list = [] + original_open = codecs.open + try: + # Test that we update expectations in place. If the expectation + # is mssing, update the expected generic location. + file_list = [] + codecs.open = _mocked_open(original_open, file_list) + passing_run(['--platform', 'test', '--pixel-tests', + '--reset-results', + 'image/canvas-bg.html', + 'image/canvas-zoom.html', + 'misc/missing-expectation.html']) + self.assertEqual(len(file_list), 9) + self.assertBaselines(file_list, + "data/image/canvas-zoom") + self.assertBaselines(file_list, + "data/platform/test/image/canvas-bg") + self.assertBaselines(file_list, + "data/misc/missing-expectation") + finally: + codecs.open = original_open + + def test_new_baseline(self): + file_list = [] + original_open = codecs.open + try: + # Test that we update the platform expectations. If the expectation + # is mssing, then create a new expectation in the platform dir. + file_list = [] + codecs.open = _mocked_open(original_open, file_list) + passing_run(['--platform', 'test', '--pixel-tests', + '--new-baseline', + 'image/canvas-zoom.html', + 'image/canvas-bg.html', + 'misc/missing-expectation.html']) + self.assertEqual(len(file_list), 9) + self.assertBaselines(file_list, + "data/platform/test/image/canvas-zoom") + self.assertBaselines(file_list, + "data/platform/test/image/canvas-bg") + self.assertBaselines(file_list, + "data/platform/test/misc/missing-expectation") + finally: + codecs.open = original_open + class TestRunnerTest(unittest.TestCase): def test_results_html(self): mock_port = Mock() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py index b37f4b3..fe73a7b 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py @@ -73,18 +73,24 @@ class ImageDiff(test_type_base.TestTypeBase): if errno.ENOENT != e.errno: raise - def _save_baseline_files(self, filename, png_path, checksum): + def _save_baseline_files(self, filename, png_path, checksum, + generate_new_baseline): """Saves new baselines for the PNG and checksum. Args: filename: test filename png_path: path to the actual PNG result file checksum: value of the actual checksum result + generate_new_baseline: whether to generate a new, platform-specific + baseline, or update the existing one """ with open(png_path, "rb") as png_file: png_data = png_file.read() - self._save_baseline_data(filename, png_data, ".png", encoding=None) - self._save_baseline_data(filename, checksum, ".checksum", encoding="ascii") + self._save_baseline_data(filename, png_data, ".png", encoding=None, + generate_new_baseline=generate_new_baseline) + self._save_baseline_data(filename, checksum, ".checksum", + encoding="ascii", + generate_new_baseline=generate_new_baseline) def _create_image_diff(self, port, filename, configuration): """Creates the visual diff of the expected/actual PNGs. @@ -128,9 +134,9 @@ class ImageDiff(test_type_base.TestTypeBase): return failures # If we're generating a new baseline, we pass. - if test_args.new_baseline: + if test_args.new_baseline or test_args.reset_results: self._save_baseline_files(filename, test_args.png_path, - test_args.hash) + test_args.hash, test_args.new_baseline) return failures # Compare hashes. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py index cf0b9ec..8db2e3d 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py @@ -93,7 +93,8 @@ class TestTypeBase(object): self._port.relative_test_filename(filename)) self._port.maybe_make_directory(os.path.split(output_filename)[0]) - def _save_baseline_data(self, filename, data, modifier, encoding): + def _save_baseline_data(self, filename, data, modifier, encoding, + generate_new_baseline=True): """Saves a new baseline file into the port's baseline directory. The file will be named simply "<test>-expected<modifier>", suitable for @@ -103,18 +104,25 @@ class TestTypeBase(object): filename: path to the test file data: result to be saved as the new baseline modifier: type of the result file, e.g. ".txt" or ".png" + encoding: file encoding (none, "utf-8", etc.) + generate_new_baseline: whether to enerate a new, platform-specific + baseline, or update the existing one """ - relative_dir = os.path.dirname( - self._port.relative_test_filename(filename)) - baseline_path = self._port.baseline_path() - output_dir = os.path.join(baseline_path, relative_dir) - output_file = os.path.basename(os.path.splitext(filename)[0] + - self.FILENAME_SUFFIX_EXPECTED + modifier) + if generate_new_baseline: + relative_dir = os.path.dirname( + self._port.relative_test_filename(filename)) + baseline_path = self._port.baseline_path() + output_dir = os.path.join(baseline_path, relative_dir) + output_file = os.path.basename(os.path.splitext(filename)[0] + + self.FILENAME_SUFFIX_EXPECTED + modifier) + self._port.maybe_make_directory(output_dir) + output_path = os.path.join(output_dir, output_file) + _log.debug('writing new baseline result "%s"' % (output_path)) + else: + output_path = self._port.expected_filename(filename, modifier) + _log.debug('resetting baseline result "%s"' % output_path) - self._port.maybe_make_directory(output_dir) - output_path = os.path.join(output_dir, output_file) - _log.debug('writing new baseline to "%s"' % (output_path)) self._write_into_file_at_path(output_path, data, encoding) def output_filename(self, filename, modifier): 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 9fed474..18f74b8 100644 --- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py +++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py @@ -89,11 +89,12 @@ class TestTextDiff(test_type_base.TestTypeBase): failures = [] # If we're generating a new baseline, we pass. - if test_args.new_baseline: + if test_args.new_baseline or test_args.reset_results: # Although all test_shell/DumpRenderTree output should be utf-8, # we do not ever decode it inside run-webkit-tests. For some tests # DumpRenderTree may not output utf-8 text (e.g. webarchives). - self._save_baseline_data(filename, output, ".txt", encoding=None) + self._save_baseline_data(filename, output, ".txt", encoding=None, + generate_new_baseline=test_args.new_baseline) return failures # Normalize text to diff diff --git a/WebKitTools/Scripts/webkitpy/style/checker.py b/WebKitTools/Scripts/webkitpy/style/checker.py index 59a3d39..8fc86c3 100644 --- a/WebKitTools/Scripts/webkitpy/style/checker.py +++ b/WebKitTools/Scripts/webkitpy/style/checker.py @@ -43,7 +43,6 @@ from error_handlers import DefaultStyleErrorHandler from filter import FilterConfiguration from optparser import ArgumentParser from optparser import DefaultCommandOptionValues -from webkitpy.style_references import parse_patch from webkitpy.style_references import configure_logging as _configure_logging _log = logging.getLogger("webkitpy.style.checker") @@ -697,42 +696,3 @@ class StyleProcessor(ProcessorBase): _log.debug("Using class: " + checker.__class__.__name__) checker.check(lines) - - -class PatchReader(object): - - """Supports checking style in patches.""" - - def __init__(self, text_file_reader): - """Create a PatchReader instance. - - Args: - text_file_reader: A TextFileReader instance. - - """ - self._text_file_reader = text_file_reader - - def check(self, patch_string): - """Check style in the given patch.""" - patch_files = parse_patch(patch_string) - - # The diff variable is a DiffFile instance. - for path, diff in patch_files.iteritems(): - line_numbers = set() - for line in diff.lines: - # When deleted line is not set, it means that - # the line is newly added (or modified). - if not line[0]: - line_numbers.add(line[1]) - - _log.debug('Found %s new or modified lines in: %s' - % (len(line_numbers), path)) - - # If line_numbers is empty, the file has no new or - # modified lines. In this case, we don't check the file - # because we'll never output errors for the file. - # This optimization also prevents the program from exiting - # due to a deleted file. - if line_numbers: - self._text_file_reader.process_file(file_path=path, - line_numbers=line_numbers) diff --git a/WebKitTools/Scripts/webkitpy/style/checker_unittest.py b/WebKitTools/Scripts/webkitpy/style/checker_unittest.py index 6e1eaa2..e99ac68 100755 --- a/WebKitTools/Scripts/webkitpy/style/checker_unittest.py +++ b/WebKitTools/Scripts/webkitpy/style/checker_unittest.py @@ -39,7 +39,6 @@ import os import unittest import checker as style -from webkitpy.style_references import parse_patch from webkitpy.style_references import LogTesting from webkitpy.style_references import TestLogStream from checker import _BASE_FILTER_RULES @@ -50,7 +49,6 @@ from checker import check_webkit_style_configuration from checker import check_webkit_style_parser from checker import configure_logging from checker import CheckerDispatcher -from checker import PatchReader from checker import ProcessorBase from checker import StyleProcessor from checker import StyleProcessorConfiguration @@ -769,52 +767,3 @@ class StyleProcessor_CodeCoverageTest(LoggingTestCase): self.assertRaises(AssertionError, self._processor.process, lines=['line1', 'line2'], file_path=path, line_numbers=[100]) - - -class PatchReaderTest(unittest.TestCase): - - """Test the PatchReader class.""" - - class MockTextFileReader(object): - - def __init__(self): - self.passed_to_process_file = [] - """A list of (file_path, line_numbers) pairs.""" - - def process_file(self, file_path, line_numbers): - self.passed_to_process_file.append((file_path, line_numbers)) - - def setUp(self): - file_reader = self.MockTextFileReader() - self._file_reader = file_reader - self._patch_checker = PatchReader(file_reader) - - def _call_check_patch(self, patch_string): - self._patch_checker.check(patch_string) - - def _assert_checked(self, passed_to_process_file): - self.assertEquals(self._file_reader.passed_to_process_file, - passed_to_process_file) - - def test_check_patch(self): - # The modified line_numbers array for this patch is: [2]. - self._call_check_patch("""diff --git a/__init__.py b/__init__.py -index ef65bee..e3db70e 100644 ---- a/__init__.py -+++ b/__init__.py -@@ -1,1 +1,2 @@ - # Required for Python to search this directory for module files -+# New line -""") - self._assert_checked([("__init__.py", set([2]))]) - - def test_check_patch_with_deletion(self): - self._call_check_patch("""Index: __init__.py -=================================================================== ---- __init__.py (revision 3593) -+++ __init__.py (working copy) -@@ -1 +0,0 @@ --foobar -""") - # _mock_check_file should not be called for the deletion patch. - self._assert_checked([]) diff --git a/WebKitTools/Scripts/webkitpy/style/patchreader.py b/WebKitTools/Scripts/webkitpy/style/patchreader.py new file mode 100644 index 0000000..7ba2b66 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/style/patchreader.py @@ -0,0 +1,75 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# Copyright (C) 2010 Chris Jerdonek (chris.jerdonek@gmail.com) +# Copyright (C) 2010 ProFUSION embedded systems +# +# 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 + +from webkitpy.common.checkout.diff_parser import DiffParser + + +_log = logging.getLogger("webkitpy.style.patchreader") + + +class PatchReader(object): + + """Supports checking style in patches.""" + + def __init__(self, text_file_reader): + """Create a PatchReader instance. + + Args: + text_file_reader: A TextFileReader instance. + + """ + self._text_file_reader = text_file_reader + + def check(self, patch_string): + """Check style in the given patch.""" + patch_files = DiffParser(patch_string.splitlines()).files + + # The diff variable is a DiffFile instance. + for path, diff in patch_files.iteritems(): + line_numbers = set() + for line in diff.lines: + # When deleted line is not set, it means that + # the line is newly added (or modified). + if not line[0]: + line_numbers.add(line[1]) + + _log.debug('Found %s new or modified lines in: %s' + % (len(line_numbers), path)) + + # If line_numbers is empty, the file has no new or + # modified lines. In this case, we don't check the file + # because we'll never output errors for the file. + # This optimization also prevents the program from exiting + # due to a deleted file. + if line_numbers: + self._text_file_reader.process_file(file_path=path, + line_numbers=line_numbers) diff --git a/WebKitTools/Scripts/webkitpy/style/patchreader_unittest.py b/WebKitTools/Scripts/webkitpy/style/patchreader_unittest.py new file mode 100644 index 0000000..10791e4 --- /dev/null +++ b/WebKitTools/Scripts/webkitpy/style/patchreader_unittest.py @@ -0,0 +1,85 @@ +#!/usr/bin/python +# +# Copyright (C) 2010 Google Inc. All rights reserved. +# Copyright (C) 2009 Torch Mobile Inc. +# Copyright (C) 2009 Apple Inc. All rights reserved. +# Copyright (C) 2010 Chris Jerdonek (chris.jerdonek@gmail.com) +# +# 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.style.patchreader import PatchReader + + +class PatchReaderTest(unittest.TestCase): + + """Test the PatchReader class.""" + + class MockTextFileReader(object): + + def __init__(self): + self.passed_to_process_file = [] + """A list of (file_path, line_numbers) pairs.""" + + def process_file(self, file_path, line_numbers): + self.passed_to_process_file.append((file_path, line_numbers)) + + def setUp(self): + file_reader = self.MockTextFileReader() + self._file_reader = file_reader + self._patch_checker = PatchReader(file_reader) + + def _call_check_patch(self, patch_string): + self._patch_checker.check(patch_string) + + def _assert_checked(self, passed_to_process_file): + self.assertEquals(self._file_reader.passed_to_process_file, + passed_to_process_file) + + def test_check_patch(self): + # The modified line_numbers array for this patch is: [2]. + self._call_check_patch("""diff --git a/__init__.py b/__init__.py +index ef65bee..e3db70e 100644 +--- a/__init__.py ++++ b/__init__.py +@@ -1,1 +1,2 @@ + # Required for Python to search this directory for module files ++# New line +""") + self._assert_checked([("__init__.py", set([2]))]) + + def test_check_patch_with_deletion(self): + self._call_check_patch("""Index: __init__.py +=================================================================== +--- __init__.py (revision 3593) ++++ __init__.py (working copy) +@@ -1 +0,0 @@ +-foobar +""") + # _mock_check_file should not be called for the deletion patch. + self._assert_checked([]) diff --git a/WebKitTools/Scripts/webkitpy/style_references.py b/WebKitTools/Scripts/webkitpy/style_references.py index 1bf087d..bab30ca 100644 --- a/WebKitTools/Scripts/webkitpy/style_references.py +++ b/WebKitTools/Scripts/webkitpy/style_references.py @@ -56,14 +56,6 @@ def detect_checkout(): return None if scm is None else WebKitCheckout(scm) -def parse_patch(patch_string): - - """Parse a patch string and return the affected files.""" - - patch = DiffParser(patch_string.splitlines()) - return patch.files - - class WebKitCheckout(object): """Simple facade to the SCM class for use by style package.""" diff --git a/WebKitTools/Scripts/webkitpy/tool/bot/patchcollection.py b/WebKitTools/Scripts/webkitpy/tool/bot/patchcollection.py index 9a2cdfa..6100cf8 100644 --- a/WebKitTools/Scripts/webkitpy/tool/bot/patchcollection.py +++ b/WebKitTools/Scripts/webkitpy/tool/bot/patchcollection.py @@ -1,4 +1,4 @@ -# Copyright (c) 2009 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 @@ -26,6 +26,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + class PersistentPatchCollectionDelegate: def collection_name(self): raise NotImplementedError, "subclasses must implement" @@ -56,9 +57,22 @@ class PersistentPatchCollection: self._status_cache[patch_id] = status return status - def next(self): + def _is_active_patch_id(self, patch_id): + """Active patches are patches waiting to be processed from this collection.""" + status = self._cached_status(patch_id) + return not status or not self._delegate.is_terminal_status(status) + + def _fetch_active_patch_ids(self): patch_ids = self._delegate.fetch_potential_patch_ids() - for patch_id in patch_ids: - status = self._cached_status(patch_id) - if not status or not self._delegate.is_terminal_status(status): - return patch_id + return filter(lambda patch_id: self._is_active_patch_id(patch_id), patch_ids) + + def next(self): + # Note: We only fetch all the ids so we can post them back to the server. + # This will go away once we have a feeder queue and all other queues are + # just pulling their next work item from the server. + patch_ids = self._fetch_active_patch_ids() + # FIXME: We're assuming self._name is a valid queue-name. + self._status.update_work_items(self._name, patch_ids) + if not patch_ids: + return None + return patch_ids[0] diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem.py b/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem.py index 7505c62..9fbfda6 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem.py @@ -116,6 +116,9 @@ class QtEWS(AbstractEarlyWarningSystem): class WinEWS(AbstractEarlyWarningSystem): name = "win-ews" port_name = "win" + # Use debug, the Apple Win port fails to link Release on 32-bit Windows. + # https://bugs.webkit.org/show_bug.cgi?id=39197 + _build_style = "debug" class AbstractChromiumEWS(AbstractEarlyWarningSystem): diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py index 3d0ddd1..27e09ba 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py @@ -47,6 +47,7 @@ class EarlyWarningSytemTest(QueuesTest): expected_stderr = { "begin_work_queue": "CAUTION: %(name)s will discard all local changes in \"%(checkout_dir)s\"\nRunning WebKit %(name)s.\n" % string_replacemnts, "handle_unexpected_error": "Mock error message\n", + "next_work_item": "MOCK: update_work_items: %(name)s [103]\n" % string_replacemnts, "process_work_item": "MOCK: update_status: %(name)s Pass\n" % string_replacemnts, } return expected_stderr diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queues.py b/WebKitTools/Scripts/webkitpy/tool/commands/queues.py index 78ca729..08bd3aa 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/queues.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/queues.py @@ -135,6 +135,9 @@ class AbstractPatchQueue(AbstractQueue): def _update_status(self, message, patch=None, results_file=None): self.tool.status_server.update_status(self.name, message, patch, results_file) + def _update_work_items(self, patch_ids): + self.tool.status_server.update_work_items(self.name, patch_ids) + def _did_pass(self, patch): self._update_status(self._pass_status, patch) @@ -169,12 +172,21 @@ class CommitQueue(AbstractPatchQueue, StepSequenceErrorHandler): all_patches = sum([self.tool.bugs.fetch_bug(bug_id).commit_queued_patches(include_invalid=True) for bug_id in bug_ids], []) return self.committer_validator.patches_after_rejecting_invalid_commiters_and_reviewers(all_patches) + def _patch_cmp(self, a, b): + # Sort first by is_rollout, then by attach_date. + # Reversing the order so that is_rollout is first. + rollout_cmp = cmp(b.is_rollout(), a.is_rollout()) + if (rollout_cmp != 0): + return rollout_cmp + return cmp(a.attach_date(), b.attach_date()) + def next_work_item(self): patches = self._validate_patches_in_commit_queue() + patches = sorted(patches, self._patch_cmp) + self._update_work_items([patch.id() for patch in patches]) builders_are_green = self._builders_are_green() if not builders_are_green: patches = filter(lambda patch: patch.is_rollout(), patches) - # FIXME: We could sort the patches in a specific order here, was suggested by https://bugs.webkit.org/show_bug.cgi?id=33395 if not patches: queue_text = "queue" if builders_are_green else "rollout queue" self._update_status("Empty %s" % queue_text) diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py index 0bd42fb..a5d56da 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py @@ -122,7 +122,8 @@ class CommitQueueTest(QueuesTest): # FIXME: The commit-queue warns about bad committers twice. This is due to the fact that we access Attachment.reviewer() twice and it logs each time. "next_work_item" : """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com) Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com) -2 patches in commit-queue [197, 106] +MOCK: update_work_items: commit-queue [106, 197] +2 patches in commit-queue [106, 197] """, "process_work_item" : "MOCK: update_status: commit-queue Pass\n", } @@ -137,6 +138,7 @@ Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.c # FIXME: The commit-queue warns about bad committers twice. This is due to the fact that we access Attachment.reviewer() twice and it logs each time. "next_work_item" : """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com) Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com) +MOCK: update_work_items: commit-queue [106, 197] MOCK: update_status: commit-queue Builders ["Builder2"] are red. See http://build.webkit.org 1 patch in commit-queue [106] """, @@ -154,6 +156,7 @@ MOCK: update_status: commit-queue Builders ["Builder2"] are red. See http://buil # FIXME: The commit-queue warns about bad committers twice. This is due to the fact that we access Attachment.reviewer() twice and it logs each time. "next_work_item": """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com) Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com) +MOCK: update_work_items: commit-queue [106, 197] MOCK: update_status: commit-queue Builders ["Builder2"] are red. See http://build.webkit.org 1 patch in commit-queue [106] """, @@ -170,11 +173,31 @@ MOCK: update_status: commit-queue Builders ["Builder2"] are red. See http://buil expected_run_args = ["echo", "--status-host=example.com", "build-and-test", "--force-clean", "--build", "--test", "--non-interactive", "--no-update", "--build-style=both", "--quiet"] tool.executive.run_and_throw_if_fail.assert_called_with(expected_run_args) + def _mock_attachment(self, is_rollout, attach_date): + attachment = Mock() + attachment.is_rollout = lambda: is_rollout + attachment.attach_date = lambda: attach_date + return attachment + + def test_patch_cmp(self): + long_ago_date = datetime(1900, 1, 21) + recent_date = datetime(2010, 1, 21) + attachment1 = self._mock_attachment(is_rollout=False, attach_date=recent_date) + attachment2 = self._mock_attachment(is_rollout=False, attach_date=long_ago_date) + attachment3 = self._mock_attachment(is_rollout=True, attach_date=recent_date) + attachment4 = self._mock_attachment(is_rollout=True, attach_date=long_ago_date) + attachments = [attachment1, attachment2, attachment3, attachment4] + expected_sort = [attachment4, attachment3, attachment2, attachment1] + queue = CommitQueue() + attachments.sort(queue._patch_cmp) + self.assertEqual(attachments, expected_sort) + class StyleQueueTest(QueuesTest): def test_style_queue(self): expected_stderr = { "begin_work_queue" : "CAUTION: style-queue will discard all local changes in \"%s\"\nRunning WebKit style-queue.\n" % MockSCM.fake_checkout_root, + "next_work_item": "MOCK: update_work_items: style-queue [103]\n", "should_proceed_with_work_item": "MOCK: update_status: style-queue Checking style\n", "process_work_item" : "MOCK: update_status: style-queue Pass\n", "handle_unexpected_error" : "Mock error message\n", diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py index 4797ef6..cf715b9 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/upload.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/upload.py @@ -168,7 +168,6 @@ class Post(AbstractPatchUploadingCommand): name = "post" help_text = "Attach the current working directory diff to a bug as a patch file" argument_names = "[BUGID]" - show_in_main_help = True steps = [ steps.CheckStyle, steps.ConfirmDiff, @@ -193,7 +192,6 @@ class Prepare(AbstractSequencedCommand): name = "prepare" help_text = "Creates a bug (or prompts for an existing bug) and prepares the ChangeLogs" argument_names = "[BUGID]" - show_in_main_help = True steps = [ steps.PromptForBugOrTitle, steps.CreateBug, diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/upload_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/upload_unittest.py index 8f6483a..d52775b 100644 --- a/WebKitTools/Scripts/webkitpy/tool/commands/upload_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/commands/upload_unittest.py @@ -55,6 +55,7 @@ class UploadCommandsTest(CommandsTest): options.description = "MOCK description" options.request_commit = False options.review = True + options.comment = None # Rietveld upload code requires a real SCM checkout. options.fancy_review = False options.cc = None @@ -85,6 +86,7 @@ MOCK: user.open_url: http://example.com/42 options.description = "MOCK description" options.request_commit = False options.review = True + options.comment = None # Rietveld upload code requires a real SCM checkout. options.fancy_review = False options.cc = None diff --git a/WebKitTools/Scripts/webkitpy/tool/main.py b/WebKitTools/Scripts/webkitpy/tool/main.py index 2dc177d..1f43145 100755 --- a/WebKitTools/Scripts/webkitpy/tool/main.py +++ b/WebKitTools/Scripts/webkitpy/tool/main.py @@ -56,6 +56,7 @@ from webkitpy.common.system.deprecated_logging import log class WebKitPatch(MultiCommandTool): global_options = [ + make_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="enable all logging"), make_option("--dry-run", action="store_true", dest="dry_run", default=False, help="do not touch remote servers"), make_option("--status-host", action="store", dest="status_host", type="string", nargs=1, help="Hostname (e.g. localhost or commit.webkit.org) where status updates should be posted."), make_option("--irc-password", action="store", dest="irc_password", type="string", nargs=1, help="Password to use when communicating via IRC."), diff --git a/WebKitTools/Scripts/webkitpy/tool/mocktool.py b/WebKitTools/Scripts/webkitpy/tool/mocktool.py index 47fff1b..2f192d9 100644 --- a/WebKitTools/Scripts/webkitpy/tool/mocktool.py +++ b/WebKitTools/Scripts/webkitpy/tool/mocktool.py @@ -477,6 +477,9 @@ class MockStatusServer(object): def svn_revision(self, svn_revision): return None + def update_work_items(self, queue_name, work_items): + log("MOCK: update_work_items: %s %s" % (queue_name, work_items)) + def update_status(self, queue_name, status, patch=None, results_file=None): log("MOCK: update_status: %s %s" % (queue_name, status)) return 187 diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/options.py b/WebKitTools/Scripts/webkitpy/tool/steps/options.py index 524a252..186d292 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/options.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/options.py @@ -36,6 +36,7 @@ class Options(object): check_style = make_option("--ignore-style", action="store_false", dest="check_style", default=True, help="Don't check to see if the patch has proper style before uploading.") clean = make_option("--no-clean", action="store_false", dest="clean", default=True, help="Don't check if the working directory is clean before applying patches") close_bug = make_option("--no-close", action="store_false", dest="close_bug", default=True, help="Leave bug open after landing.") + comment = make_option("--comment", action="store", type="string", dest="comment", help="Comment to post to bug.") component = make_option("--component", action="store", type="string", dest="component", help="Component for the new bug.") confirm = make_option("--no-confirm", action="store_false", dest="confirm", default=True, help="Skip confirmation steps.") description = make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: \"patch\")") diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/postdiff.py b/WebKitTools/Scripts/webkitpy/tool/steps/postdiff.py index 79739cd..c40b6ff 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/postdiff.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/postdiff.py @@ -35,6 +35,7 @@ class PostDiff(AbstractStep): def options(cls): return AbstractStep.options() + [ Options.description, + Options.comment, Options.review, Options.request_commit, Options.open_bug, @@ -43,7 +44,7 @@ class PostDiff(AbstractStep): def run(self, state): diff = self.cached_lookup(state, "diff") description = self._options.description or "Patch" - comment_text = None + comment_text = self._options.comment self._tool.bugs.add_patch_to_bug(state["bug_id"], diff, description, comment_text=comment_text, mark_for_review=self._options.review, mark_for_commit_queue=self._options.request_commit) if self._options.open_bug: self._tool.user.open_url(self._tool.bugs.bug_url_for_bug_id(state["bug_id"])) diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py b/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py index 0734d8f..22b9452 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/runtests.py @@ -58,9 +58,10 @@ class RunTests(AbstractStep): args.append("--no-launch-safari") args.append("--exit-after-n-failures=1") # FIXME: Hack to work around https://bugs.webkit.org/show_bug.cgi?id=38912 - # when running the commit-queue on a mac leopard machine. + # when running the commit-queue on a mac leopard machine since compositing + # does not work reliably on Leopard due to various graphics driver/system bugs. if self.port().name() == "Mac" and self.port().is_leopard(): - args.extend(["--ignore-tests", "compositing/iframes"]) + args.extend(["--ignore-tests", "compositing"]) if self._options.quiet: args.append("--quiet") diff --git a/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py b/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py index eee183b..1fd2bad 100644 --- a/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py +++ b/WebKitTools/Scripts/webkitpy/tool/steps/steps_unittest.py @@ -78,6 +78,6 @@ MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/test-webkitperl'] Running JavaScriptCore tests MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/run-javascriptcore-tests'] Running run-webkit-tests -MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/run-webkit-tests', '--no-launch-safari', '--exit-after-n-failures=1', '--ignore-tests', 'compositing/iframes', '--quiet'] +MOCK run_and_throw_if_fail: ['WebKitTools/Scripts/run-webkit-tests', '--no-launch-safari', '--exit-after-n-failures=1', '--ignore-tests', 'compositing', '--quiet'] """ OutputCapture().assert_outputs(self, step.run, [{}], expected_stderr=expected_stderr) diff --git a/WebKitTools/WebKitAPITest/WebKitAPITest.vcproj b/WebKitTools/WebKitAPITest/WebKitAPITest.vcproj index 5473f10..9984389 100644 --- a/WebKitTools/WebKitAPITest/WebKitAPITest.vcproj +++ b/WebKitTools/WebKitAPITest/WebKitAPITest.vcproj @@ -197,6 +197,69 @@ Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug_Cairo|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops;.\WebKitAPITestCommon.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
|