component_updater_service_unittest.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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 "https" 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. 1010// This test is flaky on Android. crbug.com/329883 1011#if defined(OS_ANDROID) 1012#define MAYBE_DifferentialUpdateFails DISABLED_DifferentialUpdateFails 1013#else 1014#define MAYBE_DifferentialUpdateFails DifferentialUpdateFails 1015#endif 1016TEST_F(ComponentUpdaterTest, MAYBE_DifferentialUpdateFails) { 1017 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1018 "updatecheck"), test_file("updatecheck_diff_reply_2.xml"))); 1019 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1020 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1021 "updatecheck"), test_file("updatecheck_diff_reply_3.xml"))); 1022 1023 get_interceptor_->SetResponse( 1024 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 1025 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 1026 get_interceptor_->SetResponse( 1027 GURL("http://localhost/download/" 1028 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 1029 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); 1030 get_interceptor_->SetResponse( 1031 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), 1032 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); 1033 1034 TestInstaller installer; 1035 CrxComponent com; 1036 RegisterComponent(&com, kTestComponent_ihfo, Version("1.0"), &installer); 1037 1038 test_configurator()->SetLoopCount(2); 1039 component_updater()->Start(); 1040 RunThreads(); 1041 1042 // A failed differential update does not count as a failed install. 1043 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1044 EXPECT_EQ(1, static_cast<TestInstaller*>(com.installer)->install_count()); 1045 1046 EXPECT_EQ(3, post_interceptor_->GetHitCount()) 1047 << post_interceptor_->GetRequestsAsString(); 1048 EXPECT_EQ(3, post_interceptor_->GetCount()) 1049 << post_interceptor_->GetRequestsAsString(); 1050 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 1051 1052 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find( 1053 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 1054 "<updatecheck /></app>")) 1055 << post_interceptor_->GetRequestsAsString(); 1056 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find( 1057 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1058 "version=\"1.0\" nextversion=\"2.0\">" 1059 "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"0\" " 1060 "differrorcat=\"2\" differrorcode=\"16\" nextfp=\"22\"/>")) 1061 << post_interceptor_->GetRequestsAsString(); 1062 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find( 1063 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 1064 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 1065 << post_interceptor_->GetRequestsAsString(); 1066 1067 component_updater()->Stop(); 1068} 1069 1070// Test is flakey on Android bots. See crbug.com/331420. 1071#if defined(OS_ANDROID) 1072#define MAYBE_CheckFailedInstallPing DISABLED_CheckFailedInstallPing 1073#else 1074#define MAYBE_CheckFailedInstallPing CheckFailedInstallPing 1075#endif 1076// Verify that a failed installation causes an install failure ping. 1077 TEST_F(ComponentUpdaterTest, MAYBE_CheckFailedInstallPing) { 1078 // This test installer reports installation failure. 1079 class : public TestInstaller { 1080 virtual bool Install(const base::DictionaryValue& manifest, 1081 const base::FilePath& unpack_path) OVERRIDE { 1082 ++install_count_; 1083 base::DeleteFile(unpack_path, true); 1084 return false; 1085 } 1086 } installer; 1087 1088 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1089 "updatecheck"), test_file("updatecheck_reply_1.xml"))); 1090 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1091 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1092 "updatecheck"), test_file("updatecheck_reply_1.xml"))); 1093 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1094 get_interceptor_->SetResponse( 1095 GURL(expected_crx_url), 1096 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 1097 1098 // Start with 0.9, and attempt update to 1.0. 1099 // Loop twice to issue two checks: (1) with original 0.9 version 1100 // and (2), which should retry with 0.9. 1101 CrxComponent com; 1102 RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); 1103 1104 test_configurator()->SetLoopCount(2); 1105 component_updater()->Start(); 1106 RunThreads(); 1107 1108 EXPECT_EQ(4, post_interceptor_->GetHitCount()) 1109 << post_interceptor_->GetRequestsAsString(); 1110 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 1111 1112 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find( 1113 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1114 "<updatecheck /></app>")) 1115 << post_interceptor_->GetRequestsAsString(); 1116 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find( 1117 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 1118 "version=\"0.9\" nextversion=\"1.0\">" 1119 "<event eventtype=\"3\" eventresult=\"0\" " 1120 "errorcat=\"3\" errorcode=\"9\"/>")) 1121 << post_interceptor_->GetRequestsAsString(); 1122 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find( 1123 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1124 "<updatecheck /></app>")) 1125 << post_interceptor_->GetRequestsAsString(); 1126 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[3].find( 1127 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 1128 "version=\"0.9\" nextversion=\"1.0\">" 1129 "<event eventtype=\"3\" eventresult=\"0\" " 1130 "errorcat=\"3\" errorcode=\"9\"/>")) 1131 << post_interceptor_->GetRequestsAsString(); 1132 1133 // Loop once more, but expect no ping because a noupdate response is issued. 1134 // This is necessary to clear out the fire-and-forget ping from the previous 1135 // iteration. 1136 post_interceptor_->Reset(); 1137 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1138 "updatecheck"), test_file("updatecheck_reply_noupdate.xml"))); 1139 1140 test_configurator()->SetLoopCount(1); 1141 component_updater()->Start(); 1142 RunThreads(); 1143 1144 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1145 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 1146 1147 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 1148 << post_interceptor_->GetRequestsAsString(); 1149 EXPECT_EQ(1, post_interceptor_->GetCount()) 1150 << post_interceptor_->GetRequestsAsString(); 1151 1152 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find( 1153 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1154 "<updatecheck /></app>")) 1155 << post_interceptor_->GetRequestsAsString(); 1156 1157 component_updater()->Stop(); 1158} 1159 1160// Verify that we successfully propagate a patcher error. 1161// ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx contains an incorrect 1162// patching instruction that should fail. 1163TEST_F(ComponentUpdaterTest, DifferentialUpdateFailErrorcode) { 1164 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1165 "updatecheck"), test_file("updatecheck_diff_reply_1.xml"))); 1166 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1167 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1168 "updatecheck"), test_file("updatecheck_diff_reply_2.xml"))); 1169 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1170 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1171 "updatecheck"), test_file("updatecheck_diff_reply_3.xml"))); 1172 1173 get_interceptor_->SetResponse( 1174 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 1175 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 1176 // This intercept returns a different file than what is specified in the 1177 // update check response and requested in the download. The file that is 1178 // actually dowloaded contains a patching error, an therefore, an error 1179 // is injected at the time of patching. 1180 get_interceptor_->SetResponse( 1181 GURL("http://localhost/download/" 1182 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 1183 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx")); 1184 get_interceptor_->SetResponse( 1185 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), 1186 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); 1187 1188 VersionedTestInstaller installer; 1189 CrxComponent com; 1190 RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); 1191 1192 test_configurator()->SetLoopCount(3); 1193 component_updater()->Start(); 1194 RunThreads(); 1195 component_updater()->Stop(); 1196 1197 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1198 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 1199 1200 EXPECT_EQ(5, post_interceptor_->GetHitCount()) 1201 << post_interceptor_->GetRequestsAsString(); 1202 EXPECT_EQ(5, post_interceptor_->GetCount()) 1203 << post_interceptor_->GetRequestsAsString(); 1204 EXPECT_EQ(3, get_interceptor_->GetHitCount()); 1205 1206 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find( 1207 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">" 1208 "<updatecheck /></app>")) 1209 << post_interceptor_->GetRequestsAsString(); 1210 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find( 1211 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1212 "version=\"0.0\" nextversion=\"1.0\">" 1213 "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>")) 1214 << post_interceptor_->GetRequestsAsString(); 1215 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find( 1216 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 1217 "<updatecheck /><packages><package fp=\"1\"/></packages></app>")) 1218 << post_interceptor_->GetRequestsAsString(); 1219 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[3].find( 1220 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1221 "version=\"1.0\" nextversion=\"2.0\">" 1222 "<event eventtype=\"3\" eventresult=\"1\" " 1223 "diffresult=\"0\" differrorcat=\"2\" " 1224 "differrorcode=\"14\" diffextracode1=\"305\" " 1225 "previousfp=\"1\" nextfp=\"22\"/>")) 1226 << post_interceptor_->GetRequestsAsString(); 1227 EXPECT_NE(string::npos, post_interceptor_->GetRequests()[4].find( 1228 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 1229 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 1230 << post_interceptor_->GetRequestsAsString(); 1231} 1232 1233class TestResourceController : public content::ResourceController { 1234 public: 1235 virtual void SetThrottle(content::ResourceThrottle* throttle) {} 1236}; 1237 1238content::ResourceThrottle* RequestTestResourceThrottle( 1239 ComponentUpdateService* cus, 1240 TestResourceController* controller, 1241 const char* crx_id) { 1242 1243 net::TestURLRequestContext context; 1244 net::TestURLRequest url_request( 1245 GURL("http://foo.example.com/thing.bin"), 1246 net::DEFAULT_PRIORITY, 1247 NULL, 1248 &context); 1249 1250 content::ResourceThrottle* rt = 1251 cus->GetOnDemandResourceThrottle(&url_request, crx_id); 1252 rt->set_controller_for_testing(controller); 1253 controller->SetThrottle(rt); 1254 return rt; 1255} 1256 1257void RequestAndDeleteResourceThrottle( 1258 ComponentUpdateService* cus, const char* crx_id) { 1259 // By requesting a throttle and deleting it immediately we ensure that we 1260 // hit the case where the component updater tries to use the weak 1261 // pointer to a dead Resource throttle. 1262 class NoCallResourceController : public TestResourceController { 1263 public: 1264 virtual ~NoCallResourceController() {} 1265 virtual void Cancel() OVERRIDE { CHECK(false); } 1266 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); } 1267 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); } 1268 virtual void Resume() OVERRIDE { CHECK(false); } 1269 } controller; 1270 1271 delete RequestTestResourceThrottle(cus, &controller, crx_id); 1272} 1273 1274TEST_F(ComponentUpdaterTest, ResourceThrottleDeletedNoUpdate) { 1275 MockComponentObserver observer; 1276 EXPECT_CALL(observer, 1277 OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0)) 1278 .Times(1); 1279 EXPECT_CALL(observer, 1280 OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0)) 1281 .Times(1); 1282 EXPECT_CALL(observer, 1283 OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0)) 1284 .Times(1); 1285 1286 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1287 "updatecheck"), test_file("updatecheck_reply_1.xml"))); 1288 1289 TestInstaller installer; 1290 CrxComponent com; 1291 com.observer = &observer; 1292 EXPECT_EQ(ComponentUpdateService::kOk, 1293 RegisterComponent(&com, 1294 kTestComponent_abag, 1295 Version("1.1"), 1296 &installer)); 1297 // The following two calls ensure that we don't do an update check via the 1298 // timer, so the only update check should be the on-demand one. 1299 test_configurator()->SetInitialDelay(1000000); 1300 test_configurator()->SetRecheckTime(1000000); 1301 test_configurator()->SetLoopCount(1); 1302 component_updater()->Start(); 1303 1304 RunThreadsUntilIdle(); 1305 1306 EXPECT_EQ(0, post_interceptor_->GetHitCount()); 1307 1308 BrowserThread::PostTask( 1309 BrowserThread::IO, 1310 FROM_HERE, 1311 base::Bind(&RequestAndDeleteResourceThrottle, 1312 component_updater(), 1313 "abagagagagagagagagagagagagagagag")); 1314 1315 RunThreads(); 1316 1317 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1318 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1319 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1320 1321 component_updater()->Stop(); 1322} 1323 1324class CancelResourceController: public TestResourceController { 1325 public: 1326 CancelResourceController() : throttle_(NULL), resume_called_(0) {} 1327 virtual ~CancelResourceController() { 1328 // Check that the throttle has been resumed by the time we 1329 // exit the test. 1330 CHECK(resume_called_ == 1); 1331 delete throttle_; 1332 } 1333 virtual void Cancel() OVERRIDE { CHECK(false); } 1334 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); } 1335 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); } 1336 virtual void Resume() OVERRIDE { 1337 BrowserThread::PostTask( 1338 BrowserThread::IO, 1339 FROM_HERE, 1340 base::Bind(&CancelResourceController::ResumeCalled, 1341 base::Unretained(this))); 1342 } 1343 virtual void SetThrottle(content::ResourceThrottle* throttle) OVERRIDE { 1344 throttle_ = throttle; 1345 bool defer = false; 1346 // Initially the throttle is blocked. The CUS needs to run a 1347 // task on the UI thread to decide if it should unblock. 1348 throttle_->WillStartRequest(&defer); 1349 CHECK(defer); 1350 } 1351 1352 private: 1353 void ResumeCalled() { ++resume_called_; } 1354 1355 content::ResourceThrottle* throttle_; 1356 int resume_called_; 1357}; 1358 1359TEST_F(ComponentUpdaterTest, ResourceThrottleLiveNoUpdate) { 1360 MockComponentObserver observer; 1361 EXPECT_CALL(observer, 1362 OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0)) 1363 .Times(1); 1364 EXPECT_CALL(observer, 1365 OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0)) 1366 .Times(1); 1367 EXPECT_CALL(observer, 1368 OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0)) 1369 .Times(1); 1370 1371 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch( 1372 "updatecheck"), test_file("updatecheck_reply_1.xml"))); 1373 1374 TestInstaller installer; 1375 CrxComponent com; 1376 com.observer = &observer; 1377 EXPECT_EQ(ComponentUpdateService::kOk, 1378 RegisterComponent(&com, 1379 kTestComponent_abag, 1380 Version("1.1"), 1381 &installer)); 1382 // The following two calls ensure that we don't do an update check via the 1383 // timer, so the only update check should be the on-demand one. 1384 test_configurator()->SetInitialDelay(1000000); 1385 test_configurator()->SetRecheckTime(1000000); 1386 test_configurator()->SetLoopCount(1); 1387 component_updater()->Start(); 1388 1389 RunThreadsUntilIdle(); 1390 1391 EXPECT_EQ(0, post_interceptor_->GetHitCount()); 1392 1393 CancelResourceController controller; 1394 1395 BrowserThread::PostTask( 1396 BrowserThread::IO, 1397 FROM_HERE, 1398 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle), 1399 component_updater(), 1400 &controller, 1401 "abagagagagagagagagagagagagagagag")); 1402 1403 RunThreads(); 1404 1405 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1406 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1407 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1408 1409 component_updater()->Stop(); 1410} 1411 1412 1413} // namespace component_updater 1414 1415