diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-16 14:51:15 +0200 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-16 14:51:15 +0200 |
| commit | 4e6b3a206fa4ad8bb0b664f7674c9a70376d6e26 (patch) | |
| tree | 7bb9ad7e31c24d1cf1707e03e6f1a80f6d033951 /Tools | |
| parent | 3977e3d2f72f7fe2c887c1ec0e0c342e1d169f42 (diff) | |
| download | qtwebkit-4e6b3a206fa4ad8bb0b664f7674c9a70376d6e26.tar.gz | |
Imported WebKit commit 953baa67aa07087b6ecd4199351ec554c724e27d (http://svn.webkit.org/repository/webkit/trunk@122676)
Diffstat (limited to 'Tools')
78 files changed, 2558 insertions, 2140 deletions
diff --git a/Tools/ChangeLog b/Tools/ChangeLog index 8f8d602ef..f40f69e15 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,3 +1,1038 @@ +2012-07-14 Benjamin Poulain <bpoulain@apple.com> + + [Mac] Do not try to update the cache model for every WebPreferences change + https://bugs.webkit.org/show_bug.cgi?id=91302 + + Reviewed by Joseph Pecoraro. + + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: + * TestWebKitAPI/Tests/mac/SetAndUpdateCacheModel.mm: Added. + (TestWebKitAPI): + (TestWebKitAPI::TEST): + +2012-07-14 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122665. + http://trac.webkit.org/changeset/122665 + https://bugs.webkit.org/show_bug.cgi?id=91321 + + Broke Mac builds (Requested by rniwa on #webkit). + + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: + * TestWebKitAPI/Tests/mac/SetAndUpdateCacheModel.mm: Removed. + +2012-07-13 Benjamin Poulain <bpoulain@apple.com> + + [Mac] Do not try to update the cache model for every WebPreferences change + https://bugs.webkit.org/show_bug.cgi?id=91302 + + Reviewed by Joseph Pecoraro. + + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: + * TestWebKitAPI/Tests/mac/SetAndUpdateCacheModel.mm: Added. + (TestWebKitAPI): + (TestWebKitAPI::TEST): + +2012-07-13 Dirk Pranke <dpranke@chromium.org> + + run-webkit-test outputs the wrong number of tests executed when some are skipped. + https://bugs.webkit.org/show_bug.cgi?id=89894 + + Reviewed by Ojan Vafai. + + Fix the logging of the actual number of tests run so that tests + that are skipped aren't included. + + Also revamp the 'expected' output so we distinguish the number + of tests found from the number of tests run (to account for + --repeat-each and --iterations). + + Covered by existing tests. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager.prepare_lists_and_print_output): + (Manager._log_num_workers): + (Manager.run): + (Manager._print_result_summary): + * Scripts/webkitpy/layout_tests/models/result_summary.py: + (ResultSummary.__init__): + (ResultSummary.add): + * Scripts/webkitpy/layout_tests/views/printing.py: + (Printer.print_one_line_summary): + * Scripts/webkitpy/layout_tests/views/printing_unittest.py: + (Testprinter.test_print_one_line_summary): + +2012-07-13 Dirk Pranke <dpranke@chromium.org> + + nrwt: actually print the exception name and message for otherwise unhandled exceptions + https://bugs.webkit.org/show_bug.cgi?id=91305 + + Reviewed by Adam Barth. + + Two more places where I was printing the stack trace but not the + exception itself :(. These two spots can't easily be + unit-tested, but I tested them by hand. + + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + (run): + (main): + +2012-07-13 Josh Hawn <jhawn@apple.com> + + Fix for WebContext::getWebCoreStatistics() causes crash if no m_process + https://bugs.webkit.org/show_bug.cgi?id=91116 + + Reviewed by Simon Fraser. + + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: + Added new test file. + * TestWebKitAPI/Tests/WebKit2/WebCoreStatisticsWithNoWebProcess.cpp: Added. + (TestWebKitAPI::wkContextGetStatisticsCallback): + Tests that callback function receives an error. + (TestWebKitAPI::TEST): + Creates a dummy web context object (no web process). + Calls WKContextGetStatistics with the web context and test callback. + The test callback should get an expected error. + +2012-07-13 Dirk Pranke <dpranke@chromium.org> + + test-webkitpy: move printing-related code out of the runner + https://bugs.webkit.org/show_bug.cgi?id=91289 + + Reviewed by Ryosuke Niwa. + + More refactoring ... this moves all printing-related stuff out + of runner.py and into printer.py. + + No functional changes; covered by existing tests. + + * Scripts/webkitpy/test/main.py: + (Tester._run_tests): + * Scripts/webkitpy/test/printer.py: + (Printer.__init__): + (Printer): + (Printer.test_name): + (Printer.print_started_test): + (Printer.print_finished_test): + (Printer.print_result): + * Scripts/webkitpy/test/runner.py: + (Runner.__init__): + (Runner.all_test_names): + (Runner.run): + * Scripts/webkitpy/test/runner_unittest.py: + (RunnerTest.test_regular): + (RunnerTest.test_verbose): + (RunnerTest.test_timing): + +2012-07-13 Dirk Pranke <dpranke@chromium.org> + + webkitpy: split printing/logging code for test-webkitpy out into a new class + https://bugs.webkit.org/show_bug.cgi?id=91282 + + Reviewed by Ojan Vafai. + + This patch is the first step at splitting all of the + printing/logging code out separately from the actual + test-running code. + + This is just moving stuff around; no new functionality and no + new tests needed. + + * Scripts/webkitpy/test/finder_unittest.py: + (FinderTest.setUp): + * Scripts/webkitpy/test/main.py: + (Tester.__init__): + (Tester._parse_args): + (Tester.run): + (Tester._run_tests): + (Tester._log_exception): + * Scripts/webkitpy/test/main_unittest.py: + (TesterTest.test_no_tests_found): + * Scripts/webkitpy/test/printer.py: Added. + (Printer): + (Printer.__init__): + (Printer.configure): + (Printer.configure.filter): + (_CaptureAndPassThroughStream): + (_CaptureAndPassThroughStream.__init__): + (_CaptureAndPassThroughStream.write): + (_CaptureAndPassThroughStream._message_is_from_pdb): + (_CaptureAndPassThroughStream.flush): + (_CaptureAndPassThroughStream.getvalue): + +2012-07-13 James Simonsen <simonjam@chromium.org> + + [Navigation Timing] Imported W3C tests contain duplicates and are DOS formatted + https://bugs.webkit.org/show_bug.cgi?id=91184 + + Reviewed by Adam Barth. + + The upstream 'html5' tests are just duplicates of the 'html' tests. + + * Scripts/import-w3c-performance-wg-tests: + +2012-07-13 Dirk Pranke <dpranke@chromium.org> + + webkitpy: hide yield_to_caller from callers in MessagePool :) + https://bugs.webkit.org/show_bug.cgi?id=91269 + + Reviewed by Adam Barth. + + yield_to_caller() was an optimization/hack to allow us to run + both manager and worker in a single process/loop without + starving the manager while the worker is running tests. The + worker was required to call yield_to_caller() periodically. It + turns out that I can get equivalent responsiveness by yielding + inside the MessagePool every time the worker posts a message, and this + allows me to no longer need the worker to call the routine. Thus + I rename yield_to_caller() to _yield_to_manager() to be a little + clearer about its purpose. + + Tested by existing tests. + + * Scripts/webkitpy/common/message_pool.py: + (_Worker.run): + (_Worker.post): + (_Worker._yield_to_manager): + * Scripts/webkitpy/layout_tests/controllers/worker.py: + (Worker.handle): + +2012-07-13 Adam Barth <abarth@webkit.org> + + EWSTools should be able to build a commit-queue instance from scratch + https://bugs.webkit.org/show_bug.cgi?id=91264 + + Reviewed by Eric Seidel. + + I've been using this script to build commit-queue instances on Google + Compute Engine and it seems to work. + + * EWSTools/GoogleComputeEngine/build-commit-queue.sh: Added. + +2012-07-13 Dirk Pranke <dpranke@chromium.org> + + webkitpy: make worker.start() and worker.stop() optional in the messagepool + https://bugs.webkit.org/show_bug.cgi?id=91170 + + Reviewed by Ojan Vafai. + + test-webkitpy will use messagepool workers that don't actually + have any per-worker state, so they don't need start() and stop() + methods. Now we will only call the methods if they exist; this + means that workers only need to expose a handle() method. + + * Scripts/webkitpy/common/message_pool.py: + (_Worker.terminate): + (_Worker.run): + +2012-07-13 Dirk Pranke <dpranke@chromium.org> + + NRWT doesn't print exceptions + https://bugs.webkit.org/show_bug.cgi?id=91129 + + Reviewed by Ojan Vafai. + + Although we printed exceptions in most cases, if an unexpected + exception (like a runtime error) was raised when creating a + port, we wouldn't. This patch fixes that, and also cleans up + how we were logging exceptions from the workers to be less + verbose. + + Because of the corner cases where these errors are occurring, + it's difficult to write automated unit tests for them. I've + tested it quite a bit by hand, though. + + * Scripts/webkitpy/common/message_pool.py: + (_MessagePool._close): + (_MessagePool._handle_worker_exception): + (_Worker.run): + (_Worker._raise): + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager._run_tests): + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + (main): + +2012-07-13 Wei James <james.wei@intel.com> + + enable TestWebKitAPI/webkit_unit_tests apk on x86 android platform by adding abi support + https://bugs.webkit.org/show_bug.cgi?id=91194 + + Reviewed by Adam Barth. + + * TestWebKitAPI/TestWebKitAPI.gyp/TestWebKitAPI.gyp: + +2012-07-13 Simon Pena <spena@igalia.com> + + [GTK] Gardening: update API tests skipped list + https://bugs.webkit.org/show_bug.cgi?id=91224 + + Unreviewed gardening. + + Skip "next" and "previous" tests of FindController until bug #91083 + is fixed. + + * gtk/run-api-tests: + (TestRunner): + +2012-07-13 Zeno Albisser <zeno@webkit.org> + + [Qt][WK2] Implement GraphicsSurface for Linux/GLX. + https://bugs.webkit.org/show_bug.cgi?id=90881 + + Enable GraphicsSurface for Linux based platforms + whenever the Xcomposite extension is available. + + Reviewed by Noam Rosenthal. + + * qmake/config.tests/libXcomposite/libXcomposite.cpp: Added. + (main): + * qmake/config.tests/libXcomposite/libXcomposite.pro: Added. + Add a configure test to detect Xcomposite extension and + activate GraphicsSurface on linux in case the extension is available. + * qmake/configure.pri: + * qmake/mkspecs/features/features.prf: + +2012-07-13 David Grogan <dgrogan@chromium.org> + + nrwt: don't choke when printing invalid utf-8 to stderr + https://bugs.webkit.org/show_bug.cgi?id=91181 + + Reviewed by Dirk Pranke. + + * Scripts/webkitpy/layout_tests/controllers/test_result_writer.py: + (TestResultWriter.write_stderr): + +2012-07-13 Dirk Pranke <dpranke@chromium.org> + + test-webkitpy: more class renaming cleanup + https://bugs.webkit.org/show_bug.cgi?id=91182 + + Reviewed by Adam Barth. + + More removing of the unnecessary "Test" prefix. + + * Scripts/webkitpy/test/finder.py: + (_DirectoryTree): + (Finder.add_tree): + * Scripts/webkitpy/test/main.py: + (Tester._run_tests): + * Scripts/webkitpy/test/runner.py: + (Runner): + * Scripts/webkitpy/test/runner_unittest.py: + (RunnerTest.test_regular): + (RunnerTest.test_verbose): + (RunnerTest.test_timing): + +2012-07-12 Christophe Dumez <christophe.dumez@intel.com> + + [WK2][EFL] Facilitate debugging of the Web Process + https://bugs.webkit.org/show_bug.cgi?id=90768 + + Reviewed by Kenneth Rohde Christiansen. + + Add a new --webprocess-cmd-prefix argument to + run-webkit-tests script for EFL port. If provided, + the prefix will be prepended to the command used + to spawn the Web process. This can be used for + debugging purposes with prefixes such as: + "xterm -title renderer -e gdb --args". + + * Scripts/webkitpy/layout_tests/port/efl.py: + (EflPort.__init__): + (EflPort.setup_environ_for_server): + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + (parse_args): + * WebKitTestRunner/efl/TestControllerEfl.cpp: + (WTR::TestController::platformRunUntil): Implement support for + m_noTimeout timeout value. + +2012-07-12 Adam Barth <abarth@webkit.org> + + Fix crash in the commit-queue. We need to initialize self.port during __init__. + + * Scripts/webkitpy/tool/commands/queues.py: + (CommitQueue.__init__): + (CommitQueue.begin_work_queue): + +2012-07-12 Dirk Pranke <dpranke@chromium.org> + + test-webkitpy: rename test_finder to finder + https://bugs.webkit.org/show_bug.cgi?id=91175 + + Reviewed by Adam Barth. + + Rename test_finder -> finder, TestFinder -> Finder to remove + some of the stutter in the names. + + * Scripts/webkitpy/test/finder.py: Renamed from Tools/Scripts/webkitpy/test/test_finder.py. + * Scripts/webkitpy/test/finder_unittest.py: Renamed from Tools/Scripts/webkitpy/test/test_finder_unittest.py. + * Scripts/webkitpy/test/main.py: + (Tester.__init__): + +2012-07-12 Adam Barth <abarth@webkit.org> + + CommitQueue is confused about what port it is using + https://bugs.webkit.org/show_bug.cgi?id=91040 + + Reviewed by Dirk Pranke. + + On EC2, we explicitly pass --port to the commit-queue, but that + requires editing the start-queue.sh script locally on each bot. In + moving to Google Compute Engine, we're try to avoid any local edits to + the EWSTools. + + Rather than passing --port to the commit-queue, this patch teaches the + CommitQueue which port its running, which is the approach we use for + the EWS bots. + + Mutating tool._deprecated_port is a bit ugly, but it's what we're doing + currently for the EWS bots. + + * Scripts/webkitpy/tool/commands/queues.py: + (CommitQueue): + (CommitQueue.begin_work_queue): + (CommitQueue.run_command): + * Scripts/webkitpy/tool/commands/queues_unittest.py: + (CommitQueueTest.test_commit_queue): + (mock_run_webkit_patch): + (test_rollout): + (test_rollout_lands): + (test_manual_reject_during_processing): + +2012-07-12 James Simonsen <simonjam@chromium.org> + + [Navigation Timing] Import the W3C Navigation Timing test suite + https://bugs.webkit.org/show_bug.cgi?id=84887 + + Reviewed by Tony Gentilcore. + + * Scripts/import-w3c-performance-wg-tests: Added. + +2012-07-12 Adam Barth <abarth@webkit.org> + + Unreviewed. Nit: git config files use tabs, not spaces. + + * EWSTools/cold-boot.sh: + +2012-07-12 Kwang Yul Seo <skyul@company100.net> + + Unreviewed. Add Dongsung Huang to the list of contributors. He + has submitted over 30 patches on texture mapper, canvas and image decoders. + + * Scripts/webkitpy/common/config/committers.py: + +2012-07-12 Kwang Yul Seo <skyul@company100.net> + + Unreviewed. Change my irc nickname to kseo. + + * Scripts/webkitpy/common/config/committers.py: + +2012-07-12 Dirk Pranke <dpranke@chromium.org> + + webkitpy: clean up logging handlers, lint common.message_pool + https://bugs.webkit.org/show_bug.cgi?id=91152 + + Reviewed by Ojan Vafai. + + The unix implementation of multiprocessing clones any logging + handlers from the parent process into the child; we currently + don't want this behavior in our code, so I was hand-removing the + installed handlers in the child process I knew about. After thinking + about it further, I think it was simpler and safe enough to just + remove all handlers in the child, since the message pool + propagates any message from the child back into the parent. + + We can always change this in the future if it turns out to be an issue. + + I'm also fixing a couple of other lint warnings while I'm at it. + + * Scripts/webkitpy/common/message_pool.py: + (_MessagePool.__exit__): + (_MessagePool._handle_worker_exception): + (_Worker._set_up_logging): + +2012-07-12 Dirk Pranke <dpranke@chromium.org> + + webkitpy: rename manager_worker_broker to message_pool + https://bugs.webkit.org/show_bug.cgi?id=91145 + + Reviewed by Ojan Vafai. + + Since the MessagePool interface is more generic (and simpler) + now and will be reused by test-webkitpy, I'm renaming it and + moving it to webkitpy.common. + + * Scripts/webkitpy/common/message_pool.py: Renamed from Tools/Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py. + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (TestRunInterruptedException.__reduce__): + (Manager._run_tests.worker_factory): + (Manager._run_tests): + * Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py: + +2012-07-12 Dirk Pranke <dpranke@chromium.org> + + nrwt crashes saving the output for a platform-specific expected test reference + https://bugs.webkit.org/show_bug.cgi?id=90872 + + Reviewed by Ojan Vafai. + + The expected output for a test is copied alongside the test + itself in the layout-test-results directory; in other words, for + foo/bar-expected.txt sits alongside foo/bar.html even if we're + actually using platform/mac/foo/bar-expected.txt. + + Unless the test is a reftest, in which case we would copy the + output to platform/mac/foo/bar-expected.html and set a + 'ref_file' parameter in results.json to indicate the path. This + can be useful in the cases where we have multiple references for + a single test or when multiple tests share the same reference. + + We found a bug where we weren't creating platform/mac/foo under + the results directory, and so this wasn't actually working. + However, treating reftests differently seems like a bad thing, + so we should probably be consistent. This change puts the + -expected.html next to the test, and reworks test_result_writer + so that we create directories uniformly and consistently. + + Note that we weren't catching this problem in unit tests because + the MockFileSystem creates a directory automatically if it + doesn't exist; this was done intentionally for convenience, but + is really a bug and should be fixed; see https://bugs.webkit.org/show_bug.cgi?id=91028. + + I have not added additional tests here since fixing that bug + should be sufficient. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (interpret_test_failures): + * Scripts/webkitpy/layout_tests/controllers/manager_unittest.py: + (ResultSummaryTest.test_interpret_test_failures): + * Scripts/webkitpy/layout_tests/controllers/test_result_writer.py: + (write_test_result): + (TestResultWriter._write_binary_file): + (TestResultWriter): + (TestResultWriter._write_text_file): + (TestResultWriter.write_output_files): + (TestResultWriter.write_stderr): + (TestResultWriter.write_crash_log): + (TestResultWriter.create_text_diff_and_write_result): + (TestResultWriter.write_image_diff_files): + (write_reftest): + * Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py: + (EndToEndTest.test_reftest_with_two_notrefs): + +2012-07-12 Dirk Pranke <dpranke@chromium.org> + + nrwt: reimplement manager_worker_broker in a much simpler form + https://bugs.webkit.org/show_bug.cgi?id=90513 + + Reviewed by Ojan Vafai. + + This is a wholesale replacement of the MessagePool() implementation + and the other classes in manager_worker_broker.py. All of the + BrokerConnection*, Broker*, etc. classes are gone, and there are now + just a MessagePool class and a _Worker class. Happiness ensues. + + I'm removing manager_worker_broker_unittest.py as well; we get + nearly complete coverage from the integration tests, and will + get more coverage when test-webkitpy moves to use this as well, + so having unit tests seems like unnecessary overhead. (running + coverage numbers with test-webkitpy shows that pretty much the only + uncovered lines are lines that are only run in the child processes, + which coverage doesn't handle at the moment). + + * Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py: + (_MessagePool.__init__): + (_MessagePool.run): + (_MessagePool._start_workers): + (_MessagePool): + (_MessagePool.wait): + (_MessagePool._close): + (_MessagePool._handle_done): + (_MessagePool._can_pickle): + (_MessagePool._loop): + (WorkerException): + (_Message.__init__): + (_Message.__repr__): + (_Worker): + (_Worker.__init__): + (_Worker.terminate): + (_Worker._close): + (_Worker.run): + (_Worker.post): + (_Worker.yield_to_caller): + (_Worker._post): + (_Worker._raise): + (_Worker._set_up_logging): + (_WorkerLogHandler.__init__): + (_WorkerLogHandler.emit): + * Scripts/webkitpy/layout_tests/controllers/manager_worker_broker_unittest.py: Removed. + +2012-07-12 Tony Chang <tony@chromium.org> + + [chromium] Remove drag and drop API methods that are no longer used + https://bugs.webkit.org/show_bug.cgi?id=90996 + + Reviewed by Adam Barth. + + Migrate DRT to use the methods that take modifier keys. + + * DumpRenderTree/chromium/EventSender.cpp: + (EventSender::doDragDrop): + (EventSender::doMouseUp): + (EventSender::doMouseMove): + (EventSender::beginDragWithFiles): + +2012-07-12 Ojan Vafai <ojan@chromium.org> + + Allow putting ranges in user.py list prompts + https://bugs.webkit.org/show_bug.cgi?id=91115 + + Reviewed by Adam Barth. + + Ranges are inclusive and denoted by a dash. This is useful for rebaselining a whole port + since the items are listed with each port's builders being contiguous. + + * Scripts/webkitpy/common/system/user.py: + (User._wait_on_list_response): + * Scripts/webkitpy/common/system/user_unittest.py: + (UserTest.test_prompt_with_multiple_lists.run_prompt_test): + (UserTest.test_prompt_with_multiple_lists): + +2012-07-12 Arnaud Renevier <arno@renevier.net> + + [GTK] Implement disableImageLoading in DRT + https://bugs.webkit.org/show_bug.cgi?id=87973 + + Reviewed by Martin Robinson. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (resetDefaultsToConsistentValues): + * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp: + (LayoutTestController::disableImageLoading): + +2012-07-12 Simon Hausmann <simon.hausmann@nokia.com> + + [Qt] Internal symbols are exported on Linux + https://bugs.webkit.org/show_bug.cgi?id=90981 + + Reviewed by Jocelyn Turcotte. + + I should've re-enabled ELF symbol visibility when removing the symbol map in + r106650. + + * qmake/mkspecs/features/default_post.prf: + +2012-07-11 Mark Rowe <mrowe@apple.com> + + <http://webkit.org/b/91024> Build against the latest SDK when targeting older OS X versions. + + Reviewed by Dan Bernstein. + + The deployment target is already set to the version that we're targeting, and it's that setting + which determines which functionality from the SDK is available to us. + + * DumpRenderTree/mac/Configurations/Base.xcconfig: + * TestWebKitAPI/Configurations/Base.xcconfig: + * WebKitTestRunner/Configurations/Base.xcconfig: + +2012-07-11 Mark Rowe <mrowe@apple.com> + + Replace definitions of BUILDING_ON / TARGETING macros with macros that will error when used. + + Part of <http://webkit.org/b/91015> Remove BUILDING_ON / TARGETING macros in favor of system availability macros. + + Reviewed by Anders Carlsson. + + * DumpRenderTree/TestNetscapePlugIn/PluginObject.h: Remove the macros completely from here since + they're completely unused in TestNetscapePlugIn. + * DumpRenderTree/config.h: + +2012-07-11 Mark Rowe <mrowe@apple.com> + + <http://webkit.org/b/91015> Remove BUILDING_ON / TARGETING macros in favor of system availability macros + + This removal was handled by a script that translates the relevant macros in to the equivalent checks + using the system availability macros. + + Reviewed by Filip Pizlo. + + * DumpRenderTree/cf/WebArchiveDumpSupport.cpp: + * DumpRenderTree/mac/CheckedMalloc.cpp: + * DumpRenderTree/mac/DumpRenderTree.mm: + * DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm: + * DumpRenderTree/mac/LayoutTestControllerMac.mm: + * DumpRenderTree/mac/TextInputController.m: + * TestWebKitAPI/mac/InjectedBundleControllerMac.mm: + * WebKitTestRunner/InjectedBundle/mac/ActivateFonts.mm: + * WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm: + +2012-07-11 Robert Kroeger <rjkroege@chromium.org> + + Suppress horizontal conversion of PlatformWheelEvents when hasPreciseScrollingDeltas is true + https://bugs.webkit.org/show_bug.cgi?id=89580 + + WebKit GTK and Chromium Linux force vertical wheel events to + scroll horizontally when over horizontal scroll bars. This is + undesirable for touchpad scrolling with + hasPreciseScrollingDeltas() == true. Modified DumpRenderTree to + let a layout test specify this attribute so that the change's impact + on scrolling can be tested in a layout test. + + Reviewed by Adam Barth. + + * DumpRenderTree/chromium/EventSender.cpp: + (EventSender::handleMouseWheel): + +2012-07-11 Simon Fraser <simon.fraser@apple.com> + + Fix the build by declaring -isPaginated before use. + + * MiniBrowser/mac/BrowserWindowController.m: + +2012-07-11 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122358. + http://trac.webkit.org/changeset/122358 + https://bugs.webkit.org/show_bug.cgi?id=91037 + + Build break on WebKit Win (Requested by hayato on #webkit). + + * DumpRenderTree/chromium/EventSender.cpp: + (EventSender::doDragDrop): + (EventSender::doMouseUp): + (EventSender::doMouseMove): + (EventSender::beginDragWithFiles): + +2012-07-03 Dirk Pranke <dpranke@chromium.org> + + nrwt: add a MessagePool abstraction that the manager will call to replace the broker + https://bugs.webkit.org/show_bug.cgi?id=90511 + + Reviewed by Ojan Vafai. + + This change introduces the new MessagePool abstraction that will + replace the classes in manager_worker_broker. It is a minimal + interface that tries to follow the conventions in + multiprocessing.Pool and concurrency.futures ... it provides a + context manager and a run() method that sends N messages to M + workers processes (starting workers as necessary) and waits for + them all to complete, handling cleanup as necessary. The caller + is responsible for providing a handle() method to handle + messages received from the workers. + + This interface basically hides all of the multiprocessing logic from + the manager class. + + The initial implementation of MessagePool is a simple shim + around the existing broker classes; a subsequent change will + replace all the other classes with a much simpler + implementation. + + No additional tests are provided for now; existing tests should + provide adequate coverage, and I will add new unit tests for the + MessagePool class when I replace the existing implementation. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (TestRunInterruptedException.__reduce__): + (Manager.__init__): + (Manager._run_tests): + (Manager._run_tests.instead): + (Manager.handle): + (Manager._handle_started_test): + (Manager._handle_finished_test_list): + (Manager._handle_finished_test): + * Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py: + (get): + (_MessagePool): + (_MessagePool.__init__): + (_MessagePool.__enter__): + (_MessagePool.__exit__): + (_MessagePool.run): + (_MessagePool.wait): + (_MessagePool.is_done): + (_MessagePool._worker_is_done): + (_MessagePool._close): + (_MessagePool.handle_done): + (_MessagePool.handle_started_test): + (_MessagePool.handle_finished_test): + (_MessagePool.handle_finished_test_list): + (_MessagePool.handle_exception): + (_MessagePool._log_messages): + (_MessagePool._handle_worker_exception): + (_WorkerState): + (_WorkerState.for): + (_WorkerState.__init__): + (_WorkerState.__repr__): + (_get_broker): + * Scripts/webkitpy/layout_tests/controllers/manager_worker_broker_unittest.py: + (make_broker): + +2012-07-11 Simon Fraser <simon.fraser@apple.com> + + Add an option to enter paginated mode in MiniBrowser + https://bugs.webkit.org/show_bug.cgi?id=91035 + + Reviewed by Dan Bernstein. + + Add an item to the Debug menu for MiniBrowser that puts + the web view into paginated mode. For now, we only + do left-to-right pagination, with a fixed column width. + + * MiniBrowser/mac/BrowserWindowController.h: + * MiniBrowser/mac/BrowserWindowController.m: + (-[BrowserWindowController validateMenuItem:]): Update the checked + state of the menu item. + (-[BrowserWindowController isPaginated]): Return YES if paginated. + (-[BrowserWindowController togglePaginationMode:]): Toggle in + and out of pagination mode. + * MiniBrowser/mac/MainMenu.xib: Add the debug menu item. + +2012-07-11 Adam Barth <abarth@webkit.org> + + commit-queue instances on Compute Engine are missing git-svn + https://bugs.webkit.org/show_bug.cgi?id=91034 + + Reviewed by Eric Seidel. + + git-svn is needed to actually commit to SVN from a git working copy. + + * EWSTools/cold-boot.sh: + +2012-07-11 Dirk Pranke <dpranke@chromium.org> + + webkitpy: lint code in webkitpy.layout_tests.models + https://bugs.webkit.org/show_bug.cgi?id=90416 + + Reviewed by Ojan Vafai. + + Cleaning up errors reported from lint-webkitpy. + + Also, suppress the warnings about wildcard imports in pylintrc; + we have nothing particularly against them. + + * Scripts/webkitpy/layout_tests/models/test_configuration.py: + (TestConfigurationConverter.combinations): + * Scripts/webkitpy/layout_tests/models/test_configuration_unittest.py: + (TestConfigurationTest.test_hash.query_unknown_key): + (TestConfigurationTest.test_eq): + * Scripts/webkitpy/layout_tests/models/test_expectations.py: + (ParseError.__init__): + (TestExpectationLine.__init__): + (TestExpectationsModel.get_expectations_string): + (TestExpectationsModel): + (TestExpectationsModel.expectation_to_string): + (TestExpectationsModel.add_expectation_line): + (TestExpectationsModel._clear_expectations_for_test): + (TestExpectationsModel._remove_from_sets): + (TestExpectations.get_expectations_string): + (TestExpectations.expectation_to_string): + (TestExpectations._report_warnings): + * Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py: + (Base.__init__): + (parse_exp): + (SkippedTests.check): + (TestExpectationParserTests.test_parse_empty_string): + * Scripts/webkitpy/layout_tests/models/test_failures.py: + (FailureTimeout.__init__): + (FailureCrash.__init__): + (FailureImageHashMismatch.__init__): + (FailureReftestMismatch.__init__): + (FailureReftestMismatchDidNotOccur.__init__): + (FailureReftestNoImagesGenerated.__init__): + * Scripts/webkitpy/layout_tests/models/test_failures_unittest.py: + (TestFailuresTest.test_unknown_failure_type.UnknownFailure.message): + (TestFailuresTest.test_unknown_failure_type): + (TestFailuresTest): + (TestFailuresTest.test_message_is_virtual): + * Scripts/webkitpy/layout_tests/models/test_results.py: + (TestResult.loads): + (TestResult.has_failure_matching_types): + * Scripts/webkitpy/pylintrc: + +2012-07-11 Dirk Pranke <dpranke@chromium.org> + + nrwt: clean up names in worker.py + https://bugs.webkit.org/show_bug.cgi?id=90510 + + Reviewed by Ojan Vafai. + + This is the last patch in the series of refactoring worker.py; + all this does is change some names of methods, instance + variables, and method parameters to be clearer (it also changes + some code in manager.py and manager_worker.py to be consistent). + + There are no functional changes in this patch and the existing + tests should cover everything. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager.__init__): + (Manager.prepare_lists_and_print_output): + (Manager._run_tests.worker_factory): + (Manager._run_tests): + (Manager._show_results_html_file): + (Manager.handle_finished_test_list): + (_WorkerState.__init__): + * Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py: + (_Broker.post_message): + (_Broker._dispatch_message): + (AbstractWorker.__init__): + (AbstractWorker.run): + (AbstractWorker.yield_to_caller): + (AbstractWorker.post): + (_WorkerConnection.__init__): + * Scripts/webkitpy/layout_tests/controllers/manager_worker_broker_unittest.py: + (_TestWorker.__init__): + (_TestWorker.start): + (_TestWorker.handle): + (_TestWorker.stop): + (_TestsMixin): + (_TestsMixin.test_name): + * Scripts/webkitpy/layout_tests/controllers/worker.py: + (Worker.__init__): + (Worker.__del__): + (Worker.start): + (Worker.handle): + (Worker._run_test): + (Worker.stop): + (Worker._timeout): + (Worker._kill_driver): + (Worker._run_test_with_timeout): + (Worker._clean_up_after_test): + (Worker._run_test_in_another_thread.SingleTestThread.run): + (Worker._run_test_in_this_thread): + (Worker._run_single_test): + +2012-07-11 Adam Barth <abarth@webkit.org> + + The commit-queue needs some extra git config to be able to commit + https://bugs.webkit.org/show_bug.cgi?id=91025 + + Reviewed by Eric Seidel. + + In order for the commit-queue to actually commit, it needs to know the + location of the SVN server. + + * EWSTools/cold-boot.sh: + +2012-07-11 Adam Barth <abarth@webkit.org> + + Teach EWSTools how to configure SVN auth credentials + https://bugs.webkit.org/show_bug.cgi?id=91021 + + Reviewed by Eric Seidel. + + To move the commit-queue over to Google Compute Engine, we need a way + to configure the commit-queue's credentials during the machine build + process. There doesn't seem to be a nice command line way of + configuring SVN auth credentials. I tried doing a bogus commit and + supplying the credentials that way, but that's super hacky. + + The approach in this patch is to write the config file directly. The + format of these configurations files is documented in the SVN book, so + this approach doesn't see too sketchy. + + * EWSTools/configure-svn-auth.sh: Added. + +2012-07-11 Ojan Vafai <ojan@chromium.org> + + Dedupe suffixes passed to webkit-patch rebaseline + https://bugs.webkit.org/show_bug.cgi?id=91017 + + Reviewed by Dirk Pranke. + + * Scripts/webkitpy/tool/commands/rebaseline.py: + (Rebaseline._suffixes_to_update): + * Scripts/webkitpy/tool/commands/rebaseline_unittest.py: + (test_rebaseline_multiple_builders_and_tests_command_line): + +2012-07-11 Kevin Ollivier <kevino@theolliviers.com> + + [wx] Unreviewed build fix. Add new directories and a new LayoutTestController method. + + * DumpRenderTree/wx/LayoutTestControllerWx.cpp: + (LayoutTestController::setStorageDatabaseIdleInterval): + * waf/build/settings.py: + +2012-07-11 Tony Chang <tony@chromium.org> + + [chromium] Remove drag and drop API methods that are no longer used + https://bugs.webkit.org/show_bug.cgi?id=90996 + + Reviewed by Adam Barth. + + Migrate DRT to use the methods that take modifier keys. + + * DumpRenderTree/chromium/EventSender.cpp: + (EventSender::doDragDrop): + (EventSender::doMouseUp): + (EventSender::doMouseMove): + (EventSender::beginDragWithFiles): + +2012-07-11 Mark Rowe <mrowe@apple.com> + + Add a Mountain Lion version of libWebKitSystemInterface.a. + + Reviewed by John Sullivan. + + * Scripts/copy-webkitlibraries-to-product-directory: Include libWebKitSystemInterfaceMountainLion.a in the list of libraries to copy. + +2012-07-09 Mark Rowe <mrowe@apple.com> + + <http://webkit.org/b/90835> Teach bisect-builds to work with a Safari.app that has entitlements. + + Reviewed by Dan Bernstein. + + * Scripts/bisect-builds: Use safariPathFromSafariBundle to determine which binary within the application + should be invoked. + +2012-07-11 Zan Dobersek <zandobersek@gmail.com> + + [Gtk] fast/events/keydown-function-keys.html is failing + https://bugs.webkit.org/show_bug.cgi?id=90891 + + Reviewed by Martin Robinson. + + Work around the context menu being shown on F10 key being pressed by + unbiding the key when running tests in DumpRenderTree. The problem + appears when using a recent version of the xkeyboard-config package. + + * DumpRenderTree/gtk/DumpRenderTree.cpp: + (setDefaultsToConsistentStateValuesForTesting): + +2012-07-11 No'am Rosenthal <noam.rosenthal@nokia.com> + + [Qt] QRawWebView should notify when rendering is done, so that pixel results can be grabbed at the appropriate moment. + https://bugs.webkit.org/show_bug.cgi?id=90641 + + Reviewed by Jocelyn Turcotte. + + * MiniBrowser/qt/raw/View.h: Comment used old class name (WKView). + (View): + +2012-07-11 Min Qin <qinmin@chromium.org> + + [Android] sending an extra to the DRT apk so that DRT can be run in a seperate thread + https://bugs.webkit.org/show_bug.cgi?id=90831 + + Reviewed by Adam Barth. + + On android, DRT needs to run in a background thread to avoid ANR. + However, the java tests are running on UI thread by default. + We need to send an intent extra to the apk so that it can run on a sub thread. + + * Scripts/webkitpy/layout_tests/port/chromium_android.py: + (ChromiumAndroidDriver._start_once): + +2012-07-11 Csaba Osztrogonác <ossy@webkit.org> + + [Qt] REGRESSION(r107171): Fix --timeout option of Qt's DRT + https://bugs.webkit.org/show_bug.cgi?id=90966 + + Reviewed by Ryosuke Niwa. + + * DumpRenderTree/qt/main.cpp: + (main): Don't remove the argument, because takeOptionValue() did it before. + 2012-07-11 Allan Sandfeld Jensen <allan.jensen@nokia.com> First commit; moving myself to commiters. diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h index 566537c2e..98f183951 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h @@ -29,14 +29,6 @@ #include <WebKit/npfunctions.h> #include <stdarg.h> -#if defined(XP_MACOSX) -#if !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 -#define BUILDING_ON_LEOPARD 1 -#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 -#define BUILDING_ON_SNOW_LEOPARD 1 -#endif -#endif // XP_MACOSX - class PluginTest; extern NPNetscapeFuncs *browser; diff --git a/Tools/DumpRenderTree/cf/WebArchiveDumpSupport.cpp b/Tools/DumpRenderTree/cf/WebArchiveDumpSupport.cpp index 33dc28a4c..1f7f172ab 100644 --- a/Tools/DumpRenderTree/cf/WebArchiveDumpSupport.cpp +++ b/Tools/DumpRenderTree/cf/WebArchiveDumpSupport.cpp @@ -44,7 +44,7 @@ CFTypeID CFURLResponseGetTypeID(void); static void convertMIMEType(CFMutableStringRef mimeType) { -#ifdef BUILDING_ON_LEOPARD +#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1050 // Workaround for <rdar://problem/5539824> on Leopard if (CFStringCompare(mimeType, CFSTR("text/xml"), kCFCompareAnchored | kCFCompareCaseInsensitive) == kCFCompareEqualTo) CFStringReplaceAll(mimeType, CFSTR("application/xml")); @@ -158,7 +158,7 @@ CFStringRef createXMLStringFromWebArchiveData(CFDataRef webArchiveData) CFErrorRef error = 0; CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0; -#ifdef BUILDING_ON_LEOPARD +#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1050 CFIndex bytesCount = CFDataGetLength(webArchiveData); RetainPtr<CFReadStreamRef> readStream(AdoptCF, CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(webArchiveData), bytesCount, kCFAllocatorNull)); CFReadStreamOpen(readStream.get()); @@ -208,7 +208,7 @@ CFStringRef createXMLStringFromWebArchiveData(CFDataRef webArchiveData) error = 0; -#ifdef BUILDING_ON_LEOPARD +#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1050 RetainPtr<CFDataRef> xmlData(AdoptCF, CFPropertyListCreateXMLData(kCFAllocatorDefault, propertyList.get())); #else RetainPtr<CFDataRef> xmlData(AdoptCF, CFPropertyListCreateData(kCFAllocatorDefault, propertyList.get(), kCFPropertyListXMLFormat_v1_0, 0, &error)); diff --git a/Tools/DumpRenderTree/chromium/EventSender.cpp b/Tools/DumpRenderTree/chromium/EventSender.cpp index 47bec2a71..7e81f3b54 100644 --- a/Tools/DumpRenderTree/chromium/EventSender.cpp +++ b/Tools/DumpRenderTree/chromium/EventSender.cpp @@ -351,7 +351,7 @@ void EventSender::doDragDrop(const WebDragData& dragData, WebDragOperationsMask WebPoint screenPoint(event.globalX, event.globalY); currentDragData = dragData; currentDragEffectsAllowed = mask; - currentDragEffect = webview()->dragTargetDragEnter(dragData, clientPoint, screenPoint, currentDragEffectsAllowed); + currentDragEffect = webview()->dragTargetDragEnter(dragData, clientPoint, screenPoint, currentDragEffectsAllowed, 0); // Finish processing events. replaySavedEvents(); @@ -466,9 +466,9 @@ void EventSender::doMouseUp(const WebMouseEvent& e) WebPoint clientPoint(e.x, e.y); WebPoint screenPoint(e.globalX, e.globalY); - currentDragEffect = webview()->dragTargetDragOver(clientPoint, screenPoint, currentDragEffectsAllowed); + currentDragEffect = webview()->dragTargetDragOver(clientPoint, screenPoint, currentDragEffectsAllowed, 0); if (currentDragEffect) - webview()->dragTargetDrop(clientPoint, screenPoint); + webview()->dragTargetDrop(clientPoint, screenPoint, 0); else webview()->dragTargetDragLeave(); webview()->dragSourceEndedAt(clientPoint, screenPoint, currentDragEffect); @@ -509,7 +509,7 @@ void EventSender::doMouseMove(const WebMouseEvent& e) return; WebPoint clientPoint(e.x, e.y); WebPoint screenPoint(e.globalX, e.globalY); - currentDragEffect = webview()->dragTargetDragOver(clientPoint, screenPoint, currentDragEffectsAllowed); + currentDragEffect = webview()->dragTargetDragOver(clientPoint, screenPoint, currentDragEffectsAllowed, 0); } void EventSender::keyDown(const CppArgumentList& arguments, CppVariant* result) @@ -912,7 +912,7 @@ void EventSender::beginDragWithFiles(const CppArgumentList& arguments, CppVarian currentDragEffectsAllowed = WebKit::WebDragOperationCopy; // Provide a drag source. - webview()->dragTargetDragEnter(currentDragData, lastMousePos, lastMousePos, currentDragEffectsAllowed); + webview()->dragTargetDragEnter(currentDragData, lastMousePos, lastMousePos, currentDragEffectsAllowed, 0); // dragMode saves events and then replays them later. We don't need/want that. dragMode.set(false); @@ -1043,10 +1043,14 @@ void EventSender::handleMouseWheel(const CppArgumentList& arguments, CppVariant* int horizontal = arguments[0].toInt32(); int vertical = arguments[1].toInt32(); int paged = false; + int hasPreciseScrollingDeltas = false; if (arguments.size() > 2 && arguments[2].isBool()) paged = arguments[2].toBoolean(); + if (arguments.size() > 3 && arguments[3].isBool()) + hasPreciseScrollingDeltas = arguments[3].toBoolean(); + WebMouseWheelEvent event; initMouseEvent(WebInputEvent::MouseWheel, pressedButton, lastMousePos, &event); event.wheelTicksX = static_cast<float>(horizontal); @@ -1054,6 +1058,8 @@ void EventSender::handleMouseWheel(const CppArgumentList& arguments, CppVariant* event.deltaX = event.wheelTicksX; event.deltaY = event.wheelTicksY; event.scrollByPage = paged; + event.hasPreciseScrollingDeltas = hasPreciseScrollingDeltas; + if (continuous) { event.wheelTicksX /= scrollbarPixelsPerTick; event.wheelTicksY /= scrollbarPixelsPerTick; diff --git a/Tools/DumpRenderTree/config.h b/Tools/DumpRenderTree/config.h index d52cd84de..ccff71c7c 100644 --- a/Tools/DumpRenderTree/config.h +++ b/Tools/DumpRenderTree/config.h @@ -50,11 +50,19 @@ #if PLATFORM(MAC) #define WTF_USE_CF 1 -#if !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 -#define BUILDING_ON_LEOPARD 1 -#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 -#define BUILDING_ON_SNOW_LEOPARD 1 -#endif +// FIXME: These can be removed after sufficient time has passed since the removal of BUILDING_ON / TARGETING macros. + +#define ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MIN_REQUIRED 0 / 0 +#define ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MAX_ALLOWED 0 / 0 + +#define BUILDING_ON_LEOPARD ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MIN_REQUIRED +#define BUILDING_ON_SNOW_LEOPARD ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MIN_REQUIRED +#define BUILDING_ON_LION ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MIN_REQUIRED + +#define TARGETING_LEOPARD ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MAX_ALLOWED +#define TARGETING_SNOW_LEOPARD ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MAX_ALLOWED +#define TARGETING_LION ERROR_PLEASE_COMPARE_WITH_MAC_OS_X_VERSION_MAX_ALLOWED + #endif // PLATFORM(MAC) #if OS(WINDOWS) diff --git a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp index 8e3c44ec3..57cd05917 100644 --- a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -464,6 +464,7 @@ static void resetDefaultsToConsistentValues() "enable-caret-browsing", FALSE, "enable-page-cache", FALSE, "auto-resize-window", TRUE, + "auto-load-images", TRUE, "enable-java-applet", FALSE, "enable-plugins", TRUE, "enable-hyperlink-auditing", FALSE, @@ -663,8 +664,12 @@ static void setDefaultsToConsistentStateValuesForTesting() #else GtkCssProvider* cssProvider = gtk_css_provider_new(); gtk_css_provider_load_from_data(cssProvider, + "@binding-set NoKeyboardNavigation { " + " unbind \"<shift>F10\"; " + "} " " * { " " -GtkScrolledWindow-scrollbar-spacing: 0;" + " gtk-key-bindings: NoKeyboardNavigation; " "} ", -1, 0); gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()), diff --git a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index 2eb899d61..4662df021 100644 --- a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -449,8 +449,11 @@ void LayoutTestController::setAutofilled(JSContextRef context, JSValueRef nodeOb void LayoutTestController::disableImageLoading() { - // FIXME: Implement for testing fix for https://bugs.webkit.org/show_bug.cgi?id=27896 - // Also need to make sure image loading is re-enabled for each new test. + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + ASSERT(view); + + WebKitWebSettings* settings = webkit_web_view_get_settings(view); + g_object_set(G_OBJECT(settings), "auto-load-images", FALSE, NULL); } void LayoutTestController::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma) diff --git a/Tools/DumpRenderTree/mac/CheckedMalloc.cpp b/Tools/DumpRenderTree/mac/CheckedMalloc.cpp index 8bd53e546..b56cb280d 100644 --- a/Tools/DumpRenderTree/mac/CheckedMalloc.cpp +++ b/Tools/DumpRenderTree/mac/CheckedMalloc.cpp @@ -54,7 +54,7 @@ static void* checkedRealloc(malloc_zone_t* zone, void* ptr, size_t size) return savedRealloc(zone, ptr, size); } -#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 static vm_prot_t protectionOfRegion(mach_vm_address_t address) { mach_vm_size_t regionSize = 0; @@ -71,7 +71,7 @@ void makeLargeMallocFailSilently() { malloc_zone_t* zone = malloc_default_zone(); -#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 mach_vm_address_t pageStart = reinterpret_cast<vm_address_t>(zone) & static_cast<vm_size_t>(~(getpagesize() - 1)); vm_prot_t initialProtection = protectionOfRegion(pageStart); @@ -85,7 +85,7 @@ void makeLargeMallocFailSilently() zone->malloc = checkedMalloc; zone->realloc = checkedRealloc; -#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 if (mach_vm_protect(mach_task_self(), pageStart, len, 0, initialProtection)) CRASH(); #endif diff --git a/Tools/DumpRenderTree/mac/Configurations/Base.xcconfig b/Tools/DumpRenderTree/mac/Configurations/Base.xcconfig index 8180cabdd..b6fe75a3f 100644 --- a/Tools/DumpRenderTree/mac/Configurations/Base.xcconfig +++ b/Tools/DumpRenderTree/mac/Configurations/Base.xcconfig @@ -55,15 +55,12 @@ REAL_PLATFORM_NAME_macosx = macosx; TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); -// If the target Mac OS X version does not match the current Mac OS X version then we'll want to build using the target version's SDK. -SDKROOT = $(SDKROOT_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -SDKROOT_1060_1050 = macosx10.5; -SDKROOT_1070_1050 = macosx10.5; -SDKROOT_1080_1050 = macosx10.5; -SDKROOT_1090_1050 = macosx10.5; -SDKROOT_1070_1060 = macosx10.6; -SDKROOT_1080_1060 = macosx10.6; -SDKROOT_1090_1060 = macosx10.6; -SDKROOT_1080_1070 = macosx10.7; -SDKROOT_1090_1070 = macosx10.7; -SDKROOT_1090_1080 = macosx10.8; +TARGETING_SAME_OS_X_VERSION = $(TARGETING_SAME_OS_X_VERSION_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +TARGETING_SAME_OS_X_VERSION_1060_1060 = YES; +TARGETING_SAME_OS_X_VERSION_1070_1070 = YES; +TARGETING_SAME_OS_X_VERSION_1080_1080 = YES; +TARGETING_SAME_OS_X_VERSION_1090_1090 = YES; + +// Don't build against an SDK unless we're targeting an older OS version. +SDKROOT = $(SDKROOT_TARGETING_SAME_OS_X_VERSION_$(TARGETING_SAME_OS_X_VERSION)); +SDKROOT_TARGETING_SAME_OS_X_VERSION_ = macosx; diff --git a/Tools/DumpRenderTree/mac/DumpRenderTree.mm b/Tools/DumpRenderTree/mac/DumpRenderTree.mm index dd0eff44b..abba535ed 100644 --- a/Tools/DumpRenderTree/mac/DumpRenderTree.mm +++ b/Tools/DumpRenderTree/mac/DumpRenderTree.mm @@ -418,7 +418,7 @@ static void activateTestingFonts() "WebKitWeightWatcher700.ttf", "WebKitWeightWatcher800.ttf", "WebKitWeightWatcher900.ttf", -#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 "SampleFont.sfont", #endif 0 @@ -590,7 +590,7 @@ static void resetDefaultsToConsistentValues() #endif -#if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) && !PLATFORM(CHROMIUM) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !PLATFORM(CHROMIUM) [defaults setBool:NO forKey:@"NSScrollAnimationEnabled"]; #else [defaults setBool:NO forKey:@"AppleScrollAnimationEnabled"]; @@ -655,7 +655,7 @@ static void resetDefaultsToConsistentValues() // So, turn it off for now, but we might want to turn it back on some day. [preferences setUsesPageCache:NO]; [preferences setAcceleratedCompositingEnabled:YES]; -#if USE(CA) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if USE(CA) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 [preferences setCanvasUsesAcceleratedDrawing:YES]; [preferences setAcceleratedDrawingEnabled:NO]; #endif diff --git a/Tools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm b/Tools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm index b729cf406..b6b22c269 100644 --- a/Tools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm +++ b/Tools/DumpRenderTree/mac/DumpRenderTreeDraggingInfo.mm @@ -105,7 +105,7 @@ return nil; } -#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 - (NSDraggingFormation)draggingFormation { return NSDraggingFormationDefault; @@ -140,7 +140,7 @@ { // Ignored. } -#endif // !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 @end diff --git a/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm index f360c061a..54f87546e 100644 --- a/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm +++ b/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm @@ -1031,7 +1031,7 @@ void LayoutTestController::setWebViewEditable(bool editable) static NSString *SynchronousLoaderRunLoopMode = @"DumpRenderTreeSynchronousLoaderRunLoopMode"; -#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) +#if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1060 @protocol NSURLConnectionDelegate <NSObject> @end #endif @@ -1107,7 +1107,7 @@ static NSString *SynchronousLoaderRunLoopMode = @"DumpRenderTreeSynchronousLoade void LayoutTestController::authenticateSession(JSStringRef url, JSStringRef username, JSStringRef password) { // See <rdar://problem/7880699>. -#ifndef BUILDING_ON_LEOPARD +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 RetainPtr<CFStringRef> urlStringCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url)); RetainPtr<CFStringRef> usernameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, username)); RetainPtr<CFStringRef> passwordCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, password)); @@ -1135,7 +1135,7 @@ void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval) void LayoutTestController::setTextDirection(JSStringRef directionName) { -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 if (JSStringIsEqualToUTF8CString(directionName, "ltr")) [[mainFrame webView] makeBaseWritingDirectionLeftToRight:0]; else if (JSStringIsEqualToUTF8CString(directionName, "rtl")) diff --git a/Tools/DumpRenderTree/mac/TextInputController.m b/Tools/DumpRenderTree/mac/TextInputController.m index afeb16e4d..91dbd84a1 100644 --- a/Tools/DumpRenderTree/mac/TextInputController.m +++ b/Tools/DumpRenderTree/mac/TextInputController.m @@ -31,7 +31,7 @@ #import "DumpRenderTreeMac.h" #import <AppKit/NSInputManager.h> -#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 #define SUPPORT_DICTATION_ALTERNATIVES #import <AppKit/NSTextAlternatives.h> #endif diff --git a/Tools/DumpRenderTree/qt/main.cpp b/Tools/DumpRenderTree/qt/main.cpp index 3125d61bc..8188f1816 100644 --- a/Tools/DumpRenderTree/qt/main.cpp +++ b/Tools/DumpRenderTree/qt/main.cpp @@ -220,7 +220,6 @@ int main(int argc, char* argv[]) if (index != -1) { int timeout = takeOptionValue(args, index).toInt(); dumper.setTimeout(timeout); - args.removeAt(index); } index = args.indexOf(QLatin1String("--no-timeout")); diff --git a/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp index 5935eab25..1470e95fb 100644 --- a/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp +++ b/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp @@ -639,3 +639,8 @@ void LayoutTestController::deliverWebIntent(JSStringRef, JSStringRef, JSStringRe { // FIXME: Implement this. } + +void LayoutTestController::setStorageDatabaseIdleInterval(double) +{ + // FIXME: Implement this. +} diff --git a/Tools/EWSTools/GoogleComputeEngine/build-commit-queue.sh b/Tools/EWSTools/GoogleComputeEngine/build-commit-queue.sh new file mode 100755 index 000000000..a94b02083 --- /dev/null +++ b/Tools/EWSTools/GoogleComputeEngine/build-commit-queue.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# Copyright (c) 2012 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +if [[ $# -ne 1 ]];then +echo "Usage: build-commit-queue.sh BOT_NUMBER" +exit 1 +fi + +QUEUE_TYPE=commit-queue +BOT_ID=gce-cq-$1 +BUGZILLA_USERNAME=webkit.review.bot@gmail.com +read -s -p "Bugzilla Password: " BUGZILLA_PASSWORD && echo + +SVN_USERNAME=commit-queue@webkit.org +read -s -p "Subversion Password: " SVN_PASSWORD && echo + +# FIXME: We should use gcutil to find a zone that's actually up. +ZONE=us-east-b +IMAGE=projects/google/images/ubuntu-10-04-v20120621 + +gcutil addinstance $BOT_ID --machine_type=standard-4-cpu-ephemeral-disk --image=$IMAGE --zone=$ZONE --wait_until_running + +echo "Sleeping for 30s to let the server spin up ssh..." +sleep 30 + +gcutil ssh $BOT_ID "sudo apt-get install subversion -y && svn checkout http://svn.webkit.org/repository/webkit/trunk/Tools/EWSTools tools && cd tools && bash configure-svn-auth.sh $SVN_USERNAME $SVN_PASSWORD && bash cold-boot.sh $QUEUE_TYPE $BOT_ID $BUGZILLA_USERNAME $BUGZILLA_PASSWORD" diff --git a/Tools/EWSTools/cold-boot.sh b/Tools/EWSTools/cold-boot.sh index 5cf625840..98f9fea13 100755 --- a/Tools/EWSTools/cold-boot.sh +++ b/Tools/EWSTools/cold-boot.sh @@ -49,7 +49,7 @@ echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select tr curl http://src.chromium.org/svn/trunk/src/build/install-build-deps.sh > install-build-deps.sh bash install-build-deps.sh --no-prompt -sudo apt-get install xvfb screen zip -y +sudo apt-get install xvfb screen git-svn zip -y # install-build-deps.sh will install flashplugin-installer, which causes some plug-in tests to crash. sudo apt-get remove flashplugin-installer -y @@ -70,6 +70,19 @@ cat >> .git/config <<EOF password = $4 EOF +if [[ $1 == "commit-queue" ]];then +cat >> .git/config <<EOF +[svn-remote "svn"] + url = http://svn.webkit.org/repository/webkit + fetch = trunk:refs/remotes/origin/master +[user] + email = commit-queue@webkit.org + name = Commit Queue +[merge "changelog"] + driver = perl $PWD/Tools/Scripts/resolve-ChangeLogs --merge-driver %O %B %A +EOF +fi + cd ~/tools echo "screen -t kr ./start-queue.sh" $1 $2 > screen-config bash boot.sh diff --git a/Tools/EWSTools/configure-svn-auth.sh b/Tools/EWSTools/configure-svn-auth.sh new file mode 100755 index 000000000..75fdc2c05 --- /dev/null +++ b/Tools/EWSTools/configure-svn-auth.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# Copyright (c) 2012 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +if [[ $# -ne 2 ]];then +echo "Usage: configure-svn-auth.sh SVN_USERNAME SVN_PASSWORD" +exit 1 +fi + +cat >> ~/.subversion/auth/svn.simple/7e01475a87eb5db3b8b41e7fbf6415d9 <<EOF +K 8 +passtype +V 6 +simple +K 8 +password +V ${#2} +$2 +K 15 +svn:realmstring +V 39 +<http://svn.webkit.org:80> Mac OS Forge +K 8 +username +V ${#1} +$1 +END +EOF + +# This maches the ACL that subversion uses by default. +chmod 644 ~/.subversion/auth/svn.simple/7e01475a87eb5db3b8b41e7fbf6415d9 diff --git a/Tools/MiniBrowser/Configurations/Base.xcconfig b/Tools/MiniBrowser/Configurations/Base.xcconfig index eb3a4d2ce..85d987d39 100644 --- a/Tools/MiniBrowser/Configurations/Base.xcconfig +++ b/Tools/MiniBrowser/Configurations/Base.xcconfig @@ -50,15 +50,12 @@ REAL_PLATFORM_NAME_macosx = macosx; TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); -// If the target Mac OS X version does not match the current Mac OS X version then we'll want to build using the target version's SDK. -SDKROOT = $(SDKROOT_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -SDKROOT_1060_1050 = macosx10.5; -SDKROOT_1070_1050 = macosx10.5; -SDKROOT_1080_1050 = macosx10.5; -SDKROOT_1090_1050 = macosx10.5; -SDKROOT_1070_1060 = macosx10.6; -SDKROOT_1080_1060 = macosx10.6; -SDKROOT_1090_1060 = macosx10.6; -SDKROOT_1080_1070 = macosx10.7; -SDKROOT_1090_1070 = macosx10.7; -SDKROOT_1090_1080 = macosx10.8; +TARGETING_SAME_OS_X_VERSION = $(TARGETING_SAME_OS_X_VERSION_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +TARGETING_SAME_OS_X_VERSION_1060_1060 = YES; +TARGETING_SAME_OS_X_VERSION_1070_1070 = YES; +TARGETING_SAME_OS_X_VERSION_1080_1080 = YES; +TARGETING_SAME_OS_X_VERSION_1090_1090 = YES; + +// Don't build against an SDK unless we're targeting an older OS version. +SDKROOT = $(SDKROOT_TARGETING_SAME_OS_X_VERSION_$(TARGETING_SAME_OS_X_VERSION)); +SDKROOT_TARGETING_SAME_OS_X_VERSION_ = macosx; diff --git a/Tools/MiniBrowser/mac/BrowserWindowController.h b/Tools/MiniBrowser/mac/BrowserWindowController.h index ddc195084..84c9f0afe 100644 --- a/Tools/MiniBrowser/mac/BrowserWindowController.h +++ b/Tools/MiniBrowser/mac/BrowserWindowController.h @@ -60,6 +60,7 @@ - (BOOL)canResetZoom; - (IBAction)toggleZoomMode:(id)sender; +- (IBAction)togglePaginationMode:(id)sender; - (IBAction)dumpSourceToConsole:(id)sender; diff --git a/Tools/MiniBrowser/mac/BrowserWindowController.m b/Tools/MiniBrowser/mac/BrowserWindowController.m index 5d465f6cf..72d37beac 100644 --- a/Tools/MiniBrowser/mac/BrowserWindowController.m +++ b/Tools/MiniBrowser/mac/BrowserWindowController.m @@ -40,6 +40,7 @@ - (void)didFailProvisionalLoadWithErrorForFrame:(WKFrameRef)frame; - (void)didFailLoadWithErrorForFrame:(WKFrameRef)frame; - (void)didSameDocumentNavigationForFrame:(WKFrameRef)frame; +- (BOOL)isPaginated; @end @implementation BrowserWindowController @@ -109,6 +110,9 @@ [menuItem setTitle:[_webView window] ? @"Remove Web View" : @"Insert Web View"]; else if (action == @selector(toggleZoomMode:)) [menuItem setState:_zoomTextOnly ? NSOnState : NSOffState]; + else if ([menuItem action] == @selector(togglePaginationMode:)) + [menuItem setState:[self isPaginated] ? NSOnState : NSOffState]; + return YES; } @@ -242,6 +246,22 @@ } } +- (BOOL)isPaginated +{ + return WKPageGetPaginationMode(_webView.pageRef) != kWKPaginationModeUnpaginated; +} + +- (IBAction)togglePaginationMode:(id)sender +{ + if ([self isPaginated]) + WKPageSetPaginationMode(_webView.pageRef, kWKPaginationModeUnpaginated); + else { + WKPageSetPaginationMode(_webView.pageRef, kWKPaginationModeLeftToRight); + WKPageSetPageLength(_webView.pageRef, _webView.bounds.size.width / 2); + WKPageSetGapBetweenPages(_webView.pageRef, 10); + } +} + - (IBAction)dumpSourceToConsole:(id)sender { WKPageGetSourceForFrame_b(_webView.pageRef, WKPageGetMainFrame(_webView.pageRef), ^(WKStringRef result, WKErrorRef error) { diff --git a/Tools/MiniBrowser/mac/MainMenu.xib b/Tools/MiniBrowser/mac/MainMenu.xib index 634f615b4..b6939956d 100644 --- a/Tools/MiniBrowser/mac/MainMenu.xib +++ b/Tools/MiniBrowser/mac/MainMenu.xib @@ -1,31 +1,28 @@ <?xml version="1.0" encoding="UTF-8"?> <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10"> <data> - <int key="IBDocument.SystemTarget">1060</int> - <string key="IBDocument.SystemVersion">10F569</string> - <string key="IBDocument.InterfaceBuilderVersion">788</string> - <string key="IBDocument.AppKitVersion">1038.29</string> - <string key="IBDocument.HIToolboxVersion">461.00</string> + <int key="IBDocument.SystemTarget">1080</int> + <string key="IBDocument.SystemVersion">12A265</string> + <string key="IBDocument.InterfaceBuilderVersion">2816</string> + <string key="IBDocument.AppKitVersion">1186</string> + <string key="IBDocument.HIToolboxVersion">624.00</string> <object class="NSMutableDictionary" key="IBDocument.PluginVersions"> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="NS.object.0">788</string> + <string key="NS.object.0">2816</string> </object> - <object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> + <object class="NSArray" key="IBDocument.IntegratedClassDependencies"> <bool key="EncodedWithXMLCoder">YES</bool> - <integer value="535"/> + <string>NSCustomObject</string> + <string>NSMenu</string> + <string>NSMenuItem</string> </object> <object class="NSArray" key="IBDocument.PluginDependencies"> <bool key="EncodedWithXMLCoder">YES</bool> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> </object> <object class="NSMutableDictionary" key="IBDocument.Metadata"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSArray" key="dict.sortedKeys" id="0"> - <bool key="EncodedWithXMLCoder">YES</bool> - </object> - <object class="NSMutableArray" key="dict.values"> - <bool key="EncodedWithXMLCoder">YES</bool> - </object> + <string key="NS.key.0">PluginDependencyRecalculationVersion</string> + <integer value="1" key="NS.object.0"/> </object> <object class="NSMutableArray" key="IBDocument.RootObjects" id="1048"> <bool key="EncodedWithXMLCoder">YES</bool> @@ -919,6 +916,24 @@ <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> + <object class="NSMenuItem" id="15772092"> + <reference key="NSMenu" ref="865232259"/> + <string key="NSTitle">Paginated Mode</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="35465992"/> + <reference key="NSMixedImage" ref="502551668"/> + </object> + <object class="NSMenuItem" id="624939128"> + <reference key="NSMenu" ref="865232259"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="35465992"/> + <reference key="NSMixedImage" ref="502551668"/> + </object> <object class="NSMenuItem" id="208343368"> <reference key="NSMenu" ref="865232259"/> <string key="NSTitle">Show Statistics Window</string> @@ -1004,6 +1019,30 @@ <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> + <string key="label">terminate:</string> + <reference key="source" ref="1050"/> + <reference key="destination" ref="632727374"/> + </object> + <int key="connectionID">449</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">orderFrontStandardAboutPanel:</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="238522557"/> + </object> + <int key="connectionID">142</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">delegate</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="976324537"/> + </object> + <int key="connectionID">495</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> <string key="label">performMiniaturize:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="1011231497"/> @@ -1044,14 +1083,6 @@ </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> - <string key="label">orderFrontStandardAboutPanel:</string> - <reference key="source" ref="1021"/> - <reference key="destination" ref="238522557"/> - </object> - <int key="connectionID">142</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> <string key="label">performClose:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="776162233"/> @@ -1284,14 +1315,6 @@ </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> - <string key="label">terminate:</string> - <reference key="source" ref="1050"/> - <reference key="destination" ref="632727374"/> - </object> - <int key="connectionID">449</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> <string key="label">toggleAutomaticSpellingCorrection:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="795346622"/> @@ -1387,14 +1410,6 @@ <int key="connectionID">493</int> </object> <object class="IBConnectionRecord"> - <object class="IBOutletConnection" key="connection"> - <string key="label">delegate</string> - <reference key="source" ref="1021"/> - <reference key="destination" ref="976324537"/> - </object> - <int key="connectionID">495</int> - </object> - <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">newWindow:</string> <reference key="source" ref="1014"/> @@ -1404,22 +1419,6 @@ </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> - <string key="label">setSharedProcessProcessModel:</string> - <reference key="source" ref="976324537"/> - <reference key="destination" ref="993856752"/> - </object> - <int key="connectionID">543</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">setSharedThreadProcessModel:</string> - <reference key="source" ref="976324537"/> - <reference key="destination" ref="516840223"/> - </object> - <int key="connectionID">544</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> <string key="label">forceRepaint:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="878165919"/> @@ -1444,14 +1443,6 @@ </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> - <string key="label">showStatisticsWindow:</string> - <reference key="source" ref="976324537"/> - <reference key="destination" ref="208343368"/> - </object> - <int key="connectionID">554</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> <string key="label">zoomIn:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="694544109"/> @@ -1490,13 +1481,47 @@ </object> <int key="connectionID">567</int> </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">togglePaginationMode:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="15772092"/> + </object> + <int key="connectionID">570</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">setSharedProcessProcessModel:</string> + <reference key="source" ref="976324537"/> + <reference key="destination" ref="993856752"/> + </object> + <int key="connectionID">543</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">setSharedThreadProcessModel:</string> + <reference key="source" ref="976324537"/> + <reference key="destination" ref="516840223"/> + </object> + <int key="connectionID">544</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">showStatisticsWindow:</string> + <reference key="source" ref="976324537"/> + <reference key="destination" ref="208343368"/> + </object> + <int key="connectionID">554</int> + </object> </object> <object class="IBMutableOrderedSet" key="objectRecords"> <object class="NSArray" key="orderedObjects"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBObjectRecord"> <int key="objectID">0</int> - <reference key="object" ref="0"/> + <object class="NSArray" key="object" id="0"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> <reference key="children" ref="1048"/> <nil key="parent"/> </object> @@ -2162,6 +2187,8 @@ <reference ref="208343368"/> <reference ref="377902755"/> <reference ref="191469404"/> + <reference ref="624939128"/> + <reference ref="15772092"/> </object> <reference key="parent" ref="816668511"/> </object> @@ -2262,143 +2289,84 @@ <reference key="object" ref="191469404"/> <reference key="parent" ref="865232259"/> </object> + <object class="IBObjectRecord"> + <int key="objectID">568</int> + <reference key="object" ref="624939128"/> + <reference key="parent" ref="865232259"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">569</int> + <reference key="object" ref="15772092"/> + <reference key="parent" ref="865232259"/> + </object> </object> </object> <object class="NSMutableDictionary" key="flattenedProperties"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> <bool key="EncodedWithXMLCoder">YES</bool> + <string>-1.IBPluginDependency</string> + <string>-2.IBPluginDependency</string> <string>-3.IBPluginDependency</string> <string>112.IBPluginDependency</string> - <string>112.ImportedFromIB2</string> <string>124.IBPluginDependency</string> - <string>124.ImportedFromIB2</string> <string>125.IBPluginDependency</string> - <string>125.ImportedFromIB2</string> - <string>125.editorWindowContentRectSynchronizationRect</string> <string>126.IBPluginDependency</string> - <string>126.ImportedFromIB2</string> <string>129.IBPluginDependency</string> - <string>129.ImportedFromIB2</string> <string>130.IBPluginDependency</string> - <string>130.ImportedFromIB2</string> - <string>130.editorWindowContentRectSynchronizationRect</string> <string>131.IBPluginDependency</string> - <string>131.ImportedFromIB2</string> <string>134.IBPluginDependency</string> - <string>134.ImportedFromIB2</string> <string>136.IBPluginDependency</string> - <string>136.ImportedFromIB2</string> <string>143.IBPluginDependency</string> - <string>143.ImportedFromIB2</string> <string>144.IBPluginDependency</string> - <string>144.ImportedFromIB2</string> <string>145.IBPluginDependency</string> - <string>145.ImportedFromIB2</string> <string>149.IBPluginDependency</string> - <string>149.ImportedFromIB2</string> <string>150.IBPluginDependency</string> - <string>150.ImportedFromIB2</string> <string>19.IBPluginDependency</string> - <string>19.ImportedFromIB2</string> <string>195.IBPluginDependency</string> - <string>195.ImportedFromIB2</string> <string>196.IBPluginDependency</string> - <string>196.ImportedFromIB2</string> <string>197.IBPluginDependency</string> - <string>197.ImportedFromIB2</string> <string>198.IBPluginDependency</string> - <string>198.ImportedFromIB2</string> <string>199.IBPluginDependency</string> - <string>199.ImportedFromIB2</string> - <string>200.IBEditorWindowLastContentRect</string> <string>200.IBPluginDependency</string> - <string>200.ImportedFromIB2</string> - <string>200.editorWindowContentRectSynchronizationRect</string> <string>201.IBPluginDependency</string> - <string>201.ImportedFromIB2</string> <string>202.IBPluginDependency</string> - <string>202.ImportedFromIB2</string> <string>203.IBPluginDependency</string> - <string>203.ImportedFromIB2</string> <string>204.IBPluginDependency</string> - <string>204.ImportedFromIB2</string> - <string>205.IBEditorWindowLastContentRect</string> <string>205.IBPluginDependency</string> - <string>205.ImportedFromIB2</string> - <string>205.editorWindowContentRectSynchronizationRect</string> <string>206.IBPluginDependency</string> - <string>206.ImportedFromIB2</string> <string>207.IBPluginDependency</string> - <string>207.ImportedFromIB2</string> <string>208.IBPluginDependency</string> - <string>208.ImportedFromIB2</string> <string>209.IBPluginDependency</string> - <string>209.ImportedFromIB2</string> <string>210.IBPluginDependency</string> - <string>210.ImportedFromIB2</string> <string>211.IBPluginDependency</string> - <string>211.ImportedFromIB2</string> <string>212.IBPluginDependency</string> - <string>212.ImportedFromIB2</string> - <string>212.editorWindowContentRectSynchronizationRect</string> <string>213.IBPluginDependency</string> - <string>213.ImportedFromIB2</string> <string>214.IBPluginDependency</string> - <string>214.ImportedFromIB2</string> <string>215.IBPluginDependency</string> - <string>215.ImportedFromIB2</string> <string>216.IBPluginDependency</string> - <string>216.ImportedFromIB2</string> <string>217.IBPluginDependency</string> - <string>217.ImportedFromIB2</string> <string>218.IBPluginDependency</string> - <string>218.ImportedFromIB2</string> <string>219.IBPluginDependency</string> - <string>219.ImportedFromIB2</string> - <string>220.IBEditorWindowLastContentRect</string> <string>220.IBPluginDependency</string> - <string>220.ImportedFromIB2</string> - <string>220.editorWindowContentRectSynchronizationRect</string> <string>221.IBPluginDependency</string> - <string>221.ImportedFromIB2</string> <string>23.IBPluginDependency</string> - <string>23.ImportedFromIB2</string> <string>236.IBPluginDependency</string> - <string>236.ImportedFromIB2</string> <string>239.IBPluginDependency</string> - <string>239.ImportedFromIB2</string> - <string>24.IBEditorWindowLastContentRect</string> <string>24.IBPluginDependency</string> - <string>24.ImportedFromIB2</string> - <string>24.editorWindowContentRectSynchronizationRect</string> - <string>29.IBEditorWindowLastContentRect</string> <string>29.IBPluginDependency</string> - <string>29.ImportedFromIB2</string> - <string>29.WindowOrigin</string> - <string>29.editorWindowContentRectSynchronizationRect</string> <string>295.IBPluginDependency</string> - <string>296.IBEditorWindowLastContentRect</string> <string>296.IBPluginDependency</string> - <string>296.editorWindowContentRectSynchronizationRect</string> <string>297.IBPluginDependency</string> <string>298.IBPluginDependency</string> <string>346.IBPluginDependency</string> - <string>346.ImportedFromIB2</string> <string>348.IBPluginDependency</string> - <string>348.ImportedFromIB2</string> - <string>349.IBEditorWindowLastContentRect</string> <string>349.IBPluginDependency</string> - <string>349.ImportedFromIB2</string> - <string>349.editorWindowContentRectSynchronizationRect</string> <string>350.IBPluginDependency</string> - <string>350.ImportedFromIB2</string> <string>351.IBPluginDependency</string> - <string>351.ImportedFromIB2</string> <string>354.IBPluginDependency</string> - <string>354.ImportedFromIB2</string> + <string>420.IBPluginDependency</string> <string>450.IBPluginDependency</string> - <string>451.IBEditorWindowLastContentRect</string> <string>451.IBPluginDependency</string> <string>452.IBPluginDependency</string> <string>453.IBPluginDependency</string> @@ -2411,16 +2379,13 @@ <string>466.IBPluginDependency</string> <string>485.IBPluginDependency</string> <string>490.IBPluginDependency</string> - <string>491.IBEditorWindowLastContentRect</string> <string>491.IBPluginDependency</string> <string>492.IBPluginDependency</string> + <string>494.IBPluginDependency</string> <string>5.IBPluginDependency</string> - <string>5.ImportedFromIB2</string> <string>534.IBPluginDependency</string> - <string>535.IBEditorWindowLastContentRect</string> <string>535.IBPluginDependency</string> <string>537.IBPluginDependency</string> - <string>538.IBEditorWindowLastContentRect</string> <string>538.IBPluginDependency</string> <string>539.IBPluginDependency</string> <string>540.IBPluginDependency</string> @@ -2435,176 +2400,87 @@ <string>557.IBPluginDependency</string> <string>558.IBPluginDependency</string> <string>56.IBPluginDependency</string> - <string>56.ImportedFromIB2</string> <string>562.IBPluginDependency</string> <string>565.IBPluginDependency</string> <string>566.IBPluginDependency</string> - <string>57.IBEditorWindowLastContentRect</string> + <string>568.IBPluginDependency</string> + <string>569.IBPluginDependency</string> <string>57.IBPluginDependency</string> - <string>57.ImportedFromIB2</string> - <string>57.editorWindowContentRectSynchronizationRect</string> <string>58.IBPluginDependency</string> - <string>58.ImportedFromIB2</string> <string>72.IBPluginDependency</string> - <string>72.ImportedFromIB2</string> <string>73.IBPluginDependency</string> - <string>73.ImportedFromIB2</string> <string>74.IBPluginDependency</string> - <string>74.ImportedFromIB2</string> <string>75.IBPluginDependency</string> - <string>75.ImportedFromIB2</string> <string>77.IBPluginDependency</string> - <string>77.ImportedFromIB2</string> <string>78.IBPluginDependency</string> - <string>78.ImportedFromIB2</string> <string>79.IBPluginDependency</string> - <string>79.ImportedFromIB2</string> <string>80.IBPluginDependency</string> - <string>80.ImportedFromIB2</string> - <string>81.IBEditorWindowLastContentRect</string> <string>81.IBPluginDependency</string> - <string>81.ImportedFromIB2</string> - <string>81.editorWindowContentRectSynchronizationRect</string> <string>82.IBPluginDependency</string> - <string>82.ImportedFromIB2</string> <string>83.IBPluginDependency</string> - <string>83.ImportedFromIB2</string> <string>92.IBPluginDependency</string> - <string>92.ImportedFromIB2</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{522, 812}, {146, 23}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{436, 809}, {64, 6}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{753, 187}, {275, 113}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{608, 612}, {275, 83}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{650, 538}, {254, 283}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{187, 434}, {243, 243}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{608, 612}, {167, 43}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{753, 217}, {238, 103}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{608, 612}, {241, 103}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{744, 748}, {194, 73}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{525, 802}, {197, 73}}</string> - <string>{{488, 821}, {451, 20}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{74, 862}</string> - <string>{{6, 978}, {478, 20}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{694, 688}, {234, 133}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{475, 832}, {234, 43}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{746, 287}, {220, 133}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{608, 612}, {215, 63}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{753, 197}, {170, 63}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> @@ -2617,16 +2493,12 @@ <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{881, 798}, {189, 23}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{864, 668}, {260, 153}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{1110, 678}, {154, 43}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> @@ -2641,61 +2513,44 @@ <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{286, 129}, {275, 183}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{23, 794}, {245, 183}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{608, 618}, {196, 203}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> - <string>{{145, 474}, {199, 203}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1"/> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> </object> </object> <object class="NSMutableDictionary" key="unlocalizedProperties"> <bool key="EncodedWithXMLCoder">YES</bool> <reference key="dict.sortedKeys" ref="0"/> - <object class="NSMutableArray" key="dict.values"> - <bool key="EncodedWithXMLCoder">YES</bool> - </object> + <reference key="dict.values" ref="0"/> </object> <nil key="activeLocalization"/> <object class="NSMutableDictionary" key="localizations"> <bool key="EncodedWithXMLCoder">YES</bool> <reference key="dict.sortedKeys" ref="0"/> - <object class="NSMutableArray" key="dict.values"> - <bool key="EncodedWithXMLCoder">YES</bool> - </object> + <reference key="dict.values" ref="0"/> </object> <nil key="sourceID"/> - <int key="maxID">567</int> + <int key="maxID">570</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <object class="NSMutableArray" key="referencedPartialClassDescriptions"> @@ -2711,7 +2566,7 @@ <string>setSharedThreadProcessModel:</string> <string>showStatisticsWindow:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>id</string> <string>id</string> @@ -2726,7 +2581,7 @@ <string>setSharedThreadProcessModel:</string> <string>showStatisticsWindow:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBActionInfo"> <string key="name">setSharedProcessProcessModel:</string> @@ -2744,26 +2599,7 @@ </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBProjectSource</string> - <string key="minorKey">mac/AppDelegate.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">BrowserAppDelegate</string> - <string key="superclassName">NSObject</string> - <object class="NSMutableDictionary" key="outlets"> - <string key="NS.key.0">window</string> - <string key="NS.object.0">NSWindow</string> - </object> - <object class="NSMutableDictionary" key="toOneOutletInfosByName"> - <string key="NS.key.0">window</string> - <object class="IBToOneOutletInfo" key="NS.object.0"> - <string key="name">window</string> - <string key="candidateClassName">NSWindow</string> - </object> - </object> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBUserSource</string> - <string key="minorKey"/> + <string key="minorKey">./Classes/BrowserAppDelegate.h</string> </object> </object> <object class="IBPartialClassDescription"> @@ -2775,6 +2611,7 @@ <bool key="EncodedWithXMLCoder">YES</bool> <string>dumpSourceToConsole:</string> <string>fetch:</string> + <string>find:</string> <string>forceRepaint:</string> <string>goBack:</string> <string>goForward:</string> @@ -2786,7 +2623,7 @@ <string>zoomIn:</string> <string>zoomOut:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>id</string> <string>id</string> @@ -2800,6 +2637,7 @@ <string>id</string> <string>id</string> <string>id</string> + <string>id</string> </object> </object> <object class="NSMutableDictionary" key="actionInfosByName"> @@ -2808,6 +2646,7 @@ <bool key="EncodedWithXMLCoder">YES</bool> <string>dumpSourceToConsole:</string> <string>fetch:</string> + <string>find:</string> <string>forceRepaint:</string> <string>goBack:</string> <string>goForward:</string> @@ -2819,7 +2658,7 @@ <string>zoomIn:</string> <string>zoomOut:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBActionInfo"> <string key="name">dumpSourceToConsole:</string> @@ -2830,6 +2669,10 @@ <string key="candidateClassName">id</string> </object> <object class="IBActionInfo"> + <string key="name">find:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo"> <string key="name">forceRepaint:</string> <string key="candidateClassName">id</string> </object> @@ -2877,16 +2720,18 @@ <bool key="EncodedWithXMLCoder">YES</bool> <string>backButton</string> <string>containerView</string> + <string>findPanelWindow</string> <string>forwardButton</string> <string>progressIndicator</string> <string>reloadButton</string> <string>toolbar</string> <string>urlText</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>NSButton</string> <string>NSView</string> + <string>NSWindow</string> <string>NSButton</string> <string>NSProgressIndicator</string> <string>NSButton</string> @@ -2900,13 +2745,14 @@ <bool key="EncodedWithXMLCoder">YES</bool> <string>backButton</string> <string>containerView</string> + <string>findPanelWindow</string> <string>forwardButton</string> <string>progressIndicator</string> <string>reloadButton</string> <string>toolbar</string> <string>urlText</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBToOneOutletInfo"> <string key="name">backButton</string> @@ -2917,6 +2763,10 @@ <string key="candidateClassName">NSView</string> </object> <object class="IBToOneOutletInfo"> + <string key="name">findPanelWindow</string> + <string key="candidateClassName">NSWindow</string> + </object> + <object class="IBToOneOutletInfo"> <string key="name">forwardButton</string> <string key="candidateClassName">NSButton</string> </object> @@ -2940,12 +2790,11 @@ </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBProjectSource</string> - <string key="minorKey">mac/BrowserWindowController.h</string> + <string key="minorKey">./Classes/BrowserWindowController.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">FirstResponder</string> - <string key="superclassName">NSObject</string> <object class="NSMutableDictionary" key="actions"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> @@ -2953,7 +2802,7 @@ <string>forceRepaint:</string> <string>newWindow:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>id</string> <string>id</string> @@ -2966,7 +2815,7 @@ <string>forceRepaint:</string> <string>newWindow:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBActionInfo"> <string key="name">forceRepaint:</string> @@ -2983,79 +2832,8 @@ <string key="minorKey"/> </object> </object> - </object> - <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="IBPartialClassDescription"> - <string key="className">NSApplication</string> - <string key="superclassName">NSResponder</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier" id="822405504"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSApplication.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSApplication</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier" id="850738725"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSApplicationScripting.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSApplication</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier" id="624831158"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSColorPanel.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSApplication</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSHelpManager.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSApplication</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSPageLayout.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSApplication</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSUserInterfaceItemSearching.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSBrowser</string> - <string key="superclassName">NSControl</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSBrowser.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSButton</string> - <string key="superclassName">NSControl</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSButton.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSControl</string> - <string key="superclassName">NSView</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier" id="310914472"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSControl.h</string> - </object> - </object> <object class="IBPartialClassDescription"> <string key="className">NSDocument</string> - <string key="superclassName">NSObject</string> <object class="NSMutableDictionary" key="actions"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> @@ -3067,7 +2845,7 @@ <string>saveDocumentAs:</string> <string>saveDocumentTo:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>id</string> <string>id</string> @@ -3088,7 +2866,7 @@ <string>saveDocumentAs:</string> <string>saveDocumentTo:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBActionInfo"> <string key="name">printDocument:</string> @@ -3117,30 +2895,40 @@ </object> </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSDocument.h</string> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/NSDocument.h</string> </object> </object> <object class="IBPartialClassDescription"> - <string key="className">NSDocument</string> + <string key="className">NSDocumentController</string> + <object class="NSMutableDictionary" key="actions"> + <string key="NS.key.0">_openRecentDocument:</string> + <string key="NS.object.0">id</string> + </object> + <object class="NSMutableDictionary" key="actionInfosByName"> + <string key="NS.key.0">_openRecentDocument:</string> + <object class="IBActionInfo" key="NS.object.0"> + <string key="name">_openRecentDocument:</string> + <string key="candidateClassName">id</string> + </object> + </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSDocumentScripting.h</string> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/NSDocumentController.h</string> </object> </object> <object class="IBPartialClassDescription"> - <string key="className">NSDocumentController</string> - <string key="superclassName">NSObject</string> + <string key="className">WebView</string> <object class="NSMutableDictionary" key="actions"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> <bool key="EncodedWithXMLCoder">YES</bool> - <string>clearRecentDocuments:</string> - <string>newDocument:</string> - <string>openDocument:</string> - <string>saveAllDocuments:</string> + <string>reloadFromOrigin:</string> + <string>resetPageZoom:</string> + <string>zoomPageIn:</string> + <string>zoomPageOut:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>id</string> <string>id</string> @@ -3152,447 +2940,34 @@ <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> <bool key="EncodedWithXMLCoder">YES</bool> - <string>clearRecentDocuments:</string> - <string>newDocument:</string> - <string>openDocument:</string> - <string>saveAllDocuments:</string> + <string>reloadFromOrigin:</string> + <string>resetPageZoom:</string> + <string>zoomPageIn:</string> + <string>zoomPageOut:</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBActionInfo"> - <string key="name">clearRecentDocuments:</string> + <string key="name">reloadFromOrigin:</string> <string key="candidateClassName">id</string> </object> <object class="IBActionInfo"> - <string key="name">newDocument:</string> + <string key="name">resetPageZoom:</string> <string key="candidateClassName">id</string> </object> <object class="IBActionInfo"> - <string key="name">openDocument:</string> + <string key="name">zoomPageIn:</string> <string key="candidateClassName">id</string> </object> <object class="IBActionInfo"> - <string key="name">saveAllDocuments:</string> + <string key="name">zoomPageOut:</string> <string key="candidateClassName">id</string> </object> </object> </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSDocumentController.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSFontManager</string> - <string key="superclassName">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier" id="946436764"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSFontManager.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSFormatter</string> - <string key="superclassName">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSFormatter.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSMatrix</string> - <string key="superclassName">NSControl</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSMatrix.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSMenu</string> - <string key="superclassName">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier" id="1056362899"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSMenu.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSMenuItem</string> - <string key="superclassName">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier" id="472958451"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSMenuItem.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSMovieView</string> - <string key="superclassName">NSView</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSMovieView.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSAccessibility.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <reference key="sourceIdentifier" ref="822405504"/> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <reference key="sourceIdentifier" ref="850738725"/> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <reference key="sourceIdentifier" ref="624831158"/> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <reference key="sourceIdentifier" ref="310914472"/> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSDictionaryController.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSDragging.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <reference key="sourceIdentifier" ref="946436764"/> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSFontPanel.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSKeyValueBinding.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <reference key="sourceIdentifier" ref="1056362899"/> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSNibLoading.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSOutlineView.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSPasteboard.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSSavePanel.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier" id="809545482"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSTableView.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSToolbarItem.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier" id="260078765"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSView.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSArchiver.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSClassDescription.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSError.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSObject.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSObjectScripting.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSPortCoder.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSScriptClassDescription.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSScriptKeyValueCoding.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSScriptObjectSpecifiers.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSScriptWhoseTests.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSThread.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSURL.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSProgressIndicator</string> - <string key="superclassName">NSView</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSProgressIndicator.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSResponder</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSInterfaceStyle.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSResponder</string> - <string key="superclassName">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSResponder.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSTableView</string> - <string key="superclassName">NSControl</string> - <reference key="sourceIdentifier" ref="809545482"/> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSText</string> - <string key="superclassName">NSView</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSText.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSTextField</string> - <string key="superclassName">NSControl</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSTextField.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSTextView</string> - <string key="superclassName">NSText</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSTextView.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSToolbar</string> - <string key="superclassName">NSObject</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSToolbar.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSView</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSClipView.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSView</string> - <reference key="sourceIdentifier" ref="472958451"/> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSView</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSRulerView.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSView</string> - <string key="superclassName">NSResponder</string> - <reference key="sourceIdentifier" ref="260078765"/> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSWindow</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSDrawer.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSWindow</string> - <string key="superclassName">NSResponder</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSWindow.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSWindow</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSWindowScripting.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> - <string key="className">NSWindowController</string> - <string key="superclassName">NSResponder</string> - <object class="NSMutableDictionary" key="actions"> - <string key="NS.key.0">showWindow:</string> - <string key="NS.object.0">id</string> - </object> - <object class="NSMutableDictionary" key="actionInfosByName"> - <string key="NS.key.0">showWindow:</string> - <object class="IBActionInfo" key="NS.object.0"> - <string key="name">showWindow:</string> - <string key="candidateClassName">id</string> - </object> - </object> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBFrameworkSource</string> - <string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">./Classes/WebView.h</string> </object> </object> </object> @@ -3604,7 +2979,6 @@ <integer value="3000" key="NS.object.0"/> </object> <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool> - <string key="IBDocument.LastKnownRelativeProjectPath">../MiniBrowser.xcodeproj</string> <int key="IBDocument.defaultPropertyAccessControl">3</int> <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes"> <bool key="EncodedWithXMLCoder">YES</bool> @@ -3613,10 +2987,10 @@ <string>NSMenuCheckmark</string> <string>NSMenuMixedState</string> </object> - <object class="NSMutableArray" key="dict.values"> + <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> - <string>{9, 8}</string> - <string>{7, 2}</string> + <string>{11, 11}</string> + <string>{10, 3}</string> </object> </object> </data> diff --git a/Tools/MiniBrowser/qt/raw/View.h b/Tools/MiniBrowser/qt/raw/View.h index 6de7a25e2..e53223f89 100644 --- a/Tools/MiniBrowser/qt/raw/View.h +++ b/Tools/MiniBrowser/qt/raw/View.h @@ -31,7 +31,7 @@ public: View(const QString& url); ~View(); -public: // WKViewClient +public: // QRawWebViewClient virtual void viewNeedsDisplay(const QRect&); virtual void viewRequestedScroll(const QPoint&) { } virtual void viewProcessCrashed() { } diff --git a/Tools/Scripts/bisect-builds b/Tools/Scripts/bisect-builds index cd348998d..b970db399 100755 --- a/Tools/Scripts/bisect-builds +++ b/Tools/Scripts/bisect-builds @@ -43,9 +43,13 @@ use File::Basename; use File::Path; use File::Spec; use File::Temp qw(tempfile); +use FindBin; use Getopt::Long; use Time::HiRes qw(usleep); +use lib $FindBin::Bin; +use webkitdirs qw(safariPathFromSafariBundle); + sub createTempFile($); sub downloadNightly($$$); sub findMacOSXVersion(); @@ -119,7 +123,7 @@ my $nightlyFilesURLBase = $nightlyWebSite . File::Spec->catdir("/files", $branch $nightlyDownloadDirectory = glob($nightlyDownloadDirectory) if $nightlyDownloadDirectory =~ /^~/; $safariPath = glob($safariPath) if $safariPath =~ /^~/; -$safariPath = File::Spec->catdir($safariPath, "Contents/MacOS/Safari") if $safariPath =~ m#\.app/*#; +$safariPath = safariPathFromSafariBundle($safariPath) if $safariPath =~ m#\.app/*#; $nightlyDownloadDirectory = File::Spec->catdir($nightlyDownloadDirectory, $branch); if (! -d $nightlyDownloadDirectory) { diff --git a/Tools/Scripts/copy-webkitlibraries-to-product-directory b/Tools/Scripts/copy-webkitlibraries-to-product-directory index 3c1532e47..dd6f29d0e 100755 --- a/Tools/Scripts/copy-webkitlibraries-to-product-directory +++ b/Tools/Scripts/copy-webkitlibraries-to-product-directory @@ -37,6 +37,7 @@ my @librariesToCopy = ( "libWebKitSystemInterfaceLeopard.a", "libWebKitSystemInterfaceSnowLeopard.a", "libWebKitSystemInterfaceLion.a", + "libWebKitSystemInterfaceMountainLion.a", "libWebCoreSQLite3.a", ); diff --git a/Tools/Scripts/import-w3c-performance-wg-tests b/Tools/Scripts/import-w3c-performance-wg-tests new file mode 100755 index 000000000..e48e26188 --- /dev/null +++ b/Tools/Scripts/import-w3c-performance-wg-tests @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This script imports the W3C Web Performance WG's test suite into WebKit. +# +# You must have checked out the 'webperf' repository from https://dvcs.w3.org/hg/ +# +# This script will populate the LayoutTests directory with the new tests. If the +# tests already exist, the script will refuse to run. Please clear out the +# w3c/webperf directory first. +# +# The main step in importing the tests is updating all of the URLs to match our +# directory layout. + +import os +import sys + +if len(sys.argv) != 3: + print 'USAGE: %s path_to_webperf_checkout_root path_to_webkit_checkout_root' + sys.exit(1) + +source_directory = os.path.join(sys.argv[1], 'tests') +destination_directory = os.path.join(sys.argv[2], 'LayoutTests', 'http', 'tests', 'w3c', 'webperf') + +if os.path.exists(destination_directory): + print 'Refusing to overwrite existing directory: %s' % destination_directory + sys.exit(1) +os.makedirs(destination_directory) + +directories_to_copy = ['approved', 'resources'] +directories_to_ignore = ['html5'] # These are just duplicates of the sibling directory 'html'. +replacements = [ + ('www.w3c-test.org', 'localhost:8000'), # This is the alternate host for cross-server requests. + ('w3c-test.org', '127.0.0.1:8000'), # This is the primary test server. + ('webperf/tests', 'w3c/webperf'), # We prepend /w3c to all of our paths. + ('/resources/testharness', '/w3c/resources/testharness'), + ('+ "(" + reloadTime[time] + ")"', ''), # Remove dynamic values from the output. We'll still see PASS. + ('+ "(" + startingTime[time] + ")"', ''), + ('\r\n', '\n'), # Convert to *NIX format. +] + +for directory_to_copy in directories_to_copy: + os.makedirs(os.path.join(destination_directory, directory_to_copy)) + os.chdir(source_directory) + for root, dirs, files in os.walk(directory_to_copy): + for dirname in directories_to_ignore: + if dirname in dirs: + dirs.remove(dirname) + for dirname in dirs: + os.makedirs(os.path.join(destination_directory, root, dirname)) + for filename in files: + with open(os.path.join(source_directory, root, filename), 'r') as in_file: + with open(os.path.join(destination_directory, root, filename), 'w') as out_file: + for line in in_file: + for to_find, replace_with in replacements: + line = line.replace(to_find, replace_with) + assert 'w3c-test.org' not in line, 'Imported test must not depend on live site. Bad line: "%s"' % line + out_file.write(line) diff --git a/Tools/Scripts/webkitpy/common/config/committers.py b/Tools/Scripts/webkitpy/common/config/committers.py index f31510022..4a55d495c 100644 --- a/Tools/Scripts/webkitpy/common/config/committers.py +++ b/Tools/Scripts/webkitpy/common/config/committers.py @@ -123,6 +123,7 @@ contributors_who_are_not_committers = [ Contributor("David Barr", "davidbarr@chromium.org", "barrbrain"), Contributor("David Dorwin", "ddorwin@chromium.org", "ddorwin"), Contributor("David Reveman", "reveman@chromium.org", "reveman"), + Contributor("Dongsung Huang", "luxtella@company100.net", "Huang"), Contributor("Douglas Davidson", "ddavidso@apple.com"), Contributor("Edward O'Connor", "eoconnor@apple.com", "hober"), Contributor("Eric Penner", "epenner@chromium.org", "epenner"), @@ -255,6 +256,7 @@ committers_unable_to_review = [ Committer("Hironori Bono", "hbono@chromium.org", "hbono"), Committer("Helder Correia", "helder.correia@nokia.com", "helder"), Committer("Hin-Chung Lam", ["hclam@google.com", "hclam@chromium.org"]), + Committer("Hugo Parente Lima", "hugo.lima@openbossa.org", "hugopl"), Committer("Ian Vollick", "vollick@chromium.org", "vollick"), Committer("Igor Trindade Oliveira", ["igor.oliveira@webkit.org", "igor.o@sisa.samsung.com"], "igoroliveira"), Committer("Ilya Sherman", "isherman@chromium.org", "isherman"), @@ -303,7 +305,7 @@ committers_unable_to_review = [ Committer("Konrad Piascik", "kpiascik@rim.com", "kpiascik"), Committer("Kristof Kosztyo", "kkristof@inf.u-szeged.hu", "kkristof"), Committer("Krzysztof Kowalczyk", "kkowalczyk@gmail.com"), - Committer("Kwang Yul Seo", ["skyul@company100.net", "kseo@webkit.org"], "kwangseo"), + Committer("Kwang Yul Seo", ["skyul@company100.net", "kseo@webkit.org"], "kseo"), Committer("Leandro Gracia Gil", "leandrogracia@chromium.org", "leandrogracia"), Committer("Leandro Pereira", ["leandro@profusion.mobi", "leandro@webkit.org"], "acidx"), Committer("Leo Yang", ["leo.yang@torchmobile.com.cn", "leoyang@webkit.org", "leoyang.webkit@gmail.com", "leo.yang.c@gmail.com"], "leoyang"), diff --git a/Tools/Scripts/webkitpy/common/message_pool.py b/Tools/Scripts/webkitpy/common/message_pool.py new file mode 100644 index 000000000..2d90cbe0b --- /dev/null +++ b/Tools/Scripts/webkitpy/common/message_pool.py @@ -0,0 +1,311 @@ +# Copyright (C) 2011 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. + +"""Module for handling messages and concurrency for run-webkit-tests +and test-webkitpy. This module follows the design for multiprocessing.Pool +and concurrency.futures.ProcessPoolExecutor, with the following differences: + +* Tasks are executed in stateful subprocesses via objects that implement the + Worker interface - this allows the workers to share state across tasks. +* The pool provides an asynchronous event-handling interface so the caller + may receive events as tasks are processed. + +If you don't need these features, use multiprocessing.Pool or concurrency.futures +intead. + +""" + +import cPickle +import logging +import multiprocessing +import Queue +import sys +import time +import traceback + + +from webkitpy.common.host import Host +from webkitpy.common.system import stack_utils + + +_log = logging.getLogger(__name__) + + +def get(caller, worker_factory, num_workers, worker_startup_delay_secs=0.0, host=None): + """Returns an object that exposes a run() method that takes a list of test shards and runs them in parallel.""" + return _MessagePool(caller, worker_factory, num_workers, worker_startup_delay_secs, host) + + +class _MessagePool(object): + def __init__(self, caller, worker_factory, num_workers, worker_startup_delay_secs=0.0, host=None): + self._caller = caller + self._worker_factory = worker_factory + self._num_workers = num_workers + self._worker_startup_delay_secs = worker_startup_delay_secs + self._workers = [] + self._workers_stopped = set() + self._host = host + self._name = 'manager' + self._running_inline = (self._num_workers == 1) + if self._running_inline: + self._messages_to_worker = Queue.Queue() + self._messages_to_manager = Queue.Queue() + else: + self._messages_to_worker = multiprocessing.Queue() + self._messages_to_manager = multiprocessing.Queue() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, exc_traceback): + self._close() + return False + + def run(self, shards): + """Posts a list of messages to the pool and waits for them to complete.""" + for message in shards: + self._messages_to_worker.put(_Message(self._name, message[0], message[1:], from_user=True, logs=())) + + for _ in xrange(self._num_workers): + self._messages_to_worker.put(_Message(self._name, 'stop', message_args=(), from_user=False, logs=())) + + self.wait() + + def _start_workers(self): + assert not self._workers + self._workers_stopped = set() + host = None + if self._running_inline or self._can_pickle(self._host): + host = self._host + + for worker_number in xrange(self._num_workers): + worker = _Worker(host, self._messages_to_manager, self._messages_to_worker, self._worker_factory, worker_number, self._running_inline, self if self._running_inline else None) + self._workers.append(worker) + worker.start() + if self._worker_startup_delay_secs: + time.sleep(self._worker_startup_delay_secs) + + def wait(self): + try: + self._start_workers() + if self._running_inline: + self._workers[0].run() + self._loop(block=False) + else: + self._loop(block=True) + finally: + self._close() + + def _close(self): + for worker in self._workers: + if worker.is_alive(): + worker.terminate() + worker.join() + self._workers = [] + if not self._running_inline: + # FIXME: This is a hack to get multiprocessing to not log tracebacks during shutdown :(. + multiprocessing.util._exiting = True + if self._messages_to_worker: + self._messages_to_worker.close() + self._messages_to_worker = None + if self._messages_to_manager: + self._messages_to_manager.close() + self._messages_to_manager = None + + def _log_messages(self, messages): + for message in messages: + logging.root.handle(message) + + def _handle_done(self, source): + self._workers_stopped.add(source) + + @staticmethod + def _handle_worker_exception(source, exception_type, exception_value, _): + if exception_type == KeyboardInterrupt: + raise exception_type(exception_value) + raise WorkerException(str(exception_value)) + + def _can_pickle(self, host): + try: + cPickle.dumps(host) + return True + except TypeError: + return False + + def _loop(self, block): + try: + while True: + if len(self._workers_stopped) == len(self._workers): + block = False + message = self._messages_to_manager.get(block) + self._log_messages(message.logs) + if message.from_user: + self._caller.handle(message.name, message.src, *message.args) + continue + method = getattr(self, '_handle_' + message.name) + assert method, 'bad message %s' % repr(message) + method(message.src, *message.args) + except Queue.Empty: + pass + + +class WorkerException(Exception): + """Raised when we receive an unexpected/unknown exception from a worker.""" + pass + + +class _Message(object): + def __init__(self, src, message_name, message_args, from_user, logs): + self.src = src + self.name = message_name + self.args = message_args + self.from_user = from_user + self.logs = logs + + def __repr__(self): + return '_Message(src=%s, name=%s, args=%s, from_user=%s, logs=%s)' % (self.src, self.name, self.args, self.from_user, self.logs) + + +class _Worker(multiprocessing.Process): + def __init__(self, host, messages_to_manager, messages_to_worker, worker_factory, worker_number, running_inline, manager): + super(_Worker, self).__init__() + self.host = host + self.worker_number = worker_number + self.name = 'worker/%d' % worker_number + self.log_messages = [] + self._running_inline = running_inline + self._manager = manager + + self._messages_to_manager = messages_to_manager + self._messages_to_worker = messages_to_worker + self._worker = worker_factory(self) + self._logger = None + self._log_handler = None + + def terminate(self): + if self._worker: + if hasattr(self._worker, 'stop'): + self._worker.stop() + self._worker = None + if self.is_alive(): + super(_Worker, self).terminate() + + def _close(self): + if self._log_handler and self._logger: + self._logger.removeHandler(self._log_handler) + self._log_handler = None + self._logger = None + + def start(self): + if not self._running_inline: + super(_Worker, self).start() + + def run(self): + if not self.host: + self.host = Host() + if not self._running_inline: + self._set_up_logging() + + worker = self._worker + exception_msg = "" + _log.debug("%s starting" % self.name) + + try: + if hasattr(worker, 'start'): + worker.start() + while True: + message = self._messages_to_worker.get() + if message.from_user: + worker.handle(message.name, message.src, *message.args) + self._yield_to_manager() + else: + assert message.name == 'stop', 'bad message %s' % repr(message) + break + + _log.debug("%s exiting" % self.name) + except Queue.Empty: + assert False, '%s: ran out of messages in worker queue.' % self.name + except KeyboardInterrupt, e: + self._raise(sys.exc_info()) + except Exception, e: + self._raise(sys.exc_info()) + finally: + try: + if hasattr(worker, 'stop'): + worker.stop() + finally: + self._post(name='done', args=(), from_user=False) + self._close() + + def post(self, name, *args): + self._post(name, args, from_user=True) + self._yield_to_manager() + + def _yield_to_manager(self): + if self._running_inline: + self._manager._loop(block=False) + + def _post(self, name, args, from_user): + log_messages = self.log_messages + self.log_messages = [] + self._messages_to_manager.put(_Message(self.name, name, args, from_user, log_messages)) + + def _raise(self, exc_info): + exception_type, exception_value, exception_traceback = exc_info + if self._running_inline: + raise exception_type, exception_value, exception_traceback + + if exception_type == KeyboardInterrupt: + _log.debug("%s: interrupted, exiting" % self.name) + stack_utils.log_traceback(_log.debug, exception_traceback) + else: + _log.error("%s: %s('%s') raised:" % (self.name, exception_value.__class__.__name__, str(exception_value))) + stack_utils.log_traceback(_log.error, exception_traceback) + # Since tracebacks aren't picklable, send the extracted stack instead. + stack = traceback.extract_tb(exception_traceback) + self._post(name='worker_exception', args=(exception_type, exception_value, stack), from_user=False) + + def _set_up_logging(self): + self._logger = logging.getLogger() + + # The unix multiprocessing implementation clones any log handlers into the child process, + # so we remove them to avoid duplicate logging. + for h in self._logger.handlers: + self._logger.removeHandler(h) + + self._log_handler = _WorkerLogHandler(self) + self._logger.addHandler(self._log_handler) + + +class _WorkerLogHandler(logging.Handler): + def __init__(self, worker): + logging.Handler.__init__(self) + self._worker = worker + + def emit(self, record): + self._worker.log_messages.append(record) diff --git a/Tools/Scripts/webkitpy/common/system/user.py b/Tools/Scripts/webkitpy/common/system/user.py index 262b97944..c49429c0d 100644 --- a/Tools/Scripts/webkitpy/common/system/user.py +++ b/Tools/Scripts/webkitpy/common/system/user.py @@ -90,13 +90,21 @@ class User(object): def _wait_on_list_response(cls, list_items, can_choose_multiple, raw_input): while True: if can_choose_multiple: - response = cls.prompt("Enter one or more numbers (comma-separated), or \"all\": ", raw_input=raw_input) + response = cls.prompt("Enter one or more numbers (comma-separated) or ranges (e.g. 3-7), or \"all\": ", raw_input=raw_input) if not response.strip() or response == "all": return list_items + try: - indices = [int(r) - 1 for r in re.split("\s*,\s*", response)] + indices = [] + for value in re.split("\s*,\s*", response): + parts = value.split('-') + if len(parts) == 2: + indices += range(int(parts[0]) - 1, int(parts[1])) + else: + indices.append(int(value) - 1) except ValueError, err: continue + return [list_items[i] for i in indices] else: try: diff --git a/Tools/Scripts/webkitpy/common/system/user_unittest.py b/Tools/Scripts/webkitpy/common/system/user_unittest.py index 8b7cc1c0c..86b9db7d1 100644 --- a/Tools/Scripts/webkitpy/common/system/user_unittest.py +++ b/Tools/Scripts/webkitpy/common/system/user_unittest.py @@ -59,9 +59,9 @@ class UserTest(unittest.TestCase): actual_result = output_capture.assert_outputs( self, User.prompt_with_multiple_lists, - args=["title", ["subtitle1", "subtitle2"], [["foo", "bar"], ["foobar", "barbaz"]]], + args=["title", ["subtitle1", "subtitle2"], [["foo", "bar"], ["foobar", "barbaz", "foobaz"]]], kwargs={"can_choose_multiple": can_choose_multiple, "raw_input": mock_raw_input}, - expected_stdout="title\n\nsubtitle1\n 1. foo\n 2. bar\n\nsubtitle2\n 3. foobar\n 4. barbaz\n") + expected_stdout="title\n\nsubtitle1\n 1. foo\n 2. bar\n\nsubtitle2\n 3. foobar\n 4. barbaz\n 5. foobaz\n") self.assertEqual(actual_result, expected_result) self.assertEqual(len(inputs), 0) @@ -69,13 +69,17 @@ class UserTest(unittest.TestCase): run_prompt_test(["badinput", "2"], "bar") run_prompt_test(["3"], "foobar") run_prompt_test(["4"], "barbaz") + run_prompt_test(["5"], "foobaz") run_prompt_test(["1,2"], ["foo", "bar"], can_choose_multiple=True) + run_prompt_test(["1-3"], ["foo", "bar", "foobar"], can_choose_multiple=True) + run_prompt_test(["1-2,3"], ["foo", "bar", "foobar"], can_choose_multiple=True) + run_prompt_test(["2-1,3"], ["foobar"], can_choose_multiple=True) run_prompt_test([" 1, 2 "], ["foo", "bar"], can_choose_multiple=True) - run_prompt_test(["all"], ["foo", "bar", 'foobar', 'barbaz'], can_choose_multiple=True) - run_prompt_test([""], ["foo", "bar", 'foobar', 'barbaz'], can_choose_multiple=True) - run_prompt_test([" "], ["foo", "bar", 'foobar', 'barbaz'], can_choose_multiple=True) - run_prompt_test(["badinput", "all"], ["foo", "bar", 'foobar', 'barbaz'], can_choose_multiple=True) + run_prompt_test(["all"], ["foo", "bar", 'foobar', 'barbaz', 'foobaz'], can_choose_multiple=True) + run_prompt_test([""], ["foo", "bar", 'foobar', 'barbaz', 'foobaz'], can_choose_multiple=True) + run_prompt_test([" "], ["foo", "bar", 'foobar', 'barbaz', 'foobaz'], can_choose_multiple=True) + run_prompt_test(["badinput", "all"], ["foo", "bar", 'foobar', 'barbaz', 'foobaz'], can_choose_multiple=True) def test_prompt_with_list(self): def run_prompt_test(inputs, expected_result, can_choose_multiple=False): diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py index f2fed3f4a..7aee0c2fb 100644 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py +++ b/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py @@ -44,7 +44,7 @@ import re import sys import time -from webkitpy.layout_tests.controllers import manager_worker_broker +from webkitpy.common import message_pool from webkitpy.layout_tests.controllers import worker from webkitpy.layout_tests.controllers.test_result_writer import TestResultWriter from webkitpy.layout_tests.layout_package import json_layout_results_generator @@ -88,11 +88,9 @@ def interpret_test_failures(port, test_name, failures): test_dict['image_diff_percent'] = failure.diff_percent elif isinstance(failure, test_failures.FailureReftestMismatch): test_dict['is_reftest'] = True - test_dict['ref_file'] = port.relative_test_filename(failure.reference_filename) test_dict['image_diff_percent'] = failure.diff_percent elif isinstance(failure, test_failures.FailureReftestMismatchDidNotOccur): test_dict['is_mismatch_reftest'] = True - test_dict['ref_file'] = port.relative_test_filename(failure.reference_filename) if test_failures.FailureMissingResult in failure_types: test_dict['is_missing_text'] = True @@ -266,7 +264,8 @@ class TestRunInterruptedException(Exception): return self.__class__, (self.reason,) -WorkerException = manager_worker_broker.WorkerException +# Export this so callers don't need to know about message pools. +WorkerException = message_pool.WorkerException class TestShard(object): @@ -300,7 +299,6 @@ class Manager(object): self._filesystem = port.host.filesystem self._options = options self._printer = printer - self._message_broker = None self._expectations = None self.HTTP_SUBDIR = 'http' + port.TEST_PATH_SEPARATOR @@ -328,11 +326,9 @@ class Manager(object): self._all_results = [] self._group_stats = {} + self._worker_stats = {} self._current_result_summary = None - # This maps worker names to the state we are tracking for each of them. - self._worker_states = {} - def collect_tests(self, args): """Find all the files to test. @@ -484,20 +480,13 @@ class Manager(object): # now make sure we're explicitly running any tests passed on the command line. self._test_files.update(found_test_files.intersection(self._paths)) - if not num_all_test_files: + num_to_run = len(self._test_files) + num_skipped = num_all_test_files - num_to_run + + if not num_to_run: _log.critical('No tests to run.') return None - num_skipped = num_all_test_files - len(self._test_files) - if num_skipped: - self._printer.print_expected("Running %s (found %d, skipping %d)." % ( - grammar.pluralize('test', num_all_test_files - num_skipped), - num_all_test_files, num_skipped)) - elif len(self._test_files) > 1: - self._printer.print_expected("Running all %d tests." % len(self._test_files)) - else: - self._printer.print_expected("Running %1 test.") - # Create a sorted list of test files so the subset chunk, # if used, contains alphabetically consecutive tests. self._test_files_list = list(self._test_files) @@ -522,6 +511,8 @@ class Manager(object): (self._options.repeat_each if self._options.repeat_each else 1) * \ (self._options.iterations if self._options.iterations else 1) result_summary = ResultSummary(self._expectations, self._test_files | skipped, iterations) + + self._printer.print_expected('Found %s.' % grammar.pluralize('test', num_all_test_files)) self._print_expected_results_of_type(result_summary, test_expectations.PASS, "passes") self._print_expected_results_of_type(result_summary, test_expectations.FAIL, "failures") self._print_expected_results_of_type(result_summary, test_expectations.FLAKY, "flaky") @@ -534,17 +525,16 @@ class Manager(object): for test in skipped: result = test_results.TestResult(test) result.type = test_expectations.SKIP - iterations = \ - (self._options.repeat_each if self._options.repeat_each else 1) * \ - (self._options.iterations if self._options.iterations else 1) for iteration in range(iterations): result_summary.add(result, expected=True) self._printer.print_expected('') - # Check to make sure we didn't filter out all of the tests. - if not len(self._test_files): - _log.info("All tests are being skipped") - return None + if self._options.repeat_each > 1: + self._printer.print_expected('Running each test %d times.' % self._options.repeat_each) + if self._options.iterations > 1: + self._printer.print_expected('Running %d iterations of the tests.' % self._options.iterations) + if iterations > 1: + self._printer.print_expected('') return result_summary @@ -719,11 +709,12 @@ class Manager(object): def _log_num_workers(self, num_workers, num_shards, num_locked_shards): driver_name = self._port.driver_name() if num_workers == 1: - self._printer.print_config("Running 1 %s over %s" % + self._printer.print_config("Running 1 %s over %s." % (driver_name, grammar.pluralize('shard', num_shards))) else: - self._printer.print_config("Running %d %ss in parallel over %d shards (%d locked)" % + self._printer.print_config("Running %d %ss in parallel over %d shards (%d locked)." % (num_workers, driver_name, num_shards, num_locked_shards)) + self._printer.print_config('') def _run_tests(self, file_list, result_summary, num_workers): """Runs the tests in the file_list. @@ -744,11 +735,10 @@ class Manager(object): self._current_result_summary = result_summary self._all_results = [] self._group_stats = {} - self._worker_states = {} + self._worker_stats = {} keyboard_interrupted = False interrupted = False - thread_timings = [] self._printer.print_update('Sharding tests ...') locked_shards, unlocked_shards = self._shard_tests(file_list, int(self._options.child_processes), self._options.fully_parallel) @@ -769,71 +759,32 @@ class Manager(object): num_workers = min(num_workers, len(all_shards)) self._log_num_workers(num_workers, len(all_shards), len(locked_shards)) - def worker_factory(worker_connection, worker_number): - return worker.Worker(worker_connection, worker_number, self.results_directory(), self._options) - - manager_connection = manager_worker_broker.get(num_workers, self, worker_factory, self._port.host) + def worker_factory(worker_connection): + return worker.Worker(worker_connection, self.results_directory(), self._options) if self._options.dry_run: - return (keyboard_interrupted, interrupted, thread_timings, self._group_stats, self._all_results) + return (keyboard_interrupted, interrupted, self._worker_stats.values(), self._group_stats, self._all_results) self._printer.print_update('Starting %s ...' % grammar.pluralize('worker', num_workers)) - for worker_number in xrange(num_workers): - worker_connection = manager_connection.start_worker(worker_number) - worker_state = _WorkerState(worker_number, worker_connection) - self._worker_states[worker_connection.name()] = worker_state - - time.sleep(self._port.worker_startup_delay_secs()) - - self._printer.print_update("Starting testing ...") - for shard in all_shards: - # FIXME: Change 'test_list' to 'shard', make sharding public. - manager_connection.post_message('test_list', shard.name, shard.test_inputs) - - # We post one 'stop' message for each worker. Because the stop message - # are sent after all of the tests, and because each worker will stop - # reading messsages after receiving a stop, we can be sure each - # worker will get a stop message and hence they will all shut down. - for _ in xrange(num_workers): - manager_connection.post_message('stop') try: - while not self.is_done(): - manager_connection.run_message_loop(delay_secs=1.0) - - # Make sure all of the workers have shut down (if possible). - for worker_state in self._worker_states.values(): - if worker_state.worker_connection.is_alive(): - _log.debug('Waiting for worker %d to exit' % worker_state.number) - worker_state.worker_connection.join(5.0) - if worker_state.worker_connection.is_alive(): - _log.error('Worker %d did not exit in time.' % worker_state.number) - + with message_pool.get(self, worker_factory, num_workers, self._port.worker_startup_delay_secs(), self._port.host) as pool: + pool.run(('test_list', shard.name, shard.test_inputs) for shard in all_shards) except KeyboardInterrupt: self._printer.flush() self._printer.write('Interrupted, exiting ...') - self.cancel_workers() keyboard_interrupted = True except TestRunInterruptedException, e: _log.warning(e.reason) - self.cancel_workers() interrupted = True - except WorkerException: - self.cancel_workers() - raise - except: - # Unexpected exception; don't try to clean up workers. - _log.error("Exception raised, exiting") - self.cancel_workers() + except Exception, e: + _log.debug('%s("%s") raised, exiting' % (e.__class__.__name__, str(e))) raise finally: - manager_connection.cleanup() self.stop_servers_with_lock() - thread_timings = [worker_state.stats for worker_state in self._worker_states.values()] - # FIXME: should this be a class instead of a tuple? - return (interrupted, keyboard_interrupted, thread_timings, self._group_stats, self._all_results) + return (interrupted, keyboard_interrupted, self._worker_stats.values(), self._group_stats, self._all_results) def results_directory(self): if not self._retrying: @@ -934,7 +885,7 @@ class Manager(object): self._print_timing_statistics(end_time - start_time, thread_timings, test_timings, individual_test_timings, result_summary) self._print_result_summary(result_summary) - self._printer.print_one_line_summary(result_summary.total, result_summary.expected, result_summary.unexpected) + self._printer.print_one_line_summary(result_summary.total - result_summary.expected_skips, result_summary.expected - result_summary.expected_skips, result_summary.unexpected) unexpected_results = summarize_results(self._port, self._expectations, result_summary, retry_summary, individual_test_timings, only_unexpected=True, interrupted=interrupted) self._printer.print_unexpected_results(unexpected_results) @@ -1375,9 +1326,8 @@ class Manager(object): result_summary: information to log """ failed = result_summary.total_failures - skipped = result_summary.total_tests_by_expectation[test_expectations.SKIP] - total = result_summary.total - passed = total - failed - skipped + total = result_summary.total - result_summary.expected_skips + passed = total - failed pct_passed = 0.0 if total > 0: pct_passed = float(passed) * 100 / total @@ -1442,42 +1392,17 @@ class Manager(object): results_filename = self._filesystem.join(self._results_directory, "results.html") self._port.show_results_html_file(results_filename) - def name(self): - return 'Manager' - - def is_done(self): - worker_states = self._worker_states.values() - return worker_states and all(self._worker_is_done(worker_state) for worker_state in worker_states) - - # FIXME: Inline this function. - def _worker_is_done(self, worker_state): - return worker_state.done - - def cancel_workers(self): - for worker_state in self._worker_states.values(): - worker_state.worker_connection.cancel() - - def handle_started_test(self, source, test_info, hang_timeout): - worker_state = self._worker_states[source] - worker_state.current_test_name = test_info.test_name - worker_state.next_timeout = time.time() + hang_timeout - - def handle_done(self, source, log_messages=None): - worker_state = self._worker_states[source] - worker_state.done = True - self._log_messages(log_messages) - - def handle_exception(self, source, exception_type, exception_value, stack): - if exception_type in (KeyboardInterrupt, TestRunInterruptedException): - raise exception_type(exception_value) - _log.error("%s raised %s('%s'):" % ( - source, - exception_value.__class__.__name__, - str(exception_value))) - self._log_worker_stack(stack) - raise WorkerException(str(exception_value)) - - def handle_finished_list(self, source, list_name, num_tests, elapsed_time): + def handle(self, name, source, *args): + method = getattr(self, '_handle_' + name) + if method: + return method(source, *args) + raise AssertionError('unknown message %s received from %s, args=%s' % (name, source, repr(args))) + + def _handle_started_test(self, worker_name, test_input, test_timeout_sec): + # FIXME: log that we've started another test. + pass + + def _handle_finished_test_list(self, worker_name, list_name, num_tests, elapsed_time): self._group_stats[list_name] = (num_tests, elapsed_time) def find(name, test_lists): @@ -1492,29 +1417,13 @@ class Manager(object): if not self._remaining_locked_shards: self.stop_servers_with_lock() - def handle_finished_test(self, source, result, elapsed_time, log_messages=None): - worker_state = self._worker_states[source] - worker_state.next_timeout = None - worker_state.current_test_name = None - worker_state.stats['total_time'] += elapsed_time - worker_state.stats['num_tests'] += 1 - - self._log_messages(log_messages) + def _handle_finished_test(self, worker_name, result, elapsed_time, log_messages=[]): + self._worker_stats.setdefault(worker_name, {'name': worker_name, 'num_tests': 0, 'total_time': 0}) + self._worker_stats[worker_name]['total_time'] += elapsed_time + self._worker_stats[worker_name]['num_tests'] += 1 self._all_results.append(result) self._update_summary_with_result(self._current_result_summary, result) - def _log_messages(self, messages): - for message in messages: - logging.root.handle(message) - - def _log_worker_stack(self, stack): - webkitpydir = self._port.path_from_webkit_base('Tools', 'Scripts', 'webkitpy') + self._filesystem.sep - for filename, line_number, function_name, text in stack: - if filename.startswith(webkitpydir): - filename = filename.replace(webkitpydir, '') - _log.error(' %s:%u (in %s)' % (filename, line_number, function_name)) - _log.error(' %s' % text) - def read_test_files(fs, filenames, test_path_separator): tests = [] @@ -1563,20 +1472,3 @@ def natural_sort_key(string_to_split): return val return [tryint(chunk) for chunk in re.split('(\d+)', string_to_split)] - - -class _WorkerState(object): - """A class for the manager to use to track the current state of the workers.""" - def __init__(self, number, worker_connection): - self.worker_connection = worker_connection - self.number = number - self.done = False - self.current_test_name = None - self.next_timeout = None - self.stats = {} - self.stats['name'] = worker_connection.name() - self.stats['num_tests'] = 0 - self.stats['total_time'] = 0 - - def __repr__(self): - return "_WorkerState(" + str(self.__dict__) + ")" diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py b/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py index 3496322a9..27f06a70e 100644 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py @@ -452,7 +452,6 @@ class ResultSummaryTest(unittest.TestCase): [test_failures.FailureReftestMismatch(self.port.abspath_for_test('foo/common.html'))]) self.assertTrue('is_reftest' in test_dict) self.assertFalse('is_mismatch_reftest' in test_dict) - self.assertEqual(test_dict['ref_file'], 'foo/common.html') test_dict = interpret_test_failures(self.port, 'foo/reftest.html', [test_failures.FailureReftestMismatchDidNotOccur(self.port.abspath_for_test('foo/reftest-expected-mismatch.html'))]) @@ -463,7 +462,6 @@ class ResultSummaryTest(unittest.TestCase): [test_failures.FailureReftestMismatchDidNotOccur(self.port.abspath_for_test('foo/common.html'))]) self.assertFalse('is_reftest' in test_dict) self.assertTrue(test_dict['is_mismatch_reftest']) - self.assertEqual(test_dict['ref_file'], 'foo/common.html') def get_result(self, test_name, result_type=test_expectations.PASS, run_time=0): failures = [] diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py b/Tools/Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py deleted file mode 100755 index f7baced0a..000000000 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_worker_broker.py +++ /dev/null @@ -1,515 +0,0 @@ -# Copyright (C) 2011 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. - -"""Module for handling messages and concurrency for run-webkit-tests. - -This module implements a message broker that connects the manager to the -workers: it provides a messaging abstraction and message loops (building on -top of message_broker), and handles starting workers by launching processes. - -There are a lot of classes and objects involved in a fully connected system. -They interact more or less like: - - Manager --> _InlineManager ---> _InlineWorker <-> Worker - ^ \ / ^ - | v v | - \----------------------- Broker ----------------/ - -The broker simply distributes messages onto topics (named queues); the actual -queues themselves are provided by the caller, as the queue's implementation -requirements varies vary depending on the desired concurrency model -(none/threads/processes). - -In order for shared-nothing messaging between processing to be possible, -Messages must be picklable. - -The module defines one interface and two classes. Callers of this package -must implement the BrokerClient interface, and most callers will create -_BrokerConnections as well as Brokers. - -The classes relate to each other as: - - BrokerClient ------> _BrokerConnection - ^ | - | v - \---------------- _Broker - -(The BrokerClient never calls broker directly after it is created, only -_BrokerConnection. _BrokerConnection passes a reference to BrokerClient to -_Broker, and _Broker only invokes that reference, never talking directly to -BrokerConnection). -""" - -import cPickle -import logging -import multiprocessing -import optparse -import os -import Queue -import sys -import traceback - - -from webkitpy.common.host import Host -from webkitpy.common.system import stack_utils -from webkitpy.layout_tests.views import metered_stream - - -_log = logging.getLogger(__name__) - - -# -# Topic names for Manager <-> Worker messaging -# -MANAGER_TOPIC = 'managers' -ANY_WORKER_TOPIC = 'workers' - - -def get(max_workers, client, worker_factory, host=None): - """Return a connection to a manager/worker message_broker - - Args: - max_workers - max # of workers to run concurrently. - client - BrokerClient implementation to dispatch - replies to. - worker_factory: factory method for creating objects that implement the Worker interface. - host: optional picklable host object that can be passed to workers for testing. - Returns: - A handle to an object that will talk to a message broker configured - for the normal manager/worker communication.""" - if max_workers == 1: - queue_class = Queue.Queue - manager_class = _InlineManager - else: - queue_class = multiprocessing.Queue - manager_class = _MultiProcessManager - - broker = _Broker(queue_class) - return manager_class(broker, client, worker_factory, host) - - -class WorkerException(Exception): - """Raised when we receive an unexpected/unknown exception from a worker.""" - pass - - -class BrokerClient(object): - """Abstract base class / interface that all message broker clients must - implement. In addition to the methods below, by convention clients - implement routines of the signature type - - handle_MESSAGE_NAME(self, src, ...): - - where MESSAGE_NAME matches the string passed to post_message(), and - src indicates the name of the sender. If the message contains values in - the message body, those will be provided as optparams.""" - - def is_done(self): - """Called from inside run_message_loop() to indicate whether to exit.""" - raise NotImplementedError - - def name(self): - """Return a name that identifies the client.""" - raise NotImplementedError - - -class _Broker(object): - """Brokers provide the basic model of a set of topics. Clients can post a - message to any topic using post_message(), and can process messages on one - topic at a time using run_message_loop().""" - - def __init__(self, queue_maker): - """Args: - queue_maker: a factory method that returns objects implementing a - Queue interface (put()/get()). - """ - self._queue_maker = queue_maker - self._topics = {} - - def __del__(self): - self.cleanup() - - def cleanup(self): - for queue in self._topics.values(): - if hasattr(queue, 'close'): - queue.close() - self._topics = {} - - def add_topic(self, topic_name): - if topic_name not in self._topics: - self._topics[topic_name] = self._queue_maker() - - def _get_queue_for_topic(self, topic_name): - return self._topics[topic_name] - - def post_message(self, client, topic_name, message_name, *message_args): - """Post a message to the appropriate topic name. - - Messages have a name and a tuple of optional arguments. Both must be picklable.""" - message = _Message(client.name(), topic_name, message_name, message_args) - queue = self._get_queue_for_topic(topic_name) - queue.put(_Message.dumps(message)) - - def run_message_loop(self, topic_name, client, delay_secs=None): - """Loop processing messages until client.is_done() or delay passes. - - To run indefinitely, set delay_secs to None.""" - assert delay_secs is None or delay_secs > 0 - self._run_loop(topic_name, client, block=True, delay_secs=delay_secs) - - def run_all_pending(self, topic_name, client): - """Process messages until client.is_done() or caller would block.""" - self._run_loop(topic_name, client, block=False, delay_secs=None) - - def _run_loop(self, topic_name, client, block, delay_secs): - queue = self._get_queue_for_topic(topic_name) - while not client.is_done(): - try: - s = queue.get(block, delay_secs) - except Queue.Empty: - return - msg = _Message.loads(s) - self._dispatch_message(msg, client) - - def _dispatch_message(self, message, client): - if not hasattr(client, 'handle_' + message.name): - raise ValueError( - "%s: received message '%s' it couldn't handle" % - (client.name(), message.name)) - optargs = message.args - message_handler = getattr(client, 'handle_' + message.name) - message_handler(message.src, *optargs) - - -class _Message(object): - @staticmethod - def loads(string_value): - obj = cPickle.loads(string_value) - assert(isinstance(obj, _Message)) - return obj - - def __init__(self, src, topic_name, message_name, message_args): - self.src = src - self.topic_name = topic_name - self.name = message_name - self.args = message_args - - def dumps(self): - return cPickle.dumps(self) - - def __repr__(self): - return ("_Message(from='%s', topic_name='%s', message_name='%s')" % - (self.src, self.topic_name, self.name)) - - -class _BrokerConnection(object): - """_BrokerConnection provides a connection-oriented facade on top of a - Broker, so that callers don't have to repeatedly pass the same topic - names over and over.""" - - def __init__(self, broker, client, run_topic, post_topic): - """Create a _BrokerConnection on top of a _Broker. Note that the _Broker - is passed in rather than created so that a single _Broker can be used - by multiple _BrokerConnections.""" - self._broker = broker - self._client = client - self._post_topic = post_topic - self._run_topic = run_topic - broker.add_topic(run_topic) - broker.add_topic(post_topic) - - def cleanup(self): - self._broker.cleanup() - self._broker = None - - def run_message_loop(self, delay_secs=None): - self._broker.run_message_loop(self._run_topic, self._client, delay_secs) - - def post_message(self, message_name, *message_args): - self._broker.post_message(self._client, self._post_topic, - message_name, *message_args) - - def raise_exception(self, exc_info): - # Since tracebacks aren't picklable, send the extracted stack instead, - # but at least log the full traceback. - exception_type, exception_value, exception_traceback = sys.exc_info() - stack_utils.log_traceback(_log.error, exception_traceback) - stack = traceback.extract_tb(exception_traceback) - self._broker.post_message(self._client, self._post_topic, 'exception', exception_type, exception_value, stack) - - -class AbstractWorker(BrokerClient): - def __init__(self, worker_connection, worker_number): - BrokerClient.__init__(self) - self.worker = None - self._worker_connection = worker_connection - self._worker_number = worker_number - self._name = 'worker/%d' % worker_number - self._done = False - self._canceled = False - self._options = optparse.Values({'verbose': False}) - self.host = None - - def name(self): - return self._name - - def is_done(self): - return self._done or self._canceled - - def stop_handling_messages(self): - self._done = True - - def run(self, host): - """Callback for the worker to start executing. Typically does any - remaining initialization and then calls broker_connection.run_message_loop().""" - exception_msg = "" - self.host = host - - self.worker.safe_init() - _log.debug('%s starting' % self._name) - - try: - self._worker_connection.run_message_loop() - if not self.is_done(): - raise AssertionError("%s: ran out of messages in worker queue." - % self._name) - except KeyboardInterrupt: - exception_msg = ", interrupted" - self._worker_connection.raise_exception(sys.exc_info()) - except: - exception_msg = ", exception raised" - self._worker_connection.raise_exception(sys.exc_info()) - finally: - _log.debug("%s done with message loop%s" % (self._name, exception_msg)) - try: - self.worker.cleanup() - finally: - # Make sure we post a done so that we can flush the log messages - # and clean up properly even if we raise an exception in worker.cleanup(). - self._worker_connection.post_message('done') - - def handle_stop(self, source): - self._done = True - - def handle_test_list(self, source, list_name, test_list): - self.worker.handle('test_list', source, list_name, test_list) - - def cancel(self): - """Called when possible to indicate to the worker to stop processing - messages and shut down. Note that workers may be stopped without this - method being called, so clients should not rely solely on this.""" - self._canceled = True - - def yield_to_broker(self): - self._worker_connection.yield_to_broker() - - def post_message(self, *args): - self._worker_connection.post_message(*args) - - -class _ManagerConnection(_BrokerConnection): - def __init__(self, broker, client, worker_factory, host): - _BrokerConnection.__init__(self, broker, client, MANAGER_TOPIC, ANY_WORKER_TOPIC) - self._worker_factory = worker_factory - self._host = host - - def start_worker(self, worker_number): - raise NotImplementedError - - -class _InlineManager(_ManagerConnection): - def __init__(self, broker, client, worker_factory, host): - _ManagerConnection.__init__(self, broker, client, worker_factory, host) - self._inline_worker = None - - def start_worker(self, worker_number): - host = self._host - self._inline_worker = _InlineWorkerConnection(host, self._broker, self._client, self._worker_factory, worker_number) - return self._inline_worker - - def run_message_loop(self, delay_secs=None): - # Note that delay_secs is ignored in this case since we can't easily - # implement it. - self._inline_worker.run() - self._broker.run_all_pending(MANAGER_TOPIC, self._client) - - -class _MultiProcessManager(_ManagerConnection): - def _can_pickle_host(self): - try: - cPickle.dumps(self._host) - return True - except TypeError: - return False - - def start_worker(self, worker_number): - host = None - if self._can_pickle_host(): - host = self._host - worker_connection = _MultiProcessWorkerConnection(host, self._broker, self._worker_factory, worker_number) - worker_connection.start() - return worker_connection - - -class _WorkerConnection(_BrokerConnection): - def __init__(self, host, broker, worker_factory, worker_number): - # FIXME: keeping track of the differences between the WorkerConnection, the AbstractWorker, and the - # actual Worker (created by worker_factory) is very confusing, but this all gets better when - # _WorkerConnection and AbstractWorker get merged. - self._client = AbstractWorker(self, worker_number) - self._worker = worker_factory(self._client, worker_number) - self._client.worker = self._worker - self._host = host - self._log_messages = [] - self._logger = None - self._log_handler = None - _BrokerConnection.__init__(self, broker, self._client, ANY_WORKER_TOPIC, MANAGER_TOPIC) - - def name(self): - return self._client.name() - - def cancel(self): - raise NotImplementedError - - def is_alive(self): - raise NotImplementedError - - def join(self, timeout): - raise NotImplementedError - - def yield_to_broker(self): - pass - - def post_message(self, *args): - # FIXME: This is a hack until we can remove the log_messages arg from the manager. - if args[0] in ('finished_test', 'done'): - log_messages = self._log_messages - self._log_messages = [] - args = args + tuple([log_messages]) - super(_WorkerConnection, self).post_message(*args) - - def set_up_logging(self): - self._logger = logging.root - # The unix multiprocessing implementation clones the MeteredStream log handler - # into the child process, so we need to remove it to avoid duplicate logging. - for h in self._logger.handlers: - # log handlers don't have names until python 2.7. - if getattr(h, 'name', '') == metered_stream.LOG_HANDLER_NAME: - self._logger.removeHandler(h) - break - self._logger.setLevel(logging.DEBUG if self._client._options.verbose else logging.INFO) - self._log_handler = _WorkerLogHandler(self) - self._logger.addHandler(self._log_handler) - - def clean_up_logging(self): - if self._log_handler and self._logger: - self._logger.removeHandler(self._log_handler) - self._log_handler = None - self._logger = None - - -class _InlineWorkerConnection(_WorkerConnection): - def __init__(self, host, broker, manager_client, worker_factory, worker_number): - _WorkerConnection.__init__(self, host, broker, worker_factory, worker_number) - self._alive = False - self._manager_client = manager_client - - def cancel(self): - self._client.cancel() - - def is_alive(self): - return self._alive - - def join(self, timeout): - assert not self._alive - - def run(self): - self._alive = True - try: - self._client.run(self._host) - finally: - self._alive = False - - def yield_to_broker(self): - self._broker.run_all_pending(MANAGER_TOPIC, self._manager_client) - - def raise_exception(self, exc_info): - # Since the worker is in the same process as the manager, we can - # raise the exception directly, rather than having to send it through - # the queue. This allows us to preserve the traceback, but we log - # it anyway for consistency with the multiprocess case. - exception_type, exception_value, exception_traceback = sys.exc_info() - stack_utils.log_traceback(_log.error, exception_traceback) - raise exception_type, exception_value, exception_traceback - - -class _Process(multiprocessing.Process): - def __init__(self, worker_connection, client): - multiprocessing.Process.__init__(self) - self._worker_connection = worker_connection - self._client = client - - def run(self): - if not self._worker_connection._host: - self._worker_connection._host = Host() - self._worker_connection.run() - - -class _MultiProcessWorkerConnection(_WorkerConnection): - def __init__(self, host, broker, worker_factory, worker_number): - _WorkerConnection.__init__(self, host, broker, worker_factory, worker_number) - self._proc = _Process(self, self._client) - - def cancel(self): - return self._proc.terminate() - - def is_alive(self): - return self._proc.is_alive() - - def join(self, timeout): - return self._proc.join(timeout) - - def start(self): - self._proc.start() - - def run(self): - self.set_up_logging() - try: - self._client.run(self._host) - finally: - self.clean_up_logging() - - -class _WorkerLogHandler(logging.Handler): - def __init__(self, worker): - logging.Handler.__init__(self) - self._worker = worker - self._pid = os.getpid() - - def emit(self, record): - self._worker._log_messages.append(record) diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_worker_broker_unittest.py b/Tools/Scripts/webkitpy/layout_tests/controllers/manager_worker_broker_unittest.py deleted file mode 100644 index d7c3714d8..000000000 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_worker_broker_unittest.py +++ /dev/null @@ -1,213 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import optparse -import Queue -import sys -import unittest - -from webkitpy.common.system import outputcapture -from webkitpy.layout_tests.controllers import manager_worker_broker - - -# In order to reliably control when child workers are starting and stopping, -# we use a pair of global variables to hold queues used for messaging. Ideally -# we wouldn't need globals, but we can't pass these through a lexical closure -# because those can't be Pickled and sent to a subprocess, and we'd prefer not -# to have to pass extra arguments to the worker in the start_worker() call. -starting_queue = None -stopping_queue = None - - -WORKER_NAME = 'worker/1' - -def make_broker(manager, max_workers, start_queue=None, stop_queue=None): - global starting_queue - global stopping_queue - starting_queue = start_queue - stopping_queue = stop_queue - return manager_worker_broker.get(max_workers, manager, _TestWorker) - - -class _TestWorker(object): - def __init__(self, caller, worker_number): - self._caller = caller - self._thing_to_greet = 'everybody' - self._starting_queue = starting_queue - self._stopping_queue = stopping_queue - self._options = optparse.Values({'verbose': False}) - - def name(self): - return WORKER_NAME - - def cleanup(self): - pass - - def handle(self, message, src, an_int, a_str): - assert an_int == 1 - assert a_str == "hello, world" - self._caller.post_message('finished_test', 2) - - def safe_init(self): - if self._starting_queue: - self._starting_queue.put('') - - if self._stopping_queue: - self._stopping_queue.get() - - def stop(self): - self._caller.post_message('done') - - -class FunctionTests(unittest.TestCase): - def test_get__inline(self): - self.assertTrue(make_broker(self, 1) is not None) - - def test_get__processes(self): - # This test sometimes fails on Windows. See <http://webkit.org/b/55087>. - if sys.platform in ('cygwin', 'win32'): - return - self.assertTrue(make_broker(self, 2) is not None) - - -class _TestsMixin(object): - """Mixin class that implements a series of tests to enforce the - contract all implementations must follow.""" - - def name(self): - return 'TesterManager' - - def is_done(self): - return self._done - - def handle_done(self, src, log_messages): - self._done = True - - def handle_finished_test(self, src, an_int, log_messages): - self._an_int = an_int - - def handle_exception(self, src, exception_type, exception_value, stack): - raise exception_type(exception_value) - - def setUp(self): - self._an_int = None - self._broker = None - self._done = False - self._exception = None - self._max_workers = None - - def make_broker(self, starting_queue=None, stopping_queue=None): - self._broker = make_broker(self, self._max_workers, starting_queue, - stopping_queue) - - def test_name(self): - self.make_broker() - worker = self._broker.start_worker(1) - self.assertEquals(worker.name(), WORKER_NAME) - worker.cancel() - worker.join(0.1) - self.assertFalse(worker.is_alive()) - self._broker.cleanup() - - def test_cancel(self): - self.make_broker() - worker = self._broker.start_worker(1) - self._broker.post_message('test_list', 1, 'hello, world') - worker.cancel() - worker.join(0.1) - self.assertFalse(worker.is_alive()) - self._broker.cleanup() - - def test_done(self): - self.make_broker() - worker = self._broker.start_worker(1) - self._broker.post_message('test_list', 1, 'hello, world') - self._broker.post_message('stop') - self._broker.run_message_loop() - worker.join(0.5) - self.assertFalse(worker.is_alive()) - self.assertTrue(self.is_done()) - self.assertEqual(self._an_int, 2) - self._broker.cleanup() - - def test_unknown_message(self): - self.make_broker() - worker = self._broker.start_worker(1) - self._broker.post_message('unknown') - try: - self._broker.run_message_loop() - self.fail() - except ValueError, e: - self.assertEquals(str(e), - "%s: received message 'unknown' it couldn't handle" % WORKER_NAME) - finally: - worker.join(0.5) - self.assertFalse(worker.is_alive()) - self._broker.cleanup() - - -class InlineBrokerTests(_TestsMixin, unittest.TestCase): - def setUp(self): - _TestsMixin.setUp(self) - self._max_workers = 1 - - -# FIXME: https://bugs.webkit.org/show_bug.cgi?id=54520. -if sys.platform not in ('cygwin', 'win32'): - - class MultiProcessBrokerTests(_TestsMixin, unittest.TestCase): - def setUp(self): - _TestsMixin.setUp(self) - self._max_workers = 2 - - -class MessageTest(unittest.TestCase): - def test__no_body(self): - msg = manager_worker_broker._Message('src', 'topic_name', 'message_name', None) - self.assertTrue(repr(msg)) - s = msg.dumps() - new_msg = manager_worker_broker._Message.loads(s) - self.assertEqual(new_msg.name, 'message_name') - self.assertEqual(new_msg.args, None) - self.assertEqual(new_msg.topic_name, 'topic_name') - self.assertEqual(new_msg.src, 'src') - - def test__body(self): - msg = manager_worker_broker._Message('src', 'topic_name', 'message_name', ('body', 0)) - self.assertTrue(repr(msg)) - s = msg.dumps() - new_msg = manager_worker_broker._Message.loads(s) - self.assertEqual(new_msg.name, 'message_name') - self.assertEqual(new_msg.args, ('body', 0)) - self.assertEqual(new_msg.topic_name, 'topic_name') - self.assertEqual(new_msg.src, 'src') - - - -if __name__ == '__main__': - unittest.main() diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/test_result_writer.py b/Tools/Scripts/webkitpy/layout_tests/controllers/test_result_writer.py index 62d214ee9..243a11d8d 100644 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/test_result_writer.py +++ b/Tools/Scripts/webkitpy/layout_tests/controllers/test_result_writer.py @@ -40,6 +40,7 @@ def write_test_result(filesystem, port, test_name, driver_output, """Write the test result to the result output directory.""" root_output_dir = port.results_directory() writer = TestResultWriter(filesystem, port, root_output_dir, test_name) + if driver_output.error: writer.write_stderr(driver_output.error) @@ -74,10 +75,10 @@ def write_test_result(filesystem, port, test_name, driver_output, failure.diff_percent = diff_percent else: _log.warn('Can not get image diff. ImageDiff program might not work correctly.') - writer.copy_file(failure.reference_filename) + writer.write_reftest(failure.reference_filename) elif isinstance(failure, test_failures.FailureReftestMismatchDidNotOccur): writer.write_image_files(driver_output.image, expected_image=None) - writer.copy_file(failure.reference_filename) + writer.write_reftest(failure.reference_filename) else: assert isinstance(failure, (test_failures.FailureTimeout, test_failures.FailureReftestNoImagesGenerated)) @@ -124,6 +125,16 @@ class TestResultWriter(object): output_filename = fs.join(self._root_output_dir, self._test_name) return fs.splitext(output_filename)[0] + modifier + def _write_binary_file(self, path, contents): + if contents is not None: + self._make_output_directory() + self._filesystem.write_binary_file(path, contents) + + def _write_text_file(self, path, contents): + if contents is not None: + self._make_output_directory() + self._filesystem.write_text_file(path, contents) + def _output_testname(self, modifier): fs = self._filesystem return fs.splitext(fs.basename(self._test_name))[0] + modifier @@ -141,28 +152,19 @@ class TestResultWriter(object): output: A string containing the test output expected: A string containing the expected test output """ - self._make_output_directory() actual_filename = self.output_filename(self.FILENAME_SUFFIX_ACTUAL + file_type) expected_filename = self.output_filename(self.FILENAME_SUFFIX_EXPECTED + file_type) - fs = self._filesystem - if output is not None: - fs.write_binary_file(actual_filename, output) - if expected is not None: - fs.write_binary_file(expected_filename, expected) + self._write_binary_file(actual_filename, output) + self._write_binary_file(expected_filename, expected) def write_stderr(self, error): - fs = self._filesystem filename = self.output_filename(self.FILENAME_SUFFIX_STDERR + ".txt") - fs.maybe_make_directory(fs.dirname(filename)) - fs.write_binary_file(filename, error) + self._write_binary_file(filename, error) def write_crash_log(self, crash_log): - fs = self._filesystem filename = self.output_filename(self.FILENAME_SUFFIX_CRASH_LOG + ".txt") - fs.maybe_make_directory(fs.dirname(filename)) - if crash_log is not None: - fs.write_text_file(filename, crash_log) + self._write_text_file(filename, crash_log) def write_text_files(self, actual_text, expected_text): self.write_output_files(".txt", actual_text, expected_text) @@ -173,28 +175,26 @@ class TestResultWriter(object): if not actual_text or not expected_text: return - self._make_output_directory() file_type = '.txt' actual_filename = self.output_filename(self.FILENAME_SUFFIX_ACTUAL + file_type) expected_filename = self.output_filename(self.FILENAME_SUFFIX_EXPECTED + file_type) - fs = self._filesystem # We treat diff output as binary. Diff output may contain multiple files # in conflicting encodings. diff = self._port.diff_text(expected_text, actual_text, expected_filename, actual_filename) diff_filename = self.output_filename(self.FILENAME_SUFFIX_DIFF + file_type) - fs.write_binary_file(diff_filename, diff) + self._write_binary_file(diff_filename, diff) # Shell out to wdiff to get colored inline diffs. if self._port.wdiff_available(): wdiff = self._port.wdiff_text(expected_filename, actual_filename) wdiff_filename = self.output_filename(self.FILENAME_SUFFIX_WDIFF) - fs.write_binary_file(wdiff_filename, wdiff) + self._write_binary_file(wdiff_filename, wdiff) # Use WebKit's PrettyPatch.rb to get an HTML diff. if self._port.pretty_patch_available(): pretty_patch = self._port.pretty_patch_text(diff_filename) pretty_patch_filename = self.output_filename(self.FILENAME_SUFFIX_PRETTY_PATCH) - fs.write_binary_file(pretty_patch_filename, pretty_patch) + self._write_binary_file(pretty_patch_filename, pretty_patch) def write_audio_files(self, actual_audio, expected_audio): self.write_output_files('.wav', actual_audio, expected_audio) @@ -204,8 +204,7 @@ class TestResultWriter(object): def write_image_diff_files(self, image_diff): diff_filename = self.output_filename(self.FILENAME_SUFFIX_IMAGE_DIFF) - fs = self._filesystem - fs.write_binary_file(diff_filename, image_diff) + self._write_binary_file(diff_filename, image_diff) diffs_html_filename = self.output_filename(self.FILENAME_SUFFIX_IMAGE_DIFFS_HTML) # FIXME: old-run-webkit-tests shows the diff percentage as the text contents of the "diff" link. @@ -263,9 +262,8 @@ Difference between images: <a href="%(diff_filename)s">diff</a><br> } self._filesystem.write_text_file(diffs_html_filename, html) - def copy_file(self, src_filepath): + def write_reftest(self, src_filepath): fs = self._filesystem - assert fs.exists(src_filepath), 'src_filepath: %s' % src_filepath - dst_filepath = fs.join(self._root_output_dir, self._port.relative_test_filename(src_filepath)) - self._make_output_directory() - fs.copyfile(src_filepath, dst_filepath) + dst_dir = fs.dirname(fs.join(self._root_output_dir, self._test_name)) + dst_filepath = fs.join(dst_dir, fs.basename(src_filepath)) + self._write_text_file(dst_filepath, fs.read_text_file(src_filepath)) diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py b/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py index c68915916..837aea86b 100644 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py +++ b/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py @@ -41,14 +41,14 @@ _log = logging.getLogger(__name__) class Worker(object): - def __init__(self, worker_connection, worker_number, results_directory, options): - self._worker_connection = worker_connection - self._worker_number = worker_number - self._name = 'worker/%d' % worker_number + def __init__(self, caller, results_directory, options): + self._caller = caller + self._worker_number = caller.worker_number + self._name = caller.name self._results_directory = results_directory self._options = options - # The remaining fields are initialized in safe_init() + # The remaining fields are initialized in start() self._host = None self._port = None self._batch_size = None @@ -59,12 +59,13 @@ class Worker(object): self._tests_run_filename = None def __del__(self): - self.cleanup() + self.stop() - def safe_init(self): - """This method is called when it is safe for the object to create state that - does not need to be pickled (usually this means it is called in a child process).""" - self._host = self._worker_connection.host + def start(self): + """This method is called when the object is starting to be used and it is safe + for the object to create state that does not need to be pickled (usually this means + it is called in a child process).""" + self._host = self._caller.host self._filesystem = self._host.filesystem self._port = self._host.port_factory.get(self._options.platform, self._options) @@ -73,18 +74,13 @@ class Worker(object): tests_run_filename = self._filesystem.join(self._results_directory, "tests_run%d.txt" % self._worker_number) self._tests_run_file = self._filesystem.open_text_file_for_writing(tests_run_filename) - def handle(self, name, source, list_name, test_list): + def handle(self, name, source, test_list_name, test_inputs): assert name == 'test_list' start_time = time.time() - num_tests = 0 - for test_input in test_list: - self._update_test_input(test_input) + for test_input in test_inputs: self._run_test(test_input) - num_tests += 1 - self._worker_connection.yield_to_broker() - elapsed_time = time.time() - start_time - self._worker_connection.post_message('finished_list', list_name, num_tests, elapsed_time) + self._caller.post('finished_test_list', test_list_name, len(test_inputs), elapsed_time) def _update_test_input(self, test_input): test_input.reference_files = self._port.reference_files(test_input.test_name) @@ -99,25 +95,26 @@ class Worker(object): test_input.should_run_pixel_test = False def _run_test(self, test_input): - test_timeout_sec = self.timeout(test_input) + self._update_test_input(test_input) + test_timeout_sec = self._timeout(test_input) start = time.time() - self._worker_connection.post_message('started_test', test_input, test_timeout_sec) + self._caller.post('started_test', test_input, test_timeout_sec) - result = self.run_test_with_timeout(test_input, test_timeout_sec) + result = self._run_test_with_timeout(test_input, test_timeout_sec) elapsed_time = time.time() - start - self._worker_connection.post_message('finished_test', result, elapsed_time) + self._caller.post('finished_test', result, elapsed_time) - self.clean_up_after_test(test_input, result) + self._clean_up_after_test(test_input, result) - def cleanup(self): + def stop(self): _log.debug("%s cleaning up" % self._name) - self.kill_driver() + self._kill_driver() if self._tests_run_file: self._tests_run_file.close() self._tests_run_file = None - def timeout(self, test_input): + def _timeout(self, test_input): """Compute the appropriate timeout value for a test.""" # The DumpRenderTree watchdog uses 2.5x the timeout; we want to be # larger than that. We also add a little more padding if we're @@ -133,7 +130,7 @@ class Worker(object): thread_timeout_sec = driver_timeout_sec + thread_padding_sec return thread_timeout_sec - def kill_driver(self): + def _kill_driver(self): # Be careful about how and when we kill the driver; if driver.stop() # raises an exception, this routine may get re-entered via __del__. driver = self._driver @@ -142,12 +139,12 @@ class Worker(object): _log.debug("%s killing driver" % self._name) driver.stop() - def run_test_with_timeout(self, test_input, timeout): + def _run_test_with_timeout(self, test_input, timeout): if self._options.run_singly: return self._run_test_in_another_thread(test_input, timeout) return self._run_test_in_this_thread(test_input) - def clean_up_after_test(self, test_input, result): + def _clean_up_after_test(self, test_input, result): self._batch_count += 1 test_name = test_input.test_name self._tests_run_file.write(test_name + "\n") @@ -155,7 +152,7 @@ class Worker(object): if result.failures: # Check and kill DumpRenderTree if we need to. if any([f.driver_needs_restart() for f in result.failures]): - self.kill_driver() + self._kill_driver() # Reset the batch count since the shell just bounced. self._batch_count = 0 @@ -169,7 +166,7 @@ class Worker(object): _log.debug("%s %s passed" % (self._name, test_name)) if self._batch_size > 0 and self._batch_count >= self._batch_size: - self.kill_driver() + self._kill_driver() self._batch_count = 0 def _run_test_in_another_thread(self, test_input, thread_timeout_sec): @@ -195,7 +192,7 @@ class Worker(object): self.result = None def run(self): - self.result = worker.run_single_test(driver, test_input) + self.result = worker._run_single_test(driver, test_input) thread = SingleTestThread() thread.start() @@ -227,11 +224,11 @@ class Worker(object): Returns: a TestResult object. """ if self._driver and self._driver.has_crashed(): - self.kill_driver() + self._kill_driver() if not self._driver: self._driver = self._port.create_driver(self._worker_number) - return self.run_single_test(self._driver, test_input) + return self._run_single_test(self._driver, test_input) - def run_single_test(self, driver, test_input): + def _run_single_test(self, driver, test_input): return single_test_runner.run_single_test(self._port, self._options, test_input, driver, self._name) diff --git a/Tools/Scripts/webkitpy/layout_tests/models/result_summary.py b/Tools/Scripts/webkitpy/layout_tests/models/result_summary.py index 27c5452c0..d46703e8f 100644 --- a/Tools/Scripts/webkitpy/layout_tests/models/result_summary.py +++ b/Tools/Scripts/webkitpy/layout_tests/models/result_summary.py @@ -47,6 +47,7 @@ class ResultSummary(object): self.unexpected_results = {} self.failures = {} self.total_failures = 0 + self.expected_skips = 0 self.total_tests_by_expectation[SKIP] = 0 self.tests_by_expectation[SKIP] = set() for expectation in TestExpectations.EXPECTATIONS.values(): @@ -65,6 +66,8 @@ class ResultSummary(object): self.failures[test_result.test_name] = test_result.failures if expected: self.expected += 1 + if test_result.type == SKIP: + self.expected_skips += 1 else: self.unexpected_results[test_result.test_name] = test_result self.unexpected += 1 diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_configuration.py b/Tools/Scripts/webkitpy/layout_tests/models/test_configuration.py index e9607279b..95d0f2b87 100644 --- a/Tools/Scripts/webkitpy/layout_tests/models/test_configuration.py +++ b/Tools/Scripts/webkitpy/layout_tests/models/test_configuration.py @@ -26,7 +26,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import itertools class TestConfiguration(object): def __init__(self, version, architecture, build_type): @@ -212,8 +211,8 @@ class TestConfigurationConverter(object): break else: return - indices[i] += 1 - for j in range(i + 1, r): + indices[i] += 1 # pylint: disable=W0631 + for j in range(i + 1, r): # pylint: disable=W0631 indices[j] = indices[j - 1] + 1 yield tuple(pool[i] for i in indices) diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_configuration_unittest.py b/Tools/Scripts/webkitpy/layout_tests/models/test_configuration_unittest.py index c367b7591..5c43b6ac6 100644 --- a/Tools/Scripts/webkitpy/layout_tests/models/test_configuration_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/models/test_configuration_unittest.py @@ -28,8 +28,6 @@ import unittest -from webkitpy.common.host_mock import MockHost - from webkitpy.layout_tests.models.test_configuration import * @@ -77,7 +75,7 @@ class TestConfigurationTest(unittest.TestCase): self.assertTrue(config_dict[TestConfiguration('xp', 'x86', 'release')]) def query_unknown_key(): - config_dict[TestConfiguration('xp', 'x86', 'debug')] + return config_dict[TestConfiguration('xp', 'x86', 'debug')] self.assertRaises(KeyError, query_unknown_key) self.assertTrue(TestConfiguration('xp', 'x86', 'release') in config_dict) @@ -88,8 +86,6 @@ class TestConfigurationTest(unittest.TestCase): def test_eq(self): self.assertEquals(TestConfiguration('xp', 'x86', 'release'), TestConfiguration('xp', 'x86', 'release')) - host = MockHost() - test_port = host.port_factory.get('test-win-xp', None) self.assertNotEquals(TestConfiguration('xp', 'x86', 'release'), TestConfiguration('xp', 'x86', 'debug')) def test_values(self): diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py index 93ef517f4..9c6d478d4 100644 --- a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py +++ b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py @@ -31,12 +31,10 @@ for layout tests. """ -import itertools -import json import logging import re -from webkitpy.layout_tests.models.test_configuration import TestConfiguration, TestConfigurationConverter +from webkitpy.layout_tests.models.test_configuration import TestConfigurationConverter _log = logging.getLogger(__name__) @@ -117,6 +115,7 @@ def strip_comments(line): class ParseError(Exception): def __init__(self, warnings): + super(ParseError, self).__init__() self.warnings = warnings def __str__(self): @@ -400,9 +399,10 @@ class TestExpectationLine(object): def __init__(self): """Initializes a blank-line equivalent of an expectation.""" self.original_string = None + self.filename = None # this is the path to the expectations file for this line self.line_number = None - self.name = None - self.path = None + self.name = None # this is the path in the line itself + self.path = None # this is the normpath of self.name self.modifiers = [] self.parsed_modifiers = [] self.parsed_bug_modifiers = [] @@ -515,6 +515,25 @@ class TestExpectationsModel(object): def get_expectations(self, test): return self._test_to_expectations[test] + def get_expectations_string(self, test): + """Returns the expectatons for the given test as an uppercase string. + If there are no expectations for the test, then "PASS" is returned.""" + expectations = self.get_expectations(test) + retval = [] + + for expectation in expectations: + retval.append(self.expectation_to_string(expectation)) + + return " ".join(retval) + + def expectation_to_string(self, expectation): + """Return the uppercased string equivalent of a given expectation.""" + for item in TestExpectations.EXPECTATIONS.items(): + if item[1] == expectation: + return item[0].upper() + raise ValueError(expectation) + + def add_expectation_line(self, expectation_line, in_skipped=False): """Returns a list of warnings encountered while matching modifiers.""" @@ -525,7 +544,7 @@ class TestExpectationsModel(object): if not in_skipped and self._already_seen_better_match(test, expectation_line): continue - self._clear_expectations_for_test(test, expectation_line) + self._clear_expectations_for_test(test) self._test_to_expectation_line[test] = expectation_line self._add_test(test, expectation_line) @@ -559,7 +578,7 @@ class TestExpectationsModel(object): # FIXME: What is this? self._result_type_to_tests[FAIL].add(test) - def _clear_expectations_for_test(self, test, expectation_line): + def _clear_expectations_for_test(self, test): """Remove prexisting expectations for this test. This happens if we are seeing a more precise path than a previous listing. @@ -571,13 +590,13 @@ class TestExpectationsModel(object): self._remove_from_sets(test, self._timeline_to_tests) self._remove_from_sets(test, self._result_type_to_tests) - def _remove_from_sets(self, test, dict): + def _remove_from_sets(self, test, dict_of_sets_of_tests): """Removes the given test from the sets in the dictionary. Args: test: test to look for dict: dict of sets of files""" - for set_of_tests in dict.itervalues(): + for set_of_tests in dict_of_sets_of_tests.itervalues(): if test in set_of_tests: set_of_tests.remove(test) @@ -782,22 +801,10 @@ class TestExpectations(object): return self._model.get_tests_with_timeline(timeline) def get_expectations_string(self, test): - """Returns the expectatons for the given test as an uppercase string. - If there are no expectations for the test, then "PASS" is returned.""" - expectations = self._model.get_expectations(test) - retval = [] - - for expectation in expectations: - retval.append(self.expectation_to_string(expectation)) - - return " ".join(retval) + return self._model.get_expectations_string(test) def expectation_to_string(self, expectation): - """Return the uppercased string equivalent of a given expectation.""" - for item in self.EXPECTATIONS.items(): - if item[1] == expectation: - return item[0].upper() - raise ValueError(expectation) + return self._model.expectation_to_string(expectation) def matches_an_expected_result(self, test, result, pixel_tests_are_enabled): expected_results = self._model.get_expectations(test) @@ -820,7 +827,8 @@ class TestExpectations(object): warnings = [] for expectation in self._expectations: for warning in expectation.warnings: - warnings.append('%s:%d %s %s' % (self._shorten_filename(expectation.filename), expectation.line_number, warning, expectation.name if expectation.expectations else expectation.original_string)) + warnings.append('%s:%d %s %s' % (self._shorten_filename(expectation.filename), expectation.line_number, + warning, expectation.name if expectation.expectations else expectation.original_string)) if warnings: self._has_warnings = True diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py index 7b589b501..c780dac23 100644 --- a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py @@ -95,7 +95,7 @@ class Base(unittest.TestCase): # Note that all of these tests are written assuming the configuration # being tested is Windows XP, Release build. - def __init__(self, testFunc, setUp=None, tearDown=None, description=None): + def __init__(self, testFunc): host = MockHost() self._port = host.port_factory.get('test-win-xp', None) self._exp = None @@ -123,11 +123,11 @@ BUG_TEST WONTFIX MAC : failures/expected/image.html = IMAGE """ def parse_exp(self, expectations, overrides=None, is_lint_mode=False): - self._expectations_dict = OrderedDict() - self._expectations_dict['expectations'] = expectations + expectations_dict = OrderedDict() + expectations_dict['expectations'] = expectations if overrides: - self._expectations_dict['overrides'] = overrides - self._port.expectations_dict = lambda: self._expectations_dict + expectations_dict['overrides'] = overrides + self._port.expectations_dict = lambda: expectations_dict self._exp = TestExpectations(self._port, self.get_basic_tests(), is_lint_mode) def assert_exp(self, test, result): @@ -274,11 +274,11 @@ class SkippedTests(Base): def check(self, expectations, overrides, skips, lint=False): port = MockHost().port_factory.get('qt') port._filesystem.write_text_file(port._filesystem.join(port.layout_tests_dir(), 'failures/expected/text.html'), 'foo') - self._expectations_dict = OrderedDict() - self._expectations_dict['expectations'] = expectations + expectations_dict = OrderedDict() + expectations_dict['expectations'] = expectations if overrides: - self._expectations_dict['overrides'] = overrides - port.expectations_dict = lambda: self._expectations_dict + expectations_dict['overrides'] = overrides + port.expectations_dict = lambda: expectations_dict port.skipped_layout_tests = lambda tests: set(skips) exp = TestExpectations(port, ['failures/expected/text.html'], lint) @@ -532,7 +532,6 @@ class TestExpectationParserTests(unittest.TestCase): host = MockHost() test_port = host.port_factory.get('test-win-xp', None) test_port.test_exists = lambda test: True - test_config = test_port.test_configuration() full_test_list = [] expectation_line = self._tokenize('') parser = TestExpectationParser(test_port, full_test_list, allow_rebaseline_modifier=False) diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_failures.py b/Tools/Scripts/webkitpy/layout_tests/models/test_failures.py index 029094ec4..afea52e60 100644 --- a/Tools/Scripts/webkitpy/layout_tests/models/test_failures.py +++ b/Tools/Scripts/webkitpy/layout_tests/models/test_failures.py @@ -112,6 +112,7 @@ class TestFailure(object): class FailureTimeout(TestFailure): """Test timed out. We also want to restart DumpRenderTree if this happens.""" def __init__(self, is_reftest=False): + super(FailureTimeout, self).__init__() self.is_reftest = is_reftest def message(self): @@ -124,6 +125,7 @@ class FailureTimeout(TestFailure): class FailureCrash(TestFailure): """DumpRenderTree/WebKitTestRunner crashed.""" def __init__(self, is_reftest=False, process_name='DumpRenderTree', pid=None): + super(FailureCrash, self).__init__() self.process_name = process_name self.pid = pid self.is_reftest = is_reftest @@ -168,6 +170,7 @@ class FailureMissingImage(TestFailure): class FailureImageHashMismatch(TestFailure): """Image hashes didn't match.""" def __init__(self, diff_percent=0): + super(FailureImageHashMismatch, self).__init__() self.diff_percent = diff_percent def message(self): @@ -185,6 +188,7 @@ class FailureReftestMismatch(TestFailure): """The result didn't match the reference rendering.""" def __init__(self, reference_filename=None): + super(FailureReftestMismatch, self).__init__() self.reference_filename = reference_filename self.diff_percent = None @@ -196,6 +200,7 @@ class FailureReftestMismatchDidNotOccur(TestFailure): """Unexpected match between the result and the reference rendering.""" def __init__(self, reference_filename=None): + super(FailureReftestMismatchDidNotOccur, self).__init__() self.reference_filename = reference_filename def message(self): @@ -206,6 +211,7 @@ class FailureReftestNoImagesGenerated(TestFailure): """Both the reftest and the -expected html file didn't generate pixel results.""" def __init__(self, reference_filename=None): + super(FailureReftestNoImagesGenerated, self).__init__() self.reference_filename = reference_filename def message(self): diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_failures_unittest.py b/Tools/Scripts/webkitpy/layout_tests/models/test_failures_unittest.py index 3b9ba33d0..e096b171f 100644 --- a/Tools/Scripts/webkitpy/layout_tests/models/test_failures_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/models/test_failures_unittest.py @@ -45,10 +45,14 @@ class TestFailuresTest(unittest.TestCase): def test_unknown_failure_type(self): class UnknownFailure(TestFailure): - pass + def message(self): + return '' failure_obj = UnknownFailure() self.assertRaises(ValueError, determine_result_type, [failure_obj]) + + def test_message_is_virtual(self): + failure_obj = TestFailure() self.assertRaises(NotImplementedError, failure_obj.message) def test_loads(self): diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_results.py b/Tools/Scripts/webkitpy/layout_tests/models/test_results.py index 51ac505c2..346d5a640 100644 --- a/Tools/Scripts/webkitpy/layout_tests/models/test_results.py +++ b/Tools/Scripts/webkitpy/layout_tests/models/test_results.py @@ -35,8 +35,8 @@ class TestResult(object): """Data object containing the results of a single test.""" @staticmethod - def loads(str): - return cPickle.loads(str) + def loads(string): + return cPickle.loads(string) def __init__(self, test_name, failures=None, test_run_time=None, has_stderr=False): self.test_name = test_name @@ -54,9 +54,9 @@ class TestResult(object): def __ne__(self, other): return not (self == other) - def has_failure_matching_types(self, *args, **kargs): + def has_failure_matching_types(self, *failure_classes): for failure in self.failures: - if type(failure) in args: + if type(failure) in failure_classes: return True return False diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py index 2a1877407..2240657c1 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py @@ -518,7 +518,7 @@ class ChromiumAndroidDriver(chromium.ChromiumDriver): def _start_once(self, pixel_tests, per_test_args): self._port._run_adb_command(['logcat', '-c']) self._port._run_adb_command(['shell', 'echo'] + self.cmd_line(pixel_tests, per_test_args) + ['>', COMMAND_LINE_FILE]) - start_result = self._port._run_adb_command(['shell', 'am', 'start', '-n', DRT_ACTIVITY_FULL_NAME]) + start_result = self._port._run_adb_command(['shell', 'am', 'start', '-e', 'RunInSubThread', '-n', DRT_ACTIVITY_FULL_NAME]) if start_result.find('Exception') != -1: _log.error('Failed to start DumpRenderTree application. Exception:\n' + start_result) return False diff --git a/Tools/Scripts/webkitpy/layout_tests/port/efl.py b/Tools/Scripts/webkitpy/layout_tests/port/efl.py index 5964dfe52..4e43f8b6e 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/efl.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/efl.py @@ -45,6 +45,7 @@ class EflPort(WebKitPort, PulseAudioSanitizer): self._jhbuild_wrapper_path = self.path_from_webkit_base('Tools', 'efl', 'run-with-jhbuild') self.set_option_default('wrapper', self._jhbuild_wrapper_path) + self.webprocess_cmd_prefix = self.get_option('webprocess_cmd_prefix') def _port_flag_for_scripts(self): return "--efl" @@ -56,6 +57,8 @@ class EflPort(WebKitPort, PulseAudioSanitizer): env = super(EflPort, self).setup_environ_for_server(server_name) env['TEST_RUNNER_INJECTED_BUNDLE_FILENAME'] = self._build_path('lib', 'libTestRunnerInjectedBundle.so') env['TEST_RUNNER_PLUGIN_PATH'] = self._build_path('lib') + if self.webprocess_cmd_prefix: + env['WEB_PROCESS_CMD_PREFIX'] = self.webprocess_cmd_prefix return env def clean_up_test_run(self): diff --git a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py index e3a13c20f..691c8456b 100755 --- a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py +++ b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py @@ -35,6 +35,7 @@ import optparse import os import signal import sys +import traceback from webkitpy.common.host import Host from webkitpy.common.system import stack_utils @@ -131,6 +132,7 @@ def run(port, options, args, regular_output=sys.stderr, buildbot_output=sys.stdo except Exception: exception_type, exception_value, exception_traceback = sys.exc_info() if exception_type not in (KeyboardInterrupt, TestRunInterruptedException, WorkerException): + print >> sys.stderr, '\n%s raised: %s' % (exception_type.__name__, exception_value) stack_utils.log_traceback(_log.error, exception_traceback) raise finally: @@ -254,6 +256,11 @@ def parse_args(args=None): help="Arguments parsed to Android adb, to select device, etc."), ])) + option_group_definitions.append(("EFL-specific Options", [ + optparse.make_option("--webprocess-cmd-prefix", type="string", + default=False, help="Prefix used when spawning the Web process (Debug mode only)"), + ])) + option_group_definitions.append(("WebKit Options", [ optparse.make_option("--gc-between-tests", action="store_true", default=False, help="Force garbage collection between each test"), @@ -464,6 +471,10 @@ def main(argv=None): # FIXME: is this the best way to handle unsupported port names? print >> sys.stderr, str(e) return EXCEPTIONAL_EXIT_STATUS + except Exception, e: + print >> sys.stderr, '\n%s raised: %s' % (e.__class__.__name__, str(e)) + traceback.print_exc(file=sys.stderr) + raise logging.getLogger().setLevel(logging.DEBUG if options.verbose else logging.INFO) return run(port, options, args) @@ -472,7 +483,7 @@ def main(argv=None): if '__main__' == __name__: try: sys.exit(main()) - except Exception, e: + except BaseException, e: if e.__class__ in (KeyboardInterrupt, TestRunInterruptedException): sys.exit(INTERRUPTED_EXIT_STATUS) sys.exit(EXCEPTIONAL_EXIT_STATUS) diff --git a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py index c106fbf47..ad14bf4ef 100755 --- a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py +++ b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py @@ -51,7 +51,7 @@ from webkitpy.common.host_mock import MockHost from webkitpy.layout_tests import port from webkitpy.layout_tests import run_webkit_tests -from webkitpy.layout_tests.controllers.manager_worker_broker import WorkerException +from webkitpy.layout_tests.controllers.manager import WorkerException from webkitpy.layout_tests.port import Port from webkitpy.layout_tests.port.test import TestPort, TestDriver from webkitpy.test.skip import skip_if @@ -951,11 +951,11 @@ class EndToEndTest(unittest.TestCase): self.assertTrue("multiple-mismatch-success.html" not in json["tests"]["reftests"]["foo"]) self.assertTrue("multiple-both-success.html" not in json["tests"]["reftests"]["foo"]) self.assertEqual(json["tests"]["reftests"]["foo"]["multiple-match-failure.html"], - {"expected": "PASS", "ref_file": "reftests/foo/second-mismatching-ref.html", "actual": "IMAGE", "image_diff_percent": 1, 'is_reftest': True}) + {"expected": "PASS", "actual": "IMAGE", "image_diff_percent": 1, 'is_reftest': True}) self.assertEqual(json["tests"]["reftests"]["foo"]["multiple-mismatch-failure.html"], - {"expected": "PASS", "ref_file": "reftests/foo/matching-ref.html", "actual": "IMAGE", "is_mismatch_reftest": True}) + {"expected": "PASS", "actual": "IMAGE", "is_mismatch_reftest": True}) self.assertEqual(json["tests"]["reftests"]["foo"]["multiple-both-failure.html"], - {"expected": "PASS", "ref_file": "reftests/foo/matching-ref.html", "actual": "IMAGE", "is_mismatch_reftest": True}) + {"expected": "PASS", "actual": "IMAGE", "is_mismatch_reftest": True}) class RebaselineTest(unittest.TestCase, StreamTestingMixin): diff --git a/Tools/Scripts/webkitpy/layout_tests/views/printing.py b/Tools/Scripts/webkitpy/layout_tests/views/printing.py index 3d98c6c59..2dd909930 100644 --- a/Tools/Scripts/webkitpy/layout_tests/views/printing.py +++ b/Tools/Scripts/webkitpy/layout_tests/views/printing.py @@ -31,6 +31,7 @@ import optparse +from webkitpy.tool import grammar from webkitpy.common.net import resultsjsonparser from webkitpy.layout_tests.models.test_expectations import TestExpectations from webkitpy.layout_tests.views.metered_stream import MeteredStream @@ -217,23 +218,21 @@ class Printer(object): return incomplete = total - expected - unexpected + incomplete_str = '' if incomplete: self._write("") incomplete_str = " (%d didn't run)" % incomplete - expected_str = str(expected) - else: - incomplete_str = "" - expected_str = "All %d" % expected if unexpected == 0: - self._write("%s tests ran as expected%s." % - (expected_str, incomplete_str)) - elif expected == 1: - self._write("1 test ran as expected, %d didn't%s:" % - (unexpected, incomplete_str)) + if expected == total: + if expected > 1: + self._write("All %d tests ran as expected." % expected) + else: + self._write("The test ran as expected.") + else: + self._write("%s ran as expected%s." % (grammar.pluralize('test', expected), incomplete_str)) else: - self._write("%d tests ran as expected, %d didn't%s:" % - (expected, unexpected, incomplete_str)) + self._write("%s ran as expected, %d didn't%s:" % (grammar.pluralize('test', expected), unexpected, incomplete_str)) self._write("") def print_test_result(self, result, expected, exp_str, got_str): diff --git a/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py b/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py index 56970a863..1312050e9 100644 --- a/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py @@ -206,11 +206,11 @@ class Testprinter(unittest.TestCase): printer, err, out = self.get_printer(['--print', 'one-line-summary']) printer.print_one_line_summary(1, 1, 0) - self.assertWritten(err, ["All 1 tests ran as expected.\n", "\n"]) + self.assertWritten(err, ["The test ran as expected.\n", "\n"]) printer, err, out = self.get_printer(['--print', 'everything']) printer.print_one_line_summary(1, 1, 0) - self.assertWritten(err, ["All 1 tests ran as expected.\n", "\n"]) + self.assertWritten(err, ["The test ran as expected.\n", "\n"]) printer, err, out = self.get_printer(['--print', 'everything']) printer.print_one_line_summary(2, 1, 1) diff --git a/Tools/Scripts/webkitpy/pylintrc b/Tools/Scripts/webkitpy/pylintrc index dae778d63..bdd040415 100644 --- a/Tools/Scripts/webkitpy/pylintrc +++ b/Tools/Scripts/webkitpy/pylintrc @@ -85,13 +85,15 @@ load-plugins= # W0141: Used builtin function '' # W0212: Access to a protected member X of a client class # W0142: Used * or ** magic +# W0401: Wildcard import X # W0402: Uses of a deprecated module 'string' # W0404: 41: Reimport 'XX' (imported line NN) # W0511: TODO # W0603: Using the global statement +# W0614: Unused import X from wildcard import # W0703: Catch "Exception" # W1201: Specify string format arguments as logging function parameters -disable=C0103,C0111,C0302,I0010,I0011,R0201,R0801,R0901,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,R0921,R0922,W0122,W0141,W0142,W0212,W0402,W0404,W0511,W0603,W0703,W1201 +disable=C0103,C0111,C0302,I0010,I0011,R0201,R0801,R0901,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,R0921,R0922,W0122,W0141,W0142,W0212,W0401,W0402,W0404,W0511,W0603,W0614,W0703,W1201 [REPORTS] diff --git a/Tools/Scripts/webkitpy/test/test_finder.py b/Tools/Scripts/webkitpy/test/finder.py index 3a90197e9..132072d82 100644 --- a/Tools/Scripts/webkitpy/test/test_finder.py +++ b/Tools/Scripts/webkitpy/test/finder.py @@ -31,7 +31,7 @@ import sys _log = logging.getLogger(__name__) -class TestDirectoryTree(object): +class _DirectoryTree(object): def __init__(self, filesystem, top_directory, starting_subdirectory): self.filesystem = filesystem self.top_directory = filesystem.realpath(top_directory) @@ -63,7 +63,6 @@ class TestDirectoryTree(object): return realpath.replace(self.top_directory + self.filesystem.sep, '') return None - def clean(self): """Delete all .pyc files in the tree that have no matching .py file.""" _log.debug("Cleaning orphaned *.pyc files from: %s" % self.search_directory) @@ -74,13 +73,13 @@ class TestDirectoryTree(object): self.filesystem.remove(filename) -class TestFinder(object): +class Finder(object): def __init__(self, filesystem): self.filesystem = filesystem self.trees = [] def add_tree(self, top_directory, starting_subdirectory=None): - self.trees.append(TestDirectoryTree(self.filesystem, top_directory, starting_subdirectory)) + self.trees.append(_DirectoryTree(self.filesystem, top_directory, starting_subdirectory)) def additional_paths(self, paths): return [tree.top_directory for tree in self.trees if tree.top_directory not in paths] diff --git a/Tools/Scripts/webkitpy/test/test_finder_unittest.py b/Tools/Scripts/webkitpy/test/finder_unittest.py index 5b6b3b030..09048b159 100644 --- a/Tools/Scripts/webkitpy/test/test_finder_unittest.py +++ b/Tools/Scripts/webkitpy/test/finder_unittest.py @@ -25,10 +25,10 @@ import unittest from webkitpy.common.system.filesystem_mock import MockFileSystem from webkitpy.common.system.outputcapture import OutputCapture -from webkitpy.test.test_finder import TestFinder +from webkitpy.test.finder import Finder -class TestFinderTest(unittest.TestCase): +class FinderTest(unittest.TestCase): def setUp(self): files = { '/foo/bar/baz.py': '', @@ -40,7 +40,7 @@ class TestFinderTest(unittest.TestCase): '/tmp/another_unittest.py': '', } self.fs = MockFileSystem(files) - self.finder = TestFinder(self.fs) + self.finder = Finder(self.fs) self.finder.add_tree('/foo', 'bar') self.finder.add_tree('/foo2') @@ -49,7 +49,7 @@ class TestFinderTest(unittest.TestCase): self.root_logger = logging.getLogger() self.log_handler = None for h in self.root_logger.handlers: - if getattr(h, 'name', None) == 'webkitpy.test.main': + if getattr(h, 'name', None) == 'webkitpy.test.printer': self.log_handler = h break if self.log_handler: diff --git a/Tools/Scripts/webkitpy/test/main.py b/Tools/Scripts/webkitpy/test/main.py index c5dc39433..2048d9e59 100644 --- a/Tools/Scripts/webkitpy/test/main.py +++ b/Tools/Scripts/webkitpy/test/main.py @@ -25,24 +25,24 @@ import logging import optparse -import os import StringIO import sys import traceback import unittest from webkitpy.common.system.filesystem import FileSystem -from webkitpy.common.system import outputcapture -from webkitpy.test.test_finder import TestFinder -from webkitpy.test.runner import TestRunner +from webkitpy.test.finder import Finder +from webkitpy.test.printer import Printer +from webkitpy.test.runner import Runner _log = logging.getLogger(__name__) class Tester(object): def __init__(self, filesystem=None): - self.finder = TestFinder(filesystem or FileSystem()) - self.stream = sys.stderr + self.finder = Finder(filesystem or FileSystem()) + self.printer = Printer(sys.stderr) + self._options = None def add_tree(self, top_directory, starting_subdirectory=None): self.finder.add_tree(top_directory, starting_subdirectory) @@ -50,13 +50,13 @@ class Tester(object): def _parse_args(self): parser = optparse.OptionParser(usage='usage: %prog [options] [args...]') parser.add_option('-a', '--all', action='store_true', default=False, - help='run all the tests'), + help='run all the tests') parser.add_option('-c', '--coverage', action='store_true', default=False, - help='generate code coverage info (requires http://pypi.python.org/pypi/coverage)'), + help='generate code coverage info (requires http://pypi.python.org/pypi/coverage)') parser.add_option('-q', '--quiet', action='store_true', default=False, - help='run quietly (errors, warnings, and progress only)'), + help='run quietly (errors, warnings, and progress only)') parser.add_option('-t', '--timing', action='store_true', default=False, - help='display per-test execution time (implies --verbose)'), + help='display per-test execution time (implies --verbose)') parser.add_option('-v', '--verbose', action='count', default=0, help='verbose output (specify once for individual test results, twice for debug messages)') parser.add_option('--skip-integrationtests', action='store_true', default=False, @@ -69,72 +69,9 @@ class Tester(object): return parser.parse_args() - def _configure(self, options): - self._options = options - - if options.timing: - # --timing implies --verbose - options.verbose = max(options.verbose, 1) - - log_level = logging.INFO - if options.quiet: - log_level = logging.WARNING - elif options.verbose == 2: - log_level = logging.DEBUG - self._configure_logging(log_level) - - def _configure_logging(self, log_level): - """Configure the root logger. - - Configure the root logger not to log any messages from webkitpy -- - except for messages from the autoinstall module. Also set the - logging level as described below. - """ - handler = logging.StreamHandler(self.stream) - # We constrain the level on the handler rather than on the root - # logger itself. This is probably better because the handler is - # configured and known only to this module, whereas the root logger - # is an object shared (and potentially modified) by many modules. - # Modifying the handler, then, is less intrusive and less likely to - # interfere with modifications made by other modules (e.g. in unit - # tests). - handler.name = __name__ - handler.setLevel(log_level) - formatter = logging.Formatter("%(message)s") - handler.setFormatter(formatter) - - logger = logging.getLogger() - logger.addHandler(handler) - logger.setLevel(logging.NOTSET) - - # Filter out most webkitpy messages. - # - # Messages can be selectively re-enabled for this script by updating - # this method accordingly. - def filter(record): - """Filter out autoinstall and non-third-party webkitpy messages.""" - # FIXME: Figure out a way not to use strings here, for example by - # using syntax like webkitpy.test.__name__. We want to be - # sure not to import any non-Python 2.4 code, though, until - # after the version-checking code has executed. - if (record.name.startswith("webkitpy.common.system.autoinstall") or - record.name.startswith("webkitpy.test")): - return True - if record.name.startswith("webkitpy"): - return False - return True - - testing_filter = logging.Filter() - testing_filter.filter = filter - - # Display a message so developers are not mystified as to why - # logging does not work in the unit tests. - _log.info("Suppressing most webkitpy logging while running unit tests.") - handler.addFilter(testing_filter) - def run(self): - options, args = self._parse_args() - self._configure(options) + self._options, args = self._parse_args() + self.printer.configure(self._options) self.finder.clean_trees() @@ -149,7 +86,7 @@ class Tester(object): if self._options.coverage: try: import webkitpy.thirdparty.autoinstalled.coverage as coverage - except ImportError, e: + except ImportError: _log.error("Failed to import 'coverage'; can't generate coverage numbers.") return False cov = coverage.coverage() @@ -169,7 +106,7 @@ class Tester(object): # produces lousy error messages for bad modules. try: __import__(name) - except ImportError, e: + except ImportError: _log.fatal('Failed to import %s:' % name) self._log_exception() return False @@ -177,11 +114,9 @@ class Tester(object): suites.append(loader.loadTestsFromName(name, None)) test_suite = unittest.TestSuite(suites) - test_runner = TestRunner(self.stream, self._options, loader) + test_runner = Runner(self.printer, self._options, loader) _log.debug("Running the tests.") - if self._options.pass_through: - outputcapture.OutputCapture.stream_wrapper = _CaptureAndPassThroughStream result = test_runner.run(test_suite) if self._options.coverage: cov.stop() @@ -194,32 +129,3 @@ class Tester(object): traceback.print_exc(file=s) for l in s.buflist: _log.error(' ' + l.rstrip()) - - -class _CaptureAndPassThroughStream(object): - def __init__(self, stream): - self._buffer = StringIO.StringIO() - self._stream = stream - - def write(self, msg): - self._stream.write(msg) - - # Note that we don't want to capture any output generated by the debugger - # because that could cause the results of capture_output() to be invalid. - if not self._message_is_from_pdb(): - self._buffer.write(msg) - - def _message_is_from_pdb(self): - # We will assume that if the pdb module is in the stack then the output - # is being generated by the python debugger (or the user calling something - # from inside the debugger). - import inspect - import pdb - stack = inspect.stack() - return any(frame[1] == pdb.__file__.replace('.pyc', '.py') for frame in stack) - - def flush(self): - self._stream.flush() - - def getvalue(self): - return self._buffer.getvalue() diff --git a/Tools/Scripts/webkitpy/test/main_unittest.py b/Tools/Scripts/webkitpy/test/main_unittest.py index 1a60beef3..2cf6df4a2 100644 --- a/Tools/Scripts/webkitpy/test/main_unittest.py +++ b/Tools/Scripts/webkitpy/test/main_unittest.py @@ -40,7 +40,7 @@ class TesterTest(unittest.TestCase): root_handlers = root_logger.handlers root_logger.handlers = [] - tester.stream = errors + tester.printer.stream = errors tester.finder.find_names = lambda args, skip_integration, run_all: [] oc = OutputCapture() try: diff --git a/Tools/Scripts/webkitpy/test/printer.py b/Tools/Scripts/webkitpy/test/printer.py new file mode 100644 index 000000000..77e28b8d1 --- /dev/null +++ b/Tools/Scripts/webkitpy/test/printer.py @@ -0,0 +1,182 @@ +# Copyright (C) 2012 Google, Inc. +# Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import logging +import re +import StringIO + +from webkitpy.common.system import outputcapture + +_log = logging.getLogger(__name__) + + +class Printer(object): + def __init__(self, stream, options=None): + self.stream = stream + self.options = options + self.test_description = re.compile("(\w+) \(([\w.]+)\)") + + def test_name(self, test): + m = self.test_description.match(str(test)) + return "%s.%s" % (m.group(2), m.group(1)) + + def configure(self, options): + self.options = options + + if options.timing: + # --timing implies --verbose + options.verbose = max(options.verbose, 1) + + log_level = logging.INFO + if options.quiet: + log_level = logging.WARNING + elif options.verbose == 2: + log_level = logging.DEBUG + + handler = logging.StreamHandler(self.stream) + # We constrain the level on the handler rather than on the root + # logger itself. This is probably better because the handler is + # configured and known only to this module, whereas the root logger + # is an object shared (and potentially modified) by many modules. + # Modifying the handler, then, is less intrusive and less likely to + # interfere with modifications made by other modules (e.g. in unit + # tests). + handler.name = __name__ + handler.setLevel(log_level) + formatter = logging.Formatter("%(message)s") + handler.setFormatter(formatter) + + logger = logging.getLogger() + logger.addHandler(handler) + logger.setLevel(logging.NOTSET) + + # Filter out most webkitpy messages. + # + # Messages can be selectively re-enabled for this script by updating + # this method accordingly. + def filter_records(record): + """Filter out autoinstall and non-third-party webkitpy messages.""" + # FIXME: Figure out a way not to use strings here, for example by + # using syntax like webkitpy.test.__name__. We want to be + # sure not to import any non-Python 2.4 code, though, until + # after the version-checking code has executed. + if (record.name.startswith("webkitpy.common.system.autoinstall") or + record.name.startswith("webkitpy.test")): + return True + if record.name.startswith("webkitpy"): + return False + return True + + testing_filter = logging.Filter() + testing_filter.filter = filter_records + + # Display a message so developers are not mystified as to why + # logging does not work in the unit tests. + _log.info("Suppressing most webkitpy logging while running unit tests.") + handler.addFilter(testing_filter) + + if self.options.pass_through: + outputcapture.OutputCapture.stream_wrapper = _CaptureAndPassThroughStream + + def print_started_test(self, test_name): + if self.options.verbose: + self.stream.write(test_name) + + def print_finished_test(self, result, test_name, test_time, failure, err): + timing = '' + if self.options.timing: + timing = ' %.4fs' % test_time + if self.options.verbose: + if failure: + msg = ' failed' + elif err: + msg = ' erred' + else: + msg = ' passed' + self.stream.write(msg + timing + '\n') + else: + if failure: + msg = 'F' + elif err: + msg = 'E' + else: + msg = '.' + self.stream.write(msg) + + def print_result(self, result, run_time): + self.stream.write('\n') + + for (test, err) in result.errors: + self.stream.write("=" * 80 + '\n') + self.stream.write("ERROR: " + self.test_name(test) + '\n') + self.stream.write("-" * 80 + '\n') + for line in err.splitlines(): + self.stream.write(line + '\n') + self.stream.write('\n') + + for (test, failure) in result.failures: + self.stream.write("=" * 80 + '\n') + self.stream.write("FAILURE: " + self.test_name(test) + '\n') + self.stream.write("-" * 80 + '\n') + for line in failure.splitlines(): + self.stream.write(line + '\n') + self.stream.write('\n') + + self.stream.write('-' * 80 + '\n') + self.stream.write('Ran %d test%s in %.3fs\n' % + (result.testsRun, result.testsRun != 1 and "s" or "", run_time)) + + if result.wasSuccessful(): + self.stream.write('\nOK\n') + else: + self.stream.write('FAILED (failures=%d, errors=%d)\n' % + (len(result.failures), len(result.errors))) + + +class _CaptureAndPassThroughStream(object): + def __init__(self, stream): + self._buffer = StringIO.StringIO() + self._stream = stream + + def write(self, msg): + self._stream.write(msg) + + # Note that we don't want to capture any output generated by the debugger + # because that could cause the results of capture_output() to be invalid. + if not self._message_is_from_pdb(): + self._buffer.write(msg) + + def _message_is_from_pdb(self): + # We will assume that if the pdb module is in the stack then the output + # is being generated by the python debugger (or the user calling something + # from inside the debugger). + import inspect + import pdb + stack = inspect.stack() + return any(frame[1] == pdb.__file__.replace('.pyc', '.py') for frame in stack) + + def flush(self): + self._stream.flush() + + def getvalue(self): + return self._buffer.getvalue() diff --git a/Tools/Scripts/webkitpy/test/runner.py b/Tools/Scripts/webkitpy/test/runner.py index e190f2cd4..9c952075e 100644 --- a/Tools/Scripts/webkitpy/test/runner.py +++ b/Tools/Scripts/webkitpy/test/runner.py @@ -23,7 +23,6 @@ """code to actually run a list of python tests.""" import logging -import re import time import unittest @@ -31,16 +30,11 @@ import unittest _log = logging.getLogger(__name__) -class TestRunner(object): - def __init__(self, stream, options, loader): +class Runner(object): + def __init__(self, printer, options, loader): self.options = options - self.stream = stream + self.printer = printer self.loader = loader - self.test_description = re.compile("(\w+) \(([\w.]+)\)") - - def test_name(self, test): - m = self.test_description.match(str(test)) - return "%s.%s" % (m.group(2), m.group(1)) def all_test_names(self, suite): names = [] @@ -48,7 +42,7 @@ class TestRunner(object): for t in suite._tests: names.extend(self.all_test_names(t)) else: - names.append(self.test_name(suite)) + names.append(self.printer.test_name(suite)) return names def run(self, suite): @@ -57,8 +51,7 @@ class TestRunner(object): result = unittest.TestResult() stop = run_start_time for test_name in all_test_names: - if self.options.verbose: - self.stream.write(test_name) + self.printer.print_started_test(test_name) num_failures = len(result.failures) num_errors = len(result.errors) @@ -75,58 +68,8 @@ class TestRunner(object): failure = result.failures[num_failures][1] elif len(result.errors) > num_errors: err = result.errors[num_errors][1] - self.write_result(result, test_name, stop - start, failure, err) + self.printer.print_finished_test(result, test_name, stop - start, failure, err) - self.write_summary(result, stop - run_start_time) + self.printer.print_result(result, stop - run_start_time) return result - - def write_result(self, result, test_name, test_time, failure=None, err=None): - timing = '' - if self.options.timing: - timing = ' %.4fs' % test_time - if self.options.verbose: - if failure: - msg = ' failed' - elif err: - msg = ' erred' - else: - msg = ' passed' - self.stream.write(msg + timing + '\n') - else: - if failure: - msg = 'F' - elif err: - msg = 'E' - else: - msg = '.' - self.stream.write(msg) - - def write_summary(self, result, run_time): - self.stream.write('\n') - - for (test, err) in result.errors: - self.stream.write("=" * 80 + '\n') - self.stream.write("ERROR: " + self.test_name(test) + '\n') - self.stream.write("-" * 80 + '\n') - for line in err.splitlines(): - self.stream.write(line + '\n') - self.stream.write('\n') - - for (test, failure) in result.failures: - self.stream.write("=" * 80 + '\n') - self.stream.write("FAILURE: " + self.test_name(test) + '\n') - self.stream.write("-" * 80 + '\n') - for line in failure.splitlines(): - self.stream.write(line + '\n') - self.stream.write('\n') - - self.stream.write('-' * 80 + '\n') - self.stream.write('Ran %d test%s in %.3fs\n' % - (result.testsRun, result.testsRun != 1 and "s" or "", run_time)) - - if result.wasSuccessful(): - self.stream.write('\nOK\n') - else: - self.stream.write('FAILED (failures=%d, errors=%d)\n' % - (len(result.failures), len(result.errors))) diff --git a/Tools/Scripts/webkitpy/test/runner_unittest.py b/Tools/Scripts/webkitpy/test/runner_unittest.py index e2ea31aa1..1cf0146fb 100644 --- a/Tools/Scripts/webkitpy/test/runner_unittest.py +++ b/Tools/Scripts/webkitpy/test/runner_unittest.py @@ -25,7 +25,8 @@ import StringIO import unittest from webkitpy.tool.mocktool import MockOptions -from webkitpy.test.runner import TestRunner +from webkitpy.test.printer import Printer +from webkitpy.test.runner import Runner class FakeModuleSuite(object): @@ -74,7 +75,7 @@ class RunnerTest(unittest.TestCase): loader = FakeLoader(('test1 (Foo)', '.', ''), ('test2 (Foo)', 'F', 'test2\nfailed'), ('test3 (Foo)', 'E', 'test3\nerred')) - result = TestRunner(stream, options, loader).run(loader.top_suite()) + result = Runner(Printer(stream, options), options, loader).run(loader.top_suite()) self.assertFalse(result.wasSuccessful()) self.assertEquals(result.testsRun, 3) self.assertEquals(len(result.failures), 1) @@ -87,7 +88,7 @@ class RunnerTest(unittest.TestCase): loader = FakeLoader(('test1 (Foo)', '.', ''), ('test2 (Foo)', 'F', 'test2\nfailed'), ('test3 (Foo)', 'E', 'test3\nerred')) - result = TestRunner(stream, options, loader).run(loader.top_suite()) + result = Runner(Printer(stream, options), options, loader).run(loader.top_suite()) self.assertFalse(result.wasSuccessful()) self.assertEquals(result.testsRun, 3) self.assertEquals(len(result.failures), 1) @@ -100,7 +101,7 @@ class RunnerTest(unittest.TestCase): loader = FakeLoader(('test1 (Foo)', '.', ''), ('test2 (Foo)', 'F', 'test2\nfailed'), ('test3 (Foo)', 'E', 'test3\nerred')) - result = TestRunner(stream, options, loader).run(loader.top_suite()) + result = Runner(Printer(stream, options), options, loader).run(loader.top_suite()) self.assertFalse(result.wasSuccessful()) self.assertEquals(result.testsRun, 3) self.assertEquals(len(result.failures), 1) diff --git a/Tools/Scripts/webkitpy/tool/commands/queues.py b/Tools/Scripts/webkitpy/tool/commands/queues.py index 2af08b718..e8db17c7b 100644 --- a/Tools/Scripts/webkitpy/tool/commands/queues.py +++ b/Tools/Scripts/webkitpy/tool/commands/queues.py @@ -38,6 +38,7 @@ from optparse import make_option from StringIO import StringIO from webkitpy.common.config.committervalidator import CommitterValidator +from webkitpy.common.config.ports import DeprecatedPort from webkitpy.common.net.bugzilla import Attachment from webkitpy.common.net.statusserver import StatusServer from webkitpy.common.system.deprecated_logging import error, log @@ -257,10 +258,17 @@ class AbstractPatchQueue(AbstractQueue): class CommitQueue(AbstractPatchQueue, StepSequenceErrorHandler, CommitQueueTaskDelegate): name = "commit-queue" + port_name = "chromium-xvfb" + + def __init__(self): + AbstractPatchQueue.__init__(self) + self.port = DeprecatedPort.port(self.port_name) # AbstractPatchQueue methods def begin_work_queue(self): + # FIXME: This violates abstraction + self._tool._deprecated_port = self.port AbstractPatchQueue.begin_work_queue(self) self.committer_validator = CommitterValidator(self._tool) self._expected_failures = ExpectedFailures() @@ -305,7 +313,7 @@ class CommitQueue(AbstractPatchQueue, StepSequenceErrorHandler, CommitQueueTaskD # CommitQueueTaskDelegate methods def run_command(self, command): - self.run_webkit_patch(command) + self.run_webkit_patch(command + [self.port.flag()]) def command_passed(self, message, patch): self._update_status(message, patch=patch) diff --git a/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py b/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py index 1c2d57b1c..1914ccd4b 100644 --- a/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py +++ b/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py @@ -49,7 +49,7 @@ class TestCommitQueue(CommitQueue): CommitQueue.__init__(self) if tool: self.bind_to_tool(tool) - self._options = MockOptions(confirm=False, parent_command="commit-queue") + self._options = MockOptions(confirm=False, parent_command="commit-queue", port=None) def begin_work_queue(self): output_capture = OutputCapture() @@ -231,8 +231,8 @@ class CommitQueueTest(QueuesTest): def test_commit_queue(self): tool = MockTool() - tool.filesystem.write_text_file('/mock-results/full_results.json', '') # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem. - tool.filesystem.write_text_file('/mock-results/webkit_unit_tests_output.xml', '') + tool.filesystem.write_text_file('/tmp/layout-test-results/full_results.json', '') # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem. + tool.filesystem.write_text_file('/tmp/layout-test-results/webkit_unit_tests_output.xml', '') expected_stderr = { "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue"), "next_work_item": "", @@ -269,7 +269,7 @@ MOCK: release_work_item: commit-queue 10000 queue = CommitQueue() def mock_run_webkit_patch(command): - if command == ['clean'] or command == ['update']: + if command[0] == 'clean' or command[0] == 'update': # We want cleaning to succeed so we can error out on a step # that causes the commit-queue to reject the patch. return @@ -298,7 +298,7 @@ MOCK: release_work_item: commit-queue 10000 queue = CommitQueue() def mock_run_webkit_patch(command): - if command == ['clean'] or command == ['update']: + if command[0] == 'clean' or command[0] == 'update': # We want cleaning to succeed so we can error out on a step # that causes the commit-queue to reject the patch. return @@ -310,29 +310,29 @@ MOCK: release_work_item: commit-queue 10000 def test_rollout(self): tool = MockTool(log_executive=True) - tool.filesystem.write_text_file('/mock-results/full_results.json', '') # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem. - tool.filesystem.write_text_file('/mock-results/webkit_unit_tests_output.xml', '') + tool.filesystem.write_text_file('/tmp/layout-test-results/full_results.json', '') # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem. + tool.filesystem.write_text_file('/tmp/layout-test-results/webkit_unit_tests_output.xml', '') tool.buildbot.light_tree_on_fire() expected_stderr = { "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue"), "next_work_item": "", - "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'clean'], cwd=/mock-checkout + "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'clean', '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Cleaned working directory -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'update'], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'update', '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Updated working directory -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--no-update', '--non-interactive', 10000], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--no-update', '--non-interactive', 10000, '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Applied patch -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'validate-changelog', '--non-interactive', 10000], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'validate-changelog', '--non-interactive', 10000, '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue ChangeLog validated -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--no-clean', '--no-update', '--build-style=both'], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build', '--no-clean', '--no-update', '--build-style=both', '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Built patch -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive'], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive', '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Passed tests -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--non-interactive', '--parent-command=commit-queue', 10000], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--non-interactive', '--parent-command=commit-queue', 10000, '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Landed patch MOCK: update_status: commit-queue Pass MOCK: release_work_item: commit-queue 10000 -""", +""" % {"port_name": CommitQueue.port_name}, "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '10000' with comment 'Rejecting attachment 10000 from commit-queue.' and additional comment 'Mock error message'\n", "handle_script_error": "ScriptError error message\n\nMOCK output\n", } @@ -346,19 +346,19 @@ MOCK: release_work_item: commit-queue 10000 expected_stderr = { "begin_work_queue": self._default_begin_work_queue_stderr("commit-queue"), "next_work_item": "", - "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'clean'], cwd=/mock-checkout + "process_work_item": """MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'clean', '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Cleaned working directory -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'update'], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'update', '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Updated working directory -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--no-update', '--non-interactive', 10005], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'apply-attachment', '--no-update', '--non-interactive', 10005, '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Applied patch -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'validate-changelog', '--non-interactive', 10005], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'validate-changelog', '--non-interactive', 10005, '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue ChangeLog validated -MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--non-interactive', '--parent-command=commit-queue', 10005], cwd=/mock-checkout +MOCK run_and_throw_if_fail: ['echo', '--status-host=example.com', 'land-attachment', '--force-clean', '--non-interactive', '--parent-command=commit-queue', 10005, '--port=%(port_name)s'], cwd=/mock-checkout MOCK: update_status: commit-queue Landed patch MOCK: update_status: commit-queue Pass MOCK: release_work_item: commit-queue 10005 -""", +""" % {"port_name": CommitQueue.port_name}, "handle_unexpected_error": "MOCK setting flag 'commit-queue' to '-' on attachment '10005' with comment 'Rejecting attachment 10005 from commit-queue.' and additional comment 'Mock error message'\n", "handle_script_error": "ScriptError error message\n\nMOCK output\n", } @@ -382,8 +382,8 @@ MOCK: release_work_item: commit-queue 10005 def test_manual_reject_during_processing(self): queue = SecondThoughtsCommitQueue(MockTool()) queue.begin_work_queue() - queue._tool.filesystem.write_text_file('/mock-results/full_results.json', '') # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem. - queue._tool.filesystem.write_text_file('/mock-results/webkit_unit_tests_output.xml', '') + queue._tool.filesystem.write_text_file('/tmp/layout-test-results/full_results.json', '') # Otherwise the commit-queue will hit a KeyError trying to read the results from the MockFileSystem. + queue._tool.filesystem.write_text_file('/tmp/layout-test-results/webkit_unit_tests_output.xml', '') queue._options = Mock() queue._options.port = None expected_stderr = """MOCK: update_status: commit-queue Cleaned working directory diff --git a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py index cb7254ba2..c214a339c 100644 --- a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py +++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py @@ -398,10 +398,10 @@ class Rebaseline(AbstractParallelRebaselineCommand): return self._tool.user.prompt_with_list("Which test(s) to rebaseline for %s:" % builder.name(), failing_tests, can_choose_multiple=True) def _suffixes_to_update(self, options): - suffixes = [] + suffixes = set() for suffix_list in options.suffixes: - suffixes += suffix_list.split(",") - return suffixes + suffixes |= set(suffix_list.split(",")) + return list(suffixes) def execute(self, options, args, tool): if options.builders: diff --git a/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py b/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py index a3b9efaeb..433906b8c 100644 --- a/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py +++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py @@ -465,18 +465,18 @@ MOCK run_command: ['echo', 'optimize-baselines', '--suffixes', 'txt', 'mock/path tool.executive = MockExecutive(should_log=True) - expected_stdout = """rebaseline-json: {'mock/path/to/test.html': {'MOCK builder2': ['txt', 'png', 'wav'], 'MOCK builder': ['txt', 'png', 'wav'], 'MOCK builder3': ['txt', 'png', 'wav']}, 'mock/path/to/test2.html': {'MOCK builder2': ['txt', 'png', 'wav'], 'MOCK builder': ['txt', 'png', 'wav'], 'MOCK builder3': ['txt', 'png', 'wav']}} + expected_stdout = """rebaseline-json: {'mock/path/to/test.html': {'MOCK builder2': ['wav', 'txt', 'png'], 'MOCK builder': ['wav', 'txt', 'png'], 'MOCK builder3': ['wav', 'txt', 'png']}, 'mock/path/to/test2.html': {'MOCK builder2': ['wav', 'txt', 'png'], 'MOCK builder': ['wav', 'txt', 'png'], 'MOCK builder3': ['wav', 'txt', 'png']}} """ - expected_stderr = """MOCK run_command: ['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png,wav', '--builder', 'MOCK builder2', '--test', 'mock/path/to/test.html'], cwd=/mock-checkout -MOCK run_command: ['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png,wav', '--builder', 'MOCK builder', '--test', 'mock/path/to/test.html'], cwd=/mock-checkout -MOCK run_command: ['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png,wav', '--builder', 'MOCK builder2', '--test', 'mock/path/to/test2.html'], cwd=/mock-checkout -MOCK run_command: ['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png,wav', '--builder', 'MOCK builder', '--test', 'mock/path/to/test2.html'], cwd=/mock-checkout + expected_stderr = """MOCK run_command: ['echo', 'rebaseline-test-internal', '--suffixes', 'wav,txt,png', '--builder', 'MOCK builder2', '--test', 'mock/path/to/test.html'], cwd=/mock-checkout +MOCK run_command: ['echo', 'rebaseline-test-internal', '--suffixes', 'wav,txt,png', '--builder', 'MOCK builder', '--test', 'mock/path/to/test.html'], cwd=/mock-checkout +MOCK run_command: ['echo', 'rebaseline-test-internal', '--suffixes', 'wav,txt,png', '--builder', 'MOCK builder2', '--test', 'mock/path/to/test2.html'], cwd=/mock-checkout +MOCK run_command: ['echo', 'rebaseline-test-internal', '--suffixes', 'wav,txt,png', '--builder', 'MOCK builder', '--test', 'mock/path/to/test2.html'], cwd=/mock-checkout MOCK run_command: ['echo', 'optimize-baselines', '--suffixes', 'wav,txt,png', 'mock/path/to/test.html'], cwd=/mock-checkout MOCK run_command: ['echo', 'optimize-baselines', '--suffixes', 'wav,txt,png', 'mock/path/to/test2.html'], cwd=/mock-checkout """ - OutputCapture().assert_outputs(self, command.execute, [MockOptions(optimize=True, builders=["MOCK builder,MOCK builder2", "MOCK builder3"], suffixes=["txt", "png,wav"], verbose=True), ["mock/path/to/test.html", "mock/path/to/test2.html"], tool], expected_stdout=expected_stdout, expected_stderr=expected_stderr) + OutputCapture().assert_outputs(self, command.execute, [MockOptions(optimize=True, builders=["MOCK builder,MOCK builder2", "MOCK builder3"], suffixes=["txt,png", "png,wav,txt"], verbose=True), ["mock/path/to/test.html", "mock/path/to/test2.html"], tool], expected_stdout=expected_stdout, expected_stderr=expected_stderr) finally: builders._exact_matches = old_exact_matches diff --git a/Tools/TestWebKitAPI/Configurations/Base.xcconfig b/Tools/TestWebKitAPI/Configurations/Base.xcconfig index e64af3b1f..412c440d9 100644 --- a/Tools/TestWebKitAPI/Configurations/Base.xcconfig +++ b/Tools/TestWebKitAPI/Configurations/Base.xcconfig @@ -63,18 +63,15 @@ REAL_PLATFORM_NAME_macosx = macosx; TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); -// If the target Mac OS X version does not match the current Mac OS X version then we'll want to build using the target version's SDK. -SDKROOT = $(SDKROOT_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -SDKROOT_1060_1050 = macosx10.5; -SDKROOT_1070_1050 = macosx10.5; -SDKROOT_1080_1050 = macosx10.5; -SDKROOT_1090_1050 = macosx10.5; -SDKROOT_1070_1060 = macosx10.6; -SDKROOT_1080_1060 = macosx10.6; -SDKROOT_1090_1060 = macosx10.6; -SDKROOT_1080_1070 = macosx10.7; -SDKROOT_1090_1070 = macosx10.7; -SDKROOT_1090_1080 = macosx10.8; +TARGETING_SAME_OS_X_VERSION = $(TARGETING_SAME_OS_X_VERSION_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +TARGETING_SAME_OS_X_VERSION_1060_1060 = YES; +TARGETING_SAME_OS_X_VERSION_1070_1070 = YES; +TARGETING_SAME_OS_X_VERSION_1080_1080 = YES; +TARGETING_SAME_OS_X_VERSION_1090_1090 = YES; + +// Don't build against an SDK unless we're targeting an older OS version. +SDKROOT = $(SDKROOT_TARGETING_SAME_OS_X_VERSION_$(TARGETING_SAME_OS_X_VERSION)); +SDKROOT_TARGETING_SAME_OS_X_VERSION_ = macosx; WEBKIT_UMBRELLA_FRAMEWORKS_DIR = $(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Versions/A/Frameworks; WEBCORE_PRIVATE_HEADERS_DIR = $(WEBKIT_UMBRELLA_FRAMEWORKS_DIR)/WebCore.framework/PrivateHeaders; diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.gyp/TestWebKitAPI.gyp b/Tools/TestWebKitAPI/TestWebKitAPI.gyp/TestWebKitAPI.gyp index 6f5fba2d8..ff064a02d 100644 --- a/Tools/TestWebKitAPI/TestWebKitAPI.gyp/TestWebKitAPI.gyp +++ b/Tools/TestWebKitAPI/TestWebKitAPI.gyp/TestWebKitAPI.gyp @@ -133,7 +133,9 @@ '<(PRODUCT_DIR)/TestWebKitAPI_apk', '--ant-args', '-DPRODUCT_DIR=<(ant_build_out)', - '--ant-compile' + '--ant-compile', + '--app_abi', + '<(android_app_abi)', ], }], }], diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj index f5ff80418..50045f3bb 100644 --- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj +++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 0BCD833514857CE400EA2003 /* HashMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BCD833414857CE400EA2003 /* HashMap.cpp */; }; 0BCD856A1485C98B00EA2003 /* TemporaryChange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BCD85691485C98B00EA2003 /* TemporaryChange.cpp */; }; + 0F17BBD615AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F17BBD415AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp */; }; 0FC6C4CC141027E0005B7F0C /* RedBlackTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */; }; 0FC6C4CF141034AD005B7F0C /* MetaAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC6C4CE141034AD005B7F0C /* MetaAllocator.cpp */; }; 1A02C84F125D4A8400E3F4BD /* Find.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A02C84E125D4A8400E3F4BD /* Find.cpp */; }; @@ -19,6 +20,7 @@ 1ADBEFAE130C689C00D61D19 /* ForceRepaint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADBEFAD130C689C00D61D19 /* ForceRepaint.cpp */; }; 1ADBEFE3130C6AA100D61D19 /* simple-accelerated-compositing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */; }; 1AEDE22613E5E7E700E62FE8 /* InjectedBundleControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */; }; + 261516D615B0E60500A2C201 /* SetAndUpdateCacheModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */; }; 26DF5A5E15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */; }; 26DF5A6315A2A27E003689C2 /* CancelLoadFromResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 26DF5A6115A2A22B003689C2 /* CancelLoadFromResourceLoadDelegate.html */; }; 333B9CE21277F23100FEFCE3 /* PreventEmptyUserAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */; }; @@ -229,6 +231,7 @@ /* Begin PBXFileReference section */ 0BCD833414857CE400EA2003 /* HashMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HashMap.cpp; path = WTF/HashMap.cpp; sourceTree = "<group>"; }; 0BCD85691485C98B00EA2003 /* TemporaryChange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TemporaryChange.cpp; path = WTF/TemporaryChange.cpp; sourceTree = "<group>"; }; + 0F17BBD415AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCoreStatisticsWithNoWebProcess.cpp; sourceTree = "<group>"; }; 0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RedBlackTree.cpp; path = WTF/RedBlackTree.cpp; sourceTree = "<group>"; }; 0FC6C4CE141034AD005B7F0C /* MetaAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MetaAllocator.cpp; path = WTF/MetaAllocator.cpp; sourceTree = "<group>"; }; 1A02C84B125D4A5E00E3F4BD /* find.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = find.html; sourceTree = "<group>"; }; @@ -238,6 +241,7 @@ 1ADBEFAD130C689C00D61D19 /* ForceRepaint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ForceRepaint.cpp; sourceTree = "<group>"; }; 1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-accelerated-compositing.html"; sourceTree = "<group>"; }; 1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundleControllerMac.mm; sourceTree = "<group>"; }; + 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SetAndUpdateCacheModel.mm; sourceTree = "<group>"; }; 26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CancelLoadFromResourceLoadDelegate.mm; sourceTree = "<group>"; }; 26DF5A6115A2A22B003689C2 /* CancelLoadFromResourceLoadDelegate.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = CancelLoadFromResourceLoadDelegate.html; sourceTree = "<group>"; }; 333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreventEmptyUserAgent.cpp; sourceTree = "<group>"; }; @@ -596,6 +600,7 @@ BC7B619A1299FE9E00D174A4 /* WKPreferences.cpp */, BC90995D12567BC100083756 /* WKString.cpp */, BC9099931256ACF100083756 /* WKStringJSString.cpp */, + 0F17BBD415AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp */, ); path = WebKit2; sourceTree = "<group>"; @@ -692,6 +697,7 @@ E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */, 517E7DFB15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm */, 3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */, + 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */, 52B8CF9515868CF000281053 /* SetDocumentURI.mm */, C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */, 3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */, @@ -929,6 +935,8 @@ 26DF5A5E15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm in Sources */, F660AA0D15A5F061003A1243 /* GetInjectedBundleInitializationUserDataCallback.cpp in Sources */, F660AA1315A619C9003A1243 /* InjectedBundleInitializationUserDataCallbackWins.cpp in Sources */, + 0F17BBD615AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp in Sources */, + 261516D615B0E60500A2C201 /* SetAndUpdateCacheModel.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WebCoreStatisticsWithNoWebProcess.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WebCoreStatisticsWithNoWebProcess.cpp new file mode 100644 index 000000000..f71f186b7 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WebCoreStatisticsWithNoWebProcess.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PlatformUtilities.h" +#include "test.h" + +namespace TestWebKitAPI { + +static bool done; + +// Callback for WKContextGetStatistics. +static void wkContextGetStatisticsCallback(WKDictionaryRef statistics, WKErrorRef error, void* functionContext) +{ + EXPECT_NOT_NULL(error); + done = true; +} + +TEST(WebKit2, WebCoreStatisticsWithNoWebProcess) +{ + WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); + + WKContextGetStatistics(context.get(), 0, wkContextGetStatisticsCallback); + + Util::run(&done); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/SetAndUpdateCacheModel.mm b/Tools/TestWebKitAPI/Tests/mac/SetAndUpdateCacheModel.mm new file mode 100644 index 000000000..eed1f8180 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/mac/SetAndUpdateCacheModel.mm @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include <wtf/RetainPtr.h> + +#import <WebKit/WebView.h> +#import <WebKit/WebPreferences.h> + +@interface WebView (WebViewOtherInternal) ++ (WebCacheModel)_cacheModel; +@end + +namespace TestWebKitAPI { + +TEST(WebKit1, SetAndUpdateCacheModelInitialModel) +{ + EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); + + RetainPtr<WebView> webView(AdoptNS, [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); + + EXPECT_EQ((int)WebCacheModelDocumentBrowser, (int)[WebView _cacheModel]); +} + +TEST(WebKit1, SetAndUpdateCacheModelStandardPreferenceChange) +{ + EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); + + WebPreferences *standardPreferences = [WebPreferences standardPreferences]; + EXPECT_EQ((int)WebCacheModelDocumentBrowser, (int)[WebView _cacheModel]); + + [standardPreferences setCacheModel:WebCacheModelPrimaryWebBrowser]; + EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); + + [standardPreferences setCacheModel:WebCacheModelDocumentViewer]; + EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); +} + +TEST(WebKit1, SetAndUpdateCacheModelPreferencesChangeMix) +{ + // On change, the cache model always take the highest value of any preference bound to a WebView. + EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); + + WebPreferences *standardPreferences = [WebPreferences standardPreferences]; + RetainPtr<WebPreferences> customPreferences(AdoptNS, [[WebPreferences alloc] initWithIdentifier:@"SetAndUpdateCacheModelPreferencesChangeMix"]); + + // 1) The customPreferences is not set on a view. + EXPECT_EQ((int)WebCacheModelDocumentBrowser, (int)[WebView _cacheModel]); + + [standardPreferences setCacheModel:WebCacheModelPrimaryWebBrowser]; + EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); + + [standardPreferences setCacheModel:WebCacheModelDocumentViewer]; + EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); + [customPreferences.get() setCacheModel:WebCacheModelPrimaryWebBrowser]; + EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); + + + // 2) The cache model should follow the highest value of cache model between the two preferences. + RetainPtr<WebView> webView(AdoptNS, [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); + [webView.get() setPreferences:customPreferences.get()]; + EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); + + [customPreferences.get() setCacheModel:WebCacheModelDocumentBrowser]; + EXPECT_EQ((int)WebCacheModelDocumentBrowser, (int)[WebView _cacheModel]); + + [standardPreferences setCacheModel:WebCacheModelPrimaryWebBrowser]; + EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); + [customPreferences.get() setCacheModel:WebCacheModelDocumentViewer]; + EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); + + // 3) Resetting the view should fall back to standardPreferences. + [standardPreferences setCacheModel:WebCacheModelDocumentViewer]; + [customPreferences.get() setCacheModel:WebCacheModelPrimaryWebBrowser]; + EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); + + webView.clear(); + EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/mac/InjectedBundleControllerMac.mm b/Tools/TestWebKitAPI/mac/InjectedBundleControllerMac.mm index 4dd4ef020..965beb4ae 100644 --- a/Tools/TestWebKitAPI/mac/InjectedBundleControllerMac.mm +++ b/Tools/TestWebKitAPI/mac/InjectedBundleControllerMac.mm @@ -40,7 +40,7 @@ void InjectedBundleController::platformInitialize() NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInteger:4], @"AppleAntiAliasingThreshold", [NSNumber numberWithInteger:0], @"AppleFontSmoothing", -#if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) && !PLATFORM(CHROMIUM) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !PLATFORM(CHROMIUM) [NSNumber numberWithBool:NO], @"NSScrollAnimationEnabled", #else [NSNumber numberWithBool:NO], @"AppleScrollAnimationEnabled", diff --git a/Tools/WebKitTestRunner/Configurations/Base.xcconfig b/Tools/WebKitTestRunner/Configurations/Base.xcconfig index 4015b3e31..9f5405967 100644 --- a/Tools/WebKitTestRunner/Configurations/Base.xcconfig +++ b/Tools/WebKitTestRunner/Configurations/Base.xcconfig @@ -60,18 +60,15 @@ REAL_PLATFORM_NAME_macosx = macosx; TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); -// If the target Mac OS X version does not match the current Mac OS X version then we'll want to build using the target version's SDK. -SDKROOT = $(SDKROOT_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -SDKROOT_1060_1050 = macosx10.5; -SDKROOT_1070_1050 = macosx10.5; -SDKROOT_1080_1050 = macosx10.5; -SDKROOT_1090_1050 = macosx10.5; -SDKROOT_1070_1060 = macosx10.6; -SDKROOT_1080_1060 = macosx10.6; -SDKROOT_1090_1060 = macosx10.6; -SDKROOT_1080_1070 = macosx10.7; -SDKROOT_1090_1070 = macosx10.7; -SDKROOT_1090_1080 = macosx10.8; +TARGETING_SAME_OS_X_VERSION = $(TARGETING_SAME_OS_X_VERSION_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +TARGETING_SAME_OS_X_VERSION_1060_1060 = YES; +TARGETING_SAME_OS_X_VERSION_1070_1070 = YES; +TARGETING_SAME_OS_X_VERSION_1080_1080 = YES; +TARGETING_SAME_OS_X_VERSION_1090_1090 = YES; + +// Don't build against an SDK unless we're targeting an older OS version. +SDKROOT = $(SDKROOT_TARGETING_SAME_OS_X_VERSION_$(TARGETING_SAME_OS_X_VERSION)); +SDKROOT_TARGETING_SAME_OS_X_VERSION_ = macosx; WEBKIT_UMBRELLA_FRAMEWORKS_DIR = $(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Versions/A/Frameworks; WEBCORE_PRIVATE_HEADERS_DIR = $(WEBKIT_UMBRELLA_FRAMEWORKS_DIR)/WebCore.framework/PrivateHeaders; diff --git a/Tools/WebKitTestRunner/InjectedBundle/mac/ActivateFonts.mm b/Tools/WebKitTestRunner/InjectedBundle/mac/ActivateFonts.mm index 320b28a8a..01d790bc8 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/mac/ActivateFonts.mm +++ b/Tools/WebKitTestRunner/InjectedBundle/mac/ActivateFonts.mm @@ -234,7 +234,7 @@ void activateFonts() "WebKitWeightWatcher700.ttf", "WebKitWeightWatcher800.ttf", "WebKitWeightWatcher900.ttf", -#if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 "SampleFont.sfont", #endif 0 diff --git a/Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm b/Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm index 419064fdb..996acbb09 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm +++ b/Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm @@ -39,7 +39,7 @@ void InjectedBundle::platformInitialize(WKTypeRef) NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInteger:4], @"AppleAntiAliasingThreshold", [NSNumber numberWithInteger:0], @"AppleFontSmoothing", -#if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) && !PLATFORM(CHROMIUM) +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !PLATFORM(CHROMIUM) [NSNumber numberWithBool:NO], @"NSScrollAnimationEnabled", #else [NSNumber numberWithBool:NO], @"AppleScrollAnimationEnabled", diff --git a/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp b/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp index 9dc2dfc77..fbb36508a 100644 --- a/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp +++ b/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp @@ -51,8 +51,16 @@ void TestController::platformInitialize() { } -void TestController::platformRunUntil(bool&, double timeout) +void TestController::platformRunUntil(bool& condition, double timeout) { + if (timeout == m_noTimeout) { + // Never timeout if we are debugging or not meant to timeout. + while (!condition) { + ecore_main_loop_iterate(); + sleep(1); + } + return; + } timer = ecore_timer_loop_add(timeout, timerFired, 0); ecore_main_loop_begin(); } diff --git a/Tools/gtk/run-api-tests b/Tools/gtk/run-api-tests index 441342c84..a601a766c 100755 --- a/Tools/gtk/run-api-tests +++ b/Tools/gtk/run-api-tests @@ -62,6 +62,8 @@ class TestRunner: SkippedTest("unittests/testwebinspector", "/webkit/webinspector/close-and-inspect", "Test is flaky in GTK Linux 32-bit Release bot", 82869), SkippedTest("WebKit2APITests/TestWebKitWebView", "/webkit2/WebKitWebView/mouse-target", "Test is flaky in GTK Linux 32-bit Release bot", 82866), SkippedTest("WebKit2APITests/TestResources", "/webkit2/WebKitWebView/resources", "Test is flaky in GTK Linux 32-bit Release bot", 82868), + SkippedTest("WebKit2APITests/TestWebKitFindController", "/webkit2/WebKitFindController/next", "Test fails ", 91083), + SkippedTest("WebKit2APITests/TestWebKitFindController", "/webkit2/WebKitFindController/previous", "Test fails", 91083), SkippedTest("WebKit2APITests/TestWebKitFindController", "/webkit2/WebKitFindController/hide", "Test always fails in Xvfb", 89810), SkippedTest("TestWebKitAPI/TestWebKit2", "WebKit2.WKConnection", "Tests fail and time out out", 84959), SkippedTest("TestWebKitAPI/TestWebKit2", "WebKit2.RestoreSessionStateContainingFormData", "Session State is not implemented in GTK+ port", 84960), diff --git a/Tools/qmake/config.tests/libXcomposite/libXcomposite.cpp b/Tools/qmake/config.tests/libXcomposite/libXcomposite.cpp new file mode 100644 index 000000000..10e1054bd --- /dev/null +++ b/Tools/qmake/config.tests/libXcomposite/libXcomposite.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <X11/extensions/Xcomposite.h> + +int main(int, char**) +{ + Display* display = XOpenDisplay(0); + int majorVersion; + int minorVersion; + (void)XCompositeQueryVersion(display, &majorVersion, &minorVersion); + XCloseDisplay(display); + return 0; +} diff --git a/Tools/qmake/config.tests/libXcomposite/libXcomposite.pro b/Tools/qmake/config.tests/libXcomposite/libXcomposite.pro new file mode 100644 index 000000000..96c5c2937 --- /dev/null +++ b/Tools/qmake/config.tests/libXcomposite/libXcomposite.pro @@ -0,0 +1,3 @@ +SOURCES = libXcomposite.cpp +OBJECTS_DIR = obj +LIBS += -lXcomposite -lX11 diff --git a/Tools/qmake/configure.pri b/Tools/qmake/configure.pri index 8c009fd20..575deb880 100644 --- a/Tools/qmake/configure.pri +++ b/Tools/qmake/configure.pri @@ -15,6 +15,7 @@ haveQt(5):!quick_check { libpng \ libjpeg \ libwebp \ + libXcomposite \ libxml2 \ libxslt \ libzlib diff --git a/Tools/qmake/mkspecs/features/default_post.prf b/Tools/qmake/mkspecs/features/default_post.prf index da2efe8a0..767e56372 100644 --- a/Tools/qmake/mkspecs/features/default_post.prf +++ b/Tools/qmake/mkspecs/features/default_post.prf @@ -140,7 +140,7 @@ contains(TEMPLATE, lib) { win32-msvc*|win32-icc: INCLUDEPATH += $$ROOT_WEBKIT_DIR/Source/JavaScriptCore/os-win32 !plugin { - !linux-g++*:!linux-icc*:contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols + contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions } } diff --git a/Tools/qmake/mkspecs/features/features.prf b/Tools/qmake/mkspecs/features/features.prf index 325aeca0d..a7b00869e 100644 --- a/Tools/qmake/mkspecs/features/features.prf +++ b/Tools/qmake/mkspecs/features/features.prf @@ -170,8 +170,16 @@ haveQt(4) { # is called QmlEngine and it is safe for us to use QQuick1 again. } +# Xcomposite Support +haveQt(5):linux-*:config_libXcomposite: DEFINES += HAVE_XCOMPOSITE=1 + +# Support for Graphics Surface !contains(DEFINES, WTF_USE_GRAPHICS_SURFACE=.) { - haveQt(5):mac: DEFINES += WTF_USE_GRAPHICS_SURFACE=1 + haveQt(5) { + mac: DEFINES += WTF_USE_GRAPHICS_SURFACE=1 + # On linux we require libXcomposite to enable graphics surface. + linux-*:contains(DEFINES, HAVE_XCOMPOSITE=1): DEFINES += WTF_USE_GRAPHICS_SURFACE=1 + } } # -------------- Fill in static defaults -------------- |
