NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / extensions / updater / extension_updater_unittest.cc
blobe47ae0268ebf32a1cb75315966c0e1b01a5f1cba
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.
5 #include <list>
6 #include <map>
7 #include <set>
8 #include <vector>
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/test_extension_prefs.h"
31 #include "chrome/browser/extensions/test_extension_service.h"
32 #include "chrome/browser/extensions/test_extension_system.h"
33 #include "chrome/browser/extensions/updater/extension_downloader.h"
34 #include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
35 #include "chrome/browser/extensions/updater/extension_updater.h"
36 #include "chrome/browser/extensions/updater/manifest_fetch_data.h"
37 #include "chrome/browser/extensions/updater/request_queue_impl.h"
38 #include "chrome/browser/google/google_util.h"
39 #include "chrome/browser/omaha_query_params/omaha_query_params.h"
40 #include "chrome/browser/prefs/pref_service_syncable.h"
41 #include "chrome/common/pref_names.h"
42 #include "chrome/test/base/testing_profile.h"
43 #include "content/public/browser/notification_details.h"
44 #include "content/public/browser/notification_observer.h"
45 #include "content/public/browser/notification_registrar.h"
46 #include "content/public/browser/notification_service.h"
47 #include "content/public/browser/notification_source.h"
48 #include "content/public/test/test_browser_thread_bundle.h"
49 #include "content/public/test/test_utils.h"
50 #include "extensions/browser/extension_registry.h"
51 #include "extensions/browser/extension_system.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"
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
70 using base::Time;
71 using base::TimeDelta;
72 using content::BrowserThread;
73 using testing::DoAll;
74 using testing::Invoke;
75 using testing::InvokeWithoutArgs;
76 using testing::Mock;
77 using testing::Return;
78 using testing::SetArgPointee;
79 using testing::_;
81 namespace extensions {
83 typedef ExtensionDownloaderDelegate::Error Error;
84 typedef ExtensionDownloaderDelegate::PingResult PingResult;
86 namespace {
88 const net::BackoffEntry::Policy kNoBackoffPolicy = {
89 // Number of initial errors (in sequence) to ignore before applying
90 // exponential back-off rules.
91 1000,
93 // Initial delay for exponential back-off in ms.
96 // Factor by which the waiting time will be multiplied.
99 // Fuzzing percentage. ex: 10% will spread requests randomly
100 // between 90%-100% of the calculated time.
103 // Maximum amount of time we are willing to delay our request in ms.
106 // Time to keep an entry from being discarded even when it
107 // has no significant state, -1 to never discard.
110 // Don't use initial delay unless the last request was an error.
111 false,
114 const char kEmptyUpdateUrlData[] = "";
116 int kExpectedLoadFlags =
117 net::LOAD_DO_NOT_SEND_COOKIES |
118 net::LOAD_DO_NOT_SAVE_COOKIES |
119 net::LOAD_DISABLE_CACHE;
121 int kExpectedLoadFlagsForProtectedDownload = net::LOAD_DISABLE_CACHE;
123 const ManifestFetchData::PingData kNeverPingedData(
124 ManifestFetchData::kNeverPinged, ManifestFetchData::kNeverPinged, true);
126 class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate {
127 public:
128 MOCK_METHOD4(OnExtensionDownloadFailed, void(const std::string&,
129 Error,
130 const PingResult&,
131 const std::set<int>&));
132 MOCK_METHOD7(OnExtensionDownloadFinished, void(const std::string&,
133 const base::FilePath&,
134 bool,
135 const GURL&,
136 const std::string&,
137 const PingResult&,
138 const std::set<int>&));
139 MOCK_METHOD2(GetPingDataForExtension,
140 bool(const std::string&, ManifestFetchData::PingData*));
141 MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&));
142 MOCK_METHOD1(IsExtensionPending, bool(const std::string&));
143 MOCK_METHOD2(GetExtensionExistingVersion,
144 bool(const std::string&, std::string*));
146 void Wait() {
147 scoped_refptr<content::MessageLoopRunner> runner =
148 new content::MessageLoopRunner;
149 quit_closure_ = runner->QuitClosure();
150 runner->Run();
151 quit_closure_.Reset();
154 void Quit() {
155 quit_closure_.Run();
158 void DelegateTo(ExtensionDownloaderDelegate* delegate) {
159 ON_CALL(*this, OnExtensionDownloadFailed(_, _, _, _))
160 .WillByDefault(Invoke(delegate,
161 &ExtensionDownloaderDelegate::OnExtensionDownloadFailed));
162 ON_CALL(*this, OnExtensionDownloadFinished(_, _, _, _, _, _, _))
163 .WillByDefault(Invoke(delegate,
164 &ExtensionDownloaderDelegate::OnExtensionDownloadFinished));
165 ON_CALL(*this, GetPingDataForExtension(_, _))
166 .WillByDefault(Invoke(delegate,
167 &ExtensionDownloaderDelegate::GetPingDataForExtension));
168 ON_CALL(*this, GetUpdateUrlData(_))
169 .WillByDefault(Invoke(delegate,
170 &ExtensionDownloaderDelegate::GetUpdateUrlData));
171 ON_CALL(*this, IsExtensionPending(_))
172 .WillByDefault(Invoke(delegate,
173 &ExtensionDownloaderDelegate::IsExtensionPending));
174 ON_CALL(*this, GetExtensionExistingVersion(_, _))
175 .WillByDefault(Invoke(delegate,
176 &ExtensionDownloaderDelegate::GetExtensionExistingVersion));
179 private:
180 base::Closure quit_closure_;
183 const int kNotificationsObserved[] = {
184 chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED,
185 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
188 // A class that observes the notifications sent by the ExtensionUpdater and
189 // the ExtensionDownloader.
190 class NotificationsObserver : public content::NotificationObserver {
191 public:
192 NotificationsObserver() {
193 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
194 count_[i] = 0;
195 registrar_.Add(this,
196 kNotificationsObserved[i],
197 content::NotificationService::AllSources());
201 virtual ~NotificationsObserver() {
202 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
203 registrar_.Remove(this,
204 kNotificationsObserved[i],
205 content::NotificationService::AllSources());
209 size_t StartedCount() { return count_[0]; }
210 size_t UpdatedCount() { return count_[1]; }
212 bool Updated(const std::string& id) {
213 return updated_.find(id) != updated_.end();
216 void Wait() {
217 scoped_refptr<content::MessageLoopRunner> runner =
218 new content::MessageLoopRunner;
219 quit_closure_ = runner->QuitClosure();
220 runner->Run();
221 quit_closure_.Reset();
224 private:
225 virtual void Observe(int type,
226 const content::NotificationSource& source,
227 const content::NotificationDetails& details) OVERRIDE {
228 if (!quit_closure_.is_null())
229 quit_closure_.Run();
230 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
231 if (kNotificationsObserved[i] == type) {
232 count_[i]++;
233 if (type == chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND) {
234 updated_.insert(
235 content::Details<UpdateDetails>(details)->id);
237 return;
240 NOTREACHED();
243 content::NotificationRegistrar registrar_;
244 size_t count_[arraysize(kNotificationsObserved)];
245 std::set<std::string> updated_;
246 base::Closure quit_closure_;
248 DISALLOW_COPY_AND_ASSIGN(NotificationsObserver);
251 } // namespace
253 // Base class for further specialized test classes.
254 class MockService : public TestExtensionService {
255 public:
256 explicit MockService(TestExtensionPrefs* prefs)
257 : prefs_(prefs), pending_extension_manager_(*this) {
260 virtual ~MockService() {}
262 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
263 ADD_FAILURE() << "Subclass should override this if it will "
264 << "be accessed by a test.";
265 return &pending_extension_manager_;
268 Profile* profile() { return &profile_; }
270 net::URLRequestContextGetter* request_context() {
271 return profile_.GetRequestContext();
274 ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
276 PrefService* pref_service() { return prefs_->pref_service(); }
278 // Creates test extensions and inserts them into list. The name and
279 // version are all based on their index. If |update_url| is non-null, it
280 // will be used as the update_url for each extension.
281 // The |id| is used to distinguish extension names and make sure that
282 // no two extensions share the same name.
283 void CreateTestExtensions(int id, int count, ExtensionList *list,
284 const std::string* update_url,
285 Manifest::Location location) {
286 for (int i = 1; i <= count; i++) {
287 base::DictionaryValue manifest;
288 manifest.SetString(manifest_keys::kVersion,
289 base::StringPrintf("%d.0.0.0", i));
290 manifest.SetString(manifest_keys::kName,
291 base::StringPrintf("Extension %d.%d", id, i));
292 if (update_url)
293 manifest.SetString(manifest_keys::kUpdateURL, *update_url);
294 scoped_refptr<Extension> e =
295 prefs_->AddExtensionWithManifest(manifest, location);
296 ASSERT_TRUE(e.get() != NULL);
297 list->push_back(e);
301 protected:
302 TestExtensionPrefs* const prefs_;
303 PendingExtensionManager pending_extension_manager_;
304 TestingProfile profile_;
306 private:
307 DISALLOW_COPY_AND_ASSIGN(MockService);
311 bool ShouldInstallExtensionsOnly(const Extension* extension) {
312 return extension->GetType() == Manifest::TYPE_EXTENSION;
315 bool ShouldInstallThemesOnly(const Extension* extension) {
316 return extension->is_theme();
319 bool ShouldAlwaysInstall(const Extension* extension) {
320 return true;
323 // Loads some pending extension records into a pending extension manager.
324 void SetupPendingExtensionManagerForTest(
325 int count,
326 const GURL& update_url,
327 PendingExtensionManager* pending_extension_manager) {
328 for (int i = 1; i <= count; ++i) {
329 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
330 (i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
331 const bool kIsFromSync = true;
332 const bool kInstallSilently = true;
333 const bool kMarkAcknowledged = false;
334 std::string id = id_util::GenerateId(base::StringPrintf("extension%i", i));
336 pending_extension_manager->AddForTesting(
337 PendingExtensionInfo(id,
338 update_url,
339 Version(),
340 should_allow_install,
341 kIsFromSync,
342 kInstallSilently,
343 Manifest::INTERNAL,
344 Extension::NO_FLAGS,
345 kMarkAcknowledged));
349 class ServiceForManifestTests : public MockService {
350 public:
351 explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
352 : MockService(prefs), registry_(ExtensionRegistry::Get(profile())) {}
354 virtual ~ServiceForManifestTests() {}
356 virtual const Extension* GetExtensionById(
357 const std::string& id, bool include_disabled) const OVERRIDE {
358 const Extension* result = registry_->enabled_extensions().GetByID(id);
359 if (result || !include_disabled)
360 return result;
361 return registry_->disabled_extensions().GetByID(id);
364 virtual const ExtensionSet* extensions() const OVERRIDE {
365 return &registry_->enabled_extensions();
368 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
369 return &pending_extension_manager_;
372 virtual const Extension* GetPendingExtensionUpdate(
373 const std::string& id) const OVERRIDE {
374 return NULL;
377 virtual bool IsExtensionEnabled(const std::string& id) const OVERRIDE {
378 return !registry_->disabled_extensions().Contains(id);
381 void set_extensions(ExtensionList extensions,
382 ExtensionList disabled_extensions) {
383 registry_->ClearAll();
384 for (ExtensionList::const_iterator it = extensions.begin();
385 it != extensions.end(); ++it) {
386 registry_->AddEnabled(*it);
388 for (ExtensionList::const_iterator it = disabled_extensions.begin();
389 it != disabled_extensions.end(); ++it) {
390 registry_->AddDisabled(*it);
394 private:
395 ExtensionRegistry* registry_;
398 class ServiceForDownloadTests : public MockService {
399 public:
400 explicit ServiceForDownloadTests(TestExtensionPrefs* prefs)
401 : MockService(prefs) {
404 // Add a fake crx installer to be returned by a call to UpdateExtension()
405 // with a specific ID. Caller keeps ownership of |crx_installer|.
406 void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) {
407 fake_crx_installers_[id] = crx_installer;
410 virtual bool UpdateExtension(
411 const std::string& id,
412 const base::FilePath& extension_path,
413 bool file_ownership_passed,
414 const GURL& download_url,
415 CrxInstaller** out_crx_installer) OVERRIDE {
416 extension_id_ = id;
417 install_path_ = extension_path;
418 download_url_ = download_url;
420 if (ContainsKey(fake_crx_installers_, id)) {
421 *out_crx_installer = fake_crx_installers_[id];
422 return true;
425 return false;
428 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
429 return &pending_extension_manager_;
432 virtual const Extension* GetExtensionById(
433 const std::string& id, bool) const OVERRIDE {
434 last_inquired_extension_id_ = id;
435 return NULL;
438 const std::string& extension_id() const { return extension_id_; }
439 const base::FilePath& install_path() const { return install_path_; }
440 const GURL& download_url() const { return download_url_; }
442 private:
443 // Hold the set of ids that UpdateExtension() should fake success on.
444 // UpdateExtension(id, ...) will return true iff fake_crx_installers_
445 // contains key |id|. |out_install_notification_source| will be set
446 // to Source<CrxInstaller(fake_crx_installers_[i]).
447 std::map<std::string, CrxInstaller*> fake_crx_installers_;
449 std::string extension_id_;
450 base::FilePath install_path_;
451 GURL download_url_;
453 // The last extension ID that GetExtensionById was called with.
454 // Mutable because the method that sets it (GetExtensionById) is const
455 // in the actual extension service, but must record the last extension
456 // ID in this test class.
457 mutable std::string last_inquired_extension_id_;
460 static const int kUpdateFrequencySecs = 15;
462 // Takes a string with KEY=VALUE parameters separated by '&' in |params| and
463 // puts the key/value pairs into |result|. For keys with no value, the empty
464 // string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
465 // "foo", and "c" to "".
466 static void ExtractParameters(const std::string& params,
467 std::map<std::string, std::string>* result) {
468 std::vector<std::string> pairs;
469 base::SplitString(params, '&', &pairs);
470 for (size_t i = 0; i < pairs.size(); i++) {
471 std::vector<std::string> key_val;
472 base::SplitString(pairs[i], '=', &key_val);
473 if (!key_val.empty()) {
474 std::string key = key_val[0];
475 EXPECT_TRUE(result->find(key) == result->end());
476 (*result)[key] = (key_val.size() == 2) ? key_val[1] : std::string();
477 } else {
478 NOTREACHED();
483 static void VerifyQueryAndExtractParameters(
484 const std::string& query,
485 std::map<std::string, std::string>* result) {
486 std::map<std::string, std::string> params;
487 ExtractParameters(query, &params);
489 std::string omaha_params =
490 chrome::OmahaQueryParams::Get(chrome::OmahaQueryParams::CRX);
491 std::map<std::string, std::string> expected;
492 ExtractParameters(omaha_params, &expected);
494 for (std::map<std::string, std::string>::iterator it = expected.begin();
495 it != expected.end(); ++it) {
496 EXPECT_EQ(it->second, params[it->first]);
499 EXPECT_EQ(1U, params.count("x"));
500 std::string decoded = net::UnescapeURLComponent(
501 params["x"], net::UnescapeRule::URL_SPECIAL_CHARS);
502 ExtractParameters(decoded, result);
505 // All of our tests that need to use private APIs of ExtensionUpdater live
506 // inside this class (which is a friend to ExtensionUpdater).
507 class ExtensionUpdaterTest : public testing::Test {
508 public:
509 ExtensionUpdaterTest()
510 : thread_bundle_(
511 content::TestBrowserThreadBundle::IO_MAINLOOP) {
514 virtual void SetUp() OVERRIDE {
515 prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
518 virtual void TearDown() OVERRIDE {
519 // Some tests create URLRequestContextGetters, whose destruction must run
520 // on the IO thread. Make sure the IO loop spins before shutdown so that
521 // those objects are released.
522 RunUntilIdle();
523 prefs_.reset();
526 void RunUntilIdle() {
527 prefs_->pref_service()->CommitPendingWrite();
528 base::RunLoop().RunUntilIdle();
531 void SimulateTimerFired(ExtensionUpdater* updater) {
532 EXPECT_TRUE(updater->timer_.IsRunning());
533 updater->timer_.Stop();
534 updater->TimerFired();
537 // Adds a Result with the given data to results.
538 void AddParseResult(const std::string& id,
539 const std::string& version,
540 const std::string& url,
541 UpdateManifest::Results* results) {
542 UpdateManifest::Result result;
543 result.extension_id = id;
544 result.version = version;
545 result.crx_url = GURL(url);
546 results->list.push_back(result);
549 void ResetDownloader(ExtensionUpdater* updater,
550 ExtensionDownloader* downloader) {
551 EXPECT_FALSE(updater->downloader_.get());
552 updater->downloader_.reset(downloader);
555 void StartUpdateCheck(ExtensionDownloader* downloader,
556 ManifestFetchData* fetch_data) {
557 downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data));
560 size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
561 return downloader->manifests_queue_.size() +
562 (downloader->manifest_fetcher_.get() ? 1 : 0);
565 void TestExtensionUpdateCheckRequests(bool pending) {
566 // Create an extension with an update_url.
567 ServiceForManifestTests service(prefs_.get());
568 std::string update_url("http://foo.com/bar");
569 ExtensionList extensions;
570 NotificationsObserver observer;
571 PendingExtensionManager* pending_extension_manager =
572 service.pending_extension_manager();
573 if (pending) {
574 SetupPendingExtensionManagerForTest(1, GURL(update_url),
575 pending_extension_manager);
576 } else {
577 service.CreateTestExtensions(1, 1, &extensions, &update_url,
578 Manifest::INTERNAL);
579 service.set_extensions(extensions, ExtensionList());
582 // Set up and start the updater.
583 net::TestURLFetcherFactory factory;
584 ExtensionUpdater updater(
585 &service, service.extension_prefs(), service.pref_service(),
586 service.profile(), 60*60*24, NULL);
587 updater.Start();
589 // Tell the update that it's time to do update checks.
590 EXPECT_EQ(0u, observer.StartedCount());
591 SimulateTimerFired(&updater);
592 EXPECT_EQ(1u, observer.StartedCount());
594 // Get the url our mock fetcher was asked to fetch.
595 net::TestURLFetcher* fetcher =
596 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
597 const GURL& url = fetcher->GetOriginalURL();
598 EXPECT_FALSE(url.is_empty());
599 EXPECT_TRUE(url.is_valid());
600 EXPECT_TRUE(url.SchemeIs("http"));
601 EXPECT_EQ("foo.com", url.host());
602 EXPECT_EQ("/bar", url.path());
604 // Validate the extension request parameters in the query. It should
605 // look something like "x=id%3D<id>%26v%3D<version>%26uc".
606 EXPECT_TRUE(url.has_query());
607 std::map<std::string, std::string> params;
608 VerifyQueryAndExtractParameters(url.query(), &params);
609 if (pending) {
610 EXPECT_TRUE(pending_extension_manager->IsIdPending(params["id"]));
611 EXPECT_EQ("0.0.0.0", params["v"]);
612 } else {
613 EXPECT_EQ(extensions[0]->id(), params["id"]);
614 EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
616 EXPECT_EQ("", params["uc"]);
619 void TestUpdateUrlDataEmpty() {
620 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
621 const std::string version = "1.0";
623 // Make sure that an empty update URL data string does not cause a 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, std::string(), std::string());
629 std::map<std::string, std::string> params;
630 VerifyQueryAndExtractParameters(fetch_data.full_url().query(), &params);
631 EXPECT_EQ(id, params["id"]);
632 EXPECT_EQ(version, params["v"]);
633 EXPECT_EQ(0U, params.count("ap"));
636 void TestUpdateUrlDataSimple() {
637 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
638 const std::string version = "1.0";
640 // Make sure that an update URL data string causes an appropriate ap=
641 // option to appear in the x= parameter.
642 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
643 fetch_data.AddExtension(
644 id, version, &kNeverPingedData, "bar", std::string());
645 std::map<std::string, std::string> params;
646 VerifyQueryAndExtractParameters(fetch_data.full_url().query(), &params);
647 EXPECT_EQ(id, params["id"]);
648 EXPECT_EQ(version, params["v"]);
649 EXPECT_EQ("bar", params["ap"]);
652 void TestUpdateUrlDataCompound() {
653 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
654 const std::string version = "1.0";
656 // Make sure that an update URL data string causes an appropriate ap=
657 // option to appear in the x= parameter.
658 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
659 fetch_data.AddExtension(
660 id, version, &kNeverPingedData, "a=1&b=2&c", std::string());
661 std::map<std::string, std::string> params;
662 VerifyQueryAndExtractParameters(fetch_data.full_url().query(), &params);
663 EXPECT_EQ(id, params["id"]);
664 EXPECT_EQ(version, params["v"]);
665 EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]);
668 void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
669 net::TestURLFetcherFactory factory;
671 MockService service(prefs_.get());
672 MockExtensionDownloaderDelegate delegate;
673 ExtensionDownloader downloader(&delegate, service.request_context());
674 ExtensionList extensions;
675 std::string url(gallery_url);
677 service.CreateTestExtensions(1, 1, &extensions, &url, Manifest::INTERNAL);
679 const std::string& id = extensions[0]->id();
680 EXPECT_CALL(delegate, GetPingDataForExtension(id, _));
682 downloader.AddExtension(*extensions[0].get(), 0);
683 downloader.StartAllPending(NULL);
684 net::TestURLFetcher* fetcher =
685 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
686 ASSERT_TRUE(fetcher);
687 // Make sure that extensions that update from the gallery ignore any
688 // update URL data.
689 const std::string& update_url = fetcher->GetOriginalURL().spec();
690 std::string::size_type x = update_url.find("x=");
691 EXPECT_NE(std::string::npos, x);
692 std::string::size_type ap = update_url.find("ap%3D", x);
693 EXPECT_EQ(std::string::npos, ap);
696 void TestInstallSource() {
697 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
698 const std::string version = "1.0";
699 const std::string install_source = "instally";
701 // Make sure that an installsource= appears in the x= parameter.
702 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
703 fetch_data.AddExtension(id, version, &kNeverPingedData,
704 kEmptyUpdateUrlData, install_source);
705 std::map<std::string, std::string> params;
706 VerifyQueryAndExtractParameters(fetch_data.full_url().query(), &params);
707 EXPECT_EQ(id, params["id"]);
708 EXPECT_EQ(version, params["v"]);
709 EXPECT_EQ(install_source, params["installsource"]);
712 void TestDetermineUpdates() {
713 TestingProfile profile;
714 MockExtensionDownloaderDelegate delegate;
715 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
717 // Check passing an empty list of parse results to DetermineUpdates
718 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
719 UpdateManifest::Results updates;
720 std::vector<int> updateable;
721 downloader.DetermineUpdates(fetch_data, updates, &updateable);
722 EXPECT_TRUE(updateable.empty());
724 // Create two updates - expect that DetermineUpdates will return the first
725 // one (v1.0 installed, v1.1 available) but not the second one (both
726 // installed and available at v2.0).
727 const std::string id1 = id_util::GenerateId("1");
728 const std::string id2 = id_util::GenerateId("2");
729 fetch_data.AddExtension(
730 id1, "1.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string());
731 AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);
732 fetch_data.AddExtension(
733 id2, "2.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string());
734 AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);
736 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
737 EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
738 .WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"),
739 Return(true)));
740 EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
741 .WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"),
742 Return(true)));
744 downloader.DetermineUpdates(fetch_data, updates, &updateable);
745 EXPECT_EQ(1u, updateable.size());
746 EXPECT_EQ(0, updateable[0]);
749 void TestDetermineUpdatesPending() {
750 // Create a set of test extensions
751 ServiceForManifestTests service(prefs_.get());
752 PendingExtensionManager* pending_extension_manager =
753 service.pending_extension_manager();
754 SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
756 TestingProfile profile;
757 MockExtensionDownloaderDelegate delegate;
758 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
760 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
761 UpdateManifest::Results updates;
763 std::list<std::string> ids_for_update_check;
764 pending_extension_manager->GetPendingIdsForUpdateCheck(
765 &ids_for_update_check);
767 std::list<std::string>::const_iterator it;
768 for (it = ids_for_update_check.begin();
769 it != ids_for_update_check.end(); ++it) {
770 fetch_data.AddExtension(*it,
771 "1.0.0.0",
772 &kNeverPingedData,
773 kEmptyUpdateUrlData,
774 std::string());
775 AddParseResult(*it, "1.1", "http://localhost/e1_1.1.crx", &updates);
778 // The delegate will tell the downloader that all the extensions are
779 // pending.
780 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(true));
782 std::vector<int> updateable;
783 downloader.DetermineUpdates(fetch_data, updates, &updateable);
784 // All the apps should be updateable.
785 EXPECT_EQ(3u, updateable.size());
786 for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) {
787 EXPECT_EQ(static_cast<int>(i), updateable[i]);
791 void TestMultipleManifestDownloading() {
792 net::TestURLFetcherFactory factory;
793 net::TestURLFetcher* fetcher = NULL;
794 NotificationsObserver observer;
795 MockService service(prefs_.get());
796 MockExtensionDownloaderDelegate delegate;
797 ExtensionDownloader downloader(&delegate, service.request_context());
798 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
800 GURL kUpdateUrl("http://localhost/manifest1");
802 scoped_ptr<ManifestFetchData> fetch1(new ManifestFetchData(kUpdateUrl, 0));
803 scoped_ptr<ManifestFetchData> fetch2(new ManifestFetchData(kUpdateUrl, 0));
804 scoped_ptr<ManifestFetchData> fetch3(new ManifestFetchData(kUpdateUrl, 0));
805 scoped_ptr<ManifestFetchData> fetch4(new ManifestFetchData(kUpdateUrl, 0));
806 ManifestFetchData::PingData zeroDays(0, 0, true);
807 fetch1->AddExtension(
808 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
809 fetch2->AddExtension(
810 "2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string());
811 fetch3->AddExtension(
812 "3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string());
813 fetch4->AddExtension(
814 "4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string());
816 // This will start the first fetcher and queue the others. The next in queue
817 // is started as each fetcher receives its response.
818 downloader.StartUpdateCheck(fetch1.Pass());
819 downloader.StartUpdateCheck(fetch2.Pass());
820 downloader.StartUpdateCheck(fetch3.Pass());
821 downloader.StartUpdateCheck(fetch4.Pass());
822 RunUntilIdle();
824 // The first fetch will fail.
825 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
826 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
827 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
828 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
829 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
830 fetcher->set_url(kUpdateUrl);
831 fetcher->set_status(net::URLRequestStatus());
832 fetcher->set_response_code(400);
833 fetcher->delegate()->OnURLFetchComplete(fetcher);
834 RunUntilIdle();
835 Mock::VerifyAndClearExpectations(&delegate);
837 // The second fetch gets invalid data.
838 const std::string kInvalidXml = "invalid xml";
839 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
840 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
841 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
842 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
843 "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _))
844 .WillOnce(InvokeWithoutArgs(&delegate,
845 &MockExtensionDownloaderDelegate::Quit));
846 fetcher->set_url(kUpdateUrl);
847 fetcher->set_status(net::URLRequestStatus());
848 fetcher->set_response_code(200);
849 fetcher->SetResponseString(kInvalidXml);
850 fetcher->delegate()->OnURLFetchComplete(fetcher);
851 delegate.Wait();
852 Mock::VerifyAndClearExpectations(&delegate);
854 // The third fetcher doesn't have an update available.
855 const std::string kNoUpdate =
856 "<?xml version='1.0' encoding='UTF-8'?>"
857 "<gupdate xmlns='http://www.google.com/update2/response'"
858 " protocol='2.0'>"
859 " <app appid='3333'>"
860 " <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'"
861 " version='3.0.0.0' prodversionmin='3.0.0.0' />"
862 " </app>"
863 "</gupdate>";
864 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
865 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
866 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
867 EXPECT_CALL(delegate, IsExtensionPending("3333")).WillOnce(Return(false));
868 EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _))
869 .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"),
870 Return(true)));
871 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
872 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _))
873 .WillOnce(InvokeWithoutArgs(&delegate,
874 &MockExtensionDownloaderDelegate::Quit));
875 fetcher->set_url(kUpdateUrl);
876 fetcher->set_status(net::URLRequestStatus());
877 fetcher->set_response_code(200);
878 fetcher->SetResponseString(kNoUpdate);
879 fetcher->delegate()->OnURLFetchComplete(fetcher);
880 delegate.Wait();
881 Mock::VerifyAndClearExpectations(&delegate);
883 // The last fetcher has an update.
884 const std::string kUpdateAvailable =
885 "<?xml version='1.0' encoding='UTF-8'?>"
886 "<gupdate xmlns='http://www.google.com/update2/response'"
887 " protocol='2.0'>"
888 " <app appid='4444'>"
889 " <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
890 " version='4.0.42.0' prodversionmin='4.0.42.0' />"
891 " </app>"
892 "</gupdate>";
893 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
894 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
895 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
896 EXPECT_CALL(delegate, IsExtensionPending("4444")).WillOnce(Return(false));
897 EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _))
898 .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"),
899 Return(true)));
900 fetcher->set_url(kUpdateUrl);
901 fetcher->set_status(net::URLRequestStatus());
902 fetcher->set_response_code(200);
903 fetcher->SetResponseString(kUpdateAvailable);
904 fetcher->delegate()->OnURLFetchComplete(fetcher);
905 observer.Wait();
906 Mock::VerifyAndClearExpectations(&delegate);
908 // Verify that the downloader decided to update this extension.
909 EXPECT_EQ(1u, observer.UpdatedCount());
910 EXPECT_TRUE(observer.Updated("4444"));
913 void TestManifestRetryDownloading() {
914 net::TestURLFetcherFactory factory;
915 net::TestURLFetcher* fetcher = NULL;
916 NotificationsObserver observer;
917 MockService service(prefs_.get());
918 MockExtensionDownloaderDelegate delegate;
919 ExtensionDownloader downloader(&delegate, service.request_context());
920 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
922 GURL kUpdateUrl("http://localhost/manifest1");
924 scoped_ptr<ManifestFetchData> fetch(new ManifestFetchData(kUpdateUrl, 0));
925 ManifestFetchData::PingData zeroDays(0, 0, true);
926 fetch->AddExtension(
927 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
929 // This will start the first fetcher.
930 downloader.StartUpdateCheck(fetch.Pass());
931 RunUntilIdle();
933 // ExtensionDownloader should retry kMaxRetries times and then fail.
934 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
935 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
936 for (int i = 0; i <= ExtensionDownloader::kMaxRetries; ++i) {
937 // All fetches will fail.
938 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
939 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
940 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
941 fetcher->set_url(kUpdateUrl);
942 fetcher->set_status(net::URLRequestStatus());
943 // Code 5xx causes ExtensionDownloader to retry.
944 fetcher->set_response_code(500);
945 fetcher->delegate()->OnURLFetchComplete(fetcher);
946 RunUntilIdle();
948 Mock::VerifyAndClearExpectations(&delegate);
951 // For response codes that are not in the 5xx range ExtensionDownloader
952 // should not retry.
953 fetch.reset(new ManifestFetchData(kUpdateUrl, 0));
954 fetch->AddExtension(
955 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
957 // This will start the first fetcher.
958 downloader.StartUpdateCheck(fetch.Pass());
959 RunUntilIdle();
961 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
962 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
963 // The first fetch will fail, and require retrying.
964 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
965 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
966 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
967 fetcher->set_url(kUpdateUrl);
968 fetcher->set_status(net::URLRequestStatus());
969 fetcher->set_response_code(500);
970 fetcher->delegate()->OnURLFetchComplete(fetcher);
971 RunUntilIdle();
973 // The second fetch will fail with response 400 and should not cause
974 // ExtensionDownloader to retry.
975 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
976 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
977 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
978 fetcher->set_url(kUpdateUrl);
979 fetcher->set_status(net::URLRequestStatus());
980 fetcher->set_response_code(400);
981 fetcher->delegate()->OnURLFetchComplete(fetcher);
982 RunUntilIdle();
984 Mock::VerifyAndClearExpectations(&delegate);
987 void TestSingleExtensionDownloading(bool pending, bool retry, bool fail) {
988 net::TestURLFetcherFactory factory;
989 net::TestURLFetcher* fetcher = NULL;
990 scoped_ptr<ServiceForDownloadTests> service(
991 new ServiceForDownloadTests(prefs_.get()));
992 ExtensionUpdater updater(service.get(), service->extension_prefs(),
993 service->pref_service(),
994 service->profile(),
995 kUpdateFrequencySecs,
996 NULL);
997 updater.Start();
998 MockExtensionDownloaderDelegate delegate;
999 delegate.DelegateTo(&updater);
1000 ResetDownloader(
1001 &updater,
1002 new ExtensionDownloader(&delegate, service->request_context()));
1003 updater.downloader_->extensions_queue_.set_backoff_policy(
1004 &kNoBackoffPolicy);
1006 GURL test_url("http://localhost/extension.crx");
1008 std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1009 std::string hash;
1010 Version version("0.0.1");
1011 std::set<int> requests;
1012 requests.insert(0);
1013 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
1014 new ExtensionDownloader::ExtensionFetch(
1015 id, test_url, hash, version.GetString(), requests));
1016 updater.downloader_->FetchUpdatedExtension(fetch.Pass());
1018 if (pending) {
1019 const bool kIsFromSync = true;
1020 const bool kInstallSilently = true;
1021 const bool kMarkAcknowledged = false;
1022 PendingExtensionManager* pending_extension_manager =
1023 service->pending_extension_manager();
1024 pending_extension_manager->AddForTesting(
1025 PendingExtensionInfo(id, test_url, version,
1026 &ShouldAlwaysInstall, kIsFromSync,
1027 kInstallSilently,
1028 Manifest::INTERNAL,
1029 Extension::NO_FLAGS,
1030 kMarkAcknowledged));
1033 // Call back the ExtensionUpdater with a 200 response and some test data
1034 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1035 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1036 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1037 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1039 if (retry) {
1040 // Reply with response code 500 to cause ExtensionDownloader to retry
1041 fetcher->set_url(test_url);
1042 fetcher->set_status(net::URLRequestStatus());
1043 fetcher->set_response_code(500);
1044 fetcher->delegate()->OnURLFetchComplete(fetcher);
1046 RunUntilIdle();
1047 fetcher = factory.GetFetcherByID(
1048 ExtensionDownloader::kExtensionFetcherId);
1049 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1050 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1053 fetcher->set_url(test_url);
1054 fetcher->set_status(net::URLRequestStatus());
1055 if (fail) {
1056 fetcher->set_response_code(404);
1057 EXPECT_CALL(delegate, OnExtensionDownloadFailed(id, _, _, requests));
1058 } else {
1059 fetcher->set_response_code(200);
1060 fetcher->SetResponseFilePath(extension_file_path);
1061 EXPECT_CALL(delegate, OnExtensionDownloadFinished(
1062 id, _, _, _, version.GetString(), _, requests));
1064 fetcher->delegate()->OnURLFetchComplete(fetcher);
1066 RunUntilIdle();
1068 if (fail) {
1069 // Don't expect any extension to have been installed.
1070 EXPECT_TRUE(service->extension_id().empty());
1071 } else {
1072 // Expect that ExtensionUpdater asked the mock extensions service to
1073 // install a file with the test data for the right id.
1074 EXPECT_EQ(id, service->extension_id());
1075 base::FilePath tmpfile_path = service->install_path();
1076 EXPECT_FALSE(tmpfile_path.empty());
1077 EXPECT_EQ(test_url, service->download_url());
1078 EXPECT_EQ(extension_file_path, tmpfile_path);
1082 // Update a single extension in an environment where the download request
1083 // initially responds with a 403 status. Expect the fetcher to automatically
1084 // retry with cookies enabled.
1085 void TestSingleProtectedExtensionDownloading(bool use_https, bool fail) {
1086 net::TestURLFetcherFactory factory;
1087 net::TestURLFetcher* fetcher = NULL;
1088 scoped_ptr<ServiceForDownloadTests> service(
1089 new ServiceForDownloadTests(prefs_.get()));
1090 ExtensionUpdater updater(service.get(), service->extension_prefs(),
1091 service->pref_service(),
1092 service->profile(),
1093 kUpdateFrequencySecs,
1094 NULL);
1095 updater.Start();
1096 ResetDownloader(
1097 &updater,
1098 new ExtensionDownloader(&updater, service->request_context()));
1099 updater.downloader_->extensions_queue_.set_backoff_policy(
1100 &kNoBackoffPolicy);
1102 GURL test_url(use_https ? "https://localhost/extension.crx" :
1103 "http://localhost/extension.crx");
1105 std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1106 std::string hash;
1107 Version version("0.0.1");
1108 std::set<int> requests;
1109 requests.insert(0);
1110 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
1111 new ExtensionDownloader::ExtensionFetch(
1112 id, test_url, hash, version.GetString(), requests));
1113 updater.downloader_->FetchUpdatedExtension(fetch.Pass());
1115 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1116 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1117 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1119 // Fake a 403 response.
1120 fetcher->set_url(test_url);
1121 fetcher->set_status(net::URLRequestStatus());
1122 fetcher->set_response_code(403);
1123 fetcher->delegate()->OnURLFetchComplete(fetcher);
1124 RunUntilIdle();
1126 // Verify that the fetcher has been switched to protected download mode
1127 // so that cookies would be sent with the next request (https only).
1128 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1129 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1130 if (use_https) {
1131 EXPECT_TRUE(
1132 fetcher->GetLoadFlags() == kExpectedLoadFlagsForProtectedDownload);
1133 } else {
1134 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1137 // Attempt to fetch again after the auth failure.
1138 if (fail) {
1139 // Fail and verify that the fetch queue is cleared.
1140 fetcher->set_url(test_url);
1141 fetcher->set_status(net::URLRequestStatus());
1142 fetcher->set_response_code(403);
1143 fetcher->delegate()->OnURLFetchComplete(fetcher);
1144 RunUntilIdle();
1145 EXPECT_EQ(0U, updater.downloader_->extensions_queue_.active_request());
1146 } else {
1147 // Succeed
1148 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1149 fetcher->set_url(test_url);
1150 fetcher->set_status(net::URLRequestStatus());
1151 fetcher->set_response_code(200);
1152 fetcher->SetResponseFilePath(extension_file_path);
1153 fetcher->delegate()->OnURLFetchComplete(fetcher);
1154 RunUntilIdle();
1156 // Verify installation would proceed as normal.
1157 EXPECT_EQ(id, service->extension_id());
1158 base::FilePath tmpfile_path = service->install_path();
1159 EXPECT_FALSE(tmpfile_path.empty());
1160 EXPECT_EQ(test_url, service->download_url());
1161 EXPECT_EQ(extension_file_path, tmpfile_path);
1165 // Two extensions are updated. If |updates_start_running| is true, the
1166 // mock extensions service has UpdateExtension(...) return true, and
1167 // the test is responsible for creating fake CrxInstallers. Otherwise,
1168 // UpdateExtension() returns false, signaling install failures.
1169 void TestMultipleExtensionDownloading(bool updates_start_running) {
1170 net::TestURLFetcherFactory factory;
1171 net::TestURLFetcher* fetcher = NULL;
1172 ServiceForDownloadTests service(prefs_.get());
1173 ExtensionUpdater updater(
1174 &service, service.extension_prefs(), service.pref_service(),
1175 service.profile(), kUpdateFrequencySecs, NULL);
1176 updater.Start();
1177 ResetDownloader(
1178 &updater,
1179 new ExtensionDownloader(&updater, service.request_context()));
1180 updater.downloader_->extensions_queue_.set_backoff_policy(
1181 &kNoBackoffPolicy);
1183 EXPECT_FALSE(updater.crx_install_is_running_);
1185 GURL url1("http://localhost/extension1.crx");
1186 GURL url2("http://localhost/extension2.crx");
1188 std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1189 std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
1191 std::string hash1;
1192 std::string hash2;
1194 std::string version1 = "0.1";
1195 std::string version2 = "0.1";
1196 std::set<int> requests;
1197 requests.insert(0);
1198 // Start two fetches
1199 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch1(
1200 new ExtensionDownloader::ExtensionFetch(
1201 id1, url1, hash1, version1, requests));
1202 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch2(
1203 new ExtensionDownloader::ExtensionFetch(
1204 id2, url2, hash2, version2, requests));
1205 updater.downloader_->FetchUpdatedExtension(fetch1.Pass());
1206 updater.downloader_->FetchUpdatedExtension(fetch2.Pass());
1208 // Make the first fetch complete.
1209 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1211 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1212 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1213 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1215 // We need some CrxInstallers, and CrxInstallers require a real
1216 // ExtensionService. Create one on the testing profile. Any action
1217 // the CrxInstallers take is on the testing profile's extension
1218 // service, not on our mock |service|. This allows us to fake
1219 // the CrxInstaller actions we want.
1220 TestingProfile profile;
1221 static_cast<TestExtensionSystem*>(
1222 ExtensionSystem::Get(&profile))->
1223 CreateExtensionService(
1224 CommandLine::ForCurrentProcess(),
1225 base::FilePath(),
1226 false);
1227 ExtensionService* extension_service =
1228 ExtensionSystem::Get(&profile)->extension_service();
1229 extension_service->set_extensions_enabled(true);
1230 extension_service->set_show_extensions_prompts(false);
1232 scoped_refptr<CrxInstaller> fake_crx1(
1233 CrxInstaller::CreateSilent(extension_service));
1234 scoped_refptr<CrxInstaller> fake_crx2(
1235 CrxInstaller::CreateSilent(extension_service));
1237 if (updates_start_running) {
1238 // Add fake CrxInstaller to be returned by service.UpdateExtension().
1239 service.AddFakeCrxInstaller(id1, fake_crx1.get());
1240 service.AddFakeCrxInstaller(id2, fake_crx2.get());
1241 } else {
1242 // If we don't add fake CRX installers, the mock service fakes a failure
1243 // starting the install.
1246 fetcher->set_url(url1);
1247 fetcher->set_status(net::URLRequestStatus());
1248 fetcher->set_response_code(200);
1249 fetcher->SetResponseFilePath(extension_file_path);
1250 fetcher->delegate()->OnURLFetchComplete(fetcher);
1252 RunUntilIdle();
1254 // Expect that the service was asked to do an install with the right data.
1255 base::FilePath tmpfile_path = service.install_path();
1256 EXPECT_FALSE(tmpfile_path.empty());
1257 EXPECT_EQ(id1, service.extension_id());
1258 EXPECT_EQ(url1, service.download_url());
1259 RunUntilIdle();
1261 // Make sure the second fetch finished and asked the service to do an
1262 // update.
1263 base::FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2"));
1264 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1265 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1266 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1268 fetcher->set_url(url2);
1269 fetcher->set_status(net::URLRequestStatus());
1270 fetcher->set_response_code(200);
1271 fetcher->SetResponseFilePath(extension_file_path2);
1272 fetcher->delegate()->OnURLFetchComplete(fetcher);
1273 RunUntilIdle();
1275 if (updates_start_running) {
1276 EXPECT_TRUE(updater.crx_install_is_running_);
1278 // The second install should not have run, because the first has not
1279 // sent a notification that it finished.
1280 EXPECT_EQ(id1, service.extension_id());
1281 EXPECT_EQ(url1, service.download_url());
1283 // Fake install notice. This should start the second installation,
1284 // which will be checked below.
1285 fake_crx1->NotifyCrxInstallComplete(false);
1287 EXPECT_TRUE(updater.crx_install_is_running_);
1290 EXPECT_EQ(id2, service.extension_id());
1291 EXPECT_EQ(url2, service.download_url());
1292 EXPECT_FALSE(service.install_path().empty());
1294 // Make sure the correct crx contents were passed for the update call.
1295 EXPECT_EQ(extension_file_path2, service.install_path());
1297 if (updates_start_running) {
1298 EXPECT_TRUE(updater.crx_install_is_running_);
1299 fake_crx2->NotifyCrxInstallComplete(false);
1301 EXPECT_FALSE(updater.crx_install_is_running_);
1304 void TestGalleryRequestsWithBrand(bool use_organic_brand_code) {
1305 google_util::BrandForTesting brand_for_testing(
1306 use_organic_brand_code ? "GGLS" : "TEST");
1308 // We want to test a variety of combinations of expected ping conditions for
1309 // rollcall and active pings.
1310 int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
1312 for (size_t i = 0; i < arraysize(ping_cases); i++) {
1313 for (size_t j = 0; j < arraysize(ping_cases); j++) {
1314 for (size_t k = 0; k < 2; k++) {
1315 int rollcall_ping_days = ping_cases[i];
1316 int active_ping_days = ping_cases[j];
1317 // Skip cases where rollcall_ping_days == -1, but
1318 // active_ping_days > 0, because rollcall_ping_days == -1 means the
1319 // app was just installed and this is the first update check after
1320 // installation.
1321 if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
1322 active_ping_days > 0)
1323 continue;
1325 bool active_bit = k > 0;
1326 TestGalleryRequests(rollcall_ping_days, active_ping_days, active_bit,
1327 !use_organic_brand_code);
1328 ASSERT_FALSE(HasFailure()) <<
1329 " rollcall_ping_days=" << ping_cases[i] <<
1330 " active_ping_days=" << ping_cases[j] <<
1331 " active_bit=" << active_bit;
1337 // Test requests to both a Google server and a non-google server. This allows
1338 // us to test various combinations of installed (ie roll call) and active
1339 // (ie app launch) ping scenarios. The invariant is that each type of ping
1340 // value should be present at most once per day, and can be calculated based
1341 // on the delta between now and the last ping time (or in the case of active
1342 // pings, that delta plus whether the app has been active).
1343 void TestGalleryRequests(int rollcall_ping_days,
1344 int active_ping_days,
1345 bool active_bit,
1346 bool expect_brand_code) {
1347 net::TestURLFetcherFactory factory;
1349 // Set up 2 mock extensions, one with a google.com update url and one
1350 // without.
1351 prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
1352 ServiceForManifestTests service(prefs_.get());
1353 ExtensionList tmp;
1354 GURL url1("http://clients2.google.com/service/update2/crx");
1355 GURL url2("http://www.somewebsite.com");
1356 service.CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
1357 Manifest::INTERNAL);
1358 service.CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
1359 Manifest::INTERNAL);
1360 EXPECT_EQ(2u, tmp.size());
1361 service.set_extensions(tmp, ExtensionList());
1363 ExtensionPrefs* prefs = service.extension_prefs();
1364 const std::string& id = tmp[0]->id();
1365 Time now = Time::Now();
1366 if (rollcall_ping_days == 0) {
1367 prefs->SetLastPingDay(id, now - TimeDelta::FromSeconds(15));
1368 } else if (rollcall_ping_days > 0) {
1369 Time last_ping_day = now -
1370 TimeDelta::FromDays(rollcall_ping_days) -
1371 TimeDelta::FromSeconds(15);
1372 prefs->SetLastPingDay(id, last_ping_day);
1375 // Store a value for the last day we sent an active ping.
1376 if (active_ping_days == 0) {
1377 prefs->SetLastActivePingDay(id, now - TimeDelta::FromSeconds(15));
1378 } else if (active_ping_days > 0) {
1379 Time last_active_ping_day = now -
1380 TimeDelta::FromDays(active_ping_days) -
1381 TimeDelta::FromSeconds(15);
1382 prefs->SetLastActivePingDay(id, last_active_ping_day);
1384 if (active_bit)
1385 prefs->SetActiveBit(id, true);
1387 ExtensionUpdater updater(
1388 &service, service.extension_prefs(), service.pref_service(),
1389 service.profile(), kUpdateFrequencySecs, NULL);
1390 ExtensionUpdater::CheckParams params;
1391 updater.Start();
1392 updater.CheckNow(params);
1394 // Make the updater do manifest fetching, and note the urls it tries to
1395 // fetch.
1396 std::vector<GURL> fetched_urls;
1397 net::TestURLFetcher* fetcher =
1398 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1399 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1400 fetched_urls.push_back(fetcher->GetOriginalURL());
1402 fetcher->set_url(fetched_urls[0]);
1403 fetcher->set_status(net::URLRequestStatus());
1404 fetcher->set_response_code(500);
1405 fetcher->SetResponseString(std::string());
1406 fetcher->delegate()->OnURLFetchComplete(fetcher);
1408 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1409 fetched_urls.push_back(fetcher->GetOriginalURL());
1411 // The urls could have been fetched in either order, so use the host to
1412 // tell them apart and note the query each used.
1413 std::string url1_query;
1414 std::string url2_query;
1415 if (fetched_urls[0].host() == url1.host()) {
1416 url1_query = fetched_urls[0].query();
1417 url2_query = fetched_urls[1].query();
1418 } else if (fetched_urls[0].host() == url2.host()) {
1419 url1_query = fetched_urls[1].query();
1420 url2_query = fetched_urls[0].query();
1421 } else {
1422 NOTREACHED();
1425 // First make sure the non-google query had no ping parameter.
1426 std::string search_string = "ping%3D";
1427 EXPECT_TRUE(url2_query.find(search_string) == std::string::npos);
1429 // Now make sure the google query had the correct ping parameter.
1430 bool ping_expected = false;
1431 bool did_rollcall = false;
1432 if (rollcall_ping_days != 0) {
1433 search_string += "r%253D" + base::IntToString(rollcall_ping_days);
1434 did_rollcall = true;
1435 ping_expected = true;
1437 if (active_bit && active_ping_days != 0) {
1438 if (did_rollcall)
1439 search_string += "%2526";
1440 search_string += "a%253D" + base::IntToString(active_ping_days);
1441 ping_expected = true;
1443 bool ping_found = url1_query.find(search_string) != std::string::npos;
1444 EXPECT_EQ(ping_expected, ping_found) << "query was: " << url1_query
1445 << " was looking for " << search_string;
1447 // Make sure the non-google query has no brand parameter.
1448 const std::string brand_string = "brand%3D";
1449 EXPECT_TRUE(url2_query.find(brand_string) == std::string::npos);
1451 #if defined(GOOGLE_CHROME_BUILD)
1452 // Make sure the google query has a brand parameter, but only if the
1453 // brand is non-organic.
1454 if (expect_brand_code) {
1455 EXPECT_TRUE(url1_query.find(brand_string) != std::string::npos);
1456 } else {
1457 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1459 #else
1460 // Chromium builds never add the brand to the parameter, even for google
1461 // queries.
1462 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1463 #endif
1465 RunUntilIdle();
1468 // This makes sure that the extension updater properly stores the results
1469 // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
1470 // the first time we fetched the extension, or 2) We sent a ping value of
1471 // >= 1 day for the extension.
1472 void TestHandleManifestResults() {
1473 ServiceForManifestTests service(prefs_.get());
1474 GURL update_url("http://www.google.com/manifest");
1475 ExtensionList tmp;
1476 service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
1477 Manifest::INTERNAL);
1478 service.set_extensions(tmp, ExtensionList());
1480 ExtensionUpdater updater(
1481 &service, service.extension_prefs(), service.pref_service(),
1482 service.profile(), kUpdateFrequencySecs, NULL);
1483 updater.Start();
1484 ResetDownloader(
1485 &updater,
1486 new ExtensionDownloader(&updater, service.request_context()));
1488 ManifestFetchData fetch_data(update_url, 0);
1489 const Extension* extension = tmp[0].get();
1490 fetch_data.AddExtension(extension->id(),
1491 extension->VersionString(),
1492 &kNeverPingedData,
1493 kEmptyUpdateUrlData,
1494 std::string());
1495 UpdateManifest::Results results;
1496 results.daystart_elapsed_seconds = 750;
1498 updater.downloader_->HandleManifestResults(fetch_data, &results);
1499 Time last_ping_day =
1500 service.extension_prefs()->LastPingDay(extension->id());
1501 EXPECT_FALSE(last_ping_day.is_null());
1502 int64 seconds_diff = (Time::Now() - last_ping_day).InSeconds();
1503 EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
1506 protected:
1507 scoped_ptr<TestExtensionPrefs> prefs_;
1509 private:
1510 content::TestBrowserThreadBundle thread_bundle_;
1511 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
1513 #if defined OS_CHROMEOS
1514 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
1515 chromeos::ScopedTestCrosSettings test_cros_settings_;
1516 chromeos::ScopedTestUserManager test_user_manager_;
1517 #endif
1520 // Because we test some private methods of ExtensionUpdater, it's easier for the
1521 // actual test code to live in ExtenionUpdaterTest methods instead of TEST_F
1522 // subclasses where friendship with ExtenionUpdater is not inherited.
1524 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
1525 TestExtensionUpdateCheckRequests(false);
1528 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
1529 TestExtensionUpdateCheckRequests(true);
1532 TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
1533 TestUpdateUrlDataEmpty();
1534 TestUpdateUrlDataSimple();
1535 TestUpdateUrlDataCompound();
1536 TestUpdateUrlDataFromGallery(
1537 extension_urls::GetWebstoreUpdateUrl().spec());
1540 TEST_F(ExtensionUpdaterTest, TestInstallSource) {
1541 TestInstallSource();
1544 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
1545 TestDetermineUpdates();
1548 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
1549 TestDetermineUpdatesPending();
1552 TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
1553 TestMultipleManifestDownloading();
1556 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
1557 TestSingleExtensionDownloading(false, false, false);
1560 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
1561 TestSingleExtensionDownloading(true, false, false);
1564 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
1565 TestSingleExtensionDownloading(false, true, false);
1568 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
1569 TestSingleExtensionDownloading(true, true, false);
1572 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailure) {
1573 TestSingleExtensionDownloading(false, false, true);
1576 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailureWithRetry) {
1577 TestSingleExtensionDownloading(false, true, true);
1580 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailurePending) {
1581 TestSingleExtensionDownloading(true, false, true);
1584 TEST_F(ExtensionUpdaterTest, TestSingleProtectedExtensionDownloading) {
1585 TestSingleProtectedExtensionDownloading(true, false);
1588 TEST_F(ExtensionUpdaterTest, TestSingleProtectedExtensionDownloadingFailure) {
1589 TestSingleProtectedExtensionDownloading(true, true);
1592 TEST_F(ExtensionUpdaterTest, TestSingleProtectedExtensionDownloadingNoHTTPS) {
1593 TestSingleProtectedExtensionDownloading(false, false);
1596 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
1597 TestMultipleExtensionDownloading(false);
1599 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
1600 TestMultipleExtensionDownloading(true);
1603 TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
1604 TestManifestRetryDownloading();
1607 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) {
1608 TestGalleryRequestsWithBrand(true);
1611 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) {
1612 TestGalleryRequestsWithBrand(false);
1615 TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
1616 TestHandleManifestResults();
1619 TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
1620 net::TestURLFetcherFactory factory;
1621 ServiceForManifestTests service(prefs_.get());
1622 ExtensionUpdater updater(&service, service.extension_prefs(),
1623 service.pref_service(), service.profile(),
1624 kUpdateFrequencySecs, NULL);
1625 MockExtensionDownloaderDelegate delegate;
1626 // Set the downloader directly, so that all its events end up in the mock
1627 // |delegate|.
1628 ExtensionDownloader* downloader =
1629 new ExtensionDownloader(&delegate, service.request_context());
1630 ResetDownloader(&updater, downloader);
1632 // Non-internal non-external extensions should be rejected.
1633 ExtensionList extensions;
1634 service.CreateTestExtensions(1, 1, &extensions, NULL,
1635 Manifest::INVALID_LOCATION);
1636 service.CreateTestExtensions(2, 1, &extensions, NULL, Manifest::INTERNAL);
1637 ASSERT_EQ(2u, extensions.size());
1638 const std::string& updateable_id = extensions[1]->id();
1640 // These expectations fail if the delegate's methods are invoked for the
1641 // first extension, which has a non-matching id.
1642 EXPECT_CALL(delegate, GetUpdateUrlData(updateable_id)).WillOnce(Return(""));
1643 EXPECT_CALL(delegate, GetPingDataForExtension(updateable_id, _));
1645 service.set_extensions(extensions, ExtensionList());
1646 ExtensionUpdater::CheckParams params;
1647 updater.Start();
1648 updater.CheckNow(params);
1651 TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
1652 net::TestURLFetcherFactory factory;
1653 ServiceForManifestTests service(prefs_.get());
1654 ExtensionUpdater updater(&service, service.extension_prefs(),
1655 service.pref_service(), service.profile(),
1656 kUpdateFrequencySecs, NULL);
1657 MockExtensionDownloaderDelegate delegate;
1658 // Set the downloader directly, so that all its events end up in the mock
1659 // |delegate|.
1660 ExtensionDownloader* downloader =
1661 new ExtensionDownloader(&delegate, service.request_context());
1662 ResetDownloader(&updater, downloader);
1664 // Non-internal non-external extensions should be rejected.
1665 ExtensionList enabled_extensions;
1666 ExtensionList disabled_extensions;
1667 service.CreateTestExtensions(1, 1, &enabled_extensions, NULL,
1668 Manifest::INTERNAL);
1669 service.CreateTestExtensions(2, 1, &disabled_extensions, NULL,
1670 Manifest::INTERNAL);
1671 ASSERT_EQ(1u, enabled_extensions.size());
1672 ASSERT_EQ(1u, disabled_extensions.size());
1673 const std::string& enabled_id = enabled_extensions[0]->id();
1674 const std::string& disabled_id = disabled_extensions[0]->id();
1676 // We expect that both enabled and disabled extensions are auto-updated.
1677 EXPECT_CALL(delegate, GetUpdateUrlData(enabled_id)).WillOnce(Return(""));
1678 EXPECT_CALL(delegate, GetPingDataForExtension(enabled_id, _));
1679 EXPECT_CALL(delegate, GetUpdateUrlData(disabled_id)).WillOnce(Return(""));
1680 EXPECT_CALL(delegate, GetPingDataForExtension(disabled_id, _));
1682 service.set_extensions(enabled_extensions, disabled_extensions);
1683 ExtensionUpdater::CheckParams params;
1684 updater.Start();
1685 updater.CheckNow(params);
1688 TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
1689 net::TestURLFetcherFactory factory;
1690 MockService service(prefs_.get());
1691 MockExtensionDownloaderDelegate delegate;
1692 scoped_ptr<ExtensionDownloader> downloader(
1693 new ExtensionDownloader(&delegate, service.request_context()));
1694 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
1696 // First, verify that adding valid extensions does invoke the callbacks on
1697 // the delegate.
1698 std::string id = id_util::GenerateId("foo");
1699 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
1700 EXPECT_TRUE(
1701 downloader->AddPendingExtension(id, GURL("http://example.com/update"),
1702 0));
1703 downloader->StartAllPending(NULL);
1704 Mock::VerifyAndClearExpectations(&delegate);
1705 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1707 // Extensions with invalid update URLs should be rejected.
1708 id = id_util::GenerateId("foo2");
1709 EXPECT_FALSE(
1710 downloader->AddPendingExtension(id, GURL("http:google.com:foo"), 0));
1711 downloader->StartAllPending(NULL);
1712 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1714 // Extensions with empty IDs should be rejected.
1715 EXPECT_FALSE(downloader->AddPendingExtension(std::string(), GURL(), 0));
1716 downloader->StartAllPending(NULL);
1717 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1719 // TODO(akalin): Test that extensions with empty update URLs
1720 // converted from user scripts are rejected.
1722 // Reset the ExtensionDownloader so that it drops the current fetcher.
1723 downloader.reset(
1724 new ExtensionDownloader(&delegate, service.request_context()));
1725 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
1727 // Extensions with empty update URLs should have a default one
1728 // filled in.
1729 id = id_util::GenerateId("foo3");
1730 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
1731 EXPECT_TRUE(downloader->AddPendingExtension(id, GURL(), 0));
1732 downloader->StartAllPending(NULL);
1733 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1735 net::TestURLFetcher* fetcher =
1736 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1737 ASSERT_TRUE(fetcher);
1738 EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
1741 TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
1742 net::TestURLFetcherFactory factory;
1743 MockService service(prefs_.get());
1744 MockExtensionDownloaderDelegate delegate;
1745 ExtensionDownloader downloader(&delegate, service.request_context());
1747 StartUpdateCheck(&downloader, new ManifestFetchData(GURL(), 0));
1748 // This should delete the newly-created ManifestFetchData.
1749 StartUpdateCheck(&downloader, new ManifestFetchData(GURL(), 0));
1750 // This should add into |manifests_pending_|.
1751 StartUpdateCheck(&downloader, new ManifestFetchData(GURL(
1752 GURL("http://www.google.com")), 0));
1753 // The dtor of |downloader| should delete the pending fetchers.
1756 TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
1757 ServiceForManifestTests service(prefs_.get());
1758 net::TestURLFetcherFactory factory;
1759 ExtensionUpdater updater(
1760 &service, service.extension_prefs(), service.pref_service(),
1761 service.profile(), kUpdateFrequencySecs, NULL);
1762 EXPECT_FALSE(updater.WillCheckSoon());
1763 updater.Start();
1764 EXPECT_FALSE(updater.WillCheckSoon());
1765 updater.CheckSoon();
1766 EXPECT_TRUE(updater.WillCheckSoon());
1767 updater.CheckSoon();
1768 EXPECT_TRUE(updater.WillCheckSoon());
1769 RunUntilIdle();
1770 EXPECT_FALSE(updater.WillCheckSoon());
1771 updater.CheckSoon();
1772 EXPECT_TRUE(updater.WillCheckSoon());
1773 updater.Stop();
1774 EXPECT_FALSE(updater.WillCheckSoon());
1777 // TODO(asargent) - (http://crbug.com/12780) add tests for:
1778 // -prodversionmin (shouldn't update if browser version too old)
1779 // -manifests & updates arriving out of order / interleaved
1780 // -malformed update url (empty, file://, has query, has a # fragment, etc.)
1781 // -An extension gets uninstalled while updates are in progress (so it doesn't
1782 // "come back from the dead")
1783 // -An extension gets manually updated to v3 while we're downloading v2 (ie
1784 // you don't get downgraded accidentally)
1785 // -An update manifest mentions multiple updates
1787 } // namespace extensions