OLD | NEW |
| (Empty) |
1 // Copyright 2007-2009 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 <windows.h> | |
17 #include <atlstr.h> | |
18 #include <mstask.h> | |
19 #include "omaha/base/app_util.h" | |
20 #include "omaha/base/error.h" | |
21 #include "omaha/base/file.h" | |
22 #include "omaha/base/path.h" | |
23 #include "omaha/base/scoped_ptr_cotask.h" | |
24 #include "omaha/base/user_info.h" | |
25 #include "omaha/base/vistautil.h" | |
26 #include "omaha/common/const_goopdate.h" | |
27 #include "omaha/common/scheduled_task_utils.h" | |
28 #include "omaha/common/scheduled_task_utils_internal.h" | |
29 #include "omaha/testing/unit_test.h" | |
30 | |
31 namespace omaha { | |
32 | |
33 namespace { | |
34 | |
35 const int kMaxWaitForProcessMs = 120000; | |
36 | |
37 const TCHAR kLongRunningProcessesRelativePath[] = | |
38 _T("unittest_support\\does_not_shutdown\\GoogleUpdate.exe"); | |
39 | |
40 CString GetLongRunningProcessPath() { | |
41 const CString module_dir(app_util::GetCurrentModuleDirectory()); | |
42 return ConcatenatePath(module_dir, kLongRunningProcessesRelativePath); | |
43 } | |
44 | |
45 } // namespace | |
46 | |
47 namespace scheduled_task_utils { | |
48 | |
49 using internal::GetCurrentTaskNameCore; | |
50 using internal::GetCurrentTaskNameUA; | |
51 using internal::GetScheduledTaskStatus; | |
52 using internal::HasScheduledTaskEverRun; | |
53 using internal::StartScheduledTask; | |
54 using internal::StopScheduledTask; | |
55 using internal::WaitForTaskStatus; | |
56 | |
57 namespace v2 = internal::v2; | |
58 | |
59 using vista_util::IsUserAdmin; | |
60 | |
61 namespace internal { | |
62 | |
63 void StopScheduledTaskAndVerifyReadyState(const CString& task_name) { | |
64 // For some reason, StopScheduleTask may not successfully stop the task | |
65 // even it returns S_OK. So try to stop multiple times. | |
66 for (int i = 0; i < 3; ++i) { | |
67 EXPECT_SUCCEEDED(StopScheduledTask(task_name)); | |
68 | |
69 if (SCHED_S_TASK_READY == WaitForTaskStatus(task_name, | |
70 SCHED_S_TASK_READY, | |
71 kMsPerSec)) { | |
72 break; | |
73 } | |
74 } | |
75 EXPECT_EQ(SCHED_S_TASK_READY, GetScheduledTaskStatus(task_name)); | |
76 } | |
77 | |
78 TEST(ScheduledTaskUtilsTest, ScheduledTasks) { | |
79 const TCHAR kSchedTestTaskName[] = _T("TestScheduledTask"); | |
80 const TCHAR kScheduledTaskExecutable[] = _T("netstat.exe"); | |
81 const TCHAR kScheduledTaskParameters[] = _T("20"); | |
82 const TCHAR kSchedTestTaskComment[] = _T("Google Test Task"); | |
83 | |
84 const CString task_path = ConcatenatePath(app_util::GetSystemDir(), | |
85 kScheduledTaskExecutable); | |
86 // Install/uninstall. | |
87 EXPECT_SUCCEEDED(InstallScheduledTask(kSchedTestTaskName, | |
88 task_path, | |
89 _T(""), | |
90 kSchedTestTaskComment, | |
91 IsUserAdmin(), | |
92 IsUserAdmin(), | |
93 true, | |
94 true)); | |
95 EXPECT_SUCCEEDED(UninstallScheduledTask(kSchedTestTaskName)); | |
96 | |
97 // Calling InstallScheduledTask twice should succeed. | |
98 for (int i = 0; i < 2; ++i) { | |
99 EXPECT_SUCCEEDED(InstallScheduledTask(kSchedTestTaskName, | |
100 task_path, | |
101 _T(""), | |
102 kSchedTestTaskComment, | |
103 IsUserAdmin(), | |
104 IsUserAdmin(), | |
105 true, | |
106 true)); | |
107 } | |
108 | |
109 // "Upgrade" to a new version, which now has parameters. | |
110 EXPECT_SUCCEEDED(InstallScheduledTask(kSchedTestTaskName, | |
111 task_path, | |
112 kScheduledTaskParameters, | |
113 kSchedTestTaskComment, | |
114 IsUserAdmin(), | |
115 IsUserAdmin(), | |
116 true, | |
117 true)); | |
118 | |
119 EXPECT_FALSE(HasScheduledTaskEverRun(kSchedTestTaskName)); | |
120 | |
121 // Start and stop. | |
122 EXPECT_EQ(SCHED_S_TASK_HAS_NOT_RUN, | |
123 GetScheduledTaskStatus(kSchedTestTaskName)); | |
124 EXPECT_SUCCEEDED(StartScheduledTask(kSchedTestTaskName)); | |
125 EXPECT_EQ(SCHED_S_TASK_RUNNING, | |
126 WaitForTaskStatus(kSchedTestTaskName, | |
127 SCHED_S_TASK_RUNNING, | |
128 kMaxWaitForProcessMs)); | |
129 | |
130 EXPECT_TRUE(HasScheduledTaskEverRun(kSchedTestTaskName)); | |
131 | |
132 StopScheduledTaskAndVerifyReadyState(kSchedTestTaskName); | |
133 | |
134 // Finally, uninstall. | |
135 EXPECT_SUCCEEDED(UninstallScheduledTask(kSchedTestTaskName)); | |
136 } | |
137 | |
138 TEST(ScheduledTaskUtilsTest, ScheduledTasksV2) { | |
139 if (!v2::IsTaskScheduler2APIAvailable()) { | |
140 std::wcout << _T("\tTest did not run because this OS does not support the ") | |
141 _T("Task Scheduler 2.0 API.") << std::endl; | |
142 return; | |
143 } | |
144 | |
145 const TCHAR kSchedTestTaskName[] = _T("TestScheduledTaskV2"); | |
146 const TCHAR kScheduledTaskExecutable[] = _T("netstat.exe"); | |
147 const TCHAR kScheduledTaskParameters[] = _T("20"); | |
148 const TCHAR kSchedTestTaskComment[] = _T("Google Test Task V2"); | |
149 | |
150 const CString task_path = ConcatenatePath(app_util::GetSystemDir(), | |
151 kScheduledTaskExecutable); | |
152 EXPECT_SUCCEEDED(InstallScheduledTask(kSchedTestTaskName, | |
153 task_path, | |
154 _T(""), | |
155 kSchedTestTaskComment, | |
156 IsUserAdmin(), | |
157 IsUserAdmin(), | |
158 true, | |
159 true)); | |
160 | |
161 // Start and stop. | |
162 EXPECT_FALSE(v2::IsScheduledTaskRunning(kSchedTestTaskName)); | |
163 EXPECT_SUCCEEDED(v2::StartScheduledTask(kSchedTestTaskName)); | |
164 EXPECT_TRUE(v2::IsScheduledTaskRunning(kSchedTestTaskName)); | |
165 | |
166 EXPECT_SUCCEEDED(v2::StopScheduledTask(kSchedTestTaskName)); | |
167 EXPECT_FALSE(v2::IsScheduledTaskRunning(kSchedTestTaskName)); | |
168 | |
169 // Finally, uninstall. | |
170 EXPECT_SUCCEEDED(UninstallScheduledTask(kSchedTestTaskName)); | |
171 } | |
172 | |
173 } // namespace internal | |
174 | |
175 | |
176 TEST(ScheduledTaskUtilsTest, GoopdateTasks) { | |
177 const CString task_name = GetCurrentTaskNameCore(IsUserAdmin()); | |
178 const CString task_path = GetLongRunningProcessPath(); | |
179 | |
180 // Install/uninstall. | |
181 EXPECT_SUCCEEDED(InstallGoopdateTasks(task_path, IsUserAdmin())); | |
182 EXPECT_SUCCEEDED(UninstallGoopdateTasks(IsUserAdmin())); | |
183 | |
184 EXPECT_SUCCEEDED(InstallGoopdateTasks(task_path, IsUserAdmin())); | |
185 EXPECT_FALSE(HasScheduledTaskEverRun(task_name)); | |
186 | |
187 // Start and stop. | |
188 EXPECT_EQ(SCHED_S_TASK_HAS_NOT_RUN, GetScheduledTaskStatus(task_name)); | |
189 EXPECT_SUCCEEDED(StartGoopdateTaskCore(IsUserAdmin())); | |
190 | |
191 EXPECT_EQ(SCHED_S_TASK_RUNNING, | |
192 WaitForTaskStatus(task_name, | |
193 SCHED_S_TASK_RUNNING, | |
194 kMaxWaitForProcessMs)); | |
195 | |
196 EXPECT_TRUE(HasScheduledTaskEverRun(task_name)); | |
197 | |
198 internal::StopScheduledTaskAndVerifyReadyState(task_name); | |
199 | |
200 // Finally, uninstall. | |
201 EXPECT_SUCCEEDED(UninstallGoopdateTasks(IsUserAdmin())); | |
202 } | |
203 | |
204 TEST(ScheduledTaskUtilsTest, GoopdateTaskInUseOverinstall) { | |
205 const CString task_path = GetLongRunningProcessPath(); | |
206 EXPECT_SUCCEEDED(InstallGoopdateTasks(task_path, IsUserAdmin())); | |
207 | |
208 CString original_task_name(GetCurrentTaskNameCore(IsUserAdmin())); | |
209 | |
210 // Open the file underlying the current task in exclusive mode, so that | |
211 // InstallGoopdateTasks() is forced to create a new task. | |
212 CComPtr<ITaskScheduler> scheduler; | |
213 EXPECT_SUCCEEDED(scheduler.CoCreateInstance(CLSID_CTaskScheduler, | |
214 NULL, | |
215 CLSCTX_INPROC_SERVER)); | |
216 CComPtr<ITask> task; | |
217 EXPECT_SUCCEEDED(scheduler->Activate(original_task_name, | |
218 __uuidof(ITask), | |
219 reinterpret_cast<IUnknown**>(&task))); | |
220 CComQIPtr<IPersistFile> persist(task); | |
221 EXPECT_TRUE(persist); | |
222 scoped_ptr_cotask<OLECHAR> job_file; | |
223 EXPECT_SUCCEEDED(persist->GetCurFile(address(job_file))); | |
224 persist.Release(); | |
225 | |
226 File file; | |
227 EXPECT_SUCCEEDED(file.OpenShareMode(job_file.get(), false, false, 0)); | |
228 | |
229 EXPECT_SUCCEEDED(InstallGoopdateTasks(task_path, IsUserAdmin())); | |
230 CString new_task_name(GetCurrentTaskNameCore(IsUserAdmin())); | |
231 EXPECT_STRNE(original_task_name, new_task_name); | |
232 | |
233 // Cleanup. | |
234 file.Close(); | |
235 EXPECT_SUCCEEDED(UninstallGoopdateTasks(IsUserAdmin())); | |
236 } | |
237 | |
238 TEST(ScheduledTaskUtilsTest, GetExitCodeGoopdateTaskUA) { | |
239 const CString task_name = GetCurrentTaskNameUA(IsUserAdmin()); | |
240 const CString task_path = ConcatenatePath( | |
241 app_util::GetCurrentModuleDirectory(), | |
242 _T("unittest_support\\SaveArguments.exe")); | |
243 | |
244 EXPECT_SUCCEEDED(InstallGoopdateTasks(task_path, IsUserAdmin())); | |
245 EXPECT_EQ(SCHED_S_TASK_HAS_NOT_RUN, | |
246 GetExitCodeGoopdateTaskUA(IsUserAdmin())); | |
247 EXPECT_FALSE(HasScheduledTaskEverRun(task_name)); | |
248 | |
249 // Start the task and wait for it to run and become ready again. The task | |
250 // runs a program that returns right away. Sometimes the task does not run | |
251 // for unknown reason. Attempting to run the task multiple times does not | |
252 // work. This remains a flaky test. | |
253 EXPECT_SUCCEEDED(StartScheduledTask(task_name)); | |
254 EXPECT_EQ(SCHED_S_TASK_READY, | |
255 WaitForTaskStatus(task_name, | |
256 SCHED_S_TASK_READY, | |
257 kMaxWaitForProcessMs)); | |
258 EXPECT_TRUE(HasScheduledTaskEverRun(task_name)); | |
259 EXPECT_EQ(S_OK, GetExitCodeGoopdateTaskUA(IsUserAdmin())); | |
260 | |
261 EXPECT_SUCCEEDED(File::Remove( | |
262 ConcatenatePath(app_util::GetCurrentModuleDirectory(), | |
263 _T("unittest_support\\saved_arguments.txt")))); | |
264 EXPECT_SUCCEEDED(UninstallGoopdateTasks(IsUserAdmin())); | |
265 } | |
266 | |
267 TEST(ScheduledTaskUtilsTest, GetDefaultGoopdateTaskName_Core_Machine) { | |
268 CString expected_task_name(kScheduledTaskNameMachinePrefix); | |
269 expected_task_name += kScheduledTaskNameCoreSuffix; | |
270 EXPECT_STREQ(expected_task_name, | |
271 GetDefaultGoopdateTaskName(true, COMMANDLINE_MODE_CORE)); | |
272 } | |
273 | |
274 TEST(ScheduledTaskUtilsTest, GetDefaultGoopdateTaskName_Core_User) { | |
275 CString expected_task_name_user = kScheduledTaskNameUserPrefix; | |
276 CString user_sid; | |
277 EXPECT_SUCCEEDED(user_info::GetProcessUser(NULL, NULL, &user_sid)); | |
278 expected_task_name_user += user_sid; | |
279 expected_task_name_user += kScheduledTaskNameCoreSuffix; | |
280 EXPECT_STREQ(expected_task_name_user, | |
281 GetDefaultGoopdateTaskName(false, COMMANDLINE_MODE_CORE)); | |
282 } | |
283 | |
284 TEST(ScheduledTaskUtilsTest, GetDefaultGoopdateTaskName_UA_Machine) { | |
285 CString expected_task_name(kScheduledTaskNameMachinePrefix); | |
286 expected_task_name += kScheduledTaskNameUASuffix; | |
287 EXPECT_STREQ(expected_task_name, | |
288 GetDefaultGoopdateTaskName(true, COMMANDLINE_MODE_UA)); | |
289 } | |
290 | |
291 TEST(ScheduledTaskUtilsTest, GetDefaultGoopdateTaskName_UA_User) { | |
292 CString expected_task_name_user = kScheduledTaskNameUserPrefix; | |
293 CString user_sid; | |
294 EXPECT_SUCCEEDED(user_info::GetProcessUser(NULL, NULL, &user_sid)); | |
295 expected_task_name_user += user_sid; | |
296 expected_task_name_user += kScheduledTaskNameUASuffix; | |
297 EXPECT_STREQ(expected_task_name_user, | |
298 GetDefaultGoopdateTaskName(false, COMMANDLINE_MODE_UA)); | |
299 } | |
300 | |
301 } // namespace scheduled_task_utils | |
302 | |
303 } // namespace omaha | |
304 | |
OLD | NEW |