Rename GetIconID to GetIconId
[chromium-blink-merge.git] / chrome / browser / extensions / updater / extension_updater_unittest.cc
blob59052b526c96c60c03e4576d883197050a8c0bb0
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/thread_task_runner_handle.h"
25 #include "base/threading/thread.h"
26 #include "base/version.h"
27 #include "chrome/browser/chrome_notification_types.h"
28 #include "chrome/browser/extensions/crx_installer.h"
29 #include "chrome/browser/extensions/extension_error_reporter.h"
30 #include "chrome/browser/extensions/extension_sync_data.h"
31 #include "chrome/browser/extensions/test_extension_prefs.h"
32 #include "chrome/browser/extensions/test_extension_service.h"
33 #include "chrome/browser/extensions/test_extension_system.h"
34 #include "chrome/browser/extensions/updater/chrome_extension_downloader_factory.h"
35 #include "chrome/browser/extensions/updater/extension_updater.h"
36 #include "chrome/browser/google/google_brand.h"
37 #include "chrome/browser/prefs/pref_service_syncable.h"
38 #include "chrome/test/base/scoped_testing_local_state.h"
39 #include "chrome/test/base/testing_browser_process.h"
40 #include "chrome/test/base/testing_profile.h"
41 #include "components/crx_file/id_util.h"
42 #include "components/update_client/update_query_params.h"
43 #include "content/public/browser/notification_details.h"
44 #include "content/public/browser/notification_observer.h"
45 #include "content/public/browser/notification_registrar.h"
46 #include "content/public/browser/notification_service.h"
47 #include "content/public/browser/notification_source.h"
48 #include "content/public/test/test_browser_thread_bundle.h"
49 #include "content/public/test/test_utils.h"
50 #include "extensions/browser/extension_prefs.h"
51 #include "extensions/browser/extension_registry.h"
52 #include "extensions/browser/extension_system.h"
53 #include "extensions/browser/updater/extension_downloader.h"
54 #include "extensions/browser/updater/extension_downloader_delegate.h"
55 #include "extensions/browser/updater/manifest_fetch_data.h"
56 #include "extensions/browser/updater/request_queue_impl.h"
57 #include "extensions/common/extension.h"
58 #include "extensions/common/extension_urls.h"
59 #include "extensions/common/manifest_constants.h"
60 #include "google_apis/gaia/fake_identity_provider.h"
61 #include "google_apis/gaia/fake_oauth2_token_service.h"
62 #include "net/base/backoff_entry.h"
63 #include "net/base/escape.h"
64 #include "net/base/load_flags.h"
65 #include "net/http/http_request_headers.h"
66 #include "net/url_request/test_url_fetcher_factory.h"
67 #include "net/url_request/url_request_status.h"
68 #include "testing/gmock/include/gmock/gmock.h"
69 #include "testing/gtest/include/gtest/gtest.h"
70 #include "url/third_party/mozilla/url_parse.h"
72 #if defined(OS_CHROMEOS)
73 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
74 #include "chrome/browser/chromeos/settings/cros_settings.h"
75 #include "chrome/browser/chromeos/settings/device_settings_service.h"
76 #endif
78 using base::Time;
79 using base::TimeDelta;
80 using content::BrowserThread;
81 using update_client::UpdateQueryParams;
82 using testing::DoAll;
83 using testing::Invoke;
84 using testing::InvokeWithoutArgs;
85 using testing::Mock;
86 using testing::Return;
87 using testing::SetArgPointee;
88 using testing::_;
90 namespace extensions {
92 typedef ExtensionDownloaderDelegate::Error Error;
93 typedef ExtensionDownloaderDelegate::PingResult PingResult;
95 namespace {
97 const net::BackoffEntry::Policy kNoBackoffPolicy = {
98 // Number of initial errors (in sequence) to ignore before applying
99 // exponential back-off rules.
100 1000,
102 // Initial delay for exponential back-off in ms.
105 // Factor by which the waiting time will be multiplied.
108 // Fuzzing percentage. ex: 10% will spread requests randomly
109 // between 90%-100% of the calculated time.
112 // Maximum amount of time we are willing to delay our request in ms.
115 // Time to keep an entry from being discarded even when it
116 // has no significant state, -1 to never discard.
119 // Don't use initial delay unless the last request was an error.
120 false,
123 const char kEmptyUpdateUrlData[] = "";
125 const char kAuthUserQueryKey[] = "authuser";
127 int kExpectedLoadFlags =
128 net::LOAD_DO_NOT_SEND_COOKIES |
129 net::LOAD_DO_NOT_SAVE_COOKIES |
130 net::LOAD_DISABLE_CACHE;
132 int kExpectedLoadFlagsForDownloadWithCookies = net::LOAD_DISABLE_CACHE;
134 // Fake authentication constants
135 const char kFakeAccountId[] = "bobloblaw@lawblog.example.com";
136 const char kFakeOAuth2Token[] = "ce n'est pas un jeton";
138 const ManifestFetchData::PingData kNeverPingedData(
139 ManifestFetchData::kNeverPinged,
140 ManifestFetchData::kNeverPinged,
141 true,
144 class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate {
145 public:
146 MOCK_METHOD4(OnExtensionDownloadFailed, void(const std::string&,
147 Error,
148 const PingResult&,
149 const std::set<int>&));
150 MOCK_METHOD7(OnExtensionDownloadFinished,
151 void(const extensions::CRXFileInfo&,
152 bool,
153 const GURL&,
154 const std::string&,
155 const PingResult&,
156 const std::set<int>&,
157 const InstallCallback&));
158 MOCK_METHOD2(GetPingDataForExtension,
159 bool(const std::string&, ManifestFetchData::PingData*));
160 MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&));
161 MOCK_METHOD1(IsExtensionPending, bool(const std::string&));
162 MOCK_METHOD2(GetExtensionExistingVersion,
163 bool(const std::string&, std::string*));
165 void Wait() {
166 scoped_refptr<content::MessageLoopRunner> runner =
167 new content::MessageLoopRunner;
168 quit_closure_ = runner->QuitClosure();
169 runner->Run();
170 quit_closure_.Reset();
173 void Quit() {
174 quit_closure_.Run();
177 void DelegateTo(ExtensionDownloaderDelegate* delegate) {
178 ON_CALL(*this, OnExtensionDownloadFailed(_, _, _, _))
179 .WillByDefault(Invoke(delegate,
180 &ExtensionDownloaderDelegate::OnExtensionDownloadFailed));
181 ON_CALL(*this, OnExtensionDownloadFinished(_, _, _, _, _, _, _))
182 .WillByDefault(
183 Invoke(delegate,
184 &ExtensionDownloaderDelegate::OnExtensionDownloadFinished));
185 ON_CALL(*this, GetPingDataForExtension(_, _))
186 .WillByDefault(Invoke(delegate,
187 &ExtensionDownloaderDelegate::GetPingDataForExtension));
188 ON_CALL(*this, GetUpdateUrlData(_))
189 .WillByDefault(Invoke(delegate,
190 &ExtensionDownloaderDelegate::GetUpdateUrlData));
191 ON_CALL(*this, IsExtensionPending(_))
192 .WillByDefault(Invoke(delegate,
193 &ExtensionDownloaderDelegate::IsExtensionPending));
194 ON_CALL(*this, GetExtensionExistingVersion(_, _))
195 .WillByDefault(Invoke(delegate,
196 &ExtensionDownloaderDelegate::GetExtensionExistingVersion));
199 private:
200 base::Closure quit_closure_;
203 const int kNotificationsObserved[] = {
204 extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED,
205 extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
208 // A class that observes the notifications sent by the ExtensionUpdater and
209 // the ExtensionDownloader.
210 class NotificationsObserver : public content::NotificationObserver {
211 public:
212 NotificationsObserver() {
213 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
214 count_[i] = 0;
215 registrar_.Add(this,
216 kNotificationsObserved[i],
217 content::NotificationService::AllSources());
221 ~NotificationsObserver() override {
222 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
223 registrar_.Remove(this,
224 kNotificationsObserved[i],
225 content::NotificationService::AllSources());
229 size_t StartedCount() { return count_[0]; }
230 size_t UpdatedCount() { return count_[1]; }
232 bool Updated(const std::string& id) {
233 return updated_.find(id) != updated_.end();
236 void Wait() {
237 scoped_refptr<content::MessageLoopRunner> runner =
238 new content::MessageLoopRunner;
239 quit_closure_ = runner->QuitClosure();
240 runner->Run();
241 quit_closure_.Reset();
244 private:
245 void Observe(int type,
246 const content::NotificationSource& source,
247 const content::NotificationDetails& details) override {
248 if (!quit_closure_.is_null())
249 quit_closure_.Run();
250 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
251 if (kNotificationsObserved[i] == type) {
252 count_[i]++;
253 if (type == extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND) {
254 updated_.insert(
255 content::Details<UpdateDetails>(details)->id);
257 return;
260 NOTREACHED();
263 content::NotificationRegistrar registrar_;
264 size_t count_[arraysize(kNotificationsObserved)];
265 std::set<std::string> updated_;
266 base::Closure quit_closure_;
268 DISALLOW_COPY_AND_ASSIGN(NotificationsObserver);
271 // Extracts the integer value of the |authuser| query parameter. Returns 0 if
272 // the parameter is not set.
273 int GetAuthUserQueryValue(const GURL& url) {
274 std::string query_string = url.query();
275 url::Component query(0, query_string.length());
276 url::Component key, value;
277 while (
278 url::ExtractQueryKeyValue(query_string.c_str(), &query, &key, &value)) {
279 std::string key_string = query_string.substr(key.begin, key.len);
280 if (key_string == kAuthUserQueryKey) {
281 int user_index = 0;
282 base::StringToInt(query_string.substr(value.begin, value.len),
283 &user_index);
284 return user_index;
287 return 0;
290 } // namespace
292 // Base class for further specialized test classes.
293 class MockService : public TestExtensionService {
294 public:
295 explicit MockService(TestExtensionPrefs* prefs)
296 : prefs_(prefs),
297 pending_extension_manager_(&profile_),
298 downloader_delegate_override_(NULL),
299 enable_metrics_(false) {}
301 ~MockService() override {}
303 PendingExtensionManager* pending_extension_manager() override {
304 ADD_FAILURE() << "Subclass should override this if it will "
305 << "be accessed by a test.";
306 return &pending_extension_manager_;
309 Profile* profile() { return &profile_; }
311 net::URLRequestContextGetter* request_context() {
312 return profile_.GetRequestContext();
315 ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
317 PrefService* pref_service() { return prefs_->pref_service(); }
319 FakeOAuth2TokenService* fake_token_service() {
320 return fake_token_service_.get();
323 // Controls whether metrics (enable/disabled state, etc.) are sent in the
324 // autoupdate ping requests.
325 void set_enable_metrics(bool enable) { enable_metrics_ = enable; }
327 // Creates test extensions and inserts them into list. The name and
328 // version are all based on their index. If |update_url| is non-null, it
329 // will be used as the update_url for each extension.
330 // The |id| is used to distinguish extension names and make sure that
331 // no two extensions share the same name.
332 void CreateTestExtensions(int id, int count, ExtensionList *list,
333 const std::string* update_url,
334 Manifest::Location location) {
335 for (int i = 1; i <= count; i++) {
336 base::DictionaryValue manifest;
337 manifest.SetString(manifest_keys::kVersion,
338 base::StringPrintf("%d.0.0.0", i));
339 manifest.SetString(manifest_keys::kName,
340 base::StringPrintf("Extension %d.%d", id, i));
341 if (update_url)
342 manifest.SetString(manifest_keys::kUpdateURL, *update_url);
343 scoped_refptr<Extension> e =
344 prefs_->AddExtensionWithManifest(manifest, location);
345 ASSERT_TRUE(e.get() != NULL);
346 list->push_back(e);
350 ExtensionDownloader::Factory GetDownloaderFactory() {
351 return base::Bind(&MockService::CreateExtensionDownloader,
352 base::Unretained(this));
355 ExtensionDownloader::Factory GetAuthenticatedDownloaderFactory() {
356 return base::Bind(&MockService::CreateExtensionDownloaderWithIdentity,
357 base::Unretained(this));
360 void OverrideDownloaderDelegate(ExtensionDownloaderDelegate* delegate) {
361 downloader_delegate_override_ = delegate;
364 protected:
365 TestExtensionPrefs* const prefs_;
366 TestingProfile profile_;
367 PendingExtensionManager pending_extension_manager_;
369 private:
370 scoped_ptr<ExtensionDownloader> CreateExtensionDownloader(
371 ExtensionDownloaderDelegate* delegate) {
372 scoped_ptr<ExtensionDownloader> downloader =
373 ChromeExtensionDownloaderFactory::CreateForRequestContext(
374 request_context(),
375 downloader_delegate_override_ ? downloader_delegate_override_
376 : delegate);
377 if (enable_metrics_)
378 downloader->set_enable_extra_update_metrics(true);
379 return downloader.Pass();
382 scoped_ptr<ExtensionDownloader> CreateExtensionDownloaderWithIdentity(
383 ExtensionDownloaderDelegate* delegate) {
384 scoped_ptr<FakeIdentityProvider> fake_identity_provider;
385 fake_token_service_.reset(new FakeOAuth2TokenService());
386 fake_identity_provider.reset(new FakeIdentityProvider(
387 fake_token_service_.get()));
388 fake_identity_provider->LogIn(kFakeAccountId);
389 fake_token_service_->AddAccount(kFakeAccountId);
391 scoped_ptr<ExtensionDownloader> downloader(
392 CreateExtensionDownloader(delegate));
393 downloader->SetWebstoreIdentityProvider(fake_identity_provider.Pass());
394 return downloader.Pass();
397 scoped_ptr<FakeOAuth2TokenService> fake_token_service_;
399 ExtensionDownloaderDelegate* downloader_delegate_override_;
401 bool enable_metrics_;
403 DISALLOW_COPY_AND_ASSIGN(MockService);
407 bool ShouldInstallExtensionsOnly(const Extension* extension) {
408 return extension->GetType() == Manifest::TYPE_EXTENSION;
411 bool ShouldInstallThemesOnly(const Extension* extension) {
412 return extension->is_theme();
415 bool ShouldAlwaysInstall(const Extension* extension) {
416 return true;
419 // Loads some pending extension records into a pending extension manager.
420 void SetupPendingExtensionManagerForTest(
421 int count,
422 const GURL& update_url,
423 PendingExtensionManager* pending_extension_manager) {
424 for (int i = 1; i <= count; ++i) {
425 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
426 (i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
427 const bool kIsFromSync = true;
428 const bool kMarkAcknowledged = false;
429 const bool kRemoteInstall = false;
430 std::string id =
431 crx_file::id_util::GenerateId(base::StringPrintf("extension%i", i));
433 pending_extension_manager->AddForTesting(
434 PendingExtensionInfo(id,
435 std::string(),
436 update_url,
437 Version(),
438 should_allow_install,
439 kIsFromSync,
440 Manifest::INTERNAL,
441 Extension::NO_FLAGS,
442 kMarkAcknowledged,
443 kRemoteInstall));
447 class ServiceForManifestTests : public MockService {
448 public:
449 explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
450 : MockService(prefs),
451 registry_(ExtensionRegistry::Get(profile())) {
454 ~ServiceForManifestTests() override {}
456 const Extension* GetExtensionById(const std::string& id,
457 bool include_disabled) const override {
458 const Extension* result = registry_->enabled_extensions().GetByID(id);
459 if (result || !include_disabled)
460 return result;
461 return registry_->disabled_extensions().GetByID(id);
464 PendingExtensionManager* pending_extension_manager() override {
465 return &pending_extension_manager_;
468 const Extension* GetPendingExtensionUpdate(
469 const std::string& id) const override {
470 return NULL;
473 bool IsExtensionEnabled(const std::string& id) const override {
474 return !registry_->disabled_extensions().Contains(id);
477 void set_extensions(ExtensionList extensions,
478 ExtensionList disabled_extensions) {
479 registry_->ClearAll();
480 for (ExtensionList::const_iterator it = extensions.begin();
481 it != extensions.end(); ++it) {
482 registry_->AddEnabled(*it);
484 for (ExtensionList::const_iterator it = disabled_extensions.begin();
485 it != disabled_extensions.end(); ++it) {
486 registry_->AddDisabled(*it);
490 private:
491 ExtensionRegistry* registry_;
494 class ServiceForDownloadTests : public MockService {
495 public:
496 explicit ServiceForDownloadTests(TestExtensionPrefs* prefs)
497 : MockService(prefs) {
500 // Add a fake crx installer to be returned by a call to UpdateExtension()
501 // with a specific ID. Caller keeps ownership of |crx_installer|.
502 void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) {
503 fake_crx_installers_[id] = crx_installer;
506 bool UpdateExtension(const CRXFileInfo& file,
507 bool file_ownership_passed,
508 CrxInstaller** out_crx_installer) override {
509 extension_id_ = file.extension_id;
510 install_path_ = file.path;
512 if (ContainsKey(fake_crx_installers_, extension_id_)) {
513 *out_crx_installer = fake_crx_installers_[extension_id_];
514 return true;
517 return false;
520 PendingExtensionManager* pending_extension_manager() override {
521 return &pending_extension_manager_;
524 const Extension* GetExtensionById(const std::string& id,
525 bool) const override {
526 last_inquired_extension_id_ = id;
527 return NULL;
530 const std::string& extension_id() const { return extension_id_; }
531 const base::FilePath& install_path() const { return install_path_; }
533 private:
534 // Hold the set of ids that UpdateExtension() should fake success on.
535 // UpdateExtension(id, ...) will return true iff fake_crx_installers_
536 // contains key |id|. |out_install_notification_source| will be set
537 // to Source<CrxInstaller(fake_crx_installers_[i]).
538 std::map<std::string, CrxInstaller*> fake_crx_installers_;
540 std::string extension_id_;
541 base::FilePath install_path_;
542 GURL download_url_;
544 // The last extension ID that GetExtensionById was called with.
545 // Mutable because the method that sets it (GetExtensionById) is const
546 // in the actual extension service, but must record the last extension
547 // ID in this test class.
548 mutable std::string last_inquired_extension_id_;
551 static const int kUpdateFrequencySecs = 15;
553 // Takes a string with KEY=VALUE parameters separated by '&' in |params| and
554 // puts the key/value pairs into |result|. For keys with no value, the empty
555 // string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
556 // "foo", and "c" to "".
557 static void ExtractParameters(const std::string& params,
558 std::map<std::string, std::string>* result) {
559 for (const std::string& pair : base::SplitString(
560 params, "&", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
561 std::vector<std::string> key_val = base::SplitString(
562 pair, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
563 if (!key_val.empty()) {
564 std::string key = key_val[0];
565 EXPECT_TRUE(result->find(key) == result->end());
566 (*result)[key] = (key_val.size() == 2) ? key_val[1] : std::string();
567 } else {
568 NOTREACHED();
573 // Helper function to extract the ping data param values for each extension in
574 // a manifest fetch url, returned in a map keyed by extension id.
575 // E.g. for "x=id%3Dabcdef%26ping%3Ddr%253D1%2526dr%253D1024" we'd return
576 // {"abcdef": {"dr": set("1", "1024")}}
577 typedef std::map<std::string, std::set<std::string>> ParamsMap;
578 static std::map<std::string, ParamsMap> GetPingDataFromURL(
579 const GURL& manifest_url) {
580 std::map<std::string, ParamsMap> result;
582 base::StringPairs toplevel_params;
583 base::SplitStringIntoKeyValuePairs(
584 manifest_url.query(), '=', '&', &toplevel_params);
585 for (const auto& param : toplevel_params) {
586 if (param.first != "x")
587 continue;
589 // We've found "x=<something>", now unescape <something> and look for
590 // the "id=<id>&ping=<ping_value>" parameters within.
591 std::string unescaped = net::UnescapeURLComponent(
592 param.second, net::UnescapeRule::URL_SPECIAL_CHARS);
593 base::StringPairs extension_params;
594 base::SplitStringIntoKeyValuePairs(unescaped, '=', '&', &extension_params);
595 std::multimap<std::string, std::string> param_map;
596 param_map.insert(extension_params.begin(), extension_params.end());
597 if (ContainsKey(param_map, "id") && ContainsKey(param_map, "ping")) {
598 std::string id = param_map.find("id")->second;
599 result[id] = ParamsMap();
601 // Pull the key=value pairs out of the ping parameter for this id and
602 // put into the result.
603 std::string ping = net::UnescapeURLComponent(
604 param_map.find("ping")->second, net::UnescapeRule::URL_SPECIAL_CHARS);
605 base::StringPairs ping_params;
606 base::SplitStringIntoKeyValuePairs(ping, '=', '&', &ping_params);
607 for (const auto& ping_param : ping_params) {
608 if (!ContainsKey(result[id], ping_param.first))
609 result[id][ping_param.first] = std::set<std::string>();
610 result[id][ping_param.first].insert(ping_param.second);
614 return result;
617 static void VerifyQueryAndExtractParameters(
618 const std::string& query,
619 std::map<std::string, std::string>* result) {
620 std::map<std::string, std::string> params;
621 ExtractParameters(query, &params);
623 std::string omaha_params = UpdateQueryParams::Get(UpdateQueryParams::CRX);
624 std::map<std::string, std::string> expected;
625 ExtractParameters(omaha_params, &expected);
627 for (std::map<std::string, std::string>::iterator it = expected.begin();
628 it != expected.end(); ++it) {
629 EXPECT_EQ(it->second, params[it->first]);
632 EXPECT_EQ(1U, params.count("x"));
633 std::string decoded = net::UnescapeURLComponent(
634 params["x"], net::UnescapeRule::URL_SPECIAL_CHARS);
635 ExtractParameters(decoded, result);
638 // All of our tests that need to use private APIs of ExtensionUpdater live
639 // inside this class (which is a friend to ExtensionUpdater).
640 class ExtensionUpdaterTest : public testing::Test {
641 public:
642 ExtensionUpdaterTest()
643 : thread_bundle_(
644 content::TestBrowserThreadBundle::IO_MAINLOOP),
645 testing_local_state_(TestingBrowserProcess::GetGlobal()) {
648 void SetUp() override {
649 prefs_.reset(new TestExtensionPrefs(base::ThreadTaskRunnerHandle::Get()));
652 void TearDown() override {
653 // Some tests create URLRequestContextGetters, whose destruction must run
654 // on the IO thread. Make sure the IO loop spins before shutdown so that
655 // those objects are released.
656 RunUntilIdle();
657 prefs_.reset();
660 void RunUntilIdle() {
661 prefs_->pref_service()->CommitPendingWrite();
662 base::RunLoop().RunUntilIdle();
665 void SimulateTimerFired(ExtensionUpdater* updater) {
666 EXPECT_TRUE(updater->timer_.IsRunning());
667 updater->timer_.Stop();
668 updater->TimerFired();
669 content::RunAllBlockingPoolTasksUntilIdle();
672 // Adds a Result with the given data to results.
673 void AddParseResult(const std::string& id,
674 const std::string& version,
675 const std::string& url,
676 UpdateManifest::Results* results) {
677 UpdateManifest::Result result;
678 result.extension_id = id;
679 result.version = version;
680 result.crx_url = GURL(url);
681 results->list.push_back(result);
684 void StartUpdateCheck(ExtensionDownloader* downloader,
685 ManifestFetchData* fetch_data) {
686 downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data));
689 size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
690 return downloader->manifests_queue_.size() +
691 (downloader->manifest_fetcher_.get() ? 1 : 0);
694 void TestExtensionUpdateCheckRequests(bool pending) {
695 // Create an extension with an update_url.
696 ServiceForManifestTests service(prefs_.get());
697 std::string update_url("http://foo.com/bar");
698 ExtensionList extensions;
699 NotificationsObserver observer;
700 PendingExtensionManager* pending_extension_manager =
701 service.pending_extension_manager();
702 if (pending) {
703 SetupPendingExtensionManagerForTest(1, GURL(update_url),
704 pending_extension_manager);
705 } else {
706 service.CreateTestExtensions(1, 1, &extensions, &update_url,
707 Manifest::INTERNAL);
708 service.set_extensions(extensions, ExtensionList());
711 // Set up and start the updater.
712 net::TestURLFetcherFactory factory;
713 ExtensionUpdater updater(&service,
714 service.extension_prefs(),
715 service.pref_service(),
716 service.profile(),
717 60 * 60 * 24,
718 NULL,
719 service.GetDownloaderFactory());
720 updater.Start();
722 // Tell the update that it's time to do update checks.
723 EXPECT_EQ(0u, observer.StartedCount());
724 SimulateTimerFired(&updater);
725 EXPECT_EQ(1u, observer.StartedCount());
727 // Get the url our mock fetcher was asked to fetch.
728 net::TestURLFetcher* fetcher =
729 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
730 const GURL& url = fetcher->GetOriginalURL();
731 EXPECT_FALSE(url.is_empty());
732 EXPECT_TRUE(url.is_valid());
733 EXPECT_TRUE(url.SchemeIs("http"));
734 EXPECT_EQ("foo.com", url.host());
735 EXPECT_EQ("/bar", url.path());
737 // Validate the extension request parameters in the query. It should
738 // look something like "x=id%3D<id>%26v%3D<version>%26uc".
739 EXPECT_TRUE(url.has_query());
740 std::map<std::string, std::string> params;
741 VerifyQueryAndExtractParameters(url.query(), &params);
742 if (pending) {
743 EXPECT_TRUE(pending_extension_manager->IsIdPending(params["id"]));
744 EXPECT_EQ("0.0.0.0", params["v"]);
745 } else {
746 EXPECT_EQ(extensions[0]->id(), params["id"]);
747 EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
749 EXPECT_EQ("", params["uc"]);
752 void TestUpdateUrlDataEmpty() {
753 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
754 const std::string version = "1.0";
756 // Make sure that an empty update URL data string does not cause a ap=
757 // option to appear in the x= parameter.
758 scoped_ptr<ManifestFetchData> fetch_data(
759 CreateManifestFetchData(GURL("http://localhost/foo")));
760 fetch_data->AddExtension(
761 id, version, &kNeverPingedData, std::string(), std::string(), false);
763 std::map<std::string, std::string> params;
764 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
765 EXPECT_EQ(id, params["id"]);
766 EXPECT_EQ(version, params["v"]);
767 EXPECT_EQ(0U, params.count("ap"));
770 void TestUpdateUrlDataSimple() {
771 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
772 const std::string version = "1.0";
774 // Make sure that an update URL data string causes an appropriate ap=
775 // option to appear in the x= parameter.
776 scoped_ptr<ManifestFetchData> fetch_data(
777 CreateManifestFetchData(GURL("http://localhost/foo")));
778 fetch_data->AddExtension(
779 id, version, &kNeverPingedData, "bar", std::string(), false);
780 std::map<std::string, std::string> params;
781 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
782 EXPECT_EQ(id, params["id"]);
783 EXPECT_EQ(version, params["v"]);
784 EXPECT_EQ("bar", params["ap"]);
787 void TestUpdateUrlDataCompound() {
788 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
789 const std::string version = "1.0";
791 // Make sure that an update URL data string causes an appropriate ap=
792 // option to appear in the x= parameter.
793 scoped_ptr<ManifestFetchData> fetch_data(
794 CreateManifestFetchData(GURL("http://localhost/foo")));
795 fetch_data->AddExtension(
796 id, version, &kNeverPingedData, "a=1&b=2&c", std::string(), false);
797 std::map<std::string, std::string> params;
798 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
799 EXPECT_EQ(id, params["id"]);
800 EXPECT_EQ(version, params["v"]);
801 EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]);
804 void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
805 net::TestURLFetcherFactory factory;
807 MockService service(prefs_.get());
808 MockExtensionDownloaderDelegate delegate;
809 ExtensionDownloader downloader(&delegate, service.request_context());
810 ExtensionList extensions;
811 std::string url(gallery_url);
813 service.CreateTestExtensions(1, 1, &extensions, &url, Manifest::INTERNAL);
815 const std::string& id = extensions[0]->id();
816 EXPECT_CALL(delegate, GetPingDataForExtension(id, _));
818 downloader.AddExtension(*extensions[0].get(), 0);
819 downloader.StartAllPending(NULL);
820 net::TestURLFetcher* fetcher =
821 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
822 ASSERT_TRUE(fetcher);
823 // Make sure that extensions that update from the gallery ignore any
824 // update URL data.
825 const std::string& update_url = fetcher->GetOriginalURL().spec();
826 std::string::size_type x = update_url.find("x=");
827 EXPECT_NE(std::string::npos, x);
828 std::string::size_type ap = update_url.find("ap%3D", x);
829 EXPECT_EQ(std::string::npos, ap);
832 void TestInstallSource() {
833 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
834 const std::string version = "1.0";
835 const std::string install_source = "instally";
837 // Make sure that an installsource= appears in the x= parameter.
838 scoped_ptr<ManifestFetchData> fetch_data(
839 CreateManifestFetchData(GURL("http://localhost/foo")));
840 fetch_data->AddExtension(id, version, &kNeverPingedData,
841 kEmptyUpdateUrlData, install_source, false);
842 std::map<std::string, std::string> params;
843 VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
844 EXPECT_EQ(id, params["id"]);
845 EXPECT_EQ(version, params["v"]);
846 EXPECT_EQ(install_source, params["installsource"]);
849 void TestDetermineUpdates() {
850 TestingProfile profile;
851 MockExtensionDownloaderDelegate delegate;
852 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
854 // Check passing an empty list of parse results to DetermineUpdates
855 scoped_ptr<ManifestFetchData> fetch_data(
856 CreateManifestFetchData(GURL("http://localhost/foo")));
857 UpdateManifest::Results updates;
858 std::vector<int> updateable;
859 downloader.DetermineUpdates(*fetch_data, updates, &updateable);
860 EXPECT_TRUE(updateable.empty());
862 // Create two updates - expect that DetermineUpdates will return the first
863 // one (v1.0 installed, v1.1 available) but not the second one (both
864 // installed and available at v2.0).
865 const std::string id1 = crx_file::id_util::GenerateId("1");
866 const std::string id2 = crx_file::id_util::GenerateId("2");
867 fetch_data->AddExtension(
868 id1, "1.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string(),
869 false);
870 AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);
871 fetch_data->AddExtension(
872 id2, "2.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string(),
873 false);
874 AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);
876 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
877 EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
878 .WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"),
879 Return(true)));
880 EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
881 .WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"),
882 Return(true)));
884 downloader.DetermineUpdates(*fetch_data, updates, &updateable);
885 EXPECT_EQ(1u, updateable.size());
886 EXPECT_EQ(0, updateable[0]);
889 void TestDetermineUpdatesPending() {
890 // Create a set of test extensions
891 ServiceForManifestTests service(prefs_.get());
892 PendingExtensionManager* pending_extension_manager =
893 service.pending_extension_manager();
894 SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
896 TestingProfile profile;
897 MockExtensionDownloaderDelegate delegate;
898 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
900 scoped_ptr<ManifestFetchData> fetch_data(
901 CreateManifestFetchData(GURL("http://localhost/foo")));
902 UpdateManifest::Results updates;
904 std::list<std::string> ids_for_update_check;
905 pending_extension_manager->GetPendingIdsForUpdateCheck(
906 &ids_for_update_check);
908 std::list<std::string>::const_iterator it;
909 for (it = ids_for_update_check.begin();
910 it != ids_for_update_check.end(); ++it) {
911 fetch_data->AddExtension(*it,
912 "1.0.0.0",
913 &kNeverPingedData,
914 kEmptyUpdateUrlData,
915 std::string(),
916 false);
917 AddParseResult(*it, "1.1", "http://localhost/e1_1.1.crx", &updates);
920 // The delegate will tell the downloader that all the extensions are
921 // pending.
922 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(true));
924 std::vector<int> updateable;
925 downloader.DetermineUpdates(*fetch_data, updates, &updateable);
926 // All the apps should be updateable.
927 EXPECT_EQ(3u, updateable.size());
928 for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) {
929 EXPECT_EQ(static_cast<int>(i), updateable[i]);
933 void TestMultipleManifestDownloading() {
934 net::TestURLFetcherFactory factory;
935 factory.set_remove_fetcher_on_delete(true);
936 net::TestURLFetcher* fetcher = NULL;
937 MockService service(prefs_.get());
938 MockExtensionDownloaderDelegate delegate;
939 ExtensionDownloader downloader(&delegate, service.request_context());
940 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
942 GURL kUpdateUrl("http://localhost/manifest1");
944 scoped_ptr<ManifestFetchData> fetch1(CreateManifestFetchData(kUpdateUrl));
945 scoped_ptr<ManifestFetchData> fetch2(CreateManifestFetchData(kUpdateUrl));
946 scoped_ptr<ManifestFetchData> fetch3(CreateManifestFetchData(kUpdateUrl));
947 scoped_ptr<ManifestFetchData> fetch4(CreateManifestFetchData(kUpdateUrl));
948 ManifestFetchData::PingData zeroDays(0, 0, true, 0);
949 fetch1->AddExtension(
950 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
951 fetch2->AddExtension(
952 "2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
953 fetch3->AddExtension(
954 "3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
955 fetch4->AddExtension(
956 "4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
958 // This will start the first fetcher and queue the others. The next in queue
959 // is started as each fetcher receives its response. Note that the fetchers
960 // don't necessarily run in the order that they are started from here.
961 GURL fetch1_url = fetch1->full_url();
962 GURL fetch2_url = fetch2->full_url();
963 GURL fetch3_url = fetch3->full_url();
964 GURL fetch4_url = fetch4->full_url();
965 downloader.StartUpdateCheck(fetch1.Pass());
966 downloader.StartUpdateCheck(fetch2.Pass());
967 downloader.StartUpdateCheck(fetch3.Pass());
968 downloader.StartUpdateCheck(fetch4.Pass());
969 RunUntilIdle();
971 for (int i = 0; i < 4; ++i) {
972 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
973 ASSERT_TRUE(fetcher);
974 ASSERT_TRUE(fetcher->delegate());
975 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
976 EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
978 if (fetcher->GetOriginalURL() == fetch1_url) {
979 // The first fetch will fail.
980 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
981 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
982 fetcher->set_url(kUpdateUrl);
983 fetcher->set_status(net::URLRequestStatus());
984 fetcher->set_response_code(400);
985 fetcher->delegate()->OnURLFetchComplete(fetcher);
986 RunUntilIdle();
987 Mock::VerifyAndClearExpectations(&delegate);
988 fetch1_url = GURL();
989 } else if (fetcher->GetOriginalURL() == fetch2_url) {
990 // The second fetch gets invalid data.
991 const std::string kInvalidXml = "invalid xml";
992 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
993 "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _))
994 .WillOnce(InvokeWithoutArgs(
995 &delegate,
996 &MockExtensionDownloaderDelegate::Quit));
997 fetcher->set_url(kUpdateUrl);
998 fetcher->set_status(net::URLRequestStatus());
999 fetcher->set_response_code(200);
1000 fetcher->SetResponseString(kInvalidXml);
1001 fetcher->delegate()->OnURLFetchComplete(fetcher);
1002 delegate.Wait();
1003 Mock::VerifyAndClearExpectations(&delegate);
1004 fetch2_url = GURL();
1005 } else if (fetcher->GetOriginalURL() == fetch3_url) {
1006 // The third fetcher doesn't have an update available.
1007 const std::string kNoUpdate =
1008 "<?xml version='1.0' encoding='UTF-8'?>"
1009 "<gupdate xmlns='http://www.google.com/update2/response'"
1010 " protocol='2.0'>"
1011 " <app appid='3333'>"
1012 " <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'"
1013 " version='3.0.0.0' prodversionmin='3.0.0.0' />"
1014 " </app>"
1015 "</gupdate>";
1016 EXPECT_CALL(delegate, IsExtensionPending("3333"))
1017 .WillOnce(Return(false));
1018 EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _))
1019 .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"),
1020 Return(true)));
1021 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
1022 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _))
1023 .WillOnce(InvokeWithoutArgs(
1024 &delegate,
1025 &MockExtensionDownloaderDelegate::Quit));
1026 fetcher->set_url(kUpdateUrl);
1027 fetcher->set_status(net::URLRequestStatus());
1028 fetcher->set_response_code(200);
1029 fetcher->SetResponseString(kNoUpdate);
1030 fetcher->delegate()->OnURLFetchComplete(fetcher);
1031 delegate.Wait();
1032 Mock::VerifyAndClearExpectations(&delegate);
1033 fetch3_url = GURL();
1034 } else if (fetcher->GetOriginalURL() == fetch4_url) {
1035 // The last fetcher has an update.
1036 NotificationsObserver observer;
1037 const std::string kUpdateAvailable =
1038 "<?xml version='1.0' encoding='UTF-8'?>"
1039 "<gupdate xmlns='http://www.google.com/update2/response'"
1040 " protocol='2.0'>"
1041 " <app appid='4444'>"
1042 " <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
1043 " version='4.0.42.0' prodversionmin='4.0.42.0' />"
1044 " </app>"
1045 "</gupdate>";
1046 EXPECT_CALL(delegate, IsExtensionPending("4444"))
1047 .WillOnce(Return(false));
1048 EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _))
1049 .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"),
1050 Return(true)));
1051 fetcher->set_url(kUpdateUrl);
1052 fetcher->set_status(net::URLRequestStatus());
1053 fetcher->set_response_code(200);
1054 fetcher->SetResponseString(kUpdateAvailable);
1055 fetcher->delegate()->OnURLFetchComplete(fetcher);
1056 observer.Wait();
1057 Mock::VerifyAndClearExpectations(&delegate);
1059 // Verify that the downloader decided to update this extension.
1060 EXPECT_EQ(1u, observer.UpdatedCount());
1061 EXPECT_TRUE(observer.Updated("4444"));
1062 fetch4_url = GURL();
1063 } else {
1064 ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL();
1068 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1069 if (fetcher)
1070 ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL();
1073 void TestManifestRetryDownloading() {
1074 net::TestURLFetcherFactory factory;
1075 net::TestURLFetcher* fetcher = NULL;
1076 NotificationsObserver observer;
1077 MockService service(prefs_.get());
1078 MockExtensionDownloaderDelegate delegate;
1079 ExtensionDownloader downloader(&delegate, service.request_context());
1080 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
1082 GURL kUpdateUrl("http://localhost/manifest1");
1084 scoped_ptr<ManifestFetchData> fetch(CreateManifestFetchData(kUpdateUrl));
1085 ManifestFetchData::PingData zeroDays(0, 0, true, 0);
1086 fetch->AddExtension(
1087 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
1089 // This will start the first fetcher.
1090 downloader.StartUpdateCheck(fetch.Pass());
1091 RunUntilIdle();
1093 // ExtensionDownloader should retry kMaxRetries times and then fail.
1094 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
1095 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
1096 for (int i = 0; i <= ExtensionDownloader::kMaxRetries; ++i) {
1097 // All fetches will fail.
1098 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1099 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1100 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1101 fetcher->set_url(kUpdateUrl);
1102 fetcher->set_status(net::URLRequestStatus());
1103 // Code 5xx causes ExtensionDownloader to retry.
1104 fetcher->set_response_code(500);
1105 fetcher->delegate()->OnURLFetchComplete(fetcher);
1106 RunUntilIdle();
1108 Mock::VerifyAndClearExpectations(&delegate);
1111 // For response codes that are not in the 5xx range ExtensionDownloader
1112 // should not retry.
1113 fetch.reset(CreateManifestFetchData(kUpdateUrl));
1114 fetch->AddExtension(
1115 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
1117 // This will start the first fetcher.
1118 downloader.StartUpdateCheck(fetch.Pass());
1119 RunUntilIdle();
1121 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
1122 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
1123 // The first fetch will fail, and require retrying.
1124 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1125 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1126 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1127 fetcher->set_url(kUpdateUrl);
1128 fetcher->set_status(net::URLRequestStatus());
1129 fetcher->set_response_code(500);
1130 fetcher->delegate()->OnURLFetchComplete(fetcher);
1131 RunUntilIdle();
1133 // The second fetch will fail with response 400 and should not cause
1134 // ExtensionDownloader to retry.
1135 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1136 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1137 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1138 fetcher->set_url(kUpdateUrl);
1139 fetcher->set_status(net::URLRequestStatus());
1140 fetcher->set_response_code(400);
1141 fetcher->delegate()->OnURLFetchComplete(fetcher);
1142 RunUntilIdle();
1144 Mock::VerifyAndClearExpectations(&delegate);
1147 void TestSingleExtensionDownloading(bool pending, bool retry, bool fail) {
1148 net::TestURLFetcherFactory factory;
1149 net::TestURLFetcher* fetcher = NULL;
1150 scoped_ptr<ServiceForDownloadTests> service(
1151 new ServiceForDownloadTests(prefs_.get()));
1152 ExtensionUpdater updater(service.get(),
1153 service->extension_prefs(),
1154 service->pref_service(),
1155 service->profile(),
1156 kUpdateFrequencySecs,
1157 NULL,
1158 service->GetDownloaderFactory());
1159 MockExtensionDownloaderDelegate delegate;
1160 delegate.DelegateTo(&updater);
1161 service->OverrideDownloaderDelegate(&delegate);
1162 updater.Start();
1163 updater.EnsureDownloaderCreated();
1164 updater.downloader_->extensions_queue_.set_backoff_policy(
1165 &kNoBackoffPolicy);
1167 GURL test_url("http://localhost/extension.crx");
1169 std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1170 std::string hash;
1171 Version version("0.0.1");
1172 std::set<int> requests;
1173 requests.insert(0);
1174 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
1175 new ExtensionDownloader::ExtensionFetch(
1176 id, test_url, hash, version.GetString(), requests));
1177 updater.downloader_->FetchUpdatedExtension(fetch.Pass());
1179 if (pending) {
1180 const bool kIsFromSync = true;
1181 const bool kMarkAcknowledged = false;
1182 const bool kRemoteInstall = false;
1183 PendingExtensionManager* pending_extension_manager =
1184 service->pending_extension_manager();
1185 pending_extension_manager->AddForTesting(
1186 PendingExtensionInfo(id,
1187 std::string(),
1188 test_url,
1189 version,
1190 &ShouldAlwaysInstall,
1191 kIsFromSync,
1192 Manifest::INTERNAL,
1193 Extension::NO_FLAGS,
1194 kMarkAcknowledged,
1195 kRemoteInstall));
1198 // Call back the ExtensionUpdater with a 200 response and some test data
1199 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1200 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1201 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1202 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1204 if (retry) {
1205 // Reply with response code 500 to cause ExtensionDownloader to retry
1206 fetcher->set_url(test_url);
1207 fetcher->set_status(net::URLRequestStatus());
1208 fetcher->set_response_code(500);
1209 fetcher->delegate()->OnURLFetchComplete(fetcher);
1211 RunUntilIdle();
1212 fetcher = factory.GetFetcherByID(
1213 ExtensionDownloader::kExtensionFetcherId);
1214 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1215 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1218 fetcher->set_url(test_url);
1219 fetcher->set_status(net::URLRequestStatus());
1220 if (fail) {
1221 fetcher->set_response_code(404);
1222 EXPECT_CALL(delegate, OnExtensionDownloadFailed(id, _, _, requests));
1223 } else {
1224 fetcher->set_response_code(200);
1225 fetcher->SetResponseFilePath(extension_file_path);
1226 EXPECT_CALL(delegate, OnExtensionDownloadFinished(
1227 CRXFileInfo(id, extension_file_path, hash), _,
1228 _, version.GetString(), _, requests, _));
1230 fetcher->delegate()->OnURLFetchComplete(fetcher);
1232 RunUntilIdle();
1234 if (fail) {
1235 // Don't expect any extension to have been installed.
1236 EXPECT_TRUE(service->extension_id().empty());
1237 } else {
1238 // Expect that ExtensionUpdater asked the mock extensions service to
1239 // install a file with the test data for the right id.
1240 EXPECT_EQ(id, service->extension_id());
1241 base::FilePath tmpfile_path = service->install_path();
1242 EXPECT_FALSE(tmpfile_path.empty());
1243 EXPECT_EQ(extension_file_path, tmpfile_path);
1247 // Update a single extension in an environment where the download request
1248 // initially responds with a 403 status. If |identity_provider| is not NULL,
1249 // this will first expect a request which includes an Authorization header
1250 // with an OAuth2 bearer token; otherwise, or if OAuth2 failure is simulated,
1251 // this expects the downloader to fall back onto cookie-based credentials.
1252 void TestProtectedDownload(
1253 const std::string& url_prefix,
1254 bool enable_oauth2,
1255 bool succeed_with_oauth2,
1256 int valid_authuser,
1257 int max_authuser) {
1258 net::TestURLFetcherFactory factory;
1259 net::TestURLFetcher* fetcher = NULL;
1260 scoped_ptr<ServiceForDownloadTests> service(
1261 new ServiceForDownloadTests(prefs_.get()));
1262 const ExtensionDownloader::Factory& downloader_factory =
1263 enable_oauth2 ? service->GetAuthenticatedDownloaderFactory()
1264 : service->GetDownloaderFactory();
1265 ExtensionUpdater updater(
1266 service.get(),
1267 service->extension_prefs(),
1268 service->pref_service(),
1269 service->profile(),
1270 kUpdateFrequencySecs,
1271 NULL,
1272 downloader_factory);
1273 updater.Start();
1274 updater.EnsureDownloaderCreated();
1275 updater.downloader_->extensions_queue_.set_backoff_policy(
1276 &kNoBackoffPolicy);
1278 GURL test_url(base::StringPrintf("%s/extension.crx", url_prefix.c_str()));
1279 std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1280 std::string hash;
1281 Version version("0.0.1");
1282 std::set<int> requests;
1283 requests.insert(0);
1284 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
1285 new ExtensionDownloader::ExtensionFetch(
1286 id, test_url, hash, version.GetString(), requests));
1287 updater.downloader_->FetchUpdatedExtension(fetch.Pass());
1289 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1290 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1291 EXPECT_EQ(kExpectedLoadFlags, fetcher->GetLoadFlags());
1293 // Fake a 403 response.
1294 fetcher->set_url(test_url);
1295 fetcher->set_status(net::URLRequestStatus());
1296 fetcher->set_response_code(403);
1297 fetcher->delegate()->OnURLFetchComplete(fetcher);
1299 if (service->fake_token_service()) {
1300 service->fake_token_service()->IssueAllTokensForAccount(
1301 kFakeAccountId, kFakeOAuth2Token, base::Time::Now());
1303 RunUntilIdle();
1305 bool using_oauth2 = false;
1306 int expected_load_flags = kExpectedLoadFlags;
1307 // Verify that the fetch has had its credentials properly incremented.
1308 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1309 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1310 net::HttpRequestHeaders fetch_headers;
1311 fetcher->GetExtraRequestHeaders(&fetch_headers);
1312 // If the download URL is not https, no credentials should be provided.
1313 if (!test_url.SchemeIsCryptographic()) {
1314 // No cookies.
1315 EXPECT_EQ(kExpectedLoadFlags, fetcher->GetLoadFlags());
1316 // No Authorization header.
1317 EXPECT_FALSE(fetch_headers.HasHeader(
1318 net::HttpRequestHeaders::kAuthorization));
1319 expected_load_flags = kExpectedLoadFlags;
1320 } else {
1321 // HTTPS is in use, so credentials are allowed.
1322 if (enable_oauth2 && test_url.DomainIs("google.com")) {
1323 // If an IdentityProvider is present and the URL is a google.com
1324 // URL, the fetcher should be in OAuth2 mode after the intitial
1325 // challenge.
1326 EXPECT_TRUE(fetch_headers.HasHeader(
1327 net::HttpRequestHeaders::kAuthorization));
1328 std::string expected_header_value = base::StringPrintf("Bearer %s",
1329 kFakeOAuth2Token);
1330 std::string actual_header_value;
1331 fetch_headers.GetHeader(net::HttpRequestHeaders::kAuthorization,
1332 &actual_header_value);
1333 EXPECT_EQ(expected_header_value, actual_header_value);
1334 using_oauth2 = true;
1335 } else {
1336 // No IdentityProvider (or no google.com), so expect cookies instead of
1337 // an Authorization header.
1338 EXPECT_FALSE(fetch_headers.HasHeader(
1339 net::HttpRequestHeaders::kAuthorization));
1340 EXPECT_EQ(kExpectedLoadFlagsForDownloadWithCookies,
1341 fetcher->GetLoadFlags());
1342 expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
1346 bool success = false;
1347 if (using_oauth2) {
1348 if (succeed_with_oauth2) {
1349 success = true;
1350 } else {
1351 // Simulate OAuth2 failure and ensure that we fall back on cookies.
1352 fetcher->set_url(test_url);
1353 fetcher->set_status(net::URLRequestStatus());
1354 fetcher->set_response_code(403);
1355 fetcher->delegate()->OnURLFetchComplete(fetcher);
1356 RunUntilIdle();
1358 const ExtensionDownloader::ExtensionFetch& fetch =
1359 *updater.downloader_->extensions_queue_.active_request();
1360 EXPECT_EQ(0, GetAuthUserQueryValue(fetch.url));
1361 EXPECT_EQ(ExtensionDownloader::ExtensionFetch::CREDENTIALS_COOKIES,
1362 fetch.credentials);
1364 fetcher = factory.GetFetcherByID(
1365 ExtensionDownloader::kExtensionFetcherId);
1366 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1367 fetcher->GetExtraRequestHeaders(&fetch_headers);
1368 EXPECT_FALSE(fetch_headers.HasHeader(
1369 net::HttpRequestHeaders::kAuthorization));
1370 EXPECT_EQ(kExpectedLoadFlagsForDownloadWithCookies,
1371 fetcher->GetLoadFlags());
1372 expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
1376 if (!success) {
1377 // Not yet ready to simulate a successful fetch. At this point we begin
1378 // simulating cookie-based authentication with increasing values of
1379 // authuser (starting from 0.)
1380 int user_index = 0;
1381 for (; user_index <= max_authuser; ++user_index) {
1382 const ExtensionDownloader::ExtensionFetch& fetch =
1383 *updater.downloader_->extensions_queue_.active_request();
1384 EXPECT_EQ(user_index, GetAuthUserQueryValue(fetch.url));
1385 if (user_index == valid_authuser) {
1386 success = true;
1387 break;
1389 // Simulate an authorization failure which should elicit an increment
1390 // of the authuser value.
1391 fetcher =
1392 factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1393 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1394 EXPECT_EQ(expected_load_flags, fetcher->GetLoadFlags());
1395 fetcher->set_url(fetch.url);
1396 fetcher->set_status(net::URLRequestStatus());
1397 fetcher->set_response_code(403);
1398 fetcher->delegate()->OnURLFetchComplete(fetcher);
1399 RunUntilIdle();
1402 // Simulate exhaustion of all available authusers.
1403 if (!success && user_index > max_authuser) {
1404 const ExtensionDownloader::ExtensionFetch& fetch =
1405 *updater.downloader_->extensions_queue_.active_request();
1406 fetcher =
1407 factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1408 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1409 fetcher->set_url(fetch.url);
1410 fetcher->set_status(net::URLRequestStatus());
1411 fetcher->set_response_code(401);
1412 fetcher->delegate()->OnURLFetchComplete(fetcher);
1413 RunUntilIdle();
1417 // Simulate successful authorization with a 200 response.
1418 if (success) {
1419 fetcher =
1420 factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1421 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1422 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1423 fetcher->set_url(test_url);
1424 fetcher->set_status(net::URLRequestStatus());
1425 fetcher->set_response_code(200);
1426 fetcher->SetResponseFilePath(extension_file_path);
1427 fetcher->delegate()->OnURLFetchComplete(fetcher);
1428 RunUntilIdle();
1430 // Verify installation would proceed as normal.
1431 EXPECT_EQ(id, service->extension_id());
1432 base::FilePath tmpfile_path = service->install_path();
1433 EXPECT_FALSE(tmpfile_path.empty());
1434 EXPECT_EQ(extension_file_path, tmpfile_path);
1438 // Two extensions are updated. If |updates_start_running| is true, the
1439 // mock extensions service has UpdateExtension(...) return true, and
1440 // the test is responsible for creating fake CrxInstallers. Otherwise,
1441 // UpdateExtension() returns false, signaling install failures.
1442 void TestMultipleExtensionDownloading(bool updates_start_running) {
1443 net::TestURLFetcherFactory factory;
1444 net::TestURLFetcher* fetcher = NULL;
1445 ServiceForDownloadTests service(prefs_.get());
1446 ExtensionUpdater updater(&service,
1447 service.extension_prefs(),
1448 service.pref_service(),
1449 service.profile(),
1450 kUpdateFrequencySecs,
1451 NULL,
1452 service.GetDownloaderFactory());
1453 updater.Start();
1454 updater.EnsureDownloaderCreated();
1455 updater.downloader_->extensions_queue_.set_backoff_policy(
1456 &kNoBackoffPolicy);
1458 EXPECT_FALSE(updater.crx_install_is_running_);
1460 GURL url1("http://localhost/extension1.crx");
1461 GURL url2("http://localhost/extension2.crx");
1463 std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1464 std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
1466 std::string hash1;
1467 std::string hash2;
1469 std::string version1 = "0.1";
1470 std::string version2 = "0.1";
1471 std::set<int> requests;
1472 requests.insert(0);
1473 // Start two fetches
1474 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch1(
1475 new ExtensionDownloader::ExtensionFetch(
1476 id1, url1, hash1, version1, requests));
1477 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch2(
1478 new ExtensionDownloader::ExtensionFetch(
1479 id2, url2, hash2, version2, requests));
1480 updater.downloader_->FetchUpdatedExtension(fetch1.Pass());
1481 updater.downloader_->FetchUpdatedExtension(fetch2.Pass());
1483 // Make the first fetch complete.
1484 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1486 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1487 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1488 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1490 // We need some CrxInstallers, and CrxInstallers require a real
1491 // ExtensionService. Create one on the testing profile. Any action
1492 // the CrxInstallers take is on the testing profile's extension
1493 // service, not on our mock |service|. This allows us to fake
1494 // the CrxInstaller actions we want.
1495 TestingProfile profile;
1496 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(&profile))
1497 ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
1498 base::FilePath(), false);
1499 ExtensionService* extension_service =
1500 ExtensionSystem::Get(&profile)->extension_service();
1501 extension_service->set_extensions_enabled(true);
1502 extension_service->set_show_extensions_prompts(false);
1504 scoped_refptr<CrxInstaller> fake_crx1(
1505 CrxInstaller::CreateSilent(extension_service));
1506 scoped_refptr<CrxInstaller> fake_crx2(
1507 CrxInstaller::CreateSilent(extension_service));
1509 if (updates_start_running) {
1510 // Add fake CrxInstaller to be returned by service.UpdateExtension().
1511 service.AddFakeCrxInstaller(id1, fake_crx1.get());
1512 service.AddFakeCrxInstaller(id2, fake_crx2.get());
1513 } else {
1514 // If we don't add fake CRX installers, the mock service fakes a failure
1515 // starting the install.
1518 fetcher->set_url(url1);
1519 fetcher->set_status(net::URLRequestStatus());
1520 fetcher->set_response_code(200);
1521 fetcher->SetResponseFilePath(extension_file_path);
1522 fetcher->delegate()->OnURLFetchComplete(fetcher);
1524 RunUntilIdle();
1526 // Expect that the service was asked to do an install with the right data.
1527 base::FilePath tmpfile_path = service.install_path();
1528 EXPECT_FALSE(tmpfile_path.empty());
1529 EXPECT_EQ(id1, service.extension_id());
1530 RunUntilIdle();
1532 // Make sure the second fetch finished and asked the service to do an
1533 // update.
1534 base::FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2"));
1535 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1536 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1537 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1539 fetcher->set_url(url2);
1540 fetcher->set_status(net::URLRequestStatus());
1541 fetcher->set_response_code(200);
1542 fetcher->SetResponseFilePath(extension_file_path2);
1543 fetcher->delegate()->OnURLFetchComplete(fetcher);
1544 RunUntilIdle();
1546 if (updates_start_running) {
1547 EXPECT_TRUE(updater.crx_install_is_running_);
1549 // The second install should not have run, because the first has not
1550 // sent a notification that it finished.
1551 EXPECT_EQ(id1, service.extension_id());
1553 // Fake install notice. This should start the second installation,
1554 // which will be checked below.
1555 fake_crx1->NotifyCrxInstallComplete(false);
1557 EXPECT_TRUE(updater.crx_install_is_running_);
1560 EXPECT_EQ(id2, service.extension_id());
1561 EXPECT_FALSE(service.install_path().empty());
1563 // Make sure the correct crx contents were passed for the update call.
1564 EXPECT_EQ(extension_file_path2, service.install_path());
1566 if (updates_start_running) {
1567 EXPECT_TRUE(updater.crx_install_is_running_);
1568 fake_crx2->NotifyCrxInstallComplete(false);
1570 EXPECT_FALSE(updater.crx_install_is_running_);
1573 void TestGalleryRequestsWithBrand(bool use_organic_brand_code) {
1574 google_brand::BrandForTesting brand_for_testing(
1575 use_organic_brand_code ? "GGLS" : "TEST");
1577 // We want to test a variety of combinations of expected ping conditions for
1578 // rollcall and active pings.
1579 int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
1581 for (size_t i = 0; i < arraysize(ping_cases); i++) {
1582 for (size_t j = 0; j < arraysize(ping_cases); j++) {
1583 for (size_t k = 0; k < 2; k++) {
1584 int rollcall_ping_days = ping_cases[i];
1585 int active_ping_days = ping_cases[j];
1586 // Skip cases where rollcall_ping_days == -1, but
1587 // active_ping_days > 0, because rollcall_ping_days == -1 means the
1588 // app was just installed and this is the first update check after
1589 // installation.
1590 if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
1591 active_ping_days > 0)
1592 continue;
1594 bool active_bit = k > 0;
1595 TestGalleryRequests(rollcall_ping_days, active_ping_days, active_bit,
1596 !use_organic_brand_code);
1597 ASSERT_FALSE(HasFailure()) <<
1598 " rollcall_ping_days=" << ping_cases[i] <<
1599 " active_ping_days=" << ping_cases[j] <<
1600 " active_bit=" << active_bit;
1606 // Test requests to both a Google server and a non-google server. This allows
1607 // us to test various combinations of installed (ie roll call) and active
1608 // (ie app launch) ping scenarios. The invariant is that each type of ping
1609 // value should be present at most once per day, and can be calculated based
1610 // on the delta between now and the last ping time (or in the case of active
1611 // pings, that delta plus whether the app has been active).
1612 void TestGalleryRequests(int rollcall_ping_days,
1613 int active_ping_days,
1614 bool active_bit,
1615 bool expect_brand_code) {
1616 net::TestURLFetcherFactory factory;
1618 // Set up 2 mock extensions, one with a google.com update url and one
1619 // without.
1620 prefs_.reset(new TestExtensionPrefs(base::ThreadTaskRunnerHandle::Get()));
1621 ServiceForManifestTests service(prefs_.get());
1622 ExtensionList tmp;
1623 GURL url1("http://clients2.google.com/service/update2/crx");
1624 GURL url2("http://www.somewebsite.com");
1625 service.CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
1626 Manifest::INTERNAL);
1627 service.CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
1628 Manifest::INTERNAL);
1629 EXPECT_EQ(2u, tmp.size());
1630 service.set_extensions(tmp, ExtensionList());
1632 ExtensionPrefs* prefs = service.extension_prefs();
1633 const std::string& id = tmp[0]->id();
1634 Time now = Time::Now();
1635 if (rollcall_ping_days == 0) {
1636 prefs->SetLastPingDay(id, now - TimeDelta::FromSeconds(15));
1637 } else if (rollcall_ping_days > 0) {
1638 Time last_ping_day = now -
1639 TimeDelta::FromDays(rollcall_ping_days) -
1640 TimeDelta::FromSeconds(15);
1641 prefs->SetLastPingDay(id, last_ping_day);
1644 // Store a value for the last day we sent an active ping.
1645 if (active_ping_days == 0) {
1646 prefs->SetLastActivePingDay(id, now - TimeDelta::FromSeconds(15));
1647 } else if (active_ping_days > 0) {
1648 Time last_active_ping_day = now -
1649 TimeDelta::FromDays(active_ping_days) -
1650 TimeDelta::FromSeconds(15);
1651 prefs->SetLastActivePingDay(id, last_active_ping_day);
1653 if (active_bit)
1654 prefs->SetActiveBit(id, true);
1656 ExtensionUpdater updater(&service,
1657 service.extension_prefs(),
1658 service.pref_service(),
1659 service.profile(),
1660 kUpdateFrequencySecs,
1661 NULL,
1662 service.GetDownloaderFactory());
1663 ExtensionUpdater::CheckParams params;
1664 updater.Start();
1665 updater.CheckNow(params);
1666 content::RunAllBlockingPoolTasksUntilIdle();
1668 // Make the updater do manifest fetching, and note the urls it tries to
1669 // fetch.
1670 std::vector<GURL> fetched_urls;
1671 net::TestURLFetcher* fetcher =
1672 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1673 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1674 fetched_urls.push_back(fetcher->GetOriginalURL());
1676 fetcher->set_url(fetched_urls[0]);
1677 fetcher->set_status(net::URLRequestStatus());
1678 fetcher->set_response_code(500);
1679 fetcher->SetResponseString(std::string());
1680 fetcher->delegate()->OnURLFetchComplete(fetcher);
1682 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1683 fetched_urls.push_back(fetcher->GetOriginalURL());
1685 // The urls could have been fetched in either order, so use the host to
1686 // tell them apart and note the query each used.
1687 GURL url1_fetch_url;
1688 GURL url2_fetch_url;
1689 std::string url1_query;
1690 std::string url2_query;
1691 if (fetched_urls[0].host() == url1.host()) {
1692 url1_fetch_url = fetched_urls[0];
1693 url2_fetch_url = fetched_urls[1];
1695 url1_query = fetched_urls[0].query();
1696 url2_query = fetched_urls[1].query();
1697 } else if (fetched_urls[0].host() == url2.host()) {
1698 url1_fetch_url = fetched_urls[1];
1699 url2_fetch_url = fetched_urls[0];
1700 url1_query = fetched_urls[1].query();
1701 url2_query = fetched_urls[0].query();
1702 } else {
1703 NOTREACHED();
1706 std::map<std::string, ParamsMap> url1_ping_data =
1707 GetPingDataFromURL(url1_fetch_url);
1708 ParamsMap url1_params = ParamsMap();
1709 if (!url1_ping_data.empty() && ContainsKey(url1_ping_data, id))
1710 url1_params = url1_ping_data[id];
1712 // First make sure the non-google query had no ping parameter.
1713 EXPECT_TRUE(GetPingDataFromURL(url2_fetch_url).empty());
1715 // Now make sure the google query had the correct ping parameter.
1716 bool did_rollcall = false;
1717 if (rollcall_ping_days != 0) {
1718 ASSERT_TRUE(ContainsKey(url1_params, "r"));
1719 ASSERT_EQ(1u, url1_params["r"].size());
1720 EXPECT_EQ(base::IntToString(rollcall_ping_days),
1721 *url1_params["r"].begin());
1722 did_rollcall = true;
1724 if (active_bit && active_ping_days != 0 && did_rollcall) {
1725 ASSERT_TRUE(ContainsKey(url1_params, "a"));
1726 ASSERT_EQ(1u, url1_params["a"].size());
1727 EXPECT_EQ(base::IntToString(active_ping_days),
1728 *url1_params["a"].begin());
1731 // Make sure the non-google query has no brand parameter.
1732 const std::string brand_string = "brand%3D";
1733 EXPECT_TRUE(url2_query.find(brand_string) == std::string::npos);
1735 #if defined(GOOGLE_CHROME_BUILD)
1736 // Make sure the google query has a brand parameter, but only if the
1737 // brand is non-organic.
1738 if (expect_brand_code) {
1739 EXPECT_TRUE(url1_query.find(brand_string) != std::string::npos);
1740 } else {
1741 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1743 #else
1744 // Chromium builds never add the brand to the parameter, even for google
1745 // queries.
1746 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1747 #endif
1749 RunUntilIdle();
1752 // This makes sure that the extension updater properly stores the results
1753 // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
1754 // the first time we fetched the extension, or 2) We sent a ping value of
1755 // >= 1 day for the extension.
1756 void TestHandleManifestResults() {
1757 ServiceForManifestTests service(prefs_.get());
1758 GURL update_url("http://www.google.com/manifest");
1759 ExtensionList tmp;
1760 service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
1761 Manifest::INTERNAL);
1762 service.set_extensions(tmp, ExtensionList());
1764 ExtensionUpdater updater(&service,
1765 service.extension_prefs(),
1766 service.pref_service(),
1767 service.profile(),
1768 kUpdateFrequencySecs,
1769 nullptr,
1770 service.GetDownloaderFactory());
1771 updater.Start();
1772 updater.EnsureDownloaderCreated();
1774 scoped_ptr<ManifestFetchData> fetch_data(
1775 CreateManifestFetchData(update_url));
1776 const Extension* extension = tmp[0].get();
1777 fetch_data->AddExtension(extension->id(),
1778 extension->VersionString(),
1779 &kNeverPingedData,
1780 kEmptyUpdateUrlData,
1781 std::string(),
1782 false);
1783 UpdateManifest::Results results;
1784 results.daystart_elapsed_seconds = 750;
1786 updater.downloader_->HandleManifestResults(fetch_data.get(), &results);
1787 Time last_ping_day =
1788 service.extension_prefs()->LastPingDay(extension->id());
1789 EXPECT_FALSE(last_ping_day.is_null());
1790 int64 seconds_diff = (Time::Now() - last_ping_day).InSeconds();
1791 EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
1794 // This lets us run a test with some enabled and some disabled
1795 // extensions. The |num_enabled| value specifies how many enabled extensions
1796 // to have, and |disabled| is a vector of DisableReason bitmasks for each
1797 // disabled extension we want.
1798 void TestPingMetrics(int num_enabled,
1799 const std::vector<int>& disabled) {
1800 ServiceForManifestTests service(prefs_.get());
1801 ExtensionList enabled_extensions;
1802 ExtensionList disabled_extensions;
1804 std::string update_url = extension_urls::GetWebstoreUpdateUrl().spec();
1805 if (num_enabled > 0)
1806 service.CreateTestExtensions(
1807 1, num_enabled, &enabled_extensions, &update_url, Manifest::INTERNAL);
1808 if (disabled.size() > 0)
1809 service.CreateTestExtensions(2,
1810 disabled.size(),
1811 &disabled_extensions,
1812 &update_url,
1813 Manifest::INTERNAL);
1815 service.set_extensions(enabled_extensions, disabled_extensions);
1817 ExtensionPrefs* prefs = prefs_->prefs();
1819 for (size_t i = 0; i < disabled.size(); i++)
1820 prefs->SetExtensionDisabled(disabled_extensions[i]->id(), disabled[i]);
1822 // Create the extension updater, make it issue an update, and capture the
1823 // URL that it tried to fetch.
1824 net::TestURLFetcherFactory factory;
1825 ExtensionUpdater updater(&service,
1826 service.extension_prefs(),
1827 service.pref_service(),
1828 service.profile(),
1829 kUpdateFrequencySecs,
1830 nullptr,
1831 service.GetDownloaderFactory());
1832 updater.Start();
1833 SimulateTimerFired(&updater);
1834 net::TestURLFetcher* fetcher =
1835 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1836 ASSERT_NE(nullptr, fetcher);
1837 const GURL& url = fetcher->GetOriginalURL();
1838 EXPECT_FALSE(url.is_empty());
1839 EXPECT_TRUE(url.is_valid());
1840 EXPECT_TRUE(url.has_query());
1842 std::map<std::string, ParamsMap> all_pings = GetPingDataFromURL(url);
1844 // Make sure that all the enabled extensions have "e=1" in their ping
1845 // parameter.
1846 for (const auto& ext : enabled_extensions) {
1847 ASSERT_TRUE(ContainsKey(all_pings, ext->id()));
1848 ParamsMap& ping = all_pings[ext->id()];
1849 EXPECT_FALSE(ContainsKey(ping, "dr"));
1850 ASSERT_TRUE(ContainsKey(ping, "e")) << url;
1851 std::set<std::string> e = ping["e"];
1852 ASSERT_EQ(1u, e.size()) << url;
1853 EXPECT_EQ(std::string("1"), *e.begin()) << url;
1854 EXPECT_FALSE(ContainsKey(ping, "dr"));
1857 // Make sure that all the disable extensions have the appropriate
1858 // "dr=<num>" values in their ping parameter if metrics are on, or omit
1859 // it otherwise.
1860 ASSERT_EQ(disabled_extensions.size(), disabled.size());
1861 for (size_t i = 0; i < disabled.size(); i++) {
1862 scoped_refptr<const Extension>& ext = disabled_extensions[i];
1863 int disable_reasons = disabled[i];
1864 ASSERT_TRUE(ContainsKey(all_pings, ext->id())) << url;
1865 ParamsMap& ping = all_pings[ext->id()];
1867 ASSERT_TRUE(ContainsKey(ping, "e")) << url;
1868 std::set<std::string> e = ping["e"];
1869 ASSERT_EQ(1u, e.size()) << url;
1870 EXPECT_EQ(std::string("0"), *e.begin()) << url;
1872 if (disable_reasons == 0) {
1873 EXPECT_FALSE(ContainsKey(ping, "dr"));
1874 } else {
1875 ASSERT_TRUE(ContainsKey(ping, "dr"));
1876 int found_reasons = 0;
1877 for (const auto& reason_string : ping["dr"]) {
1878 int reason = 0;
1879 ASSERT_TRUE(base::StringToInt(reason_string, &reason));
1880 // Make sure it's a power of 2.
1881 ASSERT_TRUE(reason < 2 || !(reason & (reason - 1))) << reason;
1882 found_reasons |= reason;
1884 EXPECT_EQ(disable_reasons, found_reasons);
1889 protected:
1890 scoped_ptr<TestExtensionPrefs> prefs_;
1892 ManifestFetchData* CreateManifestFetchData(const GURL& update_url) {
1893 return new ManifestFetchData(update_url, 0, "",
1894 UpdateQueryParams::Get(UpdateQueryParams::CRX),
1895 ManifestFetchData::PING);
1898 private:
1899 content::TestBrowserThreadBundle thread_bundle_;
1900 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
1901 ScopedTestingLocalState testing_local_state_;
1903 #if defined OS_CHROMEOS
1904 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
1905 chromeos::ScopedTestCrosSettings test_cros_settings_;
1906 chromeos::ScopedTestUserManager test_user_manager_;
1907 #endif
1910 // Because we test some private methods of ExtensionUpdater, it's easier for the
1911 // actual test code to live in ExtenionUpdaterTest methods instead of TEST_F
1912 // subclasses where friendship with ExtenionUpdater is not inherited.
1914 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
1915 TestExtensionUpdateCheckRequests(false);
1918 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
1919 TestExtensionUpdateCheckRequests(true);
1922 TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
1923 TestUpdateUrlDataEmpty();
1924 TestUpdateUrlDataSimple();
1925 TestUpdateUrlDataCompound();
1926 TestUpdateUrlDataFromGallery(
1927 extension_urls::GetWebstoreUpdateUrl().spec());
1930 TEST_F(ExtensionUpdaterTest, TestInstallSource) {
1931 TestInstallSource();
1934 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
1935 TestDetermineUpdates();
1938 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
1939 TestDetermineUpdatesPending();
1942 TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
1943 TestMultipleManifestDownloading();
1946 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
1947 TestSingleExtensionDownloading(false, false, false);
1950 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
1951 TestSingleExtensionDownloading(true, false, false);
1954 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
1955 TestSingleExtensionDownloading(false, true, false);
1958 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
1959 TestSingleExtensionDownloading(true, true, false);
1962 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailure) {
1963 TestSingleExtensionDownloading(false, false, true);
1966 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailureWithRetry) {
1967 TestSingleExtensionDownloading(false, true, true);
1970 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailurePending) {
1971 TestSingleExtensionDownloading(true, false, true);
1974 TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieAuth) {
1975 TestProtectedDownload(
1976 "https://chrome.google.com/webstore/download",
1977 false, false, // No OAuth2 support
1978 0, 0);
1981 TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieFailure) {
1982 TestProtectedDownload(
1983 "https://chrome.google.com/webstore/download",
1984 false, false, // No OAuth2 support
1985 0, -1); // max_authuser=-1 simulates no valid authuser value.
1988 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser1) {
1989 TestProtectedDownload("https://google.com", false, false, 1, 1);
1992 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser2) {
1993 TestProtectedDownload("https://google.com", false, false, 2, 2);
1996 TEST_F(ExtensionUpdaterTest, ProtectedDownloadAuthUserExhaustionFailure) {
1997 TestProtectedDownload("https://google.com", false, false, 2, 5);
2000 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Token) {
2001 TestProtectedDownload(
2002 "https://google.com",
2003 true, true,
2004 0, -1);
2007 TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Failure) {
2008 TestProtectedDownload(
2009 "https://google.com",
2010 true, false,
2011 0, -1);
2014 TEST_F(ExtensionUpdaterTest, ProtectedDownloadNoOAuth2WithNonGoogleDomain) {
2015 TestProtectedDownload(
2016 "https://not-google.com",
2017 true, true,
2018 0, -1);
2021 TEST_F(ExtensionUpdaterTest, ProtectedDownloadFailWithoutHTTPS) {
2022 TestProtectedDownload(
2023 "http://google.com",
2024 true, true,
2025 0, 0);
2028 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
2029 TestMultipleExtensionDownloading(false);
2031 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
2032 TestMultipleExtensionDownloading(true);
2035 TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
2036 TestManifestRetryDownloading();
2039 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) {
2040 TestGalleryRequestsWithBrand(true);
2043 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) {
2044 TestGalleryRequestsWithBrand(false);
2047 TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
2048 TestHandleManifestResults();
2051 TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
2052 net::TestURLFetcherFactory factory;
2053 ServiceForManifestTests service(prefs_.get());
2054 ExtensionUpdater updater(&service,
2055 service.extension_prefs(),
2056 service.pref_service(),
2057 service.profile(),
2058 kUpdateFrequencySecs,
2059 NULL,
2060 service.GetDownloaderFactory());
2061 MockExtensionDownloaderDelegate delegate;
2062 service.OverrideDownloaderDelegate(&delegate);
2064 // Non-internal non-external extensions should be rejected.
2065 ExtensionList extensions;
2066 service.CreateTestExtensions(1, 1, &extensions, NULL,
2067 Manifest::INVALID_LOCATION);
2068 service.CreateTestExtensions(2, 1, &extensions, NULL, Manifest::INTERNAL);
2069 ASSERT_EQ(2u, extensions.size());
2070 const std::string& updateable_id = extensions[1]->id();
2072 // These expectations fail if the delegate's methods are invoked for the
2073 // first extension, which has a non-matching id.
2074 EXPECT_CALL(delegate,
2075 GetUpdateUrlData(updateable_id)).WillOnce(Return(""));
2076 EXPECT_CALL(delegate, GetPingDataForExtension(updateable_id, _));
2078 service.set_extensions(extensions, ExtensionList());
2079 ExtensionUpdater::CheckParams params;
2080 updater.Start();
2081 updater.CheckNow(params);
2082 content::RunAllBlockingPoolTasksUntilIdle();
2085 TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
2086 net::TestURLFetcherFactory factory;
2087 ServiceForManifestTests service(prefs_.get());
2088 ExtensionUpdater updater(&service,
2089 service.extension_prefs(),
2090 service.pref_service(),
2091 service.profile(),
2092 kUpdateFrequencySecs,
2093 NULL,
2094 service.GetDownloaderFactory());
2095 MockExtensionDownloaderDelegate delegate;
2096 service.OverrideDownloaderDelegate(&delegate);
2098 // Non-internal non-external extensions should be rejected.
2099 ExtensionList enabled_extensions;
2100 ExtensionList disabled_extensions;
2101 service.CreateTestExtensions(1, 1, &enabled_extensions, NULL,
2102 Manifest::INTERNAL);
2103 service.CreateTestExtensions(2, 1, &disabled_extensions, NULL,
2104 Manifest::INTERNAL);
2105 ASSERT_EQ(1u, enabled_extensions.size());
2106 ASSERT_EQ(1u, disabled_extensions.size());
2107 const std::string& enabled_id = enabled_extensions[0]->id();
2108 const std::string& disabled_id = disabled_extensions[0]->id();
2110 // We expect that both enabled and disabled extensions are auto-updated.
2111 EXPECT_CALL(delegate, GetUpdateUrlData(enabled_id)).WillOnce(Return(""));
2112 EXPECT_CALL(delegate, GetPingDataForExtension(enabled_id, _));
2113 EXPECT_CALL(delegate,
2114 GetUpdateUrlData(disabled_id)).WillOnce(Return(""));
2115 EXPECT_CALL(delegate, GetPingDataForExtension(disabled_id, _));
2117 service.set_extensions(enabled_extensions, disabled_extensions);
2118 ExtensionUpdater::CheckParams params;
2119 updater.Start();
2120 updater.CheckNow(params);
2121 content::RunAllBlockingPoolTasksUntilIdle();
2124 TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
2125 net::TestURLFetcherFactory factory;
2126 MockService service(prefs_.get());
2127 MockExtensionDownloaderDelegate delegate;
2128 scoped_ptr<ExtensionDownloader> downloader(
2129 new ExtensionDownloader(&delegate, service.request_context()));
2130 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
2132 // First, verify that adding valid extensions does invoke the callbacks on
2133 // the delegate.
2134 std::string id = crx_file::id_util::GenerateId("foo");
2135 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
2136 EXPECT_TRUE(
2137 downloader->AddPendingExtension(id, GURL("http://example.com/update"),
2138 0));
2139 downloader->StartAllPending(NULL);
2140 Mock::VerifyAndClearExpectations(&delegate);
2141 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2143 // Extensions with invalid update URLs should be rejected.
2144 id = crx_file::id_util::GenerateId("foo2");
2145 EXPECT_FALSE(
2146 downloader->AddPendingExtension(id, GURL("http:google.com:foo"), 0));
2147 downloader->StartAllPending(NULL);
2148 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2150 // Extensions with empty IDs should be rejected.
2151 EXPECT_FALSE(downloader->AddPendingExtension(std::string(), GURL(), 0));
2152 downloader->StartAllPending(NULL);
2153 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2155 // TODO(akalin): Test that extensions with empty update URLs
2156 // converted from user scripts are rejected.
2158 // Reset the ExtensionDownloader so that it drops the current fetcher.
2159 downloader.reset(
2160 new ExtensionDownloader(&delegate, service.request_context()));
2161 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
2163 // Extensions with empty update URLs should have a default one
2164 // filled in.
2165 id = crx_file::id_util::GenerateId("foo3");
2166 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
2167 EXPECT_TRUE(downloader->AddPendingExtension(id, GURL(), 0));
2168 downloader->StartAllPending(NULL);
2169 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
2171 net::TestURLFetcher* fetcher =
2172 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
2173 ASSERT_TRUE(fetcher);
2174 EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
2177 TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
2178 net::TestURLFetcherFactory factory;
2179 MockService service(prefs_.get());
2180 MockExtensionDownloaderDelegate delegate;
2181 ExtensionDownloader downloader(&delegate, service.request_context());
2183 StartUpdateCheck(&downloader,
2184 CreateManifestFetchData(GURL("http://localhost/foo")));
2185 // This should delete the newly-created ManifestFetchData.
2186 StartUpdateCheck(&downloader,
2187 CreateManifestFetchData(GURL("http://localhost/foo")));
2188 // This should add into |manifests_pending_|.
2189 StartUpdateCheck(&downloader,
2190 CreateManifestFetchData(GURL("http://www.google.com")));
2191 // The dtor of |downloader| should delete the pending fetchers.
2194 TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
2195 ServiceForManifestTests service(prefs_.get());
2196 net::TestURLFetcherFactory factory;
2197 ExtensionUpdater updater(&service,
2198 service.extension_prefs(),
2199 service.pref_service(),
2200 service.profile(),
2201 kUpdateFrequencySecs,
2202 NULL,
2203 service.GetDownloaderFactory());
2204 EXPECT_FALSE(updater.WillCheckSoon());
2205 updater.Start();
2206 EXPECT_FALSE(updater.WillCheckSoon());
2207 updater.CheckSoon();
2208 EXPECT_TRUE(updater.WillCheckSoon());
2209 updater.CheckSoon();
2210 EXPECT_TRUE(updater.WillCheckSoon());
2211 RunUntilIdle();
2212 EXPECT_FALSE(updater.WillCheckSoon());
2213 updater.CheckSoon();
2214 EXPECT_TRUE(updater.WillCheckSoon());
2215 updater.Stop();
2216 EXPECT_FALSE(updater.WillCheckSoon());
2219 TEST_F(ExtensionUpdaterTest, TestDisabledReasons1) {
2220 std::vector<int> disabled;
2221 disabled.push_back(Extension::DISABLE_USER_ACTION);
2222 disabled.push_back(Extension::DISABLE_PERMISSIONS_INCREASE |
2223 Extension::DISABLE_CORRUPTED);
2224 TestPingMetrics(1, disabled);
2227 TEST_F(ExtensionUpdaterTest, TestDisabledReasons2) {
2228 std::vector<int> disabled;
2229 TestPingMetrics(1, disabled);
2232 TEST_F(ExtensionUpdaterTest, TestDisabledReasons3) {
2233 std::vector<int> disabled;
2234 disabled.push_back(0);
2235 TestPingMetrics(0, disabled);
2238 // TODO(asargent) - (http://crbug.com/12780) add tests for:
2239 // -prodversionmin (shouldn't update if browser version too old)
2240 // -manifests & updates arriving out of order / interleaved
2241 // -malformed update url (empty, file://, has query, has a # fragment, etc.)
2242 // -An extension gets uninstalled while updates are in progress (so it doesn't
2243 // "come back from the dead")
2244 // -An extension gets manually updated to v3 while we're downloading v2 (ie
2245 // you don't get downgraded accidentally)
2246 // -An update manifest mentions multiple updates
2248 } // namespace extensions