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