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