Changeset 60427 in webkit


Ignore:
Timestamp:
May 30, 2010 9:07:48 PM (14 years ago)
Author:
tkent@chromium.org
Message:

2010-05-30 Kent Tamura <tkent@chromium.org>

Reviewed by Dimitri Glazkov.

new-run-webkit-tests: Support DRT on Chromium-win
https://bugs.webkit.org/show_bug.cgi?id=39810

Add --test-shell flag to DRT/Chromium, and it changes DRT so that
it behaves like test_shell about command analysis, printing
format, pixel dumping, and timeout handling.

chromium.py and chromium_win.py supports the --test-shell flag and
DRT/Chromium-win binary names.

  • DumpRenderTree/DumpRenderTree.gypi: Add new files.
  • DumpRenderTree/chromium/DumpRenderTree.cpp: (runTest): Support for test_shell-style command. (main): Introduce --test-shell.
  • DumpRenderTree/chromium/TestEventPrinter.cpp: Added.
  • DumpRenderTree/chromium/TestEventPrinter.h: Added. TestEventPrinter class manages stdio output and image output. TestEventPrinter.cpp has two implementations; DRTPrinter and TestShellPrinter.
  • DumpRenderTree/chromium/TestShell.cpp: Some changes for TestEventPrinter. (TestShell::TestShell): (TestShell::runFileTest): (TestShell::testTimedOut): (TestShell::dump): (TestShell::dumpImage):
  • DumpRenderTree/chromium/TestShell.h: (TestShell::printer): (TestShell::layoutTestTimeout): (TestShell::layoutTestTimeoutForWatchDog): (TestShell::setLayoutTestTimeout):
  • DumpRenderTree/chromium/TestShellWin.cpp: (watchDogThread): Use TestShell::layoutTestTimeoutForWatchDog().
  • Scripts/webkitpy/layout_tests/port/chromium.py:
  • Scripts/webkitpy/layout_tests/port/chromium_win.py:
