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