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 33 #include "TestShell.h" 34 #include "webkit/support/webkit_support.h" 35 #include <v8/include/v8-testing.h> 36 #include <v8/include/v8.h> 37 #include <wtf/Vector.h> 38 39 using namespace std; 40 41 static const char optionComplexText[] = "--complex-text"; 42 static const char optionDumpAllPixels[] = "--dump-all-pixels"; 43 static const char optionNotree[] = "--notree"; 44 static const char optionPixelTests[] = "--pixel-tests"; 45 static const char optionThreaded[] = "--threaded"; 46 static const char optionDebugRenderTree[] = "--debug-render-tree"; 47 static const char optionDebugLayerTree[] = "--debug-layer-tree"; 48 49 static const char optionPixelTestsWithName[] = "--pixel-tests="; 50 static const char optionTestShell[] = "--test-shell"; 51 static const char optionAllowExternalPages[] = "--allow-external-pages"; 52 static const char optionStartupDialog[] = "--testshell-startup-dialog"; 53 static const char optionCheckLayoutTestSystemDeps[] = "--check-layout-test-sys-deps"; 54 55 static const char optionHardwareAcceleratedGL[] = "--enable-hardware-gpu"; 56 static const char optionEnableAcceleratedCompositing[] = "--enable-accelerated-compositing"; 57 static const char optionForceCompositingMode[] = "--force-compositing-mode"; 58 static const char optionEnableAccelerated2DCanvas[] = "--enable-accelerated-2d-canvas"; 59 60 static const char optionStressOpt[] = "--stress-opt"; 61 static const char optionStressDeopt[] = "--stress-deopt"; 62 static const char optionJavaScriptFlags[] = "--js-flags="; 63 static const char optionNoTimeout[] = "--no-timeout"; 64 65 class WebKitSupportTestEnvironment { 66 public: 67 WebKitSupportTestEnvironment() 68 { 69 webkit_support::SetUpTestEnvironment(); 70 } 71 ~WebKitSupportTestEnvironment() 72 { 73 webkit_support::TearDownTestEnvironment(); 74 } 75 }; 76 77 static void runTest(TestShell& shell, TestParams& params, const string& testName, bool testShellMode) 78 { 79 int oldTimeoutMsec = shell.layoutTestTimeout(); 80 params.pixelHash = ""; 81 string pathOrURL = testName; 82 if (testShellMode) { 83 string timeOut; 84 string::size_type separatorPosition = pathOrURL.find(' '); 85 if (separatorPosition != string::npos) { 86 timeOut = pathOrURL.substr(separatorPosition + 1); 87 pathOrURL.erase(separatorPosition); 88 separatorPosition = timeOut.find_first_of(' '); 89 if (separatorPosition != string::npos) { 90 params.pixelHash = timeOut.substr(separatorPosition + 1); 91 timeOut.erase(separatorPosition); 92 } 93 shell.setLayoutTestTimeout(atoi(timeOut.c_str())); 94 } 95 } else { 96 string::size_type separatorPosition = pathOrURL.find("'"); 97 if (separatorPosition != string::npos) { 98 params.pixelHash = pathOrURL.substr(separatorPosition + 1); 99 pathOrURL.erase(separatorPosition); 100 } 101 } 102 params.testUrl = webkit_support::CreateURLForPathOrURL(pathOrURL); 103 webkit_support::SetCurrentDirectoryForFileURL(params.testUrl); 104 v8::V8::SetFlagsFromString(shell.javaScriptFlags().c_str(), shell.javaScriptFlags().length()); 105 if (shell.stressOpt() || shell.stressDeopt()) { 106 if (shell.stressOpt()) 107 v8::Testing::SetStressRunType(v8::Testing::kStressTypeOpt); 108 else 109 v8::Testing::SetStressRunType(v8::Testing::kStressTypeDeopt); 110 for (int i = 0; i < v8::Testing::GetStressRuns(); i++) { 111 v8::Testing::PrepareStressRun(i); 112 bool isLastLoad = (i == (v8::Testing::GetStressRuns() - 1)); 113 shell.setDumpWhenFinished(isLastLoad); 114 shell.resetTestController(); 115 shell.runFileTest(params); 116 } 117 } else { 118 shell.resetTestController(); 119 shell.runFileTest(params); 120 } 121 shell.setLayoutTestTimeout(oldTimeoutMsec); 122 } 123 124 int main(int argc, char* argv[]) 125 { 126 WebKitSupportTestEnvironment testEnvironment; 127 platformInit(&argc, &argv); 128 129 TestParams params; 130 Vector<string> tests; 131 bool serverMode = false; 132 bool testShellMode = false; 133 bool allowExternalPages = false; 134 bool startupDialog = false; 135 bool acceleratedCompositingEnabled = false; 136 bool forceCompositingMode = false; 137 bool accelerated2DCanvasEnabled = false; 138 bool stressOpt = false; 139 bool stressDeopt = false; 140 bool hardwareAcceleratedGL = false; 141 string javaScriptFlags; 142 bool noTimeout = false; 143 for (int i = 1; i < argc; ++i) { 144 string argument(argv[i]); 145 if (argument == "-") 146 serverMode = true; 147 else if (argument == optionNotree) 148 params.dumpTree = false; 149 else if (argument == optionPixelTests) 150 params.dumpPixels = true; 151 else if (!argument.find(optionPixelTestsWithName)) { 152 params.dumpPixels = true; 153 params.pixelFileName = argument.substr(strlen(optionPixelTestsWithName)); 154 } else if (argument == optionDebugRenderTree) 155 params.debugRenderTree = true; 156 else if (argument == optionDebugLayerTree) 157 params.debugLayerTree = true; 158 else if (argument == optionTestShell) { 159 testShellMode = true; 160 serverMode = true; 161 } else if (argument == optionAllowExternalPages) 162 allowExternalPages = true; 163 else if (argument == optionStartupDialog) 164 startupDialog = true; 165 else if (argument == optionCheckLayoutTestSystemDeps) 166 return checkLayoutTestSystemDependencies() ? EXIT_SUCCESS : EXIT_FAILURE; 167 else if (argument == optionHardwareAcceleratedGL) 168 hardwareAcceleratedGL = true; 169 else if (argument == optionEnableAcceleratedCompositing) 170 acceleratedCompositingEnabled = true; 171 else if (argument == optionForceCompositingMode) 172 forceCompositingMode = true; 173 else if (argument == optionEnableAccelerated2DCanvas) 174 accelerated2DCanvasEnabled = true; 175 else if (argument == optionStressOpt) 176 stressOpt = true; 177 else if (argument == optionStressDeopt) 178 stressDeopt = true; 179 else if (!argument.find(optionJavaScriptFlags)) 180 javaScriptFlags = argument.substr(strlen(optionJavaScriptFlags)); 181 else if (argument == optionNoTimeout) 182 noTimeout = true; 183 else if (argument.size() && argument[0] == '-') 184 fprintf(stderr, "Unknown option: %s\n", argv[i]); 185 else 186 tests.append(argument); 187 } 188 if (testShellMode && params.dumpPixels && params.pixelFileName.empty()) { 189 fprintf(stderr, "--pixel-tests with --test-shell requires a file name.\n"); 190 return EXIT_FAILURE; 191 } 192 if (stressOpt && stressDeopt) { 193 fprintf(stderr, "--stress-opt and --stress-deopt are mutually exclusive.\n"); 194 return EXIT_FAILURE; 195 } 196 197 webkit_support::SetUpGLBindings(hardwareAcceleratedGL ? webkit_support::GL_BINDING_DEFAULT : webkit_support::GL_BINDING_SOFTWARE_RENDERER); 198 199 if (startupDialog) 200 openStartupDialog(); 201 202 { // Explicit scope for the TestShell instance. 203 TestShell shell(testShellMode); 204 shell.setAllowExternalPages(allowExternalPages); 205 shell.setAcceleratedCompositingEnabled(acceleratedCompositingEnabled); 206 shell.setForceCompositingMode(forceCompositingMode); 207 shell.setAccelerated2dCanvasEnabled(accelerated2DCanvasEnabled); 208 shell.setJavaScriptFlags(javaScriptFlags); 209 shell.setStressOpt(stressOpt); 210 shell.setStressDeopt(stressDeopt); 211 if (noTimeout) { 212 // 0x20000000ms is big enough for the purpose to avoid timeout in debugging. 213 shell.setLayoutTestTimeout(0x20000000); 214 } 215 if (serverMode && !tests.size()) { 216 params.printSeparators = true; 217 char testString[2048]; // 2048 is the same as the sizes of other platforms. 218 while (fgets(testString, sizeof(testString), stdin)) { 219 char* newLinePosition = strchr(testString, '\n'); 220 if (newLinePosition) 221 *newLinePosition = '\0'; 222 if (testString[0] == '\0') 223 continue; 224 runTest(shell, params, testString, testShellMode); 225 } 226 } else if (!tests.size()) 227 printf("#EOF\n"); 228 else { 229 params.printSeparators = tests.size() > 1; 230 for (unsigned i = 0; i < tests.size(); i++) 231 runTest(shell, params, tests[i], testShellMode); 232 } 233 234 shell.callJSGC(); 235 shell.callJSGC(); 236 237 // When we finish the last test, cleanup the LayoutTestController. 238 // It may have references to not-yet-cleaned up windows. By 239 // cleaning up here we help purify reports. 240 shell.resetTestController(); 241 } 242 243 return EXIT_SUCCESS; 244 } 245