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/extension_system.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/extension_downloader.h"
35 #include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
36 #include "chrome/browser/extensions/updater/extension_updater.h"
37 #include "chrome/browser/extensions/updater/manifest_fetch_data.h"
38 #include "chrome/browser/extensions/updater/request_queue_impl.h"
39 #include "chrome/browser/google/google_util.h"
40 #include "chrome/browser/prefs/pref_service_syncable.h"
41 #include "chrome/common/omaha_query_params/omaha_query_params.h"
42 #include "chrome/common/pref_names.h"
43 #include "chrome/test/base/testing_profile.h"
44 #include "content/public/browser/notification_details.h"
45 #include "content/public/browser/notification_observer.h"
46 #include "content/public/browser/notification_registrar.h"
47 #include "content/public/browser/notification_service.h"
48 #include "content/public/browser/notification_source.h"
49 #include "content/public/test/test_browser_thread_bundle.h"
50 #include "content/public/test/test_utils.h"
51 #include "extensions/common/extension.h"
52 #include "extensions/common/id_util.h"
53 #include "extensions/common/manifest_constants.h"
54 #include "libxml/globals.h"
55 #include "net/base/backoff_entry.h"
56 #include "net/base/escape.h"
57 #include "net/base/load_flags.h"
58 #include "net/url_request/test_url_fetcher_factory.h"
59 #include "net/url_request/url_request_status.h"
60 #include "testing/gmock/include/gmock/gmock.h"
61 #include "testing/gtest/include/gtest/gtest.h"
63 #if defined(OS_CHROMEOS)
64 #include "chrome/browser/chromeos/login/user_manager.h"
65 #include "chrome/browser/chromeos/settings/cros_settings.h"
66 #include "chrome/browser/chromeos/settings/device_settings_service.h"
70 using base::TimeDelta
;
71 using content::BrowserThread
;
73 using testing::InvokeWithoutArgs
;
75 using testing::Return
;
76 using testing::SetArgPointee
;
79 namespace extensions
{
81 typedef ExtensionDownloaderDelegate::Error Error
;
82 typedef ExtensionDownloaderDelegate::PingResult PingResult
;
86 const net::BackoffEntry::Policy kNoBackoffPolicy
= {
87 // Number of initial errors (in sequence) to ignore before applying
88 // exponential back-off rules.
91 // Initial delay for exponential back-off in ms.
94 // Factor by which the waiting time will be multiplied.
97 // Fuzzing percentage. ex: 10% will spread requests randomly
98 // between 90%-100% of the calculated time.
101 // Maximum amount of time we are willing to delay our request in ms.
104 // Time to keep an entry from being discarded even when it
105 // has no significant state, -1 to never discard.
108 // Don't use initial delay unless the last request was an error.
112 const char kEmptyUpdateUrlData
[] = "";
114 int kExpectedLoadFlags
=
115 net::LOAD_DO_NOT_SEND_COOKIES
|
116 net::LOAD_DO_NOT_SAVE_COOKIES
|
117 net::LOAD_DISABLE_CACHE
;
119 const ManifestFetchData::PingData
kNeverPingedData(
120 ManifestFetchData::kNeverPinged
, ManifestFetchData::kNeverPinged
, true);
122 class MockExtensionDownloaderDelegate
: public ExtensionDownloaderDelegate
{
124 MOCK_METHOD4(OnExtensionDownloadFailed
, void(const std::string
&,
127 const std::set
<int>&));
128 MOCK_METHOD6(OnExtensionDownloadFinished
, void(const std::string
&,
129 const base::FilePath
&,
133 const std::set
<int>&));
134 MOCK_METHOD2(GetPingDataForExtension
,
135 bool(const std::string
&, ManifestFetchData::PingData
*));
136 MOCK_METHOD1(GetUpdateUrlData
, std::string(const std::string
&));
137 MOCK_METHOD1(IsExtensionPending
, bool(const std::string
&));
138 MOCK_METHOD2(GetExtensionExistingVersion
,
139 bool(const std::string
&, std::string
*));
142 scoped_refptr
<content::MessageLoopRunner
> runner
=
143 new content::MessageLoopRunner
;
144 quit_closure_
= runner
->QuitClosure();
146 quit_closure_
.Reset();
154 base::Closure quit_closure_
;
157 const int kNotificationsObserved
[] = {
158 chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED
,
159 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND
,
162 // A class that observes the notifications sent by the ExtensionUpdater and
163 // the ExtensionDownloader.
164 class NotificationsObserver
: public content::NotificationObserver
{
166 NotificationsObserver() {
167 for (size_t i
= 0; i
< arraysize(kNotificationsObserved
); ++i
) {
170 kNotificationsObserved
[i
],
171 content::NotificationService::AllSources());
175 virtual ~NotificationsObserver() {
176 for (size_t i
= 0; i
< arraysize(kNotificationsObserved
); ++i
) {
177 registrar_
.Remove(this,
178 kNotificationsObserved
[i
],
179 content::NotificationService::AllSources());
183 size_t StartedCount() { return count_
[0]; }
184 size_t UpdatedCount() { return count_
[1]; }
186 bool Updated(const std::string
& id
) {
187 return updated_
.find(id
) != updated_
.end();
191 scoped_refptr
<content::MessageLoopRunner
> runner
=
192 new content::MessageLoopRunner
;
193 quit_closure_
= runner
->QuitClosure();
195 quit_closure_
.Reset();
199 virtual void Observe(int type
,
200 const content::NotificationSource
& source
,
201 const content::NotificationDetails
& details
) OVERRIDE
{
202 if (!quit_closure_
.is_null())
204 for (size_t i
= 0; i
< arraysize(kNotificationsObserved
); ++i
) {
205 if (kNotificationsObserved
[i
] == type
) {
207 if (type
== chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND
) {
209 content::Details
<UpdateDetails
>(details
)->id
);
217 content::NotificationRegistrar registrar_
;
218 size_t count_
[arraysize(kNotificationsObserved
)];
219 std::set
<std::string
> updated_
;
220 base::Closure quit_closure_
;
222 DISALLOW_COPY_AND_ASSIGN(NotificationsObserver
);
227 // Base class for further specialized test classes.
228 class MockService
: public TestExtensionService
{
230 explicit MockService(TestExtensionPrefs
* prefs
)
231 : prefs_(prefs
), pending_extension_manager_(*this) {
234 virtual ~MockService() {}
236 virtual PendingExtensionManager
* pending_extension_manager() OVERRIDE
{
237 ADD_FAILURE() << "Subclass should override this if it will "
238 << "be accessed by a test.";
239 return &pending_extension_manager_
;
242 Profile
* profile() { return &profile_
; }
244 net::URLRequestContextGetter
* request_context() {
245 return profile_
.GetRequestContext();
248 ExtensionPrefs
* extension_prefs() { return prefs_
->prefs(); }
250 PrefService
* pref_service() { return prefs_
->pref_service(); }
252 // Creates test extensions and inserts them into list. The name and
253 // version are all based on their index. If |update_url| is non-null, it
254 // will be used as the update_url for each extension.
255 // The |id| is used to distinguish extension names and make sure that
256 // no two extensions share the same name.
257 void CreateTestExtensions(int id
, int count
, ExtensionList
*list
,
258 const std::string
* update_url
,
259 Manifest::Location location
) {
260 for (int i
= 1; i
<= count
; i
++) {
261 base::DictionaryValue manifest
;
262 manifest
.SetString(manifest_keys::kVersion
,
263 base::StringPrintf("%d.0.0.0", i
));
264 manifest
.SetString(manifest_keys::kName
,
265 base::StringPrintf("Extension %d.%d", id
, i
));
267 manifest
.SetString(manifest_keys::kUpdateURL
, *update_url
);
268 scoped_refptr
<Extension
> e
=
269 prefs_
->AddExtensionWithManifest(manifest
, location
);
270 ASSERT_TRUE(e
.get() != NULL
);
276 TestExtensionPrefs
* const prefs_
;
277 PendingExtensionManager pending_extension_manager_
;
278 TestingProfile profile_
;
281 DISALLOW_COPY_AND_ASSIGN(MockService
);
285 bool ShouldInstallExtensionsOnly(const Extension
* extension
) {
286 return extension
->GetType() == Manifest::TYPE_EXTENSION
;
289 bool ShouldInstallThemesOnly(const Extension
* extension
) {
290 return extension
->is_theme();
293 bool ShouldAlwaysInstall(const Extension
* extension
) {
297 // Loads some pending extension records into a pending extension manager.
298 void SetupPendingExtensionManagerForTest(
300 const GURL
& update_url
,
301 PendingExtensionManager
* pending_extension_manager
) {
302 for (int i
= 1; i
<= count
; ++i
) {
303 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install
=
304 (i
% 2 == 0) ? &ShouldInstallThemesOnly
: &ShouldInstallExtensionsOnly
;
305 const bool kIsFromSync
= true;
306 const bool kInstallSilently
= true;
307 const bool kMarkAcknowledged
= false;
308 std::string id
= id_util::GenerateId(base::StringPrintf("extension%i", i
));
310 pending_extension_manager
->AddForTesting(
311 PendingExtensionInfo(id
,
314 should_allow_install
,
323 class ServiceForManifestTests
: public MockService
{
325 explicit ServiceForManifestTests(TestExtensionPrefs
* prefs
)
326 : MockService(prefs
) {
329 virtual ~ServiceForManifestTests() {}
331 virtual const Extension
* GetExtensionById(
332 const std::string
& id
, bool include_disabled
) const OVERRIDE
{
333 const Extension
* result
= extensions_
.GetByID(id
);
334 if (result
|| !include_disabled
)
336 return disabled_extensions_
.GetByID(id
);
339 virtual const ExtensionSet
* extensions() const OVERRIDE
{
343 virtual const ExtensionSet
* disabled_extensions() const OVERRIDE
{
344 return &disabled_extensions_
;
347 virtual PendingExtensionManager
* pending_extension_manager() OVERRIDE
{
348 return &pending_extension_manager_
;
351 virtual const Extension
* GetPendingExtensionUpdate(
352 const std::string
& id
) const OVERRIDE
{
356 virtual bool IsExtensionEnabled(const std::string
& id
) const OVERRIDE
{
357 return !disabled_extensions_
.Contains(id
);
360 void set_extensions(ExtensionList extensions
) {
361 for (ExtensionList::const_iterator it
= extensions
.begin();
362 it
!= extensions
.end(); ++it
) {
363 extensions_
.Insert(*it
);
367 void set_disabled_extensions(ExtensionList disabled_extensions
) {
368 for (ExtensionList::const_iterator it
= disabled_extensions
.begin();
369 it
!= disabled_extensions
.end(); ++it
) {
370 disabled_extensions_
.Insert(*it
);
375 ExtensionSet extensions_
;
376 ExtensionSet disabled_extensions_
;
379 class ServiceForDownloadTests
: public MockService
{
381 explicit ServiceForDownloadTests(TestExtensionPrefs
* prefs
)
382 : MockService(prefs
) {
385 // Add a fake crx installer to be returned by a call to UpdateExtension()
386 // with a specific ID. Caller keeps ownership of |crx_installer|.
387 void AddFakeCrxInstaller(const std::string
& id
, CrxInstaller
* crx_installer
) {
388 fake_crx_installers_
[id
] = crx_installer
;
391 virtual bool UpdateExtension(
392 const std::string
& id
,
393 const base::FilePath
& extension_path
,
394 const GURL
& download_url
,
395 CrxInstaller
** out_crx_installer
) OVERRIDE
{
397 install_path_
= extension_path
;
398 download_url_
= download_url
;
400 if (ContainsKey(fake_crx_installers_
, id
)) {
401 *out_crx_installer
= fake_crx_installers_
[id
];
408 virtual PendingExtensionManager
* pending_extension_manager() OVERRIDE
{
409 return &pending_extension_manager_
;
412 virtual const Extension
* GetExtensionById(
413 const std::string
& id
, bool) const OVERRIDE
{
414 last_inquired_extension_id_
= id
;
418 const std::string
& extension_id() const { return extension_id_
; }
419 const base::FilePath
& install_path() const { return install_path_
; }
420 const GURL
& download_url() const { return download_url_
; }
423 // Hold the set of ids that UpdateExtension() should fake success on.
424 // UpdateExtension(id, ...) will return true iff fake_crx_installers_
425 // contains key |id|. |out_install_notification_source| will be set
426 // to Source<CrxInstaller(fake_crx_installers_[i]).
427 std::map
<std::string
, CrxInstaller
*> fake_crx_installers_
;
429 std::string extension_id_
;
430 base::FilePath install_path_
;
433 // The last extension ID that GetExtensionById was called with.
434 // Mutable because the method that sets it (GetExtensionById) is const
435 // in the actual extension service, but must record the last extension
436 // ID in this test class.
437 mutable std::string last_inquired_extension_id_
;
440 static const int kUpdateFrequencySecs
= 15;
442 // Takes a string with KEY=VALUE parameters separated by '&' in |params| and
443 // puts the key/value pairs into |result|. For keys with no value, the empty
444 // string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
445 // "foo", and "c" to "".
446 static void ExtractParameters(const std::string
& params
,
447 std::map
<std::string
, std::string
>* result
) {
448 std::vector
<std::string
> pairs
;
449 base::SplitString(params
, '&', &pairs
);
450 for (size_t i
= 0; i
< pairs
.size(); i
++) {
451 std::vector
<std::string
> key_val
;
452 base::SplitString(pairs
[i
], '=', &key_val
);
453 if (!key_val
.empty()) {
454 std::string key
= key_val
[0];
455 EXPECT_TRUE(result
->find(key
) == result
->end());
456 (*result
)[key
] = (key_val
.size() == 2) ? key_val
[1] : std::string();
463 static void VerifyQueryAndExtractParameters(
464 const std::string
& query
,
465 std::map
<std::string
, std::string
>* result
) {
466 std::map
<std::string
, std::string
> params
;
467 ExtractParameters(query
, ¶ms
);
469 std::string omaha_params
=
470 chrome::OmahaQueryParams::Get(chrome::OmahaQueryParams::CRX
);
471 std::map
<std::string
, std::string
> expected
;
472 ExtractParameters(omaha_params
, &expected
);
474 for (std::map
<std::string
, std::string
>::iterator it
= expected
.begin();
475 it
!= expected
.end(); ++it
) {
476 EXPECT_EQ(it
->second
, params
[it
->first
]);
479 EXPECT_EQ(1U, params
.count("x"));
480 std::string decoded
= net::UnescapeURLComponent(
481 params
["x"], net::UnescapeRule::URL_SPECIAL_CHARS
);
482 ExtractParameters(decoded
, result
);
485 // All of our tests that need to use private APIs of ExtensionUpdater live
486 // inside this class (which is a friend to ExtensionUpdater).
487 class ExtensionUpdaterTest
: public testing::Test
{
489 ExtensionUpdaterTest()
491 content::TestBrowserThreadBundle::IO_MAINLOOP
) {
494 virtual void SetUp() OVERRIDE
{
495 prefs_
.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
498 virtual void TearDown() OVERRIDE
{
499 // Some tests create URLRequestContextGetters, whose destruction must run
500 // on the IO thread. Make sure the IO loop spins before shutdown so that
501 // those objects are released.
506 void RunUntilIdle() {
507 prefs_
->pref_service()->CommitPendingWrite();
508 base::RunLoop().RunUntilIdle();
511 void SimulateTimerFired(ExtensionUpdater
* updater
) {
512 EXPECT_TRUE(updater
->timer_
.IsRunning());
513 updater
->timer_
.Stop();
514 updater
->TimerFired();
517 // Adds a Result with the given data to results.
518 void AddParseResult(const std::string
& id
,
519 const std::string
& version
,
520 const std::string
& url
,
521 UpdateManifest::Results
* results
) {
522 UpdateManifest::Result result
;
523 result
.extension_id
= id
;
524 result
.version
= version
;
525 result
.crx_url
= GURL(url
);
526 results
->list
.push_back(result
);
529 void ResetDownloader(ExtensionUpdater
* updater
,
530 ExtensionDownloader
* downloader
) {
531 EXPECT_FALSE(updater
->downloader_
.get());
532 updater
->downloader_
.reset(downloader
);
535 void StartUpdateCheck(ExtensionDownloader
* downloader
,
536 ManifestFetchData
* fetch_data
) {
537 downloader
->StartUpdateCheck(scoped_ptr
<ManifestFetchData
>(fetch_data
));
540 size_t ManifestFetchersCount(ExtensionDownloader
* downloader
) {
541 return downloader
->manifests_queue_
.size() +
542 (downloader
->manifest_fetcher_
.get() ? 1 : 0);
545 void TestExtensionUpdateCheckRequests(bool pending
) {
546 // Create an extension with an update_url.
547 ServiceForManifestTests
service(prefs_
.get());
548 std::string
update_url("http://foo.com/bar");
549 ExtensionList extensions
;
550 NotificationsObserver observer
;
551 PendingExtensionManager
* pending_extension_manager
=
552 service
.pending_extension_manager();
554 SetupPendingExtensionManagerForTest(1, GURL(update_url
),
555 pending_extension_manager
);
557 service
.CreateTestExtensions(1, 1, &extensions
, &update_url
,
559 service
.set_extensions(extensions
);
562 // Set up and start the updater.
563 net::TestURLFetcherFactory factory
;
564 ExtensionUpdater
updater(
565 &service
, service
.extension_prefs(), service
.pref_service(),
566 service
.profile(), 60*60*24);
569 // Tell the update that it's time to do update checks.
570 EXPECT_EQ(0u, observer
.StartedCount());
571 SimulateTimerFired(&updater
);
572 EXPECT_EQ(1u, observer
.StartedCount());
574 // Get the url our mock fetcher was asked to fetch.
575 net::TestURLFetcher
* fetcher
=
576 factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
577 const GURL
& url
= fetcher
->GetOriginalURL();
578 EXPECT_FALSE(url
.is_empty());
579 EXPECT_TRUE(url
.is_valid());
580 EXPECT_TRUE(url
.SchemeIs("http"));
581 EXPECT_EQ("foo.com", url
.host());
582 EXPECT_EQ("/bar", url
.path());
584 // Validate the extension request parameters in the query. It should
585 // look something like "x=id%3D<id>%26v%3D<version>%26uc".
586 EXPECT_TRUE(url
.has_query());
587 std::map
<std::string
, std::string
> params
;
588 VerifyQueryAndExtractParameters(url
.query(), ¶ms
);
590 EXPECT_TRUE(pending_extension_manager
->IsIdPending(params
["id"]));
591 EXPECT_EQ("0.0.0.0", params
["v"]);
593 EXPECT_EQ(extensions
[0]->id(), params
["id"]);
594 EXPECT_EQ(extensions
[0]->VersionString(), params
["v"]);
596 EXPECT_EQ("", params
["uc"]);
599 void TestUpdateUrlDataEmpty() {
600 const std::string id
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
601 const std::string version
= "1.0";
603 // Make sure that an empty update URL data string does not cause a ap=
604 // option to appear in the x= parameter.
605 ManifestFetchData
fetch_data(GURL("http://localhost/foo"), 0);
606 fetch_data
.AddExtension(
607 id
, version
, &kNeverPingedData
, std::string(), std::string());
609 std::map
<std::string
, std::string
> params
;
610 VerifyQueryAndExtractParameters(fetch_data
.full_url().query(), ¶ms
);
611 EXPECT_EQ(id
, params
["id"]);
612 EXPECT_EQ(version
, params
["v"]);
613 EXPECT_EQ(0U, params
.count("ap"));
616 void TestUpdateUrlDataSimple() {
617 const std::string id
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
618 const std::string version
= "1.0";
620 // Make sure that an update URL data string causes an appropriate ap=
621 // option to appear in the x= parameter.
622 ManifestFetchData
fetch_data(GURL("http://localhost/foo"), 0);
623 fetch_data
.AddExtension(
624 id
, version
, &kNeverPingedData
, "bar", std::string());
625 std::map
<std::string
, std::string
> params
;
626 VerifyQueryAndExtractParameters(fetch_data
.full_url().query(), ¶ms
);
627 EXPECT_EQ(id
, params
["id"]);
628 EXPECT_EQ(version
, params
["v"]);
629 EXPECT_EQ("bar", params
["ap"]);
632 void TestUpdateUrlDataCompound() {
633 const std::string id
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
634 const std::string version
= "1.0";
636 // Make sure that an update URL data string causes an appropriate ap=
637 // option to appear in the x= parameter.
638 ManifestFetchData
fetch_data(GURL("http://localhost/foo"), 0);
639 fetch_data
.AddExtension(
640 id
, version
, &kNeverPingedData
, "a=1&b=2&c", std::string());
641 std::map
<std::string
, std::string
> params
;
642 VerifyQueryAndExtractParameters(fetch_data
.full_url().query(), ¶ms
);
643 EXPECT_EQ(id
, params
["id"]);
644 EXPECT_EQ(version
, params
["v"]);
645 EXPECT_EQ("a%3D1%26b%3D2%26c", params
["ap"]);
648 void TestUpdateUrlDataFromGallery(const std::string
& gallery_url
) {
649 net::TestURLFetcherFactory factory
;
651 MockService
service(prefs_
.get());
652 MockExtensionDownloaderDelegate delegate
;
653 ExtensionDownloader
downloader(&delegate
, service
.request_context());
654 ExtensionList extensions
;
655 std::string
url(gallery_url
);
657 service
.CreateTestExtensions(1, 1, &extensions
, &url
, Manifest::INTERNAL
);
659 const std::string
& id
= extensions
[0]->id();
660 EXPECT_CALL(delegate
, GetPingDataForExtension(id
, _
));
662 downloader
.AddExtension(*extensions
[0].get(), 0);
663 downloader
.StartAllPending();
664 net::TestURLFetcher
* fetcher
=
665 factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
666 ASSERT_TRUE(fetcher
);
667 // Make sure that extensions that update from the gallery ignore any
669 const std::string
& update_url
= fetcher
->GetOriginalURL().spec();
670 std::string::size_type x
= update_url
.find("x=");
671 EXPECT_NE(std::string::npos
, x
);
672 std::string::size_type ap
= update_url
.find("ap%3D", x
);
673 EXPECT_EQ(std::string::npos
, ap
);
676 void TestInstallSource() {
677 const std::string id
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
678 const std::string version
= "1.0";
679 const std::string install_source
= "instally";
681 // Make sure that an installsource= appears in the x= parameter.
682 ManifestFetchData
fetch_data(GURL("http://localhost/foo"), 0);
683 fetch_data
.AddExtension(id
, version
, &kNeverPingedData
,
684 kEmptyUpdateUrlData
, install_source
);
685 std::map
<std::string
, std::string
> params
;
686 VerifyQueryAndExtractParameters(fetch_data
.full_url().query(), ¶ms
);
687 EXPECT_EQ(id
, params
["id"]);
688 EXPECT_EQ(version
, params
["v"]);
689 EXPECT_EQ(install_source
, params
["installsource"]);
692 void TestDetermineUpdates() {
693 TestingProfile profile
;
694 MockExtensionDownloaderDelegate delegate
;
695 ExtensionDownloader
downloader(&delegate
, profile
.GetRequestContext());
697 // Check passing an empty list of parse results to DetermineUpdates
698 ManifestFetchData
fetch_data(GURL("http://localhost/foo"), 0);
699 UpdateManifest::Results updates
;
700 std::vector
<int> updateable
;
701 downloader
.DetermineUpdates(fetch_data
, updates
, &updateable
);
702 EXPECT_TRUE(updateable
.empty());
704 // Create two updates - expect that DetermineUpdates will return the first
705 // one (v1.0 installed, v1.1 available) but not the second one (both
706 // installed and available at v2.0).
707 const std::string id1
= id_util::GenerateId("1");
708 const std::string id2
= id_util::GenerateId("2");
709 fetch_data
.AddExtension(
710 id1
, "1.0.0.0", &kNeverPingedData
, kEmptyUpdateUrlData
, std::string());
711 AddParseResult(id1
, "1.1", "http://localhost/e1_1.1.crx", &updates
);
712 fetch_data
.AddExtension(
713 id2
, "2.0.0.0", &kNeverPingedData
, kEmptyUpdateUrlData
, std::string());
714 AddParseResult(id2
, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates
);
716 EXPECT_CALL(delegate
, IsExtensionPending(_
)).WillRepeatedly(Return(false));
717 EXPECT_CALL(delegate
, GetExtensionExistingVersion(id1
, _
))
718 .WillOnce(DoAll(SetArgPointee
<1>("1.0.0.0"),
720 EXPECT_CALL(delegate
, GetExtensionExistingVersion(id2
, _
))
721 .WillOnce(DoAll(SetArgPointee
<1>("2.0.0.0"),
724 downloader
.DetermineUpdates(fetch_data
, updates
, &updateable
);
725 EXPECT_EQ(1u, updateable
.size());
726 EXPECT_EQ(0, updateable
[0]);
729 void TestDetermineUpdatesPending() {
730 // Create a set of test extensions
731 ServiceForManifestTests
service(prefs_
.get());
732 PendingExtensionManager
* pending_extension_manager
=
733 service
.pending_extension_manager();
734 SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager
);
736 TestingProfile profile
;
737 MockExtensionDownloaderDelegate delegate
;
738 ExtensionDownloader
downloader(&delegate
, profile
.GetRequestContext());
740 ManifestFetchData
fetch_data(GURL("http://localhost/foo"), 0);
741 UpdateManifest::Results updates
;
743 std::list
<std::string
> ids_for_update_check
;
744 pending_extension_manager
->GetPendingIdsForUpdateCheck(
745 &ids_for_update_check
);
747 std::list
<std::string
>::const_iterator it
;
748 for (it
= ids_for_update_check
.begin();
749 it
!= ids_for_update_check
.end(); ++it
) {
750 fetch_data
.AddExtension(*it
,
755 AddParseResult(*it
, "1.1", "http://localhost/e1_1.1.crx", &updates
);
758 // The delegate will tell the downloader that all the extensions are
760 EXPECT_CALL(delegate
, IsExtensionPending(_
)).WillRepeatedly(Return(true));
762 std::vector
<int> updateable
;
763 downloader
.DetermineUpdates(fetch_data
, updates
, &updateable
);
764 // All the apps should be updateable.
765 EXPECT_EQ(3u, updateable
.size());
766 for (std::vector
<int>::size_type i
= 0; i
< updateable
.size(); ++i
) {
767 EXPECT_EQ(static_cast<int>(i
), updateable
[i
]);
771 void TestMultipleManifestDownloading() {
772 net::TestURLFetcherFactory factory
;
773 net::TestURLFetcher
* fetcher
= NULL
;
774 NotificationsObserver observer
;
775 MockService
service(prefs_
.get());
776 MockExtensionDownloaderDelegate delegate
;
777 ExtensionDownloader
downloader(&delegate
, service
.request_context());
778 downloader
.manifests_queue_
.set_backoff_policy(&kNoBackoffPolicy
);
780 GURL
kUpdateUrl("http://localhost/manifest1");
782 scoped_ptr
<ManifestFetchData
> fetch1(new ManifestFetchData(kUpdateUrl
, 0));
783 scoped_ptr
<ManifestFetchData
> fetch2(new ManifestFetchData(kUpdateUrl
, 0));
784 scoped_ptr
<ManifestFetchData
> fetch3(new ManifestFetchData(kUpdateUrl
, 0));
785 scoped_ptr
<ManifestFetchData
> fetch4(new ManifestFetchData(kUpdateUrl
, 0));
786 ManifestFetchData::PingData
zeroDays(0, 0, true);
787 fetch1
->AddExtension(
788 "1111", "1.0", &zeroDays
, kEmptyUpdateUrlData
, std::string());
789 fetch2
->AddExtension(
790 "2222", "2.0", &zeroDays
, kEmptyUpdateUrlData
, std::string());
791 fetch3
->AddExtension(
792 "3333", "3.0", &zeroDays
, kEmptyUpdateUrlData
, std::string());
793 fetch4
->AddExtension(
794 "4444", "4.0", &zeroDays
, kEmptyUpdateUrlData
, std::string());
796 // This will start the first fetcher and queue the others. The next in queue
797 // is started as each fetcher receives its response.
798 downloader
.StartUpdateCheck(fetch1
.Pass());
799 downloader
.StartUpdateCheck(fetch2
.Pass());
800 downloader
.StartUpdateCheck(fetch3
.Pass());
801 downloader
.StartUpdateCheck(fetch4
.Pass());
804 // The first fetch will fail.
805 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
806 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
807 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
808 EXPECT_CALL(delegate
, OnExtensionDownloadFailed(
809 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED
, _
, _
));
810 fetcher
->set_url(kUpdateUrl
);
811 fetcher
->set_status(net::URLRequestStatus());
812 fetcher
->set_response_code(400);
813 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
815 Mock::VerifyAndClearExpectations(&delegate
);
817 // The second fetch gets invalid data.
818 const std::string kInvalidXml
= "invalid xml";
819 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
820 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
821 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
822 EXPECT_CALL(delegate
, OnExtensionDownloadFailed(
823 "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID
, _
, _
))
824 .WillOnce(InvokeWithoutArgs(&delegate
,
825 &MockExtensionDownloaderDelegate::Quit
));
826 fetcher
->set_url(kUpdateUrl
);
827 fetcher
->set_status(net::URLRequestStatus());
828 fetcher
->set_response_code(200);
829 fetcher
->SetResponseString(kInvalidXml
);
830 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
832 Mock::VerifyAndClearExpectations(&delegate
);
834 // The third fetcher doesn't have an update available.
835 const std::string kNoUpdate
=
836 "<?xml version='1.0' encoding='UTF-8'?>"
837 "<gupdate xmlns='http://www.google.com/update2/response'"
839 " <app appid='3333'>"
840 " <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'"
841 " version='3.0.0.0' prodversionmin='3.0.0.0' />"
844 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
845 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
846 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
847 EXPECT_CALL(delegate
, IsExtensionPending("3333")).WillOnce(Return(false));
848 EXPECT_CALL(delegate
, GetExtensionExistingVersion("3333", _
))
849 .WillOnce(DoAll(SetArgPointee
<1>("3.0.0.0"),
851 EXPECT_CALL(delegate
, OnExtensionDownloadFailed(
852 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE
, _
, _
))
853 .WillOnce(InvokeWithoutArgs(&delegate
,
854 &MockExtensionDownloaderDelegate::Quit
));
855 fetcher
->set_url(kUpdateUrl
);
856 fetcher
->set_status(net::URLRequestStatus());
857 fetcher
->set_response_code(200);
858 fetcher
->SetResponseString(kNoUpdate
);
859 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
861 Mock::VerifyAndClearExpectations(&delegate
);
863 // The last fetcher has an update.
864 const std::string kUpdateAvailable
=
865 "<?xml version='1.0' encoding='UTF-8'?>"
866 "<gupdate xmlns='http://www.google.com/update2/response'"
868 " <app appid='4444'>"
869 " <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
870 " version='4.0.42.0' prodversionmin='4.0.42.0' />"
873 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
874 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
875 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
876 EXPECT_CALL(delegate
, IsExtensionPending("4444")).WillOnce(Return(false));
877 EXPECT_CALL(delegate
, GetExtensionExistingVersion("4444", _
))
878 .WillOnce(DoAll(SetArgPointee
<1>("4.0.0.0"),
880 fetcher
->set_url(kUpdateUrl
);
881 fetcher
->set_status(net::URLRequestStatus());
882 fetcher
->set_response_code(200);
883 fetcher
->SetResponseString(kUpdateAvailable
);
884 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
886 Mock::VerifyAndClearExpectations(&delegate
);
888 // Verify that the downloader decided to update this extension.
889 EXPECT_EQ(1u, observer
.UpdatedCount());
890 EXPECT_TRUE(observer
.Updated("4444"));
893 void TestManifestRetryDownloading() {
894 net::TestURLFetcherFactory factory
;
895 net::TestURLFetcher
* fetcher
= NULL
;
896 NotificationsObserver observer
;
897 MockService
service(prefs_
.get());
898 MockExtensionDownloaderDelegate delegate
;
899 ExtensionDownloader
downloader(&delegate
, service
.request_context());
900 downloader
.manifests_queue_
.set_backoff_policy(&kNoBackoffPolicy
);
902 GURL
kUpdateUrl("http://localhost/manifest1");
904 scoped_ptr
<ManifestFetchData
> fetch(new ManifestFetchData(kUpdateUrl
, 0));
905 ManifestFetchData::PingData
zeroDays(0, 0, true);
907 "1111", "1.0", &zeroDays
, kEmptyUpdateUrlData
, std::string());
909 // This will start the first fetcher.
910 downloader
.StartUpdateCheck(fetch
.Pass());
913 // ExtensionDownloader should retry kMaxRetries times and then fail.
914 EXPECT_CALL(delegate
, OnExtensionDownloadFailed(
915 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED
, _
, _
));
916 for (int i
= 0; i
<= ExtensionDownloader::kMaxRetries
; ++i
) {
917 // All fetches will fail.
918 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
919 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
920 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
921 fetcher
->set_url(kUpdateUrl
);
922 fetcher
->set_status(net::URLRequestStatus());
923 // Code 5xx causes ExtensionDownloader to retry.
924 fetcher
->set_response_code(500);
925 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
928 Mock::VerifyAndClearExpectations(&delegate
);
931 // For response codes that are not in the 5xx range ExtensionDownloader
933 fetch
.reset(new ManifestFetchData(kUpdateUrl
, 0));
935 "1111", "1.0", &zeroDays
, kEmptyUpdateUrlData
, std::string());
937 // This will start the first fetcher.
938 downloader
.StartUpdateCheck(fetch
.Pass());
941 EXPECT_CALL(delegate
, OnExtensionDownloadFailed(
942 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED
, _
, _
));
943 // The first fetch will fail, and require retrying.
944 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
945 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
946 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
947 fetcher
->set_url(kUpdateUrl
);
948 fetcher
->set_status(net::URLRequestStatus());
949 fetcher
->set_response_code(500);
950 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
953 // The second fetch will fail with response 400 and should not cause
954 // ExtensionDownloader to retry.
955 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
956 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
957 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
958 fetcher
->set_url(kUpdateUrl
);
959 fetcher
->set_status(net::URLRequestStatus());
960 fetcher
->set_response_code(400);
961 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
964 Mock::VerifyAndClearExpectations(&delegate
);
967 void TestSingleExtensionDownloading(bool pending
, bool retry
) {
968 net::TestURLFetcherFactory factory
;
969 net::TestURLFetcher
* fetcher
= NULL
;
970 scoped_ptr
<ServiceForDownloadTests
> service(
971 new ServiceForDownloadTests(prefs_
.get()));
972 ExtensionUpdater
updater(service
.get(), service
->extension_prefs(),
973 service
->pref_service(),
975 kUpdateFrequencySecs
);
979 new ExtensionDownloader(&updater
, service
->request_context()));
980 updater
.downloader_
->extensions_queue_
.set_backoff_policy(
983 GURL
test_url("http://localhost/extension.crx");
985 std::string id
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
987 Version
version("0.0.1");
988 std::set
<int> requests
;
990 scoped_ptr
<ExtensionDownloader::ExtensionFetch
> fetch(
991 new ExtensionDownloader::ExtensionFetch(
992 id
, test_url
, hash
, version
.GetString(), requests
));
993 updater
.downloader_
->FetchUpdatedExtension(fetch
.Pass());
996 const bool kIsFromSync
= true;
997 const bool kInstallSilently
= true;
998 const bool kMarkAcknowledged
= false;
999 PendingExtensionManager
* pending_extension_manager
=
1000 service
->pending_extension_manager();
1001 pending_extension_manager
->AddForTesting(
1002 PendingExtensionInfo(id
, test_url
, version
,
1003 &ShouldAlwaysInstall
, kIsFromSync
,
1006 Extension::NO_FLAGS
,
1007 kMarkAcknowledged
));
1010 // Call back the ExtensionUpdater with a 200 response and some test data
1011 base::FilePath
extension_file_path(FILE_PATH_LITERAL("/whatever"));
1012 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId
);
1013 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
1014 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
1017 // Reply with response code 500 to cause ExtensionDownloader to retry
1018 fetcher
->set_url(test_url
);
1019 fetcher
->set_status(net::URLRequestStatus());
1020 fetcher
->set_response_code(500);
1021 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
1024 fetcher
= factory
.GetFetcherByID(
1025 ExtensionDownloader::kExtensionFetcherId
);
1026 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
1027 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
1030 fetcher
->set_url(test_url
);
1031 fetcher
->set_status(net::URLRequestStatus());
1032 fetcher
->set_response_code(200);
1033 fetcher
->SetResponseFilePath(extension_file_path
);
1034 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
1038 // Expect that ExtensionUpdater asked the mock extensions service to install
1039 // a file with the test data for the right id.
1040 EXPECT_EQ(id
, service
->extension_id());
1041 base::FilePath tmpfile_path
= service
->install_path();
1042 EXPECT_FALSE(tmpfile_path
.empty());
1043 EXPECT_EQ(test_url
, service
->download_url());
1044 EXPECT_EQ(extension_file_path
, tmpfile_path
);
1047 // Two extensions are updated. If |updates_start_running| is true, the
1048 // mock extensions service has UpdateExtension(...) return true, and
1049 // the test is responsible for creating fake CrxInstallers. Otherwise,
1050 // UpdateExtension() returns false, signaling install failures.
1051 void TestMultipleExtensionDownloading(bool updates_start_running
) {
1052 net::TestURLFetcherFactory factory
;
1053 net::TestURLFetcher
* fetcher
= NULL
;
1054 ServiceForDownloadTests
service(prefs_
.get());
1055 ExtensionUpdater
updater(
1056 &service
, service
.extension_prefs(), service
.pref_service(),
1057 service
.profile(), kUpdateFrequencySecs
);
1061 new ExtensionDownloader(&updater
, service
.request_context()));
1062 updater
.downloader_
->extensions_queue_
.set_backoff_policy(
1065 EXPECT_FALSE(updater
.crx_install_is_running_
);
1067 GURL
url1("http://localhost/extension1.crx");
1068 GURL
url2("http://localhost/extension2.crx");
1070 std::string id1
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1071 std::string id2
= "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
1076 std::string version1
= "0.1";
1077 std::string version2
= "0.1";
1078 std::set
<int> requests
;
1080 // Start two fetches
1081 scoped_ptr
<ExtensionDownloader::ExtensionFetch
> fetch1(
1082 new ExtensionDownloader::ExtensionFetch(
1083 id1
, url1
, hash1
, version1
, requests
));
1084 scoped_ptr
<ExtensionDownloader::ExtensionFetch
> fetch2(
1085 new ExtensionDownloader::ExtensionFetch(
1086 id2
, url2
, hash2
, version2
, requests
));
1087 updater
.downloader_
->FetchUpdatedExtension(fetch1
.Pass());
1088 updater
.downloader_
->FetchUpdatedExtension(fetch2
.Pass());
1090 // Make the first fetch complete.
1091 base::FilePath
extension_file_path(FILE_PATH_LITERAL("/whatever"));
1093 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId
);
1094 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
1095 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
1097 // We need some CrxInstallers, and CrxInstallers require a real
1098 // ExtensionService. Create one on the testing profile. Any action
1099 // the CrxInstallers take is on the testing profile's extension
1100 // service, not on our mock |service|. This allows us to fake
1101 // the CrxInstaller actions we want.
1102 TestingProfile profile
;
1103 static_cast<TestExtensionSystem
*>(
1104 ExtensionSystem::Get(&profile
))->
1105 CreateExtensionService(
1106 CommandLine::ForCurrentProcess(),
1109 ExtensionService
* extension_service
=
1110 ExtensionSystem::Get(&profile
)->extension_service();
1111 extension_service
->set_extensions_enabled(true);
1112 extension_service
->set_show_extensions_prompts(false);
1114 scoped_refptr
<CrxInstaller
> fake_crx1(
1115 CrxInstaller::CreateSilent(extension_service
));
1116 scoped_refptr
<CrxInstaller
> fake_crx2(
1117 CrxInstaller::CreateSilent(extension_service
));
1119 if (updates_start_running
) {
1120 // Add fake CrxInstaller to be returned by service.UpdateExtension().
1121 service
.AddFakeCrxInstaller(id1
, fake_crx1
.get());
1122 service
.AddFakeCrxInstaller(id2
, fake_crx2
.get());
1124 // If we don't add fake CRX installers, the mock service fakes a failure
1125 // starting the install.
1128 fetcher
->set_url(url1
);
1129 fetcher
->set_status(net::URLRequestStatus());
1130 fetcher
->set_response_code(200);
1131 fetcher
->SetResponseFilePath(extension_file_path
);
1132 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
1136 // Expect that the service was asked to do an install with the right data.
1137 base::FilePath tmpfile_path
= service
.install_path();
1138 EXPECT_FALSE(tmpfile_path
.empty());
1139 EXPECT_EQ(id1
, service
.extension_id());
1140 EXPECT_EQ(url1
, service
.download_url());
1143 // Make sure the second fetch finished and asked the service to do an
1145 base::FilePath
extension_file_path2(FILE_PATH_LITERAL("/whatever2"));
1146 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId
);
1147 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
1148 EXPECT_TRUE(fetcher
->GetLoadFlags() == kExpectedLoadFlags
);
1150 fetcher
->set_url(url2
);
1151 fetcher
->set_status(net::URLRequestStatus());
1152 fetcher
->set_response_code(200);
1153 fetcher
->SetResponseFilePath(extension_file_path2
);
1154 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
1157 if (updates_start_running
) {
1158 EXPECT_TRUE(updater
.crx_install_is_running_
);
1160 // The second install should not have run, because the first has not
1161 // sent a notification that it finished.
1162 EXPECT_EQ(id1
, service
.extension_id());
1163 EXPECT_EQ(url1
, service
.download_url());
1165 // Fake install notice. This should start the second installation,
1166 // which will be checked below.
1167 fake_crx1
->NotifyCrxInstallComplete(false);
1169 EXPECT_TRUE(updater
.crx_install_is_running_
);
1172 EXPECT_EQ(id2
, service
.extension_id());
1173 EXPECT_EQ(url2
, service
.download_url());
1174 EXPECT_FALSE(service
.install_path().empty());
1176 // Make sure the correct crx contents were passed for the update call.
1177 EXPECT_EQ(extension_file_path2
, service
.install_path());
1179 if (updates_start_running
) {
1180 EXPECT_TRUE(updater
.crx_install_is_running_
);
1181 fake_crx2
->NotifyCrxInstallComplete(false);
1183 EXPECT_FALSE(updater
.crx_install_is_running_
);
1186 void TestGalleryRequestsWithBrand(bool use_organic_brand_code
) {
1187 google_util::BrandForTesting
brand_for_testing(
1188 use_organic_brand_code
? "GGLS" : "TEST");
1190 // We want to test a variety of combinations of expected ping conditions for
1191 // rollcall and active pings.
1192 int ping_cases
[] = { ManifestFetchData::kNeverPinged
, 0, 1, 5 };
1194 for (size_t i
= 0; i
< arraysize(ping_cases
); i
++) {
1195 for (size_t j
= 0; j
< arraysize(ping_cases
); j
++) {
1196 for (size_t k
= 0; k
< 2; k
++) {
1197 int rollcall_ping_days
= ping_cases
[i
];
1198 int active_ping_days
= ping_cases
[j
];
1199 // Skip cases where rollcall_ping_days == -1, but
1200 // active_ping_days > 0, because rollcall_ping_days == -1 means the
1201 // app was just installed and this is the first update check after
1203 if (rollcall_ping_days
== ManifestFetchData::kNeverPinged
&&
1204 active_ping_days
> 0)
1207 bool active_bit
= k
> 0;
1208 TestGalleryRequests(rollcall_ping_days
, active_ping_days
, active_bit
,
1209 !use_organic_brand_code
);
1210 ASSERT_FALSE(HasFailure()) <<
1211 " rollcall_ping_days=" << ping_cases
[i
] <<
1212 " active_ping_days=" << ping_cases
[j
] <<
1213 " active_bit=" << active_bit
;
1219 // Test requests to both a Google server and a non-google server. This allows
1220 // us to test various combinations of installed (ie roll call) and active
1221 // (ie app launch) ping scenarios. The invariant is that each type of ping
1222 // value should be present at most once per day, and can be calculated based
1223 // on the delta between now and the last ping time (or in the case of active
1224 // pings, that delta plus whether the app has been active).
1225 void TestGalleryRequests(int rollcall_ping_days
,
1226 int active_ping_days
,
1228 bool expect_brand_code
) {
1229 net::TestURLFetcherFactory factory
;
1231 // Set up 2 mock extensions, one with a google.com update url and one
1233 prefs_
.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
1234 ServiceForManifestTests
service(prefs_
.get());
1236 GURL
url1("http://clients2.google.com/service/update2/crx");
1237 GURL
url2("http://www.somewebsite.com");
1238 service
.CreateTestExtensions(1, 1, &tmp
, &url1
.possibly_invalid_spec(),
1239 Manifest::INTERNAL
);
1240 service
.CreateTestExtensions(2, 1, &tmp
, &url2
.possibly_invalid_spec(),
1241 Manifest::INTERNAL
);
1242 EXPECT_EQ(2u, tmp
.size());
1243 service
.set_extensions(tmp
);
1245 ExtensionPrefs
* prefs
= service
.extension_prefs();
1246 const std::string
& id
= tmp
[0]->id();
1247 Time now
= Time::Now();
1248 if (rollcall_ping_days
== 0) {
1249 prefs
->SetLastPingDay(id
, now
- TimeDelta::FromSeconds(15));
1250 } else if (rollcall_ping_days
> 0) {
1251 Time last_ping_day
= now
-
1252 TimeDelta::FromDays(rollcall_ping_days
) -
1253 TimeDelta::FromSeconds(15);
1254 prefs
->SetLastPingDay(id
, last_ping_day
);
1257 // Store a value for the last day we sent an active ping.
1258 if (active_ping_days
== 0) {
1259 prefs
->SetLastActivePingDay(id
, now
- TimeDelta::FromSeconds(15));
1260 } else if (active_ping_days
> 0) {
1261 Time last_active_ping_day
= now
-
1262 TimeDelta::FromDays(active_ping_days
) -
1263 TimeDelta::FromSeconds(15);
1264 prefs
->SetLastActivePingDay(id
, last_active_ping_day
);
1267 prefs
->SetActiveBit(id
, true);
1269 ExtensionUpdater
updater(
1270 &service
, service
.extension_prefs(), service
.pref_service(),
1271 service
.profile(), kUpdateFrequencySecs
);
1272 ExtensionUpdater::CheckParams params
;
1274 updater
.CheckNow(params
);
1276 // Make the updater do manifest fetching, and note the urls it tries to
1278 std::vector
<GURL
> fetched_urls
;
1279 net::TestURLFetcher
* fetcher
=
1280 factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
1281 EXPECT_TRUE(fetcher
!= NULL
&& fetcher
->delegate() != NULL
);
1282 fetched_urls
.push_back(fetcher
->GetOriginalURL());
1284 fetcher
->set_url(fetched_urls
[0]);
1285 fetcher
->set_status(net::URLRequestStatus());
1286 fetcher
->set_response_code(500);
1287 fetcher
->SetResponseString(std::string());
1288 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
1290 fetcher
= factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
1291 fetched_urls
.push_back(fetcher
->GetOriginalURL());
1293 // The urls could have been fetched in either order, so use the host to
1294 // tell them apart and note the query each used.
1295 std::string url1_query
;
1296 std::string url2_query
;
1297 if (fetched_urls
[0].host() == url1
.host()) {
1298 url1_query
= fetched_urls
[0].query();
1299 url2_query
= fetched_urls
[1].query();
1300 } else if (fetched_urls
[0].host() == url2
.host()) {
1301 url1_query
= fetched_urls
[1].query();
1302 url2_query
= fetched_urls
[0].query();
1307 // First make sure the non-google query had no ping parameter.
1308 std::string search_string
= "ping%3D";
1309 EXPECT_TRUE(url2_query
.find(search_string
) == std::string::npos
);
1311 // Now make sure the google query had the correct ping parameter.
1312 bool ping_expected
= false;
1313 bool did_rollcall
= false;
1314 if (rollcall_ping_days
!= 0) {
1315 search_string
+= "r%253D" + base::IntToString(rollcall_ping_days
);
1316 did_rollcall
= true;
1317 ping_expected
= true;
1319 if (active_bit
&& active_ping_days
!= 0) {
1321 search_string
+= "%2526";
1322 search_string
+= "a%253D" + base::IntToString(active_ping_days
);
1323 ping_expected
= true;
1325 bool ping_found
= url1_query
.find(search_string
) != std::string::npos
;
1326 EXPECT_EQ(ping_expected
, ping_found
) << "query was: " << url1_query
1327 << " was looking for " << search_string
;
1329 // Make sure the non-google query has no brand parameter.
1330 const std::string brand_string
= "brand%3D";
1331 EXPECT_TRUE(url2_query
.find(brand_string
) == std::string::npos
);
1333 #if defined(GOOGLE_CHROME_BUILD)
1334 // Make sure the google query has a brand parameter, but only if the
1335 // brand is non-organic.
1336 if (expect_brand_code
) {
1337 EXPECT_TRUE(url1_query
.find(brand_string
) != std::string::npos
);
1339 EXPECT_TRUE(url1_query
.find(brand_string
) == std::string::npos
);
1342 // Chromium builds never add the brand to the parameter, even for google
1344 EXPECT_TRUE(url1_query
.find(brand_string
) == std::string::npos
);
1350 // This makes sure that the extension updater properly stores the results
1351 // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
1352 // the first time we fetched the extension, or 2) We sent a ping value of
1353 // >= 1 day for the extension.
1354 void TestHandleManifestResults() {
1355 ServiceForManifestTests
service(prefs_
.get());
1356 GURL
update_url("http://www.google.com/manifest");
1358 service
.CreateTestExtensions(1, 1, &tmp
, &update_url
.spec(),
1359 Manifest::INTERNAL
);
1360 service
.set_extensions(tmp
);
1362 ExtensionUpdater
updater(
1363 &service
, service
.extension_prefs(), service
.pref_service(),
1364 service
.profile(), kUpdateFrequencySecs
);
1368 new ExtensionDownloader(&updater
, service
.request_context()));
1370 ManifestFetchData
fetch_data(update_url
, 0);
1371 const Extension
* extension
= tmp
[0].get();
1372 fetch_data
.AddExtension(extension
->id(),
1373 extension
->VersionString(),
1375 kEmptyUpdateUrlData
,
1377 UpdateManifest::Results results
;
1378 results
.daystart_elapsed_seconds
= 750;
1380 updater
.downloader_
->HandleManifestResults(fetch_data
, &results
);
1381 Time last_ping_day
=
1382 service
.extension_prefs()->LastPingDay(extension
->id());
1383 EXPECT_FALSE(last_ping_day
.is_null());
1384 int64 seconds_diff
= (Time::Now() - last_ping_day
).InSeconds();
1385 EXPECT_LT(seconds_diff
- results
.daystart_elapsed_seconds
, 5);
1389 scoped_ptr
<TestExtensionPrefs
> prefs_
;
1392 content::TestBrowserThreadBundle thread_bundle_
;
1393 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_
;
1395 #if defined OS_CHROMEOS
1396 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
1397 chromeos::ScopedTestCrosSettings test_cros_settings_
;
1398 chromeos::ScopedTestUserManager test_user_manager_
;
1402 // Because we test some private methods of ExtensionUpdater, it's easier for the
1403 // actual test code to live in ExtenionUpdaterTest methods instead of TEST_F
1404 // subclasses where friendship with ExtenionUpdater is not inherited.
1406 TEST_F(ExtensionUpdaterTest
, TestExtensionUpdateCheckRequests
) {
1407 TestExtensionUpdateCheckRequests(false);
1410 TEST_F(ExtensionUpdaterTest
, TestExtensionUpdateCheckRequestsPending
) {
1411 TestExtensionUpdateCheckRequests(true);
1414 TEST_F(ExtensionUpdaterTest
, TestUpdateUrlData
) {
1415 TestUpdateUrlDataEmpty();
1416 TestUpdateUrlDataSimple();
1417 TestUpdateUrlDataCompound();
1418 TestUpdateUrlDataFromGallery(
1419 extension_urls::GetWebstoreUpdateUrl().spec());
1422 TEST_F(ExtensionUpdaterTest
, TestInstallSource
) {
1423 TestInstallSource();
1426 TEST_F(ExtensionUpdaterTest
, TestDetermineUpdates
) {
1427 TestDetermineUpdates();
1430 TEST_F(ExtensionUpdaterTest
, TestDetermineUpdatesPending
) {
1431 TestDetermineUpdatesPending();
1434 TEST_F(ExtensionUpdaterTest
, TestMultipleManifestDownloading
) {
1435 TestMultipleManifestDownloading();
1438 TEST_F(ExtensionUpdaterTest
, TestSingleExtensionDownloading
) {
1439 TestSingleExtensionDownloading(false, false);
1442 TEST_F(ExtensionUpdaterTest
, TestSingleExtensionDownloadingPending
) {
1443 TestSingleExtensionDownloading(true, false);
1446 TEST_F(ExtensionUpdaterTest
, TestSingleExtensionDownloadingWithRetry
) {
1447 TestSingleExtensionDownloading(false, true);
1450 TEST_F(ExtensionUpdaterTest
, TestSingleExtensionDownloadingPendingWithRetry
) {
1451 TestSingleExtensionDownloading(true, true);
1454 TEST_F(ExtensionUpdaterTest
, TestMultipleExtensionDownloadingUpdatesFail
) {
1455 TestMultipleExtensionDownloading(false);
1457 TEST_F(ExtensionUpdaterTest
, TestMultipleExtensionDownloadingUpdatesSucceed
) {
1458 TestMultipleExtensionDownloading(true);
1461 TEST_F(ExtensionUpdaterTest
, TestManifestRetryDownloading
) {
1462 TestManifestRetryDownloading();
1465 TEST_F(ExtensionUpdaterTest
, TestGalleryRequestsWithOrganicBrand
) {
1466 TestGalleryRequestsWithBrand(true);
1469 TEST_F(ExtensionUpdaterTest
, TestGalleryRequestsWithNonOrganicBrand
) {
1470 TestGalleryRequestsWithBrand(false);
1473 TEST_F(ExtensionUpdaterTest
, TestHandleManifestResults
) {
1474 TestHandleManifestResults();
1477 TEST_F(ExtensionUpdaterTest
, TestNonAutoUpdateableLocations
) {
1478 net::TestURLFetcherFactory factory
;
1479 ServiceForManifestTests
service(prefs_
.get());
1480 ExtensionUpdater
updater(&service
, service
.extension_prefs(),
1481 service
.pref_service(), service
.profile(),
1482 kUpdateFrequencySecs
);
1483 MockExtensionDownloaderDelegate delegate
;
1484 // Set the downloader directly, so that all its events end up in the mock
1486 ExtensionDownloader
* downloader
=
1487 new ExtensionDownloader(&delegate
, service
.request_context());
1488 ResetDownloader(&updater
, downloader
);
1490 // Non-internal non-external extensions should be rejected.
1491 ExtensionList extensions
;
1492 service
.CreateTestExtensions(1, 1, &extensions
, NULL
,
1493 Manifest::INVALID_LOCATION
);
1494 service
.CreateTestExtensions(2, 1, &extensions
, NULL
, Manifest::INTERNAL
);
1495 ASSERT_EQ(2u, extensions
.size());
1496 const std::string
& updateable_id
= extensions
[1]->id();
1498 // These expectations fail if the delegate's methods are invoked for the
1499 // first extension, which has a non-matching id.
1500 EXPECT_CALL(delegate
, GetUpdateUrlData(updateable_id
)).WillOnce(Return(""));
1501 EXPECT_CALL(delegate
, GetPingDataForExtension(updateable_id
, _
));
1503 service
.set_extensions(extensions
);
1504 ExtensionUpdater::CheckParams params
;
1506 updater
.CheckNow(params
);
1509 TEST_F(ExtensionUpdaterTest
, TestUpdatingDisabledExtensions
) {
1510 net::TestURLFetcherFactory factory
;
1511 ServiceForManifestTests
service(prefs_
.get());
1512 ExtensionUpdater
updater(&service
, service
.extension_prefs(),
1513 service
.pref_service(), service
.profile(),
1514 kUpdateFrequencySecs
);
1515 MockExtensionDownloaderDelegate delegate
;
1516 // Set the downloader directly, so that all its events end up in the mock
1518 ExtensionDownloader
* downloader
=
1519 new ExtensionDownloader(&delegate
, service
.request_context());
1520 ResetDownloader(&updater
, downloader
);
1522 // Non-internal non-external extensions should be rejected.
1523 ExtensionList enabled_extensions
;
1524 ExtensionList disabled_extensions
;
1525 service
.CreateTestExtensions(1, 1, &enabled_extensions
, NULL
,
1526 Manifest::INTERNAL
);
1527 service
.CreateTestExtensions(2, 1, &disabled_extensions
, NULL
,
1528 Manifest::INTERNAL
);
1529 ASSERT_EQ(1u, enabled_extensions
.size());
1530 ASSERT_EQ(1u, disabled_extensions
.size());
1531 const std::string
& enabled_id
= enabled_extensions
[0]->id();
1532 const std::string
& disabled_id
= disabled_extensions
[0]->id();
1534 // We expect that both enabled and disabled extensions are auto-updated.
1535 EXPECT_CALL(delegate
, GetUpdateUrlData(enabled_id
)).WillOnce(Return(""));
1536 EXPECT_CALL(delegate
, GetPingDataForExtension(enabled_id
, _
));
1537 EXPECT_CALL(delegate
, GetUpdateUrlData(disabled_id
)).WillOnce(Return(""));
1538 EXPECT_CALL(delegate
, GetPingDataForExtension(disabled_id
, _
));
1540 service
.set_extensions(enabled_extensions
);
1541 service
.set_disabled_extensions(disabled_extensions
);
1542 ExtensionUpdater::CheckParams params
;
1544 updater
.CheckNow(params
);
1547 TEST_F(ExtensionUpdaterTest
, TestManifestFetchesBuilderAddExtension
) {
1548 net::TestURLFetcherFactory factory
;
1549 MockService
service(prefs_
.get());
1550 MockExtensionDownloaderDelegate delegate
;
1551 scoped_ptr
<ExtensionDownloader
> downloader(
1552 new ExtensionDownloader(&delegate
, service
.request_context()));
1553 EXPECT_EQ(0u, ManifestFetchersCount(downloader
.get()));
1555 // First, verify that adding valid extensions does invoke the callbacks on
1557 std::string id
= id_util::GenerateId("foo");
1558 EXPECT_CALL(delegate
, GetPingDataForExtension(id
, _
)).WillOnce(Return(false));
1560 downloader
->AddPendingExtension(id
, GURL("http://example.com/update"),
1562 downloader
->StartAllPending();
1563 Mock::VerifyAndClearExpectations(&delegate
);
1564 EXPECT_EQ(1u, ManifestFetchersCount(downloader
.get()));
1566 // Extensions with invalid update URLs should be rejected.
1567 id
= id_util::GenerateId("foo2");
1569 downloader
->AddPendingExtension(id
, GURL("http:google.com:foo"), 0));
1570 downloader
->StartAllPending();
1571 EXPECT_EQ(1u, ManifestFetchersCount(downloader
.get()));
1573 // Extensions with empty IDs should be rejected.
1574 EXPECT_FALSE(downloader
->AddPendingExtension(std::string(), GURL(), 0));
1575 downloader
->StartAllPending();
1576 EXPECT_EQ(1u, ManifestFetchersCount(downloader
.get()));
1578 // TODO(akalin): Test that extensions with empty update URLs
1579 // converted from user scripts are rejected.
1581 // Reset the ExtensionDownloader so that it drops the current fetcher.
1583 new ExtensionDownloader(&delegate
, service
.request_context()));
1584 EXPECT_EQ(0u, ManifestFetchersCount(downloader
.get()));
1586 // Extensions with empty update URLs should have a default one
1588 id
= id_util::GenerateId("foo3");
1589 EXPECT_CALL(delegate
, GetPingDataForExtension(id
, _
)).WillOnce(Return(false));
1590 EXPECT_TRUE(downloader
->AddPendingExtension(id
, GURL(), 0));
1591 downloader
->StartAllPending();
1592 EXPECT_EQ(1u, ManifestFetchersCount(downloader
.get()));
1594 net::TestURLFetcher
* fetcher
=
1595 factory
.GetFetcherByID(ExtensionDownloader::kManifestFetcherId
);
1596 ASSERT_TRUE(fetcher
);
1597 EXPECT_FALSE(fetcher
->GetOriginalURL().is_empty());
1600 TEST_F(ExtensionUpdaterTest
, TestStartUpdateCheckMemory
) {
1601 net::TestURLFetcherFactory factory
;
1602 MockService
service(prefs_
.get());
1603 MockExtensionDownloaderDelegate delegate
;
1604 ExtensionDownloader
downloader(&delegate
, service
.request_context());
1606 StartUpdateCheck(&downloader
, new ManifestFetchData(GURL(), 0));
1607 // This should delete the newly-created ManifestFetchData.
1608 StartUpdateCheck(&downloader
, new ManifestFetchData(GURL(), 0));
1609 // This should add into |manifests_pending_|.
1610 StartUpdateCheck(&downloader
, new ManifestFetchData(GURL(
1611 GURL("http://www.google.com")), 0));
1612 // The dtor of |downloader| should delete the pending fetchers.
1615 TEST_F(ExtensionUpdaterTest
, TestCheckSoon
) {
1616 ServiceForManifestTests
service(prefs_
.get());
1617 net::TestURLFetcherFactory factory
;
1618 ExtensionUpdater
updater(
1619 &service
, service
.extension_prefs(), service
.pref_service(),
1620 service
.profile(), kUpdateFrequencySecs
);
1621 EXPECT_FALSE(updater
.WillCheckSoon());
1623 EXPECT_FALSE(updater
.WillCheckSoon());
1624 updater
.CheckSoon();
1625 EXPECT_TRUE(updater
.WillCheckSoon());
1626 updater
.CheckSoon();
1627 EXPECT_TRUE(updater
.WillCheckSoon());
1629 EXPECT_FALSE(updater
.WillCheckSoon());
1630 updater
.CheckSoon();
1631 EXPECT_TRUE(updater
.WillCheckSoon());
1633 EXPECT_FALSE(updater
.WillCheckSoon());
1636 // TODO(asargent) - (http://crbug.com/12780) add tests for:
1637 // -prodversionmin (shouldn't update if browser version too old)
1638 // -manifests & updates arriving out of order / interleaved
1639 // -malformed update url (empty, file://, has query, has a # fragment, etc.)
1640 // -An extension gets uninstalled while updates are in progress (so it doesn't
1641 // "come back from the dead")
1642 // -An extension gets manually updated to v3 while we're downloading v2 (ie
1643 // you don't get downgraded accidentally)
1644 // -An update manifest mentions multiple updates
1646 } // namespace extensions