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