| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #include "config.h" | |
| 32 #include "TestShell.h" | |
| 33 | |
| 34 #include "webkit/support/webkit_support.h" | |
| 35 #include <fcntl.h> | |
| 36 #include <io.h> | |
| 37 #include <list> | |
| 38 #include <process.h> | |
| 39 #include <shlwapi.h> | |
| 40 #include <string> | |
| 41 #include <sys/stat.h> | |
| 42 #include <windows.h> | |
| 43 | |
| 44 #define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(structName, member) \ | |
| 45 offsetof(structName, member) + \ | |
| 46 (sizeof static_cast<structName*>(0)->member) | |
| 47 #define NONCLIENTMETRICS_SIZE_PRE_VISTA \ | |
| 48 SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont) | |
| 49 | |
| 50 // Thread main to run for the thread which just tests for timeout. | |
| 51 unsigned int __stdcall watchDogThread(void* arg) | |
| 52 { | |
| 53 // If we're debugging a layout test, don't timeout. | |
| 54 if (::IsDebuggerPresent()) | |
| 55 return 0; | |
| 56 | |
| 57 TestShell* shell = static_cast<TestShell*>(arg); | |
| 58 // FIXME: Do we need user-specified time settings as with the original | |
| 59 // Chromium implementation? | |
| 60 DWORD timeout = static_cast<DWORD>(shell->layoutTestTimeoutForWatchDog()); | |
| 61 DWORD rv = WaitForSingleObject(shell->finishedEvent(), timeout); | |
| 62 if (rv == WAIT_TIMEOUT) { | |
| 63 // Print a warning to be caught by the layout-test script. | |
| 64 // Note: the layout test driver may or may not recognize | |
| 65 // this as a timeout. | |
| 66 puts("\n#TEST_TIMED_OUT\n"); | |
| 67 puts("#EOF\n"); | |
| 68 fflush(stdout); | |
| 69 TerminateProcess(GetCurrentProcess(), 0); | |
| 70 } | |
| 71 // Finished normally. | |
| 72 return 0; | |
| 73 } | |
| 74 | |
| 75 void TestShell::waitTestFinished() | |
| 76 { | |
| 77 ASSERT(!m_testIsPending); | |
| 78 | |
| 79 m_testIsPending = true; | |
| 80 | |
| 81 // Create a watchdog thread which just sets a timer and | |
| 82 // kills the process if it times out. This catches really | |
| 83 // bad hangs where the shell isn't coming back to the | |
| 84 // message loop. If the watchdog is what catches a | |
| 85 // timeout, it can't do anything except terminate the test | |
| 86 // shell, which is unfortunate. | |
| 87 m_finishedEvent = CreateEvent(0, TRUE, FALSE, 0); | |
| 88 ASSERT(m_finishedEvent); | |
| 89 | |
| 90 HANDLE threadHandle = reinterpret_cast<HANDLE>(_beginthreadex( | |
| 91 0, | |
| 92 0, | |
| 93 &watchDogThread, | |
| 94 this, | |
| 95 0, | |
| 96 0)); | |
| 97 ASSERT(threadHandle); | |
| 98 | |
| 99 // TestFinished() will post a quit message to break this loop when the page | |
| 100 // finishes loading. | |
| 101 while (m_testIsPending) | |
| 102 webkit_support::RunMessageLoop(); | |
| 103 | |
| 104 // Tell the watchdog that we are finished. | |
| 105 SetEvent(m_finishedEvent); | |
| 106 | |
| 107 // Wait to join the watchdog thread. (up to 1s, then quit) | |
| 108 WaitForSingleObject(threadHandle, 1000); | |
| 109 } | |
| 110 | |
| 111 void platformInit(int*, char***) | |
| 112 { | |
| 113 // Set stdout/stderr binary mode. | |
| 114 _setmode(_fileno(stdout), _O_BINARY); | |
| 115 _setmode(_fileno(stderr), _O_BINARY); | |
| 116 | |
| 117 // Load Ahem font. | |
| 118 // AHEM____.TTF is copied to the directory of DumpRenderTree.exe by WebKit.g
yp. | |
| 119 WCHAR path[_MAX_PATH]; | |
| 120 if (!::GetModuleFileName(0, path, _MAX_PATH)) { | |
| 121 fprintf(stderr, "Can't get the module path.\n"); | |
| 122 exit(1); | |
| 123 } | |
| 124 ::PathRemoveFileSpec(path); | |
| 125 wcscat_s(path, _MAX_PATH, L"/AHEM____.TTF"); | |
| 126 struct _stat ahemStat; | |
| 127 if (_wstat(path, &ahemStat) == -1) { | |
| 128 fprintf(stderr, "Can't access: '%S'\n", path); | |
| 129 exit(1); | |
| 130 } | |
| 131 | |
| 132 FILE* fp = _wfopen(path, L"rb"); | |
| 133 if (!fp) { | |
| 134 _wperror(path); | |
| 135 exit(1); | |
| 136 } | |
| 137 size_t size = ahemStat.st_size; | |
| 138 char* fontBuffer = new char[size]; | |
| 139 if (fread(fontBuffer, 1, size, fp) != size) { | |
| 140 fprintf(stderr, "Can't read the font: '%S'\n", path); | |
| 141 fclose(fp); | |
| 142 exit(1); | |
| 143 } | |
| 144 fclose(fp); | |
| 145 DWORD numFonts = 1; | |
| 146 HANDLE fontHandle = ::AddFontMemResourceEx(fontBuffer, size, 0, &numFonts); | |
| 147 delete[] fontBuffer; // OS owns a copy of the buffer. | |
| 148 if (!fontHandle) { | |
| 149 fprintf(stderr, "Failed to register Ahem font: '%S'\n", path); | |
| 150 exit(1); | |
| 151 } | |
| 152 // We don't need to release the font explicitly. | |
| 153 } | |
| 154 | |
| 155 void openStartupDialog() | |
| 156 { | |
| 157 ::MessageBox(0, L"Attach to me?", L"DumpRenderTree", MB_OK); | |
| 158 } | |
| 159 | |
| 160 bool checkLayoutTestSystemDependencies() | |
| 161 { | |
| 162 // This metric will be 17 when font size is "Normal". | |
| 163 // The size of drop-down menus depends on it. | |
| 164 int verticalScrollSize = ::GetSystemMetrics(SM_CXVSCROLL); | |
| 165 int requiredVScrollSize = 17; | |
| 166 std::list<std::string> errors; | |
| 167 if (verticalScrollSize != requiredVScrollSize) | |
| 168 errors.push_back("Must use normal size fonts (96 dpi)."); | |
| 169 | |
| 170 // ClearType must be disabled, because the rendering is unpredictable. | |
| 171 BOOL fontSmoothingEnabled; | |
| 172 ::SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0); | |
| 173 int fontSmoothingType; | |
| 174 ::SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &fontSmoothingType, 0); | |
| 175 if (fontSmoothingEnabled && (fontSmoothingType == FE_FONTSMOOTHINGCLEARTYPE)
) | |
| 176 errors.push_back("ClearType must be disabled."); | |
| 177 | |
| 178 // Check that we're using the default system fonts. | |
| 179 OSVERSIONINFO versionInfo = {0}; | |
| 180 versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); | |
| 181 ::GetVersionEx(&versionInfo); | |
| 182 const bool isVistaOrLater = (versionInfo.dwMajorVersion >= 6); | |
| 183 NONCLIENTMETRICS metrics = {0}; | |
| 184 metrics.cbSize = isVistaOrLater ? sizeof(NONCLIENTMETRICS) : NONCLIENTMETRIC
S_SIZE_PRE_VISTA; | |
| 185 const bool success = !!::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metri
cs.cbSize, &metrics, 0); | |
| 186 ASSERT(success); | |
| 187 LOGFONTW* systemFonts[] = | |
| 188 {&metrics.lfStatusFont, &metrics.lfMenuFont, &metrics.lfSmCaptionFont}; | |
| 189 const wchar_t* const requiredFont = isVistaOrLater ? L"Segoe UI" : L"Tahoma"
; | |
| 190 const int requiredFontSize = isVistaOrLater ? -12 : -11; | |
| 191 for (size_t i = 0; i < arraysize(systemFonts); ++i) { | |
| 192 if (systemFonts[i]->lfHeight != requiredFontSize || wcscmp(requiredFont,
systemFonts[i]->lfFaceName)) { | |
| 193 errors.push_back(isVistaOrLater ? "Must use either the Aero or Basic
theme." : "Must use the default XP theme (Luna)."); | |
| 194 break; | |
| 195 } | |
| 196 } | |
| 197 | |
| 198 if (!errors.empty()) { | |
| 199 fprintf(stderr, "%s", | |
| 200 "###############################################################
###\n" | |
| 201 "## Layout test system dependencies check failed.\n" | |
| 202 "##\n"); | |
| 203 for (std::list<std::string>::iterator it = errors.begin(); it != errors.
end(); ++it) | |
| 204 fprintf(stderr, "## %s\n", it->c_str()); | |
| 205 fprintf(stderr, "%s", | |
| 206 "##\n" | |
| 207 "###############################################################
###\n"); | |
| 208 } | |
| 209 return errors.empty(); | |
| 210 } | |
| OLD | NEW |