| 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 |