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.
4
5 #include "chrome/test/base/test_launcher_utils.h"
6
7 #include <memory>
8
9 #include "base/command_line.h"
10 #include "base/environment.h"
11 #include "base/feature_list.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/logging.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "build/build_config.h"
17 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/url_constants.h"
20 #include "components/os_crypt/os_crypt_switches.h"
21 #include "content/public/common/content_switches.h"
22 #include "ui/display/display_switches.h"
23
24 #if defined(USE_AURA)
25 #include "ui/wm/core/wm_core_switches.h"
26 #endif
27
28 namespace test_launcher_utils {
29
PrepareBrowserCommandLineForTests(base::CommandLine * command_line)30 void PrepareBrowserCommandLineForTests(base::CommandLine* command_line) {
31 // Don't show the first run ui.
32 command_line->AppendSwitch(switches::kNoFirstRun);
33
34 // No default browser check, it would create an info-bar (if we are not the
35 // default browser) that could conflicts with some tests expectations.
36 command_line->AppendSwitch(switches::kNoDefaultBrowserCheck);
37
38 // Enable info level logging to stderr by default so that we can see when bad
39 // stuff happens, but honor the flags specified from the command line. Use the
40 // default logging level (INFO) instead of explicitly passing
41 // switches::kLoggingLevel. Passing the switch explicitly resulted in data
42 // races in tests that start async operations (that use logging) prior to
43 // initializing the browser: https://crbug.com/749066.
44 if (!command_line->HasSwitch(switches::kEnableLogging))
45 command_line->AppendSwitchASCII(switches::kEnableLogging, "stderr");
46
47 // Don't install default apps.
48 command_line->AppendSwitch(switches::kDisableDefaultApps);
49
50 #if defined(USE_AURA)
51 // Disable window animations under Ash as the animations effect the
52 // coordinates returned and result in flake.
53 command_line->AppendSwitch(
54 wm::switches::kWindowAnimationsDisabled);
55 #endif
56
57 #if defined(OS_POSIX) && !defined(OS_MAC) && !defined(OS_CHROMEOS)
58 // Don't use the native password stores on Linux since they may
59 // prompt for additional UI during tests and cause test failures or
60 // timeouts. Win, Mac and ChromeOS don't look at the kPasswordStore
61 // switch.
62 if (!command_line->HasSwitch(switches::kPasswordStore))
63 command_line->AppendSwitchASCII(switches::kPasswordStore, "basic");
64 #endif
65
66 #if defined(OS_MAC)
67 // Use mock keychain on mac to prevent blocking permissions dialogs.
68 command_line->AppendSwitch(os_crypt::switches::kUseMockKeychain);
69 #endif
70
71 command_line->AppendSwitch(switches::kDisableComponentUpdate);
72 }
73
PrepareBrowserCommandLineForBrowserTests(base::CommandLine * command_line,bool open_about_blank_on_launch)74 void PrepareBrowserCommandLineForBrowserTests(base::CommandLine* command_line,
75 bool open_about_blank_on_launch) {
76 // This is a Browser test.
77 command_line->AppendSwitchASCII(switches::kTestType, "browser");
78
79 if (open_about_blank_on_launch && command_line->GetArgs().empty())
80 command_line->AppendArg(url::kAboutBlankURL);
81 }
82
RemoveCommandLineSwitch(const base::CommandLine & in_command_line,const std::string & switch_to_remove,base::CommandLine * out_command_line)83 void RemoveCommandLineSwitch(const base::CommandLine& in_command_line,
84 const std::string& switch_to_remove,
85 base::CommandLine* out_command_line) {
86 const base::CommandLine::SwitchMap& switch_map =
87 in_command_line.GetSwitches();
88 for (auto i = switch_map.begin(); i != switch_map.end(); ++i) {
89 const std::string& switch_name = i->first;
90 if (switch_name == switch_to_remove)
91 continue;
92
93 out_command_line->AppendSwitchNative(switch_name, i->second);
94 }
95 }
96
CreateUserDataDir(base::ScopedTempDir * temp_dir)97 bool CreateUserDataDir(base::ScopedTempDir* temp_dir) {
98 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
99 base::FilePath user_data_dir =
100 command_line->GetSwitchValuePath(switches::kUserDataDir);
101 if (user_data_dir.empty()) {
102 DCHECK(temp_dir);
103 if (temp_dir->CreateUniqueTempDir() && temp_dir->IsValid()) {
104 user_data_dir = temp_dir->GetPath();
105 } else {
106 LOG(ERROR) << "Could not create temporary user data directory \""
107 << temp_dir->GetPath().value() << "\".";
108 return false;
109 }
110 }
111 return OverrideUserDataDir(user_data_dir);
112 }
113
OverrideUserDataDir(const base::FilePath & user_data_dir)114 bool OverrideUserDataDir(const base::FilePath& user_data_dir) {
115 bool success = true;
116
117 // base::PathService::Override() is the best way to change the user data
118 // directory. This matches what is done in ChromeMain().
119 success = base::PathService::Override(chrome::DIR_USER_DATA, user_data_dir);
120
121 #if defined(OS_POSIX) && !defined(OS_MAC)
122 // Make sure the cache directory is inside our clear profile. Otherwise
123 // the cache may contain data from earlier tests that could break the
124 // current test.
125 //
126 // Note: we use an environment variable here, because we have to pass the
127 // value to the child process. This is the simplest way to do it.
128 std::unique_ptr<base::Environment> env(base::Environment::Create());
129 success = success && env->SetVar("XDG_CACHE_HOME", user_data_dir.value());
130
131 // Also make sure that the machine policy directory is inside the clear
132 // profile. Otherwise the machine's policies could affect tests.
133 base::FilePath policy_files = user_data_dir.AppendASCII("policies");
134 success = success &&
135 base::PathService::Override(chrome::DIR_POLICY_FILES, policy_files);
136 #endif
137
138 return success;
139 }
140
141 } // namespace test_launcher_utils
142