MacViews: Get c/b/ui/views/tabs to build on Mac
[chromium-blink-merge.git] / chrome / browser / extensions / updater / extension_updater_unittest.cc
blob04b4d973ae2541a7c52b5139a7779fb2ea5a39f2
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/chrome_extension_downloader_factory.h"
34 #include "chrome/browser/extensions/updater/extension_updater.h"
35 #include "chrome/browser/google/google_brand.h"
36 #include "chrome/browser/prefs/pref_service_syncable.h"
37 #include "chrome/common/pref_names.h"
38 #include "chrome/test/base/testing_profile.h"
39 #include "components/crx_file/id_util.h"
40 #include "components/omaha_query_params/omaha_query_params.h"
41 #include "content/public/browser/notification_details.h"
42 #include "content/public/browser/notification_observer.h"
43 #include "content/public/browser/notification_registrar.h"
44 #include "content/public/browser/notification_service.h"
45 #include "content/public/browser/notification_source.h"
46 #include "content/public/test/test_browser_thread_bundle.h"
47 #include "content/public/test/test_utils.h"
48 #include "extensions/browser/extension_prefs.h"
49 #include "extensions/browser/extension_registry.h"
50 #include "extensions/browser/extension_system.h"
51 #include "extensions/browser/updater/extension_downloader.h"
52 #include "extensions/browser/updater/extension_downloader_delegate.h"
53 #include "extensions/browser/updater/manifest_fetch_data.h"
54 #include "extensions/browser/updater/request_queue_impl.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"
75 #endif
77 using base::Time;
78 using base::TimeDelta;
79 using content::BrowserThread;
80 using omaha_query_params::OmahaQueryParams;
81 using testing::DoAll;
82 using testing::Invoke;
83 using testing::InvokeWithoutArgs;
84 using testing::Mock;
85 using testing::Return;
86 using testing::SetArgPointee;
87 using testing::_;
89 namespace extensions {
91 typedef ExtensionDownloaderDelegate::Error Error;
92 typedef ExtensionDownloaderDelegate::PingResult PingResult;
94 namespace {
96 const net::BackoffEntry::Policy kNoBackoffPolicy = {
97 // Number of initial errors (in sequence) to ignore before applying
98 // exponential back-off rules.
99 1000,
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.
119 false,
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,
139 ManifestFetchData::kNeverPinged,
140 true,
143 class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate {
144 public:
145 MOCK_METHOD4(OnExtensionDownloadFailed, void(const std::string&,
146 Error,
147 const PingResult&,
148 const std::set<int>&));
149 MOCK_METHOD7(OnExtensionDownloadFinished, void(const std::string&,
150 const base::FilePath&,
151 bool,
152 const GURL&,
153 const std::string&,
154 const PingResult&,
155 const std::set<int>&));
156 MOCK_METHOD2(GetPingDataForExtension,
157 bool(const std::string&, ManifestFetchData::PingData*));
158 MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&));
159 MOCK_METHOD1(IsExtensionPending, bool(const std::string&));
160 MOCK_METHOD2(GetExtensionExistingVersion,
161 bool(const std::string&, std::string*));
163 void Wait() {
164 scoped_refptr<content::MessageLoopRunner> runner =
165 new content::MessageLoopRunner;
166 quit_closure_ = runner->QuitClosure();
167 runner->Run();
168 quit_closure_.Reset();
171 void Quit() {
172 quit_closure_.Run();
175 void DelegateTo(ExtensionDownloaderDelegate* delegate) {
176 ON_CALL(*this, OnExtensionDownloadFailed(_, _, _, _))
177 .WillByDefault(Invoke(delegate,
178 &ExtensionDownloaderDelegate::OnExtensionDownloadFailed));
179 ON_CALL(*this, OnExtensionDownloadFinished(_, _, _, _, _, _, _))
180 .WillByDefault(Invoke(delegate,
181 &ExtensionDownloaderDelegate::OnExtensionDownloadFinished));
182 ON_CALL(*this, GetPingDataForExtension(_, _))
183 .WillByDefault(Invoke(delegate,
184 &ExtensionDownloaderDelegate::GetPingDataForExtension));
185 ON_CALL(*this, GetUpdateUrlData(_))
186 .WillByDefault(Invoke(delegate,
187 &ExtensionDownloaderDelegate::GetUpdateUrlData));
188 ON_CALL(*this, IsExtensionPending(_))
189 .WillByDefault(Invoke(delegate,
190 &ExtensionDownloaderDelegate::IsExtensionPending));
191 ON_CALL(*this, GetExtensionExistingVersion(_, _))
192 .WillByDefault(Invoke(delegate,
193 &ExtensionDownloaderDelegate::GetExtensionExistingVersion));
196 private:
197 base::Closure quit_closure_;
200 const int kNotificationsObserved[] = {
201 extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED,
202 extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
205 // A class that observes the notifications sent by the ExtensionUpdater and
206 // the ExtensionDownloader.
207 class NotificationsObserver : public content::NotificationObserver {
208 public:
209 NotificationsObserver() {
210 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
211 count_[i] = 0;
212 registrar_.Add(this,
213 kNotificationsObserved[i],
214 content::NotificationService::AllSources());
218 ~NotificationsObserver() override {
219 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
220 registrar_.Remove(this,
221 kNotificationsObserved[i],
222 content::NotificationService::AllSources());
226 size_t StartedCount() { return count_[0]; }
227 size_t UpdatedCount() { return count_[1]; }
229 bool Updated(const std::string& id) {
230 return updated_.find(id) != updated_.end();
233 void Wait() {
234 scoped_refptr<content::MessageLoopRunner> runner =
235 new content::MessageLoopRunner;
236 quit_closure_ = runner->QuitClosure();
237 runner->Run();
238 quit_closure_.Reset();
241 private:
242 void Observe(int type,
243 const content::NotificationSource& source,
244 const content::NotificationDetails& details) override {
245 if (!quit_closure_.is_null())
246 quit_closure_.Run();
247 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
248 if (kNotificationsObserved[i] == type) {
249 count_[i]++;
250 if (type == extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND) {
251 updated_.insert(
252 content::Details<UpdateDetails>(details)->id);
254 return;
257 NOTREACHED();
260 content::NotificationRegistrar registrar_;
261 size_t count_[arraysize(kNotificationsObserved)];
262 std::set<std::string> updated_;
263 base::Closure quit_closure_;
265 DISALLOW_COPY_AND_ASSIGN(NotificationsObserver);
268 // Extracts the integer value of the |authuser| query parameter. Returns 0 if
269 // the parameter is not set.
270 int GetAuthUserQueryValue(const GURL& url) {
271 std::string query_string = url.query();
272 url::Component query(0, query_string.length());
273 url::Component key, value;
274 while (
275 url::ExtractQueryKeyValue(query_string.c_str(), &query, &key, &value)) {
276 std::string key_string = query_string.substr(key.begin, key.len);
277 if (key_string == kAuthUserQueryKey) {
278 int user_index = 0;
279 base::StringToInt(query_string.substr(value.begin, value.len),
280 &user_index);
281 return user_index;
284 return 0;
287 } // namespace
289 // Base class for further specialized test classes.
290 class MockService : public TestExtensionService {
291 public:
292 explicit MockService(TestExtensionPrefs* prefs)
293 : prefs_(prefs),
294 pending_extension_manager_(&profile_),
295 downloader_delegate_override_(NULL),
296 enable_metrics_(false) {}
298 ~MockService() override {}
300 PendingExtensionManager* pending_extension_manager() override {
301 ADD_FAILURE() << "Subclass should override this if it will "
302 << "be accessed by a test.";
303 return &pending_extension_manager_;
306 Profile* profile() { return &profile_; }
308 net::URLRequestContextGetter* request_context() {
309 return profile_.GetRequestContext();
312 ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
314 PrefService* pref_service() { return prefs_->pref_service(); }
316 FakeOAuth2TokenService* fake_token_service() {
317 return fake_token_service_.get();
320 // Controls whether metrics (enable/disabled state, etc.) are sent in the
321 // autoupdate ping requests.
322 void set_enable_metrics(bool enable) { enable_metrics_ = enable; }
324 // Creates test extensions and inserts them into list. The name and
325 // version are all based on their index. If |update_url| is non-null, it
326 // will be used as the update_url for each extension.
327 // The |id| is used to distinguish extension names and make sure that
328 // no two extensions share the same name.
329 void CreateTestExtensions(int id, int count, ExtensionList *list,
330 const std::string* update_url,
331 Manifest::Location location) {
332 for (int i = 1; i <= count; i++) {
333 base::DictionaryValue manifest;
334 manifest.SetString(manifest_keys::kVersion,
335 base::StringPrintf("%d.0.0.0", i));
336 manifest.SetString(manifest_keys::kName,
337 base::StringPrintf("Extension %d.%d", id, i));
338 if (update_url)
339 manifest.SetString(manifest_keys::kUpdateURL, *update_url);
340 scoped_refptr<Extension> e =
341 prefs_->AddExtensionWithManifest(manifest, location);
342 ASSERT_TRUE(e.get() != NULL);
343 list->push_back(e);
347 ExtensionDownloader::Factory GetDownloaderFactory() {
348 return base::Bind(&MockService::CreateExtensionDownloader,
349 base::Unretained(this));
352 ExtensionDownloader::Factory GetAuthenticatedDownloaderFactory() {
353 return base::Bind(&MockService::CreateExtensionDownloaderWithIdentity,
354 base::Unretained(this));
357 void OverrideDownloaderDelegate(ExtensionDownloaderDelegate* delegate) {
358 downloader_delegate_override_ = delegate;
361 protected:
362 TestExtensionPrefs* const prefs_;
363 TestingProfile profile_;
364 PendingExtensionManager pending_extension_manager_;
366 private:
367 scoped_ptr<ExtensionDownloader> CreateExtensionDownloader(
368 ExtensionDownloaderDelegate* delegate) {
369 scoped_ptr<ExtensionDownloader> downloader =
370 ChromeExtensionDownloaderFactory::CreateForRequestContext(
371 request_context(),
372 downloader_delegate_override_ ? downloader_delegate_override_
373 : delegate);
374 if (enable_metrics_)
375 downloader->set_enable_extra_update_metrics(true);
376 return downloader.Pass();
379 scoped_ptr<ExtensionDownloader> CreateExtensionDownloaderWithIdentity(
380 ExtensionDownloaderDelegate* delegate) {
381 scoped_ptr<FakeIdentityProvider> fake_identity_provider;
382 fake_token_service_.reset(new FakeOAuth2TokenService());
383 fake_identity_provider.reset(new FakeIdentityProvider(
384 fake_token_service_.get()));
385 fake_identity_provider->LogIn(kFakeAccountId);
386 fake_token_service_->AddAccount(kFakeAccountId);
388 scoped_ptr<ExtensionDownloader> downloader(
389 CreateExtensionDownloader(delegate));
390 downloader->SetWebstoreIdentityProvider(fake_identity_provider.Pass());
391 return downloader.Pass();
394 scoped_ptr<FakeOAuth2TokenService> fake_token_service_;
396 ExtensionDownloaderDelegate* downloader_delegate_override_;
398 bool enable_metrics_;
400 DISALLOW_COPY_AND_ASSIGN(MockService);
404 bool ShouldInstallExtensionsOnly(const Extension* extension) {
405 return extension->GetType() == Manifest::TYPE_EXTENSION;
408 bool ShouldInstallThemesOnly(const Extension* extension) {
409 return extension->is_theme();
412 bool ShouldAlwaysInstall(const Extension* extension) {
413 return true;
416 // Loads some pending extension records into a pending extension manager.
417 void SetupPendingExtensionManagerForTest(
418 int count,
419 const GURL& update_url,
420 PendingExtensionManager* pending_extension_manager) {
421 for (int i = 1; i <= count; ++i) {
422 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
423 (i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
424 const bool kIsFromSync = true;
425 const bool kMarkAcknowledged = false;
426 const bool kRemoteInstall = false;
427 std::string id =
428 crx_file::id_util::GenerateId(base::StringPrintf("extension%i", i));
430 pending_extension_manager->AddForTesting(
431 PendingExtensionInfo(id,
432 std::string(),
433 update_url,
434 Version(),
435 should_allow_install,
436 kIsFromSync,
437 Manifest::INTERNAL,
438 Extension::NO_FLAGS,
439 kMarkAcknowledged,
440 kRemoteInstall));
444 class ServiceForManifestTests : public MockService {
445 public:
446 explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
447 : MockService(prefs),
448 registry_(ExtensionRegistry::Get(profile())) {
451 ~ServiceForManifestTests() override {}
453 const Extension* GetExtensionById(const std::string& id,
454 bool include_disabled) const override {
455 const Extension* result = registry_->enabled_extensions().GetByID(id);
456 if (result || !include_disabled)
457 return result;
458 return registry_->disabled_extensions().GetByID(id);
461 const ExtensionSet* extensions() const override {
462 return &registry_->enabled_extensions();
465 PendingExtensionManager* pending_extension_manager() override {
466 return &pending_extension_manager_;
469 const Extension* GetPendingExtensionUpdate(
470 const std::string& id) const override {
471 return NULL;
474 bool IsExtensionEnabled(const std::string& id) const override {
475 return !registry_->disabled_extensions().Contains(id);
478 void set_extensions(ExtensionList extensions,
479 ExtensionList disabled_extensions) {
480 registry_->ClearAll();
481 for (ExtensionList::const_iterator it = extensions.begin();
482 it != extensions.end(); ++it) {
483 registry_->AddEnabled(*it);
485 for (ExtensionList::const_iterator it = disabled_extensions.begin();
486 it != disabled_extensions.end(); ++it) {
487 registry_->AddDisabled(*it);
491 private:
492 ExtensionRegistry* registry_;
495 class ServiceForDownloadTests : public MockService {
496 public:
497 explicit ServiceForDownloadTests(TestExtensionPrefs* prefs)
498 : MockService(prefs) {
501 // Add a fake crx installer to be returned by a call to UpdateExtension()
502 // with a specific ID. Caller keeps ownership of |crx_installer|.
503 void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) {
504 fake_crx_installers_[id] = crx_installer;
507 bool UpdateExtension(const std::string& id,
508 const base::FilePath& extension_path,
509 bool file_ownership_passed,
510 CrxInstaller** out_crx_installer) override {
511 extension_id_ = id;
512 install_path_ = extension_path;
514 if (ContainsKey(fake_crx_installers_, id)) {
515 *out_crx_installer = fake_crx_installers_[id];
516 return true;
519 return false;
522 PendingExtensionManager* pending_extension_manager() override {
523 return &pending_extension_manager_;
526 const Extension* GetExtensionById(const std::string& id,
527 bool) const override {
528 last_inquired_extension_id_ = id;
529 return NULL;
532 const std::string& extension_id() const { return extension_id_; }
533 const base::FilePath& install_path() const { return install_path_; }
535 private:
536 // Hold the set of ids that UpdateExtension() should fake success on.
537 // UpdateExtension(id, ...) will return true iff fake_crx_installers_
538 // contains key |id|. |out_install_notification_source| will be set
539 // to Source<CrxInstaller(fake_crx_installers_[i]).
540 std::map<std::string, CrxInstaller*> fake_crx_installers_;
542 std::string extension_id_;
543 base::FilePath install_path_;
544 GURL download_url_;
546 // The last extension ID that GetExtensionById was called with.
547 // Mutable because the method that sets it (GetExtensionById) is const
548 // in the actual extension service, but must record the last extension
549 // ID in this test class.
550 mutable std::string last_inquired_extension_id_;
553 static const int kUpdateFrequencySecs = 15;
555 // Takes a string with KEY=VALUE parameters separated by '&' in |params| and
556 // puts the key/value pairs into |result|. For keys with no value, the empty
557 // string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
558 // "foo", and "c" to "".
559 static void ExtractParameters(const std::string& params,
560 std::map<std::string, std::string>* result) {
561 std::vector<std::string> pairs;
562 base::SplitString(params, '&', &pairs);
563 for (size_t i = 0; i < pairs.size(); i++) {
564 std::vector<std::string> key_val;
565 base::SplitString(pairs[i], '=', &key_val);
566 if (!key_val.empty()) {
567 std::string key = key_val[0];
568 EXPECT_TRUE(result->find(key) == result->end());
569 (*result)[key] = (key_val.size() == 2) ? key_val[1] : std::string();
570 } else {
571 NOTREACHED();
576 // Helper function to extract the ping data param values for each extension in
577 // a manifest fetch url, returned in a map keyed by extension id.
578 // E.g. for "x=id%3Dabcdef%26ping%3Ddr%253D1%2526dr%253D1024" we'd return
579 // {"abcdef": {"dr": set("1", "1024")}}
580 typedef std::map<std::string, std::set<std::string>> ParamsMap;
581 static std::map<std::string, ParamsMap> GetPingDataFromURL(
582 const GURL& manifest_url) {
583 std::map<std::string, ParamsMap> result;
585 base::StringPairs toplevel_params;
586 base::SplitStringIntoKeyValuePairs(
587 manifest_url.query(), '=', '&', &toplevel_params);
588 for (const auto& param : toplevel_params) {
589 if (param.first != "x")
590 continue;
592 // We've found "x=<something>", now unescape <something> and look for
593 // the "id=<id>&ping=<ping_value>" parameters within.
594 std::string unescaped = net::UnescapeURLComponent(
595 param.second, net::UnescapeRule::URL_SPECIAL_CHARS);
596 base::StringPairs extension_params;
597 base::SplitStringIntoKeyValuePairs(unescaped, '=', '&', &extension_params);
598 std::multimap<std::string, std::string> param_map;
599 param_map.insert(extension_params.begin(), extension_params.end());
600 if (ContainsKey(param_map, "id") && ContainsKey(param_map, "ping")) {
601 std::string id = param_map.find("id")->second;
602 result[id] = ParamsMap();
604 // Pull the key=value pairs out of the ping parameter for this id and
605 // put into the result.
606 std::string ping = net::UnescapeURLComponent(
607 param_map.find("ping")->second, net::UnescapeRule::URL_SPECIAL_CHARS);
608 base::StringPairs ping_params;
609 base::SplitStringIntoKeyValuePairs(ping, '=', '&', &ping_params);
610 for (const auto& ping_param : ping_params) {
611 if (!ContainsKey(result[id], ping_param.first))
612 result[id][ping_param.first] = std::set<std::string>();
613 result[id][ping_param.first].insert(ping_param.second);
617 return result;
620 static void VerifyQueryAndExtractParameters(
621 const std::string& query,
622 std::map<std::string, std::string>* result) {
623 std::map<std::string, std::string> params;
624 ExtractParameters(query, &params);
626 std::string omaha_params = OmahaQueryParams::Get(OmahaQueryParams::CRX);
627 std::map<std::string, std::string> expected;
628 ExtractParameters(omaha_params, &expected);
630 for (std::map<std::string, std::string>::iterator it = expected.begin();
631 it != expected.end(); ++it) {
632 EXPECT_EQ(it->second, params[it->first]);
635 EXPECT_EQ(1U, params.count("x"));
636 std::string decoded = net::UnescapeURLComponent(
637 params["x"], net::UnescapeRule::URL_SPECIAL_CHARS);
638 ExtractParameters(decoded, result);
641 // All of our tests that need to use private APIs of ExtensionUpdater live
642 // inside this class (which is a friend to ExtensionUpdater).
643 class ExtensionUpdaterTest : public testing::Test {
644 public:
645 ExtensionUpdaterTest()
646 : thread_bundle_(
647 content::TestBrowserThreadBundle::IO_MAINLOOP) {
650 virtual void SetUp() override {
651 prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
654 virtual void TearDown() override {
655 // Some tests create URLRequestContextGetters, whose destruction must run
656 // on the IO thread. Make sure the IO loop spins before shutdown so that
657 // those objects are released.
658 RunUntilIdle();
659 prefs_.reset();
662 void RunUntilIdle() {
663 prefs_->pref_service()->CommitPendingWrite();
664 base::RunLoop().RunUntilIdle();
667 void SimulateTimerFired(ExtensionUpdater* updater) {
668 EXPECT_TRUE(updater->timer_.IsRunning());
669 updater->timer_.Stop();
670 updater->TimerFired();
671 content::RunAllBlockingPoolTasksUntilIdle();
674 // Adds a Result with the given data to results.
675 void AddParseResult(const std::string& id,
676 const std::string& version,
677 const std::string& url,
678 UpdateManifest::Results* results) {
679 UpdateManifest::Result result;
680 result.extension_id = id;
681 result.version = version;
682 result.crx_url = GURL(url);
683 results->list.push_back(result);
686 void StartUpdateCheck(ExtensionDownloader* downloader,
687 ManifestFetchData* fetch_data) {
688 downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data));
691 size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
692 return downloader->manifests_queue_.size() +
693 (downloader->manifest_fetcher_.get() ? 1 : 0);
696 void TestExtensionUpdateCheckRequests(bool pending) {
697 // Create an extension with an update_url.
698 ServiceForManifestTests service(prefs_.get());
699 std::string update_url("http://foo.com/bar");
700 ExtensionList extensions;
701 NotificationsObserver observer;
702 PendingExtensionManager* pending_extension_manager =
703 service.pending_extension_manager();
704 if (pending) {
705 SetupPendingExtensionManagerForTest(1, GURL(update_url),
706 pending_extension_manager);
707 } else {
708 service.CreateTestExtensions(1, 1, &extensions, &update_url,
709 Manifest::INTERNAL);
710 service.set_extensions(extensions, ExtensionList());
713 // Set up and start the updater.
714 net::TestURLFetcherFactory factory;
715 ExtensionUpdater updater(&service,
716 service.extension_prefs(),
717 service.pref_service(),
718 service.profile(),
719 60 * 60 * 24,
720 NULL,
721 service.GetDownloaderFactory());
722 updater.Start();
724 // Tell the update that it's time to do update checks.
725 EXPECT_EQ(0u, observer.StartedCount());
726 SimulateTimerFired(&updater);
727 EXPECT_EQ(1u, observer.StartedCount());
729 // Get the url our mock fetcher was asked to fetch.
730 net::TestURLFetcher* fetcher =
731 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
732 const GURL& url = fetcher->GetOriginalURL();
733 EXPECT_FALSE(url.is_empty());
734 EXPECT_TRUE(url.is_valid());
735 EXPECT_TRUE(url.SchemeIs("http"));
736 EXPECT_EQ("foo.com", url.host());
737 EXPECT_EQ("/bar", url.path());
739 // Validate the extension request parameters in the query. It should
740 // look something like "x=id%3D<id>%26v%3D<version>%26uc".
741 EXPECT_TRUE(url.has_query());
742 std::map<std::string, std::string> params;
743 VerifyQueryAndExtractParameters(url.query(), &params);
744 if (pending) {
745 EXPECT_TRUE(pending_extension_manager->IsIdPending(params["id"]));
746 EXPECT_EQ("0.0.0.0", params["v"]);
747 } else {
748 EXPECT_EQ(extensions[0]->id(), params["id"]);
749 EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
751 EXPECT_EQ("", params["uc"]);
754 void TestUpdateUrlDataEmpty() {
755 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
756 const std::string version = "1.0";
758 // Make sure that an empty update URL data string does not cause a ap=
759 // option to appear in the x= parameter.
760 scoped_ptr<ManifestFetchData> fetch_data(
761 CreateManifestFetchData(GURL("http://localhost/foo")));
762 fetch_data->AddExtension(
763 id, version, &kNeverPingedData, std::string(), std::string(), false);
765 std::map<std::string, std::string> params;
766 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
767 EXPECT_EQ(id, params["id"]);
768 EXPECT_EQ(version, params["v"]);
769 EXPECT_EQ(0U, params.count("ap"));
772 void TestUpdateUrlDataSimple() {
773 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
774 const std::string version = "1.0";
776 // Make sure that an update URL data string causes an appropriate ap=
777 // option to appear in the x= parameter.
778 scoped_ptr<ManifestFetchData> fetch_data(
779 CreateManifestFetchData(GURL("http://localhost/foo")));
780 fetch_data->AddExtension(
781 id, version, &kNeverPingedData, "bar", std::string(), false);
782 std::map<std::string, std::string> params;
783 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
784 EXPECT_EQ(id, params["id"]);
785 EXPECT_EQ(version, params["v"]);
786 EXPECT_EQ("bar", params["ap"]);
789 void TestUpdateUrlDataCompound() {
790 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
791 const std::string version = "1.0";
793 // Make sure that an update URL data string causes an appropriate ap=
794 // option to appear in the x= parameter.
795 scoped_ptr<ManifestFetchData> fetch_data(
796 CreateManifestFetchData(GURL("http://localhost/foo")));
797 fetch_data->AddExtension(
798 id, version, &kNeverPingedData, "a=1&b=2&c", std::string(), false);
799 std::map<std::string, std::string> params;
800 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
801 EXPECT_EQ(id, params["id"]);
802 EXPECT_EQ(version, params["v"]);
803 EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]);
806 void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
807 net::TestURLFetcherFactory factory;
809 MockService service(prefs_.get());
810 MockExtensionDownloaderDelegate delegate;
811 ExtensionDownloader downloader(&delegate, service.request_context());
812 ExtensionList extensions;
813 std::string url(gallery_url);
815 service.CreateTestExtensions(1, 1, &extensions, &url, Manifest::INTERNAL);
817 const std::string& id = extensions[0]->id();
818 EXPECT_CALL(delegate, GetPingDataForExtension(id, _));
820 downloader.AddExtension(*extensions[0].get(), 0);
821 downloader.StartAllPending(NULL);
822 net::TestURLFetcher* fetcher =
823 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
824 ASSERT_TRUE(fetcher);
825 // Make sure that extensions that update from the gallery ignore any
826 // update URL data.
827 const std::string& update_url = fetcher->GetOriginalURL().spec();
828 std::string::size_type x = update_url.find("x=");
829 EXPECT_NE(std::string::npos, x);
830 std::string::size_type ap = update_url.find("ap%3D", x);
831 EXPECT_EQ(std::string::npos, ap);
834 void TestInstallSource() {
835 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
836 const std::string version = "1.0";
837 const std::string install_source = "instally";
839 // Make sure that an installsource= appears in the x= parameter.
840 scoped_ptr<ManifestFetchData> fetch_data(
841 CreateManifestFetchData(GURL("http://localhost/foo")));
842 fetch_data->AddExtension(id, version, &kNeverPingedData,
843 kEmptyUpdateUrlData, install_source, false);
844 std::map<std::string, std::string> params;
845 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
846 EXPECT_EQ(id, params["id"]);
847 EXPECT_EQ(version, params["v"]);
848 EXPECT_EQ(install_source, params["installsource"]);
851 void TestDetermineUpdates() {
852 TestingProfile profile;
853 MockExtensionDownloaderDelegate delegate;
854 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
856 // Check passing an empty list of parse results to DetermineUpdates
857 scoped_ptr<ManifestFetchData> fetch_data(
858 CreateManifestFetchData(GURL("http://localhost/foo")));
859 UpdateManifest::Results updates;
860 std::vector<int> updateable;
861 downloader.DetermineUpdates(*fetch_data, updates, &updateable);
862 EXPECT_TRUE(updateable.empty());
864 // Create two updates - expect that DetermineUpdates will return the first
865 // one (v1.0 installed, v1.1 available) but not the second one (both
866 // installed and available at v2.0).
867 const std::string id1 = crx_file::id_util::GenerateId("1");
868 const std::string id2 = crx_file::id_util::GenerateId("2");
869 fetch_data->AddExtension(
870 id1, "1.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string(),
871 false);
872 AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);
873 fetch_data->AddExtension(
874 id2, "2.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string(),
875 false);
876 AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);
878 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
879 EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
880 .WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"),
881 Return(true)));
882 EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
883 .WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"),
884 Return(true)));
886 downloader.DetermineUpdates(*fetch_data, updates, &updateable);
887 EXPECT_EQ(1u, updateable.size());
888 EXPECT_EQ(0, updateable[0]);
891 void TestDetermineUpdatesPending() {
892 // Create a set of test extensions
893 ServiceForManifestTests service(prefs_.get());
894 PendingExtensionManager* pending_extension_manager =
895 service.pending_extension_manager();
896 SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
898 TestingProfile profile;
899 MockExtensionDownloaderDelegate delegate;
900 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
902 scoped_ptr<ManifestFetchData> fetch_data(
903 CreateManifestFetchData(GURL("http://localhost/foo")));
904 UpdateManifest::Results updates;
906 std::list<std::string> ids_for_update_check;
907 pending_extension_manager->GetPendingIdsForUpdateCheck(
908 &ids_for_update_check);
910 std::list<std::string>::const_iterator it;
911 for (it = ids_for_update_check.begin();
912 it != ids_for_update_check.end(); ++it) {
913 fetch_data->AddExtension(*it,
914 "1.0.0.0",
915 &kNeverPingedData,
916 kEmptyUpdateUrlData,
917 std::string(),
918 false);
919 AddParseResult(*it, "1.1", "http://localhost/e1_1.1.crx", &updates);
922 // The delegate will tell the downloader that all the extensions are
923 // pending.
924 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(true));
926 std::vector<int> updateable;
927 downloader.DetermineUpdates(*fetch_data, updates, &updateable);
928 // All the apps should be updateable.
929 EXPECT_EQ(3u, updateable.size());
930 for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) {
931 EXPECT_EQ(static_cast<int>(i), updateable[i]);
935 void TestMultipleManifestDownloading() {
936 net::TestURLFetcherFactory factory;
937 factory.set_remove_fetcher_on_delete(true);
938 net::TestURLFetcher* fetcher = NULL;
939 MockService service(prefs_.get());
940 MockExtensionDownloaderDelegate delegate;
941 ExtensionDownloader downloader(&delegate, service.request_context());
942 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
944 GURL kUpdateUrl("http://localhost/manifest1");
946 scoped_ptr<ManifestFetchData> fetch1(CreateManifestFetchData(kUpdateUrl));
947 scoped_ptr<ManifestFetchData> fetch2(CreateManifestFetchData(kUpdateUrl));
948 scoped_ptr<ManifestFetchData> fetch3(CreateManifestFetchData(kUpdateUrl));
949 scoped_ptr<ManifestFetchData> fetch4(CreateManifestFetchData(kUpdateUrl));
950 ManifestFetchData::PingData zeroDays(0, 0, true, 0);
951 fetch1->AddExtension(
952 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
953 fetch2->AddExtension(
954 "2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
955 fetch3->AddExtension(
956 "3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
957 fetch4->AddExtension(
958 "4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
960 // This will start the first fetcher and queue the others. The next in queue
961 // is started as each fetcher receives its response. Note that the fetchers
962 // don't necessarily run in the order that they are started from here.
963 GURL fetch1_url = fetch1->full_url();
964 GURL fetch2_url = fetch2->full_url();
965 GURL fetch3_url = fetch3->full_url();
966 GURL fetch4_url = fetch4->full_url();
967 downloader.StartUpdateCheck(fetch1.Pass());
968 downloader.StartUpdateCheck(fetch2.Pass());
969 downloader.StartUpdateCheck(fetch3.Pass());
970 downloader.StartUpdateCheck(fetch4.Pass());
971 RunUntilIdle();
973 for (int i = 0; i < 4; ++i) {
974 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
975 ASSERT_TRUE(fetcher);
976 ASSERT_TRUE(fetcher->delegate());
977 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
978 EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
980 if (fetcher->GetOriginalURL() == fetch1_url) {
981 // The first fetch will fail.
982 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
983 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
984 fetcher->set_url(kUpdateUrl);
985 fetcher->set_status(net::URLRequestStatus());
986 fetcher->set_response_code(400);
987 fetcher->delegate()->OnURLFetchComplete(fetcher);
988 RunUntilIdle();
989 Mock::VerifyAndClearExpectations(&delegate);
990 fetch1_url = GURL();
991 } else if (fetcher->GetOriginalURL() == fetch2_url) {
992 // The second fetch gets invalid data.
993 const std::string kInvalidXml = "invalid xml";
994 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
995 "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _))
996 .WillOnce(InvokeWithoutArgs(
997 &delegate,
998 &MockExtensionDownloaderDelegate::Quit));
999 fetcher->set_url(kUpdateUrl);
1000 fetcher->set_status(net::URLRequestStatus());
1001 fetcher->set_response_code(200);
1002 fetcher->SetResponseString(kInvalidXml);
1003 fetcher->delegate()->OnURLFetchComplete(fetcher);
1004 delegate.Wait();
1005 Mock::VerifyAndClearExpectations(&delegate);
1006 fetch2_url = GURL();
1007 } else if (fetcher->GetOriginalURL() == fetch3_url) {
1008 // The third fetcher doesn't have an update available.
1009 const std::string kNoUpdate =
1010 "<?xml version='1.0' encoding='UTF-8'?>"
1011 "<gupdate xmlns='http://www.google.com/update2/response'"
1012 " protocol='2.0'>"
1013 " <app appid='3333'>"
1014 " <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'"
1015 " version='3.0.0.0' prodversionmin='3.0.0.0' />"
1016 " </app>"
1017 "</gupdate>";
1018 EXPECT_CALL(delegate, IsExtensionPending("3333"))
1019 .WillOnce(Return(false));
1020 EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _))
1021 .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"),
1022 Return(true)));
1023 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
1024 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _))
1025 .WillOnce(InvokeWithoutArgs(
1026 &delegate,
1027 &MockExtensionDownloaderDelegate::Quit));
1028 fetcher->set_url(kUpdateUrl);
1029 fetcher->set_status(net::URLRequestStatus());
1030 fetcher->set_response_code(200);
1031 fetcher->SetResponseString(kNoUpdate);
1032 fetcher->delegate()->OnURLFetchComplete(fetcher);
1033 delegate.Wait();
1034 Mock::VerifyAndClearExpectations(&delegate);
1035 fetch3_url = GURL();
1036 } else if (fetcher->GetOriginalURL() == fetch4_url) {
1037 // The last fetcher has an update.
1038 NotificationsObserver observer;
1039 const std::string kUpdateAvailable =
1040 "<?xml version='1.0' encoding='UTF-8'?>"
1041 "<gupdate xmlns='http://www.google.com/update2/response'"
1042 " protocol='2.0'>"
1043 " <app appid='4444'>"
1044 " <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
1045 " version='4.0.42.0' prodversionmin='4.0.42.0' />"
1046 " </app>"
1047 "</gupdate>";
1048 EXPECT_CALL(delegate, IsExtensionPending("4444"))
1049 .WillOnce(Return(false));
1050 EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _))
1051 .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"),
1052 Return(true)));
1053 fetcher->set_url(kUpdateUrl);
1054 fetcher->set_status(net::URLRequestStatus());
1055 fetcher->set_response_code(200);
1056 fetcher->SetResponseString(kUpdateAvailable);
1057 fetcher->delegate()->OnURLFetchComplete(fetcher);
1058 observer.Wait();
1059 Mock::VerifyAndClearExpectations(&delegate);
1061 // Verify that the downloader decided to update this extension.
1062 EXPECT_EQ(1u, observer.UpdatedCount());
1063 EXPECT_TRUE(observer.Updated("4444"));
1064 fetch4_url = GURL();
1065 } else {
1066 ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL();
1070 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1071 if (fetcher)
1072 ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL();
1075 void TestManifestRetryDownloading() {
1076 net::TestURLFetcherFactory factory;
1077 net::TestURLFetcher* fetcher = NULL;
1078 NotificationsObserver observer;
1079 MockService service(prefs_.get());
1080 MockExtensionDownloaderDelegate delegate;
1081 ExtensionDownloader downloader(&delegate, service.request_context());
1082 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
1084 GURL kUpdateUrl("http://localhost/manifest1");
1086 scoped_ptr<ManifestFetchData> fetch(CreateManifestFetchData(kUpdateUrl));
1087 ManifestFetchData::PingData zeroDays(0, 0, true, 0);
1088 fetch->AddExtension(
1089 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
1091 // This will start the first fetcher.
1092 downloader.StartUpdateCheck(fetch.Pass());
1093 RunUntilIdle();
1095 // ExtensionDownloader should retry kMaxRetries times and then fail.
1096 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
1097 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
1098 for (int i = 0; i <= ExtensionDownloader::kMaxRetries; ++i) {
1099 // All fetches will fail.
1100 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1101 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1102 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1103 fetcher->set_url(kUpdateUrl);
1104 fetcher->set_status(net::URLRequestStatus());
1105 // Code 5xx causes ExtensionDownloader to retry.
1106 fetcher->set_response_code(500);
1107 fetcher->delegate()->OnURLFetchComplete(fetcher);
1108 RunUntilIdle();
1110 Mock::VerifyAndClearExpectations(&delegate);
1113 // For response codes that are not in the 5xx range ExtensionDownloader
1114 // should not retry.
1115 fetch.reset(CreateManifestFetchData(kUpdateUrl));
1116 fetch->AddExtension(
1117 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
1119 // This will start the first fetcher.
1120 downloader.StartUpdateCheck(fetch.Pass());
1121 RunUntilIdle();
1123 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
1124 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
1125 // The first fetch will fail, and require retrying.
1126 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1127 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1128 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1129 fetcher->set_url(kUpdateUrl);
1130 fetcher->set_status(net::URLRequestStatus());
1131 fetcher->set_response_code(500);
1132 fetcher->delegate()->OnURLFetchComplete(fetcher);
1133 RunUntilIdle();
1135 // The second fetch will fail with response 400 and should not cause
1136 // ExtensionDownloader to retry.
1137 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1138 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1139 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1140 fetcher->set_url(kUpdateUrl);
1141 fetcher->set_status(net::URLRequestStatus());
1142 fetcher->set_response_code(400);
1143 fetcher->delegate()->OnURLFetchComplete(fetcher);
1144 RunUntilIdle();
1146 Mock::VerifyAndClearExpectations(&delegate);
1149 void TestSingleExtensionDownloading(bool pending, bool retry, bool fail) {
1150 net::TestURLFetcherFactory factory;
1151 net::TestURLFetcher* fetcher = NULL;
1152 scoped_ptr<ServiceForDownloadTests> service(
1153 new ServiceForDownloadTests(prefs_.get()));
1154 ExtensionUpdater updater(service.get(),
1155 service->extension_prefs(),
1156 service->pref_service(),
1157 service->profile(),
1158 kUpdateFrequencySecs,
1159 NULL,
1160 service->GetDownloaderFactory());
1161 MockExtensionDownloaderDelegate delegate;
1162 delegate.DelegateTo(&updater);
1163 service->OverrideDownloaderDelegate(&delegate);
1164 updater.Start();
1165 updater.EnsureDownloaderCreated();
1166 updater.downloader_->extensions_queue_.set_backoff_policy(
1167 &kNoBackoffPolicy);
1169 GURL test_url("http://localhost/extension.crx");
1171 std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1172 std::string hash;
1173 Version version("0.0.1");
1174 std::set<int> requests;
1175 requests.insert(0);
1176 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
1177 new ExtensionDownloader::ExtensionFetch(
1178 id, test_url, hash, version.GetString(), requests));
1179 updater.downloader_->FetchUpdatedExtension(fetch.Pass());
1181 if (pending) {
1182 const bool kIsFromSync = true;
1183 const bool kMarkAcknowledged = false;
1184 const bool kRemoteInstall = false;
1185 PendingExtensionManager* pending_extension_manager =
1186 service->pending_extension_manager();
1187 pending_extension_manager->AddForTesting(
1188 PendingExtensionInfo(id,
1189 std::string(),
1190 test_url,
1191 version,
1192 &ShouldAlwaysInstall,
1193 kIsFromSync,
1194 Manifest::INTERNAL,
1195 Extension::NO_FLAGS,
1196 kMarkAcknowledged,
1197 kRemoteInstall));
1200 // Call back the ExtensionUpdater with a 200 response and some test data
1201 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1202 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1203 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1204 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1206 if (retry) {
1207 // Reply with response code 500 to cause ExtensionDownloader to retry
1208 fetcher->set_url(test_url);
1209 fetcher->set_status(net::URLRequestStatus());
1210 fetcher->set_response_code(500);
1211 fetcher->delegate()->OnURLFetchComplete(fetcher);
1213 RunUntilIdle();
1214 fetcher = factory.GetFetcherByID(
1215 ExtensionDownloader::kExtensionFetcherId);
1216 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1217 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1220 fetcher->set_url(test_url);
1221 fetcher->set_status(net::URLRequestStatus());
1222 if (fail) {
1223 fetcher->set_response_code(404);
1224 EXPECT_CALL(delegate, OnExtensionDownloadFailed(id, _, _, requests));
1225 } else {
1226 fetcher->set_response_code(200);
1227 fetcher->SetResponseFilePath(extension_file_path);
1228 EXPECT_CALL(delegate, OnExtensionDownloadFinished(
1229 id, _, _, _, version.GetString(), _, requests));
1231 fetcher->delegate()->OnURLFetchComplete(fetcher);
1233 RunUntilIdle();
1235 if (fail) {
1236 // Don't expect any extension to have been installed.
1237 EXPECT_TRUE(service->extension_id().empty());
1238 } else {
1239 // Expect that ExtensionUpdater asked the mock extensions service to
1240 // install a file with the test data for the right id.
1241 EXPECT_EQ(id, service->extension_id());
1242 base::FilePath tmpfile_path = service->install_path();
1243 EXPECT_FALSE(tmpfile_path.empty());
1244 EXPECT_EQ(extension_file_path, tmpfile_path);
1248 // Update a single extension in an environment where the download request
1249 // initially responds with a 403 status. If |identity_provider| is not NULL,
1250 // this will first expect a request which includes an Authorization header
1251 // with an OAuth2 bearer token; otherwise, or if OAuth2 failure is simulated,
1252 // this expects the downloader to fall back onto cookie-based credentials.
1253 void TestProtectedDownload(
1254 const std::string& url_prefix,
1255 bool enable_oauth2,
1256 bool succeed_with_oauth2,
1257 int valid_authuser,
1258 int max_authuser) {
1259 net::TestURLFetcherFactory factory;
1260 net::TestURLFetcher* fetcher = NULL;
1261 scoped_ptr<ServiceForDownloadTests> service(
1262 new ServiceForDownloadTests(prefs_.get()));
1263 const ExtensionDownloader::Factory& downloader_factory =
1264 enable_oauth2 ? service->GetAuthenticatedDownloaderFactory()
1265 : service->GetDownloaderFactory();
1266 ExtensionUpdater updater(
1267 service.get(),
1268 service->extension_prefs(),
1269 service->pref_service(),
1270 service->profile(),
1271 kUpdateFrequencySecs,
1272 NULL,
1273 downloader_factory);
1274 updater.Start();
1275 updater.EnsureDownloaderCreated();
1276 updater.downloader_->extensions_queue_.set_backoff_policy(
1277 &kNoBackoffPolicy);
1279 GURL test_url(base::StringPrintf("%s/extension.crx", url_prefix.c_str()));
1280 std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1281 std::string hash;
1282 Version version("0.0.1");
1283 std::set<int> requests;
1284 requests.insert(0);
1285 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
1286 new ExtensionDownloader::ExtensionFetch(
1287 id, test_url, hash, version.GetString(), requests));
1288 updater.downloader_->FetchUpdatedExtension(fetch.Pass());
1290 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1291 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1292 EXPECT_EQ(kExpectedLoadFlags, fetcher->GetLoadFlags());
1294 // Fake a 403 response.
1295 fetcher->set_url(test_url);
1296 fetcher->set_status(net::URLRequestStatus());
1297 fetcher->set_response_code(403);
1298 fetcher->delegate()->OnURLFetchComplete(fetcher);
1300 if (service->fake_token_service()) {
1301 service->fake_token_service()->IssueAllTokensForAccount(
1302 kFakeAccountId, kFakeOAuth2Token, base::Time::Now());
1304 RunUntilIdle();
1306 bool using_oauth2 = false;
1307 int expected_load_flags = kExpectedLoadFlags;
1308 // Verify that the fetch has had its credentials properly incremented.
1309 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1310 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1311 net::HttpRequestHeaders fetch_headers;
1312 fetcher->GetExtraRequestHeaders(&fetch_headers);
1313 // If the download URL is not https, no credentials should be provided.
1314 if (!test_url.SchemeIsSecure()) {
1315 // No cookies.
1316 EXPECT_EQ(kExpectedLoadFlags, fetcher->GetLoadFlags());
1317 // No Authorization header.
1318 EXPECT_FALSE(fetch_headers.HasHeader(
1319 net::HttpRequestHeaders::kAuthorization));
1320 expected_load_flags = kExpectedLoadFlags;
1321 } else {
1322 // HTTPS is in use, so credentials are allowed.
1323 if (enable_oauth2 && test_url.DomainIs("google.com")) {
1324 // If an IdentityProvider is present and the URL is a google.com
1325 // URL, the fetcher should be in OAuth2 mode after the intitial
1326 // challenge.
1327 EXPECT_TRUE(fetch_headers.HasHeader(
1328 net::HttpRequestHeaders::kAuthorization));
1329 std::string expected_header_value = base::StringPrintf("Bearer %s",
1330 kFakeOAuth2Token);
1331 std::string actual_header_value;
1332 fetch_headers.GetHeader(net::HttpRequestHeaders::kAuthorization,
1333 &actual_header_value);
1334 EXPECT_EQ(expected_header_value, actual_header_value);
1335 using_oauth2 = true;
1336 } else {
1337 // No IdentityProvider (or no google.com), so expect cookies instead of
1338 // an Authorization header.
1339 EXPECT_FALSE(fetch_headers.HasHeader(
1340 net::HttpRequestHeaders::kAuthorization));
1341 EXPECT_EQ(kExpectedLoadFlagsForDownloadWithCookies,
1342 fetcher->GetLoadFlags());
1343 expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
1347 bool success = false;
1348 if (using_oauth2) {
1349 if (succeed_with_oauth2) {
1350 success = true;
1351 } else {
1352 // Simulate OAuth2 failure and ensure that we fall back on cookies.
1353 fetcher->set_url(test_url);
1354 fetcher->set_status(net::URLRequestStatus());
1355 fetcher->set_response_code(403);
1356 fetcher->delegate()->OnURLFetchComplete(fetcher);
1357 RunUntilIdle();
1359 const ExtensionDownloader::ExtensionFetch& fetch =
1360 *updater.downloader_->extensions_queue_.active_request();
1361 EXPECT_EQ(0, GetAuthUserQueryValue(fetch.url));
1362 EXPECT_EQ(ExtensionDownloader::ExtensionFetch::CREDENTIALS_COOKIES,
1363 fetch.credentials);
1365 fetcher = factory.GetFetcherByID(
1366 ExtensionDownloader::kExtensionFetcherId);
1367 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1368 fetcher->GetExtraRequestHeaders(&fetch_headers);
1369 EXPECT_FALSE(fetch_headers.HasHeader(
1370 net::HttpRequestHeaders::kAuthorization));
1371 EXPECT_EQ(kExpectedLoadFlagsForDownloadWithCookies,
1372 fetcher->GetLoadFlags());
1373 expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
1377 if (!success) {
1378 // Not yet ready to simulate a successful fetch. At this point we begin
1379 // simulating cookie-based authentication with increasing values of
1380 // authuser (starting from 0.)
1381 int user_index = 0;
1382 for (; user_index <= max_authuser; ++user_index) {
1383 const ExtensionDownloader::ExtensionFetch& fetch =
1384 *updater.downloader_->extensions_queue_.active_request();
1385 EXPECT_EQ(user_index, GetAuthUserQueryValue(fetch.url));
1386 if (user_index == valid_authuser) {
1387 success = true;
1388 break;
1390 // Simulate an authorization failure which should elicit an increment
1391 // of the authuser value.
1392 fetcher =
1393 factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1394 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1395 EXPECT_EQ(expected_load_flags, fetcher->GetLoadFlags());
1396 fetcher->set_url(fetch.url);
1397 fetcher->set_status(net::URLRequestStatus());
1398 fetcher->set_response_code(403);
1399 fetcher->delegate()->OnURLFetchComplete(fetcher);
1400 RunUntilIdle();
1403 // Simulate exhaustion of all available authusers.
1404 if (!success && user_index > max_authuser) {
1405 const ExtensionDownloader::ExtensionFetch& fetch =
1406 *updater.downloader_->extensions_queue_.active_request();
1407 fetcher =
1408 factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1409 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1410 fetcher->set_url(fetch.url);
1411 fetcher->set_status(net::URLRequestStatus());
1412 fetcher->set_response_code(401);
1413 fetcher->delegate()->OnURLFetchComplete(fetcher);
1414 RunUntilIdle();
1418 // Simulate successful authorization with a 200 response.
1419 if (success) {
1420 fetcher =
1421 factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1422 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1423 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1424 fetcher->set_url(test_url);
1425 fetcher->set_status(net::URLRequestStatus());
1426 fetcher->set_response_code(200);
1427 fetcher->SetResponseFilePath(extension_file_path);
1428 fetcher->delegate()->OnURLFetchComplete(fetcher);
1429 RunUntilIdle();
1431 // Verify installation would proceed as normal.
1432 EXPECT_EQ(id, service->extension_id());
1433 base::FilePath tmpfile_path = service->install_path();
1434 EXPECT_FALSE(tmpfile_path.empty());
1435 EXPECT_EQ(extension_file_path, tmpfile_path);
1439 // Two extensions are updated. If |updates_start_running| is true, the
1440 // mock extensions service has UpdateExtension(...) return true, and
1441 // the test is responsible for creating fake CrxInstallers. Otherwise,
1442 // UpdateExtension() returns false, signaling install failures.
1443 void TestMultipleExtensionDownloading(bool updates_start_running) {
1444 net::TestURLFetcherFactory factory;
1445 net::TestURLFetcher* fetcher = NULL;
1446 ServiceForDownloadTests service(prefs_.get());
1447 ExtensionUpdater updater(&service,
1448 service.extension_prefs(),
1449 service.pref_service(),
1450 service.profile(),
1451 kUpdateFrequencySecs,
1452 NULL,
1453 service.GetDownloaderFactory());
1454 updater.Start();
1455 updater.EnsureDownloaderCreated();
1456 updater.downloader_->extensions_queue_.set_backoff_policy(
1457 &kNoBackoffPolicy);
1459 EXPECT_FALSE(updater.crx_install_is_running_);
1461 GURL url1("http://localhost/extension1.crx");
1462 GURL url2("http://localhost/extension2.crx");
1464 std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1465 std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
1467 std::string hash1;
1468 std::string hash2;
1470 std::string version1 = "0.1";
1471 std::string version2 = "0.1";
1472 std::set<int> requests;
1473 requests.insert(0);
1474 // Start two fetches
1475 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch1(
1476 new ExtensionDownloader::ExtensionFetch(
1477 id1, url1, hash1, version1, requests));
1478 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch2(
1479 new ExtensionDownloader::ExtensionFetch(
1480 id2, url2, hash2, version2, requests));
1481 updater.downloader_->FetchUpdatedExtension(fetch1.Pass());
1482 updater.downloader_->FetchUpdatedExtension(fetch2.Pass());
1484 // Make the first fetch complete.
1485 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1487 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1488 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1489 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1491 // We need some CrxInstallers, and CrxInstallers require a real
1492 // ExtensionService. Create one on the testing profile. Any action
1493 // the CrxInstallers take is on the testing profile's extension
1494 // service, not on our mock |service|. This allows us to fake
1495 // the CrxInstaller actions we want.
1496 TestingProfile profile;
1497 static_cast<TestExtensionSystem*>(
1498 ExtensionSystem::Get(&profile))->
1499 CreateExtensionService(
1500 CommandLine::ForCurrentProcess(),
1501 base::FilePath(),
1502 false);
1503 ExtensionService* extension_service =
1504 ExtensionSystem::Get(&profile)->extension_service();
1505 extension_service->set_extensions_enabled(true);
1506 extension_service->set_show_extensions_prompts(false);
1508 scoped_refptr<CrxInstaller> fake_crx1(
1509 CrxInstaller::CreateSilent(extension_service));
1510 scoped_refptr<CrxInstaller> fake_crx2(
1511 CrxInstaller::CreateSilent(extension_service));
1513 if (updates_start_running) {
1514 // Add fake CrxInstaller to be returned by service.UpdateExtension().
1515 service.AddFakeCrxInstaller(id1, fake_crx1.get());
1516 service.AddFakeCrxInstaller(id2, fake_crx2.get());
1517 } else {
1518 // If we don't add fake CRX installers, the mock service fakes a failure
1519 // starting the install.
1522 fetcher->set_url(url1);
1523 fetcher->set_status(net::URLRequestStatus());
1524 fetcher->set_response_code(200);
1525 fetcher->SetResponseFilePath(extension_file_path);
1526 fetcher->delegate()->OnURLFetchComplete(fetcher);
1528 RunUntilIdle();
1530 // Expect that the service was asked to do an install with the right data.
1531 base::FilePath tmpfile_path = service.install_path();
1532 EXPECT_FALSE(tmpfile_path.empty());
1533 EXPECT_EQ(id1, service.extension_id());
1534 RunUntilIdle();
1536 // Make sure the second fetch finished and asked the service to do an
1537 // update.
1538 base::FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2"));
1539 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1540 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1541 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1543 fetcher->set_url(url2);
1544 fetcher->set_status(net::URLRequestStatus());
1545 fetcher->set_response_code(200);
1546 fetcher->SetResponseFilePath(extension_file_path2);
1547 fetcher->delegate()->OnURLFetchComplete(fetcher);
1548 RunUntilIdle();
1550 if (updates_start_running) {
1551 EXPECT_TRUE(updater.crx_install_is_running_);
1553 // The second install should not have run, because the first has not
1554 // sent a notification that it finished.
1555 EXPECT_EQ(id1, service.extension_id());
1557 // Fake install notice. This should start the second installation,
1558 // which will be checked below.
1559 fake_crx1->NotifyCrxInstallComplete(false);
1561 EXPECT_TRUE(updater.crx_install_is_running_);
1564 EXPECT_EQ(id2, service.extension_id());
1565 EXPECT_FALSE(service.install_path().empty());
1567 // Make sure the correct crx contents were passed for the update call.
1568 EXPECT_EQ(extension_file_path2, service.install_path());
1570 if (updates_start_running) {
1571 EXPECT_TRUE(updater.crx_install_is_running_);
1572 fake_crx2->NotifyCrxInstallComplete(false);
1574 EXPECT_FALSE(updater.crx_install_is_running_);
1577 void TestGalleryRequestsWithBrand(bool use_organic_brand_code) {
1578 google_brand::BrandForTesting brand_for_testing(
1579 use_organic_brand_code ? "GGLS" : "TEST");
1581 // We want to test a variety of combinations of expected ping conditions for
1582 // rollcall and active pings.
1583 int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
1585 for (size_t i = 0; i < arraysize(ping_cases); i++) {
1586 for (size_t j = 0; j < arraysize(ping_cases); j++) {
1587 for (size_t k = 0; k < 2; k++) {
1588 int rollcall_ping_days = ping_cases[i];
1589 int active_ping_days = ping_cases[j];
1590 // Skip cases where rollcall_ping_days == -1, but
1591 // active_ping_days > 0, because rollcall_ping_days == -1 means the
1592 // app was just installed and this is the first update check after
1593 // installation.
1594 if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
1595 active_ping_days > 0)
1596 continue;
1598 bool active_bit = k > 0;
1599 TestGalleryRequests(rollcall_ping_days, active_ping_days, active_bit,
1600 !use_organic_brand_code);
1601 ASSERT_FALSE(HasFailure()) <<
1602 " rollcall_ping_days=" << ping_cases[i] <<
1603 " active_ping_days=" << ping_cases[j] <<
1604 " active_bit=" << active_bit;
1610 // Test requests to both a Google server and a non-google server. This allows
1611 // us to test various combinations of installed (ie roll call) and active
1612 // (ie app launch) ping scenarios. The invariant is that each type of ping
1613 // value should be present at most once per day, and can be calculated based
1614 // on the delta between now and the last ping time (or in the case of active
1615 // pings, that delta plus whether the app has been active).
1616 void TestGalleryRequests(int rollcall_ping_days,
1617 int active_ping_days,
1618 bool active_bit,
1619 bool expect_brand_code) {
1620 net::TestURLFetcherFactory factory;
1622 // Set up 2 mock extensions, one with a google.com update url and one
1623 // without.
1624 prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
1625 ServiceForManifestTests service(prefs_.get());
1626 ExtensionList tmp;
1627 GURL url1("http://clients2.google.com/service/update2/crx");
1628 GURL url2("http://www.somewebsite.com");
1629 service.CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
1630 Manifest::INTERNAL);
1631 service.CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
1632 Manifest::INTERNAL);
1633 EXPECT_EQ(2u, tmp.size());
1634 service.set_extensions(tmp, ExtensionList());
1636 ExtensionPrefs* prefs = service.extension_prefs();
1637 const std::string& id = tmp[0]->id();
1638 Time now = Time::Now();
1639 if (rollcall_ping_days == 0) {
1640 prefs->SetLastPingDay(id, now - TimeDelta::FromSeconds(15));
1641 } else if (rollcall_ping_days > 0) {
1642 Time last_ping_day = now -
1643 TimeDelta::FromDays(rollcall_ping_days) -
1644 TimeDelta::FromSeconds(15);
1645 prefs->SetLastPingDay(id, last_ping_day);
1648 // Store a value for the last day we sent an active ping.
1649 if (active_ping_days == 0) {
1650 prefs->SetLastActivePingDay(id, now - TimeDelta::FromSeconds(15));
1651 } else if (active_ping_days > 0) {
1652 Time last_active_ping_day = now -
1653 TimeDelta::FromDays(active_ping_days) -
1654 TimeDelta::FromSeconds(15);
1655 prefs->SetLastActivePingDay(id, last_active_ping_day);
1657 if (active_bit)
1658 prefs->SetActiveBit(id, true);
1660 ExtensionUpdater updater(&service,
1661 service.extension_prefs(),
1662 service.pref_service(),
1663 service.profile(),
1664 kUpdateFrequencySecs,
1665 NULL,
1666 service.GetDownloaderFactory());
1667 ExtensionUpdater::CheckParams params;
1668 updater.Start();
1669 updater.CheckNow(params);
1670 content::RunAllBlockingPoolTasksUntilIdle();
1672 // Make the updater do manifest fetching, and note the urls it tries to
1673 // fetch.
1674 std::vector<GURL> fetched_urls;
1675 net::TestURLFetcher* fetcher =
1676 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1677 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1678 fetched_urls.push_back(fetcher->GetOriginalURL());
1680 fetcher->set_url(fetched_urls[0]);
1681 fetcher->set_status(net::URLRequestStatus());
1682 fetcher->set_response_code(500);
1683 fetcher->SetResponseString(std::string());
1684 fetcher->delegate()->OnURLFetchComplete(fetcher);
1686 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1687 fetched_urls.push_back(fetcher->GetOriginalURL());
1689 // The urls could have been fetched in either order, so use the host to
1690 // tell them apart and note the query each used.
1691 std::string url1_query;
1692 std::string url2_query;
1693 if (fetched_urls[0].host() == url1.host()) {
1694 url1_query = fetched_urls[0].query();
1695 url2_query = fetched_urls[1].query();
1696 } else if (fetched_urls[0].host() == url2.host()) {
1697 url1_query = fetched_urls[1].query();
1698 url2_query = fetched_urls[0].query();
1699 } else {
1700 NOTREACHED();
1703 // First make sure the non-google query had no ping parameter.
1704 std::string search_string = "ping%3D";
1705 EXPECT_TRUE(url2_query.find(search_string) == std::string::npos);
1707 // Now make sure the google query had the correct ping parameter.
1708 bool ping_expected = false;
1709 bool did_rollcall = false;
1710 if (rollcall_ping_days != 0) {
1711 search_string += "r%253D" + base::IntToString(rollcall_ping_days);
1712 did_rollcall = true;
1713 ping_expected = true;
1715 if (active_bit && active_ping_days != 0) {
1716 if (did_rollcall)
1717 search_string += "%2526";
1718 search_string += "a%253D" + base::IntToString(active_ping_days);
1719 ping_expected = true;
1721 bool ping_found = url1_query.find(search_string) != std::string::npos;
1722 EXPECT_EQ(ping_expected, ping_found) << "query was: " << url1_query
1723 << " was looking for " << search_string;
1725 // Make sure the non-google query has no brand parameter.
1726 const std::string brand_string = "brand%3D";
1727 EXPECT_TRUE(url2_query.find(brand_string) == std::string::npos);
1729 #if defined(GOOGLE_CHROME_BUILD)
1730 // Make sure the google query has a brand parameter, but only if the
1731 // brand is non-organic.
1732 if (expect_brand_code) {
1733 EXPECT_TRUE(url1_query.find(brand_string) != std::string::npos);
1734 } else {
1735 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1737 #else
1738 // Chromium builds never add the brand to the parameter, even for google
1739 // queries.
1740 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1741 #endif
1743 RunUntilIdle();
1746 // This makes sure that the extension updater properly stores the results
1747 // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
1748 // the first time we fetched the extension, or 2) We sent a ping value of
1749 // >= 1 day for the extension.
1750 void TestHandleManifestResults() {
1751 ServiceForManifestTests service(prefs_.get());
1752 GURL update_url("http://www.google.com/manifest");
1753 ExtensionList tmp;
1754 service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
1755 Manifest::INTERNAL);
1756 service.set_extensions(tmp, ExtensionList());
1758 ExtensionUpdater updater(&service,
1759 service.extension_prefs(),
1760 service.pref_service(),
1761 service.profile(),
1762 kUpdateFrequencySecs,
1763 nullptr,
1764 service.GetDownloaderFactory());
1765 updater.Start();
1766 updater.EnsureDownloaderCreated();
1768 scoped_ptr<ManifestFetchData> fetch_data(
1769 CreateManifestFetchData(update_url));
1770 const Extension* extension = tmp[0].get();
1771 fetch_data->AddExtension(extension->id(),
1772 extension->VersionString(),
1773 &kNeverPingedData,
1774 kEmptyUpdateUrlData,
1775 std::string(),
1776 false);
1777 UpdateManifest::Results results;
1778 results.daystart_elapsed_seconds = 750;
1780 updater.downloader_->HandleManifestResults(*fetch_data, &results);
1781 Time last_ping_day =
1782 service.extension_prefs()->LastPingDay(extension->id());
1783 EXPECT_FALSE(last_ping_day.is_null());
1784 int64 seconds_diff = (Time::Now() - last_ping_day).InSeconds();
1785 EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
1788 // This lets us run a test with some enabled and some disabled
1789 // extensions. The |num_enabled| value specifies how many enabled extensions
1790 // to have, and |disabled| is a vector of DisableReason bitmasks for each
1791 // disabled extension we want. |enable_metrics| specifies whether we should
1792 // have enabled/disable reason information in the ping parameter.
1793 void TestPingMetrics(bool enable_metrics,
1794 int num_enabled,
1795 const std::vector<int>& disabled) {
1796 ServiceForManifestTests service(prefs_.get());
1797 service.set_enable_metrics(enable_metrics);
1799 ExtensionList enabled_extensions;
1800 ExtensionList disabled_extensions;
1802 std::string update_url = extension_urls::GetWebstoreUpdateUrl().spec();
1803 if (num_enabled > 0)
1804 service.CreateTestExtensions(
1805 1, num_enabled, &enabled_extensions, &update_url, Manifest::INTERNAL);
1806 if (disabled.size() > 0)
1807 service.CreateTestExtensions(2,
1808 disabled.size(),
1809 &disabled_extensions,
1810 &update_url,
1811 Manifest::INTERNAL);
1813 service.set_extensions(enabled_extensions, disabled_extensions);
1815 ExtensionPrefs* prefs = prefs_->prefs();
1817 for (size_t i = 0; i < disabled.size(); i++) {
1818 int reasons = disabled[i];
1819 const std::string& id = disabled_extensions[i]->id();
1820 // Iterate over the DisableReason values, marking that reason in prefs
1821 // for this id if it is set.
1822 for (int reason = 1; reason < Extension::DISABLE_REASON_LAST;
1823 reason <<= 1) {
1824 if (reasons & reason)
1825 prefs->AddDisableReason(
1826 id, static_cast<Extension::DisableReason>(reason));
1830 // Create the extension updater, make it issue an update, and capture the
1831 // URL that it tried to fetch.
1832 net::TestURLFetcherFactory factory;
1833 ExtensionUpdater updater(&service,
1834 service.extension_prefs(),
1835 service.pref_service(),
1836 service.profile(),
1837 kUpdateFrequencySecs,
1838 nullptr,
1839 service.GetDownloaderFactory());
1840 updater.Start();
1841 SimulateTimerFired(&updater);
1842 net::TestURLFetcher* fetcher =
1843 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1844 ASSERT_NE(nullptr, fetcher);
1845 const GURL& url = fetcher->GetOriginalURL();
1846 EXPECT_FALSE(url.is_empty());
1847 EXPECT_TRUE(url.is_valid());
1848 EXPECT_TRUE(url.has_query());
1850 std::map<std::string, ParamsMap> all_pings = GetPingDataFromURL(url);
1852 // Make sure that all the enabled extensions have "e=1" in their ping
1853 // parameter if metrics are turned on, or don't have it if metrics are
1854 // off.
1855 for (const auto& ext : enabled_extensions) {
1856 ASSERT_TRUE(ContainsKey(all_pings, ext->id()));
1857 ParamsMap& ping = all_pings[ext->id()];
1858 if (!enable_metrics) {
1859 EXPECT_FALSE(ContainsKey(ping, "e"));
1860 EXPECT_FALSE(ContainsKey(ping, "dr"));
1861 continue;
1863 EXPECT_FALSE(ContainsKey(ping, "dr"));
1864 ASSERT_TRUE(ContainsKey(ping, "e")) << url;
1865 std::set<std::string> e = ping["e"];
1866 ASSERT_EQ(1u, e.size()) << url;
1867 EXPECT_EQ(std::string("1"), *e.begin()) << url;
1868 EXPECT_FALSE(ContainsKey(ping, "dr"));
1871 // Make sure that all the disable extensions have the appropriate
1872 // "dr=<num>" values in their ping parameter if metrics are on, or omit
1873 // it otherwise.
1874 ASSERT_EQ(disabled_extensions.size(), disabled.size());
1875 for (size_t i = 0; i < disabled.size(); i++) {
1876 scoped_refptr<const Extension>& ext = disabled_extensions[i];
1877 int disable_reasons = disabled[i];
1878 ASSERT_TRUE(ContainsKey(all_pings, ext->id())) << url;
1879 ParamsMap& ping = all_pings[ext->id()];
1881 if (!enable_metrics) {
1882 EXPECT_FALSE(ContainsKey(ping, "e"));
1883 EXPECT_FALSE(ContainsKey(ping, "dr"));
1884 continue;
1886 ASSERT_TRUE(ContainsKey(ping, "e")) << url;
1887 std::set<std::string> e = ping["e"];
1888 ASSERT_EQ(1u, e.size()) << url;
1889 EXPECT_EQ(std::string("0"), *e.begin()) << url;
1891 if (disable_reasons == 0) {
1892 EXPECT_FALSE(ContainsKey(ping, "dr"));
1893 } else {
1894 ASSERT_TRUE(ContainsKey(ping, "dr"));
1895 int found_reasons = 0;
1896 for (const auto& reason_string : ping["dr"]) {
1897 int reason = 0;
1898 ASSERT_TRUE(base::StringToInt(reason_string, &reason));
1899 // Make sure it's a power of 2.
1900 ASSERT_TRUE(reason < 2 || !(reason & (reason - 1))) << reason;
1901 found_reasons |= reason;
1903 EXPECT_EQ(disable_reasons, found_reasons);
1908 protected:
1909 scoped_ptr<TestExtensionPrefs> prefs_;
1911 ManifestFetchData* CreateManifestFetchData(const GURL& update_url) {
1912 return new ManifestFetchData(update_url,
1915 OmahaQueryParams::Get(OmahaQueryParams::CRX),
1916 ManifestFetchData::PING);
1919 private:
1920 content::TestBrowserThreadBundle thread_bundle_;
1921 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
1923 #if defined OS_CHROMEOS
1924 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
1925 chromeos::ScopedTestCrosSettings test_cros_settings_;
1926 chromeos::ScopedTestUserManager test_user_manager_;
1927 #endif
1930 // Because we test some private methods of ExtensionUpdater, it's easier for the
1931 // actual test code to live in ExtenionUpdaterTest methods instead of TEST_F
1932 // subclasses where friendship with ExtenionUpdater is not inherited.
1934 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
1935 TestExtensionUpdateCheckRequests(false);
1938 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
1939 TestExtensionUpdateCheckRequests(true);
1942 TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
1943 TestUpdateUrlDataEmpty();
1944 TestUpdateUrlDataSimple();
1945 TestUpdateUrlDataCompound();
1946 TestUpdateUrlDataFromGallery(
1947 extension_urls::GetWebstoreUpdateUrl().spec());
1950 TEST_F(ExtensionUpdaterTest, TestInstallSource) {
1951 TestInstallSource();
1954 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
1955 TestDetermineUpdates();
1958 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
1959 TestDetermineUpdatesPending();
1962 TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
1963 TestMultipleManifestDownloading();
1966 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
1967 TestSingleExtensionDownloading(false, false, false);
1970 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
1971 TestSingleExtensionDownloading(true, false, false);
1974 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
1975 TestSingleExtensionDownloading(false, true, false);
1978 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
1979 TestSingleExtensionDownloading(true, true, false);
1982 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailure) {
1983 TestSingleExtensionDownloading(false, false, true);
1986 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailureWithRetry) {
1987 TestSingleExtensionDownloading(false, true, true);
1990 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailurePending) {
1991 TestSingleExtensionDownloading(true, false, true);
1994 TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieAuth) {
1995 TestProtectedDownload(
1996 "https://chrome.google.com/webstore/download",
1997 false, false, // No OAuth2 support
1998 0, 0);
2001 TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieFailure) {
2002 TestProtectedDownload(
2003 "https://chrome.google.com/webstore/download",
2004 false, false, // No OAuth2 support
2005 0, -1); // max_authuser=-1 simulates no valid authuser value.
2008 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser1) {
2009 TestProtectedDownload("https://google.com", false, false, 1, 1);
2012 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser2) {
2013 TestProtectedDownload("https://google.com", false, false, 2, 2);
2016 TEST_F(ExtensionUpdaterTest, ProtectedDownloadAuthUserExhaustionFailure) {
2017 TestProtectedDownload("https://google.com", false, false, 2, 5);
2020 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Token) {
2021 TestProtectedDownload(
2022 "https://google.com",
2023 true, true,
2024 0, -1);
2027 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Failure) {
2028 TestProtectedDownload(
2029 "https://google.com",
2030 true, false,
2031 0, -1);
2034 TEST_F(ExtensionUpdaterTest, ProtectedDownloadNoOAuth2WithNonGoogleDomain) {
2035 TestProtectedDownload(
2036 "https://not-google.com",
2037 true, true,
2038 0, -1);
2041 TEST_F(ExtensionUpdaterTest, ProtectedDownloadFailWithoutHTTPS) {
2042 TestProtectedDownload(
2043 "http://google.com",
2044 true, true,
2045 0, 0);
2048 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
2049 TestMultipleExtensionDownloading(false);
2051 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
2052 TestMultipleExtensionDownloading(true);
2055 TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
2056 TestManifestRetryDownloading();
2059 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) {
2060 TestGalleryRequestsWithBrand(true);
2063 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) {
2064 TestGalleryRequestsWithBrand(false);
2067 TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
2068 TestHandleManifestResults();
2071 TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
2072 net::TestURLFetcherFactory factory;
2073 ServiceForManifestTests service(prefs_.get());
2074 ExtensionUpdater updater(&service,
2075 service.extension_prefs(),
2076 service.pref_service(),
2077 service.profile(),
2078 kUpdateFrequencySecs,
2079 NULL,
2080 service.GetDownloaderFactory());
2081 MockExtensionDownloaderDelegate delegate;
2082 service.OverrideDownloaderDelegate(&delegate);
2084 // Non-internal non-external extensions should be rejected.
2085 ExtensionList extensions;
2086 service.CreateTestExtensions(1, 1, &extensions, NULL,
2087 Manifest::INVALID_LOCATION);
2088 service.CreateTestExtensions(2, 1, &extensions, NULL, Manifest::INTERNAL);
2089 ASSERT_EQ(2u, extensions.size());
2090 const std::string& updateable_id = extensions[1]->id();
2092 // These expectations fail if the delegate's methods are invoked for the
2093 // first extension, which has a non-matching id.
2094 EXPECT_CALL(delegate,
2095 GetUpdateUrlData(updateable_id)).WillOnce(Return(""));
2096 EXPECT_CALL(delegate, GetPingDataForExtension(updateable_id, _));
2098 service.set_extensions(extensions, ExtensionList());
2099 ExtensionUpdater::CheckParams params;
2100 updater.Start();
2101 updater.CheckNow(params);
2102 content::RunAllBlockingPoolTasksUntilIdle();
2105 TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
2106 net::TestURLFetcherFactory factory;
2107 ServiceForManifestTests service(prefs_.get());
2108 ExtensionUpdater updater(&service,
2109 service.extension_prefs(),
2110 service.pref_service(),
2111 service.profile(),
2112 kUpdateFrequencySecs,
2113 NULL,
2114 service.GetDownloaderFactory());
2115 MockExtensionDownloaderDelegate delegate;
2116 service.OverrideDownloaderDelegate(&delegate);
2118 // Non-internal non-external extensions should be rejected.
2119 ExtensionList enabled_extensions;
2120 ExtensionList disabled_extensions;
2121 service.CreateTestExtensions(1, 1, &enabled_extensions, NULL,
2122 Manifest::INTERNAL);
2123 service.CreateTestExtensions(2, 1, &disabled_extensions, NULL,
2124 Manifest::INTERNAL);
2125 ASSERT_EQ(1u, enabled_extensions.size());
2126 ASSERT_EQ(1u, disabled_extensions.size());
2127 const std::string& enabled_id = enabled_extensions[0]->id();
2128 const std::string& disabled_id = disabled_extensions[0]->id();
2130 // We expect that both enabled and disabled extensions are auto-updated.
2131 EXPECT_CALL(delegate, GetUpdateUrlData(enabled_id)).WillOnce(Return(""));
2132 EXPECT_CALL(delegate, GetPingDataForExtension(enabled_id, _));
2133 EXPECT_CALL(delegate,
2134 GetUpdateUrlData(disabled_id)).WillOnce(Return(""));
2135 EXPECT_CALL(delegate, GetPingDataForExtension(disabled_id, _));
2137 service.set_extensions(enabled_extensions, disabled_extensions);
2138 ExtensionUpdater::CheckParams params;
2139 updater.Start();
2140 updater.CheckNow(params);
2141 content::RunAllBlockingPoolTasksUntilIdle();
2144 TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
2145 net::TestURLFetcherFactory factory;
2146 MockService service(prefs_.get());
2147 MockExtensionDownloaderDelegate delegate;
2148 scoped_ptr<ExtensionDownloader> downloader(
2149 new ExtensionDownloader(&delegate, service.request_context()));
2150 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
2152 // First, verify that adding valid extensions does invoke the callbacks on
2153 // the delegate.
2154 std::string id = crx_file::id_util::GenerateId("foo");
2155 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
2156 EXPECT_TRUE(
2157 downloader->AddPendingExtension(id, GURL("http://example.com/update"),
2158 0));
2159 downloader->StartAllPending(NULL);
2160 Mock::VerifyAndClearExpectations(&delegate);
2161 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2163 // Extensions with invalid update URLs should be rejected.
2164 id = crx_file::id_util::GenerateId("foo2");
2165 EXPECT_FALSE(
2166 downloader->AddPendingExtension(id, GURL("http:google.com:foo"), 0));
2167 downloader->StartAllPending(NULL);
2168 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2170 // Extensions with empty IDs should be rejected.
2171 EXPECT_FALSE(downloader->AddPendingExtension(std::string(), GURL(), 0));
2172 downloader->StartAllPending(NULL);
2173 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2175 // TODO(akalin): Test that extensions with empty update URLs
2176 // converted from user scripts are rejected.
2178 // Reset the ExtensionDownloader so that it drops the current fetcher.
2179 downloader.reset(
2180 new ExtensionDownloader(&delegate, service.request_context()));
2181 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
2183 // Extensions with empty update URLs should have a default one
2184 // filled in.
2185 id = crx_file::id_util::GenerateId("foo3");
2186 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
2187 EXPECT_TRUE(downloader->AddPendingExtension(id, GURL(), 0));
2188 downloader->StartAllPending(NULL);
2189 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2191 net::TestURLFetcher* fetcher =
2192 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
2193 ASSERT_TRUE(fetcher);
2194 EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
2197 TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
2198 net::TestURLFetcherFactory factory;
2199 MockService service(prefs_.get());
2200 MockExtensionDownloaderDelegate delegate;
2201 ExtensionDownloader downloader(&delegate, service.request_context());
2203 StartUpdateCheck(&downloader, CreateManifestFetchData(GURL()));
2204 // This should delete the newly-created ManifestFetchData.
2205 StartUpdateCheck(&downloader, CreateManifestFetchData(GURL()));
2206 // This should add into |manifests_pending_|.
2207 StartUpdateCheck(&downloader,
2208 CreateManifestFetchData(GURL("http://www.google.com")));
2209 // The dtor of |downloader| should delete the pending fetchers.
2212 TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
2213 ServiceForManifestTests service(prefs_.get());
2214 net::TestURLFetcherFactory factory;
2215 ExtensionUpdater updater(&service,
2216 service.extension_prefs(),
2217 service.pref_service(),
2218 service.profile(),
2219 kUpdateFrequencySecs,
2220 NULL,
2221 service.GetDownloaderFactory());
2222 EXPECT_FALSE(updater.WillCheckSoon());
2223 updater.Start();
2224 EXPECT_FALSE(updater.WillCheckSoon());
2225 updater.CheckSoon();
2226 EXPECT_TRUE(updater.WillCheckSoon());
2227 updater.CheckSoon();
2228 EXPECT_TRUE(updater.WillCheckSoon());
2229 RunUntilIdle();
2230 EXPECT_FALSE(updater.WillCheckSoon());
2231 updater.CheckSoon();
2232 EXPECT_TRUE(updater.WillCheckSoon());
2233 updater.Stop();
2234 EXPECT_FALSE(updater.WillCheckSoon());
2237 TEST_F(ExtensionUpdaterTest, TestDisabledReasons1) {
2238 std::vector<int> disabled;
2239 disabled.push_back(Extension::DISABLE_USER_ACTION);
2240 disabled.push_back(Extension::DISABLE_PERMISSIONS_INCREASE |
2241 Extension::DISABLE_CORRUPTED);
2242 TestPingMetrics(true, 1, disabled);
2243 TestPingMetrics(false, 1, disabled);
2246 TEST_F(ExtensionUpdaterTest, TestDisabledReasons2) {
2247 std::vector<int> disabled;
2248 TestPingMetrics(true, 1, disabled);
2249 TestPingMetrics(false, 1, disabled);
2252 TEST_F(ExtensionUpdaterTest, TestDisabledReasons3) {
2253 std::vector<int> disabled;
2254 disabled.push_back(0);
2255 TestPingMetrics(true, 0, disabled);
2256 TestPingMetrics(false, 0, disabled);
2259 // TODO(asargent) - (http://crbug.com/12780) add tests for:
2260 // -prodversionmin (shouldn't update if browser version too old)
2261 // -manifests & updates arriving out of order / interleaved
2262 // -malformed update url (empty, file://, has query, has a # fragment, etc.)
2263 // -An extension gets uninstalled while updates are in progress (so it doesn't
2264 // "come back from the dead")
2265 // -An extension gets manually updated to v3 while we're downloading v2 (ie
2266 // you don't get downgraded accidentally)
2267 // -An update manifest mentions multiple updates
2269 } // namespace extensions