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