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 33using base::Time; 34using base::TimeDelta; 35using chromeos_update_engine::FakeClock; 36using chromeos_update_engine::FakePrefs; 37using chromeos_update_engine::FakeSystemState; 38using chromeos_update_engine::OmahaRequestParams; 39using std::string; 40using std::unique_ptr; 41using testing::Return; 42using testing::SetArgPointee; 43using testing::_; 44 45namespace { 46 47// Generates a fixed timestamp for use in faking the current time. 48Time 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). 63Time 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 72namespace chromeos_update_manager { 73 74class 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 109TEST_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 118TEST_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 126TEST_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 133TEST_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 140TEST_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 147TEST_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 154TEST_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 161TEST_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 168TEST_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 175TEST_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 183TEST_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 193TEST_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 203TEST_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 212TEST_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 221TEST_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 230TEST_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 240TEST_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 250TEST_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 260TEST_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 267TEST_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 275TEST_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 282TEST_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 290TEST_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 297TEST_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 305TEST_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 314TEST_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 323TEST_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 330TEST_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 338TEST_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 348TEST_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 356TEST_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 366TEST_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 374TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledOkayPrefDoesntExist) { 375 UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled()); 376} 377 378TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledOkayPrefReadsFalse) { 379 fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, false); 380 UmTestUtils::ExpectVariableHasValue(false, provider_->var_p2p_enabled()); 381} 382 383TEST_F(UmRealUpdaterProviderTest, GetP2PEnabledReadWhenInitialized) { 384 fake_prefs_.SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, true); 385 SetUp(); 386 UmTestUtils::ExpectVariableHasValue(true, provider_->var_p2p_enabled()); 387} 388 389TEST_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 398TEST_F(UmRealUpdaterProviderTest, GetCellularEnabledOkayPrefDoesntExist) { 399 UmTestUtils::ExpectVariableHasValue(false, provider_->var_cellular_enabled()); 400} 401 402TEST_F(UmRealUpdaterProviderTest, GetCellularEnabledOkayPrefReadsTrue) { 403 fake_prefs_.SetBoolean( 404 chromeos_update_engine::kPrefsUpdateOverCellularPermission, true); 405 UmTestUtils::ExpectVariableHasValue(true, provider_->var_cellular_enabled()); 406} 407 408TEST_F(UmRealUpdaterProviderTest, GetUpdateCompletedTimeOkay) { 409 Time expected = SetupUpdateCompletedTime(true); 410 UmTestUtils::ExpectVariableHasValue(expected, 411 provider_->var_update_completed_time()); 412} 413 414TEST_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 420TEST_F(UmRealUpdaterProviderTest, GetUpdateCompletedTimeFailInvalidValue) { 421 SetupUpdateCompletedTime(false); 422 UmTestUtils::ExpectVariableNotSet(provider_->var_update_completed_time()); 423} 424 425TEST_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 434TEST_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