• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Wait()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 
Quit()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:
NotificationsObserver()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 
~NotificationsObserver()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 
StartedCount()184   size_t StartedCount() { return count_[0]; }
UpdatedCount()185   size_t UpdatedCount() { return count_[1]; }
186 
Updated(const std::string & id)187   bool Updated(const std::string& id) {
188     return updated_.find(id) != updated_.end();
189   }
190 
Wait()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:
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)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:
MockService(TestExtensionPrefs * prefs)231   explicit MockService(TestExtensionPrefs* prefs)
232       : prefs_(prefs), pending_extension_manager_(*this) {
233   }
234 
~MockService()235   virtual ~MockService() {}
236 
pending_extension_manager()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 
profile()243   Profile* profile() { return &profile_; }
244 
request_context()245   net::URLRequestContextGetter* request_context() {
246     return profile_.GetRequestContext();
247   }
248 
extension_prefs()249   ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
250 
pref_service()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.
CreateTestExtensions(int id,int count,ExtensionList * list,const std::string * update_url,Manifest::Location location)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 
ShouldInstallExtensionsOnly(const Extension * extension)286 bool ShouldInstallExtensionsOnly(const Extension* extension) {
287   return extension->GetType() == Manifest::TYPE_EXTENSION;
288 }
289 
ShouldInstallThemesOnly(const Extension * extension)290 bool ShouldInstallThemesOnly(const Extension* extension) {
291   return extension->is_theme();
292 }
293 
ShouldAlwaysInstall(const Extension * extension)294 bool ShouldAlwaysInstall(const Extension* extension) {
295   return true;
296 }
297 
298 // Loads some pending extension records into a pending extension manager.
SetupPendingExtensionManagerForTest(int count,const GURL & update_url,PendingExtensionManager * 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:
ServiceForManifestTests(TestExtensionPrefs * prefs)326   explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
327       : MockService(prefs) {
328   }
329 
~ServiceForManifestTests()330   virtual ~ServiceForManifestTests() {}
331 
GetExtensionById(const std::string & id,bool include_disabled) const332   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 
extensions() const340   virtual const ExtensionSet* extensions() const OVERRIDE {
341     return &extensions_;
342   }
343 
disabled_extensions() const344   virtual const ExtensionSet* disabled_extensions() const OVERRIDE {
345     return &disabled_extensions_;
346   }
347 
pending_extension_manager()348   virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
349     return &pending_extension_manager_;
350   }
351 
GetPendingExtensionUpdate(const std::string & id) const352   virtual const Extension* GetPendingExtensionUpdate(
353       const std::string& id) const OVERRIDE {
354     return NULL;
355   }
356 
IsExtensionEnabled(const std::string & id) const357   virtual bool IsExtensionEnabled(const std::string& id) const OVERRIDE {
358     return !disabled_extensions_.Contains(id);
359   }
360 
set_extensions(ExtensionList extensions)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 
set_disabled_extensions(ExtensionList disabled_extensions)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:
ServiceForDownloadTests(TestExtensionPrefs * prefs)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|.
AddFakeCrxInstaller(const std::string & id,CrxInstaller * crx_installer)388   void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) {
389     fake_crx_installers_[id] = crx_installer;
390   }
391 
UpdateExtension(const std::string & id,const base::FilePath & extension_path,const GURL & download_url,CrxInstaller ** out_crx_installer)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 
pending_extension_manager()409   virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
410     return &pending_extension_manager_;
411   }
412 
GetExtensionById(const std::string & id,bool) const413   virtual const Extension* GetExtensionById(
414       const std::string& id, bool) const OVERRIDE {
415     last_inquired_extension_id_ = id;
416     return NULL;
417   }
418 
extension_id() const419   const std::string& extension_id() const { return extension_id_; }
install_path() const420   const base::FilePath& install_path() const { return install_path_; }
download_url() const421   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 "".
ExtractParameters(const std::string & params,std::map<std::string,std::string> * result)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 
VerifyQueryAndExtractParameters(const std::string & query,std::map<std::string,std::string> * result)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:
ExtensionUpdaterTest()490   ExtensionUpdaterTest()
491       : thread_bundle_(
492             content::TestBrowserThreadBundle::IO_MAINLOOP) {
493   }
494 
SetUp()495   virtual void SetUp() OVERRIDE {
496     prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
497     content::RenderProcessHost::SetRunRendererInProcess(true);
498   }
499 
TearDown()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 
RunUntilIdle()509   void RunUntilIdle() {
510     prefs_->pref_service()->CommitPendingWrite();
511     base::RunLoop().RunUntilIdle();
512   }
513 
SimulateTimerFired(ExtensionUpdater * updater)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.
AddParseResult(const std::string & id,const std::string & version,const std::string & url,UpdateManifest::Results * 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 
ResetDownloader(ExtensionUpdater * updater,ExtensionDownloader * downloader)532   void ResetDownloader(ExtensionUpdater* updater,
533                        ExtensionDownloader* downloader) {
534     EXPECT_FALSE(updater->downloader_.get());
535     updater->downloader_.reset(downloader);
536   }
537 
StartUpdateCheck(ExtensionDownloader * downloader,ManifestFetchData * fetch_data)538   void StartUpdateCheck(ExtensionDownloader* downloader,
539                         ManifestFetchData* fetch_data) {
540     downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data));
541   }
542 
ManifestFetchersCount(ExtensionDownloader * downloader)543   size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
544     return downloader->manifests_queue_.size() +
545            (downloader->manifest_fetcher_.get() ? 1 : 0);
546   }
547 
TestExtensionUpdateCheckRequests(bool pending)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 
TestUpdateUrlDataEmpty()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 
TestUpdateUrlDataSimple()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 
TestUpdateUrlDataCompound()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 
TestUpdateUrlDataFromGallery(const std::string & gallery_url)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 
TestInstallSource()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 
TestDetermineUpdates()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 
TestDetermineUpdatesPending()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 
TestMultipleManifestDownloading()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 
TestManifestRetryDownloading()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 
TestSingleExtensionDownloading(bool pending,bool retry)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.
TestMultipleExtensionDownloading(bool updates_start_running)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 
TestGalleryRequestsWithBrand(bool use_organic_brand_code)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).
TestGalleryRequests(int rollcall_ping_days,int active_ping_days,bool active_bit,bool expect_brand_code)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.
TestHandleManifestResults()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 
TEST_F(ExtensionUpdaterTest,TestExtensionUpdateCheckRequests)1408 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
1409   TestExtensionUpdateCheckRequests(false);
1410 }
1411 
TEST_F(ExtensionUpdaterTest,TestExtensionUpdateCheckRequestsPending)1412 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
1413   TestExtensionUpdateCheckRequests(true);
1414 }
1415 
TEST_F(ExtensionUpdaterTest,TestUpdateUrlData)1416 TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
1417   TestUpdateUrlDataEmpty();
1418   TestUpdateUrlDataSimple();
1419   TestUpdateUrlDataCompound();
1420   TestUpdateUrlDataFromGallery(
1421       extension_urls::GetWebstoreUpdateUrl().spec());
1422 }
1423 
TEST_F(ExtensionUpdaterTest,TestInstallSource)1424 TEST_F(ExtensionUpdaterTest, TestInstallSource) {
1425   TestInstallSource();
1426 }
1427 
TEST_F(ExtensionUpdaterTest,TestDetermineUpdates)1428 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
1429   TestDetermineUpdates();
1430 }
1431 
TEST_F(ExtensionUpdaterTest,TestDetermineUpdatesPending)1432 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
1433   TestDetermineUpdatesPending();
1434 }
1435 
TEST_F(ExtensionUpdaterTest,TestMultipleManifestDownloading)1436 TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
1437   TestMultipleManifestDownloading();
1438 }
1439 
TEST_F(ExtensionUpdaterTest,TestSingleExtensionDownloading)1440 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
1441   TestSingleExtensionDownloading(false, false);
1442 }
1443 
TEST_F(ExtensionUpdaterTest,TestSingleExtensionDownloadingPending)1444 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
1445   TestSingleExtensionDownloading(true, false);
1446 }
1447 
TEST_F(ExtensionUpdaterTest,TestSingleExtensionDownloadingWithRetry)1448 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
1449   TestSingleExtensionDownloading(false, true);
1450 }
1451 
TEST_F(ExtensionUpdaterTest,TestSingleExtensionDownloadingPendingWithRetry)1452 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
1453   TestSingleExtensionDownloading(true, true);
1454 }
1455 
TEST_F(ExtensionUpdaterTest,TestMultipleExtensionDownloadingUpdatesFail)1456 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
1457   TestMultipleExtensionDownloading(false);
1458 }
TEST_F(ExtensionUpdaterTest,TestMultipleExtensionDownloadingUpdatesSucceed)1459 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
1460   TestMultipleExtensionDownloading(true);
1461 }
1462 
TEST_F(ExtensionUpdaterTest,TestManifestRetryDownloading)1463 TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
1464   TestManifestRetryDownloading();
1465 }
1466 
TEST_F(ExtensionUpdaterTest,TestGalleryRequestsWithOrganicBrand)1467 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) {
1468   TestGalleryRequestsWithBrand(true);
1469 }
1470 
TEST_F(ExtensionUpdaterTest,TestGalleryRequestsWithNonOrganicBrand)1471 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) {
1472   TestGalleryRequestsWithBrand(false);
1473 }
1474 
TEST_F(ExtensionUpdaterTest,TestHandleManifestResults)1475 TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
1476   TestHandleManifestResults();
1477 }
1478 
TEST_F(ExtensionUpdaterTest,TestNonAutoUpdateableLocations)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 
TEST_F(ExtensionUpdaterTest,TestUpdatingDisabledExtensions)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 
TEST_F(ExtensionUpdaterTest,TestManifestFetchesBuilderAddExtension)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 
TEST_F(ExtensionUpdaterTest,TestStartUpdateCheckMemory)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 
TEST_F(ExtensionUpdaterTest,TestCheckSoon)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