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