diff options
author | mkwst <mkwst@chromium.org> | 2014-10-16 05:08:58 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-16 12:09:21 +0000 |
commit | 88e23180127784b736fa6b1d105d324add1d8151 (patch) | |
tree | ff3d621c562b4dd832045b9dd1bacb6fda318cef /content/shell/browser/layout_test | |
parent | 5b584d515a38c01b3d9d72d823688b67173c97cf (diff) | |
download | chromium_src-88e23180127784b736fa6b1d105d324add1d8151.zip chromium_src-88e23180127784b736fa6b1d105d324add1d8151.tar.gz chromium_src-88e23180127784b736fa6b1d105d324add1d8151.tar.bz2 |
Content Shell: Introduce LayoutTestBrowserMain.
Most of ShellBrowserMain's implementation was layout test-specific. This
patch moves all of that to LayoutTestBrowserMain, and adjusts the
delegate to call that function when DRT is enabled.
BUG=420994
NOTRY=true
Review URL: https://codereview.chromium.org/649223004
Cr-Commit-Position: refs/heads/master@{#299879}
Diffstat (limited to 'content/shell/browser/layout_test')
-rw-r--r-- | content/shell/browser/layout_test/layout_test_browser_main.cc | 223 | ||||
-rw-r--r-- | content/shell/browser/layout_test/layout_test_browser_main.h | 19 |
2 files changed, 242 insertions, 0 deletions
diff --git a/content/shell/browser/layout_test/layout_test_browser_main.cc b/content/shell/browser/layout_test/layout_test_browser_main.cc new file mode 100644 index 0000000..a1d7815 --- /dev/null +++ b/content/shell/browser/layout_test/layout_test_browser_main.cc @@ -0,0 +1,223 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/shell/browser/shell_browser_main.h" + +#include <iostream> + +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/sys_string_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" +#include "content/public/browser/browser_main_runner.h" +#include "content/public/common/url_constants.h" +#include "content/shell/browser/shell.h" +#include "content/shell/browser/webkit_test_controller.h" +#include "content/shell/common/shell_switches.h" +#include "content/shell/common/webkit_test_helpers.h" +#include "net/base/filename_util.h" + +#if defined(OS_ANDROID) +#include "base/run_loop.h" +#include "content/shell/browser/shell_layout_tests_android.h" +#endif + +namespace { + +GURL GetURLForLayoutTest(const std::string& test_name, + base::FilePath* current_working_directory, + bool* enable_pixel_dumping, + std::string* expected_pixel_hash) { + // A test name is formated like file:///path/to/test'--pixel-test'pixelhash + std::string path_or_url = test_name; + std::string pixel_switch; + std::string pixel_hash; + std::string::size_type separator_position = path_or_url.find('\''); + if (separator_position != std::string::npos) { + pixel_switch = path_or_url.substr(separator_position + 1); + path_or_url.erase(separator_position); + } + separator_position = pixel_switch.find('\''); + if (separator_position != std::string::npos) { + pixel_hash = pixel_switch.substr(separator_position + 1); + pixel_switch.erase(separator_position); + } + if (enable_pixel_dumping) { + *enable_pixel_dumping = + (pixel_switch == "--pixel-test" || pixel_switch == "-p"); + } + if (expected_pixel_hash) + *expected_pixel_hash = pixel_hash; + + GURL test_url; +#if defined(OS_ANDROID) + if (content::GetTestUrlForAndroid(path_or_url, &test_url)) + return test_url; +#endif + + test_url = GURL(path_or_url); + if (!(test_url.is_valid() && test_url.has_scheme())) { + // We're outside of the message loop here, and this is a test. + base::ThreadRestrictions::ScopedAllowIO allow_io; +#if defined(OS_WIN) + base::FilePath::StringType wide_path_or_url = + base::SysNativeMBToWide(path_or_url); + base::FilePath local_file(wide_path_or_url); +#else + base::FilePath local_file(path_or_url); +#endif + if (!base::PathExists(local_file)) { + local_file = content::GetWebKitRootDirFilePath() + .Append(FILE_PATH_LITERAL("LayoutTests")) + .Append(local_file); + } + test_url = net::FilePathToFileURL(base::MakeAbsoluteFilePath(local_file)); + } + base::FilePath local_path; + if (current_working_directory) { + // We're outside of the message loop here, and this is a test. + base::ThreadRestrictions::ScopedAllowIO allow_io; + if (net::FileURLToFilePath(test_url, &local_path)) + *current_working_directory = local_path.DirName(); + else + base::GetCurrentDirectory(current_working_directory); + } + return test_url; +} + +bool GetNextTest(const CommandLine::StringVector& args, + size_t* position, + std::string* test) { + if (*position >= args.size()) + return false; + if (args[*position] == FILE_PATH_LITERAL("-")) + return !!std::getline(std::cin, *test, '\n'); +#if defined(OS_WIN) + *test = base::WideToUTF8(args[(*position)++]); +#else + *test = args[(*position)++]; +#endif + return true; +} + +bool RunOneTest(const std::string& test_string, + bool* ran_at_least_once, + const scoped_ptr<content::BrowserMainRunner>& main_runner) { + if (test_string.empty()) + return true; + if (test_string == "QUIT") + return false; + + bool enable_pixel_dumps; + std::string pixel_hash; + base::FilePath cwd; + GURL test_url = + GetURLForLayoutTest(test_string, &cwd, &enable_pixel_dumps, &pixel_hash); + if (!content::WebKitTestController::Get()->PrepareForLayoutTest( + test_url, cwd, enable_pixel_dumps, pixel_hash)) { + return false; + } + + *ran_at_least_once = true; +#if defined(OS_ANDROID) + // The message loop on Android is provided by the system, and does not + // offer a blocking Run() method. For layout tests, use a nested loop + // together with a base::RunLoop so it can block until a QuitClosure. + base::RunLoop run_loop; + run_loop.Run(); +#else + main_runner->Run(); +#endif + + if (!content::WebKitTestController::Get()->ResetAfterLayoutTest()) + return false; + +#if defined(OS_ANDROID) + // There will be left-over tasks in the queue for Android because the + // main window is being destroyed. Run them before starting the next test. + base::MessageLoop::current()->RunUntilIdle(); +#endif + return true; +} + +} // namespace + +// Main routine for running as the Browser process. +int LayoutTestBrowserMain( + const content::MainFunctionParams& parameters, + const scoped_ptr<content::BrowserMainRunner>& main_runner) { + base::ScopedTempDir browser_context_path_for_layout_tests; + + CHECK(browser_context_path_for_layout_tests.CreateUniqueTempDir()); + CHECK(!browser_context_path_for_layout_tests.path().MaybeAsASCII().empty()); + CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kContentShellDataPath, + browser_context_path_for_layout_tests.path().MaybeAsASCII()); + +#if defined(OS_ANDROID) + content::EnsureInitializeForAndroidLayoutTests(); +#endif + + int exit_code = main_runner->Initialize(parameters); + DCHECK_LT(exit_code, 0) + << "BrowserMainRunner::Initialize failed in LayoutTestBrowserMain"; + + if (exit_code >= 0) + return exit_code; + + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kCheckLayoutTestSysDeps)) { + base::MessageLoop::current()->PostTask(FROM_HERE, + base::MessageLoop::QuitClosure()); + main_runner->Run(); + content::Shell::CloseAllWindows(); + main_runner->Shutdown(); + return 0; + } + + content::WebKitTestController test_controller; + { + // We're outside of the message loop here, and this is a test. + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::FilePath temp_path; + base::GetTempDir(&temp_path); + test_controller.SetTempPath(temp_path); + } + std::string test_string; + CommandLine::StringVector args = CommandLine::ForCurrentProcess()->GetArgs(); + size_t command_line_position = 0; + bool ran_at_least_once = false; + + std::cout << "#READY\n"; + std::cout.flush(); + + while (GetNextTest(args, &command_line_position, &test_string)) { + if (!RunOneTest(test_string, &ran_at_least_once, main_runner)) + break; + } + if (!ran_at_least_once) { + base::MessageLoop::current()->PostTask(FROM_HERE, + base::MessageLoop::QuitClosure()); + main_runner->Run(); + } + +#if defined(OS_ANDROID) + // Android should only execute Shutdown() here when running layout tests. + main_runner->Shutdown(); +#endif + + exit_code = 0; + +#if !defined(OS_ANDROID) + main_runner->Shutdown(); +#endif + + return exit_code; +} diff --git a/content/shell/browser/layout_test/layout_test_browser_main.h b/content/shell/browser/layout_test/layout_test_browser_main.h new file mode 100644 index 0000000..dfe66c5 --- /dev/null +++ b/content/shell/browser/layout_test/layout_test_browser_main.h @@ -0,0 +1,19 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_BROWSER_MAIN_H_ +#define CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_BROWSER_MAIN_H_ + +#include "base/memory/scoped_ptr.h" + +namespace content { +class BrowserMainRunner; +struct MainFunctionParams; +} + +int LayoutTestBrowserMain( + const content::MainFunctionParams& parameters, + const scoped_ptr<content::BrowserMainRunner>& main_runner); + +#endif // CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_BROWSER_MAIN_H_ |