1 // 2 // Copyright (C) 2012 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/payload_state.h" 18 19 #include <base/files/file_path.h> 20 #include <base/files/file_util.h> 21 #include <base/strings/stringprintf.h> 22 #include <gmock/gmock.h> 23 #include <gtest/gtest.h> 24 25 #include "update_engine/common/constants.h" 26 #include "update_engine/common/fake_clock.h" 27 #include "update_engine/common/fake_hardware.h" 28 #include "update_engine/common/fake_prefs.h" 29 #include "update_engine/common/mock_prefs.h" 30 #include "update_engine/common/prefs.h" 31 #include "update_engine/common/test_utils.h" 32 #include "update_engine/common/utils.h" 33 #include "update_engine/fake_system_state.h" 34 #include "update_engine/metrics_reporter_interface.h" 35 #include "update_engine/omaha_request_action.h" 36 37 using base::Time; 38 using base::TimeDelta; 39 using std::string; 40 using testing::AnyNumber; 41 using testing::AtLeast; 42 using testing::Mock; 43 using testing::NiceMock; 44 using testing::Return; 45 using testing::SetArgPointee; 46 using testing::_; 47 48 namespace chromeos_update_engine { 49 50 const char* kCurrentBytesDownloadedFromHttps = 51 "current-bytes-downloaded-from-HttpsServer"; 52 const char* kTotalBytesDownloadedFromHttps = 53 "total-bytes-downloaded-from-HttpsServer"; 54 const char* kCurrentBytesDownloadedFromHttp = 55 "current-bytes-downloaded-from-HttpServer"; 56 const char* kTotalBytesDownloadedFromHttp = 57 "total-bytes-downloaded-from-HttpServer"; 58 const char* kCurrentBytesDownloadedFromHttpPeer = 59 "current-bytes-downloaded-from-HttpPeer"; 60 const char* kTotalBytesDownloadedFromHttpPeer = 61 "total-bytes-downloaded-from-HttpPeer"; 62 63 static void SetupPayloadStateWith2Urls(string hash, 64 bool http_enabled, 65 bool is_delta_payload, 66 PayloadState* payload_state, 67 OmahaResponse* response) { 68 response->packages.clear(); 69 response->packages.push_back({.payload_urls = {"http://test", "https://test"}, 70 .size = 523456789, 71 .metadata_size = 558123, 72 .metadata_signature = "metasign", 73 .hash = hash, 74 .is_delta = is_delta_payload}); 75 response->max_failure_count_per_url = 3; 76 payload_state->SetResponse(*response); 77 string stored_response_sign = payload_state->GetResponseSignature(); 78 79 string expected_url_https_only = 80 " NumURLs = 1\n" 81 " Candidate Url0 = https://test\n"; 82 83 string expected_urls_both = 84 " NumURLs = 2\n" 85 " Candidate Url0 = http://test\n" 86 " Candidate Url1 = https://test\n"; 87 88 string expected_response_sign = base::StringPrintf( 89 "Payload 0:\n" 90 " Size = 523456789\n" 91 " Sha256 Hash = %s\n" 92 " Metadata Size = 558123\n" 93 " Metadata Signature = metasign\n" 94 " Is Delta = %d\n" 95 "%s" 96 "Max Failure Count Per Url = %d\n" 97 "Disable Payload Backoff = %d\n", 98 hash.c_str(), 99 response->packages[0].is_delta, 100 (http_enabled ? expected_urls_both : expected_url_https_only).c_str(), 101 response->max_failure_count_per_url, 102 response->disable_payload_backoff); 103 EXPECT_EQ(expected_response_sign, stored_response_sign); 104 } 105 106 class PayloadStateTest : public ::testing::Test { }; 107 108 TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) { 109 OmahaResponse response; 110 FakeSystemState fake_system_state; 111 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs(); 112 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber()); 113 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)) 114 .Times(AtLeast(1)); 115 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0)) 116 .Times(AtLeast(1)); 117 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1)); 118 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1)); 119 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)) 120 .Times(AtLeast(1)); 121 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _)) 122 .Times(AtLeast(1)); 123 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _)) 124 .Times(AtLeast(1)); 125 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0)) 126 .Times(AtLeast(1)); 127 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0)) 128 .Times(AtLeast(1)); 129 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0)) 130 .Times(AtLeast(1)); 131 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1)); 132 PayloadState payload_state; 133 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 134 payload_state.SetResponse(response); 135 string stored_response_sign = payload_state.GetResponseSignature(); 136 string expected_response_sign = 137 "Max Failure Count Per Url = 0\n" 138 "Disable Payload Backoff = 0\n"; 139 EXPECT_EQ(expected_response_sign, stored_response_sign); 140 EXPECT_EQ("", payload_state.GetCurrentUrl()); 141 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 142 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount()); 143 EXPECT_EQ(1, payload_state.GetNumResponsesSeen()); 144 } 145 146 TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) { 147 OmahaResponse response; 148 response.packages.push_back({.payload_urls = {"https://single.url.test"}, 149 .size = 123456789, 150 .metadata_size = 58123, 151 .metadata_signature = "msign", 152 .hash = "hash"}); 153 FakeSystemState fake_system_state; 154 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs(); 155 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber()); 156 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)) 157 .Times(AtLeast(1)); 158 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0)) 159 .Times(AtLeast(1)); 160 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)) 161 .Times(AtLeast(1)); 162 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)) 163 .Times(AtLeast(1)); 164 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)) 165 .Times(AtLeast(1)); 166 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _)) 167 .Times(AtLeast(1)); 168 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _)) 169 .Times(AtLeast(1)); 170 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0)) 171 .Times(AtLeast(1)); 172 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0)) 173 .Times(AtLeast(1)); 174 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0)) 175 .Times(AtLeast(1)); 176 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)) 177 .Times(AtLeast(1)); 178 PayloadState payload_state; 179 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 180 payload_state.SetResponse(response); 181 string stored_response_sign = payload_state.GetResponseSignature(); 182 string expected_response_sign = 183 "Payload 0:\n" 184 " Size = 123456789\n" 185 " Sha256 Hash = hash\n" 186 " Metadata Size = 58123\n" 187 " Metadata Signature = msign\n" 188 " Is Delta = 0\n" 189 " NumURLs = 1\n" 190 " Candidate Url0 = https://single.url.test\n" 191 "Max Failure Count Per Url = 0\n" 192 "Disable Payload Backoff = 0\n"; 193 EXPECT_EQ(expected_response_sign, stored_response_sign); 194 EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl()); 195 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 196 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount()); 197 EXPECT_EQ(1, payload_state.GetNumResponsesSeen()); 198 } 199 200 TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) { 201 OmahaResponse response; 202 response.packages.push_back({.payload_urls = {"http://multiple.url.test", 203 "https://multiple.url.test"}, 204 .size = 523456789, 205 .metadata_size = 558123, 206 .metadata_signature = "metasign", 207 .hash = "rhash"}); 208 FakeSystemState fake_system_state; 209 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs(); 210 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber()); 211 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)) 212 .Times(AtLeast(1)); 213 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0)) 214 .Times(AtLeast(1)); 215 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)) 216 .Times(AtLeast(1)); 217 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)) 218 .Times(AtLeast(1)); 219 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)) 220 .Times(AtLeast(1)); 221 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0)) 222 .Times(AtLeast(1)); 223 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0)) 224 .Times(AtLeast(1)); 225 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0)) 226 .Times(AtLeast(1)); 227 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)) 228 .Times(AtLeast(1)); 229 230 PayloadState payload_state; 231 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 232 payload_state.SetResponse(response); 233 string stored_response_sign = payload_state.GetResponseSignature(); 234 string expected_response_sign = 235 "Payload 0:\n" 236 " Size = 523456789\n" 237 " Sha256 Hash = rhash\n" 238 " Metadata Size = 558123\n" 239 " Metadata Signature = metasign\n" 240 " Is Delta = 0\n" 241 " NumURLs = 2\n" 242 " Candidate Url0 = http://multiple.url.test\n" 243 " Candidate Url1 = https://multiple.url.test\n" 244 "Max Failure Count Per Url = 0\n" 245 "Disable Payload Backoff = 0\n"; 246 EXPECT_EQ(expected_response_sign, stored_response_sign); 247 EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl()); 248 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 249 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount()); 250 EXPECT_EQ(1, payload_state.GetNumResponsesSeen()); 251 } 252 253 TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) { 254 OmahaResponse response; 255 FakeSystemState fake_system_state; 256 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs(); 257 PayloadState payload_state; 258 259 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber()); 260 // Payload attempt should start with 0 and then advance to 1. 261 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)) 262 .Times(AtLeast(1)); 263 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1)) 264 .Times(AtLeast(1)); 265 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0)) 266 .Times(AtLeast(1)); 267 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1)) 268 .Times(AtLeast(1)); 269 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2)); 270 271 // Reboots will be set 272 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1)); 273 274 // Url index should go from 0 to 1 twice. 275 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1)); 276 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1)); 277 278 // Failure count should be called each times url index is set, so that's 279 // 4 times for this test. 280 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)) 281 .Times(AtLeast(4)); 282 283 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 284 285 // This does a SetResponse which causes all the states to be set to 0 for 286 // the first time. 287 SetupPayloadStateWith2Urls( 288 "Hash1235", true, false, &payload_state, &response); 289 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 290 291 // Verify that on the first error, the URL index advances to 1. 292 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch; 293 payload_state.UpdateFailed(error); 294 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 295 296 // Verify that on the next error, the URL index wraps around to 0. 297 payload_state.UpdateFailed(error); 298 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 299 300 // Verify that on the next error, it again advances to 1. 301 payload_state.UpdateFailed(error); 302 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 303 304 // Verify that we switched URLs three times 305 EXPECT_EQ(3U, payload_state.GetUrlSwitchCount()); 306 } 307 308 TEST(PayloadStateTest, NewResponseResetsPayloadState) { 309 OmahaResponse response; 310 FakeSystemState fake_system_state; 311 PayloadState payload_state; 312 313 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 314 315 // Set the first response. 316 SetupPayloadStateWith2Urls( 317 "Hash5823", true, false, &payload_state, &response); 318 EXPECT_EQ(1, payload_state.GetNumResponsesSeen()); 319 320 // Advance the URL index to 1 by faking an error. 321 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch; 322 payload_state.UpdateFailed(error); 323 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 324 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount()); 325 326 // Now, slightly change the response and set it again. 327 SetupPayloadStateWith2Urls( 328 "Hash8225", true, false, &payload_state, &response); 329 EXPECT_EQ(2, payload_state.GetNumResponsesSeen()); 330 331 // Fake an error again. 332 payload_state.UpdateFailed(error); 333 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 334 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount()); 335 336 // Return a third different response. 337 SetupPayloadStateWith2Urls( 338 "Hash9999", true, false, &payload_state, &response); 339 EXPECT_EQ(3, payload_state.GetNumResponsesSeen()); 340 341 // Make sure the url index was reset to 0 because of the new response. 342 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 343 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 344 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount()); 345 EXPECT_EQ(0U, 346 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer)); 347 EXPECT_EQ(0U, 348 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer)); 349 EXPECT_EQ( 350 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer)); 351 EXPECT_EQ(0U, 352 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer)); 353 } 354 355 TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) { 356 OmahaResponse response; 357 PayloadState payload_state; 358 FakeSystemState fake_system_state; 359 int progress_bytes = 100; 360 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs(); 361 362 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber()); 363 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)) 364 .Times(AtLeast(2)); 365 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1)) 366 .Times(AtLeast(1)); 367 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2)) 368 .Times(AtLeast(1)); 369 370 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0)) 371 .Times(AtLeast(2)); 372 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1)) 373 .Times(AtLeast(1)); 374 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 2)) 375 .Times(AtLeast(1)); 376 377 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4)); 378 379 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4)); 380 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2)); 381 382 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)) 383 .Times(AtLeast(7)); 384 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1)) 385 .Times(AtLeast(2)); 386 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2)) 387 .Times(AtLeast(1)); 388 389 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _)) 390 .Times(AtLeast(1)); 391 EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _)) 392 .Times(AtLeast(1)); 393 394 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0)) 395 .Times(AtLeast(1)); 396 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0)) 397 .Times(AtLeast(1)); 398 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0)) 399 .Times(AtLeast(1)); 400 EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes)) 401 .Times(AtLeast(1)); 402 EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes)) 403 .Times(AtLeast(1)); 404 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)) 405 .Times(AtLeast(1)); 406 407 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 408 409 SetupPayloadStateWith2Urls( 410 "Hash5873", true, false, &payload_state, &response); 411 EXPECT_EQ(1, payload_state.GetNumResponsesSeen()); 412 413 // This should advance the URL index. 414 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 415 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber()); 416 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 417 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 418 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 419 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount()); 420 421 // This should advance the failure count only. 422 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError); 423 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber()); 424 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 425 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 426 EXPECT_EQ(1U, payload_state.GetUrlFailureCount()); 427 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount()); 428 429 // This should advance the failure count only. 430 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError); 431 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber()); 432 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 433 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 434 EXPECT_EQ(2U, payload_state.GetUrlFailureCount()); 435 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount()); 436 437 // This should advance the URL index as we've reached the 438 // max failure count and reset the failure count for the new URL index. 439 // This should also wrap around the URL index and thus cause the payload 440 // attempt number to be incremented. 441 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError); 442 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber()); 443 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber()); 444 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 445 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 446 EXPECT_EQ(2U, payload_state.GetUrlSwitchCount()); 447 EXPECT_TRUE(payload_state.ShouldBackoffDownload()); 448 449 // This should advance the URL index. 450 payload_state.UpdateFailed(ErrorCode::kPayloadHashMismatchError); 451 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber()); 452 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber()); 453 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 454 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 455 EXPECT_EQ(3U, payload_state.GetUrlSwitchCount()); 456 EXPECT_TRUE(payload_state.ShouldBackoffDownload()); 457 458 // This should advance the URL index and payload attempt number due to 459 // wrap-around of URL index. 460 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMissingError); 461 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber()); 462 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber()); 463 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 464 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 465 EXPECT_EQ(4U, payload_state.GetUrlSwitchCount()); 466 EXPECT_TRUE(payload_state.ShouldBackoffDownload()); 467 468 // This HTTP error code should only increase the failure count. 469 payload_state.UpdateFailed(static_cast<ErrorCode>( 470 static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase) + 404)); 471 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber()); 472 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber()); 473 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 474 EXPECT_EQ(1U, payload_state.GetUrlFailureCount()); 475 EXPECT_EQ(4U, payload_state.GetUrlSwitchCount()); 476 EXPECT_TRUE(payload_state.ShouldBackoffDownload()); 477 478 // And that failure count should be reset when we download some bytes 479 // afterwards. 480 payload_state.DownloadProgress(progress_bytes); 481 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber()); 482 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber()); 483 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 484 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 485 EXPECT_EQ(4U, payload_state.GetUrlSwitchCount()); 486 EXPECT_TRUE(payload_state.ShouldBackoffDownload()); 487 488 // Now, slightly change the response and set it again. 489 SetupPayloadStateWith2Urls( 490 "Hash8532", true, false, &payload_state, &response); 491 EXPECT_EQ(2, payload_state.GetNumResponsesSeen()); 492 493 // Make sure the url index was reset to 0 because of the new response. 494 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber()); 495 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 496 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 497 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 498 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount()); 499 EXPECT_FALSE(payload_state.ShouldBackoffDownload()); 500 } 501 502 TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) { 503 OmahaResponse response; 504 PayloadState payload_state; 505 FakeSystemState fake_system_state; 506 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs(); 507 508 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber()); 509 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)) 510 .Times(AtLeast(1)); 511 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1)) 512 .Times(AtLeast(1)); 513 514 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0)) 515 .Times(AtLeast(1)); 516 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1)) 517 .Times(AtLeast(1)); 518 519 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)) 520 .Times(AtLeast(2)); 521 522 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)) 523 .Times(AtLeast(1)); 524 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)) 525 .Times(AtLeast(1)); 526 527 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 528 529 SetupPayloadStateWith2Urls( 530 "Hash8593", true, false, &payload_state, &response); 531 532 // This should just advance the payload attempt number; 533 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber()); 534 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 535 payload_state.DownloadComplete(); 536 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber()); 537 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber()); 538 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 539 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 540 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount()); 541 } 542 543 TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) { 544 OmahaResponse response; 545 PayloadState payload_state; 546 FakeSystemState fake_system_state; 547 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs(); 548 549 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber()); 550 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0)) 551 .Times(AtLeast(1)); 552 EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1)) 553 .Times(AtLeast(1)); 554 555 // kPrefsFullPayloadAttemptNumber is not incremented for delta payloads. 556 EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0)) 557 .Times(AtLeast(1)); 558 559 EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)) 560 .Times(1); 561 562 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)) 563 .Times(AtLeast(1)); 564 EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0)) 565 .Times(AtLeast(1)); 566 567 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 568 569 SetupPayloadStateWith2Urls("Hash8593", true, true, &payload_state, &response); 570 571 // This should just advance the payload attempt number; 572 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber()); 573 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 574 payload_state.DownloadComplete(); 575 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber()); 576 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 577 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 578 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 579 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount()); 580 } 581 582 TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) { 583 OmahaResponse response; 584 PayloadState payload_state; 585 FakeSystemState fake_system_state; 586 587 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 588 SetupPayloadStateWith2Urls( 589 "Hash4427", true, false, &payload_state, &response); 590 591 // Generate enough events to advance URL index, failure count and 592 // payload attempt number all to 1. 593 payload_state.DownloadComplete(); 594 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 595 payload_state.UpdateFailed(ErrorCode::kDownloadTransferError); 596 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber()); 597 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber()); 598 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 599 EXPECT_EQ(1U, payload_state.GetUrlFailureCount()); 600 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount()); 601 602 // Now, simulate a corrupted url index on persisted store which gets 603 // loaded when update_engine restarts. Using a different prefs object 604 // so as to not bother accounting for the uninteresting calls above. 605 FakeSystemState fake_system_state2; 606 NiceMock<MockPrefs>* prefs2 = fake_system_state2.mock_prefs(); 607 EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true)); 608 EXPECT_CALL(*prefs2, GetInt64(_, _)).Times(AtLeast(1)); 609 EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _)) 610 .Times(AtLeast(1)); 611 EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _)) 612 .Times(AtLeast(1)); 613 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _)) 614 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(true))); 615 EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _)) 616 .Times(AtLeast(1)); 617 EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _)) 618 .Times(AtLeast(1)); 619 620 // Note: This will be a different payload object, but the response should 621 // have the same hash as before so as to not trivially reset because the 622 // response was different. We want to specifically test that even if the 623 // response is same, we should reset the state if we find it corrupted. 624 EXPECT_TRUE(payload_state.Initialize(&fake_system_state2)); 625 SetupPayloadStateWith2Urls( 626 "Hash4427", true, false, &payload_state, &response); 627 628 // Make sure all counters get reset to 0 because of the corrupted URL index 629 // we supplied above. 630 EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber()); 631 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 632 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 633 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 634 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount()); 635 } 636 637 TEST(PayloadStateTest, NoBackoffInteractiveChecks) { 638 OmahaResponse response; 639 PayloadState payload_state; 640 FakeSystemState fake_system_state; 641 OmahaRequestParams params(&fake_system_state); 642 params.Init("", "", true); // is_interactive = True. 643 fake_system_state.set_request_params(¶ms); 644 645 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 646 SetupPayloadStateWith2Urls( 647 "Hash6437", true, false, &payload_state, &response); 648 649 // Simulate two failures (enough to cause payload backoff) and check 650 // again that we're ready to re-download without any backoff as this is 651 // an interactive check. 652 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 653 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 654 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 655 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber()); 656 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber()); 657 EXPECT_FALSE(payload_state.ShouldBackoffDownload()); 658 } 659 660 TEST(PayloadStateTest, NoBackoffForP2PUpdates) { 661 OmahaResponse response; 662 PayloadState payload_state; 663 FakeSystemState fake_system_state; 664 OmahaRequestParams params(&fake_system_state); 665 params.Init("", "", false); // is_interactive = False. 666 fake_system_state.set_request_params(¶ms); 667 668 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 669 SetupPayloadStateWith2Urls( 670 "Hash6437", true, false, &payload_state, &response); 671 672 // Simulate two failures (enough to cause payload backoff) and check 673 // again that we're ready to re-download without any backoff as this is 674 // an interactive check. 675 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 676 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 677 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 678 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber()); 679 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber()); 680 // Set p2p url. 681 payload_state.SetUsingP2PForDownloading(true); 682 payload_state.SetP2PUrl("http://mypeer:52909/path/to/file"); 683 // Should not backoff for p2p updates. 684 EXPECT_FALSE(payload_state.ShouldBackoffDownload()); 685 686 payload_state.SetP2PUrl(""); 687 // No actual p2p update if no url is provided. 688 EXPECT_TRUE(payload_state.ShouldBackoffDownload()); 689 } 690 691 TEST(PayloadStateTest, NoBackoffForDeltaPayloads) { 692 OmahaResponse response; 693 PayloadState payload_state; 694 FakeSystemState fake_system_state; 695 696 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 697 SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response); 698 699 // Simulate a successful download and see that we're ready to download 700 // again without any backoff as this is a delta payload. 701 payload_state.DownloadComplete(); 702 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber()); 703 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 704 EXPECT_FALSE(payload_state.ShouldBackoffDownload()); 705 706 // Simulate two failures (enough to cause payload backoff) and check 707 // again that we're ready to re-download without any backoff as this is 708 // a delta payload. 709 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 710 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 711 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 712 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber()); 713 EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber()); 714 EXPECT_FALSE(payload_state.ShouldBackoffDownload()); 715 } 716 717 static void CheckPayloadBackoffState(PayloadState* payload_state, 718 int expected_attempt_number, 719 TimeDelta expected_days) { 720 payload_state->DownloadComplete(); 721 EXPECT_EQ(expected_attempt_number, 722 payload_state->GetFullPayloadAttemptNumber()); 723 EXPECT_TRUE(payload_state->ShouldBackoffDownload()); 724 Time backoff_expiry_time = payload_state->GetBackoffExpiryTime(); 725 // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases. 726 TimeDelta max_fuzz_delta = TimeDelta::FromHours(7); 727 Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta; 728 Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta; 729 EXPECT_LT(expected_min_time.ToInternalValue(), 730 backoff_expiry_time.ToInternalValue()); 731 EXPECT_GT(expected_max_time.ToInternalValue(), 732 backoff_expiry_time.ToInternalValue()); 733 } 734 735 TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) { 736 OmahaResponse response; 737 PayloadState payload_state; 738 FakeSystemState fake_system_state; 739 740 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 741 SetupPayloadStateWith2Urls( 742 "Hash8939", true, false, &payload_state, &response); 743 744 CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1)); 745 CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2)); 746 CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4)); 747 CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8)); 748 CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16)); 749 CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16)); 750 CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16)); 751 CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16)); 752 CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16)); 753 CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16)); 754 } 755 756 TEST(PayloadStateTest, BackoffLogicCanBeDisabled) { 757 OmahaResponse response; 758 response.disable_payload_backoff = true; 759 PayloadState payload_state; 760 FakeSystemState fake_system_state; 761 762 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 763 SetupPayloadStateWith2Urls( 764 "Hash8939", true, false, &payload_state, &response); 765 766 // Simulate a successful download and see that we are ready to download 767 // again without any backoff. 768 payload_state.DownloadComplete(); 769 EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber()); 770 EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber()); 771 EXPECT_FALSE(payload_state.ShouldBackoffDownload()); 772 773 // Test again, this time by simulating two errors that would cause 774 // the payload attempt number to increment due to wrap around. And 775 // check that we are still ready to re-download without any backoff. 776 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 777 payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch); 778 EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber()); 779 EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber()); 780 EXPECT_FALSE(payload_state.ShouldBackoffDownload()); 781 } 782 783 TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) { 784 OmahaResponse response; 785 response.disable_payload_backoff = true; 786 PayloadState payload_state; 787 FakeSystemState fake_system_state; 788 uint64_t https_total = 0; 789 uint64_t http_total = 0; 790 791 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 792 SetupPayloadStateWith2Urls( 793 "Hash3286", true, false, &payload_state, &response); 794 EXPECT_EQ(1, payload_state.GetNumResponsesSeen()); 795 796 // Simulate a previous attempt with in order to set an initial non-zero value 797 // for the total bytes downloaded for HTTP. 798 uint64_t prev_chunk = 323456789; 799 http_total += prev_chunk; 800 payload_state.DownloadProgress(prev_chunk); 801 802 // Ensure that the initial values for HTTP reflect this attempt. 803 EXPECT_EQ(prev_chunk, 804 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer)); 805 EXPECT_EQ(http_total, 806 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer)); 807 808 // Change the response hash so as to simulate a new response which will 809 // reset the current bytes downloaded, but not the total bytes downloaded. 810 SetupPayloadStateWith2Urls( 811 "Hash9904", true, false, &payload_state, &response); 812 EXPECT_EQ(2, payload_state.GetNumResponsesSeen()); 813 814 // First, simulate successful download of a few bytes over HTTP. 815 uint64_t first_chunk = 5000000; 816 http_total += first_chunk; 817 payload_state.DownloadProgress(first_chunk); 818 // Test that first all progress is made on HTTP and none on HTTPS. 819 EXPECT_EQ(first_chunk, 820 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer)); 821 EXPECT_EQ(http_total, 822 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer)); 823 EXPECT_EQ(0U, payload_state.GetCurrentBytesDownloaded( 824 kDownloadSourceHttpsServer)); 825 EXPECT_EQ(https_total, 826 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer)); 827 828 // Simulate an error that'll cause the url index to point to https. 829 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch; 830 payload_state.UpdateFailed(error); 831 832 // Test that no new progress is made on HTTP and new progress is on HTTPS. 833 uint64_t second_chunk = 23456789; 834 https_total += second_chunk; 835 payload_state.DownloadProgress(second_chunk); 836 EXPECT_EQ(first_chunk, 837 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer)); 838 EXPECT_EQ(http_total, 839 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer)); 840 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded( 841 kDownloadSourceHttpsServer)); 842 EXPECT_EQ(https_total, 843 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer)); 844 845 // Simulate error to go back to http. 846 payload_state.UpdateFailed(error); 847 uint64_t third_chunk = 32345678; 848 uint64_t http_chunk = first_chunk + third_chunk; 849 http_total += third_chunk; 850 payload_state.DownloadProgress(third_chunk); 851 852 // Test that third chunk is again back on HTTP. HTTPS remains on second chunk. 853 EXPECT_EQ(http_chunk, 854 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer)); 855 EXPECT_EQ(http_total, 856 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer)); 857 EXPECT_EQ(second_chunk, payload_state.GetCurrentBytesDownloaded( 858 kDownloadSourceHttpsServer)); 859 EXPECT_EQ(https_total, 860 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer)); 861 862 // Simulate error (will cause URL switch), set p2p is to be used and 863 // then do 42MB worth of progress 864 payload_state.UpdateFailed(error); 865 payload_state.SetUsingP2PForDownloading(true); 866 uint64_t p2p_total = 42 * 1000 * 1000; 867 payload_state.DownloadProgress(p2p_total); 868 869 EXPECT_EQ(p2p_total, 870 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer)); 871 872 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 873 ReportSuccessfulUpdateMetrics( 874 1, _, kPayloadTypeFull, _, _, 314, _, _, 3)); 875 876 payload_state.UpdateSucceeded(); 877 878 // Make sure the metrics are reset after a successful update. 879 EXPECT_EQ(0U, 880 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer)); 881 EXPECT_EQ(0U, 882 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer)); 883 EXPECT_EQ(0U, payload_state.GetCurrentBytesDownloaded( 884 kDownloadSourceHttpsServer)); 885 EXPECT_EQ(0U, 886 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer)); 887 EXPECT_EQ(0, payload_state.GetNumResponsesSeen()); 888 } 889 890 TEST(PayloadStateTest, DownloadSourcesUsedIsCorrect) { 891 OmahaResponse response; 892 PayloadState payload_state; 893 FakeSystemState fake_system_state; 894 895 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 896 SetupPayloadStateWith2Urls( 897 "Hash3286", true, false, &payload_state, &response); 898 899 // Simulate progress in order to mark HTTP as one of the sources used. 900 uint64_t num_bytes = 42 * 1000 * 1000; 901 payload_state.DownloadProgress(num_bytes); 902 903 // Check that this was done via HTTP. 904 EXPECT_EQ(num_bytes, 905 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer)); 906 EXPECT_EQ(num_bytes, 907 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer)); 908 909 // Check that only HTTP is reported as a download source. 910 int64_t total_bytes[kNumDownloadSources] = {}; 911 total_bytes[kDownloadSourceHttpServer] = num_bytes; 912 913 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 914 ReportSuccessfulUpdateMetrics( 915 _, 916 _, 917 _, 918 _, 919 test_utils::DownloadSourceMatcher(total_bytes), 920 _, 921 _, 922 _, 923 _)) 924 .Times(1); 925 926 payload_state.UpdateSucceeded(); 927 } 928 929 TEST(PayloadStateTest, RestartingUpdateResetsMetrics) { 930 OmahaResponse response; 931 FakeSystemState fake_system_state; 932 PayloadState payload_state; 933 934 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 935 936 // Set the first response. 937 SetupPayloadStateWith2Urls( 938 "Hash5823", true, false, &payload_state, &response); 939 940 uint64_t num_bytes = 10000; 941 payload_state.DownloadProgress(num_bytes); 942 EXPECT_EQ(num_bytes, 943 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer)); 944 EXPECT_EQ(num_bytes, 945 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer)); 946 EXPECT_EQ(0U, payload_state.GetCurrentBytesDownloaded( 947 kDownloadSourceHttpsServer)); 948 EXPECT_EQ(0U, 949 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer)); 950 951 payload_state.UpdateRestarted(); 952 // Make sure the current bytes downloaded is reset, but not the total bytes. 953 EXPECT_EQ(0U, 954 payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer)); 955 EXPECT_EQ(num_bytes, 956 payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer)); 957 } 958 959 TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) { 960 FakeSystemState fake_system_state; 961 PayloadState payload_state; 962 963 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs(); 964 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AtLeast(0)); 965 EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1)); 966 967 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 968 969 payload_state.UpdateRestarted(); 970 EXPECT_EQ(0U, payload_state.GetNumReboots()); 971 972 fake_system_state.set_system_rebooted(true); 973 payload_state.UpdateResumed(); 974 // Num reboots should be incremented because system rebooted detected. 975 EXPECT_EQ(1U, payload_state.GetNumReboots()); 976 977 fake_system_state.set_system_rebooted(false); 978 payload_state.UpdateResumed(); 979 // Num reboots should now be 1 as reboot was not detected. 980 EXPECT_EQ(1U, payload_state.GetNumReboots()); 981 982 // Restart the update again to verify we set the num of reboots back to 0. 983 payload_state.UpdateRestarted(); 984 EXPECT_EQ(0U, payload_state.GetNumReboots()); 985 } 986 987 TEST(PayloadStateTest, RollbackVersion) { 988 FakeSystemState fake_system_state; 989 PayloadState payload_state; 990 991 NiceMock<MockPrefs>* mock_powerwash_safe_prefs = 992 fake_system_state.mock_powerwash_safe_prefs(); 993 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 994 995 // Verify pre-conditions are good. 996 EXPECT_TRUE(payload_state.GetRollbackVersion().empty()); 997 998 // Mock out the os version and make sure it's blacklisted correctly. 999 string rollback_version = "2345.0.0"; 1000 OmahaRequestParams params(&fake_system_state); 1001 params.Init(rollback_version, "", false); 1002 fake_system_state.set_request_params(¶ms); 1003 1004 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion, 1005 rollback_version)); 1006 payload_state.Rollback(); 1007 1008 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion()); 1009 1010 // Change it up a little and verify we load it correctly. 1011 rollback_version = "2345.0.1"; 1012 // Let's verify we can reload it correctly. 1013 EXPECT_CALL(*mock_powerwash_safe_prefs, GetString( 1014 kPrefsRollbackVersion, _)).WillOnce(DoAll( 1015 SetArgPointee<1>(rollback_version), Return(true))); 1016 EXPECT_CALL(*mock_powerwash_safe_prefs, SetString(kPrefsRollbackVersion, 1017 rollback_version)); 1018 payload_state.LoadRollbackVersion(); 1019 EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion()); 1020 1021 // Check that we report only UpdateEngine.Rollback.* metrics in 1022 // UpdateSucceeded(). 1023 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1024 ReportRollbackMetrics(metrics::RollbackResult::kSuccess)) 1025 .Times(1); 1026 1027 payload_state.UpdateSucceeded(); 1028 } 1029 1030 TEST(PayloadStateTest, DurationsAreCorrect) { 1031 OmahaResponse response; 1032 response.packages.resize(1); 1033 PayloadState payload_state; 1034 FakeSystemState fake_system_state; 1035 FakeClock fake_clock; 1036 FakePrefs fake_prefs; 1037 1038 // Set the clock to a well-known time - 1 second on the wall-clock 1039 // and 2 seconds on the monotonic clock 1040 fake_clock.SetWallclockTime(Time::FromInternalValue(1000000)); 1041 fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000)); 1042 1043 fake_system_state.set_clock(&fake_clock); 1044 fake_system_state.set_prefs(&fake_prefs); 1045 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1046 1047 // Check that durations are correct for a successful update where 1048 // time has advanced 7 seconds on the wall clock and 4 seconds on 1049 // the monotonic clock. 1050 SetupPayloadStateWith2Urls( 1051 "Hash8593", true, false, &payload_state, &response); 1052 fake_clock.SetWallclockTime(Time::FromInternalValue(8000000)); 1053 fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000)); 1054 payload_state.UpdateSucceeded(); 1055 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000); 1056 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000); 1057 1058 // Check that durations are reset when a new response comes in. 1059 SetupPayloadStateWith2Urls( 1060 "Hash8594", true, false, &payload_state, &response); 1061 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0); 1062 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0); 1063 1064 // Advance time a bit (10 secs), simulate download progress and 1065 // check that durations are updated. 1066 fake_clock.SetWallclockTime(Time::FromInternalValue(18000000)); 1067 fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000)); 1068 payload_state.DownloadProgress(10); 1069 EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000); 1070 EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000); 1071 1072 // Now simulate a reboot by resetting monotonic time (to 5000) and 1073 // creating a new PayloadState object and check that we load the 1074 // durations correctly (e.g. they are the same as before). 1075 fake_clock.SetMonotonicTime(Time::FromInternalValue(5000)); 1076 PayloadState payload_state2; 1077 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state)); 1078 payload_state2.SetResponse(response); 1079 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000); 1080 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(), 1081 10000000); 1082 1083 // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds 1084 // and check that the durations are increased accordingly. 1085 fake_clock.SetWallclockTime(Time::FromInternalValue(25000000)); 1086 fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000)); 1087 payload_state2.UpdateSucceeded(); 1088 EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000); 1089 EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(), 1090 16000000); 1091 } 1092 1093 TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) { 1094 OmahaResponse response; 1095 PayloadState payload_state; 1096 FakeSystemState fake_system_state; 1097 FakeClock fake_clock; 1098 FakePrefs fake_prefs; 1099 1100 // Set the clock to a well-known time (t = 30 seconds). 1101 fake_clock.SetMonotonicTime( 1102 Time::FromInternalValue(30 * Time::kMicrosecondsPerSecond)); 1103 1104 fake_system_state.set_clock(&fake_clock); 1105 fake_system_state.set_prefs(&fake_prefs); 1106 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1107 1108 // Make the update succeed. 1109 SetupPayloadStateWith2Urls( 1110 "Hash8593", true, false, &payload_state, &response); 1111 payload_state.UpdateSucceeded(); 1112 1113 // Check that the marker was written. 1114 EXPECT_TRUE(fake_prefs.Exists(kPrefsSystemUpdatedMarker)); 1115 1116 // Now simulate a reboot and set the wallclock time to a later point 1117 // (t = 500 seconds). We do this by using a new PayloadState object 1118 // and checking that it emits the right UMA metric with the right 1119 // value. 1120 fake_clock.SetMonotonicTime( 1121 Time::FromInternalValue(500 * Time::kMicrosecondsPerSecond)); 1122 PayloadState payload_state2; 1123 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state)); 1124 1125 // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec 1126 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1127 ReportTimeToReboot(7)); 1128 fake_system_state.set_system_rebooted(true); 1129 1130 payload_state2.UpdateEngineStarted(); 1131 1132 // Check that the marker was nuked. 1133 EXPECT_FALSE(fake_prefs.Exists(kPrefsSystemUpdatedMarker)); 1134 } 1135 1136 TEST(PayloadStateTest, RestartAfterCrash) { 1137 PayloadState payload_state; 1138 FakeSystemState fake_system_state; 1139 testing::StrictMock<MockMetricsReporter> mock_metrics_reporter; 1140 fake_system_state.set_metrics_reporter(&mock_metrics_reporter); 1141 NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs(); 1142 1143 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1144 1145 // Only the |kPrefsAttemptInProgress| state variable should be read. 1146 EXPECT_CALL(*prefs, Exists(_)).Times(0); 1147 EXPECT_CALL(*prefs, SetString(_, _)).Times(0); 1148 EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0); 1149 EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0); 1150 EXPECT_CALL(*prefs, GetString(_, _)).Times(0); 1151 EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0); 1152 EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0); 1153 EXPECT_CALL(*prefs, GetBoolean(kPrefsAttemptInProgress, _)); 1154 1155 // Simulate an update_engine restart without a reboot. 1156 fake_system_state.set_system_rebooted(false); 1157 1158 payload_state.UpdateEngineStarted(); 1159 } 1160 1161 TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsNoReporting) { 1162 PayloadState payload_state; 1163 FakeSystemState fake_system_state; 1164 1165 // If there's no marker at startup, ensure we don't report a metric. 1166 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1167 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1168 ReportAbnormallyTerminatedUpdateAttemptMetrics()) 1169 .Times(0); 1170 payload_state.UpdateEngineStarted(); 1171 } 1172 1173 TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsReported) { 1174 PayloadState payload_state; 1175 FakeSystemState fake_system_state; 1176 FakePrefs fake_prefs; 1177 1178 // If we have a marker at startup, ensure it's reported and the 1179 // marker is then cleared. 1180 fake_system_state.set_prefs(&fake_prefs); 1181 fake_prefs.SetBoolean(kPrefsAttemptInProgress, true); 1182 1183 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1184 1185 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1186 ReportAbnormallyTerminatedUpdateAttemptMetrics()) 1187 .Times(1); 1188 payload_state.UpdateEngineStarted(); 1189 1190 EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress)); 1191 } 1192 1193 TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsClearedOnSucceess) { 1194 PayloadState payload_state; 1195 FakeSystemState fake_system_state; 1196 FakePrefs fake_prefs; 1197 1198 // Make sure the marker is written and cleared during an attempt and 1199 // also that we DO NOT emit the metric (since the attempt didn't end 1200 // abnormally). 1201 fake_system_state.set_prefs(&fake_prefs); 1202 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1203 OmahaResponse response; 1204 response.packages.resize(1); 1205 payload_state.SetResponse(response); 1206 1207 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1208 ReportAbnormallyTerminatedUpdateAttemptMetrics()) 1209 .Times(0); 1210 1211 // Attempt not in progress, should be clear. 1212 EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress)); 1213 1214 payload_state.UpdateRestarted(); 1215 1216 // Attempt not in progress, should be set. 1217 EXPECT_TRUE(fake_prefs.Exists(kPrefsAttemptInProgress)); 1218 1219 payload_state.UpdateSucceeded(); 1220 1221 // Attempt not in progress, should be clear. 1222 EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress)); 1223 } 1224 1225 TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) { 1226 OmahaResponse response; 1227 FakeSystemState fake_system_state; 1228 PayloadState payload_state; 1229 1230 policy::MockDevicePolicy disable_http_policy; 1231 fake_system_state.set_device_policy(&disable_http_policy); 1232 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1233 1234 // Test with no device policy. Should default to allowing http. 1235 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_)) 1236 .WillRepeatedly(Return(false)); 1237 1238 // Set the first response. 1239 SetupPayloadStateWith2Urls( 1240 "Hash8433", true, false, &payload_state, &response); 1241 1242 // Check that we use the HTTP URL since there is no value set for allowing 1243 // http. 1244 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 1245 1246 // Test with device policy not allowing http updates. 1247 EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_)) 1248 .WillRepeatedly(DoAll(SetArgPointee<0>(false), Return(true))); 1249 1250 // Reset state and set again. 1251 SetupPayloadStateWith2Urls( 1252 "Hash8433", false, false, &payload_state, &response); 1253 1254 // Check that we skip the HTTP URL and use only the HTTPS url. 1255 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 1256 1257 // Advance the URL index to 1 by faking an error. 1258 ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch; 1259 payload_state.UpdateFailed(error); 1260 1261 // Check that we still skip the HTTP URL and use only the HTTPS url. 1262 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 1263 EXPECT_EQ(0U, payload_state.GetUrlSwitchCount()); 1264 1265 // Now, slightly change the response and set it again. 1266 SetupPayloadStateWith2Urls( 1267 "Hash2399", false, false, &payload_state, &response); 1268 1269 // Check that we still skip the HTTP URL and use only the HTTPS url. 1270 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 1271 1272 // Now, pretend that the HTTP policy is turned on. We want to make sure 1273 // the new policy is honored. 1274 policy::MockDevicePolicy enable_http_policy; 1275 fake_system_state.set_device_policy(&enable_http_policy); 1276 EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_)) 1277 .WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true))); 1278 1279 // Now, set the same response using the same hash 1280 // so that we can test that the state is reset not because of the 1281 // hash but because of the policy change which results in candidate url 1282 // list change. 1283 SetupPayloadStateWith2Urls( 1284 "Hash2399", true, false, &payload_state, &response); 1285 1286 // Check that we use the HTTP URL now and the failure count is reset. 1287 EXPECT_EQ("http://test", payload_state.GetCurrentUrl()); 1288 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 1289 1290 // Fake a failure and see if we're moving over to the HTTPS url and update 1291 // the URL switch count properly. 1292 payload_state.UpdateFailed(error); 1293 EXPECT_EQ("https://test", payload_state.GetCurrentUrl()); 1294 EXPECT_EQ(1U, payload_state.GetUrlSwitchCount()); 1295 EXPECT_EQ(0U, payload_state.GetUrlFailureCount()); 1296 } 1297 1298 TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) { 1299 OmahaResponse response; 1300 PayloadState payload_state; 1301 FakeSystemState fake_system_state; 1302 1303 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1304 SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response); 1305 1306 // Simulate a successful download and update. 1307 payload_state.DownloadComplete(); 1308 EXPECT_CALL( 1309 *fake_system_state.mock_metrics_reporter(), 1310 ReportSuccessfulUpdateMetrics(_, _, kPayloadTypeDelta, _, _, _, _, _, _)); 1311 payload_state.UpdateSucceeded(); 1312 1313 // Mock the request to a request where the delta was disabled but Omaha sends 1314 // a delta anyway and test again. 1315 OmahaRequestParams params(&fake_system_state); 1316 params.set_delta_okay(false); 1317 fake_system_state.set_request_params(¶ms); 1318 1319 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1320 SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response); 1321 1322 payload_state.DownloadComplete(); 1323 1324 EXPECT_CALL( 1325 *fake_system_state.mock_metrics_reporter(), 1326 ReportSuccessfulUpdateMetrics(_, _, kPayloadTypeDelta, _, _, _, _, _, _)); 1327 payload_state.UpdateSucceeded(); 1328 } 1329 1330 TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) { 1331 OmahaResponse response; 1332 PayloadState payload_state; 1333 FakeSystemState fake_system_state; 1334 1335 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1336 SetupPayloadStateWith2Urls( 1337 "Hash6437", true, false, &payload_state, &response); 1338 1339 // Mock the request to a request where the delta was disabled. 1340 OmahaRequestParams params(&fake_system_state); 1341 params.set_delta_okay(false); 1342 fake_system_state.set_request_params(¶ms); 1343 1344 // Simulate a successful download and update. 1345 payload_state.DownloadComplete(); 1346 1347 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1348 ReportSuccessfulUpdateMetrics( 1349 _, _, kPayloadTypeForcedFull, _, _, _, _, _, _)); 1350 payload_state.UpdateSucceeded(); 1351 } 1352 1353 TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) { 1354 OmahaResponse response; 1355 PayloadState payload_state; 1356 FakeSystemState fake_system_state; 1357 1358 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1359 SetupPayloadStateWith2Urls( 1360 "Hash6437", true, false, &payload_state, &response); 1361 1362 // Mock the request to a request where the delta is enabled, although the 1363 // result is full. 1364 OmahaRequestParams params(&fake_system_state); 1365 params.set_delta_okay(true); 1366 fake_system_state.set_request_params(¶ms); 1367 1368 // Simulate a successful download and update. 1369 payload_state.DownloadComplete(); 1370 1371 EXPECT_CALL( 1372 *fake_system_state.mock_metrics_reporter(), 1373 ReportSuccessfulUpdateMetrics(_, _, kPayloadTypeFull, _, _, _, _, _, _)); 1374 payload_state.UpdateSucceeded(); 1375 } 1376 1377 TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) { 1378 FakeSystemState fake_system_state; 1379 OmahaResponse response; 1380 PayloadState payload_state; 1381 FakePrefs fake_prefs; 1382 fake_system_state.set_prefs(&fake_prefs); 1383 1384 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1385 SetupPayloadStateWith2Urls( 1386 "Hash3141", true, false, &payload_state, &response); 1387 1388 // Simulate a successful download and update. 1389 payload_state.DownloadComplete(); 1390 payload_state.UpdateSucceeded(); 1391 payload_state.ExpectRebootInNewVersion("Version:12345678"); 1392 1393 // Reboot into the same environment to get an UMA metric with a value of 1. 1394 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1395 ReportFailedUpdateCount(1)); 1396 payload_state.ReportFailedBootIfNeeded(); 1397 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter()); 1398 1399 // Simulate a second update and reboot into the same environment, this should 1400 // send a value of 2. 1401 payload_state.ExpectRebootInNewVersion("Version:12345678"); 1402 1403 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1404 ReportFailedUpdateCount(2)); 1405 payload_state.ReportFailedBootIfNeeded(); 1406 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter()); 1407 1408 // Simulate a third failed reboot to new version, but this time for a 1409 // different payload. This should send a value of 1 this time. 1410 payload_state.ExpectRebootInNewVersion("Version:3141592"); 1411 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1412 ReportFailedUpdateCount(1)); 1413 payload_state.ReportFailedBootIfNeeded(); 1414 Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter()); 1415 } 1416 1417 TEST(PayloadStateTest, RebootAfterUpdateSucceed) { 1418 FakeSystemState fake_system_state; 1419 OmahaResponse response; 1420 PayloadState payload_state; 1421 FakePrefs fake_prefs; 1422 fake_system_state.set_prefs(&fake_prefs); 1423 1424 FakeBootControl* fake_boot_control = fake_system_state.fake_boot_control(); 1425 fake_boot_control->SetCurrentSlot(0); 1426 1427 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1428 SetupPayloadStateWith2Urls( 1429 "Hash3141", true, false, &payload_state, &response); 1430 1431 // Simulate a successful download and update. 1432 payload_state.DownloadComplete(); 1433 payload_state.UpdateSucceeded(); 1434 payload_state.ExpectRebootInNewVersion("Version:12345678"); 1435 1436 // Change the BootDevice to a different one, no metric should be sent. 1437 fake_boot_control->SetCurrentSlot(1); 1438 1439 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1440 ReportFailedUpdateCount(_)) 1441 .Times(0); 1442 payload_state.ReportFailedBootIfNeeded(); 1443 1444 // A second reboot in either partition should not send a metric. 1445 payload_state.ReportFailedBootIfNeeded(); 1446 fake_boot_control->SetCurrentSlot(0); 1447 payload_state.ReportFailedBootIfNeeded(); 1448 } 1449 1450 TEST(PayloadStateTest, RebootAfterCanceledUpdate) { 1451 FakeSystemState fake_system_state; 1452 OmahaResponse response; 1453 PayloadState payload_state; 1454 FakePrefs fake_prefs; 1455 1456 fake_system_state.set_prefs(&fake_prefs); 1457 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1458 SetupPayloadStateWith2Urls( 1459 "Hash3141", true, false, &payload_state, &response); 1460 1461 // Simulate a successful download and update. 1462 payload_state.DownloadComplete(); 1463 payload_state.UpdateSucceeded(); 1464 payload_state.ExpectRebootInNewVersion("Version:12345678"); 1465 1466 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1467 ReportFailedUpdateCount(_)) 1468 .Times(0); 1469 1470 // Cancel the applied update. 1471 payload_state.ResetUpdateStatus(); 1472 1473 // Simulate a reboot. 1474 payload_state.ReportFailedBootIfNeeded(); 1475 } 1476 1477 TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) { 1478 FakeSystemState fake_system_state; 1479 PayloadState payload_state; 1480 FakePrefs fake_prefs; 1481 1482 fake_system_state.set_prefs(&fake_prefs); 1483 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1484 1485 EXPECT_CALL(*fake_system_state.mock_metrics_reporter(), 1486 ReportFailedUpdateCount(_)) 1487 .Times(0); 1488 1489 // Simulate a reboot in this environment. 1490 payload_state.ReportFailedBootIfNeeded(); 1491 } 1492 1493 TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) { 1494 OmahaResponse response; 1495 PayloadState payload_state; 1496 FakeSystemState fake_system_state; 1497 FakePrefs fake_prefs; 1498 fake_system_state.set_prefs(&fake_prefs); 1499 1500 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1501 SetupPayloadStateWith2Urls( 1502 "Hash8593", true, false, &payload_state, &response); 1503 1504 // Should allow exactly kMaxP2PAttempts... 1505 for (int n = 0; n < kMaxP2PAttempts; n++) { 1506 payload_state.P2PNewAttempt(); 1507 EXPECT_TRUE(payload_state.P2PAttemptAllowed()); 1508 } 1509 // ... but not more than that. 1510 payload_state.P2PNewAttempt(); 1511 EXPECT_FALSE(payload_state.P2PAttemptAllowed()); 1512 } 1513 1514 TEST(PayloadStateTest, DisallowP2PAfterDeadline) { 1515 OmahaResponse response; 1516 PayloadState payload_state; 1517 FakeSystemState fake_system_state; 1518 FakeClock fake_clock; 1519 FakePrefs fake_prefs; 1520 1521 fake_system_state.set_clock(&fake_clock); 1522 fake_system_state.set_prefs(&fake_prefs); 1523 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1524 SetupPayloadStateWith2Urls( 1525 "Hash8593", true, false, &payload_state, &response); 1526 1527 // Set the clock to 1 second. 1528 Time epoch = Time::FromInternalValue(1000000); 1529 fake_clock.SetWallclockTime(epoch); 1530 1531 // Do an attempt - this will set the timestamp. 1532 payload_state.P2PNewAttempt(); 1533 1534 // Check that the timestamp equals what we just set. 1535 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp()); 1536 1537 // Time hasn't advanced - this should work. 1538 EXPECT_TRUE(payload_state.P2PAttemptAllowed()); 1539 1540 // Set clock to half the deadline - this should work. 1541 fake_clock.SetWallclockTime(epoch + 1542 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2); 1543 EXPECT_TRUE(payload_state.P2PAttemptAllowed()); 1544 1545 // Check that the first attempt timestamp hasn't changed just 1546 // because the wall-clock time changed. 1547 EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp()); 1548 1549 // Set clock to _just_ before the deadline - this should work. 1550 fake_clock.SetWallclockTime(epoch + 1551 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1)); 1552 EXPECT_TRUE(payload_state.P2PAttemptAllowed()); 1553 1554 // Set clock to _just_ after the deadline - this should not work. 1555 fake_clock.SetWallclockTime(epoch + 1556 TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1)); 1557 EXPECT_FALSE(payload_state.P2PAttemptAllowed()); 1558 } 1559 1560 TEST(PayloadStateTest, P2PStateVarsInitialValue) { 1561 OmahaResponse response; 1562 PayloadState payload_state; 1563 FakeSystemState fake_system_state; 1564 FakePrefs fake_prefs; 1565 1566 fake_system_state.set_prefs(&fake_prefs); 1567 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1568 SetupPayloadStateWith2Urls( 1569 "Hash8593", true, false, &payload_state, &response); 1570 1571 Time null_time = Time(); 1572 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp()); 1573 EXPECT_EQ(0, payload_state.GetP2PNumAttempts()); 1574 } 1575 1576 TEST(PayloadStateTest, P2PStateVarsArePersisted) { 1577 OmahaResponse response; 1578 PayloadState payload_state; 1579 FakeSystemState fake_system_state; 1580 FakeClock fake_clock; 1581 FakePrefs fake_prefs; 1582 fake_system_state.set_clock(&fake_clock); 1583 fake_system_state.set_prefs(&fake_prefs); 1584 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1585 SetupPayloadStateWith2Urls( 1586 "Hash8593", true, false, &payload_state, &response); 1587 1588 // Set the clock to something known. 1589 Time time = Time::FromInternalValue(12345); 1590 fake_clock.SetWallclockTime(time); 1591 1592 // New p2p attempt - as a side-effect this will update the p2p state vars. 1593 payload_state.P2PNewAttempt(); 1594 EXPECT_EQ(1, payload_state.GetP2PNumAttempts()); 1595 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp()); 1596 1597 // Now create a new PayloadState and check that it loads the state 1598 // vars correctly. 1599 PayloadState payload_state2; 1600 EXPECT_TRUE(payload_state2.Initialize(&fake_system_state)); 1601 EXPECT_EQ(1, payload_state2.GetP2PNumAttempts()); 1602 EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp()); 1603 } 1604 1605 TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) { 1606 OmahaResponse response; 1607 PayloadState payload_state; 1608 FakeSystemState fake_system_state; 1609 FakeClock fake_clock; 1610 FakePrefs fake_prefs; 1611 fake_system_state.set_clock(&fake_clock); 1612 fake_system_state.set_prefs(&fake_prefs); 1613 1614 EXPECT_TRUE(payload_state.Initialize(&fake_system_state)); 1615 SetupPayloadStateWith2Urls( 1616 "Hash8593", true, false, &payload_state, &response); 1617 1618 // Set the clock to something known. 1619 Time time = Time::FromInternalValue(12345); 1620 fake_clock.SetWallclockTime(time); 1621 1622 // New p2p attempt - as a side-effect this will update the p2p state vars. 1623 payload_state.P2PNewAttempt(); 1624 EXPECT_EQ(1, payload_state.GetP2PNumAttempts()); 1625 EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp()); 1626 1627 // Set a new response... 1628 SetupPayloadStateWith2Urls( 1629 "Hash9904", true, false, &payload_state, &response); 1630 1631 // ... and check that it clears the P2P state vars. 1632 Time null_time = Time(); 1633 EXPECT_EQ(0, payload_state.GetP2PNumAttempts()); 1634 EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp()); 1635 } 1636 1637 } // namespace chromeos_update_engine 1638