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::Return; 42 using testing::SetArgPointee; 43 using testing::_; 44 45 namespace { 46 47 // Generates a fixed timestamp for use in faking the current time. 48 Time FixedTime() { 49 Time::Exploded now_exp; 50 now_exp.year = 2014; 51 now_exp.month = 3; 52 now_exp.day_of_week = 2; 53 now_exp.day_of_month = 18; 54 now_exp.hour = 8; 55 now_exp.minute = 5; 56 now_exp.second = 33; 57 now_exp.millisecond = 675; 58 return Time::FromLocalExploded(now_exp); 59 } 60 61 // Rounds down a timestamp to the nearest second. This is useful when faking 62 // times that are converted to time_t (no sub-second resolution). 63 Time RoundedToSecond(Time time) { 64 Time::Exploded exp; 65 time.LocalExplode(&exp); 66 exp.millisecond = 0; 67 return Time::FromLocalExploded(exp); 68 } 69 70 } // namespace 71 72 namespace chromeos_update_manager { 73 74 class UmRealUpdaterProviderTest : public ::testing::Test { 75 protected: 76 void SetUp() override { 77 fake_clock_ = fake_sys_state_.fake_clock(); 78 fake_sys_state_.set_prefs(&fake_prefs_); 79 provider_.reset(new RealUpdaterProvider(&fake_sys_state_)); 80 ASSERT_NE(nullptr, provider_.get()); 81 // Check that provider initializes correctly. 82 ASSERT_TRUE(provider_->Init()); 83 } 84 85 // Sets up mock expectations for testing the update completed time reporting. 86 // |valid| determines whether the returned time is valid. Returns the expected 87 // update completed time value. 88 Time SetupUpdateCompletedTime(bool valid) { 89 const TimeDelta kDurationSinceUpdate = TimeDelta::FromMinutes(7); 90 const Time kUpdateBootTime = Time() + kDurationSinceUpdate * 2; 91 const Time kCurrBootTime = (valid ? 92 kUpdateBootTime + kDurationSinceUpdate : 93 kUpdateBootTime - kDurationSinceUpdate); 94 const Time kCurrWallclockTime = FixedTime(); 95 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 96 GetBootTimeAtUpdate(_)) 97 .WillOnce(DoAll(SetArgPointee<0>(kUpdateBootTime), Return(true))); 98 fake_clock_->SetBootTime(kCurrBootTime); 99 fake_clock_->SetWallclockTime(kCurrWallclockTime); 100 return kCurrWallclockTime - kDurationSinceUpdate; 101 } 102 103 FakeSystemState fake_sys_state_; 104 FakeClock* fake_clock_; // Short for fake_sys_state_.fake_clock() 105 FakePrefs fake_prefs_; 106 unique_ptr<RealUpdaterProvider> provider_; 107 }; 108 109 TEST_F(UmRealUpdaterProviderTest, UpdaterStartedTimeIsWallclockTime) { 110 fake_clock_->SetWallclockTime(Time::FromDoubleT(123.456)); 111 fake_clock_->SetMonotonicTime(Time::FromDoubleT(456.123)); 112 // Run SetUp again to re-setup the provider under test to use these values. 113 SetUp(); 114 UmTestUtils::ExpectVariableHasValue(Time::FromDoubleT(123.456), 115 provider_->var_updater_started_time()); 116 } 117 118 TEST_F(UmRealUpdaterProviderTest, GetLastCheckedTimeOkay) { 119 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 120 GetStatus(_, _, _, _, _)) 121 .WillOnce(DoAll(SetArgPointee<0>(FixedTime().ToTimeT()), Return(true))); 122 UmTestUtils::ExpectVariableHasValue(RoundedToSecond(FixedTime()), 123 provider_->var_last_checked_time()); 124 } 125 126 TEST_F(UmRealUpdaterProviderTest, GetLastCheckedTimeFailNoValue) { 127 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 128 GetStatus(_, _, _, _, _)) 129 .WillOnce(Return(false)); 130 UmTestUtils::ExpectVariableNotSet(provider_->var_last_checked_time()); 131 } 132 133 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMin) { 134 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 135 GetStatus(_, _, _, _, _)) 136 .WillOnce(DoAll(SetArgPointee<1>(0.0), Return(true))); 137 UmTestUtils::ExpectVariableHasValue(0.0, provider_->var_progress()); 138 } 139 140 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMid) { 141 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 142 GetStatus(_, _, _, _, _)) 143 .WillOnce(DoAll(SetArgPointee<1>(0.3), Return(true))); 144 UmTestUtils::ExpectVariableHasValue(0.3, provider_->var_progress()); 145 } 146 147 TEST_F(UmRealUpdaterProviderTest, GetProgressOkayMax) { 148 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 149 GetStatus(_, _, _, _, _)) 150 .WillOnce(DoAll(SetArgPointee<1>(1.0), Return(true))); 151 UmTestUtils::ExpectVariableHasValue(1.0, provider_->var_progress()); 152 } 153 154 TEST_F(UmRealUpdaterProviderTest, GetProgressFailNoValue) { 155 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 156 GetStatus(_, _, _, _, _)) 157 .WillOnce(Return(false)); 158 UmTestUtils::ExpectVariableNotSet(provider_->var_progress()); 159 } 160 161 TEST_F(UmRealUpdaterProviderTest, GetProgressFailTooSmall) { 162 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 163 GetStatus(_, _, _, _, _)) 164 .WillOnce(DoAll(SetArgPointee<1>(-2.0), Return(true))); 165 UmTestUtils::ExpectVariableNotSet(provider_->var_progress()); 166 } 167 168 TEST_F(UmRealUpdaterProviderTest, GetProgressFailTooBig) { 169 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 170 GetStatus(_, _, _, _, _)) 171 .WillOnce(DoAll(SetArgPointee<1>(2.0), Return(true))); 172 UmTestUtils::ExpectVariableNotSet(provider_->var_progress()); 173 } 174 175 TEST_F(UmRealUpdaterProviderTest, GetStageOkayIdle) { 176 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 177 GetStatus(_, _, _, _, _)) 178 .WillOnce(DoAll(SetArgPointee<2>(update_engine::kUpdateStatusIdle), 179 Return(true))); 180 UmTestUtils::ExpectVariableHasValue(Stage::kIdle, provider_->var_stage()); 181 } 182 183 TEST_F(UmRealUpdaterProviderTest, GetStageOkayCheckingForUpdate) { 184 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 185 GetStatus(_, _, _, _, _)) 186 .WillOnce(DoAll( 187 SetArgPointee<2>(update_engine::kUpdateStatusCheckingForUpdate), 188 Return(true))); 189 UmTestUtils::ExpectVariableHasValue(Stage::kCheckingForUpdate, 190 provider_->var_stage()); 191 } 192 193 TEST_F(UmRealUpdaterProviderTest, GetStageOkayUpdateAvailable) { 194 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 195 GetStatus(_, _, _, _, _)) 196 .WillOnce(DoAll( 197 SetArgPointee<2>(update_engine::kUpdateStatusUpdateAvailable), 198 Return(true))); 199 UmTestUtils::ExpectVariableHasValue(Stage::kUpdateAvailable, 200 provider_->var_stage()); 201 } 202 203 TEST_F(UmRealUpdaterProviderTest, GetStageOkayDownloading) { 204 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 205 GetStatus(_, _, _, _, _)) 206 .WillOnce(DoAll(SetArgPointee<2>(update_engine::kUpdateStatusDownloading), 207 Return(true))); 208 UmTestUtils::ExpectVariableHasValue(Stage::kDownloading, 209 provider_->var_stage()); 210 } 211 212 TEST_F(UmRealUpdaterProviderTest, GetStageOkayVerifying) { 213 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 214 GetStatus(_, _, _, _, _)) 215 .WillOnce(DoAll(SetArgPointee<2>(update_engine::kUpdateStatusVerifying), 216 Return(true))); 217 UmTestUtils::ExpectVariableHasValue(Stage::kVerifying, 218 provider_->var_stage()); 219 } 220 221 TEST_F(UmRealUpdaterProviderTest, GetStageOkayFinalizing) { 222 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 223 GetStatus(_, _, _, _, _)) 224 .WillOnce(DoAll(SetArgPointee<2>(update_engine::kUpdateStatusFinalizing), 225 Return(true))); 226 UmTestUtils::ExpectVariableHasValue(Stage::kFinalizing, 227 provider_->var_stage()); 228 } 229 230 TEST_F(UmRealUpdaterProviderTest, GetStageOkayUpdatedNeedReboot) { 231 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 232 GetStatus(_, _, _, _, _)) 233 .WillOnce(DoAll( 234 SetArgPointee<2>(update_engine::kUpdateStatusUpdatedNeedReboot), 235 Return(true))); 236 UmTestUtils::ExpectVariableHasValue(Stage::kUpdatedNeedReboot, 237 provider_->var_stage()); 238 } 239 240 TEST_F(UmRealUpdaterProviderTest, GetStageOkayReportingErrorEvent) { 241 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 242 GetStatus(_, _, _, _, _)) 243 .WillOnce(DoAll( 244 SetArgPointee<2>(update_engine::kUpdateStatusReportingErrorEvent), 245 Return(true))); 246 UmTestUtils::ExpectVariableHasValue(Stage::kReportingErrorEvent, 247 provider_->var_stage()); 248 } 249 250 TEST_F(UmRealUpdaterProviderTest, GetStageOkayAttemptingRollback) { 251 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 252 GetStatus(_, _, _, _, _)) 253 .WillOnce(DoAll( 254 SetArgPointee<2>(update_engine::kUpdateStatusAttemptingRollback), 255 Return(true))); 256 UmTestUtils::ExpectVariableHasValue(Stage::kAttemptingRollback, 257 provider_->var_stage()); 258 } 259 260 TEST_F(UmRealUpdaterProviderTest, GetStageFailNoValue) { 261 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 262 GetStatus(_, _, _, _, _)) 263 .WillOnce(Return(false)); 264 UmTestUtils::ExpectVariableNotSet(provider_->var_stage()); 265 } 266 267 TEST_F(UmRealUpdaterProviderTest, GetStageFailUnknown) { 268 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 269 GetStatus(_, _, _, _, _)) 270 .WillOnce(DoAll(SetArgPointee<2>("FooUpdateEngineState"), 271 Return(true))); 272 UmTestUtils::ExpectVariableNotSet(provider_->var_stage()); 273 } 274 275 TEST_F(UmRealUpdaterProviderTest, GetStageFailEmpty) { 276 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 277 GetStatus(_, _, _, _, _)) 278 .WillOnce(DoAll(SetArgPointee<2>(""), Return(true))); 279 UmTestUtils::ExpectVariableNotSet(provider_->var_stage()); 280 } 281 282 TEST_F(UmRealUpdaterProviderTest, GetNewVersionOkay) { 283 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 284 GetStatus(_, _, _, _, _)) 285 .WillOnce(DoAll(SetArgPointee<3>("1.2.0"), Return(true))); 286 UmTestUtils::ExpectVariableHasValue(string("1.2.0"), 287 provider_->var_new_version()); 288 } 289 290 TEST_F(UmRealUpdaterProviderTest, GetNewVersionFailNoValue) { 291 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 292 GetStatus(_, _, _, _, _)) 293 .WillOnce(Return(false)); 294 UmTestUtils::ExpectVariableNotSet(provider_->var_new_version()); 295 } 296 297 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayZero) { 298 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 299 GetStatus(_, _, _, _, _)) 300 .WillOnce(DoAll(SetArgPointee<4>(static_cast<int64_t>(0)), Return(true))); 301 UmTestUtils::ExpectVariableHasValue(static_cast<int64_t>(0), 302 provider_->var_payload_size()); 303 } 304 305 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayArbitrary) { 306 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 307 GetStatus(_, _, _, _, _)) 308 .WillOnce(DoAll(SetArgPointee<4>(static_cast<int64_t>(567890)), 309 Return(true))); 310 UmTestUtils::ExpectVariableHasValue(static_cast<int64_t>(567890), 311 provider_->var_payload_size()); 312 } 313 314 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeOkayTwoGigabytes) { 315 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 316 GetStatus(_, _, _, _, _)) 317 .WillOnce(DoAll(SetArgPointee<4>(static_cast<int64_t>(1) << 31), 318 Return(true))); 319 UmTestUtils::ExpectVariableHasValue(static_cast<int64_t>(1) << 31, 320 provider_->var_payload_size()); 321 } 322 323 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeFailNoValue) { 324 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 325 GetStatus(_, _, _, _, _)) 326 .WillOnce(Return(false)); 327 UmTestUtils::ExpectVariableNotSet(provider_->var_payload_size()); 328 } 329 330 TEST_F(UmRealUpdaterProviderTest, GetPayloadSizeFailNegative) { 331 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 332 GetStatus(_, _, _, _, _)) 333 .WillOnce(DoAll(SetArgPointee<4>(static_cast<int64_t>(-1024)), 334 Return(true))); 335 UmTestUtils::ExpectVariableNotSet(provider_->var_payload_size()); 336 } 337 338 TEST_F(UmRealUpdaterProviderTest, GetCurrChannelOkay) { 339 const string kChannelName("foo-channel"); 340 OmahaRequestParams request_params(&fake_sys_state_); 341 request_params.Init("", "", false); 342 request_params.set_current_channel(kChannelName); 343 fake_sys_state_.set_request_params(&request_params); 344 UmTestUtils::ExpectVariableHasValue(kChannelName, 345 provider_->var_curr_channel()); 346 } 347 348 TEST_F(UmRealUpdaterProviderTest, GetCurrChannelFailEmpty) { 349 OmahaRequestParams request_params(&fake_sys_state_); 350 request_params.Init("", "", false); 351 request_params.set_current_channel(""); 352 fake_sys_state_.set_request_params(&request_params); 353 UmTestUtils::ExpectVariableNotSet(provider_->var_curr_channel()); 354 } 355 356 TEST_F(UmRealUpdaterProviderTest, GetNewChannelOkay) { 357 const string kChannelName("foo-channel"); 358 OmahaRequestParams request_params(&fake_sys_state_); 359 request_params.Init("", "", false); 360 request_params.set_target_channel(kChannelName); 361 fake_sys_state_.set_request_params(&request_params); 362 UmTestUtils::ExpectVariableHasValue(kChannelName, 363 provider_->var_new_channel()); 364 } 365 366 TEST_F(UmRealUpdaterProviderTest, GetNewChannelFailEmpty) { 367 OmahaRequestParams request_params(&fake_sys_state_); 368 request_params.Init("", "", false); 369 request_params.set_target_channel(""); 370 fake_sys_state_.set_request_params(&request_params); 371 UmTestUtils::ExpectVariableNotSet(provider_->var_new_channel()); 372 } 373 374 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledOkayPrefDoesntExist) { 375 UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled()); 376 } 377 378 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledOkayPrefReadsFalse) { 379 fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, false); 380 UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled()); 381 } 382 383 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledReadWhenInitialized) { 384 fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, true); 385 SetUp(); 386 UmTestUtils::ExpectVariableHasValue(true, provider_->var_p2p_enabled()); 387 } 388 389 TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledUpdated) { 390 fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, false); 391 UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled()); 392 fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, true); 393 UmTestUtils::ExpectVariableHasValue(true, provider_->var_p2p_enabled()); 394 fake_prefs_.Delete(chromeos_update_engine::kPrefsP2PEnabled); 395 UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled()); 396 } 397 398 TEST_F(UmRealUpdaterProviderTest, GetCellularEnabledOkayPrefDoesntExist) { 399 UmTestUtils::ExpectVariableHasValue(false, provider_->var_cellular_enabled()); 400 } 401 402 TEST_F(UmRealUpdaterProviderTest, GetCellularEnabledOkayPrefReadsTrue) { 403 fake_prefs_.SetBoolean( 404 chromeos_update_engine::kPrefsUpdateOverCellularPermission, true); 405 UmTestUtils::ExpectVariableHasValue(true, provider_->var_cellular_enabled()); 406 } 407 408 TEST_F(UmRealUpdaterProviderTest, GetUpdateCompletedTimeOkay) { 409 Time expected = SetupUpdateCompletedTime(true); 410 UmTestUtils::ExpectVariableHasValue(expected, 411 provider_->var_update_completed_time()); 412 } 413 414 TEST_F(UmRealUpdaterProviderTest, GetUpdateCompletedTimeFailNoValue) { 415 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), GetBootTimeAtUpdate(_)) 416 .WillOnce(Return(false)); 417 UmTestUtils::ExpectVariableNotSet(provider_->var_update_completed_time()); 418 } 419 420 TEST_F(UmRealUpdaterProviderTest, GetUpdateCompletedTimeFailInvalidValue) { 421 SetupUpdateCompletedTime(false); 422 UmTestUtils::ExpectVariableNotSet(provider_->var_update_completed_time()); 423 } 424 425 TEST_F(UmRealUpdaterProviderTest, GetConsecutiveFailedUpdateChecks) { 426 const unsigned int kNumFailedChecks = 3; 427 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 428 consecutive_failed_update_checks()) 429 .WillRepeatedly(Return(kNumFailedChecks)); 430 UmTestUtils::ExpectVariableHasValue( 431 kNumFailedChecks, provider_->var_consecutive_failed_update_checks()); 432 } 433 434 TEST_F(UmRealUpdaterProviderTest, GetServerDictatedPollInterval) { 435 const unsigned int kPollInterval = 2 * 60 * 60; // Two hours. 436 EXPECT_CALL(*fake_sys_state_.mock_update_attempter(), 437 server_dictated_poll_interval()) 438 .WillRepeatedly(Return(kPollInterval)); 439 UmTestUtils::ExpectVariableHasValue( 440 kPollInterval, provider_->var_server_dictated_poll_interval()); 441 } 442 443 } // namespace chromeos_update_manager 444