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