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