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 |