1 //
2 // Copyright (C) 2014 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "update_engine/update_manager/real_updater_provider.h"
18 
19 #include <memory>
20 #include <string>
21 
22 #include <base/time/time.h>
23 #include <gtest/gtest.h>
24 #include <update_engine/dbus-constants.h>
25 
26 #include "update_engine/common/fake_clock.h"
27 #include "update_engine/common/fake_prefs.h"
28 #include "update_engine/fake_system_state.h"
29 #include "update_engine/mock_update_attempter.h"
30 #include "update_engine/omaha_request_params.h"
31 #include "update_engine/update_manager/umtest_utils.h"
32 
33 using base::Time;
34 using base::TimeDelta;
35 using chromeos_update_engine::FakeClock;
36 using chromeos_update_engine::FakePrefs;
37 using chromeos_update_engine::FakeSystemState;
38 using chromeos_update_engine::OmahaRequestParams;
39 using std::string;
40 using std::unique_ptr;
41 using testing::_;
42 using testing::DoAll;
43 using testing::Return;
44 using testing::SetArgPointee;
45 using update_engine::UpdateAttemptFlags;
46 
47 namespace {
48 
49 // Generates a fixed timestamp for use in faking the current time.
50 Time FixedTime() {
51   Time::Exploded now_exp;
52   now_exp.year = 2014;
53   now_exp.month = 3;
54   now_exp.day_of_week = 2;
55   now_exp.day_of_month = 18;
56   now_exp.hour = 8;
57   now_exp.minute = 5;
58   now_exp.second = 33;
59   now_exp.millisecond = 675;
60   Time time;
61   ignore_result(Time::FromLocalExploded(now_exp, &time));
62   return time;
63 }
64 
65 // Rounds down a timestamp to the nearest second. This is useful when faking
66 // times that are converted to time_t (no sub-second resolution).
67 Time RoundedToSecond(Time time) {
68   Time::Exploded exp;
69   time.LocalExplode(&exp);
70   exp.millisecond = 0;
71   Time rounded_time;
72   ignore_result(Time::FromLocalExploded(exp, &rounded_time));
73   return rounded_time;
74 }
75 
76 ACTION_P(ActionSetUpdateEngineStatusLastCheckedTime, time) {
77   arg0->last_checked_time = time;
78 };
79 
80 ACTION_P(ActionSetUpdateEngineStatusProgress, progress) {
81   arg0->progress = progress;
82 };
83 
84 ACTION_P(ActionSetUpdateEngineStatusStatus, status) {
85   arg0->status = status;
86 }
87 
88 ACTION_P(ActionSetUpdateEngineStatusNewVersion, new_version) {
89   arg0->new_version = new_version;
90 }
91 
92 ACTION_P(ActionSetUpdateEngineStatusNewSizeBytes, new_size_bytes) {
93   arg0->new_size_bytes = new_size_bytes;
94 }
95 
96 }  // namespace
97 
98 namespace chromeos_update_manager {
99 
100 class UmRealUpdaterProviderTest : public ::testing::Test {
101  protected:
102   void SetUp() override {
103     fake_clock_ = fake_sys_state_.fake_clock();
104     fake_sys_state_.set_prefs(&fake_prefs_);
105     provider_.reset(new RealUpdaterProvider(&fake_sys_state_));
106     ASSERT_NE(nullptr, provider_.get());
107     // Check that provider initializes correctly.
108     ASSERT_TRUE(provider_->Init());
109   }
110 
111   // Sets up mock expectations for testing the update completed time reporting.
112   // |valid| determines whether the returned time is valid. Returns the expected
113   // update completed time value.
114   Time SetupUpdateCompletedTime(bool valid) {
115     const TimeDelta kDurationSinceUpdate = TimeDelta::FromMinutes(7);
116     const Time kUpdateBootTime = Time() + kDurationSinceUpdate * 2;
117     const Time kCurrBootTime = (valid ? kUpdateBootTime + kDurationSinceUpdate
118                                       : kUpdateBootTime - kDurationSinceUpdate);
119     const Time kCurrWallclockTime = FixedTime();
120     EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
121                 GetBootTimeAtUpdate(_))
122         .WillOnce(DoAll(SetArgPointee<0>(kUpdateBootTime), Return(true)));
123     fake_clock_->SetBootTime(kCurrBootTime);
124     fake_clock_->SetWallclockTime(kCurrWallclockTime);
125     return kCurrWallclockTime - kDurationSinceUpdate;
126   }
127 
128   FakeSystemState fake_sys_state_;
129   FakeClock* fake_clock_;  // Short for fake_sys_state_.fake_clock()
130   FakePrefs fake_prefs_;
131   unique_ptr<RealUpdaterProvider> provider_;
132 };
133 
134 TEST_F(UmRealUpdaterProviderTest, UpdaterStartedTimeIsWallclockTime) {
135   fake_clock_->SetWallclockTime(Time::FromDoubleT(123.456));
136   fake_clock_->SetMonotonicTime(Time::FromDoubleT(456.123));
137   // Run SetUp again to re-setup the provider under test to use these values.
138   SetUp();
139   UmTestUtils::ExpectVariableHasValue(Time::FromDoubleT(123.456),
140                                       provider_->var_updater_started_time());
141 }
142 
143 TEST_F(UmRealUpdaterProviderTest, GetLastCheckedTimeOkay) {
144   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
145       .WillOnce(DoAll(
146           ActionSetUpdateEngineStatusLastCheckedTime(FixedTime().ToTimeT()),
147           Return(true)));
148   UmTestUtils::ExpectVariableHasValue(RoundedToSecond(FixedTime()),
149                                       provider_->var_last_checked_time());
150 }
151 
152 TEST_F(UmRealUpdaterProviderTest, GetLastCheckedTimeFailNoValue) {
153   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
154       .WillOnce(Return(false));
155   UmTestUtils::ExpectVariableNotSet(provider_->var_last_checked_time());
156 }
157 
158 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMin) {
159   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
160       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(0.0), Return(true)));
161   UmTestUtils::ExpectVariableHasValue(0.0, provider_->var_progress());
162 }
163 
164 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMid) {
165   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
166       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(0.3), Return(true)));
167   UmTestUtils::ExpectVariableHasValue(0.3, provider_->var_progress());
168 }
169 
170 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMax) {
171   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
172       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(1.0), Return(true)));
173   UmTestUtils::ExpectVariableHasValue(1.0, provider_->var_progress());
174 }
175 
176 TEST_F(UmRealUpdaterProviderTest, GetProgressFailNoValue) {
177   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
178       .WillOnce(Return(false));
179   UmTestUtils::ExpectVariableNotSet(provider_->var_progress());
180 }
181 
182 TEST_F(UmRealUpdaterProviderTest, GetProgressFailTooSmall) {
183   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
184       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(-2.0), Return(true)));
185   UmTestUtils::ExpectVariableNotSet(provider_->var_progress());
186 }
187 
188 TEST_F(UmRealUpdaterProviderTest, GetProgressFailTooBig) {
189   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
190       .WillOnce(DoAll(ActionSetUpdateEngineStatusProgress(2.0), Return(true)));
191   UmTestUtils::ExpectVariableNotSet(provider_->var_progress());
192 }
193 
194 TEST_F(UmRealUpdaterProviderTest, GetStageOkayIdle) {
195   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
196       .WillOnce(DoAll(
197           ActionSetUpdateEngineStatusStatus(update_engine::UpdateStatus::IDLE),
198           Return(true)));
199   UmTestUtils::ExpectVariableHasValue(Stage::kIdle, provider_->var_stage());
200 }
201 
202 TEST_F(UmRealUpdaterProviderTest, GetStageOkayCheckingForUpdate) {
203   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
204       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
205                           update_engine::UpdateStatus::CHECKING_FOR_UPDATE),
206                       Return(true)));
207   UmTestUtils::ExpectVariableHasValue(Stage::kCheckingForUpdate,
208                                       provider_->var_stage());
209 }
210 
211 TEST_F(UmRealUpdaterProviderTest, GetStageOkayUpdateAvailable) {
212   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
213       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
214                           update_engine::UpdateStatus::UPDATE_AVAILABLE),
215                       Return(true)));
216   UmTestUtils::ExpectVariableHasValue(Stage::kUpdateAvailable,
217                                       provider_->var_stage());
218 }
219 
220 TEST_F(UmRealUpdaterProviderTest, GetStageOkayDownloading) {
221   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
222       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
223                           update_engine::UpdateStatus::DOWNLOADING),
224                       Return(true)));
225   UmTestUtils::ExpectVariableHasValue(Stage::kDownloading,
226                                       provider_->var_stage());
227 }
228 
229 TEST_F(UmRealUpdaterProviderTest, GetStageOkayVerifying) {
230   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
231       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
232                           update_engine::UpdateStatus::VERIFYING),
233                       Return(true)));
234   UmTestUtils::ExpectVariableHasValue(Stage::kVerifying,
235                                       provider_->var_stage());
236 }
237 
238 TEST_F(UmRealUpdaterProviderTest, GetStageOkayFinalizing) {
239   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
240       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
241                           update_engine::UpdateStatus::FINALIZING),
242                       Return(true)));
243   UmTestUtils::ExpectVariableHasValue(Stage::kFinalizing,
244                                       provider_->var_stage());
245 }
246 
247 TEST_F(UmRealUpdaterProviderTest, GetStageOkayUpdatedNeedReboot) {
248   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
249       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
250                           update_engine::UpdateStatus::UPDATED_NEED_REBOOT),
251                       Return(true)));
252   UmTestUtils::ExpectVariableHasValue(Stage::kUpdatedNeedReboot,
253                                       provider_->var_stage());
254 }
255 
256 TEST_F(UmRealUpdaterProviderTest, GetStageOkayReportingErrorEvent) {
257   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
258       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
259                           update_engine::UpdateStatus::REPORTING_ERROR_EVENT),
260                       Return(true)));
261   UmTestUtils::ExpectVariableHasValue(Stage::kReportingErrorEvent,
262                                       provider_->var_stage());
263 }
264 
265 TEST_F(UmRealUpdaterProviderTest, GetStageOkayAttemptingRollback) {
266   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
267       .WillOnce(DoAll(ActionSetUpdateEngineStatusStatus(
268                           update_engine::UpdateStatus::ATTEMPTING_ROLLBACK),
269                       Return(true)));
270   UmTestUtils::ExpectVariableHasValue(Stage::kAttemptingRollback,
271                                       provider_->var_stage());
272 }
273 
274 TEST_F(UmRealUpdaterProviderTest, GetStageFailNoValue) {
275   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
276       .WillOnce(Return(false));
277   UmTestUtils::ExpectVariableNotSet(provider_->var_stage());
278 }
279 
280 TEST_F(UmRealUpdaterProviderTest, GetNewVersionOkay) {
281   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
282       .WillOnce(
283           DoAll(ActionSetUpdateEngineStatusNewVersion("1.2.0"), Return(true)));
284   UmTestUtils::ExpectVariableHasValue(string("1.2.0"),
285                                       provider_->var_new_version());
286 }
287 
288 TEST_F(UmRealUpdaterProviderTest, GetNewVersionFailNoValue) {
289   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
290       .WillOnce(Return(false));
291   UmTestUtils::ExpectVariableNotSet(provider_->var_new_version());
292 }
293 
294 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayZero) {
295   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
296       .WillOnce(DoAll(
297           ActionSetUpdateEngineStatusNewSizeBytes(static_cast<uint64_t>(0)),
298           Return(true)));
299   UmTestUtils::ExpectVariableHasValue(static_cast<uint64_t>(0),
300                                       provider_->var_payload_size());
301 }
302 
303 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayArbitrary) {
304   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
305       .WillOnce(DoAll(ActionSetUpdateEngineStatusNewSizeBytes(
306                           static_cast<uint64_t>(567890)),
307                       Return(true)));
308   UmTestUtils::ExpectVariableHasValue(static_cast<uint64_t>(567890),
309                                       provider_->var_payload_size());
310 }
311 
312 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayTwoGigabytes) {
313   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
314       .WillOnce(DoAll(ActionSetUpdateEngineStatusNewSizeBytes(
315                           static_cast<uint64_t>(1) << 31),
316                       Return(true)));
317   UmTestUtils::ExpectVariableHasValue(static_cast<uint64_t>(1) << 31,
318                                       provider_->var_payload_size());
319 }
320 
321 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeFailNoValue) {
322   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetStatus(_))
323       .WillOnce(Return(false));
324   UmTestUtils::ExpectVariableNotSet(provider_->var_payload_size());
325 }
326 
327 TEST_F(UmRealUpdaterProviderTest, GetCurrChannelOkay) {
328   const string kChannelName("foo-channel");
329   OmahaRequestParams request_params(&fake_sys_state_);
330   request_params.Init("", "", false);
331   request_params.set_current_channel(kChannelName);
332   fake_sys_state_.set_request_params(&request_params);
333   UmTestUtils::ExpectVariableHasValue(kChannelName,
334                                       provider_->var_curr_channel());
335 }
336 
337 TEST_F(UmRealUpdaterProviderTest, GetCurrChannelFailEmpty) {
338   OmahaRequestParams request_params(&fake_sys_state_);
339   request_params.Init("", "", false);
340   request_params.set_current_channel("");
341   fake_sys_state_.set_request_params(&request_params);
342   UmTestUtils::ExpectVariableNotSet(provider_->var_curr_channel());
343 }
344 
345 TEST_F(UmRealUpdaterProviderTest, GetNewChannelOkay) {
346   const string kChannelName("foo-channel");
347   OmahaRequestParams request_params(&fake_sys_state_);
348   request_params.Init("", "", false);
349   request_params.set_target_channel(kChannelName);
350   fake_sys_state_.set_request_params(&request_params);
351   UmTestUtils::ExpectVariableHasValue(kChannelName,
352                                       provider_->var_new_channel());
353 }
354 
355 TEST_F(UmRealUpdaterProviderTest, GetNewChannelFailEmpty) {
356   OmahaRequestParams request_params(&fake_sys_state_);
357   request_params.Init("", "", false);
358   request_params.set_target_channel("");
359   fake_sys_state_.set_request_params(&request_params);
360   UmTestUtils::ExpectVariableNotSet(provider_->var_new_channel());
361 }
362 
363 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledOkayPrefDoesntExist) {
364   UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled());
365 }
366 
367 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledOkayPrefReadsFalse) {
368   fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, false);
369   UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled());
370 }
371 
372 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledReadWhenInitialized) {
373   fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, true);
374   SetUp();
375   UmTestUtils::ExpectVariableHasValue(true, provider_->var_p2p_enabled());
376 }
377 
378 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledUpdated) {
379   fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, false);
380   UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled());
381   fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, true);
382   UmTestUtils::ExpectVariableHasValue(true, provider_->var_p2p_enabled());
383   fake_prefs_.Delete(chromeos_update_engine::kPrefsP2PEnabled);
384   UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled());
385 }
386 
387 TEST_F(UmRealUpdaterProviderTest, GetCellularEnabledOkayPrefDoesntExist) {
388   UmTestUtils::ExpectVariableHasValue(false, provider_->var_cellular_enabled());
389 }
390 
391 TEST_F(UmRealUpdaterProviderTest, GetCellularEnabledOkayPrefReadsTrue) {
392   fake_prefs_.SetBoolean(
393       chromeos_update_engine::kPrefsUpdateOverCellularPermission, true);
394   UmTestUtils::ExpectVariableHasValue(true, provider_->var_cellular_enabled());
395 }
396 
397 TEST_F(UmRealUpdaterProviderTest, GetUpdateCompletedTimeOkay) {
398   Time expected = SetupUpdateCompletedTime(true);
399   UmTestUtils::ExpectVariableHasValue(expected,
400                                       provider_->var_update_completed_time());
401 }
402 
403 TEST_F(UmRealUpdaterProviderTest, GetUpdateCompletedTimeFailNoValue) {
404   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetBootTimeAtUpdate(_))
405       .WillOnce(Return(false));
406   UmTestUtils::ExpectVariableNotSet(provider_->var_update_completed_time());
407 }
408 
409 TEST_F(UmRealUpdaterProviderTest, GetUpdateCompletedTimeFailInvalidValue) {
410   SetupUpdateCompletedTime(false);
411   UmTestUtils::ExpectVariableNotSet(provider_->var_update_completed_time());
412 }
413 
414 TEST_F(UmRealUpdaterProviderTest, GetConsecutiveFailedUpdateChecks) {
415   const unsigned int kNumFailedChecks = 3;
416   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
417               consecutive_failed_update_checks())
418       .WillRepeatedly(Return(kNumFailedChecks));
419   UmTestUtils::ExpectVariableHasValue(
420       kNumFailedChecks, provider_->var_consecutive_failed_update_checks());
421 }
422 
423 TEST_F(UmRealUpdaterProviderTest, GetServerDictatedPollInterval) {
424   const unsigned int kPollInterval = 2 * 60 * 60;  // Two hours.
425   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
426               server_dictated_poll_interval())
427       .WillRepeatedly(Return(kPollInterval));
428   UmTestUtils::ExpectVariableHasValue(
429       kPollInterval, provider_->var_server_dictated_poll_interval());
430 }
431 
432 TEST_F(UmRealUpdaterProviderTest, GetUpdateRestrictions) {
433   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
434               GetCurrentUpdateAttemptFlags())
435       .WillRepeatedly(Return(UpdateAttemptFlags::kFlagRestrictDownload |
436                              UpdateAttemptFlags::kFlagNonInteractive));
437   UmTestUtils::ExpectVariableHasValue(UpdateRestrictions::kRestrictDownloading,
438                                       provider_->var_update_restrictions());
439 }
440 
441 TEST_F(UmRealUpdaterProviderTest, GetUpdateRestrictionsNone) {
442   EXPECT_CALL(*fake_sys_state_.mock_update_attempter(),
443               GetCurrentUpdateAttemptFlags())
444       .WillRepeatedly(Return(UpdateAttemptFlags::kNone));
445   UmTestUtils::ExpectVariableHasValue(UpdateRestrictions::kNone,
446                                       provider_->var_update_restrictions());
447 }
448 }  // namespace chromeos_update_manager
449