component_updater_service_unittest.cc revision 010d83a9304c5a91596085d917d248abff47903a
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->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. 691 test_configurator()->SetOnDemandTime(60 * 60); 692 EXPECT_EQ( 693 ComponentUpdateService::kError, 694 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 695 // Okay, now reset to 0 for the other tests. 696 test_configurator()->SetOnDemandTime(0); 697 component_updater()->Stop(); 698 699 // Test a few error cases. NOTE: We don't have callbacks for 700 // when the updates failed yet. 701 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); 702 { 703 InSequence seq; 704 EXPECT_CALL(observer, 705 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 706 .Times(1); 707 EXPECT_CALL(observer, 708 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 709 "abagagagagagagagagagagagagagagag")) 710 .Times(1); 711 EXPECT_CALL(observer, 712 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 713 "jebgalgnebhfojomionfpkfelancnnkf")) 714 .Times(1); 715 EXPECT_CALL(observer, 716 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 717 .Times(1); 718 } 719 720 // No update: error from no server response 721 post_interceptor_->Reset(); 722 EXPECT_TRUE(post_interceptor_->ExpectRequest( 723 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty"))); 724 725 test_configurator()->SetLoopCount(1); 726 component_updater()->Start(); 727 EXPECT_EQ( 728 ComponentUpdateService::kOk, 729 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 730 RunThreads(); 731 component_updater()->Stop(); 732 733 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 734 << post_interceptor_->GetRequestsAsString(); 735 EXPECT_EQ(1, post_interceptor_->GetCount()) 736 << post_interceptor_->GetRequestsAsString(); 737 738 // No update: already updated to 1.0 so nothing new 739 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); 740 { 741 InSequence seq; 742 EXPECT_CALL(observer, 743 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 744 .Times(1); 745 EXPECT_CALL(observer, 746 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 747 "jebgalgnebhfojomionfpkfelancnnkf")) 748 .Times(1); 749 EXPECT_CALL(observer, 750 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 751 "abagagagagagagagagagagagagagagag")) 752 .Times(1); 753 EXPECT_CALL(observer, 754 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 755 .Times(1); 756 } 757 758 post_interceptor_->Reset(); 759 EXPECT_TRUE(post_interceptor_->ExpectRequest( 760 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 761 762 test_configurator()->SetLoopCount(1); 763 component_updater()->Start(); 764 EXPECT_EQ( 765 ComponentUpdateService::kOk, 766 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 767 RunThreads(); 768 769 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 770 << post_interceptor_->GetRequestsAsString(); 771 EXPECT_EQ(1, post_interceptor_->GetCount()) 772 << post_interceptor_->GetRequestsAsString(); 773 774 component_updater()->Stop(); 775} 776 777// Verify that a previously registered component can get re-registered 778// with a different version. 779TEST_F(ComponentUpdaterTest, CheckReRegistration) { 780 MockServiceObserver observer; 781 { 782 InSequence seq; 783 EXPECT_CALL(observer, 784 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 785 .Times(1); 786 EXPECT_CALL(observer, 787 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND, 788 "jebgalgnebhfojomionfpkfelancnnkf")) 789 .Times(1); 790 EXPECT_CALL(observer, 791 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 792 "abagagagagagagagagagagagagagagag")) 793 .Times(1); 794 EXPECT_CALL(observer, 795 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING, 796 "jebgalgnebhfojomionfpkfelancnnkf")) 797 .Times(AnyNumber()); 798 EXPECT_CALL(observer, 799 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY, 800 "jebgalgnebhfojomionfpkfelancnnkf")) 801 .Times(1); 802 EXPECT_CALL(observer, 803 OnEvent(ServiceObserver::COMPONENT_UPDATED, 804 "jebgalgnebhfojomionfpkfelancnnkf")) 805 .Times(1); 806 EXPECT_CALL(observer, 807 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 808 .Times(1); 809 EXPECT_CALL(observer, 810 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 811 "jebgalgnebhfojomionfpkfelancnnkf")) 812 .Times(1); 813 EXPECT_CALL(observer, 814 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 815 "abagagagagagagagagagagagagagagag")) 816 .Times(1); 817 EXPECT_CALL(observer, 818 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 819 .Times(1); 820 } 821 822 EXPECT_TRUE(post_interceptor_->ExpectRequest( 823 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 824 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 825 EXPECT_TRUE(post_interceptor_->ExpectRequest( 826 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 827 828 get_interceptor_->SetResponse( 829 GURL(expected_crx_url), 830 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 831 832 component_updater()->AddObserver(&observer); 833 834 TestInstaller installer1; 835 CrxComponent com1; 836 RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1); 837 TestInstaller installer2; 838 CrxComponent com2; 839 RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2); 840 841 // Loop twice to issue two checks: (1) with original 0.9 version, update to 842 // 1.0, and do the second check (2) with the updated 1.0 version. 843 test_configurator()->SetLoopCount(2); 844 component_updater()->Start(); 845 RunThreads(); 846 847 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 848 EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count()); 849 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 850 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); 851 852 EXPECT_EQ(3, post_interceptor_->GetHitCount()) 853 << post_interceptor_->GetRequestsAsString(); 854 EXPECT_EQ(1, get_interceptor_->GetHitCount()); 855 856 EXPECT_NE( 857 string::npos, 858 post_interceptor_->GetRequests()[0].find( 859 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 860 "<updatecheck /></app>")) 861 << post_interceptor_->GetRequestsAsString(); 862 EXPECT_NE( 863 string::npos, 864 post_interceptor_->GetRequests()[1].find( 865 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 866 "version=\"0.9\" nextversion=\"1.0\">" 867 "<event eventtype=\"3\" eventresult=\"1\"/>")) 868 << post_interceptor_->GetRequestsAsString(); 869 EXPECT_NE( 870 string::npos, 871 post_interceptor_->GetRequests()[2].find( 872 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">" 873 "<updatecheck /></app>")) 874 << post_interceptor_->GetRequestsAsString(); 875 876 component_updater()->Stop(); 877 878 // Now re-register, pretending to be an even newer version (2.2) 879 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); 880 { 881 InSequence seq; 882 EXPECT_CALL(observer, 883 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 884 .Times(1); 885 EXPECT_CALL(observer, 886 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 887 "jebgalgnebhfojomionfpkfelancnnkf")) 888 .Times(1); 889 EXPECT_CALL(observer, 890 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 891 "abagagagagagagagagagagagagagagag")) 892 .Times(1); 893 EXPECT_CALL(observer, 894 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 895 .Times(1); 896 } 897 898 post_interceptor_->Reset(); 899 EXPECT_TRUE(post_interceptor_->ExpectRequest( 900 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 901 902 TestInstaller installer3; 903 EXPECT_EQ(ComponentUpdateService::kReplaced, 904 RegisterComponent( 905 &com1, kTestComponent_jebg, Version("2.2"), &installer3)); 906 907 // Loop once just to notice the check happening with the re-register version. 908 test_configurator()->SetLoopCount(1); 909 component_updater()->Start(); 910 RunThreads(); 911 912 // We created a new installer, so the counts go back to 0. 913 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 914 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count()); 915 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 916 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); 917 918 // One update check and no additional pings are expected. 919 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 920 << post_interceptor_->GetRequestsAsString(); 921 EXPECT_EQ(1, post_interceptor_->GetCount()) 922 << post_interceptor_->GetRequestsAsString(); 923 924 EXPECT_NE( 925 string::npos, 926 post_interceptor_->GetRequests()[0].find( 927 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"2.2\">" 928 "<updatecheck /></app>")); 929 930 component_updater()->Stop(); 931} 932 933// Verify that we can download and install a component and a differential 934// update to that component. We do three loops; the final loop should do 935// nothing. 936// We also check that exactly 5 non-ping network requests are issued: 937// 1- update check (response: v1 available) 938// 2- download crx (v1) 939// 3- update check (response: v2 available) 940// 4- download differential crx (v1 to v2) 941// 5- update check (response: no further update available) 942// There should be two pings, one for each update. The second will bear a 943// diffresult=1, while the first will not. 944TEST_F(ComponentUpdaterTest, DifferentialUpdate) { 945 EXPECT_TRUE(post_interceptor_->ExpectRequest( 946 new PartialMatch("updatecheck"), 947 test_file("updatecheck_diff_reply_1.xml"))); 948 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 949 EXPECT_TRUE(post_interceptor_->ExpectRequest( 950 new PartialMatch("updatecheck"), 951 test_file("updatecheck_diff_reply_2.xml"))); 952 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 953 EXPECT_TRUE(post_interceptor_->ExpectRequest( 954 new PartialMatch("updatecheck"), 955 test_file("updatecheck_diff_reply_3.xml"))); 956 957 get_interceptor_->SetResponse( 958 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 959 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 960 get_interceptor_->SetResponse( 961 GURL("http://localhost/download/" 962 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 963 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); 964 965 VersionedTestInstaller installer; 966 CrxComponent com; 967 RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); 968 969 test_configurator()->SetLoopCount(3); 970 component_updater()->Start(); 971 RunThreads(); 972 973 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 974 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 975 976 EXPECT_EQ(5, post_interceptor_->GetHitCount()) 977 << post_interceptor_->GetRequestsAsString(); 978 EXPECT_EQ(5, post_interceptor_->GetCount()) 979 << post_interceptor_->GetRequestsAsString(); 980 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 981 982 EXPECT_NE( 983 string::npos, 984 post_interceptor_->GetRequests()[0].find( 985 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">" 986 "<updatecheck /></app>")) 987 << post_interceptor_->GetRequestsAsString(); 988 EXPECT_NE( 989 string::npos, 990 post_interceptor_->GetRequests()[1].find( 991 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 992 "version=\"0.0\" nextversion=\"1.0\">" 993 "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>")) 994 << post_interceptor_->GetRequestsAsString(); 995 EXPECT_NE( 996 string::npos, 997 post_interceptor_->GetRequests()[2].find( 998 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 999 "<updatecheck /><packages><package fp=\"1\"/></packages></app>")) 1000 << post_interceptor_->GetRequestsAsString(); 1001 EXPECT_NE( 1002 string::npos, 1003 post_interceptor_->GetRequests()[3].find( 1004 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1005 "version=\"1.0\" nextversion=\"2.0\">" 1006 "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"1\" " 1007 "previousfp=\"1\" nextfp=\"22\"/>")) 1008 << post_interceptor_->GetRequestsAsString(); 1009 EXPECT_NE( 1010 string::npos, 1011 post_interceptor_->GetRequests()[4].find( 1012 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 1013 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 1014 << post_interceptor_->GetRequestsAsString(); 1015 component_updater()->Stop(); 1016} 1017 1018// Verify that component installation falls back to downloading and installing 1019// a full update if the differential update fails (in this case, because the 1020// installer does not know about the existing files). We do two loops; the final 1021// loop should do nothing. 1022// We also check that exactly 4 non-ping network requests are issued: 1023// 1- update check (loop 1) 1024// 2- download differential crx 1025// 3- download full crx 1026// 4- update check (loop 2 - no update available) 1027// There should be one ping for the first attempted update. 1028// This test is flaky on Android. crbug.com/329883 1029#if defined(OS_ANDROID) 1030#define MAYBE_DifferentialUpdateFails DISABLED_DifferentialUpdateFails 1031#else 1032#define MAYBE_DifferentialUpdateFails DifferentialUpdateFails 1033#endif 1034TEST_F(ComponentUpdaterTest, MAYBE_DifferentialUpdateFails) { 1035 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1036 new PartialMatch("updatecheck"), 1037 test_file("updatecheck_diff_reply_2.xml"))); 1038 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1039 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1040 new PartialMatch("updatecheck"), 1041 test_file("updatecheck_diff_reply_3.xml"))); 1042 1043 get_interceptor_->SetResponse( 1044 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 1045 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 1046 get_interceptor_->SetResponse( 1047 GURL("http://localhost/download/" 1048 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 1049 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); 1050 get_interceptor_->SetResponse( 1051 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), 1052 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); 1053 1054 TestInstaller installer; 1055 CrxComponent com; 1056 RegisterComponent(&com, kTestComponent_ihfo, Version("1.0"), &installer); 1057 1058 test_configurator()->SetLoopCount(2); 1059 component_updater()->Start(); 1060 RunThreads(); 1061 1062 // A failed differential update does not count as a failed install. 1063 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1064 EXPECT_EQ(1, static_cast<TestInstaller*>(com.installer)->install_count()); 1065 1066 EXPECT_EQ(3, post_interceptor_->GetHitCount()) 1067 << post_interceptor_->GetRequestsAsString(); 1068 EXPECT_EQ(3, post_interceptor_->GetCount()) 1069 << post_interceptor_->GetRequestsAsString(); 1070 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 1071 1072 EXPECT_NE( 1073 string::npos, 1074 post_interceptor_->GetRequests()[0].find( 1075 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 1076 "<updatecheck /></app>")) 1077 << post_interceptor_->GetRequestsAsString(); 1078 EXPECT_NE( 1079 string::npos, 1080 post_interceptor_->GetRequests()[1].find( 1081 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1082 "version=\"1.0\" nextversion=\"2.0\">" 1083 "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"0\" " 1084 "differrorcat=\"2\" differrorcode=\"16\" nextfp=\"22\"/>")) 1085 << post_interceptor_->GetRequestsAsString(); 1086 EXPECT_NE( 1087 string::npos, 1088 post_interceptor_->GetRequests()[2].find( 1089 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 1090 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 1091 << post_interceptor_->GetRequestsAsString(); 1092 1093 component_updater()->Stop(); 1094} 1095 1096// Test is flakey on Android bots. See crbug.com/331420. 1097#if defined(OS_ANDROID) 1098#define MAYBE_CheckFailedInstallPing DISABLED_CheckFailedInstallPing 1099#else 1100#define MAYBE_CheckFailedInstallPing CheckFailedInstallPing 1101#endif 1102// Verify that a failed installation causes an install failure ping. 1103TEST_F(ComponentUpdaterTest, MAYBE_CheckFailedInstallPing) { 1104 // This test installer reports installation failure. 1105 class : public TestInstaller { 1106 virtual bool Install(const base::DictionaryValue& manifest, 1107 const base::FilePath& unpack_path) OVERRIDE { 1108 ++install_count_; 1109 base::DeleteFile(unpack_path, true); 1110 return false; 1111 } 1112 } installer; 1113 1114 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1115 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1116 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1117 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1118 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1119 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1120 get_interceptor_->SetResponse( 1121 GURL(expected_crx_url), 1122 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 1123 1124 // Start with 0.9, and attempt update to 1.0. 1125 // Loop twice to issue two checks: (1) with original 0.9 version 1126 // and (2), which should retry with 0.9. 1127 CrxComponent com; 1128 RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); 1129 1130 test_configurator()->SetLoopCount(2); 1131 component_updater()->Start(); 1132 RunThreads(); 1133 1134 EXPECT_EQ(4, post_interceptor_->GetHitCount()) 1135 << post_interceptor_->GetRequestsAsString(); 1136 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 1137 1138 EXPECT_NE( 1139 string::npos, 1140 post_interceptor_->GetRequests()[0].find( 1141 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1142 "<updatecheck /></app>")) 1143 << post_interceptor_->GetRequestsAsString(); 1144 EXPECT_NE( 1145 string::npos, 1146 post_interceptor_->GetRequests()[1].find( 1147 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 1148 "version=\"0.9\" nextversion=\"1.0\">" 1149 "<event eventtype=\"3\" eventresult=\"0\" " 1150 "errorcat=\"3\" errorcode=\"9\"/>")) 1151 << post_interceptor_->GetRequestsAsString(); 1152 EXPECT_NE( 1153 string::npos, 1154 post_interceptor_->GetRequests()[2].find( 1155 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1156 "<updatecheck /></app>")) 1157 << post_interceptor_->GetRequestsAsString(); 1158 EXPECT_NE( 1159 string::npos, 1160 post_interceptor_->GetRequests()[3].find( 1161 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 1162 "version=\"0.9\" nextversion=\"1.0\">" 1163 "<event eventtype=\"3\" eventresult=\"0\" " 1164 "errorcat=\"3\" errorcode=\"9\"/>")) 1165 << post_interceptor_->GetRequestsAsString(); 1166 1167 // Loop once more, but expect no ping because a noupdate response is issued. 1168 // This is necessary to clear out the fire-and-forget ping from the previous 1169 // iteration. 1170 post_interceptor_->Reset(); 1171 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1172 new PartialMatch("updatecheck"), 1173 test_file("updatecheck_reply_noupdate.xml"))); 1174 1175 test_configurator()->SetLoopCount(1); 1176 component_updater()->Start(); 1177 RunThreads(); 1178 1179 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1180 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 1181 1182 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 1183 << post_interceptor_->GetRequestsAsString(); 1184 EXPECT_EQ(1, post_interceptor_->GetCount()) 1185 << post_interceptor_->GetRequestsAsString(); 1186 1187 EXPECT_NE( 1188 string::npos, 1189 post_interceptor_->GetRequests()[0].find( 1190 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1191 "<updatecheck /></app>")) 1192 << post_interceptor_->GetRequestsAsString(); 1193 1194 component_updater()->Stop(); 1195} 1196 1197// Verify that we successfully propagate a patcher error. 1198// ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx contains an incorrect 1199// patching instruction that should fail. 1200TEST_F(ComponentUpdaterTest, DifferentialUpdateFailErrorcode) { 1201 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1202 new PartialMatch("updatecheck"), 1203 test_file("updatecheck_diff_reply_1.xml"))); 1204 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1205 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1206 new PartialMatch("updatecheck"), 1207 test_file("updatecheck_diff_reply_2.xml"))); 1208 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1209 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1210 new PartialMatch("updatecheck"), 1211 test_file("updatecheck_diff_reply_3.xml"))); 1212 1213 get_interceptor_->SetResponse( 1214 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 1215 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 1216 // This intercept returns a different file than what is specified in the 1217 // update check response and requested in the download. The file that is 1218 // actually dowloaded contains a patching error, an therefore, an error 1219 // is injected at the time of patching. 1220 get_interceptor_->SetResponse( 1221 GURL("http://localhost/download/" 1222 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 1223 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx")); 1224 get_interceptor_->SetResponse( 1225 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), 1226 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); 1227 1228 VersionedTestInstaller installer; 1229 CrxComponent com; 1230 RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); 1231 1232 test_configurator()->SetLoopCount(3); 1233 component_updater()->Start(); 1234 RunThreads(); 1235 component_updater()->Stop(); 1236 1237 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1238 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 1239 1240 EXPECT_EQ(5, post_interceptor_->GetHitCount()) 1241 << post_interceptor_->GetRequestsAsString(); 1242 EXPECT_EQ(5, post_interceptor_->GetCount()) 1243 << post_interceptor_->GetRequestsAsString(); 1244 EXPECT_EQ(3, get_interceptor_->GetHitCount()); 1245 1246 EXPECT_NE( 1247 string::npos, 1248 post_interceptor_->GetRequests()[0].find( 1249 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">" 1250 "<updatecheck /></app>")) 1251 << post_interceptor_->GetRequestsAsString(); 1252 EXPECT_NE( 1253 string::npos, 1254 post_interceptor_->GetRequests()[1].find( 1255 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1256 "version=\"0.0\" nextversion=\"1.0\">" 1257 "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>")) 1258 << post_interceptor_->GetRequestsAsString(); 1259 EXPECT_NE( 1260 string::npos, 1261 post_interceptor_->GetRequests()[2].find( 1262 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 1263 "<updatecheck /><packages><package fp=\"1\"/></packages></app>")) 1264 << post_interceptor_->GetRequestsAsString(); 1265 EXPECT_NE( 1266 string::npos, 1267 post_interceptor_->GetRequests()[3].find( 1268 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1269 "version=\"1.0\" nextversion=\"2.0\">" 1270 "<event eventtype=\"3\" eventresult=\"1\" " 1271 "diffresult=\"0\" differrorcat=\"2\" " 1272 "differrorcode=\"14\" diffextracode1=\"305\" " 1273 "previousfp=\"1\" nextfp=\"22\"/>")) 1274 << post_interceptor_->GetRequestsAsString(); 1275 EXPECT_NE( 1276 string::npos, 1277 post_interceptor_->GetRequests()[4].find( 1278 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 1279 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 1280 << post_interceptor_->GetRequestsAsString(); 1281} 1282 1283class TestResourceController : public content::ResourceController { 1284 public: 1285 virtual void SetThrottle(content::ResourceThrottle* throttle) {} 1286}; 1287 1288content::ResourceThrottle* RequestTestResourceThrottle( 1289 ComponentUpdateService* cus, 1290 TestResourceController* controller, 1291 const char* crx_id) { 1292 net::TestURLRequestContext context; 1293 net::TestURLRequest url_request(GURL("http://foo.example.com/thing.bin"), 1294 net::DEFAULT_PRIORITY, 1295 NULL, 1296 &context); 1297 1298 content::ResourceThrottle* rt = 1299 cus->GetOnDemandResourceThrottle(&url_request, crx_id); 1300 rt->set_controller_for_testing(controller); 1301 controller->SetThrottle(rt); 1302 return rt; 1303} 1304 1305void RequestAndDeleteResourceThrottle(ComponentUpdateService* cus, 1306 const char* crx_id) { 1307 // By requesting a throttle and deleting it immediately we ensure that we 1308 // hit the case where the component updater tries to use the weak 1309 // pointer to a dead Resource throttle. 1310 class NoCallResourceController : public TestResourceController { 1311 public: 1312 virtual ~NoCallResourceController() {} 1313 virtual void Cancel() OVERRIDE { CHECK(false); } 1314 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); } 1315 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); } 1316 virtual void Resume() OVERRIDE { CHECK(false); } 1317 } controller; 1318 1319 delete RequestTestResourceThrottle(cus, &controller, crx_id); 1320} 1321 1322TEST_F(ComponentUpdaterTest, ResourceThrottleDeletedNoUpdate) { 1323 MockServiceObserver observer; 1324 { 1325 InSequence seq; 1326 EXPECT_CALL(observer, 1327 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1328 .Times(1); 1329 EXPECT_CALL(observer, 1330 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1331 "abagagagagagagagagagagagagagagag")) 1332 .Times(1); 1333 EXPECT_CALL(observer, 1334 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1335 .Times(1); 1336 } 1337 1338 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1339 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1340 1341 TestInstaller installer; 1342 CrxComponent com; 1343 component_updater()->AddObserver(&observer); 1344 EXPECT_EQ( 1345 ComponentUpdateService::kOk, 1346 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 1347 // The following two calls ensure that we don't do an update check via the 1348 // timer, so the only update check should be the on-demand one. 1349 test_configurator()->SetInitialDelay(1000000); 1350 test_configurator()->SetRecheckTime(1000000); 1351 test_configurator()->SetLoopCount(1); 1352 component_updater()->Start(); 1353 1354 RunThreadsUntilIdle(); 1355 1356 EXPECT_EQ(0, post_interceptor_->GetHitCount()); 1357 1358 BrowserThread::PostTask(BrowserThread::IO, 1359 FROM_HERE, 1360 base::Bind(&RequestAndDeleteResourceThrottle, 1361 component_updater(), 1362 "abagagagagagagagagagagagagagagag")); 1363 1364 RunThreads(); 1365 1366 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1367 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1368 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1369 1370 component_updater()->Stop(); 1371} 1372 1373class CancelResourceController : public TestResourceController { 1374 public: 1375 CancelResourceController() : throttle_(NULL), resume_called_(0) {} 1376 virtual ~CancelResourceController() { 1377 // Check that the throttle has been resumed by the time we 1378 // exit the test. 1379 CHECK_EQ(1, resume_called_); 1380 delete throttle_; 1381 } 1382 virtual void Cancel() OVERRIDE { CHECK(false); } 1383 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); } 1384 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); } 1385 virtual void Resume() OVERRIDE { 1386 BrowserThread::PostTask(BrowserThread::IO, 1387 FROM_HERE, 1388 base::Bind(&CancelResourceController::ResumeCalled, 1389 base::Unretained(this))); 1390 } 1391 virtual void SetThrottle(content::ResourceThrottle* throttle) OVERRIDE { 1392 throttle_ = throttle; 1393 bool defer = false; 1394 // Initially the throttle is blocked. The CUS needs to run a 1395 // task on the UI thread to decide if it should unblock. 1396 throttle_->WillStartRequest(&defer); 1397 CHECK(defer); 1398 } 1399 1400 private: 1401 void ResumeCalled() { ++resume_called_; } 1402 1403 content::ResourceThrottle* throttle_; 1404 int resume_called_; 1405}; 1406 1407TEST_F(ComponentUpdaterTest, ResourceThrottleLiveNoUpdate) { 1408 MockServiceObserver observer; 1409 { 1410 InSequence seq; 1411 EXPECT_CALL(observer, 1412 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1413 .Times(1); 1414 EXPECT_CALL(observer, 1415 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1416 "abagagagagagagagagagagagagagagag")) 1417 .Times(1); 1418 EXPECT_CALL(observer, 1419 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1420 .Times(1); 1421 } 1422 1423 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1424 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1425 1426 TestInstaller installer; 1427 CrxComponent com; 1428 component_updater()->AddObserver(&observer); 1429 EXPECT_EQ( 1430 ComponentUpdateService::kOk, 1431 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 1432 // The following two calls ensure that we don't do an update check via the 1433 // timer, so the only update check should be the on-demand one. 1434 test_configurator()->SetInitialDelay(1000000); 1435 test_configurator()->SetRecheckTime(1000000); 1436 test_configurator()->SetLoopCount(1); 1437 component_updater()->Start(); 1438 1439 RunThreadsUntilIdle(); 1440 1441 EXPECT_EQ(0, post_interceptor_->GetHitCount()); 1442 1443 CancelResourceController controller; 1444 1445 BrowserThread::PostTask( 1446 BrowserThread::IO, 1447 FROM_HERE, 1448 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle), 1449 component_updater(), 1450 &controller, 1451 "abagagagagagagagagagagagagagagag")); 1452 1453 RunThreads(); 1454 1455 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1456 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1457 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1458 1459 component_updater()->Stop(); 1460} 1461 1462// Tests adding and removing observers. 1463TEST_F(ComponentUpdaterTest, Observer) { 1464 MockServiceObserver observer1, observer2; 1465 1466 // Expect that two observers see the events. 1467 { 1468 InSequence seq; 1469 EXPECT_CALL(observer1, 1470 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1471 .Times(1); 1472 EXPECT_CALL(observer2, 1473 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1474 .Times(1); 1475 EXPECT_CALL(observer1, 1476 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1477 "abagagagagagagagagagagagagagagag")) 1478 .Times(1); 1479 EXPECT_CALL(observer2, 1480 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1481 "abagagagagagagagagagagagagagagag")) 1482 .Times(1); 1483 EXPECT_CALL(observer1, 1484 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1485 .Times(1); 1486 EXPECT_CALL(observer2, 1487 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1488 .Times(1); 1489 } 1490 1491 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1492 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1493 1494 component_updater()->AddObserver(&observer1); 1495 component_updater()->AddObserver(&observer2); 1496 1497 TestInstaller installer; 1498 CrxComponent com; 1499 EXPECT_EQ( 1500 ComponentUpdateService::kOk, 1501 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 1502 test_configurator()->SetLoopCount(1); 1503 component_updater()->Start(); 1504 RunThreads(); 1505 1506 // After removing the first observer, it's only the second observer that 1507 // gets the events. 1508 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1)); 1509 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2)); 1510 { 1511 InSequence seq; 1512 EXPECT_CALL(observer2, 1513 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1514 .Times(1); 1515 EXPECT_CALL(observer2, 1516 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1517 "abagagagagagagagagagagagagagagag")) 1518 .Times(1); 1519 EXPECT_CALL(observer2, 1520 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1521 .Times(1); 1522 } 1523 1524 component_updater()->RemoveObserver(&observer1); 1525 1526 test_configurator()->SetLoopCount(1); 1527 component_updater()->Start(); 1528 RunThreads(); 1529 1530 // Both observers are removed and no one gets the events. 1531 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1)); 1532 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2)); 1533 component_updater()->RemoveObserver(&observer2); 1534 1535 test_configurator()->SetLoopCount(1); 1536 component_updater()->Start(); 1537 RunThreads(); 1538 1539 component_updater()->Stop(); 1540} 1541 1542} // namespace component_updater 1543