Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: testing/unit_test.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « testing/unit_test.h ('k') | testing/unit_test_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2007-2010 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15
16 #include "testing/unit_test.h"
17 #include "omaha/base/app_util.h"
18 #include "omaha/base/constants.h"
19 #include "omaha/base/path.h"
20 #include "omaha/base/process.h"
21 #include "omaha/base/reg_key.h"
22 #include "omaha/base/scoped_any.h"
23 #include "omaha/base/system.h"
24 #include "omaha/base/utils.h"
25 #include "omaha/base/user_info.h"
26 #include "omaha/base/vistautil.h"
27 #include "omaha/common/command_line.h"
28 #include "omaha/common/command_line_builder.h"
29 #include "omaha/common/const_goopdate.h"
30
31 namespace omaha {
32
33 namespace {
34
35 static bool is_buildsystem = false;
36 static TCHAR psexec_dir[MAX_PATH] = {0};
37
38 // Returns whether all unit tests should be run.
39 bool ShouldRunAllTests() {
40 if (is_buildsystem) {
41 return true;
42 }
43
44 EXPECT_FALSE(IsEnvironmentVariableSet(_T("OMAHA_RUN_ALL_TESTS")))
45 << _T("Use OMAHA_TEST_RUN_ALL instead of OMAHA_RUN_ALL_TESTS.");
46
47 return IsEnvironmentVariableSet(_T("OMAHA_TEST_RUN_ALL"));
48 }
49
50 } // namespace
51
52 bool IsEnvironmentVariableSet(const TCHAR* name) {
53 ASSERT1(name);
54 TCHAR var[100] = {0};
55 DWORD res = ::GetEnvironmentVariable(name, var, arraysize(var));
56 if (0 == res) {
57 ASSERT1(ERROR_ENVVAR_NOT_FOUND == ::GetLastError());
58 return false;
59 } else {
60 return true;
61 }
62 }
63
64 bool IsTestRunByLocalSystem() {
65 return user_info::IsRunningAsSystem();
66 }
67
68 CString GetLocalAppDataPath() {
69 CString expected_local_app_data_path;
70 EXPECT_SUCCEEDED(GetFolderPath(CSIDL_LOCAL_APPDATA | CSIDL_FLAG_DONT_VERIFY,
71 &expected_local_app_data_path));
72 expected_local_app_data_path.Append(_T("\\"));
73 return expected_local_app_data_path;
74 }
75
76 CString GetGoogleUserPath() {
77 return GetLocalAppDataPath() + SHORT_COMPANY_NAME + _T("\\");
78 }
79
80 // TODO(omaha): make GetGoogleUpdateUserPath and GetGoogleUpdateMachinePath
81 // consistent. They should end with \ or not.
82 CString GetGoogleUpdateUserPath() {
83 return GetGoogleUserPath() + PRODUCT_NAME + _T("\\");
84 }
85
86 CString GetGoogleUpdateMachinePath() {
87 CString program_files;
88 GetFolderPath(CSIDL_PROGRAM_FILES, &program_files);
89 return program_files + _T("\\") + SHORT_COMPANY_NAME
90 + _T("\\") + PRODUCT_NAME;
91 }
92
93 DWORD GetDwordValue(const CString& full_key_name, const CString& value_name) {
94 DWORD value = 0;
95 EXPECT_SUCCEEDED(RegKey::GetValue(full_key_name, value_name, &value));
96 return value;
97 }
98
99 CString GetSzValue(const CString& full_key_name, const CString& value_name) {
100 CString value;
101 EXPECT_SUCCEEDED(RegKey::GetValue(full_key_name, value_name, &value));
102 return value;
103 }
104
105 GUID StringToGuid(const CString& str) {
106 GUID guid(GUID_NULL);
107 VERIFY(SUCCEEDED(StringToGuidSafe(str, &guid)), (_T("guid '%s'"), str));
108 return guid;
109 }
110
111 void OverrideRegistryHives(const CString& hive_override_key_name) {
112 OverrideSpecifiedRegistryHives(hive_override_key_name, true, true);
113 }
114
115 void OverrideSpecifiedRegistryHives(const CString& hive_override_key_name,
116 bool override_hklm,
117 bool override_hkcu) {
118 // Override the destinations of HKLM and HKCU to use a special location
119 // for the unit tests so that we don't disturb the actual Omaha state.
120 RegKey machine_key;
121 RegKey user_key;
122 ASSERT_SUCCEEDED(machine_key.Create(hive_override_key_name + MACHINE_KEY));
123 ASSERT_SUCCEEDED(user_key.Create(hive_override_key_name + USER_KEY));
124 if (override_hklm) {
125 ASSERT_SUCCEEDED(::RegOverridePredefKey(HKEY_LOCAL_MACHINE,
126 machine_key.Key()));
127 }
128 if (override_hkcu) {
129 ASSERT_SUCCEEDED(::RegOverridePredefKey(HKEY_CURRENT_USER,
130 user_key.Key()));
131 }
132 }
133
134 // When tests execute programs (i.e. with ShellExecute or indirectly), Windows
135 // looks at kMyComputerSecurityZoneKeyPathL:kMiscSecurityZonesValueName
136 // to see if it should run the program.
137 // Normally, these reads are not redirected to the override key even though
138 // it seems like they should be. In this case, the execution succeeds.
139 // In certain cases, the reads are redirected and the program execution
140 // fails due to permission denied errors.
141 // This has been observed when XmlUtilsTest::LoadSave() is run before such
142 // tests. Specifically, the my_xmldoc->load() call in LoadXMLFromFile()
143 // appears to somehow cause the redirection to occur.
144 //
145 // See http://support.microsoft.com/kb/182569 for information on security
146 // zones.
147 void OverrideRegistryHivesWithExecutionPermissions(
148 const CString& hive_override_key_name) {
149 OverrideRegistryHives(hive_override_key_name);
150
151 const TCHAR kMyComputerSecurityZoneKeyPath[] =
152 _T("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\")
153 _T("Internet Settings\\Zones\\0");
154 const TCHAR kMiscSecurityZonesValueName[] = _T("1806");
155 const DWORD kPermitAction = 0;
156
157 RegKey my_computer_zone_key;
158 ASSERT_SUCCEEDED(my_computer_zone_key.Create(
159 kMyComputerSecurityZoneKeyPath));
160 ASSERT_SUCCEEDED(my_computer_zone_key.SetValue(kMiscSecurityZonesValueName,
161 kPermitAction));
162 }
163
164 void RestoreRegistryHives() {
165 ASSERT_SUCCEEDED(::RegOverridePredefKey(HKEY_LOCAL_MACHINE, NULL));
166 ASSERT_SUCCEEDED(::RegOverridePredefKey(HKEY_CURRENT_USER, NULL));
167 }
168
169 void SetPsexecDir(const CString& dir) {
170 _tcscpy_s(psexec_dir, arraysize(psexec_dir), dir.GetString());
171 }
172
173 CString GetPsexecDir() {
174 EXPECT_TRUE(_tcsnlen(psexec_dir, arraysize(psexec_dir)));
175 return psexec_dir;
176 }
177
178 // Must be called after SetPsexecDir().
179 // Does not wait for the EULA accepting process to complete.
180 bool AcceptPsexecEula() {
181 CString psexec_dir = GetPsexecDir();
182 if (psexec_dir.IsEmpty()) {
183 return false;
184 }
185
186 CString psexec_path = ConcatenatePath(psexec_dir, _T("psexec.exe"));
187 return SUCCEEDED(System::StartProcessWithArgs(psexec_path,
188 _T("/accepteula")));
189 }
190
191 void SetIsBuildSystem() {
192 is_buildsystem = true;
193 }
194
195 bool IsBuildSystem() {
196 return is_buildsystem;
197 }
198
199 void SetBuildSystemTestSource() {
200 EXPECT_SUCCEEDED(RegKey::SetValue(MACHINE_REG_UPDATE_DEV,
201 kRegValueTestSource,
202 _T("buildsystem")));
203 }
204
205 bool ShouldRunLargeTest() {
206 if (ShouldRunAllTests()) {
207 return true;
208 }
209
210 if (IsEnvironmentVariableSet(_T("OMAHA_TEST_RUN_LARGE"))) {
211 return true;
212 } else {
213 std::wcout << _T("\tThis large test did not run because neither ")
214 _T("'OMAHA_TEST_RUN_LARGE' or 'OMAHA_TEST_RUN_ALL' is set ")
215 _T("in the environment.") << std::endl;
216 return false;
217 }
218 }
219
220 bool ShouldRunEnormousTest() {
221 if (ShouldRunAllTests()) {
222 return true;
223 }
224
225 std::wcout << _T("\tThis large test did not run because ")
226 _T("'OMAHA_TEST_RUN_ALL' is not set in the environment.")
227 << std::endl;
228 return false;
229 }
230
231 void TerminateAllProcessesByName(const TCHAR* process_name) {
232 std::vector<uint32> process_pids;
233 ASSERT_SUCCEEDED(Process::FindProcesses(0, // No flags.
234 process_name,
235 true,
236 &process_pids));
237
238 for (size_t i = 0; i < process_pids.size(); ++i) {
239 scoped_process process(::OpenProcess(PROCESS_TERMINATE,
240 FALSE,
241 process_pids[i]));
242 EXPECT_TRUE(process);
243 EXPECT_TRUE(::TerminateProcess(get(process), static_cast<uint32>(-3)));
244 }
245 }
246
247 void TerminateAllGoogleUpdateProcesses() {
248 TerminateAllProcessesByName(kOmahaShellFileName);
249 TerminateAllProcessesByName(kCrashHandlerFileName);
250 }
251
252 // The exit code of psexec is the pid it started when -d is used.
253 // Wait for psexec to exit, get the exit code, and use it to get a handle
254 // to the GoogleUpdate.exe instance.
255 void LaunchProcessAsSystem(const CString& launch_cmd, HANDLE* process) {
256 ASSERT_TRUE(process);
257
258 CString app_launcher = ConcatenatePath(GetPsexecDir(), _T("psexec.exe"));
259 CString cmd_line_args;
260 cmd_line_args.Format(_T("-s -d %s"), launch_cmd);
261
262 PROCESS_INFORMATION pi = {0};
263 EXPECT_SUCCEEDED(System::StartProcessWithArgsAndInfo(app_launcher,
264 cmd_line_args,
265 &pi));
266 ::CloseHandle(pi.hThread);
267 scoped_handle started_process(pi.hProcess);
268 ASSERT_TRUE(started_process);
269
270 DWORD google_update_pid = 0;
271 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(get(started_process), 30000));
272 EXPECT_TRUE(::GetExitCodeProcess(get(started_process), &google_update_pid));
273 DWORD desired_access =
274 PROCESS_QUERY_INFORMATION | SYNCHRONIZE | PROCESS_TERMINATE;
275 *process = ::OpenProcess(desired_access, false, google_update_pid);
276 DWORD last_error(::GetLastError());
277
278 // psexec sometimes returns errors instead of PIDs and there is no way to
279 // tell the difference. We see ERROR_SERVICE_MARKED_FOR_DELETE (1072)
280 // intermittently on the build server, but do not expect any other errors.
281 EXPECT_TRUE(*process ||
282 ERROR_SERVICE_MARKED_FOR_DELETE == google_update_pid) <<
283 _T("::OpenProcess failed in a case where psexec did not return ")
284 _T("ERROR_SERVICE_MARKED_FOR_DELETE.") << _T(" The error was ")
285 << last_error << _T(".");
286 }
287
288 void LaunchProcess(const CString& exe_path,
289 const CString& args,
290 bool as_system,
291 HANDLE* process) {
292 ASSERT_TRUE(process);
293 *process = NULL;
294
295 CString launch_cmd = exe_path;
296 EnclosePath(&launch_cmd);
297 launch_cmd += args.IsEmpty() ? _T("") : _T(" ") + args;
298
299 if (as_system) {
300 // Retry the process launch if the process handle is invalid. Hopefully this
301 // is robust against intermittent ERROR_SERVICE_MARKED_FOR_DELETE errors.
302 for (int tries = 0; tries < 10 && !*process; ++tries) {
303 LaunchProcessAsSystem(launch_cmd, process);
304 if (!*process) {
305 ::Sleep(1000);
306 }
307 }
308 } else {
309 PROCESS_INFORMATION pi = {0};
310 EXPECT_SUCCEEDED(System::StartProcess(NULL, launch_cmd.GetBuffer(), &pi));
311 ::CloseHandle(pi.hThread);
312 *process = pi.hProcess;
313 }
314
315 ASSERT_TRUE(*process);
316 }
317
318 void RegistryProtectedTest::SetUp() {
319 RegKey::DeleteKey(hive_override_key_name_, true);
320 OverrideRegistryHives(hive_override_key_name_);
321 }
322
323 void RegistryProtectedTest::TearDown() {
324 RestoreRegistryHives();
325 ASSERT_SUCCEEDED(RegKey::DeleteKey(hive_override_key_name_, true));
326 }
327
328 CString GetUniqueTempDirectoryName() {
329 CString guid;
330 EXPECT_HRESULT_SUCCEEDED(GetGuid(&guid));
331 return ConcatenatePath(app_util::GetTempDir(), guid);
332 }
333
334 void RunAsAdmin(const CString& exe_path, const CString& cmd_line) {
335 if (vista_util::IsUserAdmin()) {
336 EXPECT_SUCCEEDED(RegisterOrUnregisterExe(exe_path, cmd_line));
337 return;
338 }
339
340 // Elevate for medium integrity users on Vista and above.
341 DWORD exit_code(S_OK);
342 EXPECT_SUCCEEDED(vista_util::RunElevated(exe_path,
343 cmd_line,
344 SW_SHOWNORMAL,
345 &exit_code));
346 EXPECT_SUCCEEDED(exit_code);
347 }
348
349 void RegisterOrUnregisterGoopdateLocalServer(bool reg) {
350 CString server_path = ConcatenatePath(GetGoogleUpdateMachinePath(),
351 kOmahaShellFileName);
352 EnclosePath(&server_path);
353
354 CommandLineBuilder builder(reg ? COMMANDLINE_MODE_REGSERVER :
355 COMMANDLINE_MODE_UNREGSERVER);
356 CString cmd_line = builder.GetCommandLineArgs();
357 RunAsAdmin(server_path, cmd_line);
358 }
359
360 void RegisterOrUnregisterGoopdateService(bool reg) {
361 CString service_path = ConcatenatePath(GetGoogleUpdateMachinePath(),
362 kServiceFileName);
363 EnclosePath(&service_path);
364
365 CommandLineBuilder builder(reg ? COMMANDLINE_MODE_SERVICE_REGISTER :
366 COMMANDLINE_MODE_SERVICE_UNREGISTER);
367 CString cmd_line = builder.GetCommandLineArgs();
368 RunAsAdmin(service_path, cmd_line);
369 }
370
371 } // namespace omaha
OLDNEW
« no previous file with comments | « testing/unit_test.h ('k') | testing/unit_test_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698