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 |