Location:
trunk/WebKitTools
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r60415 r60427  
     12010-05-30  Kent Tamura  <tkent@chromium.org>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        new-run-webkit-tests: Support DRT on Chromium-win
     6        https://bugs.webkit.org/show_bug.cgi?id=39810
     7
     8        Add --test-shell flag to DRT/Chromium, and it changes DRT so that
     9        it behaves like test_shell about command analysis, printing
     10        format, pixel dumping, and timeout handling.
     11
     12        chromium.py and chromium_win.py supports the --test-shell flag and
     13        DRT/Chromium-win binary names.
     14       
     15        * DumpRenderTree/DumpRenderTree.gypi: Add new files.
     16        * DumpRenderTree/chromium/DumpRenderTree.cpp:
     17        (runTest): Support for test_shell-style command.
     18        (main): Introduce --test-shell.
     19        * DumpRenderTree/chromium/TestEventPrinter.cpp: Added.
     20        * DumpRenderTree/chromium/TestEventPrinter.h: Added.
     21          TestEventPrinter class manages stdio output and image output.
     22          TestEventPrinter.cpp has two implementations; DRTPrinter and
     23          TestShellPrinter.
     24        * DumpRenderTree/chromium/TestShell.cpp:
     25          Some changes for TestEventPrinter.
     26        (TestShell::TestShell):
     27        (TestShell::runFileTest):
     28        (TestShell::testTimedOut):
     29        (TestShell::dump):
     30        (TestShell::dumpImage):
     31        * DumpRenderTree/chromium/TestShell.h:
     32        (TestShell::printer):
     33        (TestShell::layoutTestTimeout):
     34        (TestShell::layoutTestTimeoutForWatchDog):
     35        (TestShell::setLayoutTestTimeout):
     36        * DumpRenderTree/chromium/TestShellWin.cpp:
     37        (watchDogThread): Use TestShell::layoutTestTimeoutForWatchDog().
     38        * Scripts/webkitpy/layout_tests/port/chromium.py:
     39        * Scripts/webkitpy/layout_tests/port/chromium_win.py:
     40
    1412010-05-30  Robert Hogan  <robert@webkit.org>
    242
  • trunk/WebKitTools/DumpRenderTree/DumpRenderTree.gypi

    r59193 r60427  
    2121            'chromium/PlainTextController.cpp',
    2222            'chromium/PlainTextController.h',
     23            'chromium/TestEventPrinter.h',
     24            'chromium/TestEventPrinter.cpp',
    2325            'chromium/TestNavigationController.cpp',
    2426            'chromium/TestNavigationController.h',
  • trunk/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp

    r60005 r60427  
    4646static const char optionTree[] = "--tree";
    4747
    48 static void runTest(TestShell& shell, TestParams& params, const string& testName)
     48static const char optionPixelTestsWithName[] = "--pixel-tests=";
     49static const char optionTestShell[] = "--test-shell";
     50
     51static void runTest(TestShell& shell, TestParams& params, const string& testName, bool testShellMode)
    4952{
     53    int oldTimeoutMsec = shell.layoutTestTimeout();
     54    params.pixelHash = "";
    5055    string pathOrURL = testName;
    51     string::size_type separatorPosition = pathOrURL.find("'");
    52     if (separatorPosition != string::npos) {
    53         params.pixelHash = pathOrURL.substr(separatorPosition + 1);
    54         pathOrURL.erase(separatorPosition);
     56    if (testShellMode) {
     57        string timeOut;
     58        string::size_type separatorPosition = pathOrURL.find(' ');
     59        if (separatorPosition != string::npos) {
     60            timeOut = pathOrURL.substr(separatorPosition + 1);
     61            pathOrURL.erase(separatorPosition);
     62            separatorPosition = timeOut.find_first_of(' ');
     63            if (separatorPosition != string::npos) {
     64                params.pixelHash = timeOut.substr(separatorPosition + 1);
     65                timeOut.erase(separatorPosition);
     66            }
     67            shell.setLayoutTestTimeout(atoi(timeOut.c_str()));
     68        }
     69    } else {
     70        string::size_type separatorPosition = pathOrURL.find("'");
     71        if (separatorPosition != string::npos) {
     72            params.pixelHash = pathOrURL.substr(separatorPosition + 1);
     73            pathOrURL.erase(separatorPosition);
     74        }
    5575    }
    5676    params.testUrl = webkit_support::CreateURLForPathOrURL(pathOrURL);
    5777    shell.resetTestController();
    5878    shell.runFileTest(params);
     79    shell.setLayoutTestTimeout(oldTimeoutMsec);
    5980}
    6081
     
    6788    Vector<string> tests;
    6889    bool serverMode = false;
     90    bool testShellMode = false;
    6991    for (int i = 1; i < argc; ++i) {
    7092        string argument(argv[i]);
     
    7597        else if (argument == optionPixelTests)
    7698            params.dumpPixels = true;
    77         else if (argument.size() && argument[0] == '-')
     99        else if (!argument.find(optionPixelTestsWithName)) {
     100            params.dumpPixels = true;
     101            params.pixelFileName = argument.substr(strlen(optionPixelTestsWithName));
     102        } else if (argument == optionTestShell) {
     103            testShellMode = true;
     104            serverMode = true;
     105        } else if (argument.size() && argument[0] == '-')
    78106            fprintf(stderr, "Unknown option: %s\n", argv[i]);
    79107        else
    80108            tests.append(argument);
    81109    }
     110    if (testShellMode && params.dumpPixels && params.pixelFileName.empty()) {
     111        fprintf(stderr, "--pixel-tests with --test-shell requires a file name.\n");
     112        return EXIT_FAILURE;
     113    }
    82114
    83115    { // Explicit scope for the TestShell instance.
    84         TestShell shell;
     116        TestShell shell(testShellMode);
    85117        if (serverMode && !tests.size()) {
    86118            params.printSeparators = true;
     
    92124                if (testString[0] == '\0')
    93125                    continue;
    94                 runTest(shell, params, testString);
     126                runTest(shell, params, testString, testShellMode);
    95127            }
    96128        } else if (!tests.size())
     
    99131            params.printSeparators = tests.size() > 1;
    100132            for (unsigned i = 0; i < tests.size(); i++)
    101                 runTest(shell, params, tests[i]);
     133                runTest(shell, params, tests[i], testShellMode);
    102134        }
    103135
  • trunk/WebKitTools/DumpRenderTree/chromium/TestShell.cpp

    r60165 r60427  
    7676static const string::size_type dataUrlPatternSize = sizeof(dataUrlPattern) - 1;
    7777
    78 TestShell::TestShell()
     78TestShell::TestShell(bool testShellMode)
    7979    : m_testIsPending(false)
    8080    , m_testIsPreparing(false)
    8181    , m_focusedWidget(0)
     82    , m_testShellMode(testShellMode)
    8283{
    8384    WebRuntimeFeatures::enableGeolocation(true);
     
    8889    m_textInputController.set(new TextInputController(this));
    8990    m_notificationPresenter.set(new NotificationPresenter(this));
     91    m_printer.set(m_testShellMode ? TestEventPrinter::createTestShellPrinter() : TestEventPrinter::createDRTPrinter());
     92
     93    // 30 second is the same as the value in Mac DRT.
     94    // If we use a value smaller than the timeout value of
     95    // (new-)run-webkit-tests, (new-)run-webkit-tests misunderstands that a
     96    // timed-out DRT process was crashed.
     97    m_timeout = 30 * 1000;
    9098
    9199    m_webViewHost = createWebView();
     
    193201        || testUrl.find("\\inspector\\") != string::npos;
    194202    m_webView->settings()->setDeveloperExtrasEnabled(inspectorTestMode);
     203    m_printer->handleTestHeader(testUrl.c_str());
    195204    loadURL(m_params.testUrl);
    196205
     
    284293void TestShell::testTimedOut()
    285294{
    286     fprintf(stderr, "FAIL: Timed out waiting for notifyDone to be called\n");
    287     fprintf(stdout, "FAIL: Timed out waiting for notifyDone to be called\n");
     295    m_printer->handleTimedOut();
    288296    testFinished();
    289297}
     
    435443    if (m_params.dumpTree) {
    436444        dumpedAnything = true;
    437         printf("Content-Type: text/plain\n");
     445        m_printer->handleTextHeader();
    438446        // Text output: the test page can request different types of output
    439447        // which we handle here.
     
    457465    }
    458466    if (dumpedAnything && m_params.printSeparators)
    459         printf("#EOF\n");
     467        m_printer->handleTextFooter();
    460468
    461469    if (m_params.dumpPixels && !shouldDumpAsText) {
     
    498506        }
    499507
    500         string md5sum = dumpImage(m_webViewHost->canvas(), m_params.pixelHash);
    501     }
    502     printf("#EOF\n"); // For the image.
     508        dumpImage(m_webViewHost->canvas());
     509    }
     510    m_printer->handleImageFooter();
     511    m_printer->handleTestFooter(dumpedAnything);
    503512    fflush(stdout);
    504513    fflush(stderr);
    505514}
    506515
    507 string TestShell::dumpImage(skia::PlatformCanvas* canvas, const string& expectedHash)
     516void TestShell::dumpImage(skia::PlatformCanvas* canvas) const
    508517{
    509518    skia::BitmapPlatformDevice& device =
     
    539548    MD5Final(&digest, &ctx);
    540549    string md5hash = MD5DigestToBase16(digest);
    541     printf("\nActualHash: %s\n", md5hash.c_str());
    542     if (!expectedHash.empty())
    543         printf("\nExpectedHash: %s\n", expectedHash.c_str());
    544550
    545551    // Only encode and dump the png if the hashes don't match. Encoding the image
    546552    // is really expensive.
    547     if (md5hash.compare(expectedHash)) {
     553    if (md5hash.compare(m_params.pixelHash)) {
    548554        std::vector<unsigned char> png;
    549555        gfx::PNGCodec::ColorFormat colorFormat = gfx::PNGCodec::FORMAT_BGRA;
     
    553559            static_cast<int>(sourceBitmap.rowBytes()), discardTransparency, &png);
    554560
    555         printf("Content-Type: image/png\n");
    556         printf("Content-Length: %lu\n", png.size());
    557         // Write to disk.
    558         if (fwrite(&png[0], 1, png.size(), stdout) != png.size())
    559             FATAL("Short write to stdout.\n");
    560     }
    561 
    562     return md5hash;
     561        m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), &png[0], png.size(), m_params.pixelFileName.c_str());
     562    } else
     563        m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), 0, 0, m_params.pixelFileName.c_str());
    563564}
    564565
     
    570571    m_plainTextController->bindToJavascript(frame, WebString::fromUTF8("plainText"));
    571572    m_textInputController->bindToJavascript(frame, WebString::fromUTF8("textInputController"));
    572 }
    573 
    574 int TestShell::layoutTestTimeout()
    575 {
    576     // 30 second is the same as the value in Mac DRT.
    577     // If we use a value smaller than the timeout value of
    578     // (new-)run-webkit-tests, (new-)run-webkit-tests misunderstands that a
    579     // timed-out DRT process was crashed.
    580     return 30 * 1000;
    581573}
    582574
  • trunk/WebKitTools/DumpRenderTree/chromium/TestShell.h

    r60005 r60427  
    3434#include "NotificationPresenter.h"
    3535#include "PlainTextController.h"
     36#include "TestEventPrinter.h"
    3637#include "TextInputController.h"
    3738#include "WebViewHost.h"
     
    5960    bool printSeparators;
    6061    WebKit::WebURL testUrl;
     62    // Resultant image file name. Reqruired only if the test_shell mode.
    6163    std::string pixelFileName;
    6264    std::string pixelHash;
     
    7072class TestShell {
    7173public:
    72     TestShell();
     74    TestShell(bool testShellMode);
    7375    ~TestShell();
    7476    // The main WebView.
     
    8082    AccessibilityController* accessibilityController() const { return m_accessibilityController.get(); }
    8183    NotificationPresenter* notificationPresenter() const { return m_notificationPresenter.get(); }
     84    TestEventPrinter* printer() const { return m_printer.get(); }
    8285
    8386    void bindJSObjectsToWindow(WebKit::WebFrame*);
     
    111114
    112115    // Get the timeout for running a test in milliseconds.
    113     static int layoutTestTimeout();
    114     static int layoutTestTimeoutForWatchDog() { return layoutTestTimeout() + 1000; }
     116    int layoutTestTimeout() { return m_timeout; }
     117    int layoutTestTimeoutForWatchDog() { return layoutTestTimeout() + 1000; }
     118    void setLayoutTestTimeout(int timeout) { m_timeout = timeout; }
    115119
    116120    WebViewHost* createWebView();
     
    128132    void dump();
    129133    std::string dumpAllBackForwardLists();
    130     static std::string dumpImage(skia::PlatformCanvas*, const std::string& expectedHash);
     134    void dumpImage(skia::PlatformCanvas*) const;
    131135
    132136    bool m_testIsPending;
     
    135139    WebKit::WebView* m_webView;
    136140    WebKit::WebWidget* m_focusedWidget;
     141    bool m_testShellMode;
    137142    WebViewHost* m_webViewHost;
    138143    OwnPtr<AccessibilityController*> m_accessibilityController;
     
    142147    OwnPtr<TextInputController*> m_textInputController;
    143148    OwnPtr<NotificationPresenter*> m_notificationPresenter;
     149    OwnPtr<TestEventPrinter*> m_printer;
    144150    TestParams m_params;
     151    int m_timeout; // timeout value in millisecond
    145152
    146153    // List of all windows in this process.
  • trunk/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp

    r60005 r60427  
    3939#include <sys/stat.h>
    4040
    41 // Default timeout in ms for file page loads when in layout test mode.
    42 const int kDefaultFileTestTimeoutMillisecs = 10 * 1000;
    43 const int kDefaultWatchDogTimeoutMillisecs = kDefaultFileTestTimeoutMillisecs + 1 * 1000;
    44 
    4541// Thread main to run for the thread which just tests for timeout.
    46 unsigned int __stdcall watchDogThread(void *arg)
     42unsigned int __stdcall watchDogThread(void* arg)
    4743{
    4844    // If we're debugging a layout test, don't timeout.
    4945    if (::IsDebuggerPresent())
    50     return 0;
     46        return 0;
    5147
    5248    TestShell* shell = static_cast<TestShell*>(arg);
    5349    // FIXME: Do we need user-specified time settings as with the original
    5450    // Chromium implementation?
    55     DWORD timeout = static_cast<DWORD>(kDefaultWatchDogTimeoutMillisecs);
     51    DWORD timeout = static_cast<DWORD>(shell->layoutTestTimeoutForWatchDog());
    5652    DWORD rv = WaitForSingleObject(shell->finishedEvent(), timeout);
    5753    if (rv == WAIT_TIMEOUT) {
     
    5955        // Note: the layout test driver may or may not recognize
    6056        // this as a timeout.
    61         puts("#TEST_TIMED_OUT\n");
     57        puts("\n#TEST_TIMED_OUT\n");
    6258        puts("#EOF\n");
    6359        fflush(stdout);
  • trunk/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py

    r59743 r60427  
    4747from webkitpy.common.system.executive import Executive
    4848
    49 # FIXME: To use the DRT-based version of this file, we need to be able to
    50 # run the webkit code, which uses server_process, which requires UNIX-style
    51 # non-blocking I/O with selects(), which requires fcntl() which doesn't exist
    52 # on Windows.
     49# Chromium DRT on non-Windows uses WebKitDriver.
    5350if sys.platform not in ('win32', 'cygwin'):
    5451    import webkit
     
    9390        result = True
    9491
    95         # FIXME: see comment above re: import webkit
    96         if (sys.platform in ('win32', 'cygwin') and self._options and
    97             hasattr(self._options, 'use_drt') and self._options.use_drt):
    98             _log.error('--use-drt is not supported on Windows yet')
    99             _log.error('')
    100             result = False
    101 
    10292        dump_render_tree_binary_path = self._path_to_driver()
    10393        result = check_file_exists(dump_render_tree_binary_path,
     
    144134            offset = abspath.find('third_party')
    145135            if offset == -1:
    146                 # FIXME: This seems like the wrong error to throw.
    147                 raise AssertionError('could not find Chromium base dir from ' +
    148                                      abspath)
    149             self._chromium_base_dir = abspath[0:offset]
     136                self._chromium_base_dir = os.path.join(
     137                    abspath[0:abspath.find('WebKitTools')],
     138                    'WebKit', 'chromium')
     139            else:
     140                self._chromium_base_dir = abspath[0:offset]
    150141        return os.path.join(self._chromium_base_dir, *comps)
    151142
     
    181172    def create_driver(self, image_path, options):
    182173        """Starts a new Driver and returns a handle to it."""
     174        if self._options.use_drt and sys.platform not in ('win32', 'cygwin'):
     175            return webkit.WebKitDriver(self, image_path, options, executive=self._executive)
    183176        if self._options.use_drt:
    184             return webkit.WebKitDriver(self, image_path, options, executive=self._executive)
     177            options += ['--test-shell']
     178        else:
     179            options += ['--layout-tests']
    185180        return ChromiumDriver(self, image_path, options, executive=self._executive)
    186181
     
    298293        # FIXME: We should not be grabbing at self._port._options.wrapper directly.
    299294        cmd += self._command_wrapper(self._port._options.wrapper)
    300         cmd += [self._port._path_to_driver(), '--layout-tests']
     295        cmd += [self._port._path_to_driver()]
    301296        if self._options:
    302297            cmd += self._options
  • trunk/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py

    r59743 r60427  
    150150        if not configuration:
    151151            configuration = self._options.configuration
    152         return self._build_path(configuration, 'test_shell.exe')
     152        binary_name = 'test_shell.exe'
     153        if self._options.use_drt:
     154            binary_name = 'DumpRenderTree.exe'
     155        return self._build_path(configuration, binary_name)
    153156
    154157    def _path_to_helper(self):
    155         return self._build_path(self._options.configuration, 'layout_test_helper.exe')
     158        binary_name = 'layout_test_helper.exe'
     159        if self._options.use_drt:
     160            binary_name = 'LayoutTestHelper.exe'
     161        return self._build_path(self._options.configuration, binary_name)
    156162
    157163    def _path_to_image_diff(self):
    158         return self._build_path(self._options.configuration, 'image_diff.exe')
     164        binary_name = 'image_diff.exe'
     165        if self._options.use_drt:
     166            binary_name = 'ImageDiff.exe'
     167        return self._build_path(self._options.configuration, binary_name)
    159168
    160169    def _path_to_wdiff(self):
Note: See TracChangeset for help on using the changeset viewer.