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/omaha_request_action.h" 18 19 #include <stdint.h> 20 21 #include <memory> 22 #include <string> 23 #include <vector> 24 25 #include <base/bind.h> 26 #include <base/files/file_util.h> 27 #include <base/files/scoped_temp_dir.h> 28 #include <base/memory/ptr_util.h> 29 #include <base/strings/string_number_conversions.h> 30 #include <base/strings/string_util.h> 31 #include <base/strings/stringprintf.h> 32 #include <base/time/time.h> 33 #include <brillo/bind_lambda.h> 34 #include <brillo/message_loops/fake_message_loop.h> 35 #include <brillo/message_loops/message_loop.h> 36 #include <brillo/message_loops/message_loop_utils.h> 37 #include <gtest/gtest.h> 38 39 #include "update_engine/common/action_pipe.h" 40 #include "update_engine/common/constants.h" 41 #include "update_engine/common/fake_prefs.h" 42 #include "update_engine/common/hash_calculator.h" 43 #include "update_engine/common/mock_http_fetcher.h" 44 #include "update_engine/common/platform_constants.h" 45 #include "update_engine/common/prefs.h" 46 #include "update_engine/common/test_utils.h" 47 #include "update_engine/fake_system_state.h" 48 #include "update_engine/metrics_reporter_interface.h" 49 #include "update_engine/mock_connection_manager.h" 50 #include "update_engine/mock_payload_state.h" 51 #include "update_engine/omaha_request_params.h" 52 53 using base::Time; 54 using base::TimeDelta; 55 using std::string; 56 using std::vector; 57 using testing::AllOf; 58 using testing::AnyNumber; 59 using testing::DoAll; 60 using testing::Ge; 61 using testing::Le; 62 using testing::NiceMock; 63 using testing::Return; 64 using testing::ReturnPointee; 65 using testing::SaveArg; 66 using testing::SetArgPointee; 67 using testing::_; 68 69 namespace { 70 71 const char kTestAppId[] = "test-app-id"; 72 const char kTestAppId2[] = "test-app2-id"; 73 74 // This is a helper struct to allow unit tests build an update response with the 75 // values they care about. 76 struct FakeUpdateResponse { 77 string GetNoUpdateResponse() const { 78 string entity_str; 79 if (include_entity) 80 entity_str = "<!DOCTYPE response [<!ENTITY CrOS \"ChromeOS\">]>"; 81 return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + entity_str + 82 "<response protocol=\"3.0\">" 83 "<daystart elapsed_seconds=\"100\"/>" 84 "<app appid=\"" + 85 app_id + "\" " + 86 (include_cohorts 87 ? "cohort=\"" + cohort + "\" cohorthint=\"" + cohorthint + 88 "\" cohortname=\"" + cohortname + "\" " 89 : "") + 90 " status=\"ok\">" 91 "<ping status=\"ok\"/>" 92 "<updatecheck status=\"noupdate\"/></app>" + 93 (multi_app_no_update 94 ? "<app appid=\"" + app_id2 + 95 "\"><updatecheck status=\"noupdate\"/></app>" 96 : "") + 97 "</response>"; 98 } 99 100 string GetUpdateResponse() const { 101 return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response " 102 "protocol=\"3.0\">" 103 "<daystart elapsed_seconds=\"100\"" + 104 (elapsed_days.empty() ? "" 105 : (" elapsed_days=\"" + elapsed_days + "\"")) + 106 "/>" 107 "<app appid=\"" + 108 app_id + "\" " + 109 (include_cohorts 110 ? "cohort=\"" + cohort + "\" cohorthint=\"" + cohorthint + 111 "\" cohortname=\"" + cohortname + "\" " 112 : "") + 113 " status=\"ok\">" 114 "<ping status=\"ok\"/><updatecheck status=\"ok\">" 115 "<urls><url codebase=\"" + 116 codebase + 117 "\"/></urls>" 118 "<manifest version=\"" + 119 version + 120 "\">" 121 "<packages><package hash=\"not-used\" name=\"" + 122 filename + "\" size=\"" + base::Int64ToString(size) + 123 "\" hash_sha256=\"" + hash + "\"/>" + 124 (multi_package ? "<package name=\"package2\" size=\"222\" " 125 "hash_sha256=\"hash2\"/>" 126 : "") + 127 "</packages>" 128 "<actions><action event=\"postinstall\" MetadataSize=\"11" + 129 (multi_package ? ":22" : "") + "\" ChromeOSVersion=\"" + version + 130 "\" MoreInfo=\"" + more_info_url + "\" Prompt=\"" + prompt + 131 "\" " 132 "IsDelta=\"true\" " 133 "IsDeltaPayload=\"true" + 134 (multi_package ? ":false" : "") + 135 "\" " 136 "MaxDaysToScatter=\"" + 137 max_days_to_scatter + 138 "\" " 139 "sha256=\"not-used\" " 140 "needsadmin=\"" + 141 needsadmin + "\" " + 142 (deadline.empty() ? "" : ("deadline=\"" + deadline + "\" ")) + 143 (disable_p2p_for_downloading ? "DisableP2PForDownloading=\"true\" " 144 : "") + 145 (disable_p2p_for_sharing ? "DisableP2PForSharing=\"true\" " : "") + 146 "/></actions></manifest></updatecheck></app>" + 147 (multi_app 148 ? "<app appid=\"" + app_id2 + "\"" + 149 (include_cohorts ? " cohort=\"cohort2\"" : "") + 150 "><updatecheck status=\"ok\"><urls><url codebase=\"" + 151 codebase2 + "\"/></urls><manifest version=\"" + version2 + 152 "\"><packages>" 153 "<package name=\"package3\" size=\"333\" " 154 "hash_sha256=\"hash3\"/></packages>" 155 "<actions><action event=\"postinstall\" " + 156 (multi_app_self_update 157 ? "noupdate=\"true\" IsDeltaPayload=\"true\" " 158 : "IsDeltaPayload=\"false\" ") + 159 "MetadataSize=\"33\"/></actions>" 160 "</manifest></updatecheck></app>" 161 : "") + 162 (multi_app_no_update 163 ? "<app><updatecheck status=\"noupdate\"/></app>" 164 : "") + 165 "</response>"; 166 } 167 168 // Return the payload URL, which is split in two fields in the XML response. 169 string GetPayloadUrl() { 170 return codebase + filename; 171 } 172 173 string app_id = kTestAppId; 174 string app_id2 = kTestAppId2; 175 string version = "1.2.3.4"; 176 string version2 = "2.3.4.5"; 177 string more_info_url = "http://more/info"; 178 string prompt = "true"; 179 string codebase = "http://code/base/"; 180 string codebase2 = "http://code/base/2/"; 181 string filename = "file.signed"; 182 string hash = "4841534831323334"; 183 string needsadmin = "false"; 184 uint64_t size = 123; 185 string deadline = ""; 186 string max_days_to_scatter = "7"; 187 string elapsed_days = "42"; 188 189 // P2P setting defaults to allowed. 190 bool disable_p2p_for_downloading = false; 191 bool disable_p2p_for_sharing = false; 192 193 // Omaha cohorts settings. 194 bool include_cohorts = false; 195 string cohort = ""; 196 string cohorthint = ""; 197 string cohortname = ""; 198 199 // Whether to include the CrOS <!ENTITY> in the XML response. 200 bool include_entity = false; 201 202 // Whether to include more than one app. 203 bool multi_app = false; 204 // Whether to include an app with noupdate="true". 205 bool multi_app_self_update = false; 206 // Whether to include an additional app with status="noupdate". 207 bool multi_app_no_update = false; 208 // Whether to include more than one package in an app. 209 bool multi_package = false; 210 }; 211 212 } // namespace 213 214 namespace chromeos_update_engine { 215 216 class OmahaRequestActionTest : public ::testing::Test { 217 protected: 218 void SetUp() override { 219 fake_system_state_.set_request_params(&request_params_); 220 fake_system_state_.set_prefs(&fake_prefs_); 221 } 222 223 // Returns true iff an output response was obtained from the 224 // OmahaRequestAction. |prefs| may be null, in which case a local MockPrefs 225 // is used. |payload_state| may be null, in which case a local mock is used. 226 // |p2p_manager| may be null, in which case a local mock is used. 227 // |connection_manager| may be null, in which case a local mock is used. 228 // out_response may be null. If |fail_http_response_code| is non-negative, 229 // the transfer will fail with that code. |ping_only| is passed through to the 230 // OmahaRequestAction constructor. out_post_data may be null; if non-null, the 231 // post-data received by the mock HttpFetcher is returned. 232 // 233 // The |expected_check_result|, |expected_check_reaction| and 234 // |expected_error_code| parameters are for checking expectations 235 // about reporting UpdateEngine.Check.{Result,Reaction,DownloadError} 236 // UMA statistics. Use the appropriate ::kUnset value to specify that 237 // the given metric should not be reported. 238 bool TestUpdateCheck(OmahaRequestParams* request_params, 239 const string& http_response, 240 int fail_http_response_code, 241 bool ping_only, 242 ErrorCode expected_code, 243 metrics::CheckResult expected_check_result, 244 metrics::CheckReaction expected_check_reaction, 245 metrics::DownloadErrorCode expected_download_error_code, 246 OmahaResponse* out_response, 247 brillo::Blob* out_post_data); 248 249 // Runs and checks a ping test. |ping_only| indicates whether it should send 250 // only a ping or also an updatecheck. 251 void PingTest(bool ping_only); 252 253 // InstallDate test helper function. 254 bool InstallDateParseHelper(const string &elapsed_days, 255 OmahaResponse *response); 256 257 // P2P test helper function. 258 void P2PTest( 259 bool initial_allow_p2p_for_downloading, 260 bool initial_allow_p2p_for_sharing, 261 bool omaha_disable_p2p_for_downloading, 262 bool omaha_disable_p2p_for_sharing, 263 bool payload_state_allow_p2p_attempt, 264 bool expect_p2p_client_lookup, 265 const string& p2p_client_result_url, 266 bool expected_allow_p2p_for_downloading, 267 bool expected_allow_p2p_for_sharing, 268 const string& expected_p2p_url); 269 270 FakeSystemState fake_system_state_; 271 FakeUpdateResponse fake_update_response_; 272 273 // By default, all tests use these objects unless they replace them in the 274 // fake_system_state_. 275 OmahaRequestParams request_params_ = OmahaRequestParams{ 276 &fake_system_state_, 277 constants::kOmahaPlatformName, 278 OmahaRequestParams::kOsVersion, 279 "service_pack", 280 "x86-generic", 281 kTestAppId, 282 "0.1.0.0", 283 "en-US", 284 "unittest", 285 "OEM MODEL 09235 7471", 286 "ChromeOSFirmware.1.0", 287 "0X0A1", 288 false, // delta okay 289 false, // interactive 290 "http://url", 291 ""}; // target_version_prefix 292 293 FakePrefs fake_prefs_; 294 }; 295 296 namespace { 297 class OmahaRequestActionTestProcessorDelegate : public ActionProcessorDelegate { 298 public: 299 OmahaRequestActionTestProcessorDelegate() 300 : expected_code_(ErrorCode::kSuccess) {} 301 ~OmahaRequestActionTestProcessorDelegate() override { 302 } 303 void ProcessingDone(const ActionProcessor* processor, 304 ErrorCode code) override { 305 brillo::MessageLoop::current()->BreakLoop(); 306 } 307 308 void ActionCompleted(ActionProcessor* processor, 309 AbstractAction* action, 310 ErrorCode code) override { 311 // make sure actions always succeed 312 if (action->Type() == OmahaRequestAction::StaticType()) 313 EXPECT_EQ(expected_code_, code); 314 else 315 EXPECT_EQ(ErrorCode::kSuccess, code); 316 } 317 ErrorCode expected_code_; 318 }; 319 } // namespace 320 321 class OutputObjectCollectorAction; 322 323 template<> 324 class ActionTraits<OutputObjectCollectorAction> { 325 public: 326 // Does not take an object for input 327 typedef OmahaResponse InputObjectType; 328 // On success, puts the output path on output 329 typedef NoneType OutputObjectType; 330 }; 331 332 class OutputObjectCollectorAction : public Action<OutputObjectCollectorAction> { 333 public: 334 OutputObjectCollectorAction() : has_input_object_(false) {} 335 void PerformAction() { 336 // copy input object 337 has_input_object_ = HasInputObject(); 338 if (has_input_object_) 339 omaha_response_ = GetInputObject(); 340 processor_->ActionComplete(this, ErrorCode::kSuccess); 341 } 342 // Should never be called 343 void TerminateProcessing() { 344 CHECK(false); 345 } 346 // Debugging/logging 347 static string StaticType() { 348 return "OutputObjectCollectorAction"; 349 } 350 string Type() const { return StaticType(); } 351 using InputObjectType = 352 ActionTraits<OutputObjectCollectorAction>::InputObjectType; 353 using OutputObjectType = 354 ActionTraits<OutputObjectCollectorAction>::OutputObjectType; 355 bool has_input_object_; 356 OmahaResponse omaha_response_; 357 }; 358 359 bool OmahaRequestActionTest::TestUpdateCheck( 360 OmahaRequestParams* request_params, 361 const string& http_response, 362 int fail_http_response_code, 363 bool ping_only, 364 ErrorCode expected_code, 365 metrics::CheckResult expected_check_result, 366 metrics::CheckReaction expected_check_reaction, 367 metrics::DownloadErrorCode expected_download_error_code, 368 OmahaResponse* out_response, 369 brillo::Blob* out_post_data) { 370 brillo::FakeMessageLoop loop(nullptr); 371 loop.SetAsCurrent(); 372 MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(), 373 http_response.size(), 374 nullptr); 375 if (fail_http_response_code >= 0) { 376 fetcher->FailTransfer(fail_http_response_code); 377 } 378 if (request_params) 379 fake_system_state_.set_request_params(request_params); 380 OmahaRequestAction action(&fake_system_state_, 381 nullptr, 382 base::WrapUnique(fetcher), 383 ping_only); 384 OmahaRequestActionTestProcessorDelegate delegate; 385 delegate.expected_code_ = expected_code; 386 387 ActionProcessor processor; 388 processor.set_delegate(&delegate); 389 processor.EnqueueAction(&action); 390 391 OutputObjectCollectorAction collector_action; 392 BondActions(&action, &collector_action); 393 processor.EnqueueAction(&collector_action); 394 395 EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(), 396 ReportUpdateCheckMetrics(_, _, _, _)) 397 .Times(AnyNumber()); 398 399 EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(), 400 ReportUpdateCheckMetrics(_, 401 expected_check_result, 402 expected_check_reaction, 403 expected_download_error_code)) 404 .Times(ping_only ? 0 : 1); 405 406 loop.PostTask(base::Bind( 407 [](ActionProcessor* processor) { processor->StartProcessing(); }, 408 base::Unretained(&processor))); 409 loop.Run(); 410 EXPECT_FALSE(loop.PendingTasks()); 411 if (collector_action.has_input_object_ && out_response) 412 *out_response = collector_action.omaha_response_; 413 if (out_post_data) 414 *out_post_data = fetcher->post_data(); 415 return collector_action.has_input_object_; 416 } 417 418 // Tests Event requests -- they should always succeed. |out_post_data| 419 // may be null; if non-null, the post-data received by the mock 420 // HttpFetcher is returned. 421 void TestEvent(OmahaRequestParams params, 422 OmahaEvent* event, 423 const string& http_response, 424 brillo::Blob* out_post_data) { 425 brillo::FakeMessageLoop loop(nullptr); 426 loop.SetAsCurrent(); 427 MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(), 428 http_response.size(), 429 nullptr); 430 FakeSystemState fake_system_state; 431 fake_system_state.set_request_params(¶ms); 432 OmahaRequestAction action(&fake_system_state, 433 event, 434 base::WrapUnique(fetcher), 435 false); 436 OmahaRequestActionTestProcessorDelegate delegate; 437 ActionProcessor processor; 438 processor.set_delegate(&delegate); 439 processor.EnqueueAction(&action); 440 441 loop.PostTask(base::Bind( 442 [](ActionProcessor* processor) { processor->StartProcessing(); }, 443 base::Unretained(&processor))); 444 loop.Run(); 445 EXPECT_FALSE(loop.PendingTasks()); 446 447 if (out_post_data) 448 *out_post_data = fetcher->post_data(); 449 } 450 451 TEST_F(OmahaRequestActionTest, RejectEntities) { 452 OmahaResponse response; 453 fake_update_response_.include_entity = true; 454 ASSERT_FALSE( 455 TestUpdateCheck(nullptr, // request_params 456 fake_update_response_.GetNoUpdateResponse(), 457 -1, 458 false, // ping_only 459 ErrorCode::kOmahaRequestXMLHasEntityDecl, 460 metrics::CheckResult::kParsingError, 461 metrics::CheckReaction::kUnset, 462 metrics::DownloadErrorCode::kUnset, 463 &response, 464 nullptr)); 465 EXPECT_FALSE(response.update_exists); 466 } 467 468 TEST_F(OmahaRequestActionTest, NoUpdateTest) { 469 OmahaResponse response; 470 ASSERT_TRUE( 471 TestUpdateCheck(nullptr, // request_params 472 fake_update_response_.GetNoUpdateResponse(), 473 -1, 474 false, // ping_only 475 ErrorCode::kSuccess, 476 metrics::CheckResult::kNoUpdateAvailable, 477 metrics::CheckReaction::kUnset, 478 metrics::DownloadErrorCode::kUnset, 479 &response, 480 nullptr)); 481 EXPECT_FALSE(response.update_exists); 482 } 483 484 TEST_F(OmahaRequestActionTest, MultiAppNoUpdateTest) { 485 OmahaResponse response; 486 fake_update_response_.multi_app_no_update = true; 487 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 488 fake_update_response_.GetNoUpdateResponse(), 489 -1, 490 false, // ping_only 491 ErrorCode::kSuccess, 492 metrics::CheckResult::kNoUpdateAvailable, 493 metrics::CheckReaction::kUnset, 494 metrics::DownloadErrorCode::kUnset, 495 &response, 496 nullptr)); 497 EXPECT_FALSE(response.update_exists); 498 } 499 500 TEST_F(OmahaRequestActionTest, MultiAppNoPartialUpdateTest) { 501 OmahaResponse response; 502 fake_update_response_.multi_app_no_update = true; 503 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 504 fake_update_response_.GetUpdateResponse(), 505 -1, 506 false, // ping_only 507 ErrorCode::kSuccess, 508 metrics::CheckResult::kNoUpdateAvailable, 509 metrics::CheckReaction::kUnset, 510 metrics::DownloadErrorCode::kUnset, 511 &response, 512 nullptr)); 513 EXPECT_FALSE(response.update_exists); 514 } 515 516 TEST_F(OmahaRequestActionTest, NoSelfUpdateTest) { 517 OmahaResponse response; 518 ASSERT_TRUE(TestUpdateCheck( 519 nullptr, // request_params 520 "<response><app><updatecheck status=\"ok\"><manifest><actions><action " 521 "event=\"postinstall\" noupdate=\"true\"/></actions>" 522 "</manifest></updatecheck></app></response>", 523 -1, 524 false, // ping_only 525 ErrorCode::kSuccess, 526 metrics::CheckResult::kNoUpdateAvailable, 527 metrics::CheckReaction::kUnset, 528 metrics::DownloadErrorCode::kUnset, 529 &response, 530 nullptr)); 531 EXPECT_FALSE(response.update_exists); 532 } 533 534 // Test that all the values in the response are parsed in a normal update 535 // response. 536 TEST_F(OmahaRequestActionTest, ValidUpdateTest) { 537 OmahaResponse response; 538 fake_update_response_.deadline = "20101020"; 539 ASSERT_TRUE( 540 TestUpdateCheck(nullptr, // request_params 541 fake_update_response_.GetUpdateResponse(), 542 -1, 543 false, // ping_only 544 ErrorCode::kSuccess, 545 metrics::CheckResult::kUpdateAvailable, 546 metrics::CheckReaction::kUpdating, 547 metrics::DownloadErrorCode::kUnset, 548 &response, 549 nullptr)); 550 EXPECT_TRUE(response.update_exists); 551 EXPECT_EQ(fake_update_response_.version, response.version); 552 EXPECT_EQ("", response.system_version); 553 EXPECT_EQ(fake_update_response_.GetPayloadUrl(), 554 response.packages[0].payload_urls[0]); 555 EXPECT_EQ(fake_update_response_.more_info_url, response.more_info_url); 556 EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash); 557 EXPECT_EQ(fake_update_response_.size, response.packages[0].size); 558 EXPECT_EQ(true, response.packages[0].is_delta); 559 EXPECT_EQ(fake_update_response_.prompt == "true", response.prompt); 560 EXPECT_EQ(fake_update_response_.deadline, response.deadline); 561 // Omaha cohort attributes are not set in the response, so they should not be 562 // persisted. 563 EXPECT_FALSE(fake_prefs_.Exists(kPrefsOmahaCohort)); 564 EXPECT_FALSE(fake_prefs_.Exists(kPrefsOmahaCohortHint)); 565 EXPECT_FALSE(fake_prefs_.Exists(kPrefsOmahaCohortName)); 566 } 567 568 TEST_F(OmahaRequestActionTest, MultiPackageUpdateTest) { 569 OmahaResponse response; 570 fake_update_response_.multi_package = true; 571 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 572 fake_update_response_.GetUpdateResponse(), 573 -1, 574 false, // ping_only 575 ErrorCode::kSuccess, 576 metrics::CheckResult::kUpdateAvailable, 577 metrics::CheckReaction::kUpdating, 578 metrics::DownloadErrorCode::kUnset, 579 &response, 580 nullptr)); 581 EXPECT_TRUE(response.update_exists); 582 EXPECT_EQ(fake_update_response_.version, response.version); 583 EXPECT_EQ(fake_update_response_.GetPayloadUrl(), 584 response.packages[0].payload_urls[0]); 585 EXPECT_EQ(fake_update_response_.codebase + "package2", 586 response.packages[1].payload_urls[0]); 587 EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash); 588 EXPECT_EQ(fake_update_response_.size, response.packages[0].size); 589 EXPECT_EQ(true, response.packages[0].is_delta); 590 EXPECT_EQ(11u, response.packages[0].metadata_size); 591 ASSERT_EQ(2u, response.packages.size()); 592 EXPECT_EQ(string("hash2"), response.packages[1].hash); 593 EXPECT_EQ(222u, response.packages[1].size); 594 EXPECT_EQ(22u, response.packages[1].metadata_size); 595 EXPECT_EQ(false, response.packages[1].is_delta); 596 } 597 598 TEST_F(OmahaRequestActionTest, MultiAppUpdateTest) { 599 OmahaResponse response; 600 fake_update_response_.multi_app = true; 601 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 602 fake_update_response_.GetUpdateResponse(), 603 -1, 604 false, // ping_only 605 ErrorCode::kSuccess, 606 metrics::CheckResult::kUpdateAvailable, 607 metrics::CheckReaction::kUpdating, 608 metrics::DownloadErrorCode::kUnset, 609 &response, 610 nullptr)); 611 EXPECT_TRUE(response.update_exists); 612 EXPECT_EQ(fake_update_response_.version, response.version); 613 EXPECT_EQ(fake_update_response_.GetPayloadUrl(), 614 response.packages[0].payload_urls[0]); 615 EXPECT_EQ(fake_update_response_.codebase2 + "package3", 616 response.packages[1].payload_urls[0]); 617 EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash); 618 EXPECT_EQ(fake_update_response_.size, response.packages[0].size); 619 EXPECT_EQ(11u, response.packages[0].metadata_size); 620 EXPECT_EQ(true, response.packages[0].is_delta); 621 ASSERT_EQ(2u, response.packages.size()); 622 EXPECT_EQ(string("hash3"), response.packages[1].hash); 623 EXPECT_EQ(333u, response.packages[1].size); 624 EXPECT_EQ(33u, response.packages[1].metadata_size); 625 EXPECT_EQ(false, response.packages[1].is_delta); 626 } 627 628 TEST_F(OmahaRequestActionTest, MultiAppAndSystemUpdateTest) { 629 OmahaResponse response; 630 fake_update_response_.multi_app = true; 631 // trigger the lining up of the app and system versions 632 request_params_.set_system_app_id(fake_update_response_.app_id2); 633 634 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 635 fake_update_response_.GetUpdateResponse(), 636 -1, 637 false, // ping_only 638 ErrorCode::kSuccess, 639 metrics::CheckResult::kUpdateAvailable, 640 metrics::CheckReaction::kUpdating, 641 metrics::DownloadErrorCode::kUnset, 642 &response, 643 nullptr)); 644 EXPECT_TRUE(response.update_exists); 645 EXPECT_EQ(fake_update_response_.version, response.version); 646 EXPECT_EQ(fake_update_response_.version2, response.system_version); 647 EXPECT_EQ(fake_update_response_.GetPayloadUrl(), 648 response.packages[0].payload_urls[0]); 649 EXPECT_EQ(fake_update_response_.codebase2 + "package3", 650 response.packages[1].payload_urls[0]); 651 EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash); 652 EXPECT_EQ(fake_update_response_.size, response.packages[0].size); 653 EXPECT_EQ(11u, response.packages[0].metadata_size); 654 EXPECT_EQ(true, response.packages[0].is_delta); 655 ASSERT_EQ(2u, response.packages.size()); 656 EXPECT_EQ(string("hash3"), response.packages[1].hash); 657 EXPECT_EQ(333u, response.packages[1].size); 658 EXPECT_EQ(33u, response.packages[1].metadata_size); 659 EXPECT_EQ(false, response.packages[1].is_delta); 660 } 661 662 TEST_F(OmahaRequestActionTest, MultiAppPartialUpdateTest) { 663 OmahaResponse response; 664 fake_update_response_.multi_app = true; 665 fake_update_response_.multi_app_self_update = true; 666 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 667 fake_update_response_.GetUpdateResponse(), 668 -1, 669 false, // ping_only 670 ErrorCode::kSuccess, 671 metrics::CheckResult::kUpdateAvailable, 672 metrics::CheckReaction::kUpdating, 673 metrics::DownloadErrorCode::kUnset, 674 &response, 675 nullptr)); 676 EXPECT_TRUE(response.update_exists); 677 EXPECT_EQ(fake_update_response_.version, response.version); 678 EXPECT_EQ("", response.system_version); 679 EXPECT_EQ(fake_update_response_.GetPayloadUrl(), 680 response.packages[0].payload_urls[0]); 681 EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash); 682 EXPECT_EQ(fake_update_response_.size, response.packages[0].size); 683 EXPECT_EQ(11u, response.packages[0].metadata_size); 684 ASSERT_EQ(2u, response.packages.size()); 685 EXPECT_EQ(string("hash3"), response.packages[1].hash); 686 EXPECT_EQ(333u, response.packages[1].size); 687 EXPECT_EQ(33u, response.packages[1].metadata_size); 688 EXPECT_EQ(true, response.packages[1].is_delta); 689 } 690 691 TEST_F(OmahaRequestActionTest, MultiAppMultiPackageUpdateTest) { 692 OmahaResponse response; 693 fake_update_response_.multi_app = true; 694 fake_update_response_.multi_package = true; 695 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 696 fake_update_response_.GetUpdateResponse(), 697 -1, 698 false, // ping_only 699 ErrorCode::kSuccess, 700 metrics::CheckResult::kUpdateAvailable, 701 metrics::CheckReaction::kUpdating, 702 metrics::DownloadErrorCode::kUnset, 703 &response, 704 nullptr)); 705 EXPECT_TRUE(response.update_exists); 706 EXPECT_EQ(fake_update_response_.version, response.version); 707 EXPECT_EQ("", response.system_version); 708 EXPECT_EQ(fake_update_response_.GetPayloadUrl(), 709 response.packages[0].payload_urls[0]); 710 EXPECT_EQ(fake_update_response_.codebase + "package2", 711 response.packages[1].payload_urls[0]); 712 EXPECT_EQ(fake_update_response_.codebase2 + "package3", 713 response.packages[2].payload_urls[0]); 714 EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash); 715 EXPECT_EQ(fake_update_response_.size, response.packages[0].size); 716 EXPECT_EQ(11u, response.packages[0].metadata_size); 717 EXPECT_EQ(true, response.packages[0].is_delta); 718 ASSERT_EQ(3u, response.packages.size()); 719 EXPECT_EQ(string("hash2"), response.packages[1].hash); 720 EXPECT_EQ(222u, response.packages[1].size); 721 EXPECT_EQ(22u, response.packages[1].metadata_size); 722 EXPECT_EQ(false, response.packages[1].is_delta); 723 EXPECT_EQ(string("hash3"), response.packages[2].hash); 724 EXPECT_EQ(333u, response.packages[2].size); 725 EXPECT_EQ(33u, response.packages[2].metadata_size); 726 EXPECT_EQ(false, response.packages[2].is_delta); 727 } 728 729 TEST_F(OmahaRequestActionTest, ExtraHeadersSentTest) { 730 const string http_response = "<?xml invalid response"; 731 request_params_.set_interactive(true); 732 733 brillo::FakeMessageLoop loop(nullptr); 734 loop.SetAsCurrent(); 735 736 MockHttpFetcher* fetcher = 737 new MockHttpFetcher(http_response.data(), http_response.size(), nullptr); 738 OmahaRequestAction action(&fake_system_state_, nullptr, 739 base::WrapUnique(fetcher), false); 740 ActionProcessor processor; 741 processor.EnqueueAction(&action); 742 743 loop.PostTask(base::Bind( 744 [](ActionProcessor* processor) { processor->StartProcessing(); }, 745 base::Unretained(&processor))); 746 loop.Run(); 747 EXPECT_FALSE(loop.PendingTasks()); 748 749 // Check that the headers were set in the fetcher during the action. Note that 750 // we set this request as "interactive". 751 EXPECT_EQ("fg", fetcher->GetHeader("X-GoogleUpdate-Interactivity")); 752 EXPECT_EQ(kTestAppId, fetcher->GetHeader("X-GoogleUpdate-AppId")); 753 EXPECT_NE("", fetcher->GetHeader("X-GoogleUpdate-Updater")); 754 } 755 756 TEST_F(OmahaRequestActionTest, ValidUpdateBlockedByConnection) { 757 OmahaResponse response; 758 // Set up a connection manager that doesn't allow a valid update over 759 // the current ethernet connection. 760 MockConnectionManager mock_cm; 761 fake_system_state_.set_connection_manager(&mock_cm); 762 763 EXPECT_CALL(mock_cm, GetConnectionProperties(_, _)) 764 .WillRepeatedly( 765 DoAll(SetArgPointee<0>(ConnectionType::kEthernet), 766 SetArgPointee<1>(ConnectionTethering::kUnknown), 767 Return(true))); 768 EXPECT_CALL(mock_cm, IsUpdateAllowedOver(ConnectionType::kEthernet, _)) 769 .WillRepeatedly(Return(false)); 770 771 ASSERT_FALSE( 772 TestUpdateCheck(nullptr, // request_params 773 fake_update_response_.GetUpdateResponse(), 774 -1, 775 false, // ping_only 776 ErrorCode::kOmahaUpdateIgnoredPerPolicy, 777 metrics::CheckResult::kUpdateAvailable, 778 metrics::CheckReaction::kIgnored, 779 metrics::DownloadErrorCode::kUnset, 780 &response, 781 nullptr)); 782 EXPECT_FALSE(response.update_exists); 783 } 784 785 TEST_F(OmahaRequestActionTest, ValidUpdateBlockedByRollback) { 786 string rollback_version = "1234.0.0"; 787 OmahaResponse response; 788 789 MockPayloadState mock_payload_state; 790 fake_system_state_.set_payload_state(&mock_payload_state); 791 792 EXPECT_CALL(mock_payload_state, GetRollbackVersion()) 793 .WillRepeatedly(Return(rollback_version)); 794 795 fake_update_response_.version = rollback_version; 796 ASSERT_FALSE( 797 TestUpdateCheck(nullptr, // request_params 798 fake_update_response_.GetUpdateResponse(), 799 -1, 800 false, // ping_only 801 ErrorCode::kOmahaUpdateIgnoredPerPolicy, 802 metrics::CheckResult::kUpdateAvailable, 803 metrics::CheckReaction::kIgnored, 804 metrics::DownloadErrorCode::kUnset, 805 &response, 806 nullptr)); 807 EXPECT_FALSE(response.update_exists); 808 } 809 810 // Verify that update checks called during OOBE will only try to download 811 // an update if the response includes a non-empty deadline field. 812 TEST_F(OmahaRequestActionTest, SkipNonCriticalUpdatesBeforeOOBE) { 813 OmahaResponse response; 814 815 // TODO(senj): set better default value for metrics::checkresult in 816 // OmahaRequestAction::ActionCompleted. 817 fake_system_state_.fake_hardware()->UnsetIsOOBEComplete(); 818 ASSERT_FALSE(TestUpdateCheck(nullptr, // request_params 819 fake_update_response_.GetUpdateResponse(), 820 -1, 821 false, // ping_only 822 ErrorCode::kNonCriticalUpdateInOOBE, 823 metrics::CheckResult::kParsingError, 824 metrics::CheckReaction::kUnset, 825 metrics::DownloadErrorCode::kUnset, 826 &response, 827 nullptr)); 828 EXPECT_FALSE(response.update_exists); 829 830 // The IsOOBEComplete() value is ignored when the OOBE flow is not enabled. 831 fake_system_state_.fake_hardware()->SetIsOOBEEnabled(false); 832 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 833 fake_update_response_.GetUpdateResponse(), 834 -1, 835 false, // ping_only 836 ErrorCode::kSuccess, 837 metrics::CheckResult::kUpdateAvailable, 838 metrics::CheckReaction::kUpdating, 839 metrics::DownloadErrorCode::kUnset, 840 &response, 841 nullptr)); 842 EXPECT_TRUE(response.update_exists); 843 fake_system_state_.fake_hardware()->SetIsOOBEEnabled(true); 844 845 // The payload is applied when a deadline was set in the response. 846 fake_update_response_.deadline = "20101020"; 847 ASSERT_TRUE( 848 TestUpdateCheck(nullptr, // request_params 849 fake_update_response_.GetUpdateResponse(), 850 -1, 851 false, // ping_only 852 ErrorCode::kSuccess, 853 metrics::CheckResult::kUpdateAvailable, 854 metrics::CheckReaction::kUpdating, 855 metrics::DownloadErrorCode::kUnset, 856 &response, 857 nullptr)); 858 EXPECT_TRUE(response.update_exists); 859 } 860 861 TEST_F(OmahaRequestActionTest, WallClockBasedWaitAloneCausesScattering) { 862 OmahaResponse response; 863 OmahaRequestParams params = request_params_; 864 params.set_wall_clock_based_wait_enabled(true); 865 params.set_update_check_count_wait_enabled(false); 866 params.set_waiting_period(TimeDelta::FromDays(2)); 867 868 ASSERT_FALSE( 869 TestUpdateCheck(¶ms, 870 fake_update_response_.GetUpdateResponse(), 871 -1, 872 false, // ping_only 873 ErrorCode::kOmahaUpdateDeferredPerPolicy, 874 metrics::CheckResult::kUpdateAvailable, 875 metrics::CheckReaction::kDeferring, 876 metrics::DownloadErrorCode::kUnset, 877 &response, 878 nullptr)); 879 EXPECT_FALSE(response.update_exists); 880 881 // Verify if we are interactive check we don't defer. 882 params.set_interactive(true); 883 ASSERT_TRUE( 884 TestUpdateCheck(¶ms, 885 fake_update_response_.GetUpdateResponse(), 886 -1, 887 false, // ping_only 888 ErrorCode::kSuccess, 889 metrics::CheckResult::kUpdateAvailable, 890 metrics::CheckReaction::kUpdating, 891 metrics::DownloadErrorCode::kUnset, 892 &response, 893 nullptr)); 894 EXPECT_TRUE(response.update_exists); 895 } 896 897 TEST_F(OmahaRequestActionTest, NoWallClockBasedWaitCausesNoScattering) { 898 OmahaResponse response; 899 OmahaRequestParams params = request_params_; 900 params.set_wall_clock_based_wait_enabled(false); 901 params.set_waiting_period(TimeDelta::FromDays(2)); 902 903 params.set_update_check_count_wait_enabled(true); 904 params.set_min_update_checks_needed(1); 905 params.set_max_update_checks_allowed(8); 906 907 ASSERT_TRUE( 908 TestUpdateCheck(¶ms, 909 fake_update_response_.GetUpdateResponse(), 910 -1, 911 false, // ping_only 912 ErrorCode::kSuccess, 913 metrics::CheckResult::kUpdateAvailable, 914 metrics::CheckReaction::kUpdating, 915 metrics::DownloadErrorCode::kUnset, 916 &response, 917 nullptr)); 918 EXPECT_TRUE(response.update_exists); 919 } 920 921 TEST_F(OmahaRequestActionTest, ZeroMaxDaysToScatterCausesNoScattering) { 922 OmahaResponse response; 923 OmahaRequestParams params = request_params_; 924 params.set_wall_clock_based_wait_enabled(true); 925 params.set_waiting_period(TimeDelta::FromDays(2)); 926 927 params.set_update_check_count_wait_enabled(true); 928 params.set_min_update_checks_needed(1); 929 params.set_max_update_checks_allowed(8); 930 931 fake_update_response_.max_days_to_scatter = "0"; 932 ASSERT_TRUE( 933 TestUpdateCheck(¶ms, 934 fake_update_response_.GetUpdateResponse(), 935 -1, 936 false, // ping_only 937 ErrorCode::kSuccess, 938 metrics::CheckResult::kUpdateAvailable, 939 metrics::CheckReaction::kUpdating, 940 metrics::DownloadErrorCode::kUnset, 941 &response, 942 nullptr)); 943 EXPECT_TRUE(response.update_exists); 944 } 945 946 947 TEST_F(OmahaRequestActionTest, ZeroUpdateCheckCountCausesNoScattering) { 948 OmahaResponse response; 949 OmahaRequestParams params = request_params_; 950 params.set_wall_clock_based_wait_enabled(true); 951 params.set_waiting_period(TimeDelta()); 952 953 params.set_update_check_count_wait_enabled(true); 954 params.set_min_update_checks_needed(0); 955 params.set_max_update_checks_allowed(0); 956 957 ASSERT_TRUE(TestUpdateCheck( 958 ¶ms, 959 fake_update_response_.GetUpdateResponse(), 960 -1, 961 false, // ping_only 962 ErrorCode::kSuccess, 963 metrics::CheckResult::kUpdateAvailable, 964 metrics::CheckReaction::kUpdating, 965 metrics::DownloadErrorCode::kUnset, 966 &response, 967 nullptr)); 968 969 int64_t count; 970 ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateCheckCount, &count)); 971 ASSERT_EQ(count, 0); 972 EXPECT_TRUE(response.update_exists); 973 } 974 975 TEST_F(OmahaRequestActionTest, NonZeroUpdateCheckCountCausesScattering) { 976 OmahaResponse response; 977 OmahaRequestParams params = request_params_; 978 params.set_wall_clock_based_wait_enabled(true); 979 params.set_waiting_period(TimeDelta()); 980 981 params.set_update_check_count_wait_enabled(true); 982 params.set_min_update_checks_needed(1); 983 params.set_max_update_checks_allowed(8); 984 985 ASSERT_FALSE(TestUpdateCheck( 986 ¶ms, 987 fake_update_response_.GetUpdateResponse(), 988 -1, 989 false, // ping_only 990 ErrorCode::kOmahaUpdateDeferredPerPolicy, 991 metrics::CheckResult::kUpdateAvailable, 992 metrics::CheckReaction::kDeferring, 993 metrics::DownloadErrorCode::kUnset, 994 &response, 995 nullptr)); 996 997 int64_t count; 998 ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateCheckCount, &count)); 999 ASSERT_GT(count, 0); 1000 EXPECT_FALSE(response.update_exists); 1001 1002 // Verify if we are interactive check we don't defer. 1003 params.set_interactive(true); 1004 ASSERT_TRUE( 1005 TestUpdateCheck(¶ms, 1006 fake_update_response_.GetUpdateResponse(), 1007 -1, 1008 false, // ping_only 1009 ErrorCode::kSuccess, 1010 metrics::CheckResult::kUpdateAvailable, 1011 metrics::CheckReaction::kUpdating, 1012 metrics::DownloadErrorCode::kUnset, 1013 &response, 1014 nullptr)); 1015 EXPECT_TRUE(response.update_exists); 1016 } 1017 1018 TEST_F(OmahaRequestActionTest, ExistingUpdateCheckCountCausesScattering) { 1019 OmahaResponse response; 1020 OmahaRequestParams params = request_params_; 1021 params.set_wall_clock_based_wait_enabled(true); 1022 params.set_waiting_period(TimeDelta()); 1023 1024 params.set_update_check_count_wait_enabled(true); 1025 params.set_min_update_checks_needed(1); 1026 params.set_max_update_checks_allowed(8); 1027 1028 ASSERT_TRUE(fake_prefs_.SetInt64(kPrefsUpdateCheckCount, 5)); 1029 1030 ASSERT_FALSE(TestUpdateCheck( 1031 ¶ms, 1032 fake_update_response_.GetUpdateResponse(), 1033 -1, 1034 false, // ping_only 1035 ErrorCode::kOmahaUpdateDeferredPerPolicy, 1036 metrics::CheckResult::kUpdateAvailable, 1037 metrics::CheckReaction::kDeferring, 1038 metrics::DownloadErrorCode::kUnset, 1039 &response, 1040 nullptr)); 1041 1042 int64_t count; 1043 ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateCheckCount, &count)); 1044 // count remains the same, as the decrementing happens in update_attempter 1045 // which this test doesn't exercise. 1046 ASSERT_EQ(count, 5); 1047 EXPECT_FALSE(response.update_exists); 1048 1049 // Verify if we are interactive check we don't defer. 1050 params.set_interactive(true); 1051 ASSERT_TRUE( 1052 TestUpdateCheck(¶ms, 1053 fake_update_response_.GetUpdateResponse(), 1054 -1, 1055 false, // ping_only 1056 ErrorCode::kSuccess, 1057 metrics::CheckResult::kUpdateAvailable, 1058 metrics::CheckReaction::kUpdating, 1059 metrics::DownloadErrorCode::kUnset, 1060 &response, 1061 nullptr)); 1062 EXPECT_TRUE(response.update_exists); 1063 } 1064 1065 TEST_F(OmahaRequestActionTest, CohortsArePersisted) { 1066 OmahaResponse response; 1067 OmahaRequestParams params = request_params_; 1068 fake_update_response_.include_cohorts = true; 1069 fake_update_response_.cohort = "s/154454/8479665"; 1070 fake_update_response_.cohorthint = "please-put-me-on-beta"; 1071 fake_update_response_.cohortname = "stable"; 1072 1073 ASSERT_TRUE(TestUpdateCheck(¶ms, 1074 fake_update_response_.GetUpdateResponse(), 1075 -1, 1076 false, // ping_only 1077 ErrorCode::kSuccess, 1078 metrics::CheckResult::kUpdateAvailable, 1079 metrics::CheckReaction::kUpdating, 1080 metrics::DownloadErrorCode::kUnset, 1081 &response, 1082 nullptr)); 1083 1084 string value; 1085 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value)); 1086 EXPECT_EQ(fake_update_response_.cohort, value); 1087 1088 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value)); 1089 EXPECT_EQ(fake_update_response_.cohorthint, value); 1090 1091 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value)); 1092 EXPECT_EQ(fake_update_response_.cohortname, value); 1093 } 1094 1095 TEST_F(OmahaRequestActionTest, CohortsAreUpdated) { 1096 OmahaResponse response; 1097 OmahaRequestParams params = request_params_; 1098 EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohort, "old_value")); 1099 EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohortHint, "old_hint")); 1100 EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohortName, "old_name")); 1101 fake_update_response_.include_cohorts = true; 1102 fake_update_response_.cohort = "s/154454/8479665"; 1103 fake_update_response_.cohorthint = "please-put-me-on-beta"; 1104 fake_update_response_.cohortname = ""; 1105 1106 ASSERT_TRUE(TestUpdateCheck(¶ms, 1107 fake_update_response_.GetUpdateResponse(), 1108 -1, 1109 false, // ping_only 1110 ErrorCode::kSuccess, 1111 metrics::CheckResult::kUpdateAvailable, 1112 metrics::CheckReaction::kUpdating, 1113 metrics::DownloadErrorCode::kUnset, 1114 &response, 1115 nullptr)); 1116 1117 string value; 1118 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value)); 1119 EXPECT_EQ(fake_update_response_.cohort, value); 1120 1121 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value)); 1122 EXPECT_EQ(fake_update_response_.cohorthint, value); 1123 1124 EXPECT_FALSE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value)); 1125 } 1126 1127 TEST_F(OmahaRequestActionTest, CohortsAreNotModifiedWhenMissing) { 1128 OmahaResponse response; 1129 OmahaRequestParams params = request_params_; 1130 EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohort, "old_value")); 1131 1132 ASSERT_TRUE(TestUpdateCheck(¶ms, 1133 fake_update_response_.GetUpdateResponse(), 1134 -1, 1135 false, // ping_only 1136 ErrorCode::kSuccess, 1137 metrics::CheckResult::kUpdateAvailable, 1138 metrics::CheckReaction::kUpdating, 1139 metrics::DownloadErrorCode::kUnset, 1140 &response, 1141 nullptr)); 1142 1143 string value; 1144 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value)); 1145 EXPECT_EQ("old_value", value); 1146 1147 EXPECT_FALSE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value)); 1148 EXPECT_FALSE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value)); 1149 } 1150 1151 TEST_F(OmahaRequestActionTest, CohortsArePersistedWhenNoUpdate) { 1152 OmahaResponse response; 1153 OmahaRequestParams params = request_params_; 1154 fake_update_response_.include_cohorts = true; 1155 fake_update_response_.cohort = "s/154454/8479665"; 1156 fake_update_response_.cohorthint = "please-put-me-on-beta"; 1157 fake_update_response_.cohortname = "stable"; 1158 1159 ASSERT_TRUE(TestUpdateCheck(¶ms, 1160 fake_update_response_.GetNoUpdateResponse(), 1161 -1, 1162 false, // ping_only 1163 ErrorCode::kSuccess, 1164 metrics::CheckResult::kNoUpdateAvailable, 1165 metrics::CheckReaction::kUnset, 1166 metrics::DownloadErrorCode::kUnset, 1167 &response, 1168 nullptr)); 1169 1170 string value; 1171 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value)); 1172 EXPECT_EQ(fake_update_response_.cohort, value); 1173 1174 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value)); 1175 EXPECT_EQ(fake_update_response_.cohorthint, value); 1176 1177 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value)); 1178 EXPECT_EQ(fake_update_response_.cohortname, value); 1179 } 1180 1181 TEST_F(OmahaRequestActionTest, MultiAppCohortTest) { 1182 OmahaResponse response; 1183 OmahaRequestParams params = request_params_; 1184 fake_update_response_.multi_app = true; 1185 fake_update_response_.include_cohorts = true; 1186 fake_update_response_.cohort = "s/154454/8479665"; 1187 fake_update_response_.cohorthint = "please-put-me-on-beta"; 1188 fake_update_response_.cohortname = "stable"; 1189 1190 ASSERT_TRUE(TestUpdateCheck(¶ms, 1191 fake_update_response_.GetUpdateResponse(), 1192 -1, 1193 false, // ping_only 1194 ErrorCode::kSuccess, 1195 metrics::CheckResult::kUpdateAvailable, 1196 metrics::CheckReaction::kUpdating, 1197 metrics::DownloadErrorCode::kUnset, 1198 &response, 1199 nullptr)); 1200 1201 string value; 1202 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value)); 1203 EXPECT_EQ(fake_update_response_.cohort, value); 1204 1205 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value)); 1206 EXPECT_EQ(fake_update_response_.cohorthint, value); 1207 1208 EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value)); 1209 EXPECT_EQ(fake_update_response_.cohortname, value); 1210 } 1211 1212 TEST_F(OmahaRequestActionTest, NoOutputPipeTest) { 1213 const string http_response(fake_update_response_.GetNoUpdateResponse()); 1214 1215 brillo::FakeMessageLoop loop(nullptr); 1216 loop.SetAsCurrent(); 1217 1218 OmahaRequestParams params = request_params_; 1219 fake_system_state_.set_request_params(¶ms); 1220 OmahaRequestAction action( 1221 &fake_system_state_, 1222 nullptr, 1223 std::make_unique<MockHttpFetcher>(http_response.data(), 1224 http_response.size(), 1225 nullptr), 1226 false); 1227 OmahaRequestActionTestProcessorDelegate delegate; 1228 ActionProcessor processor; 1229 processor.set_delegate(&delegate); 1230 processor.EnqueueAction(&action); 1231 1232 loop.PostTask(base::Bind( 1233 [](ActionProcessor* processor) { processor->StartProcessing(); }, 1234 base::Unretained(&processor))); 1235 loop.Run(); 1236 EXPECT_FALSE(loop.PendingTasks()); 1237 EXPECT_FALSE(processor.IsRunning()); 1238 } 1239 1240 TEST_F(OmahaRequestActionTest, InvalidXmlTest) { 1241 OmahaResponse response; 1242 ASSERT_FALSE( 1243 TestUpdateCheck(nullptr, // request_params 1244 "invalid xml>", 1245 -1, 1246 false, // ping_only 1247 ErrorCode::kOmahaRequestXMLParseError, 1248 metrics::CheckResult::kParsingError, 1249 metrics::CheckReaction::kUnset, 1250 metrics::DownloadErrorCode::kUnset, 1251 &response, 1252 nullptr)); 1253 EXPECT_FALSE(response.update_exists); 1254 } 1255 1256 TEST_F(OmahaRequestActionTest, EmptyResponseTest) { 1257 OmahaResponse response; 1258 ASSERT_FALSE( 1259 TestUpdateCheck(nullptr, // request_params 1260 "", 1261 -1, 1262 false, // ping_only 1263 ErrorCode::kOmahaRequestEmptyResponseError, 1264 metrics::CheckResult::kParsingError, 1265 metrics::CheckReaction::kUnset, 1266 metrics::DownloadErrorCode::kUnset, 1267 &response, 1268 nullptr)); 1269 EXPECT_FALSE(response.update_exists); 1270 } 1271 1272 TEST_F(OmahaRequestActionTest, MissingStatusTest) { 1273 OmahaResponse response; 1274 ASSERT_FALSE(TestUpdateCheck( 1275 nullptr, // request_params 1276 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\">" 1277 "<daystart elapsed_seconds=\"100\"/>" 1278 "<app appid=\"foo\" status=\"ok\">" 1279 "<ping status=\"ok\"/>" 1280 "<updatecheck/></app></response>", 1281 -1, 1282 false, // ping_only 1283 ErrorCode::kOmahaResponseInvalid, 1284 metrics::CheckResult::kParsingError, 1285 metrics::CheckReaction::kUnset, 1286 metrics::DownloadErrorCode::kUnset, 1287 &response, 1288 nullptr)); 1289 EXPECT_FALSE(response.update_exists); 1290 } 1291 1292 TEST_F(OmahaRequestActionTest, InvalidStatusTest) { 1293 OmahaResponse response; 1294 ASSERT_FALSE(TestUpdateCheck( 1295 nullptr, // request_params 1296 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\">" 1297 "<daystart elapsed_seconds=\"100\"/>" 1298 "<app appid=\"foo\" status=\"ok\">" 1299 "<ping status=\"ok\"/>" 1300 "<updatecheck status=\"InvalidStatusTest\"/></app></response>", 1301 -1, 1302 false, // ping_only 1303 ErrorCode::kOmahaResponseInvalid, 1304 metrics::CheckResult::kParsingError, 1305 metrics::CheckReaction::kUnset, 1306 metrics::DownloadErrorCode::kUnset, 1307 &response, 1308 nullptr)); 1309 EXPECT_FALSE(response.update_exists); 1310 } 1311 1312 TEST_F(OmahaRequestActionTest, MissingNodesetTest) { 1313 OmahaResponse response; 1314 ASSERT_FALSE(TestUpdateCheck( 1315 nullptr, // request_params 1316 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\">" 1317 "<daystart elapsed_seconds=\"100\"/>" 1318 "<app appid=\"foo\" status=\"ok\">" 1319 "<ping status=\"ok\"/>" 1320 "</app></response>", 1321 -1, 1322 false, // ping_only 1323 ErrorCode::kOmahaResponseInvalid, 1324 metrics::CheckResult::kParsingError, 1325 metrics::CheckReaction::kUnset, 1326 metrics::DownloadErrorCode::kUnset, 1327 &response, 1328 nullptr)); 1329 EXPECT_FALSE(response.update_exists); 1330 } 1331 1332 TEST_F(OmahaRequestActionTest, MissingFieldTest) { 1333 string input_response = 1334 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\">" 1335 "<daystart elapsed_seconds=\"100\"/>" 1336 // the appid needs to match that in the request params 1337 "<app appid=\"" + 1338 fake_update_response_.app_id + 1339 "\" status=\"ok\">" 1340 "<updatecheck status=\"ok\">" 1341 "<urls><url codebase=\"http://missing/field/test/\"/></urls>" 1342 "<manifest version=\"10.2.3.4\">" 1343 "<packages><package hash=\"not-used\" name=\"f\" " 1344 "size=\"587\" hash_sha256=\"lkq34j5345\"/></packages>" 1345 "<actions><action event=\"postinstall\" " 1346 "ChromeOSVersion=\"10.2.3.4\" " 1347 "Prompt=\"false\" " 1348 "IsDelta=\"true\" " 1349 "IsDeltaPayload=\"false\" " 1350 "sha256=\"not-used\" " 1351 "needsadmin=\"true\" " 1352 "/></actions></manifest></updatecheck></app></response>"; 1353 LOG(INFO) << "Input Response = " << input_response; 1354 1355 OmahaResponse response; 1356 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 1357 input_response, 1358 -1, 1359 false, // ping_only 1360 ErrorCode::kSuccess, 1361 metrics::CheckResult::kUpdateAvailable, 1362 metrics::CheckReaction::kUpdating, 1363 metrics::DownloadErrorCode::kUnset, 1364 &response, 1365 nullptr)); 1366 EXPECT_TRUE(response.update_exists); 1367 EXPECT_EQ("10.2.3.4", response.version); 1368 EXPECT_EQ("http://missing/field/test/f", 1369 response.packages[0].payload_urls[0]); 1370 EXPECT_EQ("", response.more_info_url); 1371 EXPECT_EQ("lkq34j5345", response.packages[0].hash); 1372 EXPECT_EQ(587u, response.packages[0].size); 1373 EXPECT_FALSE(response.prompt); 1374 EXPECT_TRUE(response.deadline.empty()); 1375 } 1376 1377 namespace { 1378 class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate { 1379 public: 1380 void ProcessingStopped(const ActionProcessor* processor) { 1381 brillo::MessageLoop::current()->BreakLoop(); 1382 } 1383 }; 1384 1385 void TerminateTransferTestStarter(ActionProcessor* processor) { 1386 processor->StartProcessing(); 1387 CHECK(processor->IsRunning()); 1388 processor->StopProcessing(); 1389 } 1390 } // namespace 1391 1392 TEST_F(OmahaRequestActionTest, TerminateTransferTest) { 1393 brillo::FakeMessageLoop loop(nullptr); 1394 loop.SetAsCurrent(); 1395 1396 string http_response("doesn't matter"); 1397 OmahaRequestAction action( 1398 &fake_system_state_, 1399 nullptr, 1400 std::make_unique<MockHttpFetcher>(http_response.data(), 1401 http_response.size(), 1402 nullptr), 1403 false); 1404 TerminateEarlyTestProcessorDelegate delegate; 1405 ActionProcessor processor; 1406 processor.set_delegate(&delegate); 1407 processor.EnqueueAction(&action); 1408 1409 loop.PostTask(base::Bind(&TerminateTransferTestStarter, &processor)); 1410 loop.Run(); 1411 EXPECT_FALSE(loop.PendingTasks()); 1412 } 1413 1414 TEST_F(OmahaRequestActionTest, XmlEncodeTest) { 1415 string output; 1416 EXPECT_TRUE(XmlEncode("ab", &output)); 1417 EXPECT_EQ("ab", output); 1418 EXPECT_TRUE(XmlEncode("a<b", &output)); 1419 EXPECT_EQ("a<b", output); 1420 EXPECT_TRUE(XmlEncode("<&>\"\'\\", &output)); 1421 EXPECT_EQ("<&>"'\\", output); 1422 EXPECT_TRUE(XmlEncode("<&>", &output)); 1423 EXPECT_EQ("&lt;&amp;&gt;", output); 1424 // Check that unterminated UTF-8 strings are handled properly. 1425 EXPECT_FALSE(XmlEncode("\xc2", &output)); 1426 // Fail with invalid ASCII-7 chars. 1427 EXPECT_FALSE(XmlEncode("This is an 'n' with a tilde: \xc3\xb1", &output)); 1428 } 1429 1430 TEST_F(OmahaRequestActionTest, XmlEncodeWithDefaultTest) { 1431 EXPECT_EQ("<&>", XmlEncodeWithDefault("<&>", "something else")); 1432 EXPECT_EQ("<not escaped>", XmlEncodeWithDefault("\xc2", "<not escaped>")); 1433 } 1434 1435 TEST_F(OmahaRequestActionTest, XmlEncodeIsUsedForParams) { 1436 brillo::Blob post_data; 1437 1438 // Make sure XML Encode is being called on the params 1439 OmahaRequestParams params(&fake_system_state_, 1440 constants::kOmahaPlatformName, 1441 OmahaRequestParams::kOsVersion, 1442 "testtheservice_pack>", 1443 "x86 generic<id", 1444 kTestAppId, 1445 "0.1.0.0", 1446 "en-US", 1447 "unittest_track<", 1448 "<OEM MODEL>", 1449 "ChromeOSFirmware.1.0", 1450 "EC100", 1451 false, // delta okay 1452 false, // interactive 1453 "http://url", 1454 ""); // target_version_prefix 1455 fake_prefs_.SetString(kPrefsOmahaCohort, "evil\nstring"); 1456 fake_prefs_.SetString(kPrefsOmahaCohortHint, "evil&string\\"); 1457 fake_prefs_.SetString(kPrefsOmahaCohortName, 1458 base::JoinString( 1459 vector<string>(100, "My spoon is too big."), " ")); 1460 OmahaResponse response; 1461 ASSERT_FALSE( 1462 TestUpdateCheck(¶ms, 1463 "invalid xml>", 1464 -1, 1465 false, // ping_only 1466 ErrorCode::kOmahaRequestXMLParseError, 1467 metrics::CheckResult::kParsingError, 1468 metrics::CheckReaction::kUnset, 1469 metrics::DownloadErrorCode::kUnset, 1470 &response, 1471 &post_data)); 1472 // convert post_data to string 1473 string post_str(post_data.begin(), post_data.end()); 1474 EXPECT_NE(string::npos, post_str.find("testtheservice_pack>")); 1475 EXPECT_EQ(string::npos, post_str.find("testtheservice_pack>")); 1476 EXPECT_NE(string::npos, post_str.find("x86 generic<id")); 1477 EXPECT_EQ(string::npos, post_str.find("x86 generic<id")); 1478 EXPECT_NE(string::npos, post_str.find("unittest_track&lt;")); 1479 EXPECT_EQ(string::npos, post_str.find("unittest_track<")); 1480 EXPECT_NE(string::npos, post_str.find("<OEM MODEL>")); 1481 EXPECT_EQ(string::npos, post_str.find("<OEM MODEL>")); 1482 EXPECT_NE(string::npos, post_str.find("cohort=\"evil\nstring\"")); 1483 EXPECT_EQ(string::npos, post_str.find("cohorthint=\"evil&string\\\"")); 1484 EXPECT_NE(string::npos, post_str.find("cohorthint=\"evil&string\\\"")); 1485 // Values from Prefs that are too big are removed from the XML instead of 1486 // encoded. 1487 EXPECT_EQ(string::npos, post_str.find("cohortname=")); 1488 } 1489 1490 TEST_F(OmahaRequestActionTest, XmlDecodeTest) { 1491 OmahaResponse response; 1492 fake_update_response_.deadline = "<20110101"; 1493 fake_update_response_.more_info_url = "testthe<url"; 1494 fake_update_response_.codebase = "testthe&codebase/"; 1495 ASSERT_TRUE( 1496 TestUpdateCheck(nullptr, // request_params 1497 fake_update_response_.GetUpdateResponse(), 1498 -1, 1499 false, // ping_only 1500 ErrorCode::kSuccess, 1501 metrics::CheckResult::kUpdateAvailable, 1502 metrics::CheckReaction::kUpdating, 1503 metrics::DownloadErrorCode::kUnset, 1504 &response, 1505 nullptr)); 1506 1507 EXPECT_EQ("testthe<url", response.more_info_url); 1508 EXPECT_EQ("testthe&codebase/file.signed", 1509 response.packages[0].payload_urls[0]); 1510 EXPECT_EQ("<20110101", response.deadline); 1511 } 1512 1513 TEST_F(OmahaRequestActionTest, ParseIntTest) { 1514 OmahaResponse response; 1515 // overflows int32_t: 1516 fake_update_response_.size = 123123123123123ull; 1517 ASSERT_TRUE( 1518 TestUpdateCheck(nullptr, // request_params 1519 fake_update_response_.GetUpdateResponse(), 1520 -1, 1521 false, // ping_only 1522 ErrorCode::kSuccess, 1523 metrics::CheckResult::kUpdateAvailable, 1524 metrics::CheckReaction::kUpdating, 1525 metrics::DownloadErrorCode::kUnset, 1526 &response, 1527 nullptr)); 1528 1529 EXPECT_EQ(fake_update_response_.size, response.packages[0].size); 1530 } 1531 1532 TEST_F(OmahaRequestActionTest, FormatUpdateCheckOutputTest) { 1533 brillo::Blob post_data; 1534 NiceMock<MockPrefs> prefs; 1535 fake_system_state_.set_prefs(&prefs); 1536 1537 EXPECT_CALL(prefs, GetString(kPrefsPreviousVersion, _)) 1538 .WillOnce(DoAll(SetArgPointee<1>(string("")), Return(true))); 1539 // An existing but empty previous version means that we didn't reboot to a new 1540 // update, therefore, no need to update the previous version. 1541 EXPECT_CALL(prefs, SetString(kPrefsPreviousVersion, _)).Times(0); 1542 ASSERT_FALSE(TestUpdateCheck(nullptr, // request_params 1543 "invalid xml>", 1544 -1, 1545 false, // ping_only 1546 ErrorCode::kOmahaRequestXMLParseError, 1547 metrics::CheckResult::kParsingError, 1548 metrics::CheckReaction::kUnset, 1549 metrics::DownloadErrorCode::kUnset, 1550 nullptr, // response 1551 &post_data)); 1552 // convert post_data to string 1553 string post_str(post_data.begin(), post_data.end()); 1554 EXPECT_NE(post_str.find( 1555 " <ping active=\"1\" a=\"-1\" r=\"-1\"></ping>\n" 1556 " <updatecheck targetversionprefix=\"\"></updatecheck>\n"), 1557 string::npos); 1558 EXPECT_NE(post_str.find("hardware_class=\"OEM MODEL 09235 7471\""), 1559 string::npos); 1560 EXPECT_NE(post_str.find("fw_version=\"ChromeOSFirmware.1.0\""), 1561 string::npos); 1562 EXPECT_NE(post_str.find("ec_version=\"0X0A1\""), 1563 string::npos); 1564 // No <event> tag should be sent if we didn't reboot to an update. 1565 EXPECT_EQ(post_str.find("<event"), string::npos); 1566 } 1567 1568 1569 TEST_F(OmahaRequestActionTest, FormatSuccessEventOutputTest) { 1570 brillo::Blob post_data; 1571 TestEvent(request_params_, 1572 new OmahaEvent(OmahaEvent::kTypeUpdateDownloadStarted), 1573 "invalid xml>", 1574 &post_data); 1575 // convert post_data to string 1576 string post_str(post_data.begin(), post_data.end()); 1577 string expected_event = base::StringPrintf( 1578 " <event eventtype=\"%d\" eventresult=\"%d\"></event>\n", 1579 OmahaEvent::kTypeUpdateDownloadStarted, 1580 OmahaEvent::kResultSuccess); 1581 EXPECT_NE(post_str.find(expected_event), string::npos); 1582 EXPECT_EQ(post_str.find("ping"), string::npos); 1583 EXPECT_EQ(post_str.find("updatecheck"), string::npos); 1584 } 1585 1586 TEST_F(OmahaRequestActionTest, FormatErrorEventOutputTest) { 1587 brillo::Blob post_data; 1588 TestEvent(request_params_, 1589 new OmahaEvent(OmahaEvent::kTypeDownloadComplete, 1590 OmahaEvent::kResultError, 1591 ErrorCode::kError), 1592 "invalid xml>", 1593 &post_data); 1594 // convert post_data to string 1595 string post_str(post_data.begin(), post_data.end()); 1596 string expected_event = base::StringPrintf( 1597 " <event eventtype=\"%d\" eventresult=\"%d\" " 1598 "errorcode=\"%d\"></event>\n", 1599 OmahaEvent::kTypeDownloadComplete, 1600 OmahaEvent::kResultError, 1601 static_cast<int>(ErrorCode::kError)); 1602 EXPECT_NE(post_str.find(expected_event), string::npos); 1603 EXPECT_EQ(post_str.find("updatecheck"), string::npos); 1604 } 1605 1606 TEST_F(OmahaRequestActionTest, IsEventTest) { 1607 string http_response("doesn't matter"); 1608 // Create a copy of the OmahaRequestParams to reuse it later. 1609 OmahaRequestParams params = request_params_; 1610 fake_system_state_.set_request_params(¶ms); 1611 OmahaRequestAction update_check_action( 1612 &fake_system_state_, 1613 nullptr, 1614 std::make_unique<MockHttpFetcher>(http_response.data(), 1615 http_response.size(), 1616 nullptr), 1617 false); 1618 EXPECT_FALSE(update_check_action.IsEvent()); 1619 1620 params = request_params_; 1621 fake_system_state_.set_request_params(¶ms); 1622 OmahaRequestAction event_action( 1623 &fake_system_state_, 1624 new OmahaEvent(OmahaEvent::kTypeUpdateComplete), 1625 std::make_unique<MockHttpFetcher>(http_response.data(), 1626 http_response.size(), 1627 nullptr), 1628 false); 1629 EXPECT_TRUE(event_action.IsEvent()); 1630 } 1631 1632 TEST_F(OmahaRequestActionTest, FormatDeltaOkayOutputTest) { 1633 for (int i = 0; i < 2; i++) { 1634 bool delta_okay = i == 1; 1635 const char* delta_okay_str = delta_okay ? "true" : "false"; 1636 brillo::Blob post_data; 1637 OmahaRequestParams params(&fake_system_state_, 1638 constants::kOmahaPlatformName, 1639 OmahaRequestParams::kOsVersion, 1640 "service_pack", 1641 "x86-generic", 1642 kTestAppId, 1643 "0.1.0.0", 1644 "en-US", 1645 "unittest_track", 1646 "OEM MODEL REV 1234", 1647 "ChromeOSFirmware.1.0", 1648 "EC100", 1649 delta_okay, 1650 false, // interactive 1651 "http://url", 1652 ""); // target_version_prefix 1653 ASSERT_FALSE(TestUpdateCheck(¶ms, 1654 "invalid xml>", 1655 -1, 1656 false, // ping_only 1657 ErrorCode::kOmahaRequestXMLParseError, 1658 metrics::CheckResult::kParsingError, 1659 metrics::CheckReaction::kUnset, 1660 metrics::DownloadErrorCode::kUnset, 1661 nullptr, 1662 &post_data)); 1663 // convert post_data to string 1664 string post_str(post_data.begin(), post_data.end()); 1665 EXPECT_NE(post_str.find(base::StringPrintf(" delta_okay=\"%s\"", 1666 delta_okay_str)), 1667 string::npos) 1668 << "i = " << i; 1669 } 1670 } 1671 1672 TEST_F(OmahaRequestActionTest, FormatInteractiveOutputTest) { 1673 for (int i = 0; i < 2; i++) { 1674 bool interactive = i == 1; 1675 const char* interactive_str = interactive ? "ondemandupdate" : "scheduler"; 1676 brillo::Blob post_data; 1677 FakeSystemState fake_system_state; 1678 OmahaRequestParams params(&fake_system_state_, 1679 constants::kOmahaPlatformName, 1680 OmahaRequestParams::kOsVersion, 1681 "service_pack", 1682 "x86-generic", 1683 kTestAppId, 1684 "0.1.0.0", 1685 "en-US", 1686 "unittest_track", 1687 "OEM MODEL REV 1234", 1688 "ChromeOSFirmware.1.0", 1689 "EC100", 1690 true, // delta_okay 1691 interactive, 1692 "http://url", 1693 ""); // target_version_prefix 1694 ASSERT_FALSE(TestUpdateCheck(¶ms, 1695 "invalid xml>", 1696 -1, 1697 false, // ping_only 1698 ErrorCode::kOmahaRequestXMLParseError, 1699 metrics::CheckResult::kParsingError, 1700 metrics::CheckReaction::kUnset, 1701 metrics::DownloadErrorCode::kUnset, 1702 nullptr, 1703 &post_data)); 1704 // convert post_data to string 1705 string post_str(post_data.begin(), post_data.end()); 1706 EXPECT_NE(post_str.find(base::StringPrintf("installsource=\"%s\"", 1707 interactive_str)), 1708 string::npos) 1709 << "i = " << i; 1710 } 1711 } 1712 1713 TEST_F(OmahaRequestActionTest, OmahaEventTest) { 1714 OmahaEvent default_event; 1715 EXPECT_EQ(OmahaEvent::kTypeUnknown, default_event.type); 1716 EXPECT_EQ(OmahaEvent::kResultError, default_event.result); 1717 EXPECT_EQ(ErrorCode::kError, default_event.error_code); 1718 1719 OmahaEvent success_event(OmahaEvent::kTypeUpdateDownloadStarted); 1720 EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadStarted, success_event.type); 1721 EXPECT_EQ(OmahaEvent::kResultSuccess, success_event.result); 1722 EXPECT_EQ(ErrorCode::kSuccess, success_event.error_code); 1723 1724 OmahaEvent error_event(OmahaEvent::kTypeUpdateDownloadFinished, 1725 OmahaEvent::kResultError, 1726 ErrorCode::kError); 1727 EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadFinished, error_event.type); 1728 EXPECT_EQ(OmahaEvent::kResultError, error_event.result); 1729 EXPECT_EQ(ErrorCode::kError, error_event.error_code); 1730 } 1731 1732 void OmahaRequestActionTest::PingTest(bool ping_only) { 1733 NiceMock<MockPrefs> prefs; 1734 fake_system_state_.set_prefs(&prefs); 1735 EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _)) 1736 .Times(AnyNumber()); 1737 EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber()); 1738 // Add a few hours to the day difference to test no rounding, etc. 1739 int64_t five_days_ago = 1740 (Time::Now() - TimeDelta::FromHours(5 * 24 + 13)).ToInternalValue(); 1741 int64_t six_days_ago = 1742 (Time::Now() - TimeDelta::FromHours(6 * 24 + 11)).ToInternalValue(); 1743 EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _)) 1744 .WillOnce(DoAll(SetArgPointee<1>(0), Return(true))); 1745 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _)) 1746 .WillOnce(DoAll(SetArgPointee<1>(six_days_ago), Return(true))); 1747 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _)) 1748 .WillOnce(DoAll(SetArgPointee<1>(five_days_ago), Return(true))); 1749 brillo::Blob post_data; 1750 ASSERT_TRUE(TestUpdateCheck(nullptr, // request_params 1751 fake_update_response_.GetNoUpdateResponse(), 1752 -1, 1753 ping_only, 1754 ErrorCode::kSuccess, 1755 metrics::CheckResult::kNoUpdateAvailable, 1756 metrics::CheckReaction::kUnset, 1757 metrics::DownloadErrorCode::kUnset, 1758 nullptr, 1759 &post_data)); 1760 string post_str(post_data.begin(), post_data.end()); 1761 EXPECT_NE(post_str.find("<ping active=\"1\" a=\"6\" r=\"5\"></ping>"), 1762 string::npos); 1763 if (ping_only) { 1764 EXPECT_EQ(post_str.find("updatecheck"), string::npos); 1765 EXPECT_EQ(post_str.find("previousversion"), string::npos); 1766 } else { 1767 EXPECT_NE(post_str.find("updatecheck"), string::npos); 1768 EXPECT_NE(post_str.find("previousversion"), string::npos); 1769 } 1770 } 1771 1772 TEST_F(OmahaRequestActionTest, PingTestSendOnlyAPing) { 1773 PingTest(true /* ping_only */); 1774 } 1775 1776 TEST_F(OmahaRequestActionTest, PingTestSendAlsoAnUpdateCheck) { 1777 PingTest(false /* ping_only */); 1778 } 1779 1780 TEST_F(OmahaRequestActionTest, ActivePingTest) { 1781 NiceMock<MockPrefs> prefs; 1782 fake_system_state_.set_prefs(&prefs); 1783 EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _)) 1784 .Times(AnyNumber()); 1785 EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber()); 1786 int64_t three_days_ago = 1787 (Time::Now() - TimeDelta::FromHours(3 * 24 + 12)).ToInternalValue(); 1788 int64_t now = Time::Now().ToInternalValue(); 1789 EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _)) 1790 .WillOnce(DoAll(SetArgPointee<1>(0), Return(true))); 1791 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _)) 1792 .WillOnce(DoAll(SetArgPointee<1>(three_days_ago), Return(true))); 1793 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _)) 1794 .WillOnce(DoAll(SetArgPointee<1>(now), Return(true))); 1795 brillo::Blob post_data; 1796 ASSERT_TRUE( 1797 TestUpdateCheck(nullptr, // request_params 1798 fake_update_response_.GetNoUpdateResponse(), 1799 -1, 1800 false, // ping_only 1801 ErrorCode::kSuccess, 1802 metrics::CheckResult::kNoUpdateAvailable, 1803 metrics::CheckReaction::kUnset, 1804 metrics::DownloadErrorCode::kUnset, 1805 nullptr, 1806 &post_data)); 1807 string post_str(post_data.begin(), post_data.end()); 1808 EXPECT_NE(post_str.find("<ping active=\"1\" a=\"3\"></ping>"), 1809 string::npos); 1810 } 1811 1812 TEST_F(OmahaRequestActionTest, RollCallPingTest) { 1813 NiceMock<MockPrefs> prefs; 1814 fake_system_state_.set_prefs(&prefs); 1815 EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _)) 1816 .Times(AnyNumber()); 1817 EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber()); 1818 int64_t four_days_ago = 1819 (Time::Now() - TimeDelta::FromHours(4 * 24)).ToInternalValue(); 1820 int64_t now = Time::Now().ToInternalValue(); 1821 EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _)) 1822 .WillOnce(DoAll(SetArgPointee<1>(0), Return(true))); 1823 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _)) 1824 .WillOnce(DoAll(SetArgPointee<1>(now), Return(true))); 1825 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _)) 1826 .WillOnce(DoAll(SetArgPointee<1>(four_days_ago), Return(true))); 1827 brillo::Blob post_data; 1828 ASSERT_TRUE( 1829 TestUpdateCheck(nullptr, // request_params 1830 fake_update_response_.GetNoUpdateResponse(), 1831 -1, 1832 false, // ping_only 1833 ErrorCode::kSuccess, 1834 metrics::CheckResult::kNoUpdateAvailable, 1835 metrics::CheckReaction::kUnset, 1836 metrics::DownloadErrorCode::kUnset, 1837 nullptr, 1838 &post_data)); 1839 string post_str(post_data.begin(), post_data.end()); 1840 EXPECT_NE(post_str.find("<ping active=\"1\" r=\"4\"></ping>\n"), 1841 string::npos); 1842 } 1843 1844 TEST_F(OmahaRequestActionTest, NoPingTest) { 1845 NiceMock<MockPrefs> prefs; 1846 fake_system_state_.set_prefs(&prefs); 1847 EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _)) 1848 .Times(AnyNumber()); 1849 EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber()); 1850 int64_t one_hour_ago = 1851 (Time::Now() - TimeDelta::FromHours(1)).ToInternalValue(); 1852 EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _)) 1853 .WillOnce(DoAll(SetArgPointee<1>(0), Return(true))); 1854 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _)) 1855 .WillOnce(DoAll(SetArgPointee<1>(one_hour_ago), Return(true))); 1856 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _)) 1857 .WillOnce(DoAll(SetArgPointee<1>(one_hour_ago), Return(true))); 1858 // LastActivePingDay and PrefsLastRollCallPingDay are set even if we didn't 1859 // send a ping. 1860 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)) 1861 .WillOnce(Return(true)); 1862 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)) 1863 .WillOnce(Return(true)); 1864 brillo::Blob post_data; 1865 ASSERT_TRUE( 1866 TestUpdateCheck(nullptr, // request_params 1867 fake_update_response_.GetNoUpdateResponse(), 1868 -1, 1869 false, // ping_only 1870 ErrorCode::kSuccess, 1871 metrics::CheckResult::kNoUpdateAvailable, 1872 metrics::CheckReaction::kUnset, 1873 metrics::DownloadErrorCode::kUnset, 1874 nullptr, 1875 &post_data)); 1876 string post_str(post_data.begin(), post_data.end()); 1877 EXPECT_EQ(post_str.find("ping"), string::npos); 1878 } 1879 1880 TEST_F(OmahaRequestActionTest, IgnoreEmptyPingTest) { 1881 // This test ensures that we ignore empty ping only requests. 1882 NiceMock<MockPrefs> prefs; 1883 fake_system_state_.set_prefs(&prefs); 1884 int64_t now = Time::Now().ToInternalValue(); 1885 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _)) 1886 .WillOnce(DoAll(SetArgPointee<1>(now), Return(true))); 1887 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _)) 1888 .WillOnce(DoAll(SetArgPointee<1>(now), Return(true))); 1889 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0); 1890 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0); 1891 brillo::Blob post_data; 1892 EXPECT_TRUE( 1893 TestUpdateCheck(nullptr, // request_params 1894 fake_update_response_.GetNoUpdateResponse(), 1895 -1, 1896 true, // ping_only 1897 ErrorCode::kSuccess, 1898 metrics::CheckResult::kUnset, 1899 metrics::CheckReaction::kUnset, 1900 metrics::DownloadErrorCode::kUnset, 1901 nullptr, 1902 &post_data)); 1903 EXPECT_EQ(0U, post_data.size()); 1904 } 1905 1906 TEST_F(OmahaRequestActionTest, BackInTimePingTest) { 1907 NiceMock<MockPrefs> prefs; 1908 fake_system_state_.set_prefs(&prefs); 1909 EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _)) 1910 .Times(AnyNumber()); 1911 EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber()); 1912 int64_t future = 1913 (Time::Now() + TimeDelta::FromHours(3 * 24 + 4)).ToInternalValue(); 1914 EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _)) 1915 .WillOnce(DoAll(SetArgPointee<1>(0), Return(true))); 1916 EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _)) 1917 .WillOnce(DoAll(SetArgPointee<1>(future), Return(true))); 1918 EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _)) 1919 .WillOnce(DoAll(SetArgPointee<1>(future), Return(true))); 1920 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)) 1921 .WillOnce(Return(true)); 1922 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)) 1923 .WillOnce(Return(true)); 1924 brillo::Blob post_data; 1925 ASSERT_TRUE( 1926 TestUpdateCheck(nullptr, // request_params 1927 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response " 1928 "protocol=\"3.0\"><daystart elapsed_seconds=\"100\"/>" 1929 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>" 1930 "<updatecheck status=\"noupdate\"/></app></response>", 1931 -1, 1932 false, // ping_only 1933 ErrorCode::kSuccess, 1934 metrics::CheckResult::kNoUpdateAvailable, 1935 metrics::CheckReaction::kUnset, 1936 metrics::DownloadErrorCode::kUnset, 1937 nullptr, 1938 &post_data)); 1939 string post_str(post_data.begin(), post_data.end()); 1940 EXPECT_EQ(post_str.find("ping"), string::npos); 1941 } 1942 1943 TEST_F(OmahaRequestActionTest, LastPingDayUpdateTest) { 1944 // This test checks that the action updates the last ping day to now 1945 // minus 200 seconds with a slack of 5 seconds. Therefore, the test 1946 // may fail if it runs for longer than 5 seconds. It shouldn't run 1947 // that long though. 1948 int64_t midnight = 1949 (Time::Now() - TimeDelta::FromSeconds(200)).ToInternalValue(); 1950 int64_t midnight_slack = 1951 (Time::Now() - TimeDelta::FromSeconds(195)).ToInternalValue(); 1952 NiceMock<MockPrefs> prefs; 1953 fake_system_state_.set_prefs(&prefs); 1954 EXPECT_CALL(prefs, GetInt64(_, _)).Times(AnyNumber()); 1955 EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber()); 1956 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, 1957 AllOf(Ge(midnight), Le(midnight_slack)))) 1958 .WillOnce(Return(true)); 1959 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, 1960 AllOf(Ge(midnight), Le(midnight_slack)))) 1961 .WillOnce(Return(true)); 1962 ASSERT_TRUE( 1963 TestUpdateCheck(nullptr, // request_params 1964 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response " 1965 "protocol=\"3.0\"><daystart elapsed_seconds=\"200\"/>" 1966 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>" 1967 "<updatecheck status=\"noupdate\"/></app></response>", 1968 -1, 1969 false, // ping_only 1970 ErrorCode::kSuccess, 1971 metrics::CheckResult::kNoUpdateAvailable, 1972 metrics::CheckReaction::kUnset, 1973 metrics::DownloadErrorCode::kUnset, 1974 nullptr, 1975 nullptr)); 1976 } 1977 1978 TEST_F(OmahaRequestActionTest, NoElapsedSecondsTest) { 1979 NiceMock<MockPrefs> prefs; 1980 fake_system_state_.set_prefs(&prefs); 1981 EXPECT_CALL(prefs, GetInt64(_, _)).Times(AnyNumber()); 1982 EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber()); 1983 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0); 1984 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0); 1985 ASSERT_TRUE( 1986 TestUpdateCheck(nullptr, // request_params 1987 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response " 1988 "protocol=\"3.0\"><daystart blah=\"200\"/>" 1989 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>" 1990 "<updatecheck status=\"noupdate\"/></app></response>", 1991 -1, 1992 false, // ping_only 1993 ErrorCode::kSuccess, 1994 metrics::CheckResult::kNoUpdateAvailable, 1995 metrics::CheckReaction::kUnset, 1996 metrics::DownloadErrorCode::kUnset, 1997 nullptr, 1998 nullptr)); 1999 } 2000 2001 TEST_F(OmahaRequestActionTest, BadElapsedSecondsTest) { 2002 NiceMock<MockPrefs> prefs; 2003 fake_system_state_.set_prefs(&prefs); 2004 EXPECT_CALL(prefs, GetInt64(_, _)).Times(AnyNumber()); 2005 EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber()); 2006 EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0); 2007 EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0); 2008 ASSERT_TRUE( 2009 TestUpdateCheck(nullptr, // request_params 2010 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response " 2011 "protocol=\"3.0\"><daystart elapsed_seconds=\"x\"/>" 2012 "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>" 2013 "<updatecheck status=\"noupdate\"/></app></response>", 2014 -1, 2015 false, // ping_only 2016 ErrorCode::kSuccess, 2017 metrics::CheckResult::kNoUpdateAvailable, 2018 metrics::CheckReaction::kUnset, 2019 metrics::DownloadErrorCode::kUnset, 2020 nullptr, 2021 nullptr)); 2022 } 2023 2024 TEST_F(OmahaRequestActionTest, ParseUpdateCheckAttributesTest) { 2025 // Test that the "eol" flags is only parsed from the "_eol" attribute and not 2026 // the "eol" attribute. 2027 ASSERT_TRUE( 2028 TestUpdateCheck(nullptr, // request_params 2029 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response " 2030 "protocol=\"3.0\"><app appid=\"foo\" status=\"ok\">" 2031 "<ping status=\"ok\"/><updatecheck status=\"noupdate\" " 2032 "_eol=\"security-only\" eol=\"eol\" _foo=\"bar\"/>" 2033 "</app></response>", 2034 -1, 2035 false, // ping_only 2036 ErrorCode::kSuccess, 2037 metrics::CheckResult::kNoUpdateAvailable, 2038 metrics::CheckReaction::kUnset, 2039 metrics::DownloadErrorCode::kUnset, 2040 nullptr, 2041 nullptr)); 2042 string eol_pref; 2043 EXPECT_TRUE( 2044 fake_system_state_.prefs()->GetString(kPrefsOmahaEolStatus, &eol_pref)); 2045 // Note that the eol="eol" attribute should be ignored and the _eol should be 2046 // used instead. 2047 EXPECT_EQ("security-only", eol_pref); 2048 } 2049 2050 TEST_F(OmahaRequestActionTest, NoUniqueIDTest) { 2051 brillo::Blob post_data; 2052 ASSERT_FALSE(TestUpdateCheck(nullptr, // request_params 2053 "invalid xml>", 2054 -1, 2055 false, // ping_only 2056 ErrorCode::kOmahaRequestXMLParseError, 2057 metrics::CheckResult::kParsingError, 2058 metrics::CheckReaction::kUnset, 2059 metrics::DownloadErrorCode::kUnset, 2060 nullptr, // response 2061 &post_data)); 2062 // convert post_data to string 2063 string post_str(post_data.begin(), post_data.end()); 2064 EXPECT_EQ(post_str.find("machineid="), string::npos); 2065 EXPECT_EQ(post_str.find("userid="), string::npos); 2066 } 2067 2068 TEST_F(OmahaRequestActionTest, NetworkFailureTest) { 2069 OmahaResponse response; 2070 const int http_error_code = 2071 static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase) + 501; 2072 ASSERT_FALSE( 2073 TestUpdateCheck(nullptr, // request_params 2074 "", 2075 501, 2076 false, // ping_only 2077 static_cast<ErrorCode>(http_error_code), 2078 metrics::CheckResult::kDownloadError, 2079 metrics::CheckReaction::kUnset, 2080 static_cast<metrics::DownloadErrorCode>(501), 2081 &response, 2082 nullptr)); 2083 EXPECT_FALSE(response.update_exists); 2084 } 2085 2086 TEST_F(OmahaRequestActionTest, NetworkFailureBadHTTPCodeTest) { 2087 OmahaResponse response; 2088 const int http_error_code = 2089 static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase) + 999; 2090 ASSERT_FALSE( 2091 TestUpdateCheck(nullptr, // request_params 2092 "", 2093 1500, 2094 false, // ping_only 2095 static_cast<ErrorCode>(http_error_code), 2096 metrics::CheckResult::kDownloadError, 2097 metrics::CheckReaction::kUnset, 2098 metrics::DownloadErrorCode::kHttpStatusOther, 2099 &response, 2100 nullptr)); 2101 EXPECT_FALSE(response.update_exists); 2102 } 2103 2104 TEST_F(OmahaRequestActionTest, TestUpdateFirstSeenAtGetsPersistedFirstTime) { 2105 OmahaResponse response; 2106 OmahaRequestParams params = request_params_; 2107 params.set_wall_clock_based_wait_enabled(true); 2108 params.set_waiting_period(TimeDelta().FromDays(1)); 2109 params.set_update_check_count_wait_enabled(false); 2110 2111 Time arbitrary_date; 2112 ASSERT_TRUE(Time::FromString("6/4/1989", &arbitrary_date)); 2113 fake_system_state_.fake_clock()->SetWallclockTime(arbitrary_date); 2114 ASSERT_FALSE(TestUpdateCheck(¶ms, 2115 fake_update_response_.GetUpdateResponse(), 2116 -1, 2117 false, // ping_only 2118 ErrorCode::kOmahaUpdateDeferredPerPolicy, 2119 metrics::CheckResult::kUpdateAvailable, 2120 metrics::CheckReaction::kDeferring, 2121 metrics::DownloadErrorCode::kUnset, 2122 &response, 2123 nullptr)); 2124 2125 int64_t timestamp = 0; 2126 ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateFirstSeenAt, ×tamp)); 2127 EXPECT_EQ(arbitrary_date.ToInternalValue(), timestamp); 2128 EXPECT_FALSE(response.update_exists); 2129 2130 // Verify if we are interactive check we don't defer. 2131 params.set_interactive(true); 2132 ASSERT_TRUE(TestUpdateCheck(¶ms, 2133 fake_update_response_.GetUpdateResponse(), 2134 -1, 2135 false, // ping_only 2136 ErrorCode::kSuccess, 2137 metrics::CheckResult::kUpdateAvailable, 2138 metrics::CheckReaction::kUpdating, 2139 metrics::DownloadErrorCode::kUnset, 2140 &response, 2141 nullptr)); 2142 EXPECT_TRUE(response.update_exists); 2143 } 2144 2145 TEST_F(OmahaRequestActionTest, TestUpdateFirstSeenAtGetsUsedIfAlreadyPresent) { 2146 OmahaResponse response; 2147 OmahaRequestParams params = request_params_; 2148 params.set_wall_clock_based_wait_enabled(true); 2149 params.set_waiting_period(TimeDelta().FromDays(1)); 2150 params.set_update_check_count_wait_enabled(false); 2151 2152 Time t1, t2; 2153 ASSERT_TRUE(Time::FromString("1/1/2012", &t1)); 2154 ASSERT_TRUE(Time::FromString("1/3/2012", &t2)); 2155 ASSERT_TRUE( 2156 fake_prefs_.SetInt64(kPrefsUpdateFirstSeenAt, t1.ToInternalValue())); 2157 fake_system_state_.fake_clock()->SetWallclockTime(t2); 2158 ASSERT_TRUE(TestUpdateCheck(¶ms, 2159 fake_update_response_.GetUpdateResponse(), 2160 -1, 2161 false, // ping_only 2162 ErrorCode::kSuccess, 2163 metrics::CheckResult::kUpdateAvailable, 2164 metrics::CheckReaction::kUpdating, 2165 metrics::DownloadErrorCode::kUnset, 2166 &response, 2167 nullptr)); 2168 2169 EXPECT_TRUE(response.update_exists); 2170 2171 // Make sure the timestamp t1 is unchanged showing that it was reused. 2172 int64_t timestamp = 0; 2173 ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateFirstSeenAt, ×tamp)); 2174 ASSERT_TRUE(timestamp == t1.ToInternalValue()); 2175 } 2176 2177 TEST_F(OmahaRequestActionTest, TestChangingToMoreStableChannel) { 2178 // Create a uniquely named test directory. 2179 base::ScopedTempDir tempdir; 2180 ASSERT_TRUE(tempdir.CreateUniqueTempDir()); 2181 2182 brillo::Blob post_data; 2183 OmahaRequestParams params(&fake_system_state_); 2184 params.set_root(tempdir.GetPath().value()); 2185 params.set_app_id("{22222222-2222-2222-2222-222222222222}"); 2186 params.set_app_version("1.2.3.4"); 2187 params.set_product_components("o.bundle=1"); 2188 params.set_current_channel("canary-channel"); 2189 EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr)); 2190 params.UpdateDownloadChannel(); 2191 EXPECT_TRUE(params.ShouldPowerwash()); 2192 ASSERT_FALSE(TestUpdateCheck(¶ms, 2193 "invalid xml>", 2194 -1, 2195 false, // ping_only 2196 ErrorCode::kOmahaRequestXMLParseError, 2197 metrics::CheckResult::kParsingError, 2198 metrics::CheckReaction::kUnset, 2199 metrics::DownloadErrorCode::kUnset, 2200 nullptr, // response 2201 &post_data)); 2202 // convert post_data to string 2203 string post_str(post_data.begin(), post_data.end()); 2204 EXPECT_NE(string::npos, post_str.find( 2205 "appid=\"{22222222-2222-2222-2222-222222222222}\" " 2206 "version=\"0.0.0.0\" from_version=\"1.2.3.4\" " 2207 "track=\"stable-channel\" from_track=\"canary-channel\" ")); 2208 EXPECT_EQ(string::npos, post_str.find("o.bundle")); 2209 } 2210 2211 TEST_F(OmahaRequestActionTest, TestChangingToLessStableChannel) { 2212 // Create a uniquely named test directory. 2213 base::ScopedTempDir tempdir; 2214 ASSERT_TRUE(tempdir.CreateUniqueTempDir()); 2215 2216 brillo::Blob post_data; 2217 OmahaRequestParams params(&fake_system_state_); 2218 params.set_root(tempdir.GetPath().value()); 2219 params.set_app_id("{11111111-1111-1111-1111-111111111111}"); 2220 params.set_app_version("5.6.7.8"); 2221 params.set_product_components("o.bundle=1"); 2222 params.set_current_channel("stable-channel"); 2223 EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr)); 2224 params.UpdateDownloadChannel(); 2225 EXPECT_FALSE(params.ShouldPowerwash()); 2226 ASSERT_FALSE(TestUpdateCheck(¶ms, 2227 "invalid xml>", 2228 -1, 2229 false, // ping_only 2230 ErrorCode::kOmahaRequestXMLParseError, 2231 metrics::CheckResult::kParsingError, 2232 metrics::CheckReaction::kUnset, 2233 metrics::DownloadErrorCode::kUnset, 2234 nullptr, // response 2235 &post_data)); 2236 // convert post_data to string 2237 string post_str(post_data.begin(), post_data.end()); 2238 EXPECT_NE(string::npos, post_str.find( 2239 "appid=\"{11111111-1111-1111-1111-111111111111}\" " 2240 "version=\"5.6.7.8\" " 2241 "track=\"canary-channel\" from_track=\"stable-channel\"")); 2242 EXPECT_EQ(string::npos, post_str.find("from_version")); 2243 EXPECT_NE(string::npos, post_str.find("o.bundle.version=\"1\"")); 2244 } 2245 2246 // Checks that the initial ping with a=-1 r=-1 is not send when the device 2247 // was powerwashed. 2248 TEST_F(OmahaRequestActionTest, PingWhenPowerwashed) { 2249 fake_prefs_.SetString(kPrefsPreviousVersion, ""); 2250 2251 // Flag that the device was powerwashed in the past. 2252 fake_system_state_.fake_hardware()->SetPowerwashCount(1); 2253 2254 brillo::Blob post_data; 2255 ASSERT_TRUE( 2256 TestUpdateCheck(nullptr, // request_params 2257 fake_update_response_.GetNoUpdateResponse(), 2258 -1, 2259 false, // ping_only 2260 ErrorCode::kSuccess, 2261 metrics::CheckResult::kNoUpdateAvailable, 2262 metrics::CheckReaction::kUnset, 2263 metrics::DownloadErrorCode::kUnset, 2264 nullptr, 2265 &post_data)); 2266 // We shouldn't send a ping in this case since powerwash > 0. 2267 string post_str(post_data.begin(), post_data.end()); 2268 EXPECT_EQ(string::npos, post_str.find("<ping")); 2269 } 2270 2271 // Checks that the initial ping with a=-1 r=-1 is not send when the device 2272 // first_active_omaha_ping_sent is set. 2273 TEST_F(OmahaRequestActionTest, PingWhenFirstActiveOmahaPingIsSent) { 2274 fake_prefs_.SetString(kPrefsPreviousVersion, ""); 2275 2276 // Flag that the device was not powerwashed in the past. 2277 fake_system_state_.fake_hardware()->SetPowerwashCount(0); 2278 2279 // Flag that the device has sent first active ping in the past. 2280 fake_system_state_.fake_hardware()->SetFirstActiveOmahaPingSent(); 2281 2282 brillo::Blob post_data; 2283 ASSERT_TRUE( 2284 TestUpdateCheck(nullptr, // request_params 2285 fake_update_response_.GetNoUpdateResponse(), 2286 -1, 2287 false, // ping_only 2288 ErrorCode::kSuccess, 2289 metrics::CheckResult::kNoUpdateAvailable, 2290 metrics::CheckReaction::kUnset, 2291 metrics::DownloadErrorCode::kUnset, 2292 nullptr, 2293 &post_data)); 2294 // We shouldn't send a ping in this case since 2295 // first_active_omaha_ping_sent=true 2296 string post_str(post_data.begin(), post_data.end()); 2297 EXPECT_EQ(string::npos, post_str.find("<ping")); 2298 } 2299 2300 // Checks that the event 54 is sent on a reboot to a new update. 2301 TEST_F(OmahaRequestActionTest, RebootAfterUpdateEvent) { 2302 // Flag that the device was updated in a previous boot. 2303 fake_prefs_.SetString(kPrefsPreviousVersion, "1.2.3.4"); 2304 2305 brillo::Blob post_data; 2306 ASSERT_TRUE( 2307 TestUpdateCheck(nullptr, // request_params 2308 fake_update_response_.GetNoUpdateResponse(), 2309 -1, 2310 false, // ping_only 2311 ErrorCode::kSuccess, 2312 metrics::CheckResult::kNoUpdateAvailable, 2313 metrics::CheckReaction::kUnset, 2314 metrics::DownloadErrorCode::kUnset, 2315 nullptr, 2316 &post_data)); 2317 string post_str(post_data.begin(), post_data.end()); 2318 2319 // An event 54 is included and has the right version. 2320 EXPECT_NE(string::npos, 2321 post_str.find(base::StringPrintf( 2322 "<event eventtype=\"%d\"", 2323 OmahaEvent::kTypeRebootedAfterUpdate))); 2324 EXPECT_NE(string::npos, 2325 post_str.find("previousversion=\"1.2.3.4\"></event>")); 2326 2327 // The previous version flag should have been removed. 2328 EXPECT_TRUE(fake_prefs_.Exists(kPrefsPreviousVersion)); 2329 string prev_version; 2330 EXPECT_TRUE(fake_prefs_.GetString(kPrefsPreviousVersion, &prev_version)); 2331 EXPECT_TRUE(prev_version.empty()); 2332 } 2333 2334 void OmahaRequestActionTest::P2PTest( 2335 bool initial_allow_p2p_for_downloading, 2336 bool initial_allow_p2p_for_sharing, 2337 bool omaha_disable_p2p_for_downloading, 2338 bool omaha_disable_p2p_for_sharing, 2339 bool payload_state_allow_p2p_attempt, 2340 bool expect_p2p_client_lookup, 2341 const string& p2p_client_result_url, 2342 bool expected_allow_p2p_for_downloading, 2343 bool expected_allow_p2p_for_sharing, 2344 const string& expected_p2p_url) { 2345 OmahaResponse response; 2346 OmahaRequestParams request_params = request_params_; 2347 bool actual_allow_p2p_for_downloading = initial_allow_p2p_for_downloading; 2348 bool actual_allow_p2p_for_sharing = initial_allow_p2p_for_sharing; 2349 string actual_p2p_url; 2350 2351 MockPayloadState mock_payload_state; 2352 fake_system_state_.set_payload_state(&mock_payload_state); 2353 EXPECT_CALL(mock_payload_state, P2PAttemptAllowed()) 2354 .WillRepeatedly(Return(payload_state_allow_p2p_attempt)); 2355 EXPECT_CALL(mock_payload_state, GetUsingP2PForDownloading()) 2356 .WillRepeatedly(ReturnPointee(&actual_allow_p2p_for_downloading)); 2357 EXPECT_CALL(mock_payload_state, GetUsingP2PForSharing()) 2358 .WillRepeatedly(ReturnPointee(&actual_allow_p2p_for_sharing)); 2359 EXPECT_CALL(mock_payload_state, SetUsingP2PForDownloading(_)) 2360 .WillRepeatedly(SaveArg<0>(&actual_allow_p2p_for_downloading)); 2361 EXPECT_CALL(mock_payload_state, SetUsingP2PForSharing(_)) 2362 .WillRepeatedly(SaveArg<0>(&actual_allow_p2p_for_sharing)); 2363 EXPECT_CALL(mock_payload_state, SetP2PUrl(_)) 2364 .WillRepeatedly(SaveArg<0>(&actual_p2p_url)); 2365 2366 MockP2PManager mock_p2p_manager; 2367 fake_system_state_.set_p2p_manager(&mock_p2p_manager); 2368 mock_p2p_manager.fake().SetLookupUrlForFileResult(p2p_client_result_url); 2369 2370 TimeDelta timeout = TimeDelta::FromSeconds(kMaxP2PNetworkWaitTimeSeconds); 2371 EXPECT_CALL(mock_p2p_manager, LookupUrlForFile(_, _, timeout, _)) 2372 .Times(expect_p2p_client_lookup ? 1 : 0); 2373 2374 fake_update_response_.disable_p2p_for_downloading = 2375 omaha_disable_p2p_for_downloading; 2376 fake_update_response_.disable_p2p_for_sharing = omaha_disable_p2p_for_sharing; 2377 ASSERT_TRUE( 2378 TestUpdateCheck(&request_params, 2379 fake_update_response_.GetUpdateResponse(), 2380 -1, 2381 false, // ping_only 2382 ErrorCode::kSuccess, 2383 metrics::CheckResult::kUpdateAvailable, 2384 metrics::CheckReaction::kUpdating, 2385 metrics::DownloadErrorCode::kUnset, 2386 &response, 2387 nullptr)); 2388 EXPECT_TRUE(response.update_exists); 2389 2390 EXPECT_EQ(omaha_disable_p2p_for_downloading, 2391 response.disable_p2p_for_downloading); 2392 EXPECT_EQ(omaha_disable_p2p_for_sharing, 2393 response.disable_p2p_for_sharing); 2394 2395 EXPECT_EQ(expected_allow_p2p_for_downloading, 2396 actual_allow_p2p_for_downloading); 2397 EXPECT_EQ(expected_allow_p2p_for_sharing, actual_allow_p2p_for_sharing); 2398 EXPECT_EQ(expected_p2p_url, actual_p2p_url); 2399 } 2400 2401 TEST_F(OmahaRequestActionTest, P2PWithPeer) { 2402 P2PTest(true, // initial_allow_p2p_for_downloading 2403 true, // initial_allow_p2p_for_sharing 2404 false, // omaha_disable_p2p_for_downloading 2405 false, // omaha_disable_p2p_for_sharing 2406 true, // payload_state_allow_p2p_attempt 2407 true, // expect_p2p_client_lookup 2408 "http://1.3.5.7/p2p", // p2p_client_result_url 2409 true, // expected_allow_p2p_for_downloading 2410 true, // expected_allow_p2p_for_sharing 2411 "http://1.3.5.7/p2p"); // expected_p2p_url 2412 } 2413 2414 TEST_F(OmahaRequestActionTest, P2PWithoutPeer) { 2415 P2PTest(true, // initial_allow_p2p_for_downloading 2416 true, // initial_allow_p2p_for_sharing 2417 false, // omaha_disable_p2p_for_downloading 2418 false, // omaha_disable_p2p_for_sharing 2419 true, // payload_state_allow_p2p_attempt 2420 true, // expect_p2p_client_lookup 2421 "", // p2p_client_result_url 2422 false, // expected_allow_p2p_for_downloading 2423 true, // expected_allow_p2p_for_sharing 2424 ""); // expected_p2p_url 2425 } 2426 2427 TEST_F(OmahaRequestActionTest, P2PDownloadNotAllowed) { 2428 P2PTest(false, // initial_allow_p2p_for_downloading 2429 true, // initial_allow_p2p_for_sharing 2430 false, // omaha_disable_p2p_for_downloading 2431 false, // omaha_disable_p2p_for_sharing 2432 true, // payload_state_allow_p2p_attempt 2433 false, // expect_p2p_client_lookup 2434 "unset", // p2p_client_result_url 2435 false, // expected_allow_p2p_for_downloading 2436 true, // expected_allow_p2p_for_sharing 2437 ""); // expected_p2p_url 2438 } 2439 2440 TEST_F(OmahaRequestActionTest, P2PWithPeerDownloadDisabledByOmaha) { 2441 P2PTest(true, // initial_allow_p2p_for_downloading 2442 true, // initial_allow_p2p_for_sharing 2443 true, // omaha_disable_p2p_for_downloading 2444 false, // omaha_disable_p2p_for_sharing 2445 true, // payload_state_allow_p2p_attempt 2446 false, // expect_p2p_client_lookup 2447 "unset", // p2p_client_result_url 2448 false, // expected_allow_p2p_for_downloading 2449 true, // expected_allow_p2p_for_sharing 2450 ""); // expected_p2p_url 2451 } 2452 2453 TEST_F(OmahaRequestActionTest, P2PWithPeerSharingDisabledByOmaha) { 2454 P2PTest(true, // initial_allow_p2p_for_downloading 2455 true, // initial_allow_p2p_for_sharing 2456 false, // omaha_disable_p2p_for_downloading 2457 true, // omaha_disable_p2p_for_sharing 2458 true, // payload_state_allow_p2p_attempt 2459 true, // expect_p2p_client_lookup 2460 "http://1.3.5.7/p2p", // p2p_client_result_url 2461 true, // expected_allow_p2p_for_downloading 2462 false, // expected_allow_p2p_for_sharing 2463 "http://1.3.5.7/p2p"); // expected_p2p_url 2464 } 2465 2466 TEST_F(OmahaRequestActionTest, P2PWithPeerBothDisabledByOmaha) { 2467 P2PTest(true, // initial_allow_p2p_for_downloading 2468 true, // initial_allow_p2p_for_sharing 2469 true, // omaha_disable_p2p_for_downloading 2470 true, // omaha_disable_p2p_for_sharing 2471 true, // payload_state_allow_p2p_attempt 2472 false, // expect_p2p_client_lookup 2473 "unset", // p2p_client_result_url 2474 false, // expected_allow_p2p_for_downloading 2475 false, // expected_allow_p2p_for_sharing 2476 ""); // expected_p2p_url 2477 } 2478 2479 bool OmahaRequestActionTest::InstallDateParseHelper(const string &elapsed_days, 2480 OmahaResponse *response) { 2481 fake_update_response_.elapsed_days = elapsed_days; 2482 return 2483 TestUpdateCheck(nullptr, // request_params 2484 fake_update_response_.GetUpdateResponse(), 2485 -1, 2486 false, // ping_only 2487 ErrorCode::kSuccess, 2488 metrics::CheckResult::kUpdateAvailable, 2489 metrics::CheckReaction::kUpdating, 2490 metrics::DownloadErrorCode::kUnset, 2491 response, 2492 nullptr); 2493 } 2494 2495 TEST_F(OmahaRequestActionTest, ParseInstallDateFromResponse) { 2496 OmahaResponse response; 2497 2498 // Simulate a successful update check that happens during OOBE. The 2499 // deadline in the response is needed to force the update attempt to 2500 // occur; responses without a deadline seen during OOBE will normally 2501 // return ErrorCode::kNonCriticalUpdateInOOBE. 2502 fake_system_state_.fake_hardware()->UnsetIsOOBEComplete(); 2503 fake_update_response_.deadline = "20101020"; 2504 2505 // Check that we parse elapsed_days in the Omaha Response correctly. 2506 // and that the kPrefsInstallDateDays value is written to. 2507 EXPECT_FALSE(fake_prefs_.Exists(kPrefsInstallDateDays)); 2508 EXPECT_TRUE(InstallDateParseHelper("42", &response)); 2509 EXPECT_TRUE(response.update_exists); 2510 EXPECT_EQ(42, response.install_date_days); 2511 EXPECT_TRUE(fake_prefs_.Exists(kPrefsInstallDateDays)); 2512 int64_t prefs_days; 2513 EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days)); 2514 EXPECT_EQ(prefs_days, 42); 2515 2516 // If there already is a value set, we shouldn't do anything. 2517 EXPECT_TRUE(InstallDateParseHelper("7", &response)); 2518 EXPECT_TRUE(response.update_exists); 2519 EXPECT_EQ(7, response.install_date_days); 2520 EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days)); 2521 EXPECT_EQ(prefs_days, 42); 2522 2523 // Note that elapsed_days is not necessarily divisible by 7 so check 2524 // that we round down correctly when populating kPrefsInstallDateDays. 2525 EXPECT_TRUE(fake_prefs_.Delete(kPrefsInstallDateDays)); 2526 EXPECT_TRUE(InstallDateParseHelper("23", &response)); 2527 EXPECT_TRUE(response.update_exists); 2528 EXPECT_EQ(23, response.install_date_days); 2529 EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days)); 2530 EXPECT_EQ(prefs_days, 21); 2531 2532 // Check that we correctly handle elapsed_days not being included in 2533 // the Omaha Response. 2534 EXPECT_TRUE(InstallDateParseHelper("", &response)); 2535 EXPECT_TRUE(response.update_exists); 2536 EXPECT_EQ(-1, response.install_date_days); 2537 } 2538 2539 // If there is no prefs and OOBE is not complete, we should not 2540 // report anything to Omaha. 2541 TEST_F(OmahaRequestActionTest, GetInstallDateWhenNoPrefsNorOOBE) { 2542 fake_system_state_.fake_hardware()->UnsetIsOOBEComplete(); 2543 EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), -1); 2544 EXPECT_FALSE(fake_prefs_.Exists(kPrefsInstallDateDays)); 2545 } 2546 2547 // If OOBE is complete and happened on a valid date (e.g. after Jan 2548 // 1 2007 0:00 PST), that date should be used and written to 2549 // prefs. However, first try with an invalid date and check we do 2550 // nothing. 2551 TEST_F(OmahaRequestActionTest, GetInstallDateWhenOOBECompletedWithInvalidDate) { 2552 Time oobe_date = Time::FromTimeT(42); // Dec 31, 1969 16:00:42 PST. 2553 fake_system_state_.fake_hardware()->SetIsOOBEComplete(oobe_date); 2554 EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), -1); 2555 EXPECT_FALSE(fake_prefs_.Exists(kPrefsInstallDateDays)); 2556 } 2557 2558 // Then check with a valid date. The date Jan 20, 2007 0:00 PST 2559 // should yield an InstallDate of 14. 2560 TEST_F(OmahaRequestActionTest, GetInstallDateWhenOOBECompletedWithValidDate) { 2561 Time oobe_date = Time::FromTimeT(1169280000); // Jan 20, 2007 0:00 PST. 2562 fake_system_state_.fake_hardware()->SetIsOOBEComplete(oobe_date); 2563 EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), 14); 2564 EXPECT_TRUE(fake_prefs_.Exists(kPrefsInstallDateDays)); 2565 2566 int64_t prefs_days; 2567 EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days)); 2568 EXPECT_EQ(prefs_days, 14); 2569 } 2570 2571 // Now that we have a valid date in prefs, check that we keep using 2572 // that even if OOBE date reports something else. The date Jan 30, 2573 // 2007 0:00 PST should yield an InstallDate of 28... but since 2574 // there's a prefs file, we should still get 14. 2575 TEST_F(OmahaRequestActionTest, GetInstallDateWhenOOBECompletedDateChanges) { 2576 // Set a valid date in the prefs first. 2577 EXPECT_TRUE(fake_prefs_.SetInt64(kPrefsInstallDateDays, 14)); 2578 2579 Time oobe_date = Time::FromTimeT(1170144000); // Jan 30, 2007 0:00 PST. 2580 fake_system_state_.fake_hardware()->SetIsOOBEComplete(oobe_date); 2581 EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), 14); 2582 2583 int64_t prefs_days; 2584 EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days)); 2585 EXPECT_EQ(prefs_days, 14); 2586 2587 // If we delete the prefs file, we should get 28 days. 2588 EXPECT_TRUE(fake_prefs_.Delete(kPrefsInstallDateDays)); 2589 EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), 28); 2590 EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days)); 2591 EXPECT_EQ(prefs_days, 28); 2592 } 2593 2594 } // namespace chromeos_update_engine 2595