OLD | NEW |
| (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 | |
17 #include <vector> | |
18 #include "base/basictypes.h" | |
19 #include "base/scoped_ptr.h" | |
20 #include "omaha/base/app_util.h" | |
21 #include "omaha/base/const_object_names.h" | |
22 #include "omaha/base/error.h" | |
23 #include "omaha/base/file.h" | |
24 #include "omaha/base/path.h" | |
25 #include "omaha/base/omaha_version.h" | |
26 #include "omaha/base/process.h" | |
27 #include "omaha/base/scope_guard.h" | |
28 #include "omaha/base/scoped_any.h" | |
29 #include "omaha/base/synchronized.h" | |
30 #include "omaha/base/system.h" | |
31 #include "omaha/base/thread.h" | |
32 #include "omaha/base/user_info.h" | |
33 #include "omaha/base/utils.h" | |
34 #include "omaha/base/vistautil.h" | |
35 #include "omaha/common/command_line.h" | |
36 #include "omaha/common/config_manager.h" | |
37 #include "omaha/common/const_goopdate.h" | |
38 #include "omaha/setup/setup.h" | |
39 #include "omaha/setup/setup_files.h" | |
40 #include "omaha/testing/unit_test.h" | |
41 | |
42 namespace omaha { | |
43 | |
44 namespace { | |
45 | |
46 const int kProcessesCleanupWait = 30000; | |
47 | |
48 const TCHAR* const kFutureVersionString = _T("9.8.7.6"); | |
49 | |
50 const TCHAR* const kAppMachineClientsPath = | |
51 _T("HKLM\\Software\\") SHORT_COMPANY_NAME _T("\\") PRODUCT_NAME | |
52 _T("\\Clients\\{50DA5C89-FF97-4536-BF3F-DF54C2F02EA8}\\"); | |
53 const TCHAR* const kAppMachineClientStatePath = | |
54 _T("HKLM\\Software\\") SHORT_COMPANY_NAME _T("\\") PRODUCT_NAME | |
55 _T("\\ClientState\\{50DA5C89-FF97-4536-BF3F-DF54C2F02EA8}\\"); | |
56 const TCHAR* const kApp2MachineClientsPath = | |
57 _T("HKLM\\Software\\") SHORT_COMPANY_NAME _T("\\") PRODUCT_NAME | |
58 _T("\\Clients\\{CB8E8A3C-7295-4529-B083-D5F76DCD4CC2}\\"); | |
59 | |
60 const TCHAR* const kAppUserClientsPath = | |
61 _T("HKCU\\Software\\") SHORT_COMPANY_NAME _T("\\") PRODUCT_NAME | |
62 _T("\\Clients\\{50DA5C89-FF97-4536-BF3F-DF54C2F02EA8}\\"); | |
63 const TCHAR* const kAppUserClientStatePath = | |
64 _T("HKCU\\Software\\") SHORT_COMPANY_NAME _T("\\") PRODUCT_NAME | |
65 _T("\\ClientState\\{50DA5C89-FF97-4536-BF3F-DF54C2F02EA8}\\"); | |
66 const TCHAR* const kApp2UserClientsPath = | |
67 _T("HKCU\\Software\\") SHORT_COMPANY_NAME _T("\\") PRODUCT_NAME | |
68 _T("\\Clients\\{CB8E8A3C-7295-4529-B083-D5F76DCD4CC2}\\"); | |
69 | |
70 | |
71 class HoldLock : public Runnable { | |
72 public: | |
73 explicit HoldLock(bool is_machine) | |
74 : is_machine_(is_machine) { | |
75 reset(lock_acquired_event_, ::CreateEvent(NULL, false, false, NULL)); | |
76 reset(stop_event_, ::CreateEvent(NULL, false, false, NULL)); | |
77 } | |
78 | |
79 virtual void Run() { | |
80 GLock setup_lock; | |
81 NamedObjectAttributes setup_lock_attr; | |
82 GetNamedObjectAttributes(omaha::kSetupMutex, is_machine_, &setup_lock_attr); | |
83 EXPECT_TRUE(setup_lock.InitializeWithSecAttr(setup_lock_attr.name, | |
84 &setup_lock_attr.sa)); | |
85 __mutexScope(setup_lock); | |
86 | |
87 EXPECT_TRUE(::SetEvent(get(lock_acquired_event_))); | |
88 | |
89 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(get(stop_event_), INFINITE)); | |
90 } | |
91 | |
92 void Stop() { | |
93 EXPECT_TRUE(::SetEvent(get(stop_event_))); | |
94 } | |
95 | |
96 void WaitForLockToBeAcquired() { | |
97 EXPECT_EQ(WAIT_OBJECT_0, | |
98 ::WaitForSingleObject(get(lock_acquired_event_), 2000)); | |
99 } | |
100 | |
101 private: | |
102 const bool is_machine_; | |
103 scoped_event lock_acquired_event_; | |
104 scoped_event stop_event_; | |
105 | |
106 DISALLOW_IMPLICIT_CONSTRUCTORS(HoldLock); | |
107 }; | |
108 | |
109 } // namespace | |
110 | |
111 void CopyGoopdateFiles(const CString& omaha_path, const CString& version); | |
112 | |
113 class SetupTest : public testing::Test { | |
114 protected: | |
115 | |
116 typedef std::vector<uint32> Pids; | |
117 | |
118 // Returns the path to the long-running GoogleUpdate.exe. | |
119 static CString CopyGoopdateAndLongRunningFiles(const CString& omaha_path, | |
120 const CString& version) { | |
121 CopyGoopdateFiles(omaha_path, version); | |
122 | |
123 CString long_running_target_path = ConcatenatePath(omaha_path, | |
124 _T("does_not_shutdown")); | |
125 EXPECT_SUCCEEDED(CreateDir(long_running_target_path, NULL)); | |
126 long_running_target_path = ConcatenatePath(long_running_target_path, | |
127 kOmahaShellFileName); | |
128 EXPECT_SUCCEEDED(File::Copy( | |
129 ConcatenatePath(ConcatenatePath( | |
130 app_util::GetCurrentModuleDirectory(), | |
131 _T("unittest_support\\does_not_shutdown")), | |
132 kOmahaShellFileName), | |
133 long_running_target_path, | |
134 false)); | |
135 | |
136 return long_running_target_path; | |
137 } | |
138 | |
139 static void SetUpTestCase() { | |
140 not_listening_machine_exe_path_ = | |
141 CopyGoopdateAndLongRunningFiles(GetGoogleUpdateMachinePath(), | |
142 GetVersionString()); | |
143 not_listening_user_exe_path_ = | |
144 CopyGoopdateAndLongRunningFiles(GetGoogleUpdateUserPath(), | |
145 GetVersionString()); | |
146 } | |
147 | |
148 explicit SetupTest(bool is_machine) | |
149 : is_machine_(is_machine), | |
150 omaha_path_(is_machine ? GetGoogleUpdateMachinePath() : | |
151 GetGoogleUpdateUserPath()), | |
152 not_listening_exe_path_(is_machine ? not_listening_machine_exe_path_ : | |
153 not_listening_user_exe_path_), | |
154 not_listening_exe_opposite_path_(!is_machine ? | |
155 not_listening_machine_exe_path_ : | |
156 not_listening_user_exe_path_) { | |
157 omaha_exe_path_ = ConcatenatePath(omaha_path_, _T("GoogleUpdate.exe")); | |
158 } | |
159 | |
160 virtual void SetUp() { | |
161 ASSERT_SUCCEEDED(CreateDir(omaha_path_, NULL)); | |
162 setup_.reset(new omaha::Setup(is_machine_)); | |
163 } | |
164 | |
165 bool ShouldInstall() { | |
166 SetupFiles setup_files(is_machine_); | |
167 setup_files.Init(); | |
168 return setup_->ShouldInstall(&setup_files); | |
169 } | |
170 | |
171 HRESULT StopGoogleUpdateAndWait() { | |
172 return setup_->StopGoogleUpdateAndWait(); | |
173 } | |
174 | |
175 HRESULT TerminateCoreProcesses() const { | |
176 return setup_->TerminateCoreProcesses(); | |
177 } | |
178 | |
179 // Acquires the Setup Lock in another thread then calls TestInstall(). | |
180 void TestInstallWhileHoldingLock() { | |
181 HoldLock hold_lock(is_machine_); | |
182 | |
183 Thread thread; | |
184 thread.Start(&hold_lock); | |
185 hold_lock.WaitForLockToBeAcquired(); | |
186 | |
187 EXPECT_EQ(GOOPDATE_E_FAILED_TO_GET_LOCK, setup_->Install(false)); | |
188 | |
189 hold_lock.Stop(); | |
190 thread.WaitTillExit(1000); | |
191 } | |
192 | |
193 void StopGoogleUpdateAndWaitSucceedsTestHelper(bool use_job_objects_only) { | |
194 if (is_machine_ && !vista_util::IsUserAdmin()) { | |
195 std::wcout << _T("\tTest did not run because the user is not an admin.") | |
196 << std::endl; | |
197 return; | |
198 } | |
199 | |
200 if (!ShouldRunLargeTest()) { | |
201 return; | |
202 } | |
203 if (IsBuildSystem()) { | |
204 std::wcout << _T("\tTest not run because it is flaky on build system.") | |
205 << std::endl; | |
206 return; | |
207 } | |
208 | |
209 scoped_process core_process; | |
210 scoped_process install_process; | |
211 scoped_process opposite_process; | |
212 scoped_process user_handoff_process; | |
213 scoped_process user_install_goopdate_process; | |
214 scoped_process user_install_slashinstall_process; | |
215 scoped_process setup_phase1_job_process; | |
216 scoped_process setup_phase1_job_opposite_process; | |
217 scoped_process install_job_opposite_process; | |
218 scoped_process silent_job_opposite_process; | |
219 scoped_process silent_do_not_kill_job_opposite_process; | |
220 scoped_job setup_phase1_job; | |
221 scoped_job setup_phase1_job_opposite; | |
222 scoped_job install_job_opposite; | |
223 scoped_job silent_job_opposite; | |
224 scoped_job silent_do_not_kill_job_opposite; | |
225 | |
226 StartCoreProcessesToShutdown(address(core_process)); | |
227 ASSERT_TRUE(core_process); | |
228 | |
229 if (use_job_objects_only && is_machine_) { | |
230 // When starting the core process with psexec, there is a race condition | |
231 // between that process initializing (and joining a Job Object) and | |
232 // StopGoogleUpdateAndWait() looking for processes. If the latter wins, | |
233 // the core process is not found and StopGoogleUpdateAndWait() does not | |
234 // wait for the core process. As a result, | |
235 // ::WaitForSingleObject(get(core_process), 0)) would fail intermittently. | |
236 // Sleep here to allow the process to start and join the job. | |
237 // Note that this race condition is similar to ones we might encounter | |
238 // in the field when using Job Objects. | |
239 ::Sleep(500); | |
240 } | |
241 | |
242 // /install is always ignored. | |
243 LaunchProcess(not_listening_exe_path_, | |
244 _T("/install"), | |
245 is_machine_, | |
246 address(install_process)); | |
247 ASSERT_TRUE(install_process); | |
248 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(get(install_process), 0)); | |
249 | |
250 if (vista_util::IsUserAdmin()) { | |
251 // GoogleUpdate running from the opposite directory should always be | |
252 // ignored. Using a command line that would not be ignored if it were not | |
253 // an opposite. | |
254 LaunchProcess(not_listening_exe_opposite_path_, | |
255 _T(""), | |
256 false, | |
257 address(opposite_process)); | |
258 EXPECT_TRUE(opposite_process); | |
259 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(get(opposite_process), 0)); | |
260 } else { | |
261 EXPECT_FALSE(is_machine_) | |
262 << _T("Unexpected call for machine when non-admin."); | |
263 // We can't launch a system process when non-admin. | |
264 std::wcout << _T("\tPart of this test did not run because the user is ") | |
265 _T("not an admin.") << std::endl; | |
266 } | |
267 | |
268 CString same_needsadmin = is_machine_ ? _T("\"needsadmin=True\"") : | |
269 _T("\"needsadmin=False\""); | |
270 // Machine setup looks for users running most modes from the machine | |
271 // official directory, and user setup looks for users running most modes | |
272 // from the user official directory. | |
273 // Launching with needsadmin=<same> tests that machine still ignores | |
274 // needsadmin=True and user ignores needsadmin=False when the opposite | |
275 // instances are running. | |
276 LaunchProcess(not_listening_exe_opposite_path_, | |
277 _T("/handoff ") + same_needsadmin, | |
278 false, // As the user. | |
279 address(user_handoff_process)); | |
280 EXPECT_TRUE(user_handoff_process); | |
281 EXPECT_EQ(WAIT_TIMEOUT, | |
282 ::WaitForSingleObject(get(user_handoff_process), 0)); | |
283 | |
284 // This process should be ignored even though it is running from the correct | |
285 // official directory. | |
286 LaunchProcess(not_listening_exe_path_, | |
287 _T("/install ") + same_needsadmin, | |
288 false, // As the user. | |
289 address(user_install_slashinstall_process)); | |
290 EXPECT_TRUE(user_install_goopdate_process); | |
291 EXPECT_EQ(WAIT_TIMEOUT, | |
292 ::WaitForSingleObject(get(user_install_goopdate_process), 0)); | |
293 | |
294 if (use_job_objects_only) { | |
295 // This Job Object is ignored. | |
296 // Only start this process when only using Job Objects because the | |
297 // argument-less process would be caught by the command line search. | |
298 LaunchJobProcess(is_machine_, | |
299 is_machine_, | |
300 kSetupPhase1NonSelfUpdateJobObject, | |
301 address(setup_phase1_job_process), | |
302 address(setup_phase1_job)); | |
303 ASSERT_TRUE(setup_phase1_job_process); | |
304 EXPECT_EQ(WAIT_TIMEOUT, | |
305 ::WaitForSingleObject(get(setup_phase1_job_process), 0)); | |
306 } | |
307 | |
308 if (is_machine_ || vista_util::IsUserAdmin()) { | |
309 // These processes should be ignored because they are for the opposite | |
310 // set of processes. | |
311 | |
312 LaunchJobProcess(!is_machine_, | |
313 !is_machine_, | |
314 kSetupPhase1NonSelfUpdateJobObject, | |
315 address(setup_phase1_job_opposite_process), | |
316 address(setup_phase1_job_opposite)); | |
317 ASSERT_TRUE(setup_phase1_job_opposite_process); | |
318 EXPECT_EQ(WAIT_TIMEOUT, | |
319 ::WaitForSingleObject(get(setup_phase1_job_opposite_process), | |
320 0)); | |
321 | |
322 LaunchJobProcess(!is_machine_, | |
323 !is_machine_, | |
324 kAppInstallJobObject, | |
325 address(install_job_opposite_process), | |
326 address(install_job_opposite)); | |
327 ASSERT_TRUE(install_job_opposite_process); | |
328 EXPECT_EQ(WAIT_TIMEOUT, | |
329 ::WaitForSingleObject(get(install_job_opposite_process), 0)); | |
330 | |
331 LaunchJobProcess(!is_machine_, | |
332 !is_machine_, | |
333 kSilentJobObject, | |
334 address(silent_job_opposite_process), | |
335 address(silent_job_opposite)); | |
336 ASSERT_TRUE(install_job_opposite_process); | |
337 EXPECT_EQ(WAIT_TIMEOUT, | |
338 ::WaitForSingleObject(get(install_job_opposite_process), 0)); | |
339 | |
340 LaunchJobProcess(!is_machine_, | |
341 !is_machine_, | |
342 kSilentDoNotKillJobObject, | |
343 address(silent_do_not_kill_job_opposite_process), | |
344 address(silent_do_not_kill_job_opposite)); | |
345 ASSERT_TRUE(install_job_opposite_process); | |
346 EXPECT_EQ(WAIT_TIMEOUT, | |
347 ::WaitForSingleObject(get(install_job_opposite_process), 0)); | |
348 } | |
349 | |
350 EXPECT_SUCCEEDED(StopGoogleUpdateAndWait()); | |
351 EXPECT_EQ(0, setup_->extra_code1()); | |
352 | |
353 // Verify the real core process exited and terminate the processes that are | |
354 // not listening to shutdown. | |
355 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(get(core_process), 0)); | |
356 | |
357 // Terminate all the processes and wait for them to exit to avoid | |
358 // interfering with other tests. | |
359 std::vector<HANDLE> started_processes; | |
360 started_processes.push_back(get(install_process)); | |
361 if (vista_util::IsUserAdmin()) { | |
362 started_processes.push_back(get(opposite_process)); | |
363 } | |
364 started_processes.push_back(get(user_handoff_process)); | |
365 started_processes.push_back(get(user_install_goopdate_process)); | |
366 started_processes.push_back(get(user_install_slashinstall_process)); | |
367 if (use_job_objects_only) { | |
368 started_processes.push_back(get(setup_phase1_job_process)); | |
369 } | |
370 if (is_machine_ || vista_util::IsUserAdmin()) { | |
371 started_processes.push_back(get(setup_phase1_job_opposite_process)); | |
372 started_processes.push_back(get(install_job_opposite_process)); | |
373 started_processes.push_back(get(silent_job_opposite_process)); | |
374 started_processes.push_back(get(silent_do_not_kill_job_opposite_process)); | |
375 } | |
376 | |
377 for (size_t i = 0; i < started_processes.size(); ++i) { | |
378 SETUP_LOG(L1, (_T("Terminating PID %u]"), | |
379 ::GetProcessId(started_processes[i]))); | |
380 EXPECT_TRUE(::TerminateProcess(started_processes[i], 1)); | |
381 } | |
382 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForMultipleObjects(started_processes.size(), | |
383 &started_processes[0], | |
384 true, // wait for all | |
385 kProcessesCleanupWait)); | |
386 } | |
387 | |
388 void StopGoogleUpdateAndWaitSucceedsTest() { | |
389 StopGoogleUpdateAndWaitSucceedsTestHelper(false); | |
390 } | |
391 | |
392 HRESULT GetRunningCoreProcesses(Pids* core_processes) { | |
393 ASSERT1(core_processes); | |
394 | |
395 CString user_sid_to_use; | |
396 if (is_machine_) { | |
397 user_sid_to_use = kLocalSystemSid; | |
398 } else { | |
399 EXPECT_SUCCEEDED(user_info::GetProcessUser(NULL, NULL, &user_sid_to_use)); | |
400 } | |
401 | |
402 DWORD flags = INCLUDE_ONLY_PROCESS_OWNED_BY_USER | | |
403 EXCLUDE_CURRENT_PROCESS | | |
404 INCLUDE_PROCESS_COMMAND_LINE_CONTAINING_STRING; | |
405 | |
406 std::vector<CString> command_lines; | |
407 command_lines.push_back(_T("/c")); | |
408 | |
409 return Process::FindProcesses(flags, | |
410 kOmahaShellFileName, | |
411 true, | |
412 user_sid_to_use, | |
413 command_lines, | |
414 core_processes); | |
415 } | |
416 | |
417 void KillRunningCoreProcesses() { | |
418 Pids core_processes; | |
419 EXPECT_SUCCEEDED(GetRunningCoreProcesses(&core_processes)); | |
420 | |
421 for (size_t i = 0; i < core_processes.size(); ++i) { | |
422 scoped_process process(::OpenProcess(PROCESS_TERMINATE, | |
423 FALSE, | |
424 core_processes[i])); | |
425 EXPECT_TRUE(process); | |
426 EXPECT_TRUE(::TerminateProcess(get(process), static_cast<uint32>(-2))); | |
427 } | |
428 } | |
429 | |
430 // Uses psexec to start processes as SYSTEM if necessary. | |
431 // Assumes that psexec blocks until the process exits. | |
432 // TODO(omaha): Start the opposite instances and wait for them in | |
433 // StopGoogleUpdateAndWaitSucceedsTest. They should not close. | |
434 void StartCoreProcessesToShutdown(HANDLE* core_process) { | |
435 ASSERT_TRUE(core_process); | |
436 | |
437 // Find the core process or start one if necessary. | |
438 Pids core_processes; | |
439 EXPECT_SUCCEEDED(GetRunningCoreProcesses(&core_processes)); | |
440 ASSERT_LE(core_processes.size(), static_cast<size_t>(1)) | |
441 << _T("Only one core should be running."); | |
442 | |
443 if (core_processes.empty()) { | |
444 LaunchProcess(omaha_exe_path_, | |
445 _T("/c"), | |
446 is_machine_, | |
447 core_process); | |
448 } else { | |
449 *core_process = ::OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, | |
450 FALSE, | |
451 core_processes[0]); | |
452 } | |
453 ASSERT_TRUE(*core_process); | |
454 | |
455 HANDLE processes[] = {*core_process}; | |
456 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForMultipleObjects(arraysize(processes), | |
457 processes, | |
458 true, // wait for all | |
459 0)); | |
460 } | |
461 | |
462 // Launches an instance of GoogleUpdate.exe that doesn't exit. | |
463 void StopGoogleUpdateAndWaitProcessesDoNotStopTest() { | |
464 LaunchProcessAndExpectStopGoogleUpdateAndWaitKillsProcess( | |
465 is_machine_, | |
466 _T("")); | |
467 } | |
468 | |
469 void LaunchProcessAndExpectStopGoogleUpdateAndWaitKillsProcess( | |
470 bool is_machine_process, | |
471 const CString& args) { | |
472 ASSERT_TRUE(args); | |
473 | |
474 if (is_machine_ && !vista_util::IsUserAdmin()) { | |
475 std::wcout << _T("\tTest did not run because the user is not an admin.") | |
476 << std::endl; | |
477 return; | |
478 } | |
479 | |
480 if (!ShouldRunLargeTest()) { | |
481 return; | |
482 } | |
483 scoped_process process; | |
484 LaunchProcess(not_listening_exe_path_, | |
485 args, | |
486 is_machine_process, | |
487 address(process)); | |
488 ASSERT_TRUE(process); | |
489 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(get(process), 0)); | |
490 | |
491 // Tests that use this method intermittently fail when run on build systems. | |
492 // This code attempts to ensure that the process is further along in the | |
493 // initialization process by waiting until Process::GetCommandLine succeeds. | |
494 HRESULT hr = E_FAIL; | |
495 CString process_cmd; | |
496 for (int tries = 0; tries < 100 && FAILED(hr); ++tries) { | |
497 hr = Process::GetCommandLine(::GetProcessId(get(process)), &process_cmd); | |
498 if (FAILED(hr)) { | |
499 ::Sleep(50); | |
500 } | |
501 } | |
502 EXPECT_SUCCEEDED(hr); | |
503 | |
504 EXPECT_EQ(S_OK, StopGoogleUpdateAndWait()); | |
505 // Make sure the process has been killed. | |
506 EXPECT_EQ(WAIT_OBJECT_0, | |
507 ::WaitForSingleObject(get(process), kProcessesCleanupWait)); | |
508 } | |
509 | |
510 // Starts a core process for this user, a core for the opposite type of user, | |
511 // and a /cr process (similar command line to /c), and a process without args. | |
512 void TestTerminateCoreProcessesWithBothTypesRunningAndOtherProcesses() { | |
513 scoped_process core_process; | |
514 scoped_process opposite_core_process; | |
515 scoped_process codered_process; | |
516 scoped_process noargs_process; | |
517 LaunchProcess(not_listening_exe_path_, | |
518 _T("/c"), | |
519 is_machine_, | |
520 address(core_process)); | |
521 ASSERT_TRUE(core_process); | |
522 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(get(core_process), 0)); | |
523 LaunchProcess(not_listening_exe_opposite_path_, | |
524 _T("/c"), | |
525 !is_machine_, | |
526 address(opposite_core_process)); | |
527 ASSERT_TRUE(opposite_core_process); | |
528 EXPECT_EQ(WAIT_TIMEOUT, | |
529 ::WaitForSingleObject(get(opposite_core_process), 0)); | |
530 LaunchProcess(not_listening_exe_path_, | |
531 _T("/cr"), | |
532 is_machine_, | |
533 address(codered_process)); | |
534 ASSERT_TRUE(codered_process); | |
535 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(get(codered_process), 0)); | |
536 LaunchProcess(not_listening_exe_path_, | |
537 _T(""), | |
538 is_machine_, | |
539 address(noargs_process)); | |
540 ASSERT_TRUE(noargs_process); | |
541 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(get(noargs_process), 0)); | |
542 | |
543 EXPECT_SUCCEEDED(TerminateCoreProcesses()); | |
544 | |
545 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(get(core_process), 8000)); | |
546 HANDLE ignored_processes[] = {get(opposite_core_process), | |
547 get(codered_process), | |
548 get(noargs_process)}; | |
549 EXPECT_EQ(WAIT_TIMEOUT, | |
550 ::WaitForMultipleObjects(arraysize(ignored_processes), | |
551 ignored_processes, | |
552 false, // wait for any | |
553 1000)); | |
554 | |
555 HANDLE started_processes[] = {get(core_process), | |
556 get(opposite_core_process), | |
557 get(codered_process), | |
558 get(noargs_process)}; | |
559 EXPECT_TRUE(::TerminateProcess(get(opposite_core_process), 1)); | |
560 EXPECT_TRUE(::TerminateProcess(get(codered_process), 1)); | |
561 EXPECT_TRUE(::TerminateProcess(get(noargs_process), 1)); | |
562 EXPECT_EQ(WAIT_OBJECT_0, | |
563 ::WaitForMultipleObjects(arraysize(started_processes), | |
564 started_processes, | |
565 true, // wait for all | |
566 kProcessesCleanupWait)); | |
567 } | |
568 | |
569 // Starts dummy process that doesn't exit and assigns it to the specified job. | |
570 // The handle returned by ShellExecute does not have PROCESS_SET_QUOTA access | |
571 // rights, so we get a new handle with the correct access rights to return to | |
572 // the caller. | |
573 void LaunchJobProcess(bool is_machine, | |
574 bool as_system, | |
575 const CString& job_base_name, | |
576 HANDLE* process, | |
577 HANDLE* job) { | |
578 ASSERT_TRUE(process); | |
579 ASSERT_TRUE(job); | |
580 ASSERT_TRUE(is_machine || !as_system); | |
581 | |
582 scoped_process launched_process; | |
583 LaunchProcess(is_machine ? not_listening_machine_exe_path_ : | |
584 not_listening_user_exe_path_, | |
585 _T(""), | |
586 as_system, | |
587 address(launched_process)); | |
588 ASSERT_TRUE(launched_process); | |
589 | |
590 *process = ::OpenProcess(PROCESS_ALL_ACCESS, | |
591 false, | |
592 ::GetProcessId(get(launched_process))); | |
593 ASSERT_TRUE(*process); | |
594 | |
595 NamedObjectAttributes job_attr; | |
596 GetNamedObjectAttributes(job_base_name, is_machine, &job_attr); | |
597 *job = ::CreateJobObject(&job_attr.sa, job_attr.name); | |
598 ASSERT_TRUE(*job); | |
599 | |
600 if (ERROR_ALREADY_EXISTS != ::GetLastError()) { | |
601 // Configure the newly created Job Object so it is compatible with any | |
602 // real processes that may be created. | |
603 JOBOBJECT_EXTENDED_LIMIT_INFORMATION extended_info = {0}; | |
604 | |
605 ASSERT_TRUE(::QueryInformationJobObject( | |
606 *job, | |
607 ::JobObjectExtendedLimitInformation, | |
608 &extended_info, | |
609 sizeof(extended_info), | |
610 NULL)) << | |
611 _T("Last Error: ") << ::GetLastError() << std::endl; | |
612 | |
613 extended_info.BasicLimitInformation.LimitFlags = | |
614 JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK; | |
615 ASSERT_TRUE(::SetInformationJobObject(*job, | |
616 ::JobObjectExtendedLimitInformation, | |
617 &extended_info, | |
618 sizeof(extended_info))) << | |
619 _T("Last Error: ") << ::GetLastError() << std::endl; | |
620 } | |
621 | |
622 ASSERT_TRUE(::AssignProcessToJobObject(*job, *process)) << | |
623 _T("Last Error: ") << ::GetLastError() << std::endl; | |
624 } | |
625 | |
626 void TestShouldDelayUninstall() { | |
627 EXPECT_FALSE(setup_->ShouldDelayUninstall()); | |
628 | |
629 const TCHAR* key = ConfigManager::Instance()->registry_update(is_machine_); | |
630 | |
631 DWORD value = 1; | |
632 EXPECT_SUCCEEDED(RegKey::SetValue(key, | |
633 kRegValueDelayOmahaUninstall, | |
634 value)); | |
635 EXPECT_TRUE(setup_->ShouldDelayUninstall()); | |
636 | |
637 value = 0; | |
638 EXPECT_SUCCEEDED(RegKey::SetValue(key, | |
639 kRegValueDelayOmahaUninstall, | |
640 value)); | |
641 EXPECT_FALSE(setup_->ShouldDelayUninstall()); | |
642 | |
643 EXPECT_SUCCEEDED(RegKey::DeleteValue(key, | |
644 kRegValueDelayOmahaUninstall)); | |
645 EXPECT_FALSE(setup_->ShouldDelayUninstall()); | |
646 } | |
647 | |
648 void TestSetDelayUninstall() { | |
649 EXPECT_FALSE(setup_->ShouldDelayUninstall()); | |
650 | |
651 EXPECT_SUCCEEDED(setup_->SetDelayUninstall(true)); | |
652 EXPECT_TRUE(setup_->ShouldDelayUninstall()); | |
653 | |
654 EXPECT_SUCCEEDED(setup_->SetDelayUninstall(true)); | |
655 EXPECT_TRUE(setup_->ShouldDelayUninstall()); | |
656 | |
657 EXPECT_SUCCEEDED(setup_->SetDelayUninstall(false)); | |
658 EXPECT_FALSE(setup_->ShouldDelayUninstall()); | |
659 | |
660 EXPECT_SUCCEEDED(setup_->SetDelayUninstall(false)); | |
661 EXPECT_FALSE(setup_->ShouldDelayUninstall()); | |
662 } | |
663 | |
664 const bool is_machine_; | |
665 const CString omaha_path_; | |
666 CString omaha_exe_path_; | |
667 CString not_listening_exe_path_; | |
668 CString not_listening_exe_opposite_path_; | |
669 scoped_ptr<omaha::Setup> setup_; | |
670 | |
671 static CString not_listening_user_exe_path_; | |
672 static CString not_listening_machine_exe_path_; | |
673 }; | |
674 | |
675 CString SetupTest::not_listening_user_exe_path_; | |
676 CString SetupTest::not_listening_machine_exe_path_; | |
677 | |
678 class SetupMachineTest : public SetupTest { | |
679 protected: | |
680 SetupMachineTest() : SetupTest(true) { | |
681 } | |
682 | |
683 static void SetUpTestCase() { | |
684 // SeDebugPrivilege is required for elevated admins to open process open | |
685 // Local System processes with PROCESS_QUERY_INFORMATION access rights. | |
686 System::AdjustPrivilege(SE_DEBUG_NAME, true); | |
687 | |
688 SetupTest::SetUpTestCase(); | |
689 } | |
690 }; | |
691 | |
692 class SetupUserTest : public SetupTest { | |
693 protected: | |
694 SetupUserTest() : SetupTest(false) { | |
695 } | |
696 }; | |
697 | |
698 class SetupFutureVersionInstalledUserTest : public SetupUserTest { | |
699 protected: | |
700 SetupFutureVersionInstalledUserTest() | |
701 : SetupUserTest(), | |
702 future_version_path_(ConcatenatePath(omaha_path_, | |
703 kFutureVersionString)) { | |
704 } | |
705 | |
706 virtual void SetUp() { | |
707 SetupUserTest::SetUp(); | |
708 | |
709 // Save the existing version if present. | |
710 RegKey::GetValue(USER_REG_CLIENTS_GOOPDATE, | |
711 kRegValueProductVersion, | |
712 &existing_version_); | |
713 InstallFutureVersion(); | |
714 } | |
715 | |
716 virtual void TearDown() { | |
717 EXPECT_SUCCEEDED(DeleteDirectory(future_version_path_)); | |
718 if (existing_version_.IsEmpty()) { | |
719 EXPECT_SUCCEEDED(RegKey::DeleteValue(USER_REG_CLIENTS_GOOPDATE, | |
720 kRegValueProductVersion)); | |
721 } else { | |
722 EXPECT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
723 kRegValueProductVersion, | |
724 existing_version_)); | |
725 } | |
726 | |
727 SetupUserTest::TearDown(); | |
728 } | |
729 | |
730 void InstallFutureVersion() { | |
731 DeleteDirectory(future_version_path_); | |
732 EXPECT_FALSE(File::IsDirectory(future_version_path_)); | |
733 | |
734 EXPECT_SUCCEEDED(CreateDir(future_version_path_, NULL)); | |
735 | |
736 EXPECT_SUCCEEDED(File::Copy( | |
737 ConcatenatePath(app_util::GetCurrentModuleDirectory(), | |
738 kOmahaShellFileName), | |
739 omaha_path_ + kOmahaShellFileName, | |
740 false)); | |
741 | |
742 EXPECT_SUCCEEDED(File::Copy( | |
743 ConcatenatePath(app_util::GetCurrentModuleDirectory(), | |
744 kOmahaDllName), | |
745 ConcatenatePath(future_version_path_, kOmahaDllName), | |
746 false)); | |
747 EXPECT_SUCCEEDED(File::Copy( | |
748 ConcatenatePath(app_util::GetCurrentModuleDirectory(), | |
749 _T("goopdateres_en.dll")), | |
750 ConcatenatePath(future_version_path_, _T("goopdateres_en.dll")), | |
751 false)); | |
752 | |
753 EXPECT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
754 kRegValueProductVersion, | |
755 kFutureVersionString)); | |
756 } | |
757 | |
758 CString existing_version_; // Saves the existing version from the registry. | |
759 const CString future_version_path_; | |
760 static const TCHAR* const kAppGuid_; | |
761 }; | |
762 | |
763 const TCHAR* const SetupFutureVersionInstalledUserTest::kAppGuid_ = | |
764 _T("{01D33078-BA95-4da6-A3FC-F31593FD4AA2}"); | |
765 | |
766 class SetupRegistryProtectedUserTest : public SetupUserTest { | |
767 protected: | |
768 SetupRegistryProtectedUserTest() | |
769 : SetupUserTest(), | |
770 hive_override_key_name_(kRegistryHiveOverrideRoot) { | |
771 } | |
772 | |
773 static void SetUpTestCase() { | |
774 this_version_ = GetVersionString(); | |
775 expected_is_overinstall_ = !OFFICIAL_BUILD; | |
776 #ifdef DEBUG | |
777 if (RegKey::HasValue(MACHINE_REG_UPDATE_DEV, kRegValueNameOverInstall)) { | |
778 DWORD value = 0; | |
779 EXPECT_SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
780 kRegValueNameOverInstall, | |
781 &value)); | |
782 expected_is_overinstall_ = value != 0; | |
783 } | |
784 #endif | |
785 } | |
786 | |
787 virtual void SetUp() { | |
788 SetupUserTest::SetUp(); | |
789 | |
790 RegKey::DeleteKey(hive_override_key_name_, true); | |
791 // Do not override HKLM because it contains the CSIDL_* definitions. | |
792 OverrideSpecifiedRegistryHives(hive_override_key_name_, false, true); | |
793 } | |
794 | |
795 virtual void TearDown() { | |
796 RestoreRegistryHives(); | |
797 ASSERT_SUCCEEDED(RegKey::DeleteKey(hive_override_key_name_, true)); | |
798 | |
799 SetupUserTest::TearDown(); | |
800 } | |
801 | |
802 const CString hive_override_key_name_; | |
803 | |
804 static CString this_version_; | |
805 static bool expected_is_overinstall_; | |
806 }; | |
807 | |
808 CString SetupRegistryProtectedUserTest::this_version_; | |
809 bool SetupRegistryProtectedUserTest::expected_is_overinstall_; | |
810 | |
811 class SetupRegistryProtectedMachineTest : public SetupMachineTest { | |
812 protected: | |
813 SetupRegistryProtectedMachineTest() | |
814 : SetupMachineTest(), | |
815 hive_override_key_name_(kRegistryHiveOverrideRoot) { | |
816 } | |
817 | |
818 virtual void SetUp() { | |
819 SetupMachineTest::SetUp(); | |
820 | |
821 RegKey::DeleteKey(hive_override_key_name_, true); | |
822 OverrideRegistryHives(hive_override_key_name_); | |
823 } | |
824 | |
825 virtual void TearDown() { | |
826 RestoreRegistryHives(); | |
827 ASSERT_SUCCEEDED(RegKey::DeleteKey(hive_override_key_name_, true)); | |
828 | |
829 SetupMachineTest::TearDown(); | |
830 } | |
831 | |
832 const CString hive_override_key_name_; | |
833 }; | |
834 | |
835 // TODO(omaha3): These tests are left over from Omaha2's InstallSelfSilently(), | |
836 // which like Omaha3's Install(), does not install the app. It did, however, | |
837 // start another process to complete installation. This would cause it to fail | |
838 // if the shell or main DLL were missing. | |
839 TEST_F(SetupFutureVersionInstalledUserTest, DISABLED_Install_NoRunKey) { | |
840 RegKey::DeleteKey(kRegistryHiveOverrideRoot, true); | |
841 OverrideSpecifiedRegistryHives(kRegistryHiveOverrideRoot, false, true); | |
842 | |
843 // Write the future version to the override registry. | |
844 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
845 kRegValueProductVersion, | |
846 kFutureVersionString)); | |
847 | |
848 CString dll_path = ConcatenatePath(future_version_path_, kOmahaDllName); | |
849 ASSERT_SUCCEEDED(File::Remove(dll_path)); | |
850 ASSERT_FALSE(File::Exists(dll_path)); | |
851 | |
852 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), | |
853 setup_->Install(false)); | |
854 EXPECT_EQ(0, setup_->extra_code1()); | |
855 | |
856 RestoreRegistryHives(); | |
857 ASSERT_SUCCEEDED(RegKey::DeleteKey(kRegistryHiveOverrideRoot, true)); | |
858 } | |
859 | |
860 // Command line must be valid to avoid displaying invalid command line error. | |
861 TEST_F(SetupFutureVersionInstalledUserTest, Install_ValidRunKey) { | |
862 RegKey::DeleteKey(kRegistryHiveOverrideRoot, true); | |
863 OverrideSpecifiedRegistryHives(kRegistryHiveOverrideRoot, false, true); | |
864 | |
865 // Write the future version to the override registry. | |
866 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
867 kRegValueProductVersion, | |
868 kFutureVersionString)); | |
869 | |
870 const TCHAR kRunKey[] = | |
871 _T("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"); | |
872 const CString shell_path = ConcatenatePath(omaha_path_, kOmahaShellFileName); | |
873 CString run_value; | |
874 run_value.Format(_T("\"%s\" /cr"), shell_path); | |
875 ASSERT_SUCCEEDED(RegKey::SetValue(kRunKey, _T("Google Update"), run_value)); | |
876 | |
877 CString dll_path = ConcatenatePath(future_version_path_, kOmahaDllName); | |
878 ASSERT_SUCCEEDED(File::Remove(dll_path)); | |
879 ASSERT_FALSE(File::Exists(dll_path)); | |
880 | |
881 EXPECT_SUCCEEDED(setup_->Install(false)); | |
882 EXPECT_EQ(0, setup_->extra_code1()); | |
883 | |
884 RestoreRegistryHives(); | |
885 ASSERT_SUCCEEDED(RegKey::DeleteKey(kRegistryHiveOverrideRoot, true)); | |
886 } | |
887 | |
888 TEST_F(SetupUserTest, Install_LockTimedOut) { | |
889 TestInstallWhileHoldingLock(); | |
890 } | |
891 | |
892 TEST_F(SetupMachineTest, Install_LockTimedOut) { | |
893 if (!vista_util::IsUserAdmin()) { | |
894 std::wcout << _T("\tTest did not run because the user is not an admin.") | |
895 << std::endl; | |
896 return; | |
897 } | |
898 | |
899 TestInstallWhileHoldingLock(); | |
900 } | |
901 | |
902 // | |
903 // ShouldInstall tests. | |
904 // | |
905 | |
906 TEST_F(SetupRegistryProtectedUserTest, ShouldInstall_NewerVersion) { | |
907 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
908 kRegValueProductVersion, | |
909 _T("1.0.3.4"))); | |
910 EXPECT_TRUE(ShouldInstall()); | |
911 } | |
912 | |
913 TEST_F(SetupRegistryProtectedUserTest, ShouldInstall_OlderVersion) { | |
914 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
915 kRegValueProductVersion, | |
916 _T("9.8.7.6"))); | |
917 EXPECT_FALSE(ShouldInstall()); | |
918 } | |
919 | |
920 TEST_F(SetupRegistryProtectedUserTest, | |
921 ShouldInstall_SameVersionFilesMissingSameLanguage) { | |
922 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, | |
923 kRegValueInstalledVersion, | |
924 this_version_)); | |
925 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
926 kRegValueProductVersion, | |
927 this_version_)); | |
928 ASSERT_SUCCEEDED( | |
929 DeleteDirectory(ConcatenatePath(omaha_path_, this_version_))); | |
930 CString file_path = ConcatenatePath( | |
931 ConcatenatePath(omaha_path_, this_version_), | |
932 kOmahaDllName); | |
933 ASSERT_FALSE(File::Exists(file_path)); | |
934 | |
935 EXPECT_TRUE(ShouldInstall()); | |
936 } | |
937 | |
938 TEST_F(SetupRegistryProtectedUserTest, | |
939 ShouldInstall_SameVersionFilesPresentSameLanguage) { | |
940 if (!ShouldRunLargeTest()) { | |
941 return; | |
942 } | |
943 | |
944 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, | |
945 kRegValueInstalledVersion, | |
946 this_version_)); | |
947 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
948 kRegValueProductVersion, | |
949 this_version_)); | |
950 | |
951 CopyGoopdateFiles(omaha_path_, this_version_); | |
952 | |
953 EXPECT_EQ(expected_is_overinstall_, ShouldInstall()); | |
954 | |
955 // Override OverInstall to test official behavior on non-official builds. | |
956 | |
957 DWORD existing_overinstall(0); | |
958 bool had_existing_overinstall = SUCCEEDED(RegKey::GetValue( | |
959 MACHINE_REG_UPDATE_DEV, | |
960 kRegValueNameOverInstall, | |
961 &existing_overinstall)); | |
962 | |
963 EXPECT_SUCCEEDED(RegKey::SetValue(MACHINE_REG_UPDATE_DEV, | |
964 kRegValueNameOverInstall, | |
965 static_cast<DWORD>(0))); | |
966 #ifdef DEBUG | |
967 EXPECT_FALSE(ShouldInstall()); | |
968 #else | |
969 EXPECT_EQ(expected_is_overinstall_, ShouldInstall()); | |
970 #endif | |
971 | |
972 // Restore "overinstall" | |
973 if (had_existing_overinstall) { | |
974 EXPECT_SUCCEEDED(RegKey::SetValue(MACHINE_REG_UPDATE_DEV, | |
975 kRegValueNameOverInstall, | |
976 existing_overinstall)); | |
977 } else { | |
978 EXPECT_SUCCEEDED(RegKey::DeleteValue(MACHINE_REG_UPDATE_DEV, | |
979 kRegValueNameOverInstall)); | |
980 } | |
981 } | |
982 | |
983 TEST_F(SetupRegistryProtectedUserTest, | |
984 ShouldInstall_SameVersionFilesPresentSameLanguageMissingInstalledVer) { | |
985 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
986 kRegValueProductVersion, | |
987 this_version_)); | |
988 | |
989 CopyGoopdateFiles(omaha_path_, this_version_); | |
990 | |
991 EXPECT_TRUE(ShouldInstall()); | |
992 } | |
993 | |
994 TEST_F(SetupRegistryProtectedUserTest, | |
995 ShouldInstall_SameVersionFilesPresentSameLanguageNewerInstalledVer) { | |
996 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, | |
997 kRegValueInstalledVersion, | |
998 kRegValueInstalledVersion)); | |
999 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
1000 kRegValueProductVersion, | |
1001 this_version_)); | |
1002 | |
1003 CopyGoopdateFiles(omaha_path_, this_version_); | |
1004 | |
1005 EXPECT_TRUE(ShouldInstall()); | |
1006 } | |
1007 | |
1008 TEST_F(SetupRegistryProtectedUserTest, | |
1009 ShouldInstall_SameVersionFilesPresentDifferentLanguage) { | |
1010 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, | |
1011 kRegValueInstalledVersion, | |
1012 this_version_)); | |
1013 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
1014 kRegValueProductVersion, | |
1015 this_version_)); | |
1016 | |
1017 CopyGoopdateFiles(omaha_path_, this_version_); | |
1018 | |
1019 EXPECT_EQ(expected_is_overinstall_, ShouldInstall()); | |
1020 } | |
1021 | |
1022 TEST_F(SetupRegistryProtectedUserTest, | |
1023 ShouldInstall_SameVersionFilesPresentNoLanguage) { | |
1024 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, | |
1025 kRegValueInstalledVersion, | |
1026 this_version_)); | |
1027 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
1028 kRegValueProductVersion, | |
1029 this_version_)); | |
1030 | |
1031 CopyGoopdateFiles(omaha_path_, this_version_); | |
1032 | |
1033 EXPECT_EQ(expected_is_overinstall_, ShouldInstall()); | |
1034 } | |
1035 | |
1036 TEST_F(SetupRegistryProtectedUserTest, | |
1037 ShouldInstall_SameVersionRequiredFileMissing) { | |
1038 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, | |
1039 kRegValueInstalledVersion, | |
1040 this_version_)); | |
1041 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
1042 kRegValueProductVersion, | |
1043 this_version_)); | |
1044 | |
1045 CopyGoopdateFiles(omaha_path_, this_version_); | |
1046 CString path = ConcatenatePath(ConcatenatePath(omaha_path_, this_version_), | |
1047 kOmahaDllName); | |
1048 ASSERT_SUCCEEDED(File::Remove(path)); | |
1049 ASSERT_FALSE(File::Exists(path)); | |
1050 | |
1051 EXPECT_TRUE(ShouldInstall()); | |
1052 } | |
1053 | |
1054 TEST_F(SetupRegistryProtectedUserTest, | |
1055 ShouldInstall_SameVersionOptionalFileMissing) { | |
1056 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, | |
1057 kRegValueInstalledVersion, | |
1058 this_version_)); | |
1059 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
1060 kRegValueProductVersion, | |
1061 this_version_)); | |
1062 | |
1063 CopyGoopdateFiles(omaha_path_, this_version_); | |
1064 CString path = ConcatenatePath(ConcatenatePath(omaha_path_, this_version_), | |
1065 UPDATE_PLUGIN_FILENAME); | |
1066 ASSERT_SUCCEEDED(File::Remove(path)); | |
1067 ASSERT_FALSE(File::Exists(path)); | |
1068 | |
1069 DWORD existing_overinstall(0); | |
1070 bool had_existing_overinstall = SUCCEEDED(RegKey::GetValue( | |
1071 MACHINE_REG_UPDATE_DEV, | |
1072 kRegValueNameOverInstall, | |
1073 &existing_overinstall)); | |
1074 if (had_existing_overinstall) { | |
1075 EXPECT_SUCCEEDED(RegKey::DeleteValue(MACHINE_REG_UPDATE_DEV, | |
1076 kRegValueNameOverInstall)); | |
1077 } | |
1078 | |
1079 EXPECT_TRUE(ShouldInstall()); | |
1080 | |
1081 // Restore "overinstall" | |
1082 if (had_existing_overinstall) { | |
1083 EXPECT_SUCCEEDED(RegKey::SetValue(MACHINE_REG_UPDATE_DEV, | |
1084 kRegValueNameOverInstall, | |
1085 existing_overinstall)); | |
1086 } | |
1087 } | |
1088 | |
1089 TEST_F(SetupRegistryProtectedUserTest, ShouldInstall_SameVersionShellMissing) { | |
1090 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, | |
1091 kRegValueInstalledVersion, | |
1092 this_version_)); | |
1093 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
1094 kRegValueProductVersion, | |
1095 this_version_)); | |
1096 | |
1097 CopyGoopdateFiles(omaha_path_, this_version_); | |
1098 CString shell_path = ConcatenatePath(omaha_path_, kOmahaShellFileName); | |
1099 ASSERT_TRUE(SUCCEEDED(File::DeleteAfterReboot(shell_path)) || | |
1100 !vista_util::IsUserAdmin()); | |
1101 ASSERT_FALSE(File::Exists(shell_path)); | |
1102 | |
1103 EXPECT_TRUE(ShouldInstall()); | |
1104 } | |
1105 | |
1106 TEST_F(SetupRegistryProtectedUserTest, ShouldInstall_NewerVersionShellMissing) { | |
1107 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_UPDATE, | |
1108 kRegValueInstalledVersion, | |
1109 this_version_)); | |
1110 ASSERT_SUCCEEDED(RegKey::SetValue(USER_REG_CLIENTS_GOOPDATE, | |
1111 kRegValueProductVersion, | |
1112 kFutureVersionString)); | |
1113 | |
1114 CopyGoopdateFiles(omaha_path_, kFutureVersionString); | |
1115 CString shell_path = ConcatenatePath(omaha_path_, kOmahaShellFileName); | |
1116 ASSERT_TRUE(SUCCEEDED(File::DeleteAfterReboot(shell_path)) || | |
1117 !vista_util::IsUserAdmin()); | |
1118 ASSERT_FALSE(File::Exists(shell_path)); | |
1119 | |
1120 EXPECT_FALSE(ShouldInstall()); | |
1121 | |
1122 EXPECT_SUCCEEDED( | |
1123 DeleteDirectory(ConcatenatePath(omaha_path_, kFutureVersionString))); | |
1124 } | |
1125 | |
1126 // | |
1127 // ShouldDelayUninstall/SetDelayUninstall tests. | |
1128 // | |
1129 | |
1130 TEST_F(SetupRegistryProtectedUserTest, ShouldDelayUninstall) { | |
1131 TestShouldDelayUninstall(); | |
1132 } | |
1133 | |
1134 TEST_F(SetupRegistryProtectedUserTest, SetDelayUninstall) { | |
1135 TestSetDelayUninstall(); | |
1136 } | |
1137 | |
1138 TEST_F(SetupRegistryProtectedMachineTest, ShouldDelayUninstall) { | |
1139 TestShouldDelayUninstall(); | |
1140 } | |
1141 | |
1142 TEST_F(SetupRegistryProtectedMachineTest, SetDelayUninstall) { | |
1143 TestSetDelayUninstall(); | |
1144 } | |
1145 | |
1146 // | |
1147 // StopGoogleUpdateAndWait tests. | |
1148 // | |
1149 // These are "large" tests. | |
1150 // They kill currently running GoogleUpdate processes, including the core, owned | |
1151 // by the current user or SYSTEM. | |
1152 // A core may already be running, so if a core process is found, it is used for | |
1153 // the tests. Otherwise, they launch a core from a previous build. | |
1154 // Using a previous build ensures that the shutdown event hasn't changed. | |
1155 // There is no test directly that this version can shutdown itself, but that is | |
1156 // much less likely to break. | |
1157 // The Succeeds tests will fail if any processes that don't listen to the | |
1158 // shutdown event are running. | |
1159 // | |
1160 | |
1161 // TODO(omaha3): Make these tests pass. | |
1162 TEST_F(SetupUserTest, DISABLED_StopGoogleUpdateAndWait_Succeeds) { | |
1163 StopGoogleUpdateAndWaitSucceedsTest(); | |
1164 } | |
1165 | |
1166 TEST_F(SetupMachineTest, DISABLED_StopGoogleUpdateAndWait_Succeeds) { | |
1167 StopGoogleUpdateAndWaitSucceedsTest(); | |
1168 } | |
1169 | |
1170 // TODO(omaha): If start using Job Objects again, enable these tests. | |
1171 /* | |
1172 TEST_F(SetupUserTest, StopGoogleUpdateAndWait_SucceedsUsingOnlyJobObjects) { | |
1173 StopGoogleUpdateAndWaitWithProcessSearchDisabledSucceedsTest(); | |
1174 } | |
1175 | |
1176 TEST_F(SetupMachineTest, StopGoogleUpdateAndWait_SucceedsUsingOnlyJobObjects) { | |
1177 StopGoogleUpdateAndWaitWithProcessSearchDisabledSucceedsTest(); | |
1178 } | |
1179 */ | |
1180 | |
1181 TEST_F(SetupUserTest, StopGoogleUpdateAndWait_ProcessesDoNotStop) { | |
1182 StopGoogleUpdateAndWaitProcessesDoNotStopTest(); | |
1183 } | |
1184 | |
1185 TEST_F(SetupMachineTest, StopGoogleUpdateAndWait_ProcessesDoNotStop) { | |
1186 StopGoogleUpdateAndWaitProcessesDoNotStopTest(); | |
1187 } | |
1188 | |
1189 TEST_F(SetupMachineTest, | |
1190 StopGoogleUpdateAndWait_MachineHandoffWorkerRunningAsUser) { | |
1191 LaunchProcessAndExpectStopGoogleUpdateAndWaitKillsProcess( | |
1192 false, | |
1193 _T("/handoff \"needsadmin=True\"")); | |
1194 } | |
1195 | |
1196 // Process mode is unknown because Omaha 3 does not recognize IG. | |
1197 TEST_F(SetupMachineTest, | |
1198 StopGoogleUpdateAndWait_MachineLegacyInstallGoogleUpdateWorkerRunningAsUs
er) { // NOLINT | |
1199 LaunchProcessAndExpectStopGoogleUpdateAndWaitKillsProcess( | |
1200 false, | |
1201 _T("/ig \"needsadmin=True\"")); | |
1202 } | |
1203 | |
1204 TEST_F(SetupMachineTest, | |
1205 StopGoogleUpdateAndWait_UserHandoffWorkerRunningAsSystem) { | |
1206 LaunchProcessAndExpectStopGoogleUpdateAndWaitKillsProcess( | |
1207 true, | |
1208 _T("/handoff \"needsadmin=False\"")); | |
1209 } | |
1210 | |
1211 // Process mode is unknown because Omaha 3 does not recognize IG. | |
1212 TEST_F(SetupMachineTest, | |
1213 StopGoogleUpdateAndWait_UserLegacyInstallGoogleUpdateWorkerRunningAsSyste
m) { // NOLINT | |
1214 LaunchProcessAndExpectStopGoogleUpdateAndWaitKillsProcess( | |
1215 true, | |
1216 _T("/ig \"needsadmin=False\"")); | |
1217 } | |
1218 | |
1219 TEST_F(SetupUserTest, TerminateCoreProcesses_NoneRunning) { | |
1220 KillRunningCoreProcesses(); | |
1221 | |
1222 EXPECT_SUCCEEDED(TerminateCoreProcesses()); | |
1223 } | |
1224 | |
1225 TEST_F(SetupUserTest, | |
1226 TerminateCoreProcesses_BothTypesRunningAndSimilarArgsProcess) { | |
1227 TestTerminateCoreProcessesWithBothTypesRunningAndOtherProcesses(); | |
1228 } | |
1229 | |
1230 TEST_F(SetupMachineTest, TerminateCoreProcesses_NoneRunning) { | |
1231 KillRunningCoreProcesses(); | |
1232 | |
1233 EXPECT_SUCCEEDED(TerminateCoreProcesses()); | |
1234 } | |
1235 | |
1236 TEST_F(SetupMachineTest, | |
1237 TerminateCoreProcesses_BothTypesRunningAndSimilarArgsProcess) { | |
1238 if (!vista_util::IsUserAdmin()) { | |
1239 std::wcout << _T("\tTest did not run because the user is not an admin.") | |
1240 << std::endl; | |
1241 return; | |
1242 } | |
1243 TestTerminateCoreProcessesWithBothTypesRunningAndOtherProcesses(); | |
1244 } | |
1245 | |
1246 } // namespace omaha | |
OLD | NEW |