13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell_browser_main.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iostream> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/sys_string_conversions.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_main_runner.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/url_constants.h" 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell.h" 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/webkit_test_controller.h" 23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "content/shell/common/shell_switches.h" 24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "content/shell/common/webkit_test_helpers.h" 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/base/filename_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_ANDROID) 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/run_loop.h" 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell_layout_tests_android.h" 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace { 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL GetURLForLayoutTest(const std::string& test_name, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath* current_working_directory, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* enable_pixel_dumping, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* expected_pixel_hash) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A test name is formated like file:///path/to/test'--pixel-test'pixelhash 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string path_or_url = test_name; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string pixel_switch; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string pixel_hash; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::size_type separator_position = path_or_url.find('\''); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (separator_position != std::string::npos) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixel_switch = path_or_url.substr(separator_position + 1); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path_or_url.erase(separator_position); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) separator_position = pixel_switch.find('\''); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (separator_position != std::string::npos) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixel_hash = pixel_switch.substr(separator_position + 1); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixel_switch.erase(separator_position); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enable_pixel_dumping) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *enable_pixel_dumping = 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (pixel_switch == "--pixel-test" || pixel_switch == "-p"); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expected_pixel_hash) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *expected_pixel_hash = pixel_hash; 587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL test_url; 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_ANDROID) 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (content::GetTestUrlForAndroid(path_or_url, &test_url)) 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return test_url; 637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test_url = GURL(path_or_url); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(test_url.is_valid() && test_url.has_scheme())) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We're outside of the message loop here, and this is a test. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring wide_path_or_url = 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SysNativeMBToWide(path_or_url); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath local_file(wide_path_or_url); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath local_file(path_or_url); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(local_file)) { 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) local_file = content::GetWebKitRootDirFilePath() 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .Append(FILE_PATH_LITERAL("LayoutTests")).Append(local_file); 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) test_url = net::FilePathToFileURL(base::MakeAbsoluteFilePath(local_file)); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath local_path; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (current_working_directory) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We're outside of the message loop here, and this is a test. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (net::FileURLToFilePath(test_url, &local_path)) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *current_working_directory = local_path.DirName(); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::GetCurrentDirectory(current_working_directory); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return test_url; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetNextTest(const CommandLine::StringVector& args, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* position, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* test) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*position >= args.size()) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args[*position] == FILE_PATH_LITERAL("-")) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !!std::getline(std::cin, *test, '\n'); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *test = base::WideToUTF8(args[(*position)++]); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *test = args[(*position)++]; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool RunOneTest(const std::string& test_string, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool* ran_at_least_once, 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_ptr<content::BrowserMainRunner>& main_runner) { 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (test_string.empty()) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (test_string == "QUIT") 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool enable_pixel_dumps; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string pixel_hash; 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FilePath cwd; 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL test_url = GetURLForLayoutTest( 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test_string, &cwd, &enable_pixel_dumps, &pixel_hash); 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!content::WebKitTestController::Get()->PrepareForLayoutTest( 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test_url, cwd, enable_pixel_dumps, pixel_hash)) { 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *ran_at_least_once = true; 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID) 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The message loop on Android is provided by the system, and does not 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // offer a blocking Run() method. For layout tests, use a nested loop 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // together with a base::RunLoop so it can block until a QuitClosure. 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop run_loop; 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) run_loop.Run(); 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) main_runner->Run(); 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!content::WebKitTestController::Get()->ResetAfterLayoutTest()) 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There will be left-over tasks in the queue for Android because the 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // main window is being destroyed. Run them before starting the next test. 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Main routine for running as the Browser process. 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint ShellBrowserMain( 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const content::MainFunctionParams& parameters, 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const scoped_ptr<content::BrowserMainRunner>& main_runner) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool layout_test_mode = 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ScopedTempDir browser_context_path_for_layout_tests; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (layout_test_mode) { 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(browser_context_path_for_layout_tests.CreateUniqueTempDir()); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!browser_context_path_for_layout_tests.path().MaybeAsASCII().empty()); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandLine::ForCurrentProcess()->AppendSwitchASCII( 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kContentShellDataPath, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_context_path_for_layout_tests.path().MaybeAsASCII()); 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID) 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::EnsureInitializeForAndroidLayoutTests(); 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int exit_code = main_runner->Initialize(parameters); 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_LT(exit_code, 0) 1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << "BrowserMainRunner::Initialize failed in ShellBrowserMain"; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exit_code >= 0) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return exit_code; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kCheckLayoutTestSysDeps)) { 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::QuitClosure()); 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) main_runner->Run(); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Shell::CloseAllWindows(); 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) main_runner->Shutdown(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (layout_test_mode) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebKitTestController test_controller; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We're outside of the message loop here, and this is a test. 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath temp_path; 194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::GetTempDir(&temp_path); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_controller.SetTempPath(temp_path); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string test_string; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::StringVector args = 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::ForCurrentProcess()->GetArgs(); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t command_line_position = 0; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ran_at_least_once = false; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::cout << "#READY\n"; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::cout.flush(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (GetNextTest(args, &command_line_position, &test_string)) { 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!RunOneTest(test_string, &ran_at_least_once, main_runner)) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ran_at_least_once) { 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::QuitClosure()); 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) main_runner->Run(); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_ANDROID) 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Android should only execute Shutdown() here when running layout tests. 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) main_runner->Shutdown(); 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit_code = 0; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if !defined(OS_ANDROID) 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!layout_test_mode) 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) exit_code = main_runner->Run(); 2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) main_runner->Shutdown(); 2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return exit_code; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 233