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.
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/chrome_extension_downloader_factory.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/request_queue_impl.h"
38 #include "chrome/browser/google/google_brand.h"
39 #include "chrome/browser/prefs/pref_service_syncable.h"
40 #include "chrome/common/pref_names.h"
41 #include "chrome/test/base/testing_profile.h"
42 #include "components/crx_file/id_util.h"
43 #include "components/omaha_query_params/omaha_query_params.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/test/test_browser_thread_bundle.h"
50 #include "content/public/test/test_utils.h"
51 #include "extensions/browser/extension_prefs.h"
52 #include "extensions/browser/extension_registry.h"
53 #include "extensions/browser/extension_system.h"
54 #include "extensions/browser/updater/manifest_fetch_data.h"
55 #include "extensions/common/extension.h"
56 #include "extensions/common/extension_urls.h"
57 #include "extensions/common/manifest_constants.h"
58 #include "google_apis/gaia/fake_identity_provider.h"
59 #include "google_apis/gaia/fake_oauth2_token_service.h"
60 #include "libxml/globals.h"
61 #include "net/base/backoff_entry.h"
62 #include "net/base/escape.h"
63 #include "net/base/load_flags.h"
64 #include "net/http/http_request_headers.h"
65 #include "net/url_request/test_url_fetcher_factory.h"
66 #include "net/url_request/url_request_status.h"
67 #include "testing/gmock/include/gmock/gmock.h"
68 #include "testing/gtest/include/gtest/gtest.h"
69 #include "url/third_party/mozilla/url_parse.h"
71 #if defined(OS_CHROMEOS)
72 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
73 #include "chrome/browser/chromeos/settings/cros_settings.h"
74 #include "chrome/browser/chromeos/settings/device_settings_service.h"
78 using base::TimeDelta;
79 using content::BrowserThread;
80 using omaha_query_params::OmahaQueryParams;
82 using testing::Invoke;
83 using testing::InvokeWithoutArgs;
85 using testing::Return;
86 using testing::SetArgPointee;
89 namespace extensions {
91 typedef ExtensionDownloaderDelegate::Error Error;
92 typedef ExtensionDownloaderDelegate::PingResult PingResult;
96 const net::BackoffEntry::Policy kNoBackoffPolicy = {
97 // Number of initial errors (in sequence) to ignore before applying
98 // exponential back-off rules.
101 // Initial delay for exponential back-off in ms.
104 // Factor by which the waiting time will be multiplied.
107 // Fuzzing percentage. ex: 10% will spread requests randomly
108 // between 90%-100% of the calculated time.
111 // Maximum amount of time we are willing to delay our request in ms.
114 // Time to keep an entry from being discarded even when it
115 // has no significant state, -1 to never discard.
118 // Don't use initial delay unless the last request was an error.
122 const char kEmptyUpdateUrlData[] = "";
124 const char kAuthUserQueryKey[] = "authuser";
126 int kExpectedLoadFlags =
127 net::LOAD_DO_NOT_SEND_COOKIES |
128 net::LOAD_DO_NOT_SAVE_COOKIES |
129 net::LOAD_DISABLE_CACHE;
131 int kExpectedLoadFlagsForDownloadWithCookies = net::LOAD_DISABLE_CACHE;
133 // Fake authentication constants
134 const char kFakeAccountId[] = "bobloblaw@lawblog.example.com";
135 const char kFakeOAuth2Token[] = "ce n'est pas un jeton";
137 const ManifestFetchData::PingData kNeverPingedData(
138 ManifestFetchData::kNeverPinged, ManifestFetchData::kNeverPinged, true);
140 class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate {
142 MOCK_METHOD4(OnExtensionDownloadFailed, void(const std::string&,
145 const std::set<int>&));
146 MOCK_METHOD7(OnExtensionDownloadFinished, void(const std::string&,
147 const base::FilePath&,
152 const std::set<int>&));
153 MOCK_METHOD2(GetPingDataForExtension,
154 bool(const std::string&, ManifestFetchData::PingData*));
155 MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&));
156 MOCK_METHOD1(IsExtensionPending, bool(const std::string&));
157 MOCK_METHOD2(GetExtensionExistingVersion,
158 bool(const std::string&, std::string*));
161 scoped_refptr<content::MessageLoopRunner> runner =
162 new content::MessageLoopRunner;
163 quit_closure_ = runner->QuitClosure();
165 quit_closure_.Reset();
172 void DelegateTo(ExtensionDownloaderDelegate* delegate) {
173 ON_CALL(*this, OnExtensionDownloadFailed(_, _, _, _))
174 .WillByDefault(Invoke(delegate,
175 &ExtensionDownloaderDelegate::OnExtensionDownloadFailed));
176 ON_CALL(*this, OnExtensionDownloadFinished(_, _, _, _, _, _, _))
177 .WillByDefault(Invoke(delegate,
178 &ExtensionDownloaderDelegate::OnExtensionDownloadFinished));
179 ON_CALL(*this, GetPingDataForExtension(_, _))
180 .WillByDefault(Invoke(delegate,
181 &ExtensionDownloaderDelegate::GetPingDataForExtension));
182 ON_CALL(*this, GetUpdateUrlData(_))
183 .WillByDefault(Invoke(delegate,
184 &ExtensionDownloaderDelegate::GetUpdateUrlData));
185 ON_CALL(*this, IsExtensionPending(_))
186 .WillByDefault(Invoke(delegate,
187 &ExtensionDownloaderDelegate::IsExtensionPending));
188 ON_CALL(*this, GetExtensionExistingVersion(_, _))
189 .WillByDefault(Invoke(delegate,
190 &ExtensionDownloaderDelegate::GetExtensionExistingVersion));
194 base::Closure quit_closure_;
197 const int kNotificationsObserved[] = {
198 extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED,
199 extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
202 // A class that observes the notifications sent by the ExtensionUpdater and
203 // the ExtensionDownloader.
204 class NotificationsObserver : public content::NotificationObserver {
206 NotificationsObserver() {
207 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
210 kNotificationsObserved[i],
211 content::NotificationService::AllSources());
215 virtual ~NotificationsObserver() {
216 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
217 registrar_.Remove(this,
218 kNotificationsObserved[i],
219 content::NotificationService::AllSources());
223 size_t StartedCount() { return count_[0]; }
224 size_t UpdatedCount() { return count_[1]; }
226 bool Updated(const std::string& id) {
227 return updated_.find(id) != updated_.end();
231 scoped_refptr<content::MessageLoopRunner> runner =
232 new content::MessageLoopRunner;
233 quit_closure_ = runner->QuitClosure();
235 quit_closure_.Reset();
239 virtual void Observe(int type,
240 const content::NotificationSource& source,
241 const content::NotificationDetails& details) OVERRIDE {
242 if (!quit_closure_.is_null())
244 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
245 if (kNotificationsObserved[i] == type) {
247 if (type == extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND) {
249 content::Details<UpdateDetails>(details)->id);
257 content::NotificationRegistrar registrar_;
258 size_t count_[arraysize(kNotificationsObserved)];
259 std::set<std::string> updated_;
260 base::Closure quit_closure_;
262 DISALLOW_COPY_AND_ASSIGN(NotificationsObserver);
265 // Extracts the integer value of the |authuser| query parameter. Returns 0 if
266 // the parameter is not set.
267 int GetAuthUserQueryValue(const GURL& url) {
268 std::string query_string = url.query();
269 url::Component query(0, query_string.length());
270 url::Component key, value;
272 url::ExtractQueryKeyValue(query_string.c_str(), &query, &key, &value)) {
273 std::string key_string = query_string.substr(key.begin, key.len);
274 if (key_string == kAuthUserQueryKey) {
276 base::StringToInt(query_string.substr(value.begin, value.len),
286 // Base class for further specialized test classes.
287 class MockService : public TestExtensionService {
289 explicit MockService(TestExtensionPrefs* prefs)
291 pending_extension_manager_(&profile_),
292 downloader_delegate_override_(NULL) {
295 virtual ~MockService() {}
297 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
298 ADD_FAILURE() << "Subclass should override this if it will "
299 << "be accessed by a test.";
300 return &pending_extension_manager_;
303 Profile* profile() { return &profile_; }
305 net::URLRequestContextGetter* request_context() {
306 return profile_.GetRequestContext();
309 ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
311 PrefService* pref_service() { return prefs_->pref_service(); }
313 FakeOAuth2TokenService* fake_token_service() {
314 return fake_token_service_.get();
317 // Creates test extensions and inserts them into list. The name and
318 // version are all based on their index. If |update_url| is non-null, it
319 // will be used as the update_url for each extension.
320 // The |id| is used to distinguish extension names and make sure that
321 // no two extensions share the same name.
322 void CreateTestExtensions(int id, int count, ExtensionList *list,
323 const std::string* update_url,
324 Manifest::Location location) {
325 for (int i = 1; i <= count; i++) {
326 base::DictionaryValue manifest;
327 manifest.SetString(manifest_keys::kVersion,
328 base::StringPrintf("%d.0.0.0", i));
329 manifest.SetString(manifest_keys::kName,
330 base::StringPrintf("Extension %d.%d", id, i));
332 manifest.SetString(manifest_keys::kUpdateURL, *update_url);
333 scoped_refptr<Extension> e =
334 prefs_->AddExtensionWithManifest(manifest, location);
335 ASSERT_TRUE(e.get() != NULL);
340 ExtensionDownloader::Factory GetDownloaderFactory() {
341 return base::Bind(&MockService::CreateExtensionDownloader,
342 base::Unretained(this));
345 ExtensionDownloader::Factory GetAuthenticatedDownloaderFactory() {
346 return base::Bind(&MockService::CreateExtensionDownloaderWithIdentity,
347 base::Unretained(this));
350 void OverrideDownloaderDelegate(ExtensionDownloaderDelegate* delegate) {
351 downloader_delegate_override_ = delegate;
355 TestExtensionPrefs* const prefs_;
356 TestingProfile profile_;
357 PendingExtensionManager pending_extension_manager_;
360 scoped_ptr<ExtensionDownloader> CreateExtensionDownloader(
361 ExtensionDownloaderDelegate* delegate) {
362 return ChromeExtensionDownloaderFactory::CreateForRequestContext(
364 downloader_delegate_override_ ? downloader_delegate_override_
368 scoped_ptr<ExtensionDownloader> CreateExtensionDownloaderWithIdentity(
369 ExtensionDownloaderDelegate* delegate) {
370 scoped_ptr<FakeIdentityProvider> fake_identity_provider;
371 fake_token_service_.reset(new FakeOAuth2TokenService());
372 fake_identity_provider.reset(new FakeIdentityProvider(
373 fake_token_service_.get()));
374 fake_identity_provider->LogIn(kFakeAccountId);
375 fake_token_service_->AddAccount(kFakeAccountId);
377 scoped_ptr<ExtensionDownloader> downloader(
378 CreateExtensionDownloader(delegate));
379 downloader->SetWebstoreIdentityProvider(
380 fake_identity_provider.PassAs<IdentityProvider>());
381 return downloader.Pass();
384 scoped_ptr<FakeOAuth2TokenService> fake_token_service_;
386 ExtensionDownloaderDelegate* downloader_delegate_override_;
388 DISALLOW_COPY_AND_ASSIGN(MockService);
392 bool ShouldInstallExtensionsOnly(const Extension* extension) {
393 return extension->GetType() == Manifest::TYPE_EXTENSION;
396 bool ShouldInstallThemesOnly(const Extension* extension) {
397 return extension->is_theme();
400 bool ShouldAlwaysInstall(const Extension* extension) {
404 // Loads some pending extension records into a pending extension manager.
405 void SetupPendingExtensionManagerForTest(
407 const GURL& update_url,
408 PendingExtensionManager* pending_extension_manager) {
409 for (int i = 1; i <= count; ++i) {
410 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
411 (i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
412 const bool kIsFromSync = true;
413 const bool kInstallSilently = true;
414 const bool kMarkAcknowledged = false;
415 const bool kRemoteInstall = false;
417 crx_file::id_util::GenerateId(base::StringPrintf("extension%i", i));
419 pending_extension_manager->AddForTesting(
420 PendingExtensionInfo(id,
424 should_allow_install,
434 class ServiceForManifestTests : public MockService {
436 explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
437 : MockService(prefs),
438 registry_(ExtensionRegistry::Get(profile())) {
441 virtual ~ServiceForManifestTests() {}
443 virtual const Extension* GetExtensionById(
444 const std::string& id, bool include_disabled) const OVERRIDE {
445 const Extension* result = registry_->enabled_extensions().GetByID(id);
446 if (result || !include_disabled)
448 return registry_->disabled_extensions().GetByID(id);
451 virtual const ExtensionSet* extensions() const OVERRIDE {
452 return ®istry_->enabled_extensions();
455 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
456 return &pending_extension_manager_;
459 virtual const Extension* GetPendingExtensionUpdate(
460 const std::string& id) const OVERRIDE {
464 virtual bool IsExtensionEnabled(const std::string& id) const OVERRIDE {
465 return !registry_->disabled_extensions().Contains(id);
468 void set_extensions(ExtensionList extensions,
469 ExtensionList disabled_extensions) {
470 registry_->ClearAll();
471 for (ExtensionList::const_iterator it = extensions.begin();
472 it != extensions.end(); ++it) {
473 registry_->AddEnabled(*it);
475 for (ExtensionList::const_iterator it = disabled_extensions.begin();
476 it != disabled_extensions.end(); ++it) {
477 registry_->AddDisabled(*it);
482 ExtensionRegistry* registry_;
485 class ServiceForDownloadTests : public MockService {
487 explicit ServiceForDownloadTests(TestExtensionPrefs* prefs)
488 : MockService(prefs) {
491 // Add a fake crx installer to be returned by a call to UpdateExtension()
492 // with a specific ID. Caller keeps ownership of |crx_installer|.
493 void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) {
494 fake_crx_installers_[id] = crx_installer;
497 virtual bool UpdateExtension(
498 const std::string& id,
499 const base::FilePath& extension_path,
500 bool file_ownership_passed,
501 CrxInstaller** out_crx_installer) OVERRIDE {
503 install_path_ = extension_path;
505 if (ContainsKey(fake_crx_installers_, id)) {
506 *out_crx_installer = fake_crx_installers_[id];
513 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
514 return &pending_extension_manager_;
517 virtual const Extension* GetExtensionById(
518 const std::string& id, bool) const OVERRIDE {
519 last_inquired_extension_id_ = id;
523 const std::string& extension_id() const { return extension_id_; }
524 const base::FilePath& install_path() const { return install_path_; }
527 // Hold the set of ids that UpdateExtension() should fake success on.
528 // UpdateExtension(id, ...) will return true iff fake_crx_installers_
529 // contains key |id|. |out_install_notification_source| will be set
530 // to Source<CrxInstaller(fake_crx_installers_[i]).
531 std::map<std::string, CrxInstaller*> fake_crx_installers_;
533 std::string extension_id_;
534 base::FilePath install_path_;
537 // The last extension ID that GetExtensionById was called with.
538 // Mutable because the method that sets it (GetExtensionById) is const
539 // in the actual extension service, but must record the last extension
540 // ID in this test class.
541 mutable std::string last_inquired_extension_id_;
544 static const int kUpdateFrequencySecs = 15;
546 // Takes a string with KEY=VALUE parameters separated by '&' in |params| and
547 // puts the key/value pairs into |result|. For keys with no value, the empty
548 // string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
549 // "foo", and "c" to "".
550 static void ExtractParameters(const std::string& params,
551 std::map<std::string, std::string>* result) {
552 std::vector<std::string> pairs;
553 base::SplitString(params, '&', &pairs);
554 for (size_t i = 0; i < pairs.size(); i++) {
555 std::vector<std::string> key_val;
556 base::SplitString(pairs[i], '=', &key_val);
557 if (!key_val.empty()) {
558 std::string key = key_val[0];
559 EXPECT_TRUE(result->find(key) == result->end());
560 (*result)[key] = (key_val.size() == 2) ? key_val[1] : std::string();
567 static void VerifyQueryAndExtractParameters(
568 const std::string& query,
569 std::map<std::string, std::string>* result) {
570 std::map<std::string, std::string> params;
571 ExtractParameters(query, ¶ms);
573 std::string omaha_params = OmahaQueryParams::Get(OmahaQueryParams::CRX);
574 std::map<std::string, std::string> expected;
575 ExtractParameters(omaha_params, &expected);
577 for (std::map<std::string, std::string>::iterator it = expected.begin();
578 it != expected.end(); ++it) {
579 EXPECT_EQ(it->second, params[it->first]);
582 EXPECT_EQ(1U, params.count("x"));
583 std::string decoded = net::UnescapeURLComponent(
584 params["x"], net::UnescapeRule::URL_SPECIAL_CHARS);
585 ExtractParameters(decoded, result);
588 // All of our tests that need to use private APIs of ExtensionUpdater live
589 // inside this class (which is a friend to ExtensionUpdater).
590 class ExtensionUpdaterTest : public testing::Test {
592 ExtensionUpdaterTest()
594 content::TestBrowserThreadBundle::IO_MAINLOOP) {
597 virtual void SetUp() OVERRIDE {
598 prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
601 virtual void TearDown() OVERRIDE {
602 // Some tests create URLRequestContextGetters, whose destruction must run
603 // on the IO thread. Make sure the IO loop spins before shutdown so that
604 // those objects are released.
609 void RunUntilIdle() {
610 prefs_->pref_service()->CommitPendingWrite();
611 base::RunLoop().RunUntilIdle();
614 void SimulateTimerFired(ExtensionUpdater* updater) {
615 EXPECT_TRUE(updater->timer_.IsRunning());
616 updater->timer_.Stop();
617 updater->TimerFired();
618 content::RunAllBlockingPoolTasksUntilIdle();
621 // Adds a Result with the given data to results.
622 void AddParseResult(const std::string& id,
623 const std::string& version,
624 const std::string& url,
625 UpdateManifest::Results* results) {
626 UpdateManifest::Result result;
627 result.extension_id = id;
628 result.version = version;
629 result.crx_url = GURL(url);
630 results->list.push_back(result);
633 void StartUpdateCheck(ExtensionDownloader* downloader,
634 ManifestFetchData* fetch_data) {
635 downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data));
638 size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
639 return downloader->manifests_queue_.size() +
640 (downloader->manifest_fetcher_.get() ? 1 : 0);
643 void TestExtensionUpdateCheckRequests(bool pending) {
644 // Create an extension with an update_url.
645 ServiceForManifestTests service(prefs_.get());
646 std::string update_url("http://foo.com/bar");
647 ExtensionList extensions;
648 NotificationsObserver observer;
649 PendingExtensionManager* pending_extension_manager =
650 service.pending_extension_manager();
652 SetupPendingExtensionManagerForTest(1, GURL(update_url),
653 pending_extension_manager);
655 service.CreateTestExtensions(1, 1, &extensions, &update_url,
657 service.set_extensions(extensions, ExtensionList());
660 // Set up and start the updater.
661 net::TestURLFetcherFactory factory;
662 ExtensionUpdater updater(&service,
663 service.extension_prefs(),
664 service.pref_service(),
668 service.GetDownloaderFactory());
671 // Tell the update that it's time to do update checks.
672 EXPECT_EQ(0u, observer.StartedCount());
673 SimulateTimerFired(&updater);
674 EXPECT_EQ(1u, observer.StartedCount());
676 // Get the url our mock fetcher was asked to fetch.
677 net::TestURLFetcher* fetcher =
678 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
679 const GURL& url = fetcher->GetOriginalURL();
680 EXPECT_FALSE(url.is_empty());
681 EXPECT_TRUE(url.is_valid());
682 EXPECT_TRUE(url.SchemeIs("http"));
683 EXPECT_EQ("foo.com", url.host());
684 EXPECT_EQ("/bar", url.path());
686 // Validate the extension request parameters in the query. It should
687 // look something like "x=id%3D<id>%26v%3D<version>%26uc".
688 EXPECT_TRUE(url.has_query());
689 std::map<std::string, std::string> params;
690 VerifyQueryAndExtractParameters(url.query(), ¶ms);
692 EXPECT_TRUE(pending_extension_manager->IsIdPending(params["id"]));
693 EXPECT_EQ("0.0.0.0", params["v"]);
695 EXPECT_EQ(extensions[0]->id(), params["id"]);
696 EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
698 EXPECT_EQ("", params["uc"]);
701 void TestUpdateUrlDataEmpty() {
702 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
703 const std::string version = "1.0";
705 // Make sure that an empty update URL data string does not cause a ap=
706 // option to appear in the x= parameter.
707 scoped_ptr<ManifestFetchData> fetch_data(
708 CreateManifestFetchData(GURL("http://localhost/foo")));
709 fetch_data->AddExtension(
710 id, version, &kNeverPingedData, std::string(), std::string(), false);
712 std::map<std::string, std::string> params;
713 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), ¶ms);
714 EXPECT_EQ(id, params["id"]);
715 EXPECT_EQ(version, params["v"]);
716 EXPECT_EQ(0U, params.count("ap"));
719 void TestUpdateUrlDataSimple() {
720 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
721 const std::string version = "1.0";
723 // Make sure that an update URL data string causes an appropriate ap=
724 // option to appear in the x= parameter.
725 scoped_ptr<ManifestFetchData> fetch_data(
726 CreateManifestFetchData(GURL("http://localhost/foo")));
727 fetch_data->AddExtension(
728 id, version, &kNeverPingedData, "bar", std::string(), false);
729 std::map<std::string, std::string> params;
730 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), ¶ms);
731 EXPECT_EQ(id, params["id"]);
732 EXPECT_EQ(version, params["v"]);
733 EXPECT_EQ("bar", params["ap"]);
736 void TestUpdateUrlDataCompound() {
737 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
738 const std::string version = "1.0";
740 // Make sure that an update URL data string causes an appropriate ap=
741 // option to appear in the x= parameter.
742 scoped_ptr<ManifestFetchData> fetch_data(
743 CreateManifestFetchData(GURL("http://localhost/foo")));
744 fetch_data->AddExtension(
745 id, version, &kNeverPingedData, "a=1&b=2&c", std::string(), false);
746 std::map<std::string, std::string> params;
747 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), ¶ms);
748 EXPECT_EQ(id, params["id"]);
749 EXPECT_EQ(version, params["v"]);
750 EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]);
753 void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
754 net::TestURLFetcherFactory factory;
756 MockService service(prefs_.get());
757 MockExtensionDownloaderDelegate delegate;
758 ExtensionDownloader downloader(&delegate, service.request_context());
759 ExtensionList extensions;
760 std::string url(gallery_url);
762 service.CreateTestExtensions(1, 1, &extensions, &url, Manifest::INTERNAL);
764 const std::string& id = extensions[0]->id();
765 EXPECT_CALL(delegate, GetPingDataForExtension(id, _));
767 downloader.AddExtension(*extensions[0].get(), 0);
768 downloader.StartAllPending(NULL);
769 net::TestURLFetcher* fetcher =
770 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
771 ASSERT_TRUE(fetcher);
772 // Make sure that extensions that update from the gallery ignore any
774 const std::string& update_url = fetcher->GetOriginalURL().spec();
775 std::string::size_type x = update_url.find("x=");
776 EXPECT_NE(std::string::npos, x);
777 std::string::size_type ap = update_url.find("ap%3D", x);
778 EXPECT_EQ(std::string::npos, ap);
781 void TestInstallSource() {
782 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
783 const std::string version = "1.0";
784 const std::string install_source = "instally";
786 // Make sure that an installsource= appears in the x= parameter.
787 scoped_ptr<ManifestFetchData> fetch_data(
788 CreateManifestFetchData(GURL("http://localhost/foo")));
789 fetch_data->AddExtension(id, version, &kNeverPingedData,
790 kEmptyUpdateUrlData, install_source, false);
791 std::map<std::string, std::string> params;
792 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), ¶ms);
793 EXPECT_EQ(id, params["id"]);
794 EXPECT_EQ(version, params["v"]);
795 EXPECT_EQ(install_source, params["installsource"]);
798 void TestDetermineUpdates() {
799 TestingProfile profile;
800 MockExtensionDownloaderDelegate delegate;
801 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
803 // Check passing an empty list of parse results to DetermineUpdates
804 scoped_ptr<ManifestFetchData> fetch_data(
805 CreateManifestFetchData(GURL("http://localhost/foo")));
806 UpdateManifest::Results updates;
807 std::vector<int> updateable;
808 downloader.DetermineUpdates(*fetch_data, updates, &updateable);
809 EXPECT_TRUE(updateable.empty());
811 // Create two updates - expect that DetermineUpdates will return the first
812 // one (v1.0 installed, v1.1 available) but not the second one (both
813 // installed and available at v2.0).
814 const std::string id1 = crx_file::id_util::GenerateId("1");
815 const std::string id2 = crx_file::id_util::GenerateId("2");
816 fetch_data->AddExtension(
817 id1, "1.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string(),
819 AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);
820 fetch_data->AddExtension(
821 id2, "2.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string(),
823 AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);
825 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
826 EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
827 .WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"),
829 EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
830 .WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"),
833 downloader.DetermineUpdates(*fetch_data, updates, &updateable);
834 EXPECT_EQ(1u, updateable.size());
835 EXPECT_EQ(0, updateable[0]);
838 void TestDetermineUpdatesPending() {
839 // Create a set of test extensions
840 ServiceForManifestTests service(prefs_.get());
841 PendingExtensionManager* pending_extension_manager =
842 service.pending_extension_manager();
843 SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
845 TestingProfile profile;
846 MockExtensionDownloaderDelegate delegate;
847 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
849 scoped_ptr<ManifestFetchData> fetch_data(
850 CreateManifestFetchData(GURL("http://localhost/foo")));
851 UpdateManifest::Results updates;
853 std::list<std::string> ids_for_update_check;
854 pending_extension_manager->GetPendingIdsForUpdateCheck(
855 &ids_for_update_check);
857 std::list<std::string>::const_iterator it;
858 for (it = ids_for_update_check.begin();
859 it != ids_for_update_check.end(); ++it) {
860 fetch_data->AddExtension(*it,
866 AddParseResult(*it, "1.1", "http://localhost/e1_1.1.crx", &updates);
869 // The delegate will tell the downloader that all the extensions are
871 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(true));
873 std::vector<int> updateable;
874 downloader.DetermineUpdates(*fetch_data, updates, &updateable);
875 // All the apps should be updateable.
876 EXPECT_EQ(3u, updateable.size());
877 for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) {
878 EXPECT_EQ(static_cast<int>(i), updateable[i]);
882 void TestMultipleManifestDownloading() {
883 net::TestURLFetcherFactory factory;
884 factory.set_remove_fetcher_on_delete(true);
885 net::TestURLFetcher* fetcher = NULL;
886 MockService service(prefs_.get());
887 MockExtensionDownloaderDelegate delegate;
888 ExtensionDownloader downloader(&delegate, service.request_context());
889 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
891 GURL kUpdateUrl("http://localhost/manifest1");
893 scoped_ptr<ManifestFetchData> fetch1(CreateManifestFetchData(kUpdateUrl));
894 scoped_ptr<ManifestFetchData> fetch2(CreateManifestFetchData(kUpdateUrl));
895 scoped_ptr<ManifestFetchData> fetch3(CreateManifestFetchData(kUpdateUrl));
896 scoped_ptr<ManifestFetchData> fetch4(CreateManifestFetchData(kUpdateUrl));
897 ManifestFetchData::PingData zeroDays(0, 0, true);
898 fetch1->AddExtension(
899 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
900 fetch2->AddExtension(
901 "2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
902 fetch3->AddExtension(
903 "3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
904 fetch4->AddExtension(
905 "4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
907 // This will start the first fetcher and queue the others. The next in queue
908 // is started as each fetcher receives its response. Note that the fetchers
909 // don't necessarily run in the order that they are started from here.
910 GURL fetch1_url = fetch1->full_url();
911 GURL fetch2_url = fetch2->full_url();
912 GURL fetch3_url = fetch3->full_url();
913 GURL fetch4_url = fetch4->full_url();
914 downloader.StartUpdateCheck(fetch1.Pass());
915 downloader.StartUpdateCheck(fetch2.Pass());
916 downloader.StartUpdateCheck(fetch3.Pass());
917 downloader.StartUpdateCheck(fetch4.Pass());
920 for (int i = 0; i < 4; ++i) {
921 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
922 ASSERT_TRUE(fetcher);
923 ASSERT_TRUE(fetcher->delegate());
924 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
925 EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
927 if (fetcher->GetOriginalURL() == fetch1_url) {
928 // The first fetch will fail.
929 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
930 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
931 fetcher->set_url(kUpdateUrl);
932 fetcher->set_status(net::URLRequestStatus());
933 fetcher->set_response_code(400);
934 fetcher->delegate()->OnURLFetchComplete(fetcher);
936 Mock::VerifyAndClearExpectations(&delegate);
938 } else if (fetcher->GetOriginalURL() == fetch2_url) {
939 // The second fetch gets invalid data.
940 const std::string kInvalidXml = "invalid xml";
941 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
942 "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _))
943 .WillOnce(InvokeWithoutArgs(
945 &MockExtensionDownloaderDelegate::Quit));
946 fetcher->set_url(kUpdateUrl);
947 fetcher->set_status(net::URLRequestStatus());
948 fetcher->set_response_code(200);
949 fetcher->SetResponseString(kInvalidXml);
950 fetcher->delegate()->OnURLFetchComplete(fetcher);
952 Mock::VerifyAndClearExpectations(&delegate);
954 } else if (fetcher->GetOriginalURL() == fetch3_url) {
955 // The third fetcher doesn't have an update available.
956 const std::string kNoUpdate =
957 "<?xml version='1.0' encoding='UTF-8'?>"
958 "<gupdate xmlns='http://www.google.com/update2/response'"
960 " <app appid='3333'>"
961 " <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'"
962 " version='3.0.0.0' prodversionmin='3.0.0.0' />"
965 EXPECT_CALL(delegate, IsExtensionPending("3333"))
966 .WillOnce(Return(false));
967 EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _))
968 .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"),
970 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
971 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _))
972 .WillOnce(InvokeWithoutArgs(
974 &MockExtensionDownloaderDelegate::Quit));
975 fetcher->set_url(kUpdateUrl);
976 fetcher->set_status(net::URLRequestStatus());
977 fetcher->set_response_code(200);
978 fetcher->SetResponseString(kNoUpdate);
979 fetcher->delegate()->OnURLFetchComplete(fetcher);
981 Mock::VerifyAndClearExpectations(&delegate);
983 } else if (fetcher->GetOriginalURL() == fetch4_url) {
984 // The last fetcher has an update.
985 NotificationsObserver observer;
986 const std::string kUpdateAvailable =
987 "<?xml version='1.0' encoding='UTF-8'?>"
988 "<gupdate xmlns='http://www.google.com/update2/response'"
990 " <app appid='4444'>"
991 " <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
992 " version='4.0.42.0' prodversionmin='4.0.42.0' />"
995 EXPECT_CALL(delegate, IsExtensionPending("4444"))
996 .WillOnce(Return(false));
997 EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _))
998 .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"),
1000 fetcher->set_url(kUpdateUrl);
1001 fetcher->set_status(net::URLRequestStatus());
1002 fetcher->set_response_code(200);
1003 fetcher->SetResponseString(kUpdateAvailable);
1004 fetcher->delegate()->OnURLFetchComplete(fetcher);
1006 Mock::VerifyAndClearExpectations(&delegate);
1008 // Verify that the downloader decided to update this extension.
1009 EXPECT_EQ(1u, observer.UpdatedCount());
1010 EXPECT_TRUE(observer.Updated("4444"));
1011 fetch4_url = GURL();
1013 ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL();
1017 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1019 ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL();
1022 void TestManifestRetryDownloading() {
1023 net::TestURLFetcherFactory factory;
1024 net::TestURLFetcher* fetcher = NULL;
1025 NotificationsObserver observer;
1026 MockService service(prefs_.get());
1027 MockExtensionDownloaderDelegate delegate;
1028 ExtensionDownloader downloader(&delegate, service.request_context());
1029 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
1031 GURL kUpdateUrl("http://localhost/manifest1");
1033 scoped_ptr<ManifestFetchData> fetch(CreateManifestFetchData(kUpdateUrl));
1034 ManifestFetchData::PingData zeroDays(0, 0, true);
1035 fetch->AddExtension(
1036 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
1038 // This will start the first fetcher.
1039 downloader.StartUpdateCheck(fetch.Pass());
1042 // ExtensionDownloader should retry kMaxRetries times and then fail.
1043 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
1044 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
1045 for (int i = 0; i <= ExtensionDownloader::kMaxRetries; ++i) {
1046 // All fetches will fail.
1047 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1048 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1049 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1050 fetcher->set_url(kUpdateUrl);
1051 fetcher->set_status(net::URLRequestStatus());
1052 // Code 5xx causes ExtensionDownloader to retry.
1053 fetcher->set_response_code(500);
1054 fetcher->delegate()->OnURLFetchComplete(fetcher);
1057 Mock::VerifyAndClearExpectations(&delegate);
1060 // For response codes that are not in the 5xx range ExtensionDownloader
1061 // should not retry.
1062 fetch.reset(CreateManifestFetchData(kUpdateUrl));
1063 fetch->AddExtension(
1064 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
1066 // This will start the first fetcher.
1067 downloader.StartUpdateCheck(fetch.Pass());
1070 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
1071 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
1072 // The first fetch will fail, and require retrying.
1073 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1074 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1075 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1076 fetcher->set_url(kUpdateUrl);
1077 fetcher->set_status(net::URLRequestStatus());
1078 fetcher->set_response_code(500);
1079 fetcher->delegate()->OnURLFetchComplete(fetcher);
1082 // The second fetch will fail with response 400 and should not cause
1083 // ExtensionDownloader to retry.
1084 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1085 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1086 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1087 fetcher->set_url(kUpdateUrl);
1088 fetcher->set_status(net::URLRequestStatus());
1089 fetcher->set_response_code(400);
1090 fetcher->delegate()->OnURLFetchComplete(fetcher);
1093 Mock::VerifyAndClearExpectations(&delegate);
1096 void TestSingleExtensionDownloading(bool pending, bool retry, bool fail) {
1097 net::TestURLFetcherFactory factory;
1098 net::TestURLFetcher* fetcher = NULL;
1099 scoped_ptr<ServiceForDownloadTests> service(
1100 new ServiceForDownloadTests(prefs_.get()));
1101 ExtensionUpdater updater(service.get(),
1102 service->extension_prefs(),
1103 service->pref_service(),
1105 kUpdateFrequencySecs,
1107 service->GetDownloaderFactory());
1108 MockExtensionDownloaderDelegate delegate;
1109 delegate.DelegateTo(&updater);
1110 service->OverrideDownloaderDelegate(&delegate);
1112 updater.EnsureDownloaderCreated();
1113 updater.downloader_->extensions_queue_.set_backoff_policy(
1116 GURL test_url("http://localhost/extension.crx");
1118 std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1120 Version version("0.0.1");
1121 std::set<int> requests;
1123 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
1124 new ExtensionDownloader::ExtensionFetch(
1125 id, test_url, hash, version.GetString(), requests));
1126 updater.downloader_->FetchUpdatedExtension(fetch.Pass());
1129 const bool kIsFromSync = true;
1130 const bool kInstallSilently = true;
1131 const bool kMarkAcknowledged = false;
1132 const bool kRemoteInstall = false;
1133 PendingExtensionManager* pending_extension_manager =
1134 service->pending_extension_manager();
1135 pending_extension_manager->AddForTesting(
1136 PendingExtensionInfo(id,
1140 &ShouldAlwaysInstall,
1144 Extension::NO_FLAGS,
1149 // Call back the ExtensionUpdater with a 200 response and some test data
1150 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1151 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1152 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1153 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1156 // Reply with response code 500 to cause ExtensionDownloader to retry
1157 fetcher->set_url(test_url);
1158 fetcher->set_status(net::URLRequestStatus());
1159 fetcher->set_response_code(500);
1160 fetcher->delegate()->OnURLFetchComplete(fetcher);
1163 fetcher = factory.GetFetcherByID(
1164 ExtensionDownloader::kExtensionFetcherId);
1165 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1166 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1169 fetcher->set_url(test_url);
1170 fetcher->set_status(net::URLRequestStatus());
1172 fetcher->set_response_code(404);
1173 EXPECT_CALL(delegate, OnExtensionDownloadFailed(id, _, _, requests));
1175 fetcher->set_response_code(200);
1176 fetcher->SetResponseFilePath(extension_file_path);
1177 EXPECT_CALL(delegate, OnExtensionDownloadFinished(
1178 id, _, _, _, version.GetString(), _, requests));
1180 fetcher->delegate()->OnURLFetchComplete(fetcher);
1185 // Don't expect any extension to have been installed.
1186 EXPECT_TRUE(service->extension_id().empty());
1188 // Expect that ExtensionUpdater asked the mock extensions service to
1189 // install a file with the test data for the right id.
1190 EXPECT_EQ(id, service->extension_id());
1191 base::FilePath tmpfile_path = service->install_path();
1192 EXPECT_FALSE(tmpfile_path.empty());
1193 EXPECT_EQ(extension_file_path, tmpfile_path);
1197 // Update a single extension in an environment where the download request
1198 // initially responds with a 403 status. If |identity_provider| is not NULL,
1199 // this will first expect a request which includes an Authorization header
1200 // with an OAuth2 bearer token; otherwise, or if OAuth2 failure is simulated,
1201 // this expects the downloader to fall back onto cookie-based credentials.
1202 void TestProtectedDownload(
1203 const std::string& url_prefix,
1205 bool succeed_with_oauth2,
1208 net::TestURLFetcherFactory factory;
1209 net::TestURLFetcher* fetcher = NULL;
1210 scoped_ptr<ServiceForDownloadTests> service(
1211 new ServiceForDownloadTests(prefs_.get()));
1212 const ExtensionDownloader::Factory& downloader_factory =
1213 enable_oauth2 ? service->GetAuthenticatedDownloaderFactory()
1214 : service->GetDownloaderFactory();
1215 ExtensionUpdater updater(
1217 service->extension_prefs(),
1218 service->pref_service(),
1220 kUpdateFrequencySecs,
1222 downloader_factory);
1224 updater.EnsureDownloaderCreated();
1225 updater.downloader_->extensions_queue_.set_backoff_policy(
1228 GURL test_url(base::StringPrintf("%s/extension.crx", url_prefix.c_str()));
1229 std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1231 Version version("0.0.1");
1232 std::set<int> requests;
1234 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
1235 new ExtensionDownloader::ExtensionFetch(
1236 id, test_url, hash, version.GetString(), requests));
1237 updater.downloader_->FetchUpdatedExtension(fetch.Pass());
1239 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1240 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1241 EXPECT_EQ(kExpectedLoadFlags, fetcher->GetLoadFlags());
1243 // Fake a 403 response.
1244 fetcher->set_url(test_url);
1245 fetcher->set_status(net::URLRequestStatus());
1246 fetcher->set_response_code(403);
1247 fetcher->delegate()->OnURLFetchComplete(fetcher);
1249 if (service->fake_token_service()) {
1250 service->fake_token_service()->IssueAllTokensForAccount(
1251 kFakeAccountId, kFakeOAuth2Token, base::Time::Now());
1255 bool using_oauth2 = false;
1256 int expected_load_flags = kExpectedLoadFlags;
1257 // Verify that the fetch has had its credentials properly incremented.
1258 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1259 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1260 net::HttpRequestHeaders fetch_headers;
1261 fetcher->GetExtraRequestHeaders(&fetch_headers);
1262 // If the download URL is not https, no credentials should be provided.
1263 if (!test_url.SchemeIsSecure()) {
1265 EXPECT_EQ(kExpectedLoadFlags, fetcher->GetLoadFlags());
1266 // No Authorization header.
1267 EXPECT_FALSE(fetch_headers.HasHeader(
1268 net::HttpRequestHeaders::kAuthorization));
1269 expected_load_flags = kExpectedLoadFlags;
1271 // HTTPS is in use, so credentials are allowed.
1272 if (enable_oauth2 && test_url.DomainIs("google.com")) {
1273 // If an IdentityProvider is present and the URL is a google.com
1274 // URL, the fetcher should be in OAuth2 mode after the intitial
1276 EXPECT_TRUE(fetch_headers.HasHeader(
1277 net::HttpRequestHeaders::kAuthorization));
1278 std::string expected_header_value = base::StringPrintf("Bearer %s",
1280 std::string actual_header_value;
1281 fetch_headers.GetHeader(net::HttpRequestHeaders::kAuthorization,
1282 &actual_header_value);
1283 EXPECT_EQ(expected_header_value, actual_header_value);
1284 using_oauth2 = true;
1286 // No IdentityProvider (or no google.com), so expect cookies instead of
1287 // an Authorization header.
1288 EXPECT_FALSE(fetch_headers.HasHeader(
1289 net::HttpRequestHeaders::kAuthorization));
1290 EXPECT_EQ(kExpectedLoadFlagsForDownloadWithCookies,
1291 fetcher->GetLoadFlags());
1292 expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
1296 bool success = false;
1298 if (succeed_with_oauth2) {
1301 // Simulate OAuth2 failure and ensure that we fall back on cookies.
1302 fetcher->set_url(test_url);
1303 fetcher->set_status(net::URLRequestStatus());
1304 fetcher->set_response_code(403);
1305 fetcher->delegate()->OnURLFetchComplete(fetcher);
1308 const ExtensionDownloader::ExtensionFetch& fetch =
1309 *updater.downloader_->extensions_queue_.active_request();
1310 EXPECT_EQ(0, GetAuthUserQueryValue(fetch.url));
1311 EXPECT_EQ(ExtensionDownloader::ExtensionFetch::CREDENTIALS_COOKIES,
1314 fetcher = factory.GetFetcherByID(
1315 ExtensionDownloader::kExtensionFetcherId);
1316 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1317 fetcher->GetExtraRequestHeaders(&fetch_headers);
1318 EXPECT_FALSE(fetch_headers.HasHeader(
1319 net::HttpRequestHeaders::kAuthorization));
1320 EXPECT_EQ(kExpectedLoadFlagsForDownloadWithCookies,
1321 fetcher->GetLoadFlags());
1322 expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
1327 // Not yet ready to simulate a successful fetch. At this point we begin
1328 // simulating cookie-based authentication with increasing values of
1329 // authuser (starting from 0.)
1331 for (; user_index <= max_authuser; ++user_index) {
1332 const ExtensionDownloader::ExtensionFetch& fetch =
1333 *updater.downloader_->extensions_queue_.active_request();
1334 EXPECT_EQ(user_index, GetAuthUserQueryValue(fetch.url));
1335 if (user_index == valid_authuser) {
1339 // Simulate an authorization failure which should elicit an increment
1340 // of the authuser value.
1342 factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1343 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1344 EXPECT_EQ(expected_load_flags, fetcher->GetLoadFlags());
1345 fetcher->set_url(fetch.url);
1346 fetcher->set_status(net::URLRequestStatus());
1347 fetcher->set_response_code(403);
1348 fetcher->delegate()->OnURLFetchComplete(fetcher);
1352 // Simulate exhaustion of all available authusers.
1353 if (!success && user_index > max_authuser) {
1354 const ExtensionDownloader::ExtensionFetch& fetch =
1355 *updater.downloader_->extensions_queue_.active_request();
1357 factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1358 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1359 fetcher->set_url(fetch.url);
1360 fetcher->set_status(net::URLRequestStatus());
1361 fetcher->set_response_code(401);
1362 fetcher->delegate()->OnURLFetchComplete(fetcher);
1367 // Simulate successful authorization with a 200 response.
1370 factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1371 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1372 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1373 fetcher->set_url(test_url);
1374 fetcher->set_status(net::URLRequestStatus());
1375 fetcher->set_response_code(200);
1376 fetcher->SetResponseFilePath(extension_file_path);
1377 fetcher->delegate()->OnURLFetchComplete(fetcher);
1380 // Verify installation would proceed as normal.
1381 EXPECT_EQ(id, service->extension_id());
1382 base::FilePath tmpfile_path = service->install_path();
1383 EXPECT_FALSE(tmpfile_path.empty());
1384 EXPECT_EQ(extension_file_path, tmpfile_path);
1388 // Two extensions are updated. If |updates_start_running| is true, the
1389 // mock extensions service has UpdateExtension(...) return true, and
1390 // the test is responsible for creating fake CrxInstallers. Otherwise,
1391 // UpdateExtension() returns false, signaling install failures.
1392 void TestMultipleExtensionDownloading(bool updates_start_running) {
1393 net::TestURLFetcherFactory factory;
1394 net::TestURLFetcher* fetcher = NULL;
1395 ServiceForDownloadTests service(prefs_.get());
1396 ExtensionUpdater updater(&service,
1397 service.extension_prefs(),
1398 service.pref_service(),
1400 kUpdateFrequencySecs,
1402 service.GetDownloaderFactory());
1404 updater.EnsureDownloaderCreated();
1405 updater.downloader_->extensions_queue_.set_backoff_policy(
1408 EXPECT_FALSE(updater.crx_install_is_running_);
1410 GURL url1("http://localhost/extension1.crx");
1411 GURL url2("http://localhost/extension2.crx");
1413 std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1414 std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
1419 std::string version1 = "0.1";
1420 std::string version2 = "0.1";
1421 std::set<int> requests;
1423 // Start two fetches
1424 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch1(
1425 new ExtensionDownloader::ExtensionFetch(
1426 id1, url1, hash1, version1, requests));
1427 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch2(
1428 new ExtensionDownloader::ExtensionFetch(
1429 id2, url2, hash2, version2, requests));
1430 updater.downloader_->FetchUpdatedExtension(fetch1.Pass());
1431 updater.downloader_->FetchUpdatedExtension(fetch2.Pass());
1433 // Make the first fetch complete.
1434 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1436 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1437 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1438 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1440 // We need some CrxInstallers, and CrxInstallers require a real
1441 // ExtensionService. Create one on the testing profile. Any action
1442 // the CrxInstallers take is on the testing profile's extension
1443 // service, not on our mock |service|. This allows us to fake
1444 // the CrxInstaller actions we want.
1445 TestingProfile profile;
1446 static_cast<TestExtensionSystem*>(
1447 ExtensionSystem::Get(&profile))->
1448 CreateExtensionService(
1449 CommandLine::ForCurrentProcess(),
1452 ExtensionService* extension_service =
1453 ExtensionSystem::Get(&profile)->extension_service();
1454 extension_service->set_extensions_enabled(true);
1455 extension_service->set_show_extensions_prompts(false);
1457 scoped_refptr<CrxInstaller> fake_crx1(
1458 CrxInstaller::CreateSilent(extension_service));
1459 scoped_refptr<CrxInstaller> fake_crx2(
1460 CrxInstaller::CreateSilent(extension_service));
1462 if (updates_start_running) {
1463 // Add fake CrxInstaller to be returned by service.UpdateExtension().
1464 service.AddFakeCrxInstaller(id1, fake_crx1.get());
1465 service.AddFakeCrxInstaller(id2, fake_crx2.get());
1467 // If we don't add fake CRX installers, the mock service fakes a failure
1468 // starting the install.
1471 fetcher->set_url(url1);
1472 fetcher->set_status(net::URLRequestStatus());
1473 fetcher->set_response_code(200);
1474 fetcher->SetResponseFilePath(extension_file_path);
1475 fetcher->delegate()->OnURLFetchComplete(fetcher);
1479 // Expect that the service was asked to do an install with the right data.
1480 base::FilePath tmpfile_path = service.install_path();
1481 EXPECT_FALSE(tmpfile_path.empty());
1482 EXPECT_EQ(id1, service.extension_id());
1485 // Make sure the second fetch finished and asked the service to do an
1487 base::FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2"));
1488 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1489 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1490 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1492 fetcher->set_url(url2);
1493 fetcher->set_status(net::URLRequestStatus());
1494 fetcher->set_response_code(200);
1495 fetcher->SetResponseFilePath(extension_file_path2);
1496 fetcher->delegate()->OnURLFetchComplete(fetcher);
1499 if (updates_start_running) {
1500 EXPECT_TRUE(updater.crx_install_is_running_);
1502 // The second install should not have run, because the first has not
1503 // sent a notification that it finished.
1504 EXPECT_EQ(id1, service.extension_id());
1506 // Fake install notice. This should start the second installation,
1507 // which will be checked below.
1508 fake_crx1->NotifyCrxInstallComplete(false);
1510 EXPECT_TRUE(updater.crx_install_is_running_);
1513 EXPECT_EQ(id2, service.extension_id());
1514 EXPECT_FALSE(service.install_path().empty());
1516 // Make sure the correct crx contents were passed for the update call.
1517 EXPECT_EQ(extension_file_path2, service.install_path());
1519 if (updates_start_running) {
1520 EXPECT_TRUE(updater.crx_install_is_running_);
1521 fake_crx2->NotifyCrxInstallComplete(false);
1523 EXPECT_FALSE(updater.crx_install_is_running_);
1526 void TestGalleryRequestsWithBrand(bool use_organic_brand_code) {
1527 google_brand::BrandForTesting brand_for_testing(
1528 use_organic_brand_code ? "GGLS" : "TEST");
1530 // We want to test a variety of combinations of expected ping conditions for
1531 // rollcall and active pings.
1532 int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
1534 for (size_t i = 0; i < arraysize(ping_cases); i++) {
1535 for (size_t j = 0; j < arraysize(ping_cases); j++) {
1536 for (size_t k = 0; k < 2; k++) {
1537 int rollcall_ping_days = ping_cases[i];
1538 int active_ping_days = ping_cases[j];
1539 // Skip cases where rollcall_ping_days == -1, but
1540 // active_ping_days > 0, because rollcall_ping_days == -1 means the
1541 // app was just installed and this is the first update check after
1543 if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
1544 active_ping_days > 0)
1547 bool active_bit = k > 0;
1548 TestGalleryRequests(rollcall_ping_days, active_ping_days, active_bit,
1549 !use_organic_brand_code);
1550 ASSERT_FALSE(HasFailure()) <<
1551 " rollcall_ping_days=" << ping_cases[i] <<
1552 " active_ping_days=" << ping_cases[j] <<
1553 " active_bit=" << active_bit;
1559 // Test requests to both a Google server and a non-google server. This allows
1560 // us to test various combinations of installed (ie roll call) and active
1561 // (ie app launch) ping scenarios. The invariant is that each type of ping
1562 // value should be present at most once per day, and can be calculated based
1563 // on the delta between now and the last ping time (or in the case of active
1564 // pings, that delta plus whether the app has been active).
1565 void TestGalleryRequests(int rollcall_ping_days,
1566 int active_ping_days,
1568 bool expect_brand_code) {
1569 net::TestURLFetcherFactory factory;
1571 // Set up 2 mock extensions, one with a google.com update url and one
1573 prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
1574 ServiceForManifestTests service(prefs_.get());
1576 GURL url1("http://clients2.google.com/service/update2/crx");
1577 GURL url2("http://www.somewebsite.com");
1578 service.CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
1579 Manifest::INTERNAL);
1580 service.CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
1581 Manifest::INTERNAL);
1582 EXPECT_EQ(2u, tmp.size());
1583 service.set_extensions(tmp, ExtensionList());
1585 ExtensionPrefs* prefs = service.extension_prefs();
1586 const std::string& id = tmp[0]->id();
1587 Time now = Time::Now();
1588 if (rollcall_ping_days == 0) {
1589 prefs->SetLastPingDay(id, now - TimeDelta::FromSeconds(15));
1590 } else if (rollcall_ping_days > 0) {
1591 Time last_ping_day = now -
1592 TimeDelta::FromDays(rollcall_ping_days) -
1593 TimeDelta::FromSeconds(15);
1594 prefs->SetLastPingDay(id, last_ping_day);
1597 // Store a value for the last day we sent an active ping.
1598 if (active_ping_days == 0) {
1599 prefs->SetLastActivePingDay(id, now - TimeDelta::FromSeconds(15));
1600 } else if (active_ping_days > 0) {
1601 Time last_active_ping_day = now -
1602 TimeDelta::FromDays(active_ping_days) -
1603 TimeDelta::FromSeconds(15);
1604 prefs->SetLastActivePingDay(id, last_active_ping_day);
1607 prefs->SetActiveBit(id, true);
1609 ExtensionUpdater updater(&service,
1610 service.extension_prefs(),
1611 service.pref_service(),
1613 kUpdateFrequencySecs,
1615 service.GetDownloaderFactory());
1616 ExtensionUpdater::CheckParams params;
1618 updater.CheckNow(params);
1619 content::RunAllBlockingPoolTasksUntilIdle();
1621 // Make the updater do manifest fetching, and note the urls it tries to
1623 std::vector<GURL> fetched_urls;
1624 net::TestURLFetcher* fetcher =
1625 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1626 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1627 fetched_urls.push_back(fetcher->GetOriginalURL());
1629 fetcher->set_url(fetched_urls[0]);
1630 fetcher->set_status(net::URLRequestStatus());
1631 fetcher->set_response_code(500);
1632 fetcher->SetResponseString(std::string());
1633 fetcher->delegate()->OnURLFetchComplete(fetcher);
1635 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1636 fetched_urls.push_back(fetcher->GetOriginalURL());
1638 // The urls could have been fetched in either order, so use the host to
1639 // tell them apart and note the query each used.
1640 std::string url1_query;
1641 std::string url2_query;
1642 if (fetched_urls[0].host() == url1.host()) {
1643 url1_query = fetched_urls[0].query();
1644 url2_query = fetched_urls[1].query();
1645 } else if (fetched_urls[0].host() == url2.host()) {
1646 url1_query = fetched_urls[1].query();
1647 url2_query = fetched_urls[0].query();
1652 // First make sure the non-google query had no ping parameter.
1653 std::string search_string = "ping%3D";
1654 EXPECT_TRUE(url2_query.find(search_string) == std::string::npos);
1656 // Now make sure the google query had the correct ping parameter.
1657 bool ping_expected = false;
1658 bool did_rollcall = false;
1659 if (rollcall_ping_days != 0) {
1660 search_string += "r%253D" + base::IntToString(rollcall_ping_days);
1661 did_rollcall = true;
1662 ping_expected = true;
1664 if (active_bit && active_ping_days != 0) {
1666 search_string += "%2526";
1667 search_string += "a%253D" + base::IntToString(active_ping_days);
1668 ping_expected = true;
1670 bool ping_found = url1_query.find(search_string) != std::string::npos;
1671 EXPECT_EQ(ping_expected, ping_found) << "query was: " << url1_query
1672 << " was looking for " << search_string;
1674 // Make sure the non-google query has no brand parameter.
1675 const std::string brand_string = "brand%3D";
1676 EXPECT_TRUE(url2_query.find(brand_string) == std::string::npos);
1678 #if defined(GOOGLE_CHROME_BUILD)
1679 // Make sure the google query has a brand parameter, but only if the
1680 // brand is non-organic.
1681 if (expect_brand_code) {
1682 EXPECT_TRUE(url1_query.find(brand_string) != std::string::npos);
1684 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1687 // Chromium builds never add the brand to the parameter, even for google
1689 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1695 // This makes sure that the extension updater properly stores the results
1696 // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
1697 // the first time we fetched the extension, or 2) We sent a ping value of
1698 // >= 1 day for the extension.
1699 void TestHandleManifestResults() {
1700 ServiceForManifestTests service(prefs_.get());
1701 GURL update_url("http://www.google.com/manifest");
1703 service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
1704 Manifest::INTERNAL);
1705 service.set_extensions(tmp, ExtensionList());
1707 ExtensionUpdater updater(&service,
1708 service.extension_prefs(),
1709 service.pref_service(),
1711 kUpdateFrequencySecs,
1713 service.GetDownloaderFactory());
1715 updater.EnsureDownloaderCreated();
1717 scoped_ptr<ManifestFetchData> fetch_data(
1718 CreateManifestFetchData(update_url));
1719 const Extension* extension = tmp[0].get();
1720 fetch_data->AddExtension(extension->id(),
1721 extension->VersionString(),
1723 kEmptyUpdateUrlData,
1726 UpdateManifest::Results results;
1727 results.daystart_elapsed_seconds = 750;
1729 updater.downloader_->HandleManifestResults(*fetch_data, &results);
1730 Time last_ping_day =
1731 service.extension_prefs()->LastPingDay(extension->id());
1732 EXPECT_FALSE(last_ping_day.is_null());
1733 int64 seconds_diff = (Time::Now() - last_ping_day).InSeconds();
1734 EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
1738 scoped_ptr<TestExtensionPrefs> prefs_;
1740 ManifestFetchData* CreateManifestFetchData(const GURL& update_url) {
1741 return new ManifestFetchData(update_url,
1744 OmahaQueryParams::Get(OmahaQueryParams::CRX),
1745 ManifestFetchData::PING);
1749 content::TestBrowserThreadBundle thread_bundle_;
1750 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
1752 #if defined OS_CHROMEOS
1753 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
1754 chromeos::ScopedTestCrosSettings test_cros_settings_;
1755 chromeos::ScopedTestUserManager test_user_manager_;
1759 // Because we test some private methods of ExtensionUpdater, it's easier for the
1760 // actual test code to live in ExtenionUpdaterTest methods instead of TEST_F
1761 // subclasses where friendship with ExtenionUpdater is not inherited.
1763 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
1764 TestExtensionUpdateCheckRequests(false);
1767 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
1768 TestExtensionUpdateCheckRequests(true);
1771 TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
1772 TestUpdateUrlDataEmpty();
1773 TestUpdateUrlDataSimple();
1774 TestUpdateUrlDataCompound();
1775 TestUpdateUrlDataFromGallery(
1776 extension_urls::GetWebstoreUpdateUrl().spec());
1779 TEST_F(ExtensionUpdaterTest, TestInstallSource) {
1780 TestInstallSource();
1783 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
1784 TestDetermineUpdates();
1787 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
1788 TestDetermineUpdatesPending();
1791 TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
1792 TestMultipleManifestDownloading();
1795 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
1796 TestSingleExtensionDownloading(false, false, false);
1799 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
1800 TestSingleExtensionDownloading(true, false, false);
1803 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
1804 TestSingleExtensionDownloading(false, true, false);
1807 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
1808 TestSingleExtensionDownloading(true, true, false);
1811 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailure) {
1812 TestSingleExtensionDownloading(false, false, true);
1815 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailureWithRetry) {
1816 TestSingleExtensionDownloading(false, true, true);
1819 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailurePending) {
1820 TestSingleExtensionDownloading(true, false, true);
1823 TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieAuth) {
1824 TestProtectedDownload(
1825 "https://chrome.google.com/webstore/download",
1826 false, false, // No OAuth2 support
1830 TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieFailure) {
1831 TestProtectedDownload(
1832 "https://chrome.google.com/webstore/download",
1833 false, false, // No OAuth2 support
1834 0, -1); // max_authuser=-1 simulates no valid authuser value.
1837 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser1) {
1838 TestProtectedDownload("https://google.com", false, false, 1, 1);
1841 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser2) {
1842 TestProtectedDownload("https://google.com", false, false, 2, 2);
1845 TEST_F(ExtensionUpdaterTest, ProtectedDownloadAuthUserExhaustionFailure) {
1846 TestProtectedDownload("https://google.com", false, false, 2, 5);
1849 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Token) {
1850 TestProtectedDownload(
1851 "https://google.com",
1856 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Failure) {
1857 TestProtectedDownload(
1858 "https://google.com",
1863 TEST_F(ExtensionUpdaterTest, ProtectedDownloadNoOAuth2WithNonGoogleDomain) {
1864 TestProtectedDownload(
1865 "https://not-google.com",
1870 TEST_F(ExtensionUpdaterTest, ProtectedDownloadFailWithoutHTTPS) {
1871 TestProtectedDownload(
1872 "http://google.com",
1877 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
1878 TestMultipleExtensionDownloading(false);
1880 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
1881 TestMultipleExtensionDownloading(true);
1884 TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
1885 TestManifestRetryDownloading();
1888 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) {
1889 TestGalleryRequestsWithBrand(true);
1892 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) {
1893 TestGalleryRequestsWithBrand(false);
1896 TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
1897 TestHandleManifestResults();
1900 TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
1901 net::TestURLFetcherFactory factory;
1902 ServiceForManifestTests service(prefs_.get());
1903 ExtensionUpdater updater(&service,
1904 service.extension_prefs(),
1905 service.pref_service(),
1907 kUpdateFrequencySecs,
1909 service.GetDownloaderFactory());
1910 MockExtensionDownloaderDelegate delegate;
1911 service.OverrideDownloaderDelegate(&delegate);
1913 // Non-internal non-external extensions should be rejected.
1914 ExtensionList extensions;
1915 service.CreateTestExtensions(1, 1, &extensions, NULL,
1916 Manifest::INVALID_LOCATION);
1917 service.CreateTestExtensions(2, 1, &extensions, NULL, Manifest::INTERNAL);
1918 ASSERT_EQ(2u, extensions.size());
1919 const std::string& updateable_id = extensions[1]->id();
1921 // These expectations fail if the delegate's methods are invoked for the
1922 // first extension, which has a non-matching id.
1923 EXPECT_CALL(delegate,
1924 GetUpdateUrlData(updateable_id)).WillOnce(Return(""));
1925 EXPECT_CALL(delegate, GetPingDataForExtension(updateable_id, _));
1927 service.set_extensions(extensions, ExtensionList());
1928 ExtensionUpdater::CheckParams params;
1930 updater.CheckNow(params);
1931 content::RunAllBlockingPoolTasksUntilIdle();
1934 TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
1935 net::TestURLFetcherFactory factory;
1936 ServiceForManifestTests service(prefs_.get());
1937 ExtensionUpdater updater(&service,
1938 service.extension_prefs(),
1939 service.pref_service(),
1941 kUpdateFrequencySecs,
1943 service.GetDownloaderFactory());
1944 MockExtensionDownloaderDelegate delegate;
1945 service.OverrideDownloaderDelegate(&delegate);
1947 // Non-internal non-external extensions should be rejected.
1948 ExtensionList enabled_extensions;
1949 ExtensionList disabled_extensions;
1950 service.CreateTestExtensions(1, 1, &enabled_extensions, NULL,
1951 Manifest::INTERNAL);
1952 service.CreateTestExtensions(2, 1, &disabled_extensions, NULL,
1953 Manifest::INTERNAL);
1954 ASSERT_EQ(1u, enabled_extensions.size());
1955 ASSERT_EQ(1u, disabled_extensions.size());
1956 const std::string& enabled_id = enabled_extensions[0]->id();
1957 const std::string& disabled_id = disabled_extensions[0]->id();
1959 // We expect that both enabled and disabled extensions are auto-updated.
1960 EXPECT_CALL(delegate, GetUpdateUrlData(enabled_id)).WillOnce(Return(""));
1961 EXPECT_CALL(delegate, GetPingDataForExtension(enabled_id, _));
1962 EXPECT_CALL(delegate,
1963 GetUpdateUrlData(disabled_id)).WillOnce(Return(""));
1964 EXPECT_CALL(delegate, GetPingDataForExtension(disabled_id, _));
1966 service.set_extensions(enabled_extensions, disabled_extensions);
1967 ExtensionUpdater::CheckParams params;
1969 updater.CheckNow(params);
1970 content::RunAllBlockingPoolTasksUntilIdle();
1973 TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
1974 net::TestURLFetcherFactory factory;
1975 MockService service(prefs_.get());
1976 MockExtensionDownloaderDelegate delegate;
1977 scoped_ptr<ExtensionDownloader> downloader(
1978 new ExtensionDownloader(&delegate, service.request_context()));
1979 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
1981 // First, verify that adding valid extensions does invoke the callbacks on
1983 std::string id = crx_file::id_util::GenerateId("foo");
1984 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
1986 downloader->AddPendingExtension(id, GURL("http://example.com/update"),
1988 downloader->StartAllPending(NULL);
1989 Mock::VerifyAndClearExpectations(&delegate);
1990 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1992 // Extensions with invalid update URLs should be rejected.
1993 id = crx_file::id_util::GenerateId("foo2");
1995 downloader->AddPendingExtension(id, GURL("http:google.com:foo"), 0));
1996 downloader->StartAllPending(NULL);
1997 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1999 // Extensions with empty IDs should be rejected.
2000 EXPECT_FALSE(downloader->AddPendingExtension(std::string(), GURL(), 0));
2001 downloader->StartAllPending(NULL);
2002 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2004 // TODO(akalin): Test that extensions with empty update URLs
2005 // converted from user scripts are rejected.
2007 // Reset the ExtensionDownloader so that it drops the current fetcher.
2009 new ExtensionDownloader(&delegate, service.request_context()));
2010 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
2012 // Extensions with empty update URLs should have a default one
2014 id = crx_file::id_util::GenerateId("foo3");
2015 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
2016 EXPECT_TRUE(downloader->AddPendingExtension(id, GURL(), 0));
2017 downloader->StartAllPending(NULL);
2018 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2020 net::TestURLFetcher* fetcher =
2021 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
2022 ASSERT_TRUE(fetcher);
2023 EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
2026 TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
2027 net::TestURLFetcherFactory factory;
2028 MockService service(prefs_.get());
2029 MockExtensionDownloaderDelegate delegate;
2030 ExtensionDownloader downloader(&delegate, service.request_context());
2032 StartUpdateCheck(&downloader, CreateManifestFetchData(GURL()));
2033 // This should delete the newly-created ManifestFetchData.
2034 StartUpdateCheck(&downloader, CreateManifestFetchData(GURL()));
2035 // This should add into |manifests_pending_|.
2036 StartUpdateCheck(&downloader,
2037 CreateManifestFetchData(GURL("http://www.google.com")));
2038 // The dtor of |downloader| should delete the pending fetchers.
2041 TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
2042 ServiceForManifestTests service(prefs_.get());
2043 net::TestURLFetcherFactory factory;
2044 ExtensionUpdater updater(&service,
2045 service.extension_prefs(),
2046 service.pref_service(),
2048 kUpdateFrequencySecs,
2050 service.GetDownloaderFactory());
2051 EXPECT_FALSE(updater.WillCheckSoon());
2053 EXPECT_FALSE(updater.WillCheckSoon());
2054 updater.CheckSoon();
2055 EXPECT_TRUE(updater.WillCheckSoon());
2056 updater.CheckSoon();
2057 EXPECT_TRUE(updater.WillCheckSoon());
2059 EXPECT_FALSE(updater.WillCheckSoon());
2060 updater.CheckSoon();
2061 EXPECT_TRUE(updater.WillCheckSoon());
2063 EXPECT_FALSE(updater.WillCheckSoon());
2066 // TODO(asargent) - (http://crbug.com/12780) add tests for:
2067 // -prodversionmin (shouldn't update if browser version too old)
2068 // -manifests & updates arriving out of order / interleaved
2069 // -malformed update url (empty, file://, has query, has a # fragment, etc.)
2070 // -An extension gets uninstalled while updates are in progress (so it doesn't
2071 // "come back from the dead")
2072 // -An extension gets manually updated to v3 while we're downloading v2 (ie
2073 // you don't get downgraded accidentally)
2074 // -An update manifest mentions multiple updates
2076 } // namespace extensions