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