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