1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/test/base/chrome_test_suite.h"
7 #if defined(OS_CHROMEOS)
12 #include "base/command_line.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/metrics/stats_table.h"
15 #include "base/path_service.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/chrome_content_browser_client.h"
20 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
21 #include "chrome/common/chrome_constants.h"
22 #include "chrome/common/chrome_content_client.h"
23 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/extensions/chrome_extensions_client.h"
25 #include "chrome/common/url_constants.h"
26 #include "chrome/utility/chrome_content_utility_client.h"
27 #include "content/public/test/test_launcher.h"
28 #include "extensions/common/extension_paths.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/base/resource/resource_handle.h"
33 #if defined(OS_ANDROID)
34 #include "base/android/jni_android.h"
35 #include "chrome/browser/android/chrome_jni_registrar.h"
36 #include "net/android/net_jni_registrar.h"
37 #include "ui/base/android/ui_base_jni_registrar.h"
38 #include "ui/gfx/android/gfx_jni_registrar.h"
39 #include "ui/gl/android/gl_jni_registrar.h"
42 #if defined(OS_CHROMEOS)
43 #include "base/process/process_metrics.h"
44 #include "chromeos/chromeos_paths.h"
47 #if defined(OS_MACOSX)
48 #include "base/mac/bundle_locations.h"
49 #include "base/mac/scoped_nsautorelease_pool.h"
51 #include "base/mac/mac_util.h"
52 #include "chrome/browser/chrome_browser_application_mac.h"
53 #endif // !defined(OS_IOS)
57 #include "base/memory/shared_memory.h"
62 void RemoveSharedMemoryFile(const std::string
& filename
) {
63 // Stats uses SharedMemory under the hood. On posix, this results in a file
66 base::SharedMemory memory
;
67 memory
.Delete(filename
);
71 bool IsCrosPythonProcess() {
72 #if defined(OS_CHROMEOS)
74 int num_read
= readlink(base::kProcSelfExe
, buf
, sizeof(buf
) - 1);
78 const char kPythonPrefix
[] = "/python";
79 return !strncmp(strrchr(buf
, '/'), kPythonPrefix
, sizeof(kPythonPrefix
) - 1);
82 #endif // defined(OS_CHROMEOS)
85 // Initializes services needed by both unit tests and browser tests.
86 // See also ChromeUnitTestSuite for additional services created for unit tests.
87 class ChromeTestSuiteInitializer
: public testing::EmptyTestEventListener
{
89 ChromeTestSuiteInitializer() {
92 virtual void OnTestStart(const testing::TestInfo
& test_info
) OVERRIDE
{
93 content_client_
.reset(new ChromeContentClient
);
94 content::SetContentClient(content_client_
.get());
95 // TODO(ios): Bring this back once ChromeContentBrowserClient is building.
97 browser_content_client_
.reset(new chrome::ChromeContentBrowserClient());
98 content::SetBrowserClientForTesting(browser_content_client_
.get());
99 utility_content_client_
.reset(new chrome::ChromeContentUtilityClient());
100 content::SetUtilityClientForTesting(utility_content_client_
.get());
104 virtual void OnTestEnd(const testing::TestInfo
& test_info
) OVERRIDE
{
105 // TODO(ios): Bring this back once ChromeContentBrowserClient is building.
107 browser_content_client_
.reset();
108 utility_content_client_
.reset();
110 content_client_
.reset();
111 content::SetContentClient(NULL
);
115 // Client implementations for the content module.
116 scoped_ptr
<ChromeContentClient
> content_client_
;
117 // TODO(ios): Bring this back once ChromeContentBrowserClient is building.
119 scoped_ptr
<chrome::ChromeContentBrowserClient
> browser_content_client_
;
120 scoped_ptr
<chrome::ChromeContentUtilityClient
> utility_content_client_
;
123 DISALLOW_COPY_AND_ASSIGN(ChromeTestSuiteInitializer
);
128 ChromeTestSuite::ChromeTestSuite(int argc
, char** argv
)
129 : content::ContentTestSuiteBase(argc
, argv
) {
132 ChromeTestSuite::~ChromeTestSuite() {
135 void ChromeTestSuite::Initialize() {
136 #if defined(OS_MACOSX)
137 base::mac::ScopedNSAutoreleasePool autorelease_pool
;
139 chrome_browser_application_mac::RegisterBrowserCrApp();
140 #endif // !defined(OS_IOS)
143 #if defined(OS_ANDROID)
144 // Register JNI bindings for android.
145 gfx::android::RegisterJni(base::android::AttachCurrentThread());
146 net::android::RegisterJni(base::android::AttachCurrentThread());
147 ui::android::RegisterJni(base::android::AttachCurrentThread());
148 ui::gl::android::RegisterJni(base::android::AttachCurrentThread());
149 chrome::android::RegisterJni(base::android::AttachCurrentThread());
152 chrome::RegisterPathProvider();
153 #if defined(OS_CHROMEOS)
154 chromeos::RegisterPathProvider();
156 if (!browser_dir_
.empty()) {
157 PathService::Override(base::DIR_EXE
, browser_dir_
);
158 PathService::Override(base::DIR_MODULE
, browser_dir_
);
162 extensions::RegisterPathProvider();
164 extensions::ExtensionsClient::Set(
165 extensions::ChromeExtensionsClient::GetInstance());
167 // Only want to do this for unit tests.
168 if (!content::GetCurrentTestLauncherDelegate()) {
169 // For browser tests, this won't create the right object since
170 // TestChromeWebUIControllerFactory is used. That's created and
171 // registered in ChromeBrowserMainParts as in normal startup.
172 content::WebUIControllerFactory::RegisterFactory(
173 ChromeWebUIControllerFactory::GetInstance());
177 // Disable external libraries load if we are under python process in
178 // ChromeOS. That means we are autotest and, if ASAN is used,
179 // external libraries load crashes.
180 content::ContentTestSuiteBase::set_external_libraries_enabled(
181 !IsCrosPythonProcess());
183 // Initialize after overriding paths as some content paths depend on correct
184 // values for DIR_EXE and DIR_MODULE.
185 content::ContentTestSuiteBase::Initialize();
187 #if defined(OS_MACOSX) && !defined(OS_IOS)
188 // Look in the framework bundle for resources.
190 PathService::Get(base::DIR_EXE
, &path
);
191 path
= path
.Append(chrome::kFrameworkName
);
192 base::mac::SetOverrideFrameworkBundlePath(path
);
195 // Force unittests to run using en-US so if we test against string
196 // output, it'll pass regardless of the system language.
197 ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL
);
198 base::FilePath resources_pack_path
;
199 #if defined(OS_MACOSX) && !defined(OS_IOS)
200 PathService::Get(base::DIR_MODULE
, &resources_pack_path
);
201 resources_pack_path
=
202 resources_pack_path
.Append(FILE_PATH_LITERAL("resources.pak"));
204 PathService::Get(chrome::FILE_RESOURCES_PACK
, &resources_pack_path
);
206 ResourceBundle::GetSharedInstance().AddDataPackFromPath(
207 resources_pack_path
, ui::SCALE_FACTOR_NONE
);
209 stats_filename_
= base::StringPrintf("unit_tests-%d",
210 base::GetCurrentProcId());
211 RemoveSharedMemoryFile(stats_filename_
);
212 stats_table_
.reset(new base::StatsTable(stats_filename_
, 20, 200));
213 base::StatsTable::set_current(stats_table_
.get());
215 testing::TestEventListeners
& listeners
=
216 testing::UnitTest::GetInstance()->listeners();
217 listeners
.Append(new ChromeTestSuiteInitializer
);
220 content::ContentClient
* ChromeTestSuite::CreateClientForInitialization() {
221 return new ChromeContentClient();
224 void ChromeTestSuite::Shutdown() {
225 ResourceBundle::CleanupSharedInstance();
227 #if defined(OS_MACOSX) && !defined(OS_IOS)
228 base::mac::SetOverrideFrameworkBundle(NULL
);
231 base::StatsTable::set_current(NULL
);
232 stats_table_
.reset();
233 RemoveSharedMemoryFile(stats_filename_
);
235 base::TestSuite::Shutdown();