| OLD | NEW |
| (Empty) |
| 1 // Copyright 2008-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 "omaha/base/app_util.h" | |
| 18 #include "omaha/base/const_object_names.h" | |
| 19 #include "omaha/base/error.h" | |
| 20 #include "omaha/base/path.h" | |
| 21 #include "omaha/base/scoped_any.h" | |
| 22 #include "omaha/base/thread.h" | |
| 23 #include "omaha/base/time.h" | |
| 24 #include "omaha/base/utils.h" | |
| 25 #include "omaha/base/vistautil.h" | |
| 26 #include "omaha/common/config_manager.h" | |
| 27 #include "omaha/common/const_goopdate.h" | |
| 28 #include "omaha/common/goopdate_utils.h" | |
| 29 #include "omaha/common/scheduled_task_utils.h" | |
| 30 #include "omaha/core/core.h" | |
| 31 #include "omaha/setup/setup_service.h" | |
| 32 #include "omaha/testing/unit_test.h" | |
| 33 | |
| 34 namespace omaha { | |
| 35 | |
| 36 namespace { | |
| 37 | |
| 38 // Runs the core on a different thread. Since the core captures the thread id | |
| 39 // in its constructor, the core instance must be created on this thread, not | |
| 40 // on the main thread. | |
| 41 class CoreRunner : public Runnable { | |
| 42 public: | |
| 43 explicit CoreRunner(bool is_machine) : is_machine_(is_machine) {} | |
| 44 virtual ~CoreRunner() {} | |
| 45 | |
| 46 private: | |
| 47 virtual void Run() { | |
| 48 Core core; | |
| 49 core.Main(is_machine_, false); // Do not run the crash handler. | |
| 50 } | |
| 51 | |
| 52 bool is_machine_; | |
| 53 DISALLOW_EVIL_CONSTRUCTORS(CoreRunner); | |
| 54 }; | |
| 55 | |
| 56 } // namespace | |
| 57 | |
| 58 class CoreTest : public testing::Test { | |
| 59 public: | |
| 60 CoreTest() : is_machine_(false) {} | |
| 61 | |
| 62 virtual void SetUp() { | |
| 63 // The Core has it's own ATL module. ATL does not like having multiple ATL | |
| 64 // modules. This TestCase saves and restore the original ATL module to get | |
| 65 // around ATL's limitation. This is a hack. | |
| 66 original_atl_module_ = _pAtlModule; | |
| 67 _pAtlModule = NULL; | |
| 68 | |
| 69 ASSERT_HRESULT_SUCCEEDED(IsSystemProcess(&is_machine_)); | |
| 70 | |
| 71 ConfigManager::Instance()->SetLastCheckedTime(is_machine_, 10); | |
| 72 | |
| 73 NamedObjectAttributes attr; | |
| 74 GetNamedObjectAttributes(kShutdownEvent, is_machine_, &attr); | |
| 75 reset(shutdown_event_, ::CreateEvent(&attr.sa, true, false, attr.name)); | |
| 76 ASSERT_TRUE(shutdown_event_); | |
| 77 } | |
| 78 | |
| 79 virtual void TearDown() { | |
| 80 _pAtlModule = original_atl_module_; | |
| 81 } | |
| 82 | |
| 83 HRESULT SignalShutdownEvent() { | |
| 84 EXPECT_TRUE(valid(shutdown_event_)); | |
| 85 return ::SetEvent(get(shutdown_event_)) ? S_OK : HRESULTFromLastError(); | |
| 86 } | |
| 87 | |
| 88 HRESULT ResetShutdownEvent() { | |
| 89 EXPECT_TRUE(valid(shutdown_event_)); | |
| 90 return ::ResetEvent(get(shutdown_event_)) ? S_OK : HRESULTFromLastError(); | |
| 91 } | |
| 92 | |
| 93 protected: | |
| 94 bool is_machine_; | |
| 95 scoped_event shutdown_event_; | |
| 96 | |
| 97 CAtlModule* original_atl_module_; | |
| 98 }; | |
| 99 | |
| 100 // Tests the core shutdown mechanism. | |
| 101 TEST_F(CoreTest, Shutdown) { | |
| 102 // Signal existing core instances to shutdown, otherwise new instances | |
| 103 // can't start. | |
| 104 ASSERT_HRESULT_SUCCEEDED(SignalShutdownEvent()); | |
| 105 ::Sleep(0); | |
| 106 ASSERT_HRESULT_SUCCEEDED(ResetShutdownEvent()); | |
| 107 | |
| 108 // Start a thread to run the core, signal the core to exit, and wait a while | |
| 109 // for the thread to exit. Terminate the thread if it is still running. | |
| 110 Thread thread; | |
| 111 CoreRunner core_runner(is_machine_); | |
| 112 EXPECT_TRUE(thread.Start(&core_runner)); | |
| 113 | |
| 114 // Give the core a little time to run before signaling it to exit. | |
| 115 ::Sleep(100); | |
| 116 EXPECT_HRESULT_SUCCEEDED(SignalShutdownEvent()); | |
| 117 EXPECT_TRUE(thread.WaitTillExit(2000)); | |
| 118 if (thread.Running()) { | |
| 119 // If you see a crash here, it was likely caused by Application Verifier. | |
| 120 // TODO(omaha): Is there a better way to exit? Should we wait longer? | |
| 121 thread.Terminate(-1); | |
| 122 } | |
| 123 EXPECT_HRESULT_SUCCEEDED(ResetShutdownEvent()); | |
| 124 } | |
| 125 | |
| 126 class CoreUtilsTest : public testing::Test { | |
| 127 public: | |
| 128 CoreUtilsTest() : is_machine_(vista_util::IsUserAdmin()) {} | |
| 129 | |
| 130 virtual void SetUp() { | |
| 131 // The Core has it's own ATL module. ATL does not like having multiple ATL | |
| 132 // modules. This TestCase saves and restore the original ATL module to get | |
| 133 // around ATL's limitation. This is a hack. | |
| 134 original_atl_module_ = _pAtlModule; | |
| 135 _pAtlModule = NULL; | |
| 136 | |
| 137 // The Core must be created after the ATL module work around. | |
| 138 core_.reset(new Core); | |
| 139 core_->is_system_ = is_machine_; | |
| 140 } | |
| 141 | |
| 142 virtual void TearDown() { | |
| 143 _pAtlModule = original_atl_module_; | |
| 144 } | |
| 145 | |
| 146 bool AreScheduledTasksHealthy() { | |
| 147 return core_->AreScheduledTasksHealthy(); | |
| 148 } | |
| 149 | |
| 150 bool IsCheckingForUpdates() { | |
| 151 return core_->IsCheckingForUpdates(); | |
| 152 } | |
| 153 | |
| 154 static HRESULT DoInstallService(const TCHAR* service_cmd_line) { | |
| 155 return SetupUpdate3Service::DoInstallService(service_cmd_line); | |
| 156 } | |
| 157 | |
| 158 static HRESULT DeleteService() { | |
| 159 return SetupUpdate3Service::DeleteService(); | |
| 160 } | |
| 161 | |
| 162 scoped_ptr<Core> core_; | |
| 163 bool is_machine_; | |
| 164 | |
| 165 CAtlModule* original_atl_module_; | |
| 166 }; | |
| 167 | |
| 168 TEST_F(CoreUtilsTest, AreScheduledTasksHealthy) { | |
| 169 EXPECT_SUCCEEDED(scheduled_task_utils::UninstallGoopdateTasks(is_machine_)); | |
| 170 EXPECT_FALSE(AreScheduledTasksHealthy()); | |
| 171 | |
| 172 CString task_path = ConcatenatePath(app_util::GetCurrentModuleDirectory(), | |
| 173 _T("LongRunningSilent.exe")); | |
| 174 EXPECT_SUCCEEDED(scheduled_task_utils::InstallGoopdateTasks(task_path, | |
| 175 is_machine_)); | |
| 176 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 177 const int k12HourPeriodSec = 12 * 60 * 60; | |
| 178 const DWORD first_install_12 = now - k12HourPeriodSec; | |
| 179 EXPECT_SUCCEEDED(RegKey::SetValue( | |
| 180 ConfigManager::Instance()->registry_client_state_goopdate(is_machine_), | |
| 181 kRegValueInstallTimeSec, | |
| 182 first_install_12)); | |
| 183 EXPECT_TRUE(AreScheduledTasksHealthy()); | |
| 184 | |
| 185 EXPECT_SUCCEEDED(scheduled_task_utils::UninstallGoopdateTasks(is_machine_)); | |
| 186 } | |
| 187 | |
| 188 TEST_F(CoreUtilsTest, IsCheckingForUpdates) { | |
| 189 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 190 const int k12HourPeriodSec = 12 * 60 * 60; | |
| 191 const DWORD first_install_12_hours_back = now - k12HourPeriodSec; | |
| 192 EXPECT_SUCCEEDED(RegKey::SetValue( | |
| 193 ConfigManager::Instance()->registry_client_state_goopdate(is_machine_), | |
| 194 kRegValueInstallTimeSec, | |
| 195 first_install_12_hours_back)); | |
| 196 | |
| 197 ConfigManager::Instance()->SetLastCheckedTime(is_machine_, 10); | |
| 198 EXPECT_TRUE(IsCheckingForUpdates()); | |
| 199 | |
| 200 const int k48HourPeriodSec = 48 * 60 * 60; | |
| 201 const DWORD first_install_48_hours_back = now - k48HourPeriodSec; | |
| 202 EXPECT_SUCCEEDED(RegKey::SetValue( | |
| 203 ConfigManager::Instance()->registry_client_state_goopdate(is_machine_), | |
| 204 kRegValueInstallTimeSec, | |
| 205 first_install_48_hours_back)); | |
| 206 EXPECT_FALSE(IsCheckingForUpdates()); | |
| 207 | |
| 208 EXPECT_SUCCEEDED(goopdate_utils::UpdateLastChecked(is_machine_)); | |
| 209 EXPECT_TRUE(IsCheckingForUpdates()); | |
| 210 | |
| 211 const int k15DaysPeriodSec = 15 * 24 * 60 * 60; | |
| 212 const DWORD last_checked_15_days_back = now - k15DaysPeriodSec; | |
| 213 ConfigManager::Instance()->SetLastCheckedTime(is_machine_, | |
| 214 last_checked_15_days_back); | |
| 215 EXPECT_FALSE(IsCheckingForUpdates()); | |
| 216 } | |
| 217 | |
| 218 } // namespace omaha | |
| OLD | NEW |