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