1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/command_line.h"
13 #include "base/compiler_specific.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/run_loop.h"
18 #include "base/sequenced_task_runner.h"
19 #include "base/stl_util.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_split.h"
22 #include "base/strings/string_util.h"
23 #include "base/strings/stringprintf.h"
24 #include "base/threading/thread.h"
25 #include "base/version.h"
26 #include "chrome/browser/chrome_notification_types.h"
27 #include "chrome/browser/extensions/crx_installer.h"
28 #include "chrome/browser/extensions/extension_error_reporter.h"
29 #include "chrome/browser/extensions/extension_sync_data.h"
30 #include "chrome/browser/extensions/test_extension_prefs.h"
31 #include "chrome/browser/extensions/test_extension_service.h"
32 #include "chrome/browser/extensions/test_extension_system.h"
33 #include "chrome/browser/extensions/updater/chrome_extension_downloader_factory.h"
34 #include "chrome/browser/extensions/updater/extension_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"
78 using base::TimeDelta
;
79 using content::BrowserThread
;
80 using omaha_query_params::OmahaQueryParams
;
82 using testing::Invoke
;
83 using testing::InvokeWithoutArgs
;
85 using testing::Return
;
86 using testing::SetArgPointee
;
89 namespace extensions
{
91 typedef ExtensionDownloaderDelegate::Error Error
;
92 typedef ExtensionDownloaderDelegate::PingResult PingResult
;
96 const net::BackoffEntry::Policy kNoBackoffPolicy
= {
97 // Number of initial errors (in sequence) to ignore before applying
98 // exponential back-off rules.
101 // Initial delay for exponential back-off in ms.
104 // Factor by which the waiting time will be multiplied.
107 // Fuzzing percentage. ex: 10% will spread requests randomly
108 // between 90%-100% of the calculated time.
111 // Maximum amount of time we are willing to delay our request in ms.
114 // Time to keep an entry from being discarded even when it
115 // has no significant state, -1 to never discard.
118 // Don't use initial delay unless the last request was an error.
122 const char kEmptyUpdateUrlData
[] = "";
124 const char kAuthUserQueryKey
[] = "authuser";
126 int kExpectedLoadFlags
=
127 net::LOAD_DO_NOT_SEND_COOKIES
|
128 net::LOAD_DO_NOT_SAVE_COOKIES
|
129 net::LOAD_DISABLE_CACHE
;
131 int kExpectedLoadFlagsForDownloadWithCookies
= net::LOAD_DISABLE_CACHE
;
133 // Fake authentication constants
134 const char kFakeAccountId
[] = "bobloblaw@lawblog.example.com";
135 const char kFakeOAuth2Token
[] = "ce n'est pas un jeton";
137 const ManifestFetchData::PingData
kNeverPingedData(
138 ManifestFetchData::kNeverPinged
,
139 ManifestFetchData::kNeverPinged
,
143 class MockExtensionDownloaderDelegate
: public ExtensionDownloaderDelegate
{
145 MOCK_METHOD4(OnExtensionDownloadFailed
, void(const std::string
&,
148 const std::set
<int>&));
149 MOCK_METHOD7(OnExtensionDownloadFinished
, void(const std::string
&,
150 const base::FilePath
&,
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
*));
164 scoped_refptr
<content::MessageLoopRunner
> runner
=
165 new content::MessageLoopRunner
;
166 quit_closure_
= runner
->QuitClosure();
168 quit_closure_
.Reset();
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
));
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
{
209 NotificationsObserver() {
210 for (size_t i
= 0; i
< arraysize(kNotificationsObserved
); ++i
) {
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();
234 scoped_refptr
<content::MessageLoopRunner
> runner
=
235 new content::MessageLoopRunner
;
236 quit_closure_
= runner
->QuitClosure();
238 quit_closure_
.Reset();
242 void Observe(int type
,
243 const content::NotificationSource
& source
,
244 const content::NotificationDetails
& details
) override
{
245 if (!quit_closure_
.is_null())
247 for (size_t i
= 0; i
< arraysize(kNotificationsObserved
); ++i
) {
248 if (kNotificationsObserved
[i
] == type
) {
250 if (type
== extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND
) {
252 content::Details
<UpdateDetails
>(details
)->id
);
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
;
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
) {
279 base::StringToInt(query_string
.substr(value
.begin
, value
.len
),
289 // Base class for further specialized test classes.
290 class MockService
: public TestExtensionService
{
292 explicit MockService(TestExtensionPrefs
* 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
));
339 manifest
.SetString(manifest_keys::kUpdateURL
, *update_url
);
340 scoped_refptr
<Extension
> e
=
341 prefs_
->AddExtensionWithManifest(manifest
, location
);
342 ASSERT_TRUE(e
.get() != NULL
);
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
;
362 TestExtensionPrefs
* const prefs_
;
363 TestingProfile profile_
;
364 PendingExtensionManager pending_extension_manager_
;
367 scoped_ptr
<ExtensionDownloader
> CreateExtensionDownloader(
368 ExtensionDownloaderDelegate
* delegate
) {
369 scoped_ptr
<ExtensionDownloader
> downloader
=
370 ChromeExtensionDownloaderFactory::CreateForRequestContext(
372 downloader_delegate_override_
? downloader_delegate_override_
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
) {
416 // Loads some pending extension records into a pending extension manager.
417 void SetupPendingExtensionManagerForTest(
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;
428 crx_file::id_util::GenerateId(base::StringPrintf("extension%i", i
));
430 pending_extension_manager
->AddForTesting(
431 PendingExtensionInfo(id
,
435 should_allow_install
,
444 class ServiceForManifestTests
: public MockService
{
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
)
458 return registry_
->disabled_extensions().GetByID(id
);
461 const ExtensionSet
* extensions() const override
{
462 return ®istry_
->enabled_extensions();
465 PendingExtensionManager
* pending_extension_manager() override
{
466 return &pending_extension_manager_
;
469 const Extension
* GetPendingExtensionUpdate(
470 const std::string
& id
) const override
{
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
);
492 ExtensionRegistry
* registry_
;
495 class ServiceForDownloadTests
: public MockService
{
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
{
512 install_path_
= extension_path
;
514 if (ContainsKey(fake_crx_installers_
, id
)) {
515 *out_crx_installer
= fake_crx_installers_
[id
];
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
;
532 const std::string
& extension_id() const { return extension_id_
; }
533 const base::FilePath
& install_path() const { return install_path_
; }
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_
;
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();
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")
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
);
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
, ¶ms
);
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
{
645 ExtensionUpdaterTest()
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.
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();
705 SetupPendingExtensionManagerForTest(1, GURL(update_url
),
706 pending_extension_manager
);
708 service
.CreateTestExtensions(1, 1, &extensions
, &update_url
,
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(),
721 service
.GetDownloaderFactory());
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(), ¶ms
);
745 EXPECT_TRUE(pending_extension_manager
->IsIdPending(params
["id"]));
746 EXPECT_EQ("0.0.0.0", params
["v"]);
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(), ¶ms
);
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(), ¶ms
);
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(), ¶ms
);
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
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(), ¶ms
);
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(),
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(),
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"),
882 EXPECT_CALL(delegate
, GetExtensionExistingVersion(id2
, _
))
883 .WillOnce(DoAll(SetArgPointee
<1>("2.0.0.0"),
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
,
919 AddParseResult(*it
, "1.1", "http://localhost/e1_1.1.crx", &updates
);
922 // The delegate will tell the downloader that all the extensions are
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());
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
);
989 Mock::VerifyAndClearExpectations(&delegate
);
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(
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
);
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'"
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' />"
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"),
1023 EXPECT_CALL(delegate
, OnExtensionDownloadFailed(
1024 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE
, _
, _
))
1025 .WillOnce(InvokeWithoutArgs(
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
);
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'"
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' />"
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"),
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
);
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();
1066 ADD_FAILURE() << "Unexpected fetch: " << fetcher
->GetOriginalURL();
1070 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
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());
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
);
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());
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
);
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
);
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(),
1158 kUpdateFrequencySecs
,
1160 service
->GetDownloaderFactory());
1161 MockExtensionDownloaderDelegate delegate
;
1162 delegate
.DelegateTo(&updater
);
1163 service
->OverrideDownloaderDelegate(&delegate
);
1165 updater
.EnsureDownloaderCreated();
1166 updater
.downloader_
->extensions_queue_
.set_backoff_policy(
1169 GURL
test_url("http://localhost/extension.crx");
1171 std::string id
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1173 Version
version("0.0.1");
1174 std::set
<int> requests
;
1176 scoped_ptr
<ExtensionDownloader::ExtensionFetch
> fetch(
1177 new ExtensionDownloader::ExtensionFetch(
1178 id
, test_url
, hash
, version
.GetString(), requests
));
1179 updater
.downloader_
->FetchUpdatedExtension(fetch
.Pass());
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
,
1192 &ShouldAlwaysInstall
,
1195 Extension::NO_FLAGS
,
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
);
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
);
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());
1223 fetcher
->set_response_code(404);
1224 EXPECT_CALL(delegate
, OnExtensionDownloadFailed(id
, _
, _
, requests
));
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
);
1236 // Don't expect any extension to have been installed.
1237 EXPECT_TRUE(service
->extension_id().empty());
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
,
1256 bool succeed_with_oauth2
,
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(
1268 service
->extension_prefs(),
1269 service
->pref_service(),
1271 kUpdateFrequencySecs
,
1273 downloader_factory
);
1275 updater
.EnsureDownloaderCreated();
1276 updater
.downloader_
->extensions_queue_
.set_backoff_policy(
1279 GURL
test_url(base::StringPrintf("%s/extension.crx", url_prefix
.c_str()));
1280 std::string id
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1282 Version
version("0.0.1");
1283 std::set
<int> requests
;
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());
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()) {
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
;
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
1327 EXPECT_TRUE(fetch_headers
.HasHeader(
1328 net::HttpRequestHeaders::kAuthorization
));
1329 std::string expected_header_value
= base::StringPrintf("Bearer %s",
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;
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;
1349 if (succeed_with_oauth2
) {
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
);
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
,
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
;
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.)
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
) {
1390 // Simulate an authorization failure which should elicit an increment
1391 // of the authuser value.
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
);
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();
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
);
1418 // Simulate successful authorization with a 200 response.
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
);
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(),
1451 kUpdateFrequencySecs
,
1453 service
.GetDownloaderFactory());
1455 updater
.EnsureDownloaderCreated();
1456 updater
.downloader_
->extensions_queue_
.set_backoff_policy(
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";
1470 std::string version1
= "0.1";
1471 std::string version2
= "0.1";
1472 std::set
<int> requests
;
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(),
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());
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
);
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());
1536 // Make sure the second fetch finished and asked the service to do an
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
);
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
1594 if (rollcall_ping_days
== ManifestFetchData::kNeverPinged
&&
1595 active_ping_days
> 0)
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
,
1619 bool expect_brand_code
) {
1620 net::TestURLFetcherFactory factory
;
1622 // Set up 2 mock extensions, one with a google.com update url and one
1624 prefs_
.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
1625 ServiceForManifestTests
service(prefs_
.get());
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
);
1658 prefs
->SetActiveBit(id
, true);
1660 ExtensionUpdater
updater(&service
,
1661 service
.extension_prefs(),
1662 service
.pref_service(),
1664 kUpdateFrequencySecs
,
1666 service
.GetDownloaderFactory());
1667 ExtensionUpdater::CheckParams params
;
1669 updater
.CheckNow(params
);
1670 content::RunAllBlockingPoolTasksUntilIdle();
1672 // Make the updater do manifest fetching, and note the urls it tries to
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();
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) {
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
);
1735 EXPECT_TRUE(url1_query
.find(brand_string
) == std::string::npos
);
1738 // Chromium builds never add the brand to the parameter, even for google
1740 EXPECT_TRUE(url1_query
.find(brand_string
) == std::string::npos
);
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");
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(),
1762 kUpdateFrequencySecs
,
1764 service
.GetDownloaderFactory());
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(),
1774 kEmptyUpdateUrlData
,
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
,
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,
1809 &disabled_extensions
,
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
;
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(),
1837 kUpdateFrequencySecs
,
1839 service
.GetDownloaderFactory());
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
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"));
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
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"));
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"));
1894 ASSERT_TRUE(ContainsKey(ping
, "dr"));
1895 int found_reasons
= 0;
1896 for (const auto& reason_string
: ping
["dr"]) {
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
);
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
);
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_
;
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
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",
2027 TEST_F(ExtensionUpdaterTest
, ProtectedDownloadWithOAuth2Failure
) {
2028 TestProtectedDownload(
2029 "https://google.com",
2034 TEST_F(ExtensionUpdaterTest
, ProtectedDownloadNoOAuth2WithNonGoogleDomain
) {
2035 TestProtectedDownload(
2036 "https://not-google.com",
2041 TEST_F(ExtensionUpdaterTest
, ProtectedDownloadFailWithoutHTTPS
) {
2042 TestProtectedDownload(
2043 "http://google.com",
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(),
2078 kUpdateFrequencySecs
,
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
;
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(),
2112 kUpdateFrequencySecs
,
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
;
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
2154 std::string id
= crx_file::id_util::GenerateId("foo");
2155 EXPECT_CALL(delegate
, GetPingDataForExtension(id
, _
)).WillOnce(Return(false));
2157 downloader
->AddPendingExtension(id
, GURL("http://example.com/update"),
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");
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.
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
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(),
2219 kUpdateFrequencySecs
,
2221 service
.GetDownloaderFactory());
2222 EXPECT_FALSE(updater
.WillCheckSoon());
2224 EXPECT_FALSE(updater
.WillCheckSoon());
2225 updater
.CheckSoon();
2226 EXPECT_TRUE(updater
.WillCheckSoon());
2227 updater
.CheckSoon();
2228 EXPECT_TRUE(updater
.WillCheckSoon());
2230 EXPECT_FALSE(updater
.WillCheckSoon());
2231 updater
.CheckSoon();
2232 EXPECT_TRUE(updater
.WillCheckSoon());
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