Home | History | Annotate | Download | only in updater
      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 <list>
      6 #include <map>
      7 #include <set>
      8 #include <vector>
      9 
     10 #include "base/bind.h"
     11 #include "base/bind_helpers.h"
     12 #include "base/command_line.h"
     13 #include "base/compiler_specific.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "base/message_loop/message_loop.h"
     17 #include "base/run_loop.h"
     18 #include "base/sequenced_task_runner.h"
     19 #include "base/stl_util.h"
     20 #include "base/strings/string_number_conversions.h"
     21 #include "base/strings/string_split.h"
     22 #include "base/strings/string_util.h"
     23 #include "base/strings/stringprintf.h"
     24 #include "base/threading/thread.h"
     25 #include "base/version.h"
     26 #include "chrome/browser/chrome_notification_types.h"
     27 #include "chrome/browser/extensions/crx_installer.h"
     28 #include "chrome/browser/extensions/extension_error_reporter.h"
     29 #include "chrome/browser/extensions/extension_sync_data.h"
     30 #include "chrome/browser/extensions/extension_system.h"
     31 #include "chrome/browser/extensions/test_extension_prefs.h"
     32 #include "chrome/browser/extensions/test_extension_service.h"
     33 #include "chrome/browser/extensions/test_extension_system.h"
     34 #include "chrome/browser/extensions/updater/extension_downloader.h"
     35 #include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
     36 #include "chrome/browser/extensions/updater/extension_updater.h"
     37 #include "chrome/browser/extensions/updater/manifest_fetch_data.h"
     38 #include "chrome/browser/extensions/updater/request_queue_impl.h"
     39 #include "chrome/browser/google/google_util.h"
     40 #include "chrome/browser/prefs/pref_service_syncable.h"
     41 #include "chrome/common/omaha_query_params/omaha_query_params.h"
     42 #include "chrome/common/pref_names.h"
     43 #include "chrome/test/base/testing_profile.h"
     44 #include "content/public/browser/notification_details.h"
     45 #include "content/public/browser/notification_observer.h"
     46 #include "content/public/browser/notification_registrar.h"
     47 #include "content/public/browser/notification_service.h"
     48 #include "content/public/browser/notification_source.h"
     49 #include "content/public/browser/render_process_host.h"
     50 #include "content/public/test/test_browser_thread_bundle.h"
     51 #include "content/public/test/test_utils.h"
     52 #include "extensions/common/extension.h"
     53 #include "extensions/common/id_util.h"
     54 #include "extensions/common/manifest_constants.h"
     55 #include "libxml/globals.h"
     56 #include "net/base/backoff_entry.h"
     57 #include "net/base/escape.h"
     58 #include "net/base/load_flags.h"
     59 #include "net/url_request/test_url_fetcher_factory.h"
     60 #include "net/url_request/url_request_status.h"
     61 #include "testing/gmock/include/gmock/gmock.h"
     62 #include "testing/gtest/include/gtest/gtest.h"
     63 
     64 #if defined(OS_CHROMEOS)
     65 #include "chrome/browser/chromeos/login/user_manager.h"
     66 #include "chrome/browser/chromeos/settings/cros_settings.h"
     67 #include "chrome/browser/chromeos/settings/device_settings_service.h"
     68 #endif
     69 
     70 using base::Time;
     71 using base::TimeDelta;
     72 using content::BrowserThread;
     73 using testing::DoAll;
     74 using testing::InvokeWithoutArgs;
     75 using testing::Mock;
     76 using testing::Return;
     77 using testing::SetArgPointee;
     78 using testing::_;
     79 
     80 namespace extensions {
     81 
     82 typedef ExtensionDownloaderDelegate::Error Error;
     83 typedef ExtensionDownloaderDelegate::PingResult PingResult;
     84 
     85 namespace {
     86 
     87 const net::BackoffEntry::Policy kNoBackoffPolicy = {
     88   // Number of initial errors (in sequence) to ignore before applying
     89   // exponential back-off rules.
     90   1000,
     91 
     92   // Initial delay for exponential back-off in ms.
     93   0,
     94 
     95   // Factor by which the waiting time will be multiplied.
     96   0,
     97 
     98   // Fuzzing percentage. ex: 10% will spread requests randomly
     99   // between 90%-100% of the calculated time.
    100   0,
    101 
    102   // Maximum amount of time we are willing to delay our request in ms.
    103   0,
    104 
    105   // Time to keep an entry from being discarded even when it
    106   // has no significant state, -1 to never discard.
    107   -1,
    108 
    109   // Don't use initial delay unless the last request was an error.
    110   false,
    111 };
    112 
    113 const char kEmptyUpdateUrlData[] = "";
    114 
    115 int kExpectedLoadFlags =
    116     net::LOAD_DO_NOT_SEND_COOKIES |
    117     net::LOAD_DO_NOT_SAVE_COOKIES |
    118     net::LOAD_DISABLE_CACHE;
    119 
    120 const ManifestFetchData::PingData kNeverPingedData(
    121     ManifestFetchData::kNeverPinged, ManifestFetchData::kNeverPinged, true);
    122 
    123 class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate {
    124  public:
    125   MOCK_METHOD4(OnExtensionDownloadFailed, void(const std::string&,
    126                                                Error,
    127                                                const PingResult&,
    128                                                const std::set<int>&));
    129   MOCK_METHOD6(OnExtensionDownloadFinished, void(const std::string&,
    130                                                  const base::FilePath&,
    131                                                  const GURL&,
    132                                                  const std::string&,
    133                                                  const PingResult&,
    134                                                  const std::set<int>&));
    135   MOCK_METHOD2(GetPingDataForExtension,
    136                bool(const std::string&, ManifestFetchData::PingData*));
    137   MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&));
    138   MOCK_METHOD1(IsExtensionPending, bool(const std::string&));
    139   MOCK_METHOD2(GetExtensionExistingVersion,
    140                bool(const std::string&, std::string*));
    141 
    142   void Wait() {
    143     scoped_refptr<content::MessageLoopRunner> runner =
    144         new content::MessageLoopRunner;
    145     quit_closure_ = runner->QuitClosure();
    146     runner->Run();
    147     quit_closure_.Reset();
    148   }
    149 
    150   void Quit() {
    151     quit_closure_.Run();
    152   }
    153 
    154  private:
    155   base::Closure quit_closure_;
    156 };
    157 
    158 const int kNotificationsObserved[] = {
    159   chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED,
    160   chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
    161 };
    162 
    163 // A class that observes the notifications sent by the ExtensionUpdater and
    164 // the ExtensionDownloader.
    165 class NotificationsObserver : public content::NotificationObserver {
    166  public:
    167   NotificationsObserver() {
    168     for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
    169       count_[i] = 0;
    170       registrar_.Add(this,
    171                      kNotificationsObserved[i],
    172                      content::NotificationService::AllSources());
    173     }
    174   }
    175 
    176   virtual ~NotificationsObserver() {
    177     for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
    178       registrar_.Remove(this,
    179                         kNotificationsObserved[i],
    180                         content::NotificationService::AllSources());
    181     }
    182   }
    183 
    184   size_t StartedCount() { return count_[0]; }
    185   size_t UpdatedCount() { return count_[1]; }
    186 
    187   bool Updated(const std::string& id) {
    188     return updated_.find(id) != updated_.end();
    189   }
    190 
    191   void Wait() {
    192     scoped_refptr<content::MessageLoopRunner> runner =
    193         new content::MessageLoopRunner;
    194     quit_closure_ = runner->QuitClosure();
    195     runner->Run();
    196     quit_closure_.Reset();
    197   }
    198 
    199  private:
    200   virtual void Observe(int type,
    201                        const content::NotificationSource& source,
    202                        const content::NotificationDetails& details) OVERRIDE {
    203     if (!quit_closure_.is_null())
    204       quit_closure_.Run();
    205     for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
    206       if (kNotificationsObserved[i] == type) {
    207         count_[i]++;
    208         if (type == chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND) {
    209           updated_.insert(
    210               content::Details<UpdateDetails>(details)->id);
    211         }
    212         return;
    213       }
    214     }
    215     NOTREACHED();
    216   }
    217 
    218   content::NotificationRegistrar registrar_;
    219   size_t count_[arraysize(kNotificationsObserved)];
    220   std::set<std::string> updated_;
    221   base::Closure quit_closure_;
    222 
    223   DISALLOW_COPY_AND_ASSIGN(NotificationsObserver);
    224 };
    225 
    226 }  // namespace
    227 
    228 // Base class for further specialized test classes.
    229 class MockService : public TestExtensionService {
    230  public:
    231   explicit MockService(TestExtensionPrefs* prefs)
    232       : prefs_(prefs), pending_extension_manager_(*this) {
    233   }
    234 
    235   virtual ~MockService() {}
    236 
    237   virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
    238     ADD_FAILURE() << "Subclass should override this if it will "
    239                   << "be accessed by a test.";
    240     return &pending_extension_manager_;
    241   }
    242 
    243   Profile* profile() { return &profile_; }
    244 
    245   net::URLRequestContextGetter* request_context() {
    246     return profile_.GetRequestContext();
    247   }
    248 
    249   ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
    250 
    251   PrefService* pref_service() { return prefs_->pref_service(); }
    252 
    253   // Creates test extensions and inserts them into list. The name and
    254   // version are all based on their index. If |update_url| is non-null, it
    255   // will be used as the update_url for each extension.
    256   // The |id| is used to distinguish extension names and make sure that
    257   // no two extensions share the same name.
    258   void CreateTestExtensions(int id, int count, ExtensionList *list,
    259                             const std::string* update_url,
    260                             Manifest::Location location) {
    261     for (int i = 1; i <= count; i++) {
    262       DictionaryValue manifest;
    263       manifest.SetString(manifest_keys::kVersion,
    264                          base::StringPrintf("%d.0.0.0", i));
    265       manifest.SetString(manifest_keys::kName,
    266                          base::StringPrintf("Extension %d.%d", id, i));
    267       if (update_url)
    268         manifest.SetString(manifest_keys::kUpdateURL, *update_url);
    269       scoped_refptr<Extension> e =
    270           prefs_->AddExtensionWithManifest(manifest, location);
    271       ASSERT_TRUE(e.get() != NULL);
    272       list->push_back(e);
    273     }
    274   }
    275 
    276  protected:
    277   TestExtensionPrefs* const prefs_;
    278   PendingExtensionManager pending_extension_manager_;
    279   TestingProfile profile_;
    280 
    281  private:
    282   DISALLOW_COPY_AND_ASSIGN(MockService);
    283 };
    284 
    285 
    286 bool ShouldInstallExtensionsOnly(const Extension* extension) {
    287   return extension->GetType() == Manifest::TYPE_EXTENSION;
    288 }
    289 
    290 bool ShouldInstallThemesOnly(const Extension* extension) {
    291   return extension->is_theme();
    292 }
    293 
    294 bool ShouldAlwaysInstall(const Extension* extension) {
    295   return true;
    296 }
    297 
    298 // Loads some pending extension records into a pending extension manager.
    299 void SetupPendingExtensionManagerForTest(
    300     int count,
    301     const GURL& update_url,
    302     PendingExtensionManager* pending_extension_manager) {
    303   for (int i = 1; i <= count; ++i) {
    304     PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
    305         (i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
    306     const bool kIsFromSync = true;
    307     const bool kInstallSilently = true;
    308     const bool kMarkAcknowledged = false;
    309     std::string id = id_util::GenerateId(base::StringPrintf("extension%i", i));
    310 
    311     pending_extension_manager->AddForTesting(
    312         PendingExtensionInfo(id,
    313                              update_url,
    314                              Version(),
    315                              should_allow_install,
    316                              kIsFromSync,
    317                              kInstallSilently,
    318                              Manifest::INTERNAL,
    319                              Extension::NO_FLAGS,
    320                              kMarkAcknowledged));
    321   }
    322 }
    323 
    324 class ServiceForManifestTests : public MockService {
    325  public:
    326   explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
    327       : MockService(prefs) {
    328   }
    329 
    330   virtual ~ServiceForManifestTests() {}
    331 
    332   virtual const Extension* GetExtensionById(
    333       const std::string& id, bool include_disabled) const OVERRIDE {
    334     const Extension* result = extensions_.GetByID(id);
    335     if (result || !include_disabled)
    336       return result;
    337     return disabled_extensions_.GetByID(id);
    338   }
    339 
    340   virtual const ExtensionSet* extensions() const OVERRIDE {
    341     return &extensions_;
    342   }
    343 
    344   virtual const ExtensionSet* disabled_extensions() const OVERRIDE {
    345     return &disabled_extensions_;
    346   }
    347 
    348   virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
    349     return &pending_extension_manager_;
    350   }
    351 
    352   virtual const Extension* GetPendingExtensionUpdate(
    353       const std::string& id) const OVERRIDE {
    354     return NULL;
    355   }
    356 
    357   virtual bool IsExtensionEnabled(const std::string& id) const OVERRIDE {
    358     return !disabled_extensions_.Contains(id);
    359   }
    360 
    361   void set_extensions(ExtensionList extensions) {
    362     for (ExtensionList::const_iterator it = extensions.begin();
    363          it != extensions.end(); ++it) {
    364       extensions_.Insert(*it);
    365     }
    366   }
    367 
    368   void set_disabled_extensions(ExtensionList disabled_extensions) {
    369     for (ExtensionList::const_iterator it = disabled_extensions.begin();
    370          it != disabled_extensions.end(); ++it) {
    371       disabled_extensions_.Insert(*it);
    372     }
    373   }
    374 
    375  private:
    376   ExtensionSet extensions_;
    377   ExtensionSet disabled_extensions_;
    378 };
    379 
    380 class ServiceForDownloadTests : public MockService {
    381  public:
    382   explicit ServiceForDownloadTests(TestExtensionPrefs* prefs)
    383       : MockService(prefs) {
    384   }
    385 
    386   // Add a fake crx installer to be returned by a call to UpdateExtension()
    387   // with a specific ID.  Caller keeps ownership of |crx_installer|.
    388   void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) {
    389     fake_crx_installers_[id] = crx_installer;
    390   }
    391 
    392   virtual bool UpdateExtension(
    393       const std::string& id,
    394       const base::FilePath& extension_path,
    395       const GURL& download_url,
    396       CrxInstaller** out_crx_installer) OVERRIDE {
    397     extension_id_ = id;
    398     install_path_ = extension_path;
    399     download_url_ = download_url;
    400 
    401     if (ContainsKey(fake_crx_installers_, id)) {
    402       *out_crx_installer = fake_crx_installers_[id];
    403       return true;
    404     }
    405 
    406     return false;
    407   }
    408 
    409   virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
    410     return &pending_extension_manager_;
    411   }
    412 
    413   virtual const Extension* GetExtensionById(
    414       const std::string& id, bool) const OVERRIDE {
    415     last_inquired_extension_id_ = id;
    416     return NULL;
    417   }
    418 
    419   const std::string& extension_id() const { return extension_id_; }
    420   const base::FilePath& install_path() const { return install_path_; }
    421   const GURL& download_url() const { return download_url_; }
    422 
    423  private:
    424   // Hold the set of ids that UpdateExtension() should fake success on.
    425   // UpdateExtension(id, ...) will return true iff fake_crx_installers_
    426   // contains key |id|.  |out_install_notification_source| will be set
    427   // to Source<CrxInstaller(fake_crx_installers_[i]).
    428   std::map<std::string, CrxInstaller*> fake_crx_installers_;
    429 
    430   std::string extension_id_;
    431   base::FilePath install_path_;
    432   GURL download_url_;
    433 
    434   // The last extension ID that GetExtensionById was called with.
    435   // Mutable because the method that sets it (GetExtensionById) is const
    436   // in the actual extension service, but must record the last extension
    437   // ID in this test class.
    438   mutable std::string last_inquired_extension_id_;
    439 };
    440 
    441 static const int kUpdateFrequencySecs = 15;
    442 
    443 // Takes a string with KEY=VALUE parameters separated by '&' in |params| and
    444 // puts the key/value pairs into |result|. For keys with no value, the empty
    445 // string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
    446 // "foo", and "c" to "".
    447 static void ExtractParameters(const std::string& params,
    448                               std::map<std::string, std::string>* result) {
    449   std::vector<std::string> pairs;
    450   base::SplitString(params, '&', &pairs);
    451   for (size_t i = 0; i < pairs.size(); i++) {
    452     std::vector<std::string> key_val;
    453     base::SplitString(pairs[i], '=', &key_val);
    454     if (!key_val.empty()) {
    455       std::string key = key_val[0];
    456       EXPECT_TRUE(result->find(key) == result->end());
    457       (*result)[key] = (key_val.size() == 2) ? key_val[1] : std::string();
    458     } else {
    459       NOTREACHED();
    460     }
    461   }
    462 }
    463 
    464 static void VerifyQueryAndExtractParameters(
    465     const std::string& query,
    466     std::map<std::string, std::string>* result) {
    467   std::map<std::string, std::string> params;
    468   ExtractParameters(query, &params);
    469 
    470   std::string omaha_params =
    471       chrome::OmahaQueryParams::Get(chrome::OmahaQueryParams::CRX);
    472   std::map<std::string, std::string> expected;
    473   ExtractParameters(omaha_params, &expected);
    474 
    475   for (std::map<std::string, std::string>::iterator it = expected.begin();
    476        it != expected.end(); ++it) {
    477     EXPECT_EQ(it->second, params[it->first]);
    478   }
    479 
    480   EXPECT_EQ(1U, params.count("x"));
    481   std::string decoded = net::UnescapeURLComponent(
    482       params["x"], net::UnescapeRule::URL_SPECIAL_CHARS);
    483   ExtractParameters(decoded, result);
    484 }
    485 
    486 // All of our tests that need to use private APIs of ExtensionUpdater live
    487 // inside this class (which is a friend to ExtensionUpdater).
    488 class ExtensionUpdaterTest : public testing::Test {
    489  public:
    490   ExtensionUpdaterTest()
    491       : thread_bundle_(
    492             content::TestBrowserThreadBundle::IO_MAINLOOP) {
    493   }
    494 
    495   virtual void SetUp() OVERRIDE {
    496     prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
    497     content::RenderProcessHost::SetRunRendererInProcess(true);
    498   }
    499 
    500   virtual void TearDown() OVERRIDE {
    501     // Some tests create URLRequestContextGetters, whose destruction must run
    502     // on the IO thread. Make sure the IO loop spins before shutdown so that
    503     // those objects are released.
    504     RunUntilIdle();
    505     prefs_.reset();
    506     content::RenderProcessHost::SetRunRendererInProcess(false);
    507   }
    508 
    509   void RunUntilIdle() {
    510     prefs_->pref_service()->CommitPendingWrite();
    511     base::RunLoop().RunUntilIdle();
    512   }
    513 
    514   void SimulateTimerFired(ExtensionUpdater* updater) {
    515     EXPECT_TRUE(updater->timer_.IsRunning());
    516     updater->timer_.Stop();
    517     updater->TimerFired();
    518   }
    519 
    520   // Adds a Result with the given data to results.
    521   void AddParseResult(const std::string& id,
    522                       const std::string& version,
    523                       const std::string& url,
    524                       UpdateManifest::Results* results) {
    525     UpdateManifest::Result result;
    526     result.extension_id = id;
    527     result.version = version;
    528     result.crx_url = GURL(url);
    529     results->list.push_back(result);
    530   }
    531 
    532   void ResetDownloader(ExtensionUpdater* updater,
    533                        ExtensionDownloader* downloader) {
    534     EXPECT_FALSE(updater->downloader_.get());
    535     updater->downloader_.reset(downloader);
    536   }
    537 
    538   void StartUpdateCheck(ExtensionDownloader* downloader,
    539                         ManifestFetchData* fetch_data) {
    540     downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data));
    541   }
    542 
    543   size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
    544     return downloader->manifests_queue_.size() +
    545            (downloader->manifest_fetcher_.get() ? 1 : 0);
    546   }
    547 
    548   void TestExtensionUpdateCheckRequests(bool pending) {
    549     // Create an extension with an update_url.
    550     ServiceForManifestTests service(prefs_.get());
    551     std::string update_url("http://foo.com/bar");
    552     ExtensionList extensions;
    553     NotificationsObserver observer;
    554     PendingExtensionManager* pending_extension_manager =
    555         service.pending_extension_manager();
    556     if (pending) {
    557       SetupPendingExtensionManagerForTest(1, GURL(update_url),
    558                                           pending_extension_manager);
    559     } else {
    560       service.CreateTestExtensions(1, 1, &extensions, &update_url,
    561                                    Manifest::INTERNAL);
    562       service.set_extensions(extensions);
    563     }
    564 
    565     // Set up and start the updater.
    566     net::TestURLFetcherFactory factory;
    567     ExtensionUpdater updater(
    568         &service, service.extension_prefs(), service.pref_service(),
    569         service.profile(), 60*60*24);
    570     updater.Start();
    571 
    572     // Tell the update that it's time to do update checks.
    573     EXPECT_EQ(0u, observer.StartedCount());
    574     SimulateTimerFired(&updater);
    575     EXPECT_EQ(1u, observer.StartedCount());
    576 
    577     // Get the url our mock fetcher was asked to fetch.
    578     net::TestURLFetcher* fetcher =
    579         factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
    580     const GURL& url = fetcher->GetOriginalURL();
    581     EXPECT_FALSE(url.is_empty());
    582     EXPECT_TRUE(url.is_valid());
    583     EXPECT_TRUE(url.SchemeIs("http"));
    584     EXPECT_EQ("foo.com", url.host());
    585     EXPECT_EQ("/bar", url.path());
    586 
    587     // Validate the extension request parameters in the query. It should
    588     // look something like "x=id%3D<id>%26v%3D<version>%26uc".
    589     EXPECT_TRUE(url.has_query());
    590     std::map<std::string, std::string> params;
    591     VerifyQueryAndExtractParameters(url.query(), &params);
    592     if (pending) {
    593       EXPECT_TRUE(pending_extension_manager->IsIdPending(params["id"]));
    594       EXPECT_EQ("0.0.0.0", params["v"]);
    595     } else {
    596       EXPECT_EQ(extensions[0]->id(), params["id"]);
    597       EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
    598     }
    599     EXPECT_EQ("", params["uc"]);
    600   }
    601 
    602   void TestUpdateUrlDataEmpty() {
    603     const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    604     const std::string version = "1.0";
    605 
    606     // Make sure that an empty update URL data string does not cause a ap=
    607     // option to appear in the x= parameter.
    608     ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
    609     fetch_data.AddExtension(
    610         id, version, &kNeverPingedData, std::string(), std::string());
    611 
    612     std::map<std::string, std::string> params;
    613     VerifyQueryAndExtractParameters(fetch_data.full_url().query(), &params);
    614     EXPECT_EQ(id, params["id"]);
    615     EXPECT_EQ(version, params["v"]);
    616     EXPECT_EQ(0U, params.count("ap"));
    617   }
    618 
    619   void TestUpdateUrlDataSimple() {
    620     const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    621     const std::string version = "1.0";
    622 
    623     // Make sure that an update URL data string causes an appropriate ap=
    624     // option to appear in the x= parameter.
    625     ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
    626     fetch_data.AddExtension(
    627         id, version, &kNeverPingedData, "bar", std::string());
    628     std::map<std::string, std::string> params;
    629     VerifyQueryAndExtractParameters(fetch_data.full_url().query(), &params);
    630     EXPECT_EQ(id, params["id"]);
    631     EXPECT_EQ(version, params["v"]);
    632     EXPECT_EQ("bar", params["ap"]);
    633   }
    634 
    635   void TestUpdateUrlDataCompound() {
    636     const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    637     const std::string version = "1.0";
    638 
    639     // Make sure that an update URL data string causes an appropriate ap=
    640     // option to appear in the x= parameter.
    641     ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
    642     fetch_data.AddExtension(
    643         id, version, &kNeverPingedData, "a=1&b=2&c", std::string());
    644     std::map<std::string, std::string> params;
    645     VerifyQueryAndExtractParameters(fetch_data.full_url().query(), &params);
    646     EXPECT_EQ(id, params["id"]);
    647     EXPECT_EQ(version, params["v"]);
    648     EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]);
    649   }
    650 
    651   void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
    652     net::TestURLFetcherFactory factory;
    653 
    654     MockService service(prefs_.get());
    655     MockExtensionDownloaderDelegate delegate;
    656     ExtensionDownloader downloader(&delegate, service.request_context());
    657     ExtensionList extensions;
    658     std::string url(gallery_url);
    659 
    660     service.CreateTestExtensions(1, 1, &extensions, &url, Manifest::INTERNAL);
    661 
    662     const std::string& id = extensions[0]->id();
    663     EXPECT_CALL(delegate, GetPingDataForExtension(id, _));
    664 
    665     downloader.AddExtension(*extensions[0].get(), 0);
    666     downloader.StartAllPending();
    667     net::TestURLFetcher* fetcher =
    668         factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
    669     ASSERT_TRUE(fetcher);
    670     // Make sure that extensions that update from the gallery ignore any
    671     // update URL data.
    672     const std::string& update_url = fetcher->GetOriginalURL().spec();
    673     std::string::size_type x = update_url.find("x=");
    674     EXPECT_NE(std::string::npos, x);
    675     std::string::size_type ap = update_url.find("ap%3D", x);
    676     EXPECT_EQ(std::string::npos, ap);
    677   }
    678 
    679   void TestInstallSource() {
    680     const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    681     const std::string version = "1.0";
    682     const std::string install_source = "instally";
    683 
    684     // Make sure that an installsource= appears in the x= parameter.
    685     ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
    686     fetch_data.AddExtension(id, version, &kNeverPingedData,
    687                             kEmptyUpdateUrlData, install_source);
    688     std::map<std::string, std::string> params;
    689     VerifyQueryAndExtractParameters(fetch_data.full_url().query(), &params);
    690     EXPECT_EQ(id, params["id"]);
    691     EXPECT_EQ(version, params["v"]);
    692     EXPECT_EQ(install_source, params["installsource"]);
    693   }
    694 
    695   void TestDetermineUpdates() {
    696     TestingProfile profile;
    697     MockExtensionDownloaderDelegate delegate;
    698     ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
    699 
    700     // Check passing an empty list of parse results to DetermineUpdates
    701     ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
    702     UpdateManifest::Results updates;
    703     std::vector<int> updateable;
    704     downloader.DetermineUpdates(fetch_data, updates, &updateable);
    705     EXPECT_TRUE(updateable.empty());
    706 
    707     // Create two updates - expect that DetermineUpdates will return the first
    708     // one (v1.0 installed, v1.1 available) but not the second one (both
    709     // installed and available at v2.0).
    710     const std::string id1 = id_util::GenerateId("1");
    711     const std::string id2 = id_util::GenerateId("2");
    712     fetch_data.AddExtension(
    713         id1, "1.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string());
    714     AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);
    715     fetch_data.AddExtension(
    716         id2, "2.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string());
    717     AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);
    718 
    719     EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
    720     EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
    721         .WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"),
    722                         Return(true)));
    723     EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
    724         .WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"),
    725                         Return(true)));
    726 
    727     downloader.DetermineUpdates(fetch_data, updates, &updateable);
    728     EXPECT_EQ(1u, updateable.size());
    729     EXPECT_EQ(0, updateable[0]);
    730   }
    731 
    732   void TestDetermineUpdatesPending() {
    733     // Create a set of test extensions
    734     ServiceForManifestTests service(prefs_.get());
    735     PendingExtensionManager* pending_extension_manager =
    736         service.pending_extension_manager();
    737     SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
    738 
    739     TestingProfile profile;
    740     MockExtensionDownloaderDelegate delegate;
    741     ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
    742 
    743     ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
    744     UpdateManifest::Results updates;
    745 
    746     std::list<std::string> ids_for_update_check;
    747     pending_extension_manager->GetPendingIdsForUpdateCheck(
    748         &ids_for_update_check);
    749 
    750     std::list<std::string>::const_iterator it;
    751     for (it = ids_for_update_check.begin();
    752          it != ids_for_update_check.end(); ++it) {
    753       fetch_data.AddExtension(*it,
    754                               "1.0.0.0",
    755                               &kNeverPingedData,
    756                               kEmptyUpdateUrlData,
    757                               std::string());
    758       AddParseResult(*it, "1.1", "http://localhost/e1_1.1.crx", &updates);
    759     }
    760 
    761     // The delegate will tell the downloader that all the extensions are
    762     // pending.
    763     EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(true));
    764 
    765     std::vector<int> updateable;
    766     downloader.DetermineUpdates(fetch_data, updates, &updateable);
    767     // All the apps should be updateable.
    768     EXPECT_EQ(3u, updateable.size());
    769     for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) {
    770       EXPECT_EQ(static_cast<int>(i), updateable[i]);
    771     }
    772   }
    773 
    774   void TestMultipleManifestDownloading() {
    775     net::TestURLFetcherFactory factory;
    776     net::TestURLFetcher* fetcher = NULL;
    777     NotificationsObserver observer;
    778     MockService service(prefs_.get());
    779     MockExtensionDownloaderDelegate delegate;
    780     ExtensionDownloader downloader(&delegate, service.request_context());
    781     downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
    782 
    783     GURL kUpdateUrl("http://localhost/manifest1");
    784 
    785     scoped_ptr<ManifestFetchData> fetch1(new ManifestFetchData(kUpdateUrl, 0));
    786     scoped_ptr<ManifestFetchData> fetch2(new ManifestFetchData(kUpdateUrl, 0));
    787     scoped_ptr<ManifestFetchData> fetch3(new ManifestFetchData(kUpdateUrl, 0));
    788     scoped_ptr<ManifestFetchData> fetch4(new ManifestFetchData(kUpdateUrl, 0));
    789     ManifestFetchData::PingData zeroDays(0, 0, true);
    790     fetch1->AddExtension(
    791         "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
    792     fetch2->AddExtension(
    793         "2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string());
    794     fetch3->AddExtension(
    795         "3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string());
    796     fetch4->AddExtension(
    797         "4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string());
    798 
    799     // This will start the first fetcher and queue the others. The next in queue
    800     // is started as each fetcher receives its response.
    801     downloader.StartUpdateCheck(fetch1.Pass());
    802     downloader.StartUpdateCheck(fetch2.Pass());
    803     downloader.StartUpdateCheck(fetch3.Pass());
    804     downloader.StartUpdateCheck(fetch4.Pass());
    805     RunUntilIdle();
    806 
    807     // The first fetch will fail.
    808     fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
    809     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
    810     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
    811     EXPECT_CALL(delegate, OnExtensionDownloadFailed(
    812         "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
    813     fetcher->set_url(kUpdateUrl);
    814     fetcher->set_status(net::URLRequestStatus());
    815     fetcher->set_response_code(400);
    816     fetcher->delegate()->OnURLFetchComplete(fetcher);
    817     RunUntilIdle();
    818     Mock::VerifyAndClearExpectations(&delegate);
    819 
    820     // The second fetch gets invalid data.
    821     const std::string kInvalidXml = "invalid xml";
    822     fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
    823     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
    824     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
    825     EXPECT_CALL(delegate, OnExtensionDownloadFailed(
    826         "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _))
    827         .WillOnce(InvokeWithoutArgs(&delegate,
    828                                     &MockExtensionDownloaderDelegate::Quit));
    829     fetcher->set_url(kUpdateUrl);
    830     fetcher->set_status(net::URLRequestStatus());
    831     fetcher->set_response_code(200);
    832     fetcher->SetResponseString(kInvalidXml);
    833     fetcher->delegate()->OnURLFetchComplete(fetcher);
    834     delegate.Wait();
    835     Mock::VerifyAndClearExpectations(&delegate);
    836 
    837     // The third fetcher doesn't have an update available.
    838     const std::string kNoUpdate =
    839         "<?xml version='1.0' encoding='UTF-8'?>"
    840         "<gupdate xmlns='http://www.google.com/update2/response'"
    841         "                protocol='2.0'>"
    842         " <app appid='3333'>"
    843         "  <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'"
    844         "               version='3.0.0.0' prodversionmin='3.0.0.0' />"
    845         " </app>"
    846         "</gupdate>";
    847     fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
    848     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
    849     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
    850     EXPECT_CALL(delegate, IsExtensionPending("3333")).WillOnce(Return(false));
    851     EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _))
    852         .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"),
    853                         Return(true)));
    854     EXPECT_CALL(delegate, OnExtensionDownloadFailed(
    855         "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _))
    856         .WillOnce(InvokeWithoutArgs(&delegate,
    857                                     &MockExtensionDownloaderDelegate::Quit));
    858     fetcher->set_url(kUpdateUrl);
    859     fetcher->set_status(net::URLRequestStatus());
    860     fetcher->set_response_code(200);
    861     fetcher->SetResponseString(kNoUpdate);
    862     fetcher->delegate()->OnURLFetchComplete(fetcher);
    863     delegate.Wait();
    864     Mock::VerifyAndClearExpectations(&delegate);
    865 
    866     // The last fetcher has an update.
    867     const std::string kUpdateAvailable =
    868         "<?xml version='1.0' encoding='UTF-8'?>"
    869         "<gupdate xmlns='http://www.google.com/update2/response'"
    870         "                protocol='2.0'>"
    871         " <app appid='4444'>"
    872         "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
    873         "               version='4.0.42.0' prodversionmin='4.0.42.0' />"
    874         " </app>"
    875         "</gupdate>";
    876     fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
    877     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
    878     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
    879     EXPECT_CALL(delegate, IsExtensionPending("4444")).WillOnce(Return(false));
    880     EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _))
    881         .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"),
    882                         Return(true)));
    883     fetcher->set_url(kUpdateUrl);
    884     fetcher->set_status(net::URLRequestStatus());
    885     fetcher->set_response_code(200);
    886     fetcher->SetResponseString(kUpdateAvailable);
    887     fetcher->delegate()->OnURLFetchComplete(fetcher);
    888     observer.Wait();
    889     Mock::VerifyAndClearExpectations(&delegate);
    890 
    891     // Verify that the downloader decided to update this extension.
    892     EXPECT_EQ(1u, observer.UpdatedCount());
    893     EXPECT_TRUE(observer.Updated("4444"));
    894   }
    895 
    896   void TestManifestRetryDownloading() {
    897     net::TestURLFetcherFactory factory;
    898     net::TestURLFetcher* fetcher = NULL;
    899     NotificationsObserver observer;
    900     MockService service(prefs_.get());
    901     MockExtensionDownloaderDelegate delegate;
    902     ExtensionDownloader downloader(&delegate, service.request_context());
    903     downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
    904 
    905     GURL kUpdateUrl("http://localhost/manifest1");
    906 
    907     scoped_ptr<ManifestFetchData> fetch(new ManifestFetchData(kUpdateUrl, 0));
    908     ManifestFetchData::PingData zeroDays(0, 0, true);
    909     fetch->AddExtension(
    910         "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
    911 
    912     // This will start the first fetcher.
    913     downloader.StartUpdateCheck(fetch.Pass());
    914     RunUntilIdle();
    915 
    916     // ExtensionDownloader should retry kMaxRetries times and then fail.
    917     EXPECT_CALL(delegate, OnExtensionDownloadFailed(
    918         "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
    919     for (int i = 0; i <= ExtensionDownloader::kMaxRetries; ++i) {
    920       // All fetches will fail.
    921       fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
    922       EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
    923       EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
    924       fetcher->set_url(kUpdateUrl);
    925       fetcher->set_status(net::URLRequestStatus());
    926       // Code 5xx causes ExtensionDownloader to retry.
    927       fetcher->set_response_code(500);
    928       fetcher->delegate()->OnURLFetchComplete(fetcher);
    929       RunUntilIdle();
    930     }
    931     Mock::VerifyAndClearExpectations(&delegate);
    932 
    933 
    934     // For response codes that are not in the 5xx range ExtensionDownloader
    935     // should not retry.
    936     fetch.reset(new ManifestFetchData(kUpdateUrl, 0));
    937     fetch->AddExtension(
    938         "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
    939 
    940     // This will start the first fetcher.
    941     downloader.StartUpdateCheck(fetch.Pass());
    942     RunUntilIdle();
    943 
    944     EXPECT_CALL(delegate, OnExtensionDownloadFailed(
    945         "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
    946     // The first fetch will fail, and require retrying.
    947     fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
    948     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
    949     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
    950     fetcher->set_url(kUpdateUrl);
    951     fetcher->set_status(net::URLRequestStatus());
    952     fetcher->set_response_code(500);
    953     fetcher->delegate()->OnURLFetchComplete(fetcher);
    954     RunUntilIdle();
    955 
    956     // The second fetch will fail with response 400 and should not cause
    957     // ExtensionDownloader to retry.
    958     fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
    959     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
    960     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
    961     fetcher->set_url(kUpdateUrl);
    962     fetcher->set_status(net::URLRequestStatus());
    963     fetcher->set_response_code(400);
    964     fetcher->delegate()->OnURLFetchComplete(fetcher);
    965     RunUntilIdle();
    966 
    967     Mock::VerifyAndClearExpectations(&delegate);
    968   }
    969 
    970   void TestSingleExtensionDownloading(bool pending, bool retry) {
    971     net::TestURLFetcherFactory factory;
    972     net::TestURLFetcher* fetcher = NULL;
    973     scoped_ptr<ServiceForDownloadTests> service(
    974         new ServiceForDownloadTests(prefs_.get()));
    975     ExtensionUpdater updater(service.get(), service->extension_prefs(),
    976                              service->pref_service(),
    977                              service->profile(),
    978                              kUpdateFrequencySecs);
    979     updater.Start();
    980     ResetDownloader(
    981         &updater,
    982         new ExtensionDownloader(&updater, service->request_context()));
    983     updater.downloader_->extensions_queue_.set_backoff_policy(
    984         &kNoBackoffPolicy);
    985 
    986     GURL test_url("http://localhost/extension.crx");
    987 
    988     std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    989     std::string hash;
    990     Version version("0.0.1");
    991     std::set<int> requests;
    992     requests.insert(0);
    993     scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
    994         new ExtensionDownloader::ExtensionFetch(
    995             id, test_url, hash, version.GetString(), requests));
    996     updater.downloader_->FetchUpdatedExtension(fetch.Pass());
    997 
    998     if (pending) {
    999       const bool kIsFromSync = true;
   1000       const bool kInstallSilently = true;
   1001       const bool kMarkAcknowledged = false;
   1002       PendingExtensionManager* pending_extension_manager =
   1003           service->pending_extension_manager();
   1004       pending_extension_manager->AddForTesting(
   1005           PendingExtensionInfo(id, test_url, version,
   1006                                &ShouldAlwaysInstall, kIsFromSync,
   1007                                kInstallSilently,
   1008                                Manifest::INTERNAL,
   1009                                Extension::NO_FLAGS,
   1010                                kMarkAcknowledged));
   1011     }
   1012 
   1013     // Call back the ExtensionUpdater with a 200 response and some test data
   1014     base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
   1015     fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
   1016     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
   1017     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
   1018 
   1019     if (retry) {
   1020       // Reply with response code 500 to cause ExtensionDownloader to retry
   1021       fetcher->set_url(test_url);
   1022       fetcher->set_status(net::URLRequestStatus());
   1023       fetcher->set_response_code(500);
   1024       fetcher->delegate()->OnURLFetchComplete(fetcher);
   1025 
   1026       RunUntilIdle();
   1027       fetcher = factory.GetFetcherByID(
   1028           ExtensionDownloader::kExtensionFetcherId);
   1029       EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
   1030       EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
   1031     }
   1032 
   1033     fetcher->set_url(test_url);
   1034     fetcher->set_status(net::URLRequestStatus());
   1035     fetcher->set_response_code(200);
   1036     fetcher->SetResponseFilePath(extension_file_path);
   1037     fetcher->delegate()->OnURLFetchComplete(fetcher);
   1038 
   1039     RunUntilIdle();
   1040 
   1041     // Expect that ExtensionUpdater asked the mock extensions service to install
   1042     // a file with the test data for the right id.
   1043     EXPECT_EQ(id, service->extension_id());
   1044     base::FilePath tmpfile_path = service->install_path();
   1045     EXPECT_FALSE(tmpfile_path.empty());
   1046     EXPECT_EQ(test_url, service->download_url());
   1047     EXPECT_EQ(extension_file_path, tmpfile_path);
   1048   }
   1049 
   1050   // Two extensions are updated.  If |updates_start_running| is true, the
   1051   // mock extensions service has UpdateExtension(...) return true, and
   1052   // the test is responsible for creating fake CrxInstallers.  Otherwise,
   1053   // UpdateExtension() returns false, signaling install failures.
   1054   void TestMultipleExtensionDownloading(bool updates_start_running) {
   1055     net::TestURLFetcherFactory factory;
   1056     net::TestURLFetcher* fetcher = NULL;
   1057     ServiceForDownloadTests service(prefs_.get());
   1058     ExtensionUpdater updater(
   1059         &service, service.extension_prefs(), service.pref_service(),
   1060         service.profile(), kUpdateFrequencySecs);
   1061     updater.Start();
   1062     ResetDownloader(
   1063         &updater,
   1064         new ExtensionDownloader(&updater, service.request_context()));
   1065     updater.downloader_->extensions_queue_.set_backoff_policy(
   1066         &kNoBackoffPolicy);
   1067 
   1068     EXPECT_FALSE(updater.crx_install_is_running_);
   1069 
   1070     GURL url1("http://localhost/extension1.crx");
   1071     GURL url2("http://localhost/extension2.crx");
   1072 
   1073     std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
   1074     std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
   1075 
   1076     std::string hash1;
   1077     std::string hash2;
   1078 
   1079     std::string version1 = "0.1";
   1080     std::string version2 = "0.1";
   1081     std::set<int> requests;
   1082     requests.insert(0);
   1083     // Start two fetches
   1084     scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch1(
   1085         new ExtensionDownloader::ExtensionFetch(
   1086             id1, url1, hash1, version1, requests));
   1087     scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch2(
   1088         new ExtensionDownloader::ExtensionFetch(
   1089             id2, url2, hash2, version2, requests));
   1090     updater.downloader_->FetchUpdatedExtension(fetch1.Pass());
   1091     updater.downloader_->FetchUpdatedExtension(fetch2.Pass());
   1092 
   1093     // Make the first fetch complete.
   1094     base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
   1095 
   1096     fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
   1097     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
   1098     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
   1099 
   1100     // We need some CrxInstallers, and CrxInstallers require a real
   1101     // ExtensionService.  Create one on the testing profile.  Any action
   1102     // the CrxInstallers take is on the testing profile's extension
   1103     // service, not on our mock |service|.  This allows us to fake
   1104     // the CrxInstaller actions we want.
   1105     TestingProfile profile;
   1106     static_cast<TestExtensionSystem*>(
   1107         ExtensionSystem::Get(&profile))->
   1108         CreateExtensionService(
   1109             CommandLine::ForCurrentProcess(),
   1110             base::FilePath(),
   1111             false);
   1112     ExtensionService* extension_service =
   1113         ExtensionSystem::Get(&profile)->extension_service();
   1114     extension_service->set_extensions_enabled(true);
   1115     extension_service->set_show_extensions_prompts(false);
   1116 
   1117     scoped_refptr<CrxInstaller> fake_crx1(
   1118         CrxInstaller::CreateSilent(extension_service));
   1119     scoped_refptr<CrxInstaller> fake_crx2(
   1120         CrxInstaller::CreateSilent(extension_service));
   1121 
   1122     if (updates_start_running) {
   1123       // Add fake CrxInstaller to be returned by service.UpdateExtension().
   1124       service.AddFakeCrxInstaller(id1, fake_crx1.get());
   1125       service.AddFakeCrxInstaller(id2, fake_crx2.get());
   1126     } else {
   1127       // If we don't add fake CRX installers, the mock service fakes a failure
   1128       // starting the install.
   1129     }
   1130 
   1131     fetcher->set_url(url1);
   1132     fetcher->set_status(net::URLRequestStatus());
   1133     fetcher->set_response_code(200);
   1134     fetcher->SetResponseFilePath(extension_file_path);
   1135     fetcher->delegate()->OnURLFetchComplete(fetcher);
   1136 
   1137     RunUntilIdle();
   1138 
   1139     // Expect that the service was asked to do an install with the right data.
   1140     base::FilePath tmpfile_path = service.install_path();
   1141     EXPECT_FALSE(tmpfile_path.empty());
   1142     EXPECT_EQ(id1, service.extension_id());
   1143     EXPECT_EQ(url1, service.download_url());
   1144     RunUntilIdle();
   1145 
   1146     // Make sure the second fetch finished and asked the service to do an
   1147     // update.
   1148     base::FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2"));
   1149     fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
   1150     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
   1151     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
   1152 
   1153     fetcher->set_url(url2);
   1154     fetcher->set_status(net::URLRequestStatus());
   1155     fetcher->set_response_code(200);
   1156     fetcher->SetResponseFilePath(extension_file_path2);
   1157     fetcher->delegate()->OnURLFetchComplete(fetcher);
   1158     RunUntilIdle();
   1159 
   1160     if (updates_start_running) {
   1161       EXPECT_TRUE(updater.crx_install_is_running_);
   1162 
   1163       // The second install should not have run, because the first has not
   1164       // sent a notification that it finished.
   1165       EXPECT_EQ(id1, service.extension_id());
   1166       EXPECT_EQ(url1, service.download_url());
   1167 
   1168       // Fake install notice.  This should start the second installation,
   1169       // which will be checked below.
   1170       fake_crx1->NotifyCrxInstallComplete(false);
   1171 
   1172       EXPECT_TRUE(updater.crx_install_is_running_);
   1173     }
   1174 
   1175     EXPECT_EQ(id2, service.extension_id());
   1176     EXPECT_EQ(url2, service.download_url());
   1177     EXPECT_FALSE(service.install_path().empty());
   1178 
   1179     // Make sure the correct crx contents were passed for the update call.
   1180     EXPECT_EQ(extension_file_path2, service.install_path());
   1181 
   1182     if (updates_start_running) {
   1183       EXPECT_TRUE(updater.crx_install_is_running_);
   1184       fake_crx2->NotifyCrxInstallComplete(false);
   1185     }
   1186     EXPECT_FALSE(updater.crx_install_is_running_);
   1187   }
   1188 
   1189   void TestGalleryRequestsWithBrand(bool use_organic_brand_code) {
   1190     google_util::BrandForTesting brand_for_testing(
   1191         use_organic_brand_code ? "GGLS" : "TEST");
   1192 
   1193     // We want to test a variety of combinations of expected ping conditions for
   1194     // rollcall and active pings.
   1195     int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
   1196 
   1197     for (size_t i = 0; i < arraysize(ping_cases); i++) {
   1198       for (size_t j = 0; j < arraysize(ping_cases); j++) {
   1199         for (size_t k = 0; k < 2; k++) {
   1200           int rollcall_ping_days = ping_cases[i];
   1201           int active_ping_days = ping_cases[j];
   1202           // Skip cases where rollcall_ping_days == -1, but
   1203           // active_ping_days > 0, because rollcall_ping_days == -1 means the
   1204           // app was just installed and this is the first update check after
   1205           // installation.
   1206           if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
   1207               active_ping_days > 0)
   1208             continue;
   1209 
   1210           bool active_bit = k > 0;
   1211           TestGalleryRequests(rollcall_ping_days, active_ping_days, active_bit,
   1212                               !use_organic_brand_code);
   1213           ASSERT_FALSE(HasFailure()) <<
   1214             " rollcall_ping_days=" << ping_cases[i] <<
   1215             " active_ping_days=" << ping_cases[j] <<
   1216             " active_bit=" << active_bit;
   1217         }
   1218       }
   1219     }
   1220   }
   1221 
   1222   // Test requests to both a Google server and a non-google server. This allows
   1223   // us to test various combinations of installed (ie roll call) and active
   1224   // (ie app launch) ping scenarios. The invariant is that each type of ping
   1225   // value should be present at most once per day, and can be calculated based
   1226   // on the delta between now and the last ping time (or in the case of active
   1227   // pings, that delta plus whether the app has been active).
   1228   void TestGalleryRequests(int rollcall_ping_days,
   1229                            int active_ping_days,
   1230                            bool active_bit,
   1231                            bool expect_brand_code) {
   1232     net::TestURLFetcherFactory factory;
   1233 
   1234     // Set up 2 mock extensions, one with a google.com update url and one
   1235     // without.
   1236     prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
   1237     ServiceForManifestTests service(prefs_.get());
   1238     ExtensionList tmp;
   1239     GURL url1("http://clients2.google.com/service/update2/crx");
   1240     GURL url2("http://www.somewebsite.com");
   1241     service.CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
   1242                                  Manifest::INTERNAL);
   1243     service.CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
   1244                                  Manifest::INTERNAL);
   1245     EXPECT_EQ(2u, tmp.size());
   1246     service.set_extensions(tmp);
   1247 
   1248     ExtensionPrefs* prefs = service.extension_prefs();
   1249     const std::string& id = tmp[0]->id();
   1250     Time now = Time::Now();
   1251     if (rollcall_ping_days == 0) {
   1252       prefs->SetLastPingDay(id, now - TimeDelta::FromSeconds(15));
   1253     } else if (rollcall_ping_days > 0) {
   1254       Time last_ping_day = now -
   1255                            TimeDelta::FromDays(rollcall_ping_days) -
   1256                            TimeDelta::FromSeconds(15);
   1257       prefs->SetLastPingDay(id, last_ping_day);
   1258     }
   1259 
   1260     // Store a value for the last day we sent an active ping.
   1261     if (active_ping_days == 0) {
   1262       prefs->SetLastActivePingDay(id, now - TimeDelta::FromSeconds(15));
   1263     } else if (active_ping_days > 0) {
   1264       Time last_active_ping_day = now -
   1265                                   TimeDelta::FromDays(active_ping_days) -
   1266                                   TimeDelta::FromSeconds(15);
   1267       prefs->SetLastActivePingDay(id, last_active_ping_day);
   1268     }
   1269     if (active_bit)
   1270       prefs->SetActiveBit(id, true);
   1271 
   1272     ExtensionUpdater updater(
   1273         &service, service.extension_prefs(), service.pref_service(),
   1274         service.profile(), kUpdateFrequencySecs);
   1275     ExtensionUpdater::CheckParams params;
   1276     updater.Start();
   1277     updater.CheckNow(params);
   1278 
   1279     // Make the updater do manifest fetching, and note the urls it tries to
   1280     // fetch.
   1281     std::vector<GURL> fetched_urls;
   1282     net::TestURLFetcher* fetcher =
   1283       factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
   1284     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
   1285     fetched_urls.push_back(fetcher->GetOriginalURL());
   1286 
   1287     fetcher->set_url(fetched_urls[0]);
   1288     fetcher->set_status(net::URLRequestStatus());
   1289     fetcher->set_response_code(500);
   1290     fetcher->SetResponseString(std::string());
   1291     fetcher->delegate()->OnURLFetchComplete(fetcher);
   1292 
   1293     fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
   1294     fetched_urls.push_back(fetcher->GetOriginalURL());
   1295 
   1296     // The urls could have been fetched in either order, so use the host to
   1297     // tell them apart and note the query each used.
   1298     std::string url1_query;
   1299     std::string url2_query;
   1300     if (fetched_urls[0].host() == url1.host()) {
   1301       url1_query = fetched_urls[0].query();
   1302       url2_query = fetched_urls[1].query();
   1303     } else if (fetched_urls[0].host() == url2.host()) {
   1304       url1_query = fetched_urls[1].query();
   1305       url2_query = fetched_urls[0].query();
   1306     } else {
   1307       NOTREACHED();
   1308     }
   1309 
   1310     // First make sure the non-google query had no ping parameter.
   1311     std::string search_string = "ping%3D";
   1312     EXPECT_TRUE(url2_query.find(search_string) == std::string::npos);
   1313 
   1314     // Now make sure the google query had the correct ping parameter.
   1315     bool ping_expected = false;
   1316     bool did_rollcall = false;
   1317     if (rollcall_ping_days != 0) {
   1318       search_string += "r%253D" + base::IntToString(rollcall_ping_days);
   1319       did_rollcall = true;
   1320       ping_expected = true;
   1321     }
   1322     if (active_bit && active_ping_days != 0) {
   1323       if (did_rollcall)
   1324         search_string += "%2526";
   1325       search_string += "a%253D" + base::IntToString(active_ping_days);
   1326       ping_expected = true;
   1327     }
   1328     bool ping_found = url1_query.find(search_string) != std::string::npos;
   1329     EXPECT_EQ(ping_expected, ping_found) << "query was: " << url1_query
   1330         << " was looking for " << search_string;
   1331 
   1332     // Make sure the non-google query has no brand parameter.
   1333     const std::string brand_string = "brand%3D";
   1334     EXPECT_TRUE(url2_query.find(brand_string) == std::string::npos);
   1335 
   1336 #if defined(GOOGLE_CHROME_BUILD)
   1337     // Make sure the google query has a brand parameter, but only if the
   1338     // brand is non-organic.
   1339     if (expect_brand_code) {
   1340       EXPECT_TRUE(url1_query.find(brand_string) != std::string::npos);
   1341     } else {
   1342       EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
   1343     }
   1344 #else
   1345     // Chromium builds never add the brand to the parameter, even for google
   1346     // queries.
   1347     EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
   1348 #endif
   1349 
   1350     RunUntilIdle();
   1351   }
   1352 
   1353   // This makes sure that the extension updater properly stores the results
   1354   // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
   1355   // the first time we fetched the extension, or 2) We sent a ping value of
   1356   // >= 1 day for the extension.
   1357   void TestHandleManifestResults() {
   1358     ServiceForManifestTests service(prefs_.get());
   1359     GURL update_url("http://www.google.com/manifest");
   1360     ExtensionList tmp;
   1361     service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
   1362                                  Manifest::INTERNAL);
   1363     service.set_extensions(tmp);
   1364 
   1365     ExtensionUpdater updater(
   1366         &service, service.extension_prefs(), service.pref_service(),
   1367         service.profile(), kUpdateFrequencySecs);
   1368     updater.Start();
   1369     ResetDownloader(
   1370         &updater,
   1371         new ExtensionDownloader(&updater, service.request_context()));
   1372 
   1373     ManifestFetchData fetch_data(update_url, 0);
   1374     const Extension* extension = tmp[0].get();
   1375     fetch_data.AddExtension(extension->id(),
   1376                             extension->VersionString(),
   1377                             &kNeverPingedData,
   1378                             kEmptyUpdateUrlData,
   1379                             std::string());
   1380     UpdateManifest::Results results;
   1381     results.daystart_elapsed_seconds = 750;
   1382 
   1383     updater.downloader_->HandleManifestResults(fetch_data, &results);
   1384     Time last_ping_day =
   1385         service.extension_prefs()->LastPingDay(extension->id());
   1386     EXPECT_FALSE(last_ping_day.is_null());
   1387     int64 seconds_diff = (Time::Now() - last_ping_day).InSeconds();
   1388     EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
   1389   }
   1390 
   1391  protected:
   1392   scoped_ptr<TestExtensionPrefs> prefs_;
   1393 
   1394  private:
   1395   content::TestBrowserThreadBundle thread_bundle_;
   1396 
   1397 #if defined OS_CHROMEOS
   1398   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
   1399   chromeos::ScopedTestCrosSettings test_cros_settings_;
   1400   chromeos::ScopedTestUserManager test_user_manager_;
   1401 #endif
   1402 };
   1403 
   1404 // Because we test some private methods of ExtensionUpdater, it's easier for the
   1405 // actual test code to live in ExtenionUpdaterTest methods instead of TEST_F
   1406 // subclasses where friendship with ExtenionUpdater is not inherited.
   1407 
   1408 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
   1409   TestExtensionUpdateCheckRequests(false);
   1410 }
   1411 
   1412 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
   1413   TestExtensionUpdateCheckRequests(true);
   1414 }
   1415 
   1416 TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
   1417   TestUpdateUrlDataEmpty();
   1418   TestUpdateUrlDataSimple();
   1419   TestUpdateUrlDataCompound();
   1420   TestUpdateUrlDataFromGallery(
   1421       extension_urls::GetWebstoreUpdateUrl().spec());
   1422 }
   1423 
   1424 TEST_F(ExtensionUpdaterTest, TestInstallSource) {
   1425   TestInstallSource();
   1426 }
   1427 
   1428 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
   1429   TestDetermineUpdates();
   1430 }
   1431 
   1432 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
   1433   TestDetermineUpdatesPending();
   1434 }
   1435 
   1436 TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
   1437   TestMultipleManifestDownloading();
   1438 }
   1439 
   1440 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
   1441   TestSingleExtensionDownloading(false, false);
   1442 }
   1443 
   1444 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
   1445   TestSingleExtensionDownloading(true, false);
   1446 }
   1447 
   1448 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
   1449   TestSingleExtensionDownloading(false, true);
   1450 }
   1451 
   1452 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
   1453   TestSingleExtensionDownloading(true, true);
   1454 }
   1455 
   1456 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
   1457   TestMultipleExtensionDownloading(false);
   1458 }
   1459 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
   1460   TestMultipleExtensionDownloading(true);
   1461 }
   1462 
   1463 TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
   1464   TestManifestRetryDownloading();
   1465 }
   1466 
   1467 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) {
   1468   TestGalleryRequestsWithBrand(true);
   1469 }
   1470 
   1471 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) {
   1472   TestGalleryRequestsWithBrand(false);
   1473 }
   1474 
   1475 TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
   1476   TestHandleManifestResults();
   1477 }
   1478 
   1479 TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
   1480   net::TestURLFetcherFactory factory;
   1481   ServiceForManifestTests service(prefs_.get());
   1482   ExtensionUpdater updater(&service, service.extension_prefs(),
   1483                            service.pref_service(), service.profile(),
   1484                            kUpdateFrequencySecs);
   1485   MockExtensionDownloaderDelegate delegate;
   1486   // Set the downloader directly, so that all its events end up in the mock
   1487   // |delegate|.
   1488   ExtensionDownloader* downloader =
   1489       new ExtensionDownloader(&delegate, service.request_context());
   1490   ResetDownloader(&updater, downloader);
   1491 
   1492   // Non-internal non-external extensions should be rejected.
   1493   ExtensionList extensions;
   1494   service.CreateTestExtensions(1, 1, &extensions, NULL,
   1495                                Manifest::INVALID_LOCATION);
   1496   service.CreateTestExtensions(2, 1, &extensions, NULL, Manifest::INTERNAL);
   1497   ASSERT_EQ(2u, extensions.size());
   1498   const std::string& updateable_id = extensions[1]->id();
   1499 
   1500   // These expectations fail if the delegate's methods are invoked for the
   1501   // first extension, which has a non-matching id.
   1502   EXPECT_CALL(delegate, GetUpdateUrlData(updateable_id)).WillOnce(Return(""));
   1503   EXPECT_CALL(delegate, GetPingDataForExtension(updateable_id, _));
   1504 
   1505   service.set_extensions(extensions);
   1506   ExtensionUpdater::CheckParams params;
   1507   updater.Start();
   1508   updater.CheckNow(params);
   1509 }
   1510 
   1511 TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
   1512   net::TestURLFetcherFactory factory;
   1513   ServiceForManifestTests service(prefs_.get());
   1514   ExtensionUpdater updater(&service, service.extension_prefs(),
   1515                            service.pref_service(), service.profile(),
   1516                            kUpdateFrequencySecs);
   1517   MockExtensionDownloaderDelegate delegate;
   1518   // Set the downloader directly, so that all its events end up in the mock
   1519   // |delegate|.
   1520   ExtensionDownloader* downloader =
   1521       new ExtensionDownloader(&delegate, service.request_context());
   1522   ResetDownloader(&updater, downloader);
   1523 
   1524   // Non-internal non-external extensions should be rejected.
   1525   ExtensionList enabled_extensions;
   1526   ExtensionList disabled_extensions;
   1527   service.CreateTestExtensions(1, 1, &enabled_extensions, NULL,
   1528       Manifest::INTERNAL);
   1529   service.CreateTestExtensions(2, 1, &disabled_extensions, NULL,
   1530       Manifest::INTERNAL);
   1531   ASSERT_EQ(1u, enabled_extensions.size());
   1532   ASSERT_EQ(1u, disabled_extensions.size());
   1533   const std::string& enabled_id = enabled_extensions[0]->id();
   1534   const std::string& disabled_id = disabled_extensions[0]->id();
   1535 
   1536   // We expect that both enabled and disabled extensions are auto-updated.
   1537   EXPECT_CALL(delegate, GetUpdateUrlData(enabled_id)).WillOnce(Return(""));
   1538   EXPECT_CALL(delegate, GetPingDataForExtension(enabled_id, _));
   1539   EXPECT_CALL(delegate, GetUpdateUrlData(disabled_id)).WillOnce(Return(""));
   1540   EXPECT_CALL(delegate, GetPingDataForExtension(disabled_id, _));
   1541 
   1542   service.set_extensions(enabled_extensions);
   1543   service.set_disabled_extensions(disabled_extensions);
   1544   ExtensionUpdater::CheckParams params;
   1545   updater.Start();
   1546   updater.CheckNow(params);
   1547 }
   1548 
   1549 TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
   1550   net::TestURLFetcherFactory factory;
   1551   MockService service(prefs_.get());
   1552   MockExtensionDownloaderDelegate delegate;
   1553   scoped_ptr<ExtensionDownloader> downloader(
   1554       new ExtensionDownloader(&delegate, service.request_context()));
   1555   EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
   1556 
   1557   // First, verify that adding valid extensions does invoke the callbacks on
   1558   // the delegate.
   1559   std::string id = id_util::GenerateId("foo");
   1560   EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
   1561   EXPECT_TRUE(
   1562       downloader->AddPendingExtension(id, GURL("http://example.com/update"),
   1563                                       0));
   1564   downloader->StartAllPending();
   1565   Mock::VerifyAndClearExpectations(&delegate);
   1566   EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
   1567 
   1568   // Extensions with invalid update URLs should be rejected.
   1569   id = id_util::GenerateId("foo2");
   1570   EXPECT_FALSE(
   1571       downloader->AddPendingExtension(id, GURL("http:google.com:foo"), 0));
   1572   downloader->StartAllPending();
   1573   EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
   1574 
   1575   // Extensions with empty IDs should be rejected.
   1576   EXPECT_FALSE(downloader->AddPendingExtension(std::string(), GURL(), 0));
   1577   downloader->StartAllPending();
   1578   EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
   1579 
   1580   // TODO(akalin): Test that extensions with empty update URLs
   1581   // converted from user scripts are rejected.
   1582 
   1583   // Reset the ExtensionDownloader so that it drops the current fetcher.
   1584   downloader.reset(
   1585       new ExtensionDownloader(&delegate, service.request_context()));
   1586   EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
   1587 
   1588   // Extensions with empty update URLs should have a default one
   1589   // filled in.
   1590   id = id_util::GenerateId("foo3");
   1591   EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
   1592   EXPECT_TRUE(downloader->AddPendingExtension(id, GURL(), 0));
   1593   downloader->StartAllPending();
   1594   EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
   1595 
   1596   net::TestURLFetcher* fetcher =
   1597       factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
   1598   ASSERT_TRUE(fetcher);
   1599   EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
   1600 }
   1601 
   1602 TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
   1603   net::TestURLFetcherFactory factory;
   1604   MockService service(prefs_.get());
   1605   MockExtensionDownloaderDelegate delegate;
   1606   ExtensionDownloader downloader(&delegate, service.request_context());
   1607 
   1608   StartUpdateCheck(&downloader, new ManifestFetchData(GURL(), 0));
   1609   // This should delete the newly-created ManifestFetchData.
   1610   StartUpdateCheck(&downloader, new ManifestFetchData(GURL(), 0));
   1611   // This should add into |manifests_pending_|.
   1612   StartUpdateCheck(&downloader, new ManifestFetchData(GURL(
   1613       GURL("http://www.google.com")), 0));
   1614   // The dtor of |downloader| should delete the pending fetchers.
   1615 }
   1616 
   1617 TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
   1618   ServiceForManifestTests service(prefs_.get());
   1619   net::TestURLFetcherFactory factory;
   1620   ExtensionUpdater updater(
   1621       &service, service.extension_prefs(), service.pref_service(),
   1622       service.profile(), kUpdateFrequencySecs);
   1623   EXPECT_FALSE(updater.WillCheckSoon());
   1624   updater.Start();
   1625   EXPECT_FALSE(updater.WillCheckSoon());
   1626   updater.CheckSoon();
   1627   EXPECT_TRUE(updater.WillCheckSoon());
   1628   updater.CheckSoon();
   1629   EXPECT_TRUE(updater.WillCheckSoon());
   1630   RunUntilIdle();
   1631   EXPECT_FALSE(updater.WillCheckSoon());
   1632   updater.CheckSoon();
   1633   EXPECT_TRUE(updater.WillCheckSoon());
   1634   updater.Stop();
   1635   EXPECT_FALSE(updater.WillCheckSoon());
   1636 }
   1637 
   1638 // TODO(asargent) - (http://crbug.com/12780) add tests for:
   1639 // -prodversionmin (shouldn't update if browser version too old)
   1640 // -manifests & updates arriving out of order / interleaved
   1641 // -malformed update url (empty, file://, has query, has a # fragment, etc.)
   1642 // -An extension gets uninstalled while updates are in progress (so it doesn't
   1643 //  "come back from the dead")
   1644 // -An extension gets manually updated to v3 while we're downloading v2 (ie
   1645 //  you don't get downgraded accidentally)
   1646 // -An update manifest mentions multiple updates
   1647 
   1648 }  // namespace extensions
   1649