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/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"
79 using base::TimeDelta
;
80 using content::BrowserThread
;
81 using update_client::UpdateQueryParams
;
83 using testing::Invoke
;
84 using testing::InvokeWithoutArgs
;
86 using testing::Return
;
87 using testing::SetArgPointee
;
90 namespace extensions
{
92 typedef ExtensionDownloaderDelegate::Error Error
;
93 typedef ExtensionDownloaderDelegate::PingResult PingResult
;
97 const net::BackoffEntry::Policy kNoBackoffPolicy
= {
98 // Number of initial errors (in sequence) to ignore before applying
99 // exponential back-off rules.
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.
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
,
144 class MockExtensionDownloaderDelegate
: public ExtensionDownloaderDelegate
{
146 MOCK_METHOD4(OnExtensionDownloadFailed
, void(const std::string
&,
149 const std::set
<int>&));
150 MOCK_METHOD7(OnExtensionDownloadFinished
,
151 void(const extensions::CRXFileInfo
&,
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
*));
166 scoped_refptr
<content::MessageLoopRunner
> runner
=
167 new content::MessageLoopRunner
;
168 quit_closure_
= runner
->QuitClosure();
170 quit_closure_
.Reset();
177 void DelegateTo(ExtensionDownloaderDelegate
* delegate
) {
178 ON_CALL(*this, OnExtensionDownloadFailed(_
, _
, _
, _
))
179 .WillByDefault(Invoke(delegate
,
180 &ExtensionDownloaderDelegate::OnExtensionDownloadFailed
));
181 ON_CALL(*this, OnExtensionDownloadFinished(_
, _
, _
, _
, _
, _
, _
))
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
));
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
{
212 NotificationsObserver() {
213 for (size_t i
= 0; i
< arraysize(kNotificationsObserved
); ++i
) {
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();
237 scoped_refptr
<content::MessageLoopRunner
> runner
=
238 new content::MessageLoopRunner
;
239 quit_closure_
= runner
->QuitClosure();
241 quit_closure_
.Reset();
245 void Observe(int type
,
246 const content::NotificationSource
& source
,
247 const content::NotificationDetails
& details
) override
{
248 if (!quit_closure_
.is_null())
250 for (size_t i
= 0; i
< arraysize(kNotificationsObserved
); ++i
) {
251 if (kNotificationsObserved
[i
] == type
) {
253 if (type
== extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND
) {
255 content::Details
<UpdateDetails
>(details
)->id
);
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
;
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
) {
282 base::StringToInt(query_string
.substr(value
.begin
, value
.len
),
292 // Base class for further specialized test classes.
293 class MockService
: public TestExtensionService
{
295 explicit MockService(TestExtensionPrefs
* 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
));
342 manifest
.SetString(manifest_keys::kUpdateURL
, *update_url
);
343 scoped_refptr
<Extension
> e
=
344 prefs_
->AddExtensionWithManifest(manifest
, location
);
345 ASSERT_TRUE(e
.get() != NULL
);
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
;
365 TestExtensionPrefs
* const prefs_
;
366 TestingProfile profile_
;
367 PendingExtensionManager pending_extension_manager_
;
370 scoped_ptr
<ExtensionDownloader
> CreateExtensionDownloader(
371 ExtensionDownloaderDelegate
* delegate
) {
372 scoped_ptr
<ExtensionDownloader
> downloader
=
373 ChromeExtensionDownloaderFactory::CreateForRequestContext(
375 downloader_delegate_override_
? downloader_delegate_override_
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
) {
419 // Loads some pending extension records into a pending extension manager.
420 void SetupPendingExtensionManagerForTest(
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;
431 crx_file::id_util::GenerateId(base::StringPrintf("extension%i", i
));
433 pending_extension_manager
->AddForTesting(
434 PendingExtensionInfo(id
,
438 should_allow_install
,
447 class ServiceForManifestTests
: public MockService
{
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
)
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
{
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
);
491 ExtensionRegistry
* registry_
;
494 class ServiceForDownloadTests
: public MockService
{
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_
];
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
;
530 const std::string
& extension_id() const { return extension_id_
; }
531 const base::FilePath
& install_path() const { return install_path_
; }
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_
;
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();
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")
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
);
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
, ¶ms
);
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
{
642 ExtensionUpdaterTest()
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.
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();
703 SetupPendingExtensionManagerForTest(1, GURL(update_url
),
704 pending_extension_manager
);
706 service
.CreateTestExtensions(1, 1, &extensions
, &update_url
,
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(),
719 service
.GetDownloaderFactory());
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(), ¶ms
);
743 EXPECT_TRUE(pending_extension_manager
->IsIdPending(params
["id"]));
744 EXPECT_EQ("0.0.0.0", params
["v"]);
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(), ¶ms
);
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(), ¶ms
);
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(), ¶ms
);
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
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(), ¶ms
);
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(),
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(),
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"),
880 EXPECT_CALL(delegate
, GetExtensionExistingVersion(id2
, _
))
881 .WillOnce(DoAll(SetArgPointee
<1>("2.0.0.0"),
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
,
917 AddParseResult(*it
, "1.1", "http://localhost/e1_1.1.crx", &updates
);
920 // The delegate will tell the downloader that all the extensions are
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());
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
);
987 Mock::VerifyAndClearExpectations(&delegate
);
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(
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
);
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'"
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' />"
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"),
1021 EXPECT_CALL(delegate
, OnExtensionDownloadFailed(
1022 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE
, _
, _
))
1023 .WillOnce(InvokeWithoutArgs(
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
);
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'"
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' />"
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"),
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
);
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();
1064 ADD_FAILURE() << "Unexpected fetch: " << fetcher
->GetOriginalURL();
1068 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
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());
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
);
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());
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
);
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
);
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(),
1156 kUpdateFrequencySecs
,
1158 service
->GetDownloaderFactory());
1159 MockExtensionDownloaderDelegate delegate
;
1160 delegate
.DelegateTo(&updater
);
1161 service
->OverrideDownloaderDelegate(&delegate
);
1163 updater
.EnsureDownloaderCreated();
1164 updater
.downloader_
->extensions_queue_
.set_backoff_policy(
1167 GURL
test_url("http://localhost/extension.crx");
1169 std::string id
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1171 Version
version("0.0.1");
1172 std::set
<int> requests
;
1174 scoped_ptr
<ExtensionDownloader::ExtensionFetch
> fetch(
1175 new ExtensionDownloader::ExtensionFetch(
1176 id
, test_url
, hash
, version
.GetString(), requests
));
1177 updater
.downloader_
->FetchUpdatedExtension(fetch
.Pass());
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
,
1190 &ShouldAlwaysInstall
,
1193 Extension::NO_FLAGS
,
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
);
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
);
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());
1221 fetcher
->set_response_code(404);
1222 EXPECT_CALL(delegate
, OnExtensionDownloadFailed(id
, _
, _
, requests
));
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
);
1235 // Don't expect any extension to have been installed.
1236 EXPECT_TRUE(service
->extension_id().empty());
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
,
1255 bool succeed_with_oauth2
,
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(
1267 service
->extension_prefs(),
1268 service
->pref_service(),
1270 kUpdateFrequencySecs
,
1272 downloader_factory
);
1274 updater
.EnsureDownloaderCreated();
1275 updater
.downloader_
->extensions_queue_
.set_backoff_policy(
1278 GURL
test_url(base::StringPrintf("%s/extension.crx", url_prefix
.c_str()));
1279 std::string id
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1281 Version
version("0.0.1");
1282 std::set
<int> requests
;
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());
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()) {
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
;
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
1326 EXPECT_TRUE(fetch_headers
.HasHeader(
1327 net::HttpRequestHeaders::kAuthorization
));
1328 std::string expected_header_value
= base::StringPrintf("Bearer %s",
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;
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;
1348 if (succeed_with_oauth2
) {
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
);
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
,
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
;
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.)
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
) {
1389 // Simulate an authorization failure which should elicit an increment
1390 // of the authuser value.
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
);
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();
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
);
1417 // Simulate successful authorization with a 200 response.
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
);
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(),
1450 kUpdateFrequencySecs
,
1452 service
.GetDownloaderFactory());
1454 updater
.EnsureDownloaderCreated();
1455 updater
.downloader_
->extensions_queue_
.set_backoff_policy(
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";
1469 std::string version1
= "0.1";
1470 std::string version2
= "0.1";
1471 std::set
<int> requests
;
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());
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
);
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());
1532 // Make sure the second fetch finished and asked the service to do an
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
);
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
1590 if (rollcall_ping_days
== ManifestFetchData::kNeverPinged
&&
1591 active_ping_days
> 0)
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
,
1615 bool expect_brand_code
) {
1616 net::TestURLFetcherFactory factory
;
1618 // Set up 2 mock extensions, one with a google.com update url and one
1620 prefs_
.reset(new TestExtensionPrefs(base::ThreadTaskRunnerHandle::Get()));
1621 ServiceForManifestTests
service(prefs_
.get());
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
);
1654 prefs
->SetActiveBit(id
, true);
1656 ExtensionUpdater
updater(&service
,
1657 service
.extension_prefs(),
1658 service
.pref_service(),
1660 kUpdateFrequencySecs
,
1662 service
.GetDownloaderFactory());
1663 ExtensionUpdater::CheckParams params
;
1665 updater
.CheckNow(params
);
1666 content::RunAllBlockingPoolTasksUntilIdle();
1668 // Make the updater do manifest fetching, and note the urls it tries to
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();
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
);
1741 EXPECT_TRUE(url1_query
.find(brand_string
) == std::string::npos
);
1744 // Chromium builds never add the brand to the parameter, even for google
1746 EXPECT_TRUE(url1_query
.find(brand_string
) == std::string::npos
);
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");
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(),
1768 kUpdateFrequencySecs
,
1770 service
.GetDownloaderFactory());
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(),
1780 kEmptyUpdateUrlData
,
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,
1811 &disabled_extensions
,
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(),
1829 kUpdateFrequencySecs
,
1831 service
.GetDownloaderFactory());
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
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
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"));
1875 ASSERT_TRUE(ContainsKey(ping
, "dr"));
1876 int found_reasons
= 0;
1877 for (const auto& reason_string
: ping
["dr"]) {
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
);
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
);
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_
;
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
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",
2007 TEST_F(ExtensionUpdaterTest
, ProtectedDownloadWithOAuth2Failure
) {
2008 TestProtectedDownload(
2009 "https://google.com",
2014 TEST_F(ExtensionUpdaterTest
, ProtectedDownloadNoOAuth2WithNonGoogleDomain
) {
2015 TestProtectedDownload(
2016 "https://not-google.com",
2021 TEST_F(ExtensionUpdaterTest
, ProtectedDownloadFailWithoutHTTPS
) {
2022 TestProtectedDownload(
2023 "http://google.com",
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(),
2058 kUpdateFrequencySecs
,
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
;
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(),
2092 kUpdateFrequencySecs
,
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
;
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
2134 std::string id
= crx_file::id_util::GenerateId("foo");
2135 EXPECT_CALL(delegate
, GetPingDataForExtension(id
, _
)).WillOnce(Return(false));
2137 downloader
->AddPendingExtension(id
, GURL("http://example.com/update"),
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");
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.
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
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(),
2201 kUpdateFrequencySecs
,
2203 service
.GetDownloaderFactory());
2204 EXPECT_FALSE(updater
.WillCheckSoon());
2206 EXPECT_FALSE(updater
.WillCheckSoon());
2207 updater
.CheckSoon();
2208 EXPECT_TRUE(updater
.WillCheckSoon());
2209 updater
.CheckSoon();
2210 EXPECT_TRUE(updater
.WillCheckSoon());
2212 EXPECT_FALSE(updater
.WillCheckSoon());
2213 updater
.CheckSoon();
2214 EXPECT_TRUE(updater
.WillCheckSoon());
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