component_updater_service_unittest.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
1// Copyright 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/component_updater/test/component_updater_service_unittest.h" 6#include "base/file_util.h" 7#include "base/path_service.h" 8#include "base/run_loop.h" 9#include "base/strings/string_number_conversions.h" 10#include "base/strings/string_util.h" 11#include "base/strings/stringprintf.h" 12#include "base/values.h" 13#include "chrome/browser/component_updater/component_updater_utils.h" 14#include "chrome/browser/component_updater/test/test_installer.h" 15#include "chrome/common/chrome_paths.h" 16#include "content/public/browser/browser_thread.h" 17#include "content/public/browser/resource_controller.h" 18#include "content/public/browser/resource_request_info.h" 19#include "content/public/browser/resource_throttle.h" 20#include "libxml/globals.h" 21#include "net/base/upload_bytes_element_reader.h" 22#include "net/url_request/url_fetcher.h" 23#include "net/url_request/url_request_test_util.h" 24#include "url/gurl.h" 25 26using content::BrowserThread; 27 28using ::testing::_; 29using ::testing::AnyNumber; 30using ::testing::InSequence; 31using ::testing::Mock; 32 33namespace component_updater { 34 35#define POST_INTERCEPT_SCHEME "https" 36#define POST_INTERCEPT_HOSTNAME "localhost2" 37#define POST_INTERCEPT_PATH "/update2" 38 39MockServiceObserver::MockServiceObserver() { 40} 41 42MockServiceObserver::~MockServiceObserver() { 43} 44 45bool PartialMatch::Match(const std::string& actual) const { 46 return actual.find(expected_) != std::string::npos; 47} 48 49TestConfigurator::TestConfigurator() 50 : initial_time_(0), 51 times_(1), 52 recheck_time_(0), 53 ondemand_time_(0), 54 cus_(NULL), 55 context_(new net::TestURLRequestContextGetter( 56 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))) { 57} 58 59TestConfigurator::~TestConfigurator() { 60} 61 62int TestConfigurator::InitialDelay() { 63 return initial_time_; 64} 65 66int TestConfigurator::NextCheckDelay() { 67 // This is called when a new full cycle of checking for updates is going 68 // to happen. In test we normally only test one cycle so it is a good 69 // time to break from the test messageloop Run() method so the test can 70 // finish. 71 if (--times_ <= 0) { 72 quit_closure_.Run(); 73 return 0; 74 } 75 return 1; 76} 77 78int TestConfigurator::StepDelay() { 79 return 0; 80} 81 82int TestConfigurator::StepDelayMedium() { 83 return NextCheckDelay(); 84} 85 86int TestConfigurator::MinimumReCheckWait() { 87 return recheck_time_; 88} 89 90int TestConfigurator::OnDemandDelay() { 91 return ondemand_time_; 92} 93 94GURL TestConfigurator::UpdateUrl() { 95 return GURL(POST_INTERCEPT_SCHEME 96 "://" POST_INTERCEPT_HOSTNAME POST_INTERCEPT_PATH); 97} 98 99GURL TestConfigurator::PingUrl() { 100 return UpdateUrl(); 101} 102 103std::string TestConfigurator::ExtraRequestParams() { 104 return "extra=\"foo\""; 105} 106 107size_t TestConfigurator::UrlSizeLimit() { 108 return 256; 109} 110 111net::URLRequestContextGetter* TestConfigurator::RequestContext() { 112 return context_.get(); 113} 114 115// Don't use the utility process to run code out-of-process. 116bool TestConfigurator::InProcess() { 117 return true; 118} 119 120bool TestConfigurator::DeltasEnabled() const { 121 return true; 122} 123 124bool TestConfigurator::UseBackgroundDownloader() const { 125 return false; 126} 127 128// Set how many update checks are called, the default value is just once. 129void TestConfigurator::SetLoopCount(int times) { 130 times_ = times; 131} 132 133void TestConfigurator::SetRecheckTime(int seconds) { 134 recheck_time_ = seconds; 135} 136 137void TestConfigurator::SetOnDemandTime(int seconds) { 138 ondemand_time_ = seconds; 139} 140 141void TestConfigurator::SetComponentUpdateService(ComponentUpdateService* cus) { 142 cus_ = cus; 143} 144 145void TestConfigurator::SetQuitClosure(const base::Closure& quit_closure) { 146 quit_closure_ = quit_closure; 147} 148 149void TestConfigurator::SetInitialDelay(int seconds) { 150 initial_time_ = seconds; 151} 152 153InterceptorFactory::InterceptorFactory() 154 : URLRequestPostInterceptorFactory(POST_INTERCEPT_SCHEME, 155 POST_INTERCEPT_HOSTNAME) { 156} 157 158InterceptorFactory::~InterceptorFactory() { 159} 160 161URLRequestPostInterceptor* InterceptorFactory::CreateInterceptor() { 162 return URLRequestPostInterceptorFactory::CreateInterceptor( 163 base::FilePath::FromUTF8Unsafe(POST_INTERCEPT_PATH)); 164} 165 166ComponentUpdaterTest::ComponentUpdaterTest() 167 : test_config_(NULL), 168 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) { 169 // The component updater instance under test. 170 test_config_ = new TestConfigurator; 171 component_updater_.reset(ComponentUpdateServiceFactory(test_config_)); 172 test_config_->SetComponentUpdateService(component_updater_.get()); 173 174 // The test directory is chrome/test/data/components. 175 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); 176 test_data_dir_ = test_data_dir_.AppendASCII("components"); 177 178 net::URLFetcher::SetEnableInterceptionForTests(true); 179} 180 181ComponentUpdaterTest::~ComponentUpdaterTest() { 182 net::URLFetcher::SetEnableInterceptionForTests(false); 183} 184 185void ComponentUpdaterTest::SetUp() { 186 get_interceptor_.reset(new GetInterceptor); 187 interceptor_factory_.reset(new InterceptorFactory); 188 post_interceptor_ = interceptor_factory_->CreateInterceptor(); 189 EXPECT_TRUE(post_interceptor_); 190} 191 192void ComponentUpdaterTest::TearDown() { 193 interceptor_factory_.reset(); 194 get_interceptor_.reset(); 195 xmlCleanupGlobals(); 196} 197 198ComponentUpdateService* ComponentUpdaterTest::component_updater() { 199 return component_updater_.get(); 200} 201 202// Makes the full path to a component updater test file. 203const base::FilePath ComponentUpdaterTest::test_file(const char* file) { 204 return test_data_dir_.AppendASCII(file); 205} 206 207TestConfigurator* ComponentUpdaterTest::test_configurator() { 208 return test_config_; 209} 210 211ComponentUpdateService::Status ComponentUpdaterTest::RegisterComponent( 212 CrxComponent* com, 213 TestComponents component, 214 const Version& version, 215 TestInstaller* installer) { 216 if (component == kTestComponent_abag) { 217 com->name = "test_abag"; 218 com->pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash)); 219 } else if (component == kTestComponent_jebg) { 220 com->name = "test_jebg"; 221 com->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash)); 222 } else { 223 com->name = "test_ihfo"; 224 com->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash)); 225 } 226 com->version = version; 227 com->installer = installer; 228 return component_updater_->RegisterComponent(*com); 229} 230 231void ComponentUpdaterTest::RunThreads() { 232 base::RunLoop runloop; 233 test_configurator()->SetQuitClosure(runloop.QuitClosure()); 234 runloop.Run(); 235 236 // Since some tests need to drain currently enqueued tasks such as network 237 // intercepts on the IO thread, run the threads until they are 238 // idle. The component updater service won't loop again until the loop count 239 // is set and the service is started. 240 RunThreadsUntilIdle(); 241} 242 243void ComponentUpdaterTest::RunThreadsUntilIdle() { 244 base::RunLoop().RunUntilIdle(); 245} 246 247ComponentUpdateService::Status OnDemandTester::OnDemand( 248 ComponentUpdateService* cus, 249 const std::string& component_id) { 250 return cus->GetOnDemandUpdater().OnDemandUpdate(component_id); 251} 252 253// Verify that our test fixture work and the component updater can 254// be created and destroyed with no side effects. 255TEST_F(ComponentUpdaterTest, VerifyFixture) { 256 EXPECT_TRUE(component_updater() != NULL); 257} 258 259// Verify that the component updater can be caught in a quick 260// start-shutdown situation. Failure of this test will be a crash. 261TEST_F(ComponentUpdaterTest, StartStop) { 262 component_updater()->Start(); 263 RunThreadsUntilIdle(); 264 component_updater()->Stop(); 265} 266 267// Verify that when the server has no updates, we go back to sleep and 268// the COMPONENT_UPDATER_STARTED and COMPONENT_UPDATER_SLEEPING notifications 269// are generated. No pings are sent. 270TEST_F(ComponentUpdaterTest, CheckCrxSleep) { 271 MockServiceObserver observer; 272 273 EXPECT_CALL(observer, 274 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 275 .Times(1); 276 EXPECT_CALL(observer, 277 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 278 .Times(2); 279 EXPECT_CALL(observer, 280 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 281 "abagagagagagagagagagagagagagagag")) 282 .Times(2); 283 284 EXPECT_TRUE(post_interceptor_->ExpectRequest( 285 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 286 EXPECT_TRUE(post_interceptor_->ExpectRequest( 287 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 288 289 TestInstaller installer; 290 CrxComponent com; 291 component_updater()->AddObserver(&observer); 292 EXPECT_EQ( 293 ComponentUpdateService::kOk, 294 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 295 296 // We loop twice, but there are no updates so we expect two sleep messages. 297 test_configurator()->SetLoopCount(2); 298 component_updater()->Start(); 299 RunThreads(); 300 301 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 302 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 303 304 // Expect to see the two update check requests and no other requests, 305 // including pings. 306 EXPECT_EQ(2, post_interceptor_->GetHitCount()) 307 << post_interceptor_->GetRequestsAsString(); 308 EXPECT_EQ(2, post_interceptor_->GetCount()) 309 << post_interceptor_->GetRequestsAsString(); 310 EXPECT_NE( 311 string::npos, 312 post_interceptor_->GetRequests()[0].find( 313 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">" 314 "<updatecheck /></app>")) 315 << post_interceptor_->GetRequestsAsString(); 316 EXPECT_NE( 317 string::npos, 318 post_interceptor_->GetRequests()[1].find( 319 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">" 320 "<updatecheck /></app>")) 321 << post_interceptor_->GetRequestsAsString(); 322 323 component_updater()->Stop(); 324 325 // Loop twice again but this case we simulate a server error by returning 326 // an empty file. Expect the behavior of the service to be the same as before. 327 EXPECT_CALL(observer, OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 328 .Times(1); 329 EXPECT_CALL(observer, 330 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 331 .Times(2); 332 EXPECT_CALL(observer, 333 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 334 "abagagagagagagagagagagagagagagag")) 335 .Times(2); 336 337 post_interceptor_->Reset(); 338 EXPECT_TRUE(post_interceptor_->ExpectRequest( 339 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty"))); 340 EXPECT_TRUE(post_interceptor_->ExpectRequest( 341 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty"))); 342 343 test_configurator()->SetLoopCount(2); 344 component_updater()->Start(); 345 RunThreads(); 346 347 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 348 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 349 350 EXPECT_EQ(2, post_interceptor_->GetHitCount()) 351 << post_interceptor_->GetRequestsAsString(); 352 EXPECT_EQ(2, post_interceptor_->GetCount()) 353 << post_interceptor_->GetRequestsAsString(); 354 EXPECT_NE( 355 string::npos, 356 post_interceptor_->GetRequests()[0].find( 357 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">" 358 "<updatecheck /></app>")) 359 << post_interceptor_->GetRequestsAsString(); 360 EXPECT_NE( 361 string::npos, 362 post_interceptor_->GetRequests()[1].find( 363 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">" 364 "<updatecheck /></app>")) 365 << post_interceptor_->GetRequestsAsString(); 366 367 component_updater()->Stop(); 368} 369 370// Verify that we can check for updates and install one component. Besides 371// the notifications above COMPONENT_UPDATE_FOUND and COMPONENT_UPDATE_READY 372// should have been fired. We do two loops so the second time around there 373// should be nothing left to do. 374// We also check that the following network requests are issued: 375// 1- update check 376// 2- download crx 377// 3- ping 378// 4- second update check. 379TEST_F(ComponentUpdaterTest, InstallCrx) { 380 MockServiceObserver observer; 381 { 382 InSequence seq; 383 EXPECT_CALL(observer, 384 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 385 .Times(1); 386 EXPECT_CALL(observer, 387 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND, 388 "jebgalgnebhfojomionfpkfelancnnkf")) 389 .Times(1); 390 EXPECT_CALL(observer, 391 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 392 "abagagagagagagagagagagagagagagag")) 393 .Times(1); 394 EXPECT_CALL(observer, 395 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING, 396 "jebgalgnebhfojomionfpkfelancnnkf")) 397 .Times(AnyNumber()); 398 EXPECT_CALL(observer, 399 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY, 400 "jebgalgnebhfojomionfpkfelancnnkf")) 401 .Times(1); 402 EXPECT_CALL(observer, 403 OnEvent(ServiceObserver::COMPONENT_UPDATED, 404 "jebgalgnebhfojomionfpkfelancnnkf")) 405 .Times(1); 406 EXPECT_CALL(observer, 407 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 408 .Times(1); 409 EXPECT_CALL(observer, 410 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 411 "jebgalgnebhfojomionfpkfelancnnkf")) 412 .Times(1); 413 EXPECT_CALL(observer, 414 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 415 "abagagagagagagagagagagagagagagag")) 416 .Times(1); 417 EXPECT_CALL(observer, 418 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 419 .Times(1); 420 } 421 422 EXPECT_TRUE(post_interceptor_->ExpectRequest( 423 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 424 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 425 EXPECT_TRUE(post_interceptor_->ExpectRequest( 426 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 427 428 get_interceptor_->SetResponse( 429 GURL(expected_crx_url), 430 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 431 432 component_updater()->AddObserver(&observer); 433 434 TestInstaller installer1; 435 CrxComponent com1; 436 RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1); 437 TestInstaller installer2; 438 CrxComponent com2; 439 RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2); 440 441 test_configurator()->SetLoopCount(2); 442 component_updater()->Start(); 443 RunThreads(); 444 445 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 446 EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count()); 447 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 448 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); 449 450 // Expect three request in total: two update checks and one ping. 451 EXPECT_EQ(3, post_interceptor_->GetHitCount()) 452 << post_interceptor_->GetRequestsAsString(); 453 EXPECT_EQ(3, post_interceptor_->GetCount()) 454 << post_interceptor_->GetRequestsAsString(); 455 456 // Expect one component download. 457 EXPECT_EQ(1, get_interceptor_->GetHitCount()); 458 459 EXPECT_NE( 460 string::npos, 461 post_interceptor_->GetRequests()[0].find( 462 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 463 "<updatecheck /></app>")) 464 << post_interceptor_->GetRequestsAsString(); 465 EXPECT_NE( 466 string::npos, 467 post_interceptor_->GetRequests()[0].find( 468 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">" 469 "<updatecheck /></app>")) 470 << post_interceptor_->GetRequestsAsString(); 471 472 EXPECT_NE( 473 string::npos, 474 post_interceptor_->GetRequests()[1].find( 475 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 476 "version=\"0.9\" nextversion=\"1.0\">" 477 "<event eventtype=\"3\" eventresult=\"1\"/>")) 478 << post_interceptor_->GetRequestsAsString(); 479 480 EXPECT_NE( 481 string::npos, 482 post_interceptor_->GetRequests()[2].find( 483 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">" 484 "<updatecheck /></app>")); 485 EXPECT_NE( 486 string::npos, 487 post_interceptor_->GetRequests()[2].find( 488 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">" 489 "<updatecheck /></app>")) 490 << post_interceptor_->GetRequestsAsString(); 491 492 // Test the protocol version is correct and the extra request attributes 493 // are included in the request. 494 EXPECT_NE( 495 string::npos, 496 post_interceptor_->GetRequests()[0].find( 497 "request protocol=\"3.0\" extra=\"foo\"")) 498 << post_interceptor_->GetRequestsAsString(); 499 500 // Tokenize the request string to look for specific attributes, which 501 // are important for backward compatibility with the version v2 of the update 502 // protocol. In this case, inspect the <request>, which is the first element 503 // after the xml declaration of the update request body. 504 // Expect to find the |os|, |arch|, |prodchannel|, and |prodversion| 505 // attributes: 506 // <?xml version="1.0" encoding="UTF-8"?> 507 // <request... os=... arch=... prodchannel=... prodversion=...> 508 // ... 509 // </request> 510 const std::string update_request(post_interceptor_->GetRequests()[0]); 511 std::vector<base::StringPiece> elements; 512 Tokenize(update_request, "<>", &elements); 513 EXPECT_NE(string::npos, elements[1].find(" os=")); 514 EXPECT_NE(string::npos, elements[1].find(" arch=")); 515 EXPECT_NE(string::npos, elements[1].find(" prodchannel=")); 516 EXPECT_NE(string::npos, elements[1].find(" prodversion=")); 517 518 // Look for additional attributes of the request, such as |version|, 519 // |requestid|, |lang|, and |nacl_arch|. 520 EXPECT_NE(string::npos, elements[1].find(" version=")); 521 EXPECT_NE(string::npos, elements[1].find(" requestid=")); 522 EXPECT_NE(string::npos, elements[1].find(" lang=")); 523 EXPECT_NE(string::npos, elements[1].find(" nacl_arch=")); 524 525 component_updater()->Stop(); 526} 527 528// This test checks that the "prodversionmin" value is handled correctly. In 529// particular there should not be an install because the minimum product 530// version is much higher than of chrome. 531TEST_F(ComponentUpdaterTest, ProdVersionCheck) { 532 EXPECT_TRUE(post_interceptor_->ExpectRequest( 533 new PartialMatch("updatecheck"), test_file("updatecheck_reply_2.xml"))); 534 535 get_interceptor_->SetResponse( 536 GURL(expected_crx_url), 537 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 538 539 TestInstaller installer; 540 CrxComponent com; 541 RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); 542 543 test_configurator()->SetLoopCount(1); 544 component_updater()->Start(); 545 RunThreads(); 546 547 // Expect one update check and no ping. 548 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 549 << post_interceptor_->GetRequestsAsString(); 550 EXPECT_EQ(1, post_interceptor_->GetCount()) 551 << post_interceptor_->GetRequestsAsString(); 552 553 // Expect no download to occur. 554 EXPECT_EQ(0, get_interceptor_->GetHitCount()); 555 556 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 557 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 558 559 component_updater()->Stop(); 560} 561 562// Test that a update check due to an on demand call can cause installs. 563// Here is the timeline: 564// - First loop: we return a reply that indicates no update, so 565// nothing happens. 566// - We make an on demand call. 567// - This triggers a second loop, which has a reply that triggers an install. 568TEST_F(ComponentUpdaterTest, OnDemandUpdate) { 569 MockServiceObserver observer; 570 { 571 InSequence seq; 572 EXPECT_CALL(observer, 573 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 574 .Times(1); 575 EXPECT_CALL(observer, 576 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 577 "abagagagagagagagagagagagagagagag")) 578 .Times(1); 579 EXPECT_CALL(observer, 580 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 581 "jebgalgnebhfojomionfpkfelancnnkf")) 582 .Times(1); 583 EXPECT_CALL(observer, 584 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 585 .Times(1); 586 EXPECT_CALL(observer, 587 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 588 .Times(1); 589 EXPECT_CALL(observer, 590 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND, 591 "jebgalgnebhfojomionfpkfelancnnkf")) 592 .Times(1); 593 EXPECT_CALL(observer, 594 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 595 "abagagagagagagagagagagagagagagag")) 596 .Times(1); 597 EXPECT_CALL(observer, 598 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING, 599 "jebgalgnebhfojomionfpkfelancnnkf")) 600 .Times(AnyNumber()); 601 EXPECT_CALL(observer, 602 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY, 603 "jebgalgnebhfojomionfpkfelancnnkf")) 604 .Times(1); 605 EXPECT_CALL(observer, 606 OnEvent(ServiceObserver::COMPONENT_UPDATED, 607 "jebgalgnebhfojomionfpkfelancnnkf")) 608 .Times(1); 609 EXPECT_CALL(observer, 610 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 611 .Times(1); 612 } 613 614 EXPECT_TRUE(post_interceptor_->ExpectRequest( 615 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty"))); 616 617 get_interceptor_->SetResponse( 618 GURL(expected_crx_url), 619 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 620 621 component_updater()->AddObserver(&observer); 622 623 TestInstaller installer1; 624 CrxComponent com1; 625 RegisterComponent(&com1, kTestComponent_abag, Version("2.2"), &installer1); 626 TestInstaller installer2; 627 CrxComponent com2; 628 RegisterComponent(&com2, kTestComponent_jebg, Version("0.9"), &installer2); 629 630 // No update normally. 631 test_configurator()->SetLoopCount(1); 632 component_updater()->Start(); 633 RunThreads(); 634 component_updater()->Stop(); 635 636 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 637 << post_interceptor_->GetRequestsAsString(); 638 EXPECT_EQ(1, post_interceptor_->GetCount()) 639 << post_interceptor_->GetRequestsAsString(); 640 641 EXPECT_EQ(0, get_interceptor_->GetHitCount()); 642 643 // Update after an on-demand check is issued. 644 post_interceptor_->Reset(); 645 EXPECT_TRUE(post_interceptor_->ExpectRequest( 646 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 647 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 648 649 EXPECT_EQ( 650 ComponentUpdateService::kOk, 651 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 652 test_configurator()->SetLoopCount(1); 653 component_updater()->Start(); 654 RunThreads(); 655 656 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 657 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count()); 658 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 659 EXPECT_EQ(1, static_cast<TestInstaller*>(com2.installer)->install_count()); 660 661 EXPECT_EQ(2, post_interceptor_->GetHitCount()) 662 << post_interceptor_->GetRequestsAsString(); 663 EXPECT_EQ(2, post_interceptor_->GetCount()) 664 << post_interceptor_->GetRequestsAsString(); 665 666 EXPECT_EQ(1, get_interceptor_->GetHitCount()); 667 668 // Expect the update check to contain an "ondemand" request for the 669 // second component (com2) and a normal request for the other component. 670 EXPECT_NE( 671 string::npos, 672 post_interceptor_->GetRequests()[0].find( 673 "<app appid=\"abagagagagagagagagagagagagagagag\" " 674 "version=\"2.2\"><updatecheck /></app>")) 675 << post_interceptor_->GetRequestsAsString(); 676 EXPECT_NE( 677 string::npos, 678 post_interceptor_->GetRequests()[0].find( 679 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 680 "version=\"0.9\" installsource=\"ondemand\"><updatecheck /></app>")) 681 << post_interceptor_->GetRequestsAsString(); 682 EXPECT_NE( 683 string::npos, 684 post_interceptor_->GetRequests()[1].find( 685 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 686 "version=\"0.9\" nextversion=\"1.0\">" 687 "<event eventtype=\"3\" eventresult=\"1\"/>")) 688 << post_interceptor_->GetRequestsAsString(); 689 690 // Also check what happens if previous check too soon. It works, since this 691 // direct OnDemand call does not implement a cooldown. 692 test_configurator()->SetOnDemandTime(60 * 60); 693 EXPECT_EQ( 694 ComponentUpdateService::kOk, 695 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 696 // Okay, now reset to 0 for the other tests. 697 test_configurator()->SetOnDemandTime(0); 698 component_updater()->Stop(); 699 700 // Test a few error cases. NOTE: We don't have callbacks for 701 // when the updates failed yet. 702 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); 703 { 704 InSequence seq; 705 EXPECT_CALL(observer, 706 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 707 .Times(1); 708 EXPECT_CALL(observer, 709 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 710 "abagagagagagagagagagagagagagagag")) 711 .Times(1); 712 EXPECT_CALL(observer, 713 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 714 "jebgalgnebhfojomionfpkfelancnnkf")) 715 .Times(1); 716 EXPECT_CALL(observer, 717 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 718 .Times(1); 719 } 720 721 // No update: error from no server response 722 post_interceptor_->Reset(); 723 EXPECT_TRUE(post_interceptor_->ExpectRequest( 724 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty"))); 725 726 test_configurator()->SetLoopCount(1); 727 component_updater()->Start(); 728 EXPECT_EQ( 729 ComponentUpdateService::kOk, 730 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 731 RunThreads(); 732 component_updater()->Stop(); 733 734 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 735 << post_interceptor_->GetRequestsAsString(); 736 EXPECT_EQ(1, post_interceptor_->GetCount()) 737 << post_interceptor_->GetRequestsAsString(); 738 739 // No update: already updated to 1.0 so nothing new 740 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); 741 { 742 InSequence seq; 743 EXPECT_CALL(observer, 744 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 745 .Times(1); 746 EXPECT_CALL(observer, 747 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 748 "jebgalgnebhfojomionfpkfelancnnkf")) 749 .Times(1); 750 EXPECT_CALL(observer, 751 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 752 "abagagagagagagagagagagagagagagag")) 753 .Times(1); 754 EXPECT_CALL(observer, 755 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 756 .Times(1); 757 } 758 759 post_interceptor_->Reset(); 760 EXPECT_TRUE(post_interceptor_->ExpectRequest( 761 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 762 763 test_configurator()->SetLoopCount(1); 764 component_updater()->Start(); 765 EXPECT_EQ( 766 ComponentUpdateService::kOk, 767 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 768 RunThreads(); 769 770 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 771 << post_interceptor_->GetRequestsAsString(); 772 EXPECT_EQ(1, post_interceptor_->GetCount()) 773 << post_interceptor_->GetRequestsAsString(); 774 775 component_updater()->Stop(); 776} 777 778// Verify that a previously registered component can get re-registered 779// with a different version. 780TEST_F(ComponentUpdaterTest, CheckReRegistration) { 781 MockServiceObserver observer; 782 { 783 InSequence seq; 784 EXPECT_CALL(observer, 785 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 786 .Times(1); 787 EXPECT_CALL(observer, 788 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND, 789 "jebgalgnebhfojomionfpkfelancnnkf")) 790 .Times(1); 791 EXPECT_CALL(observer, 792 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 793 "abagagagagagagagagagagagagagagag")) 794 .Times(1); 795 EXPECT_CALL(observer, 796 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING, 797 "jebgalgnebhfojomionfpkfelancnnkf")) 798 .Times(AnyNumber()); 799 EXPECT_CALL(observer, 800 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY, 801 "jebgalgnebhfojomionfpkfelancnnkf")) 802 .Times(1); 803 EXPECT_CALL(observer, 804 OnEvent(ServiceObserver::COMPONENT_UPDATED, 805 "jebgalgnebhfojomionfpkfelancnnkf")) 806 .Times(1); 807 EXPECT_CALL(observer, 808 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 809 .Times(1); 810 EXPECT_CALL(observer, 811 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 812 "jebgalgnebhfojomionfpkfelancnnkf")) 813 .Times(1); 814 EXPECT_CALL(observer, 815 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 816 "abagagagagagagagagagagagagagagag")) 817 .Times(1); 818 EXPECT_CALL(observer, 819 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 820 .Times(1); 821 } 822 823 EXPECT_TRUE(post_interceptor_->ExpectRequest( 824 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 825 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 826 EXPECT_TRUE(post_interceptor_->ExpectRequest( 827 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 828 829 get_interceptor_->SetResponse( 830 GURL(expected_crx_url), 831 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 832 833 component_updater()->AddObserver(&observer); 834 835 TestInstaller installer1; 836 CrxComponent com1; 837 RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1); 838 TestInstaller installer2; 839 CrxComponent com2; 840 RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2); 841 842 // Loop twice to issue two checks: (1) with original 0.9 version, update to 843 // 1.0, and do the second check (2) with the updated 1.0 version. 844 test_configurator()->SetLoopCount(2); 845 component_updater()->Start(); 846 RunThreads(); 847 848 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 849 EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count()); 850 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 851 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); 852 853 EXPECT_EQ(3, post_interceptor_->GetHitCount()) 854 << post_interceptor_->GetRequestsAsString(); 855 EXPECT_EQ(1, get_interceptor_->GetHitCount()); 856 857 EXPECT_NE( 858 string::npos, 859 post_interceptor_->GetRequests()[0].find( 860 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 861 "<updatecheck /></app>")) 862 << post_interceptor_->GetRequestsAsString(); 863 EXPECT_NE( 864 string::npos, 865 post_interceptor_->GetRequests()[1].find( 866 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 867 "version=\"0.9\" nextversion=\"1.0\">" 868 "<event eventtype=\"3\" eventresult=\"1\"/>")) 869 << post_interceptor_->GetRequestsAsString(); 870 EXPECT_NE( 871 string::npos, 872 post_interceptor_->GetRequests()[2].find( 873 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">" 874 "<updatecheck /></app>")) 875 << post_interceptor_->GetRequestsAsString(); 876 877 component_updater()->Stop(); 878 879 // Now re-register, pretending to be an even newer version (2.2) 880 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); 881 { 882 InSequence seq; 883 EXPECT_CALL(observer, 884 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 885 .Times(1); 886 EXPECT_CALL(observer, 887 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 888 "jebgalgnebhfojomionfpkfelancnnkf")) 889 .Times(1); 890 EXPECT_CALL(observer, 891 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 892 "abagagagagagagagagagagagagagagag")) 893 .Times(1); 894 EXPECT_CALL(observer, 895 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 896 .Times(1); 897 } 898 899 post_interceptor_->Reset(); 900 EXPECT_TRUE(post_interceptor_->ExpectRequest( 901 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 902 903 TestInstaller installer3; 904 EXPECT_EQ(ComponentUpdateService::kReplaced, 905 RegisterComponent( 906 &com1, kTestComponent_jebg, Version("2.2"), &installer3)); 907 908 // Loop once just to notice the check happening with the re-register version. 909 test_configurator()->SetLoopCount(1); 910 component_updater()->Start(); 911 RunThreads(); 912 913 // We created a new installer, so the counts go back to 0. 914 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 915 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count()); 916 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 917 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); 918 919 // One update check and no additional pings are expected. 920 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 921 << post_interceptor_->GetRequestsAsString(); 922 EXPECT_EQ(1, post_interceptor_->GetCount()) 923 << post_interceptor_->GetRequestsAsString(); 924 925 EXPECT_NE( 926 string::npos, 927 post_interceptor_->GetRequests()[0].find( 928 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"2.2\">" 929 "<updatecheck /></app>")); 930 931 component_updater()->Stop(); 932} 933 934// Verify that we can download and install a component and a differential 935// update to that component. We do three loops; the final loop should do 936// nothing. 937// We also check that exactly 5 non-ping network requests are issued: 938// 1- update check (response: v1 available) 939// 2- download crx (v1) 940// 3- update check (response: v2 available) 941// 4- download differential crx (v1 to v2) 942// 5- update check (response: no further update available) 943// There should be two pings, one for each update. The second will bear a 944// diffresult=1, while the first will not. 945TEST_F(ComponentUpdaterTest, DifferentialUpdate) { 946 EXPECT_TRUE(post_interceptor_->ExpectRequest( 947 new PartialMatch("updatecheck"), 948 test_file("updatecheck_diff_reply_1.xml"))); 949 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 950 EXPECT_TRUE(post_interceptor_->ExpectRequest( 951 new PartialMatch("updatecheck"), 952 test_file("updatecheck_diff_reply_2.xml"))); 953 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 954 EXPECT_TRUE(post_interceptor_->ExpectRequest( 955 new PartialMatch("updatecheck"), 956 test_file("updatecheck_diff_reply_3.xml"))); 957 958 get_interceptor_->SetResponse( 959 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 960 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 961 get_interceptor_->SetResponse( 962 GURL("http://localhost/download/" 963 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 964 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); 965 966 VersionedTestInstaller installer; 967 CrxComponent com; 968 RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); 969 970 test_configurator()->SetLoopCount(3); 971 component_updater()->Start(); 972 RunThreads(); 973 974 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 975 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 976 977 EXPECT_EQ(5, post_interceptor_->GetHitCount()) 978 << post_interceptor_->GetRequestsAsString(); 979 EXPECT_EQ(5, post_interceptor_->GetCount()) 980 << post_interceptor_->GetRequestsAsString(); 981 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 982 983 EXPECT_NE( 984 string::npos, 985 post_interceptor_->GetRequests()[0].find( 986 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">" 987 "<updatecheck /></app>")) 988 << post_interceptor_->GetRequestsAsString(); 989 EXPECT_NE( 990 string::npos, 991 post_interceptor_->GetRequests()[1].find( 992 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 993 "version=\"0.0\" nextversion=\"1.0\">" 994 "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>")) 995 << post_interceptor_->GetRequestsAsString(); 996 EXPECT_NE( 997 string::npos, 998 post_interceptor_->GetRequests()[2].find( 999 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 1000 "<updatecheck /><packages><package fp=\"1\"/></packages></app>")) 1001 << post_interceptor_->GetRequestsAsString(); 1002 EXPECT_NE( 1003 string::npos, 1004 post_interceptor_->GetRequests()[3].find( 1005 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1006 "version=\"1.0\" nextversion=\"2.0\">" 1007 "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"1\" " 1008 "previousfp=\"1\" nextfp=\"22\"/>")) 1009 << post_interceptor_->GetRequestsAsString(); 1010 EXPECT_NE( 1011 string::npos, 1012 post_interceptor_->GetRequests()[4].find( 1013 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 1014 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 1015 << post_interceptor_->GetRequestsAsString(); 1016 component_updater()->Stop(); 1017} 1018 1019// Verify that component installation falls back to downloading and installing 1020// a full update if the differential update fails (in this case, because the 1021// installer does not know about the existing files). We do two loops; the final 1022// loop should do nothing. 1023// We also check that exactly 4 non-ping network requests are issued: 1024// 1- update check (loop 1) 1025// 2- download differential crx 1026// 3- download full crx 1027// 4- update check (loop 2 - no update available) 1028// There should be one ping for the first attempted update. 1029// This test is flaky on Android. crbug.com/329883 1030#if defined(OS_ANDROID) 1031#define MAYBE_DifferentialUpdateFails DISABLED_DifferentialUpdateFails 1032#else 1033#define MAYBE_DifferentialUpdateFails DifferentialUpdateFails 1034#endif 1035TEST_F(ComponentUpdaterTest, MAYBE_DifferentialUpdateFails) { 1036 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1037 new PartialMatch("updatecheck"), 1038 test_file("updatecheck_diff_reply_2.xml"))); 1039 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1040 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1041 new PartialMatch("updatecheck"), 1042 test_file("updatecheck_diff_reply_3.xml"))); 1043 1044 get_interceptor_->SetResponse( 1045 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 1046 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 1047 get_interceptor_->SetResponse( 1048 GURL("http://localhost/download/" 1049 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 1050 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); 1051 get_interceptor_->SetResponse( 1052 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), 1053 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); 1054 1055 TestInstaller installer; 1056 CrxComponent com; 1057 RegisterComponent(&com, kTestComponent_ihfo, Version("1.0"), &installer); 1058 1059 test_configurator()->SetLoopCount(2); 1060 component_updater()->Start(); 1061 RunThreads(); 1062 1063 // A failed differential update does not count as a failed install. 1064 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1065 EXPECT_EQ(1, static_cast<TestInstaller*>(com.installer)->install_count()); 1066 1067 EXPECT_EQ(3, post_interceptor_->GetHitCount()) 1068 << post_interceptor_->GetRequestsAsString(); 1069 EXPECT_EQ(3, post_interceptor_->GetCount()) 1070 << post_interceptor_->GetRequestsAsString(); 1071 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 1072 1073 EXPECT_NE( 1074 string::npos, 1075 post_interceptor_->GetRequests()[0].find( 1076 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 1077 "<updatecheck /></app>")) 1078 << post_interceptor_->GetRequestsAsString(); 1079 EXPECT_NE( 1080 string::npos, 1081 post_interceptor_->GetRequests()[1].find( 1082 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1083 "version=\"1.0\" nextversion=\"2.0\">" 1084 "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"0\" " 1085 "differrorcat=\"2\" differrorcode=\"16\" nextfp=\"22\"/>")) 1086 << post_interceptor_->GetRequestsAsString(); 1087 EXPECT_NE( 1088 string::npos, 1089 post_interceptor_->GetRequests()[2].find( 1090 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 1091 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 1092 << post_interceptor_->GetRequestsAsString(); 1093 1094 component_updater()->Stop(); 1095} 1096 1097// Test is flakey on Android bots. See crbug.com/331420. 1098#if defined(OS_ANDROID) 1099#define MAYBE_CheckFailedInstallPing DISABLED_CheckFailedInstallPing 1100#else 1101#define MAYBE_CheckFailedInstallPing CheckFailedInstallPing 1102#endif 1103// Verify that a failed installation causes an install failure ping. 1104TEST_F(ComponentUpdaterTest, MAYBE_CheckFailedInstallPing) { 1105 // This test installer reports installation failure. 1106 class : public TestInstaller { 1107 virtual bool Install(const base::DictionaryValue& manifest, 1108 const base::FilePath& unpack_path) OVERRIDE { 1109 ++install_count_; 1110 base::DeleteFile(unpack_path, true); 1111 return false; 1112 } 1113 } installer; 1114 1115 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1116 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1117 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1118 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1119 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1120 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1121 get_interceptor_->SetResponse( 1122 GURL(expected_crx_url), 1123 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 1124 1125 // Start with 0.9, and attempt update to 1.0. 1126 // Loop twice to issue two checks: (1) with original 0.9 version 1127 // and (2), which should retry with 0.9. 1128 CrxComponent com; 1129 RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); 1130 1131 test_configurator()->SetLoopCount(2); 1132 component_updater()->Start(); 1133 RunThreads(); 1134 1135 EXPECT_EQ(4, post_interceptor_->GetHitCount()) 1136 << post_interceptor_->GetRequestsAsString(); 1137 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 1138 1139 EXPECT_NE( 1140 string::npos, 1141 post_interceptor_->GetRequests()[0].find( 1142 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1143 "<updatecheck /></app>")) 1144 << post_interceptor_->GetRequestsAsString(); 1145 EXPECT_NE( 1146 string::npos, 1147 post_interceptor_->GetRequests()[1].find( 1148 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 1149 "version=\"0.9\" nextversion=\"1.0\">" 1150 "<event eventtype=\"3\" eventresult=\"0\" " 1151 "errorcat=\"3\" errorcode=\"9\"/>")) 1152 << post_interceptor_->GetRequestsAsString(); 1153 EXPECT_NE( 1154 string::npos, 1155 post_interceptor_->GetRequests()[2].find( 1156 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1157 "<updatecheck /></app>")) 1158 << post_interceptor_->GetRequestsAsString(); 1159 EXPECT_NE( 1160 string::npos, 1161 post_interceptor_->GetRequests()[3].find( 1162 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 1163 "version=\"0.9\" nextversion=\"1.0\">" 1164 "<event eventtype=\"3\" eventresult=\"0\" " 1165 "errorcat=\"3\" errorcode=\"9\"/>")) 1166 << post_interceptor_->GetRequestsAsString(); 1167 1168 // Loop once more, but expect no ping because a noupdate response is issued. 1169 // This is necessary to clear out the fire-and-forget ping from the previous 1170 // iteration. 1171 post_interceptor_->Reset(); 1172 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1173 new PartialMatch("updatecheck"), 1174 test_file("updatecheck_reply_noupdate.xml"))); 1175 1176 test_configurator()->SetLoopCount(1); 1177 component_updater()->Start(); 1178 RunThreads(); 1179 1180 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1181 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 1182 1183 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 1184 << post_interceptor_->GetRequestsAsString(); 1185 EXPECT_EQ(1, post_interceptor_->GetCount()) 1186 << post_interceptor_->GetRequestsAsString(); 1187 1188 EXPECT_NE( 1189 string::npos, 1190 post_interceptor_->GetRequests()[0].find( 1191 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1192 "<updatecheck /></app>")) 1193 << post_interceptor_->GetRequestsAsString(); 1194 1195 component_updater()->Stop(); 1196} 1197 1198// Verify that we successfully propagate a patcher error. 1199// ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx contains an incorrect 1200// patching instruction that should fail. 1201TEST_F(ComponentUpdaterTest, DifferentialUpdateFailErrorcode) { 1202 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1203 new PartialMatch("updatecheck"), 1204 test_file("updatecheck_diff_reply_1.xml"))); 1205 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1206 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1207 new PartialMatch("updatecheck"), 1208 test_file("updatecheck_diff_reply_2.xml"))); 1209 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1210 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1211 new PartialMatch("updatecheck"), 1212 test_file("updatecheck_diff_reply_3.xml"))); 1213 1214 get_interceptor_->SetResponse( 1215 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 1216 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 1217 // This intercept returns a different file than what is specified in the 1218 // update check response and requested in the download. The file that is 1219 // actually dowloaded contains a patching error, an therefore, an error 1220 // is injected at the time of patching. 1221 get_interceptor_->SetResponse( 1222 GURL("http://localhost/download/" 1223 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 1224 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx")); 1225 get_interceptor_->SetResponse( 1226 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), 1227 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); 1228 1229 VersionedTestInstaller installer; 1230 CrxComponent com; 1231 RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); 1232 1233 test_configurator()->SetLoopCount(3); 1234 component_updater()->Start(); 1235 RunThreads(); 1236 component_updater()->Stop(); 1237 1238 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1239 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 1240 1241 EXPECT_EQ(5, post_interceptor_->GetHitCount()) 1242 << post_interceptor_->GetRequestsAsString(); 1243 EXPECT_EQ(5, post_interceptor_->GetCount()) 1244 << post_interceptor_->GetRequestsAsString(); 1245 EXPECT_EQ(3, get_interceptor_->GetHitCount()); 1246 1247 EXPECT_NE( 1248 string::npos, 1249 post_interceptor_->GetRequests()[0].find( 1250 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">" 1251 "<updatecheck /></app>")) 1252 << post_interceptor_->GetRequestsAsString(); 1253 EXPECT_NE( 1254 string::npos, 1255 post_interceptor_->GetRequests()[1].find( 1256 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1257 "version=\"0.0\" nextversion=\"1.0\">" 1258 "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>")) 1259 << post_interceptor_->GetRequestsAsString(); 1260 EXPECT_NE( 1261 string::npos, 1262 post_interceptor_->GetRequests()[2].find( 1263 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 1264 "<updatecheck /><packages><package fp=\"1\"/></packages></app>")) 1265 << post_interceptor_->GetRequestsAsString(); 1266 EXPECT_NE( 1267 string::npos, 1268 post_interceptor_->GetRequests()[3].find( 1269 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1270 "version=\"1.0\" nextversion=\"2.0\">" 1271 "<event eventtype=\"3\" eventresult=\"1\" " 1272 "diffresult=\"0\" differrorcat=\"2\" " 1273 "differrorcode=\"14\" diffextracode1=\"305\" " 1274 "previousfp=\"1\" nextfp=\"22\"/>")) 1275 << post_interceptor_->GetRequestsAsString(); 1276 EXPECT_NE( 1277 string::npos, 1278 post_interceptor_->GetRequests()[4].find( 1279 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 1280 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 1281 << post_interceptor_->GetRequestsAsString(); 1282} 1283 1284class TestResourceController : public content::ResourceController { 1285 public: 1286 virtual void SetThrottle(content::ResourceThrottle* throttle) {} 1287}; 1288 1289content::ResourceThrottle* RequestTestResourceThrottle( 1290 ComponentUpdateService* cus, 1291 TestResourceController* controller, 1292 const char* crx_id) { 1293 net::TestURLRequestContext context; 1294 net::TestURLRequest url_request(GURL("http://foo.example.com/thing.bin"), 1295 net::DEFAULT_PRIORITY, 1296 NULL, 1297 &context); 1298 1299 content::ResourceThrottle* rt = 1300 cus->GetOnDemandUpdater().GetOnDemandResourceThrottle(&url_request, 1301 crx_id); 1302 rt->set_controller_for_testing(controller); 1303 controller->SetThrottle(rt); 1304 return rt; 1305} 1306 1307void RequestAndDeleteResourceThrottle(ComponentUpdateService* cus, 1308 const char* crx_id) { 1309 // By requesting a throttle and deleting it immediately we ensure that we 1310 // hit the case where the component updater tries to use the weak 1311 // pointer to a dead Resource throttle. 1312 class NoCallResourceController : public TestResourceController { 1313 public: 1314 virtual ~NoCallResourceController() {} 1315 virtual void Cancel() OVERRIDE { CHECK(false); } 1316 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); } 1317 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); } 1318 virtual void Resume() OVERRIDE { CHECK(false); } 1319 } controller; 1320 1321 delete RequestTestResourceThrottle(cus, &controller, crx_id); 1322} 1323 1324TEST_F(ComponentUpdaterTest, ResourceThrottleDeletedNoUpdate) { 1325 MockServiceObserver observer; 1326 { 1327 InSequence seq; 1328 EXPECT_CALL(observer, 1329 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1330 .Times(1); 1331 EXPECT_CALL(observer, 1332 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1333 "abagagagagagagagagagagagagagagag")) 1334 .Times(1); 1335 EXPECT_CALL(observer, 1336 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1337 .Times(1); 1338 } 1339 1340 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1341 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1342 1343 TestInstaller installer; 1344 CrxComponent com; 1345 component_updater()->AddObserver(&observer); 1346 EXPECT_EQ( 1347 ComponentUpdateService::kOk, 1348 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 1349 // The following two calls ensure that we don't do an update check via the 1350 // timer, so the only update check should be the on-demand one. 1351 test_configurator()->SetInitialDelay(1000000); 1352 test_configurator()->SetRecheckTime(1000000); 1353 test_configurator()->SetLoopCount(1); 1354 component_updater()->Start(); 1355 1356 RunThreadsUntilIdle(); 1357 1358 EXPECT_EQ(0, post_interceptor_->GetHitCount()); 1359 1360 BrowserThread::PostTask(BrowserThread::IO, 1361 FROM_HERE, 1362 base::Bind(&RequestAndDeleteResourceThrottle, 1363 component_updater(), 1364 "abagagagagagagagagagagagagagagag")); 1365 1366 RunThreads(); 1367 1368 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1369 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1370 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1371 1372 component_updater()->Stop(); 1373} 1374 1375class CancelResourceController : public TestResourceController { 1376 public: 1377 CancelResourceController() : throttle_(NULL), resume_called_(0) {} 1378 virtual ~CancelResourceController() { 1379 // Check that the throttle has been resumed by the time we 1380 // exit the test. 1381 CHECK_EQ(1, resume_called_); 1382 delete throttle_; 1383 } 1384 virtual void Cancel() OVERRIDE { CHECK(false); } 1385 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); } 1386 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); } 1387 virtual void Resume() OVERRIDE { 1388 BrowserThread::PostTask(BrowserThread::IO, 1389 FROM_HERE, 1390 base::Bind(&CancelResourceController::ResumeCalled, 1391 base::Unretained(this))); 1392 } 1393 virtual void SetThrottle(content::ResourceThrottle* throttle) OVERRIDE { 1394 throttle_ = throttle; 1395 bool defer = false; 1396 // Initially the throttle is blocked. The CUS needs to run a 1397 // task on the UI thread to decide if it should unblock. 1398 throttle_->WillStartRequest(&defer); 1399 CHECK(defer); 1400 } 1401 1402 private: 1403 void ResumeCalled() { ++resume_called_; } 1404 1405 content::ResourceThrottle* throttle_; 1406 int resume_called_; 1407}; 1408 1409// Tests the on-demand update with resource throttle, including the 1410// cooldown interval between calls. 1411TEST_F(ComponentUpdaterTest, ResourceThrottleLiveNoUpdate) { 1412 MockServiceObserver observer; 1413 { 1414 InSequence seq; 1415 EXPECT_CALL(observer, 1416 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1417 .Times(1); 1418 EXPECT_CALL(observer, 1419 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1420 "abagagagagagagagagagagagagagagag")) 1421 .Times(1); 1422 EXPECT_CALL(observer, 1423 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1424 .Times(1); 1425 EXPECT_CALL(observer, 1426 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1427 .Times(1); 1428 EXPECT_CALL(observer, 1429 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1430 "abagagagagagagagagagagagagagagag")) 1431 .Times(1); 1432 EXPECT_CALL(observer, 1433 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1434 .Times(1); 1435 EXPECT_CALL(observer, 1436 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1437 .Times(1); 1438 } 1439 1440 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1441 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1442 1443 TestInstaller installer; 1444 CrxComponent com; 1445 component_updater()->AddObserver(&observer); 1446 EXPECT_EQ( 1447 ComponentUpdateService::kOk, 1448 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 1449 // The following two calls ensure that we don't do an update check via the 1450 // timer, so the only update check should be the on-demand one. 1451 test_configurator()->SetInitialDelay(1000000); 1452 test_configurator()->SetRecheckTime(1000000); 1453 test_configurator()->SetLoopCount(1); 1454 component_updater()->Start(); 1455 1456 RunThreadsUntilIdle(); 1457 1458 EXPECT_EQ(0, post_interceptor_->GetHitCount()); 1459 1460 { 1461 // First on-demand update check is expected to succeeded. 1462 CancelResourceController controller; 1463 1464 BrowserThread::PostTask( 1465 BrowserThread::IO, 1466 FROM_HERE, 1467 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle), 1468 component_updater(), 1469 &controller, 1470 "abagagagagagagagagagagagagagagag")); 1471 1472 RunThreads(); 1473 1474 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1475 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1476 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1477 1478 component_updater()->Stop(); 1479 } 1480 1481 { 1482 // Second on-demand update check is expected to succeed as well, since there 1483 // is no cooldown interval between calls, due to calling SetOnDemandTime. 1484 test_configurator()->SetOnDemandTime(0); 1485 test_configurator()->SetLoopCount(1); 1486 component_updater()->Start(); 1487 1488 CancelResourceController controller; 1489 1490 BrowserThread::PostTask( 1491 BrowserThread::IO, 1492 FROM_HERE, 1493 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle), 1494 component_updater(), 1495 &controller, 1496 "abagagagagagagagagagagagagagagag")); 1497 1498 RunThreads(); 1499 1500 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1501 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1502 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1503 1504 component_updater()->Stop(); 1505 } 1506 1507 { 1508 // This on-demand call is expected not to trigger a component update check. 1509 test_configurator()->SetOnDemandTime(1000000); 1510 component_updater()->Start(); 1511 1512 CancelResourceController controller; 1513 1514 BrowserThread::PostTask( 1515 BrowserThread::IO, 1516 FROM_HERE, 1517 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle), 1518 component_updater(), 1519 &controller, 1520 "abagagagagagagagagagagagagagagag")); 1521 RunThreadsUntilIdle(); 1522 } 1523} 1524 1525// Tests adding and removing observers. 1526TEST_F(ComponentUpdaterTest, Observer) { 1527 MockServiceObserver observer1, observer2; 1528 1529 // Expect that two observers see the events. 1530 { 1531 InSequence seq; 1532 EXPECT_CALL(observer1, 1533 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1534 .Times(1); 1535 EXPECT_CALL(observer2, 1536 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1537 .Times(1); 1538 EXPECT_CALL(observer1, 1539 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1540 "abagagagagagagagagagagagagagagag")) 1541 .Times(1); 1542 EXPECT_CALL(observer2, 1543 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1544 "abagagagagagagagagagagagagagagag")) 1545 .Times(1); 1546 EXPECT_CALL(observer1, 1547 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1548 .Times(1); 1549 EXPECT_CALL(observer2, 1550 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1551 .Times(1); 1552 } 1553 1554 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1555 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1556 1557 component_updater()->AddObserver(&observer1); 1558 component_updater()->AddObserver(&observer2); 1559 1560 TestInstaller installer; 1561 CrxComponent com; 1562 EXPECT_EQ( 1563 ComponentUpdateService::kOk, 1564 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 1565 test_configurator()->SetLoopCount(1); 1566 component_updater()->Start(); 1567 RunThreads(); 1568 1569 // After removing the first observer, it's only the second observer that 1570 // gets the events. 1571 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1)); 1572 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2)); 1573 { 1574 InSequence seq; 1575 EXPECT_CALL(observer2, 1576 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1577 .Times(1); 1578 EXPECT_CALL(observer2, 1579 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1580 "abagagagagagagagagagagagagagagag")) 1581 .Times(1); 1582 EXPECT_CALL(observer2, 1583 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1584 .Times(1); 1585 } 1586 1587 component_updater()->RemoveObserver(&observer1); 1588 1589 test_configurator()->SetLoopCount(1); 1590 component_updater()->Start(); 1591 RunThreads(); 1592 1593 // Both observers are removed and no one gets the events. 1594 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1)); 1595 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2)); 1596 component_updater()->RemoveObserver(&observer2); 1597 1598 test_configurator()->SetLoopCount(1); 1599 component_updater()->Start(); 1600 RunThreads(); 1601 1602 component_updater()->Stop(); 1603} 1604 1605} // namespace component_updater 1606