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.
4
5 #include <list>
6 #include <map>
7 #include <set>
8 #include <vector>
9
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/browser/render_process_host.h"
50 #include "content/public/test/test_browser_thread_bundle.h"
51 #include "content/public/test/test_utils.h"
52 #include "extensions/common/extension.h"
53 #include "extensions/common/id_util.h"
54 #include "extensions/common/manifest_constants.h"
55 #include "libxml/globals.h"
56 #include "net/base/backoff_entry.h"
57 #include "net/base/escape.h"
58 #include "net/base/load_flags.h"
59 #include "net/url_request/test_url_fetcher_factory.h"
60 #include "net/url_request/url_request_status.h"
61 #include "testing/gmock/include/gmock/gmock.h"
62 #include "testing/gtest/include/gtest/gtest.h"
63
64 #if defined(OS_CHROMEOS)
65 #include "chrome/browser/chromeos/login/user_manager.h"
66 #include "chrome/browser/chromeos/settings/cros_settings.h"
67 #include "chrome/browser/chromeos/settings/device_settings_service.h"
68 #endif
69
70 using base::Time;
71 using base::TimeDelta;
72 using content::BrowserThread;
73 using testing::DoAll;
74 using testing::InvokeWithoutArgs;
75 using testing::Mock;
76 using testing::Return;
77 using testing::SetArgPointee;
78 using testing::_;
79
80 namespace extensions {
81
82 typedef ExtensionDownloaderDelegate::Error Error;
83 typedef ExtensionDownloaderDelegate::PingResult PingResult;
84
85 namespace {
86
87 const net::BackoffEntry::Policy kNoBackoffPolicy = {
88 // Number of initial errors (in sequence) to ignore before applying
89 // exponential back-off rules.
90 1000,
91
92 // Initial delay for exponential back-off in ms.
93 0,
94
95 // Factor by which the waiting time will be multiplied.
96 0,
97
98 // Fuzzing percentage. ex: 10% will spread requests randomly
99 // between 90%-100% of the calculated time.
100 0,
101
102 // Maximum amount of time we are willing to delay our request in ms.
103 0,
104
105 // Time to keep an entry from being discarded even when it
106 // has no significant state, -1 to never discard.
107 -1,
108
109 // Don't use initial delay unless the last request was an error.
110 false,
111 };
112
113 const char kEmptyUpdateUrlData[] = "";
114
115 int kExpectedLoadFlags =
116 net::LOAD_DO_NOT_SEND_COOKIES |
117 net::LOAD_DO_NOT_SAVE_COOKIES |
118 net::LOAD_DISABLE_CACHE;
119
120 const ManifestFetchData::PingData kNeverPingedData(
121 ManifestFetchData::kNeverPinged, ManifestFetchData::kNeverPinged, true);
122
123 class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate {
124 public:
125 MOCK_METHOD4(OnExtensionDownloadFailed, void(const std::string&,
126 Error,
127 const PingResult&,
128 const std::set<int>&));
129 MOCK_METHOD6(OnExtensionDownloadFinished, void(const std::string&,
130 const base::FilePath&,
131 const GURL&,
132 const std::string&,
133 const PingResult&,
134 const std::set<int>&));
135 MOCK_METHOD2(GetPingDataForExtension,
136 bool(const std::string&, ManifestFetchData::PingData*));
137 MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&));
138 MOCK_METHOD1(IsExtensionPending, bool(const std::string&));
139 MOCK_METHOD2(GetExtensionExistingVersion,
140 bool(const std::string&, std::string*));
141
Wait()142 void Wait() {
143 scoped_refptr<content::MessageLoopRunner> runner =
144 new content::MessageLoopRunner;
145 quit_closure_ = runner->QuitClosure();
146 runner->Run();
147 quit_closure_.Reset();
148 }
149
Quit()150 void Quit() {
151 quit_closure_.Run();
152 }
153
154 private:
155 base::Closure quit_closure_;
156 };
157
158 const int kNotificationsObserved[] = {
159 chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED,
160 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
161 };
162
163 // A class that observes the notifications sent by the ExtensionUpdater and
164 // the ExtensionDownloader.
165 class NotificationsObserver : public content::NotificationObserver {
166 public:
NotificationsObserver()167 NotificationsObserver() {
168 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
169 count_[i] = 0;
170 registrar_.Add(this,
171 kNotificationsObserved[i],
172 content::NotificationService::AllSources());
173 }
174 }
175
~NotificationsObserver()176 virtual ~NotificationsObserver() {
177 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
178 registrar_.Remove(this,
179 kNotificationsObserved[i],
180 content::NotificationService::AllSources());
181 }
182 }
183
StartedCount()184 size_t StartedCount() { return count_[0]; }
UpdatedCount()185 size_t UpdatedCount() { return count_[1]; }
186
Updated(const std::string & id)187 bool Updated(const std::string& id) {
188 return updated_.find(id) != updated_.end();
189 }
190
Wait()191 void Wait() {
192 scoped_refptr<content::MessageLoopRunner> runner =
193 new content::MessageLoopRunner;
194 quit_closure_ = runner->QuitClosure();
195 runner->Run();
196 quit_closure_.Reset();
197 }
198
199 private:
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)200 virtual void Observe(int type,
201 const content::NotificationSource& source,
202 const content::NotificationDetails& details) OVERRIDE {
203 if (!quit_closure_.is_null())
204 quit_closure_.Run();
205 for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
206 if (kNotificationsObserved[i] == type) {
207 count_[i]++;
208 if (type == chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND) {
209 updated_.insert(
210 content::Details<UpdateDetails>(details)->id);
211 }
212 return;
213 }
214 }
215 NOTREACHED();
216 }
217
218 content::NotificationRegistrar registrar_;
219 size_t count_[arraysize(kNotificationsObserved)];
220 std::set<std::string> updated_;
221 base::Closure quit_closure_;
222
223 DISALLOW_COPY_AND_ASSIGN(NotificationsObserver);
224 };
225
226 } // namespace
227
228 // Base class for further specialized test classes.
229 class MockService : public TestExtensionService {
230 public:
MockService(TestExtensionPrefs * prefs)231 explicit MockService(TestExtensionPrefs* prefs)
232 : prefs_(prefs), pending_extension_manager_(*this) {
233 }
234
~MockService()235 virtual ~MockService() {}
236
pending_extension_manager()237 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
238 ADD_FAILURE() << "Subclass should override this if it will "
239 << "be accessed by a test.";
240 return &pending_extension_manager_;
241 }
242
profile()243 Profile* profile() { return &profile_; }
244
request_context()245 net::URLRequestContextGetter* request_context() {
246 return profile_.GetRequestContext();
247 }
248
extension_prefs()249 ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
250
pref_service()251 PrefService* pref_service() { return prefs_->pref_service(); }
252
253 // Creates test extensions and inserts them into list. The name and
254 // version are all based on their index. If |update_url| is non-null, it
255 // will be used as the update_url for each extension.
256 // The |id| is used to distinguish extension names and make sure that
257 // no two extensions share the same name.
CreateTestExtensions(int id,int count,ExtensionList * list,const std::string * update_url,Manifest::Location location)258 void CreateTestExtensions(int id, int count, ExtensionList *list,
259 const std::string* update_url,
260 Manifest::Location location) {
261 for (int i = 1; i <= count; i++) {
262 DictionaryValue manifest;
263 manifest.SetString(manifest_keys::kVersion,
264 base::StringPrintf("%d.0.0.0", i));
265 manifest.SetString(manifest_keys::kName,
266 base::StringPrintf("Extension %d.%d", id, i));
267 if (update_url)
268 manifest.SetString(manifest_keys::kUpdateURL, *update_url);
269 scoped_refptr<Extension> e =
270 prefs_->AddExtensionWithManifest(manifest, location);
271 ASSERT_TRUE(e.get() != NULL);
272 list->push_back(e);
273 }
274 }
275
276 protected:
277 TestExtensionPrefs* const prefs_;
278 PendingExtensionManager pending_extension_manager_;
279 TestingProfile profile_;
280
281 private:
282 DISALLOW_COPY_AND_ASSIGN(MockService);
283 };
284
285
ShouldInstallExtensionsOnly(const Extension * extension)286 bool ShouldInstallExtensionsOnly(const Extension* extension) {
287 return extension->GetType() == Manifest::TYPE_EXTENSION;
288 }
289
ShouldInstallThemesOnly(const Extension * extension)290 bool ShouldInstallThemesOnly(const Extension* extension) {
291 return extension->is_theme();
292 }
293
ShouldAlwaysInstall(const Extension * extension)294 bool ShouldAlwaysInstall(const Extension* extension) {
295 return true;
296 }
297
298 // Loads some pending extension records into a pending extension manager.
SetupPendingExtensionManagerForTest(int count,const GURL & update_url,PendingExtensionManager * pending_extension_manager)299 void SetupPendingExtensionManagerForTest(
300 int count,
301 const GURL& update_url,
302 PendingExtensionManager* pending_extension_manager) {
303 for (int i = 1; i <= count; ++i) {
304 PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
305 (i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
306 const bool kIsFromSync = true;
307 const bool kInstallSilently = true;
308 const bool kMarkAcknowledged = false;
309 std::string id = id_util::GenerateId(base::StringPrintf("extension%i", i));
310
311 pending_extension_manager->AddForTesting(
312 PendingExtensionInfo(id,
313 update_url,
314 Version(),
315 should_allow_install,
316 kIsFromSync,
317 kInstallSilently,
318 Manifest::INTERNAL,
319 Extension::NO_FLAGS,
320 kMarkAcknowledged));
321 }
322 }
323
324 class ServiceForManifestTests : public MockService {
325 public:
ServiceForManifestTests(TestExtensionPrefs * prefs)326 explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
327 : MockService(prefs) {
328 }
329
~ServiceForManifestTests()330 virtual ~ServiceForManifestTests() {}
331
GetExtensionById(const std::string & id,bool include_disabled) const332 virtual const Extension* GetExtensionById(
333 const std::string& id, bool include_disabled) const OVERRIDE {
334 const Extension* result = extensions_.GetByID(id);
335 if (result || !include_disabled)
336 return result;
337 return disabled_extensions_.GetByID(id);
338 }
339
extensions() const340 virtual const ExtensionSet* extensions() const OVERRIDE {
341 return &extensions_;
342 }
343
disabled_extensions() const344 virtual const ExtensionSet* disabled_extensions() const OVERRIDE {
345 return &disabled_extensions_;
346 }
347
pending_extension_manager()348 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
349 return &pending_extension_manager_;
350 }
351
GetPendingExtensionUpdate(const std::string & id) const352 virtual const Extension* GetPendingExtensionUpdate(
353 const std::string& id) const OVERRIDE {
354 return NULL;
355 }
356
IsExtensionEnabled(const std::string & id) const357 virtual bool IsExtensionEnabled(const std::string& id) const OVERRIDE {
358 return !disabled_extensions_.Contains(id);
359 }
360
set_extensions(ExtensionList extensions)361 void set_extensions(ExtensionList extensions) {
362 for (ExtensionList::const_iterator it = extensions.begin();
363 it != extensions.end(); ++it) {
364 extensions_.Insert(*it);
365 }
366 }
367
set_disabled_extensions(ExtensionList disabled_extensions)368 void set_disabled_extensions(ExtensionList disabled_extensions) {
369 for (ExtensionList::const_iterator it = disabled_extensions.begin();
370 it != disabled_extensions.end(); ++it) {
371 disabled_extensions_.Insert(*it);
372 }
373 }
374
375 private:
376 ExtensionSet extensions_;
377 ExtensionSet disabled_extensions_;
378 };
379
380 class ServiceForDownloadTests : public MockService {
381 public:
ServiceForDownloadTests(TestExtensionPrefs * prefs)382 explicit ServiceForDownloadTests(TestExtensionPrefs* prefs)
383 : MockService(prefs) {
384 }
385
386 // Add a fake crx installer to be returned by a call to UpdateExtension()
387 // with a specific ID. Caller keeps ownership of |crx_installer|.
AddFakeCrxInstaller(const std::string & id,CrxInstaller * crx_installer)388 void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) {
389 fake_crx_installers_[id] = crx_installer;
390 }
391
UpdateExtension(const std::string & id,const base::FilePath & extension_path,const GURL & download_url,CrxInstaller ** out_crx_installer)392 virtual bool UpdateExtension(
393 const std::string& id,
394 const base::FilePath& extension_path,
395 const GURL& download_url,
396 CrxInstaller** out_crx_installer) OVERRIDE {
397 extension_id_ = id;
398 install_path_ = extension_path;
399 download_url_ = download_url;
400
401 if (ContainsKey(fake_crx_installers_, id)) {
402 *out_crx_installer = fake_crx_installers_[id];
403 return true;
404 }
405
406 return false;
407 }
408
pending_extension_manager()409 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
410 return &pending_extension_manager_;
411 }
412
GetExtensionById(const std::string & id,bool) const413 virtual const Extension* GetExtensionById(
414 const std::string& id, bool) const OVERRIDE {
415 last_inquired_extension_id_ = id;
416 return NULL;
417 }
418
extension_id() const419 const std::string& extension_id() const { return extension_id_; }
install_path() const420 const base::FilePath& install_path() const { return install_path_; }
download_url() const421 const GURL& download_url() const { return download_url_; }
422
423 private:
424 // Hold the set of ids that UpdateExtension() should fake success on.
425 // UpdateExtension(id, ...) will return true iff fake_crx_installers_
426 // contains key |id|. |out_install_notification_source| will be set
427 // to Source<CrxInstaller(fake_crx_installers_[i]).
428 std::map<std::string, CrxInstaller*> fake_crx_installers_;
429
430 std::string extension_id_;
431 base::FilePath install_path_;
432 GURL download_url_;
433
434 // The last extension ID that GetExtensionById was called with.
435 // Mutable because the method that sets it (GetExtensionById) is const
436 // in the actual extension service, but must record the last extension
437 // ID in this test class.
438 mutable std::string last_inquired_extension_id_;
439 };
440
441 static const int kUpdateFrequencySecs = 15;
442
443 // Takes a string with KEY=VALUE parameters separated by '&' in |params| and
444 // puts the key/value pairs into |result|. For keys with no value, the empty
445 // string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
446 // "foo", and "c" to "".
ExtractParameters(const std::string & params,std::map<std::string,std::string> * result)447 static void ExtractParameters(const std::string& params,
448 std::map<std::string, std::string>* result) {
449 std::vector<std::string> pairs;
450 base::SplitString(params, '&', &pairs);
451 for (size_t i = 0; i < pairs.size(); i++) {
452 std::vector<std::string> key_val;
453 base::SplitString(pairs[i], '=', &key_val);
454 if (!key_val.empty()) {
455 std::string key = key_val[0];
456 EXPECT_TRUE(result->find(key) == result->end());
457 (*result)[key] = (key_val.size() == 2) ? key_val[1] : std::string();
458 } else {
459 NOTREACHED();
460 }
461 }
462 }
463
VerifyQueryAndExtractParameters(const std::string & query,std::map<std::string,std::string> * result)464 static void VerifyQueryAndExtractParameters(
465 const std::string& query,
466 std::map<std::string, std::string>* result) {
467 std::map<std::string, std::string> params;
468 ExtractParameters(query, ¶ms);
469
470 std::string omaha_params =
471 chrome::OmahaQueryParams::Get(chrome::OmahaQueryParams::CRX);
472 std::map<std::string, std::string> expected;
473 ExtractParameters(omaha_params, &expected);
474
475 for (std::map<std::string, std::string>::iterator it = expected.begin();
476 it != expected.end(); ++it) {
477 EXPECT_EQ(it->second, params[it->first]);
478 }
479
480 EXPECT_EQ(1U, params.count("x"));
481 std::string decoded = net::UnescapeURLComponent(
482 params["x"], net::UnescapeRule::URL_SPECIAL_CHARS);
483 ExtractParameters(decoded, result);
484 }
485
486 // All of our tests that need to use private APIs of ExtensionUpdater live
487 // inside this class (which is a friend to ExtensionUpdater).
488 class ExtensionUpdaterTest : public testing::Test {
489 public:
ExtensionUpdaterTest()490 ExtensionUpdaterTest()
491 : thread_bundle_(
492 content::TestBrowserThreadBundle::IO_MAINLOOP) {
493 }
494
SetUp()495 virtual void SetUp() OVERRIDE {
496 prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
497 content::RenderProcessHost::SetRunRendererInProcess(true);
498 }
499
TearDown()500 virtual void TearDown() OVERRIDE {
501 // Some tests create URLRequestContextGetters, whose destruction must run
502 // on the IO thread. Make sure the IO loop spins before shutdown so that
503 // those objects are released.
504 RunUntilIdle();
505 prefs_.reset();
506 content::RenderProcessHost::SetRunRendererInProcess(false);
507 }
508
RunUntilIdle()509 void RunUntilIdle() {
510 prefs_->pref_service()->CommitPendingWrite();
511 base::RunLoop().RunUntilIdle();
512 }
513
SimulateTimerFired(ExtensionUpdater * updater)514 void SimulateTimerFired(ExtensionUpdater* updater) {
515 EXPECT_TRUE(updater->timer_.IsRunning());
516 updater->timer_.Stop();
517 updater->TimerFired();
518 }
519
520 // Adds a Result with the given data to results.
AddParseResult(const std::string & id,const std::string & version,const std::string & url,UpdateManifest::Results * results)521 void AddParseResult(const std::string& id,
522 const std::string& version,
523 const std::string& url,
524 UpdateManifest::Results* results) {
525 UpdateManifest::Result result;
526 result.extension_id = id;
527 result.version = version;
528 result.crx_url = GURL(url);
529 results->list.push_back(result);
530 }
531
ResetDownloader(ExtensionUpdater * updater,ExtensionDownloader * downloader)532 void ResetDownloader(ExtensionUpdater* updater,
533 ExtensionDownloader* downloader) {
534 EXPECT_FALSE(updater->downloader_.get());
535 updater->downloader_.reset(downloader);
536 }
537
StartUpdateCheck(ExtensionDownloader * downloader,ManifestFetchData * fetch_data)538 void StartUpdateCheck(ExtensionDownloader* downloader,
539 ManifestFetchData* fetch_data) {
540 downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data));
541 }
542
ManifestFetchersCount(ExtensionDownloader * downloader)543 size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
544 return downloader->manifests_queue_.size() +
545 (downloader->manifest_fetcher_.get() ? 1 : 0);
546 }
547
TestExtensionUpdateCheckRequests(bool pending)548 void TestExtensionUpdateCheckRequests(bool pending) {
549 // Create an extension with an update_url.
550 ServiceForManifestTests service(prefs_.get());
551 std::string update_url("http://foo.com/bar");
552 ExtensionList extensions;
553 NotificationsObserver observer;
554 PendingExtensionManager* pending_extension_manager =
555 service.pending_extension_manager();
556 if (pending) {
557 SetupPendingExtensionManagerForTest(1, GURL(update_url),
558 pending_extension_manager);
559 } else {
560 service.CreateTestExtensions(1, 1, &extensions, &update_url,
561 Manifest::INTERNAL);
562 service.set_extensions(extensions);
563 }
564
565 // Set up and start the updater.
566 net::TestURLFetcherFactory factory;
567 ExtensionUpdater updater(
568 &service, service.extension_prefs(), service.pref_service(),
569 service.profile(), 60*60*24);
570 updater.Start();
571
572 // Tell the update that it's time to do update checks.
573 EXPECT_EQ(0u, observer.StartedCount());
574 SimulateTimerFired(&updater);
575 EXPECT_EQ(1u, observer.StartedCount());
576
577 // Get the url our mock fetcher was asked to fetch.
578 net::TestURLFetcher* fetcher =
579 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
580 const GURL& url = fetcher->GetOriginalURL();
581 EXPECT_FALSE(url.is_empty());
582 EXPECT_TRUE(url.is_valid());
583 EXPECT_TRUE(url.SchemeIs("http"));
584 EXPECT_EQ("foo.com", url.host());
585 EXPECT_EQ("/bar", url.path());
586
587 // Validate the extension request parameters in the query. It should
588 // look something like "x=id%3D<id>%26v%3D<version>%26uc".
589 EXPECT_TRUE(url.has_query());
590 std::map<std::string, std::string> params;
591 VerifyQueryAndExtractParameters(url.query(), ¶ms);
592 if (pending) {
593 EXPECT_TRUE(pending_extension_manager->IsIdPending(params["id"]));
594 EXPECT_EQ("0.0.0.0", params["v"]);
595 } else {
596 EXPECT_EQ(extensions[0]->id(), params["id"]);
597 EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
598 }
599 EXPECT_EQ("", params["uc"]);
600 }
601
TestUpdateUrlDataEmpty()602 void TestUpdateUrlDataEmpty() {
603 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
604 const std::string version = "1.0";
605
606 // Make sure that an empty update URL data string does not cause a ap=
607 // option to appear in the x= parameter.
608 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
609 fetch_data.AddExtension(
610 id, version, &kNeverPingedData, std::string(), std::string());
611
612 std::map<std::string, std::string> params;
613 VerifyQueryAndExtractParameters(fetch_data.full_url().query(), ¶ms);
614 EXPECT_EQ(id, params["id"]);
615 EXPECT_EQ(version, params["v"]);
616 EXPECT_EQ(0U, params.count("ap"));
617 }
618
TestUpdateUrlDataSimple()619 void TestUpdateUrlDataSimple() {
620 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
621 const std::string version = "1.0";
622
623 // Make sure that an update URL data string causes an appropriate ap=
624 // option to appear in the x= parameter.
625 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
626 fetch_data.AddExtension(
627 id, version, &kNeverPingedData, "bar", std::string());
628 std::map<std::string, std::string> params;
629 VerifyQueryAndExtractParameters(fetch_data.full_url().query(), ¶ms);
630 EXPECT_EQ(id, params["id"]);
631 EXPECT_EQ(version, params["v"]);
632 EXPECT_EQ("bar", params["ap"]);
633 }
634
TestUpdateUrlDataCompound()635 void TestUpdateUrlDataCompound() {
636 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
637 const std::string version = "1.0";
638
639 // Make sure that an update URL data string causes an appropriate ap=
640 // option to appear in the x= parameter.
641 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
642 fetch_data.AddExtension(
643 id, version, &kNeverPingedData, "a=1&b=2&c", std::string());
644 std::map<std::string, std::string> params;
645 VerifyQueryAndExtractParameters(fetch_data.full_url().query(), ¶ms);
646 EXPECT_EQ(id, params["id"]);
647 EXPECT_EQ(version, params["v"]);
648 EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]);
649 }
650
TestUpdateUrlDataFromGallery(const std::string & gallery_url)651 void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
652 net::TestURLFetcherFactory factory;
653
654 MockService service(prefs_.get());
655 MockExtensionDownloaderDelegate delegate;
656 ExtensionDownloader downloader(&delegate, service.request_context());
657 ExtensionList extensions;
658 std::string url(gallery_url);
659
660 service.CreateTestExtensions(1, 1, &extensions, &url, Manifest::INTERNAL);
661
662 const std::string& id = extensions[0]->id();
663 EXPECT_CALL(delegate, GetPingDataForExtension(id, _));
664
665 downloader.AddExtension(*extensions[0].get(), 0);
666 downloader.StartAllPending();
667 net::TestURLFetcher* fetcher =
668 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
669 ASSERT_TRUE(fetcher);
670 // Make sure that extensions that update from the gallery ignore any
671 // update URL data.
672 const std::string& update_url = fetcher->GetOriginalURL().spec();
673 std::string::size_type x = update_url.find("x=");
674 EXPECT_NE(std::string::npos, x);
675 std::string::size_type ap = update_url.find("ap%3D", x);
676 EXPECT_EQ(std::string::npos, ap);
677 }
678
TestInstallSource()679 void TestInstallSource() {
680 const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
681 const std::string version = "1.0";
682 const std::string install_source = "instally";
683
684 // Make sure that an installsource= appears in the x= parameter.
685 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
686 fetch_data.AddExtension(id, version, &kNeverPingedData,
687 kEmptyUpdateUrlData, install_source);
688 std::map<std::string, std::string> params;
689 VerifyQueryAndExtractParameters(fetch_data.full_url().query(), ¶ms);
690 EXPECT_EQ(id, params["id"]);
691 EXPECT_EQ(version, params["v"]);
692 EXPECT_EQ(install_source, params["installsource"]);
693 }
694
TestDetermineUpdates()695 void TestDetermineUpdates() {
696 TestingProfile profile;
697 MockExtensionDownloaderDelegate delegate;
698 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
699
700 // Check passing an empty list of parse results to DetermineUpdates
701 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
702 UpdateManifest::Results updates;
703 std::vector<int> updateable;
704 downloader.DetermineUpdates(fetch_data, updates, &updateable);
705 EXPECT_TRUE(updateable.empty());
706
707 // Create two updates - expect that DetermineUpdates will return the first
708 // one (v1.0 installed, v1.1 available) but not the second one (both
709 // installed and available at v2.0).
710 const std::string id1 = id_util::GenerateId("1");
711 const std::string id2 = id_util::GenerateId("2");
712 fetch_data.AddExtension(
713 id1, "1.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string());
714 AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);
715 fetch_data.AddExtension(
716 id2, "2.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string());
717 AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);
718
719 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
720 EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
721 .WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"),
722 Return(true)));
723 EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
724 .WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"),
725 Return(true)));
726
727 downloader.DetermineUpdates(fetch_data, updates, &updateable);
728 EXPECT_EQ(1u, updateable.size());
729 EXPECT_EQ(0, updateable[0]);
730 }
731
TestDetermineUpdatesPending()732 void TestDetermineUpdatesPending() {
733 // Create a set of test extensions
734 ServiceForManifestTests service(prefs_.get());
735 PendingExtensionManager* pending_extension_manager =
736 service.pending_extension_manager();
737 SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
738
739 TestingProfile profile;
740 MockExtensionDownloaderDelegate delegate;
741 ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
742
743 ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
744 UpdateManifest::Results updates;
745
746 std::list<std::string> ids_for_update_check;
747 pending_extension_manager->GetPendingIdsForUpdateCheck(
748 &ids_for_update_check);
749
750 std::list<std::string>::const_iterator it;
751 for (it = ids_for_update_check.begin();
752 it != ids_for_update_check.end(); ++it) {
753 fetch_data.AddExtension(*it,
754 "1.0.0.0",
755 &kNeverPingedData,
756 kEmptyUpdateUrlData,
757 std::string());
758 AddParseResult(*it, "1.1", "http://localhost/e1_1.1.crx", &updates);
759 }
760
761 // The delegate will tell the downloader that all the extensions are
762 // pending.
763 EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(true));
764
765 std::vector<int> updateable;
766 downloader.DetermineUpdates(fetch_data, updates, &updateable);
767 // All the apps should be updateable.
768 EXPECT_EQ(3u, updateable.size());
769 for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) {
770 EXPECT_EQ(static_cast<int>(i), updateable[i]);
771 }
772 }
773
TestMultipleManifestDownloading()774 void TestMultipleManifestDownloading() {
775 net::TestURLFetcherFactory factory;
776 net::TestURLFetcher* fetcher = NULL;
777 NotificationsObserver observer;
778 MockService service(prefs_.get());
779 MockExtensionDownloaderDelegate delegate;
780 ExtensionDownloader downloader(&delegate, service.request_context());
781 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
782
783 GURL kUpdateUrl("http://localhost/manifest1");
784
785 scoped_ptr<ManifestFetchData> fetch1(new ManifestFetchData(kUpdateUrl, 0));
786 scoped_ptr<ManifestFetchData> fetch2(new ManifestFetchData(kUpdateUrl, 0));
787 scoped_ptr<ManifestFetchData> fetch3(new ManifestFetchData(kUpdateUrl, 0));
788 scoped_ptr<ManifestFetchData> fetch4(new ManifestFetchData(kUpdateUrl, 0));
789 ManifestFetchData::PingData zeroDays(0, 0, true);
790 fetch1->AddExtension(
791 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
792 fetch2->AddExtension(
793 "2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string());
794 fetch3->AddExtension(
795 "3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string());
796 fetch4->AddExtension(
797 "4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string());
798
799 // This will start the first fetcher and queue the others. The next in queue
800 // is started as each fetcher receives its response.
801 downloader.StartUpdateCheck(fetch1.Pass());
802 downloader.StartUpdateCheck(fetch2.Pass());
803 downloader.StartUpdateCheck(fetch3.Pass());
804 downloader.StartUpdateCheck(fetch4.Pass());
805 RunUntilIdle();
806
807 // The first fetch will fail.
808 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
809 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
810 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
811 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
812 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
813 fetcher->set_url(kUpdateUrl);
814 fetcher->set_status(net::URLRequestStatus());
815 fetcher->set_response_code(400);
816 fetcher->delegate()->OnURLFetchComplete(fetcher);
817 RunUntilIdle();
818 Mock::VerifyAndClearExpectations(&delegate);
819
820 // The second fetch gets invalid data.
821 const std::string kInvalidXml = "invalid xml";
822 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
823 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
824 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
825 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
826 "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _))
827 .WillOnce(InvokeWithoutArgs(&delegate,
828 &MockExtensionDownloaderDelegate::Quit));
829 fetcher->set_url(kUpdateUrl);
830 fetcher->set_status(net::URLRequestStatus());
831 fetcher->set_response_code(200);
832 fetcher->SetResponseString(kInvalidXml);
833 fetcher->delegate()->OnURLFetchComplete(fetcher);
834 delegate.Wait();
835 Mock::VerifyAndClearExpectations(&delegate);
836
837 // The third fetcher doesn't have an update available.
838 const std::string kNoUpdate =
839 "<?xml version='1.0' encoding='UTF-8'?>"
840 "<gupdate xmlns='http://www.google.com/update2/response'"
841 " protocol='2.0'>"
842 " <app appid='3333'>"
843 " <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'"
844 " version='3.0.0.0' prodversionmin='3.0.0.0' />"
845 " </app>"
846 "</gupdate>";
847 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
848 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
849 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
850 EXPECT_CALL(delegate, IsExtensionPending("3333")).WillOnce(Return(false));
851 EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _))
852 .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"),
853 Return(true)));
854 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
855 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _))
856 .WillOnce(InvokeWithoutArgs(&delegate,
857 &MockExtensionDownloaderDelegate::Quit));
858 fetcher->set_url(kUpdateUrl);
859 fetcher->set_status(net::URLRequestStatus());
860 fetcher->set_response_code(200);
861 fetcher->SetResponseString(kNoUpdate);
862 fetcher->delegate()->OnURLFetchComplete(fetcher);
863 delegate.Wait();
864 Mock::VerifyAndClearExpectations(&delegate);
865
866 // The last fetcher has an update.
867 const std::string kUpdateAvailable =
868 "<?xml version='1.0' encoding='UTF-8'?>"
869 "<gupdate xmlns='http://www.google.com/update2/response'"
870 " protocol='2.0'>"
871 " <app appid='4444'>"
872 " <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
873 " version='4.0.42.0' prodversionmin='4.0.42.0' />"
874 " </app>"
875 "</gupdate>";
876 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
877 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
878 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
879 EXPECT_CALL(delegate, IsExtensionPending("4444")).WillOnce(Return(false));
880 EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _))
881 .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"),
882 Return(true)));
883 fetcher->set_url(kUpdateUrl);
884 fetcher->set_status(net::URLRequestStatus());
885 fetcher->set_response_code(200);
886 fetcher->SetResponseString(kUpdateAvailable);
887 fetcher->delegate()->OnURLFetchComplete(fetcher);
888 observer.Wait();
889 Mock::VerifyAndClearExpectations(&delegate);
890
891 // Verify that the downloader decided to update this extension.
892 EXPECT_EQ(1u, observer.UpdatedCount());
893 EXPECT_TRUE(observer.Updated("4444"));
894 }
895
TestManifestRetryDownloading()896 void TestManifestRetryDownloading() {
897 net::TestURLFetcherFactory factory;
898 net::TestURLFetcher* fetcher = NULL;
899 NotificationsObserver observer;
900 MockService service(prefs_.get());
901 MockExtensionDownloaderDelegate delegate;
902 ExtensionDownloader downloader(&delegate, service.request_context());
903 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
904
905 GURL kUpdateUrl("http://localhost/manifest1");
906
907 scoped_ptr<ManifestFetchData> fetch(new ManifestFetchData(kUpdateUrl, 0));
908 ManifestFetchData::PingData zeroDays(0, 0, true);
909 fetch->AddExtension(
910 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
911
912 // This will start the first fetcher.
913 downloader.StartUpdateCheck(fetch.Pass());
914 RunUntilIdle();
915
916 // ExtensionDownloader should retry kMaxRetries times and then fail.
917 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
918 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
919 for (int i = 0; i <= ExtensionDownloader::kMaxRetries; ++i) {
920 // All fetches will fail.
921 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
922 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
923 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
924 fetcher->set_url(kUpdateUrl);
925 fetcher->set_status(net::URLRequestStatus());
926 // Code 5xx causes ExtensionDownloader to retry.
927 fetcher->set_response_code(500);
928 fetcher->delegate()->OnURLFetchComplete(fetcher);
929 RunUntilIdle();
930 }
931 Mock::VerifyAndClearExpectations(&delegate);
932
933
934 // For response codes that are not in the 5xx range ExtensionDownloader
935 // should not retry.
936 fetch.reset(new ManifestFetchData(kUpdateUrl, 0));
937 fetch->AddExtension(
938 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
939
940 // This will start the first fetcher.
941 downloader.StartUpdateCheck(fetch.Pass());
942 RunUntilIdle();
943
944 EXPECT_CALL(delegate, OnExtensionDownloadFailed(
945 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
946 // The first fetch will fail, and require retrying.
947 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
948 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
949 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
950 fetcher->set_url(kUpdateUrl);
951 fetcher->set_status(net::URLRequestStatus());
952 fetcher->set_response_code(500);
953 fetcher->delegate()->OnURLFetchComplete(fetcher);
954 RunUntilIdle();
955
956 // The second fetch will fail with response 400 and should not cause
957 // ExtensionDownloader to retry.
958 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
959 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
960 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
961 fetcher->set_url(kUpdateUrl);
962 fetcher->set_status(net::URLRequestStatus());
963 fetcher->set_response_code(400);
964 fetcher->delegate()->OnURLFetchComplete(fetcher);
965 RunUntilIdle();
966
967 Mock::VerifyAndClearExpectations(&delegate);
968 }
969
TestSingleExtensionDownloading(bool pending,bool retry)970 void TestSingleExtensionDownloading(bool pending, bool retry) {
971 net::TestURLFetcherFactory factory;
972 net::TestURLFetcher* fetcher = NULL;
973 scoped_ptr<ServiceForDownloadTests> service(
974 new ServiceForDownloadTests(prefs_.get()));
975 ExtensionUpdater updater(service.get(), service->extension_prefs(),
976 service->pref_service(),
977 service->profile(),
978 kUpdateFrequencySecs);
979 updater.Start();
980 ResetDownloader(
981 &updater,
982 new ExtensionDownloader(&updater, service->request_context()));
983 updater.downloader_->extensions_queue_.set_backoff_policy(
984 &kNoBackoffPolicy);
985
986 GURL test_url("http://localhost/extension.crx");
987
988 std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
989 std::string hash;
990 Version version("0.0.1");
991 std::set<int> requests;
992 requests.insert(0);
993 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
994 new ExtensionDownloader::ExtensionFetch(
995 id, test_url, hash, version.GetString(), requests));
996 updater.downloader_->FetchUpdatedExtension(fetch.Pass());
997
998 if (pending) {
999 const bool kIsFromSync = true;
1000 const bool kInstallSilently = true;
1001 const bool kMarkAcknowledged = false;
1002 PendingExtensionManager* pending_extension_manager =
1003 service->pending_extension_manager();
1004 pending_extension_manager->AddForTesting(
1005 PendingExtensionInfo(id, test_url, version,
1006 &ShouldAlwaysInstall, kIsFromSync,
1007 kInstallSilently,
1008 Manifest::INTERNAL,
1009 Extension::NO_FLAGS,
1010 kMarkAcknowledged));
1011 }
1012
1013 // Call back the ExtensionUpdater with a 200 response and some test data
1014 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1015 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1016 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1017 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1018
1019 if (retry) {
1020 // Reply with response code 500 to cause ExtensionDownloader to retry
1021 fetcher->set_url(test_url);
1022 fetcher->set_status(net::URLRequestStatus());
1023 fetcher->set_response_code(500);
1024 fetcher->delegate()->OnURLFetchComplete(fetcher);
1025
1026 RunUntilIdle();
1027 fetcher = factory.GetFetcherByID(
1028 ExtensionDownloader::kExtensionFetcherId);
1029 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1030 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1031 }
1032
1033 fetcher->set_url(test_url);
1034 fetcher->set_status(net::URLRequestStatus());
1035 fetcher->set_response_code(200);
1036 fetcher->SetResponseFilePath(extension_file_path);
1037 fetcher->delegate()->OnURLFetchComplete(fetcher);
1038
1039 RunUntilIdle();
1040
1041 // Expect that ExtensionUpdater asked the mock extensions service to install
1042 // a file with the test data for the right id.
1043 EXPECT_EQ(id, service->extension_id());
1044 base::FilePath tmpfile_path = service->install_path();
1045 EXPECT_FALSE(tmpfile_path.empty());
1046 EXPECT_EQ(test_url, service->download_url());
1047 EXPECT_EQ(extension_file_path, tmpfile_path);
1048 }
1049
1050 // Two extensions are updated. If |updates_start_running| is true, the
1051 // mock extensions service has UpdateExtension(...) return true, and
1052 // the test is responsible for creating fake CrxInstallers. Otherwise,
1053 // UpdateExtension() returns false, signaling install failures.
TestMultipleExtensionDownloading(bool updates_start_running)1054 void TestMultipleExtensionDownloading(bool updates_start_running) {
1055 net::TestURLFetcherFactory factory;
1056 net::TestURLFetcher* fetcher = NULL;
1057 ServiceForDownloadTests service(prefs_.get());
1058 ExtensionUpdater updater(
1059 &service, service.extension_prefs(), service.pref_service(),
1060 service.profile(), kUpdateFrequencySecs);
1061 updater.Start();
1062 ResetDownloader(
1063 &updater,
1064 new ExtensionDownloader(&updater, service.request_context()));
1065 updater.downloader_->extensions_queue_.set_backoff_policy(
1066 &kNoBackoffPolicy);
1067
1068 EXPECT_FALSE(updater.crx_install_is_running_);
1069
1070 GURL url1("http://localhost/extension1.crx");
1071 GURL url2("http://localhost/extension2.crx");
1072
1073 std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1074 std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
1075
1076 std::string hash1;
1077 std::string hash2;
1078
1079 std::string version1 = "0.1";
1080 std::string version2 = "0.1";
1081 std::set<int> requests;
1082 requests.insert(0);
1083 // Start two fetches
1084 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch1(
1085 new ExtensionDownloader::ExtensionFetch(
1086 id1, url1, hash1, version1, requests));
1087 scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch2(
1088 new ExtensionDownloader::ExtensionFetch(
1089 id2, url2, hash2, version2, requests));
1090 updater.downloader_->FetchUpdatedExtension(fetch1.Pass());
1091 updater.downloader_->FetchUpdatedExtension(fetch2.Pass());
1092
1093 // Make the first fetch complete.
1094 base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
1095
1096 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1097 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1098 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1099
1100 // We need some CrxInstallers, and CrxInstallers require a real
1101 // ExtensionService. Create one on the testing profile. Any action
1102 // the CrxInstallers take is on the testing profile's extension
1103 // service, not on our mock |service|. This allows us to fake
1104 // the CrxInstaller actions we want.
1105 TestingProfile profile;
1106 static_cast<TestExtensionSystem*>(
1107 ExtensionSystem::Get(&profile))->
1108 CreateExtensionService(
1109 CommandLine::ForCurrentProcess(),
1110 base::FilePath(),
1111 false);
1112 ExtensionService* extension_service =
1113 ExtensionSystem::Get(&profile)->extension_service();
1114 extension_service->set_extensions_enabled(true);
1115 extension_service->set_show_extensions_prompts(false);
1116
1117 scoped_refptr<CrxInstaller> fake_crx1(
1118 CrxInstaller::CreateSilent(extension_service));
1119 scoped_refptr<CrxInstaller> fake_crx2(
1120 CrxInstaller::CreateSilent(extension_service));
1121
1122 if (updates_start_running) {
1123 // Add fake CrxInstaller to be returned by service.UpdateExtension().
1124 service.AddFakeCrxInstaller(id1, fake_crx1.get());
1125 service.AddFakeCrxInstaller(id2, fake_crx2.get());
1126 } else {
1127 // If we don't add fake CRX installers, the mock service fakes a failure
1128 // starting the install.
1129 }
1130
1131 fetcher->set_url(url1);
1132 fetcher->set_status(net::URLRequestStatus());
1133 fetcher->set_response_code(200);
1134 fetcher->SetResponseFilePath(extension_file_path);
1135 fetcher->delegate()->OnURLFetchComplete(fetcher);
1136
1137 RunUntilIdle();
1138
1139 // Expect that the service was asked to do an install with the right data.
1140 base::FilePath tmpfile_path = service.install_path();
1141 EXPECT_FALSE(tmpfile_path.empty());
1142 EXPECT_EQ(id1, service.extension_id());
1143 EXPECT_EQ(url1, service.download_url());
1144 RunUntilIdle();
1145
1146 // Make sure the second fetch finished and asked the service to do an
1147 // update.
1148 base::FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2"));
1149 fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1150 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1151 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
1152
1153 fetcher->set_url(url2);
1154 fetcher->set_status(net::URLRequestStatus());
1155 fetcher->set_response_code(200);
1156 fetcher->SetResponseFilePath(extension_file_path2);
1157 fetcher->delegate()->OnURLFetchComplete(fetcher);
1158 RunUntilIdle();
1159
1160 if (updates_start_running) {
1161 EXPECT_TRUE(updater.crx_install_is_running_);
1162
1163 // The second install should not have run, because the first has not
1164 // sent a notification that it finished.
1165 EXPECT_EQ(id1, service.extension_id());
1166 EXPECT_EQ(url1, service.download_url());
1167
1168 // Fake install notice. This should start the second installation,
1169 // which will be checked below.
1170 fake_crx1->NotifyCrxInstallComplete(false);
1171
1172 EXPECT_TRUE(updater.crx_install_is_running_);
1173 }
1174
1175 EXPECT_EQ(id2, service.extension_id());
1176 EXPECT_EQ(url2, service.download_url());
1177 EXPECT_FALSE(service.install_path().empty());
1178
1179 // Make sure the correct crx contents were passed for the update call.
1180 EXPECT_EQ(extension_file_path2, service.install_path());
1181
1182 if (updates_start_running) {
1183 EXPECT_TRUE(updater.crx_install_is_running_);
1184 fake_crx2->NotifyCrxInstallComplete(false);
1185 }
1186 EXPECT_FALSE(updater.crx_install_is_running_);
1187 }
1188
TestGalleryRequestsWithBrand(bool use_organic_brand_code)1189 void TestGalleryRequestsWithBrand(bool use_organic_brand_code) {
1190 google_util::BrandForTesting brand_for_testing(
1191 use_organic_brand_code ? "GGLS" : "TEST");
1192
1193 // We want to test a variety of combinations of expected ping conditions for
1194 // rollcall and active pings.
1195 int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
1196
1197 for (size_t i = 0; i < arraysize(ping_cases); i++) {
1198 for (size_t j = 0; j < arraysize(ping_cases); j++) {
1199 for (size_t k = 0; k < 2; k++) {
1200 int rollcall_ping_days = ping_cases[i];
1201 int active_ping_days = ping_cases[j];
1202 // Skip cases where rollcall_ping_days == -1, but
1203 // active_ping_days > 0, because rollcall_ping_days == -1 means the
1204 // app was just installed and this is the first update check after
1205 // installation.
1206 if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
1207 active_ping_days > 0)
1208 continue;
1209
1210 bool active_bit = k > 0;
1211 TestGalleryRequests(rollcall_ping_days, active_ping_days, active_bit,
1212 !use_organic_brand_code);
1213 ASSERT_FALSE(HasFailure()) <<
1214 " rollcall_ping_days=" << ping_cases[i] <<
1215 " active_ping_days=" << ping_cases[j] <<
1216 " active_bit=" << active_bit;
1217 }
1218 }
1219 }
1220 }
1221
1222 // Test requests to both a Google server and a non-google server. This allows
1223 // us to test various combinations of installed (ie roll call) and active
1224 // (ie app launch) ping scenarios. The invariant is that each type of ping
1225 // value should be present at most once per day, and can be calculated based
1226 // on the delta between now and the last ping time (or in the case of active
1227 // pings, that delta plus whether the app has been active).
TestGalleryRequests(int rollcall_ping_days,int active_ping_days,bool active_bit,bool expect_brand_code)1228 void TestGalleryRequests(int rollcall_ping_days,
1229 int active_ping_days,
1230 bool active_bit,
1231 bool expect_brand_code) {
1232 net::TestURLFetcherFactory factory;
1233
1234 // Set up 2 mock extensions, one with a google.com update url and one
1235 // without.
1236 prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
1237 ServiceForManifestTests service(prefs_.get());
1238 ExtensionList tmp;
1239 GURL url1("http://clients2.google.com/service/update2/crx");
1240 GURL url2("http://www.somewebsite.com");
1241 service.CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
1242 Manifest::INTERNAL);
1243 service.CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
1244 Manifest::INTERNAL);
1245 EXPECT_EQ(2u, tmp.size());
1246 service.set_extensions(tmp);
1247
1248 ExtensionPrefs* prefs = service.extension_prefs();
1249 const std::string& id = tmp[0]->id();
1250 Time now = Time::Now();
1251 if (rollcall_ping_days == 0) {
1252 prefs->SetLastPingDay(id, now - TimeDelta::FromSeconds(15));
1253 } else if (rollcall_ping_days > 0) {
1254 Time last_ping_day = now -
1255 TimeDelta::FromDays(rollcall_ping_days) -
1256 TimeDelta::FromSeconds(15);
1257 prefs->SetLastPingDay(id, last_ping_day);
1258 }
1259
1260 // Store a value for the last day we sent an active ping.
1261 if (active_ping_days == 0) {
1262 prefs->SetLastActivePingDay(id, now - TimeDelta::FromSeconds(15));
1263 } else if (active_ping_days > 0) {
1264 Time last_active_ping_day = now -
1265 TimeDelta::FromDays(active_ping_days) -
1266 TimeDelta::FromSeconds(15);
1267 prefs->SetLastActivePingDay(id, last_active_ping_day);
1268 }
1269 if (active_bit)
1270 prefs->SetActiveBit(id, true);
1271
1272 ExtensionUpdater updater(
1273 &service, service.extension_prefs(), service.pref_service(),
1274 service.profile(), kUpdateFrequencySecs);
1275 ExtensionUpdater::CheckParams params;
1276 updater.Start();
1277 updater.CheckNow(params);
1278
1279 // Make the updater do manifest fetching, and note the urls it tries to
1280 // fetch.
1281 std::vector<GURL> fetched_urls;
1282 net::TestURLFetcher* fetcher =
1283 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1284 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
1285 fetched_urls.push_back(fetcher->GetOriginalURL());
1286
1287 fetcher->set_url(fetched_urls[0]);
1288 fetcher->set_status(net::URLRequestStatus());
1289 fetcher->set_response_code(500);
1290 fetcher->SetResponseString(std::string());
1291 fetcher->delegate()->OnURLFetchComplete(fetcher);
1292
1293 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1294 fetched_urls.push_back(fetcher->GetOriginalURL());
1295
1296 // The urls could have been fetched in either order, so use the host to
1297 // tell them apart and note the query each used.
1298 std::string url1_query;
1299 std::string url2_query;
1300 if (fetched_urls[0].host() == url1.host()) {
1301 url1_query = fetched_urls[0].query();
1302 url2_query = fetched_urls[1].query();
1303 } else if (fetched_urls[0].host() == url2.host()) {
1304 url1_query = fetched_urls[1].query();
1305 url2_query = fetched_urls[0].query();
1306 } else {
1307 NOTREACHED();
1308 }
1309
1310 // First make sure the non-google query had no ping parameter.
1311 std::string search_string = "ping%3D";
1312 EXPECT_TRUE(url2_query.find(search_string) == std::string::npos);
1313
1314 // Now make sure the google query had the correct ping parameter.
1315 bool ping_expected = false;
1316 bool did_rollcall = false;
1317 if (rollcall_ping_days != 0) {
1318 search_string += "r%253D" + base::IntToString(rollcall_ping_days);
1319 did_rollcall = true;
1320 ping_expected = true;
1321 }
1322 if (active_bit && active_ping_days != 0) {
1323 if (did_rollcall)
1324 search_string += "%2526";
1325 search_string += "a%253D" + base::IntToString(active_ping_days);
1326 ping_expected = true;
1327 }
1328 bool ping_found = url1_query.find(search_string) != std::string::npos;
1329 EXPECT_EQ(ping_expected, ping_found) << "query was: " << url1_query
1330 << " was looking for " << search_string;
1331
1332 // Make sure the non-google query has no brand parameter.
1333 const std::string brand_string = "brand%3D";
1334 EXPECT_TRUE(url2_query.find(brand_string) == std::string::npos);
1335
1336 #if defined(GOOGLE_CHROME_BUILD)
1337 // Make sure the google query has a brand parameter, but only if the
1338 // brand is non-organic.
1339 if (expect_brand_code) {
1340 EXPECT_TRUE(url1_query.find(brand_string) != std::string::npos);
1341 } else {
1342 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1343 }
1344 #else
1345 // Chromium builds never add the brand to the parameter, even for google
1346 // queries.
1347 EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
1348 #endif
1349
1350 RunUntilIdle();
1351 }
1352
1353 // This makes sure that the extension updater properly stores the results
1354 // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
1355 // the first time we fetched the extension, or 2) We sent a ping value of
1356 // >= 1 day for the extension.
TestHandleManifestResults()1357 void TestHandleManifestResults() {
1358 ServiceForManifestTests service(prefs_.get());
1359 GURL update_url("http://www.google.com/manifest");
1360 ExtensionList tmp;
1361 service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
1362 Manifest::INTERNAL);
1363 service.set_extensions(tmp);
1364
1365 ExtensionUpdater updater(
1366 &service, service.extension_prefs(), service.pref_service(),
1367 service.profile(), kUpdateFrequencySecs);
1368 updater.Start();
1369 ResetDownloader(
1370 &updater,
1371 new ExtensionDownloader(&updater, service.request_context()));
1372
1373 ManifestFetchData fetch_data(update_url, 0);
1374 const Extension* extension = tmp[0].get();
1375 fetch_data.AddExtension(extension->id(),
1376 extension->VersionString(),
1377 &kNeverPingedData,
1378 kEmptyUpdateUrlData,
1379 std::string());
1380 UpdateManifest::Results results;
1381 results.daystart_elapsed_seconds = 750;
1382
1383 updater.downloader_->HandleManifestResults(fetch_data, &results);
1384 Time last_ping_day =
1385 service.extension_prefs()->LastPingDay(extension->id());
1386 EXPECT_FALSE(last_ping_day.is_null());
1387 int64 seconds_diff = (Time::Now() - last_ping_day).InSeconds();
1388 EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
1389 }
1390
1391 protected:
1392 scoped_ptr<TestExtensionPrefs> prefs_;
1393
1394 private:
1395 content::TestBrowserThreadBundle thread_bundle_;
1396
1397 #if defined OS_CHROMEOS
1398 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
1399 chromeos::ScopedTestCrosSettings test_cros_settings_;
1400 chromeos::ScopedTestUserManager test_user_manager_;
1401 #endif
1402 };
1403
1404 // Because we test some private methods of ExtensionUpdater, it's easier for the
1405 // actual test code to live in ExtenionUpdaterTest methods instead of TEST_F
1406 // subclasses where friendship with ExtenionUpdater is not inherited.
1407
TEST_F(ExtensionUpdaterTest,TestExtensionUpdateCheckRequests)1408 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
1409 TestExtensionUpdateCheckRequests(false);
1410 }
1411
TEST_F(ExtensionUpdaterTest,TestExtensionUpdateCheckRequestsPending)1412 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
1413 TestExtensionUpdateCheckRequests(true);
1414 }
1415
TEST_F(ExtensionUpdaterTest,TestUpdateUrlData)1416 TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
1417 TestUpdateUrlDataEmpty();
1418 TestUpdateUrlDataSimple();
1419 TestUpdateUrlDataCompound();
1420 TestUpdateUrlDataFromGallery(
1421 extension_urls::GetWebstoreUpdateUrl().spec());
1422 }
1423
TEST_F(ExtensionUpdaterTest,TestInstallSource)1424 TEST_F(ExtensionUpdaterTest, TestInstallSource) {
1425 TestInstallSource();
1426 }
1427
TEST_F(ExtensionUpdaterTest,TestDetermineUpdates)1428 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
1429 TestDetermineUpdates();
1430 }
1431
TEST_F(ExtensionUpdaterTest,TestDetermineUpdatesPending)1432 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
1433 TestDetermineUpdatesPending();
1434 }
1435
TEST_F(ExtensionUpdaterTest,TestMultipleManifestDownloading)1436 TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
1437 TestMultipleManifestDownloading();
1438 }
1439
TEST_F(ExtensionUpdaterTest,TestSingleExtensionDownloading)1440 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
1441 TestSingleExtensionDownloading(false, false);
1442 }
1443
TEST_F(ExtensionUpdaterTest,TestSingleExtensionDownloadingPending)1444 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
1445 TestSingleExtensionDownloading(true, false);
1446 }
1447
TEST_F(ExtensionUpdaterTest,TestSingleExtensionDownloadingWithRetry)1448 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
1449 TestSingleExtensionDownloading(false, true);
1450 }
1451
TEST_F(ExtensionUpdaterTest,TestSingleExtensionDownloadingPendingWithRetry)1452 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
1453 TestSingleExtensionDownloading(true, true);
1454 }
1455
TEST_F(ExtensionUpdaterTest,TestMultipleExtensionDownloadingUpdatesFail)1456 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
1457 TestMultipleExtensionDownloading(false);
1458 }
TEST_F(ExtensionUpdaterTest,TestMultipleExtensionDownloadingUpdatesSucceed)1459 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
1460 TestMultipleExtensionDownloading(true);
1461 }
1462
TEST_F(ExtensionUpdaterTest,TestManifestRetryDownloading)1463 TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
1464 TestManifestRetryDownloading();
1465 }
1466
TEST_F(ExtensionUpdaterTest,TestGalleryRequestsWithOrganicBrand)1467 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) {
1468 TestGalleryRequestsWithBrand(true);
1469 }
1470
TEST_F(ExtensionUpdaterTest,TestGalleryRequestsWithNonOrganicBrand)1471 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) {
1472 TestGalleryRequestsWithBrand(false);
1473 }
1474
TEST_F(ExtensionUpdaterTest,TestHandleManifestResults)1475 TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
1476 TestHandleManifestResults();
1477 }
1478
TEST_F(ExtensionUpdaterTest,TestNonAutoUpdateableLocations)1479 TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
1480 net::TestURLFetcherFactory factory;
1481 ServiceForManifestTests service(prefs_.get());
1482 ExtensionUpdater updater(&service, service.extension_prefs(),
1483 service.pref_service(), service.profile(),
1484 kUpdateFrequencySecs);
1485 MockExtensionDownloaderDelegate delegate;
1486 // Set the downloader directly, so that all its events end up in the mock
1487 // |delegate|.
1488 ExtensionDownloader* downloader =
1489 new ExtensionDownloader(&delegate, service.request_context());
1490 ResetDownloader(&updater, downloader);
1491
1492 // Non-internal non-external extensions should be rejected.
1493 ExtensionList extensions;
1494 service.CreateTestExtensions(1, 1, &extensions, NULL,
1495 Manifest::INVALID_LOCATION);
1496 service.CreateTestExtensions(2, 1, &extensions, NULL, Manifest::INTERNAL);
1497 ASSERT_EQ(2u, extensions.size());
1498 const std::string& updateable_id = extensions[1]->id();
1499
1500 // These expectations fail if the delegate's methods are invoked for the
1501 // first extension, which has a non-matching id.
1502 EXPECT_CALL(delegate, GetUpdateUrlData(updateable_id)).WillOnce(Return(""));
1503 EXPECT_CALL(delegate, GetPingDataForExtension(updateable_id, _));
1504
1505 service.set_extensions(extensions);
1506 ExtensionUpdater::CheckParams params;
1507 updater.Start();
1508 updater.CheckNow(params);
1509 }
1510
TEST_F(ExtensionUpdaterTest,TestUpdatingDisabledExtensions)1511 TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
1512 net::TestURLFetcherFactory factory;
1513 ServiceForManifestTests service(prefs_.get());
1514 ExtensionUpdater updater(&service, service.extension_prefs(),
1515 service.pref_service(), service.profile(),
1516 kUpdateFrequencySecs);
1517 MockExtensionDownloaderDelegate delegate;
1518 // Set the downloader directly, so that all its events end up in the mock
1519 // |delegate|.
1520 ExtensionDownloader* downloader =
1521 new ExtensionDownloader(&delegate, service.request_context());
1522 ResetDownloader(&updater, downloader);
1523
1524 // Non-internal non-external extensions should be rejected.
1525 ExtensionList enabled_extensions;
1526 ExtensionList disabled_extensions;
1527 service.CreateTestExtensions(1, 1, &enabled_extensions, NULL,
1528 Manifest::INTERNAL);
1529 service.CreateTestExtensions(2, 1, &disabled_extensions, NULL,
1530 Manifest::INTERNAL);
1531 ASSERT_EQ(1u, enabled_extensions.size());
1532 ASSERT_EQ(1u, disabled_extensions.size());
1533 const std::string& enabled_id = enabled_extensions[0]->id();
1534 const std::string& disabled_id = disabled_extensions[0]->id();
1535
1536 // We expect that both enabled and disabled extensions are auto-updated.
1537 EXPECT_CALL(delegate, GetUpdateUrlData(enabled_id)).WillOnce(Return(""));
1538 EXPECT_CALL(delegate, GetPingDataForExtension(enabled_id, _));
1539 EXPECT_CALL(delegate, GetUpdateUrlData(disabled_id)).WillOnce(Return(""));
1540 EXPECT_CALL(delegate, GetPingDataForExtension(disabled_id, _));
1541
1542 service.set_extensions(enabled_extensions);
1543 service.set_disabled_extensions(disabled_extensions);
1544 ExtensionUpdater::CheckParams params;
1545 updater.Start();
1546 updater.CheckNow(params);
1547 }
1548
TEST_F(ExtensionUpdaterTest,TestManifestFetchesBuilderAddExtension)1549 TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
1550 net::TestURLFetcherFactory factory;
1551 MockService service(prefs_.get());
1552 MockExtensionDownloaderDelegate delegate;
1553 scoped_ptr<ExtensionDownloader> downloader(
1554 new ExtensionDownloader(&delegate, service.request_context()));
1555 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
1556
1557 // First, verify that adding valid extensions does invoke the callbacks on
1558 // the delegate.
1559 std::string id = id_util::GenerateId("foo");
1560 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
1561 EXPECT_TRUE(
1562 downloader->AddPendingExtension(id, GURL("http://example.com/update"),
1563 0));
1564 downloader->StartAllPending();
1565 Mock::VerifyAndClearExpectations(&delegate);
1566 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1567
1568 // Extensions with invalid update URLs should be rejected.
1569 id = id_util::GenerateId("foo2");
1570 EXPECT_FALSE(
1571 downloader->AddPendingExtension(id, GURL("http:google.com:foo"), 0));
1572 downloader->StartAllPending();
1573 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1574
1575 // Extensions with empty IDs should be rejected.
1576 EXPECT_FALSE(downloader->AddPendingExtension(std::string(), GURL(), 0));
1577 downloader->StartAllPending();
1578 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1579
1580 // TODO(akalin): Test that extensions with empty update URLs
1581 // converted from user scripts are rejected.
1582
1583 // Reset the ExtensionDownloader so that it drops the current fetcher.
1584 downloader.reset(
1585 new ExtensionDownloader(&delegate, service.request_context()));
1586 EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
1587
1588 // Extensions with empty update URLs should have a default one
1589 // filled in.
1590 id = id_util::GenerateId("foo3");
1591 EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
1592 EXPECT_TRUE(downloader->AddPendingExtension(id, GURL(), 0));
1593 downloader->StartAllPending();
1594 EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
1595
1596 net::TestURLFetcher* fetcher =
1597 factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1598 ASSERT_TRUE(fetcher);
1599 EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
1600 }
1601
TEST_F(ExtensionUpdaterTest,TestStartUpdateCheckMemory)1602 TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
1603 net::TestURLFetcherFactory factory;
1604 MockService service(prefs_.get());
1605 MockExtensionDownloaderDelegate delegate;
1606 ExtensionDownloader downloader(&delegate, service.request_context());
1607
1608 StartUpdateCheck(&downloader, new ManifestFetchData(GURL(), 0));
1609 // This should delete the newly-created ManifestFetchData.
1610 StartUpdateCheck(&downloader, new ManifestFetchData(GURL(), 0));
1611 // This should add into |manifests_pending_|.
1612 StartUpdateCheck(&downloader, new ManifestFetchData(GURL(
1613 GURL("http://www.google.com")), 0));
1614 // The dtor of |downloader| should delete the pending fetchers.
1615 }
1616
TEST_F(ExtensionUpdaterTest,TestCheckSoon)1617 TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
1618 ServiceForManifestTests service(prefs_.get());
1619 net::TestURLFetcherFactory factory;
1620 ExtensionUpdater updater(
1621 &service, service.extension_prefs(), service.pref_service(),
1622 service.profile(), kUpdateFrequencySecs);
1623 EXPECT_FALSE(updater.WillCheckSoon());
1624 updater.Start();
1625 EXPECT_FALSE(updater.WillCheckSoon());
1626 updater.CheckSoon();
1627 EXPECT_TRUE(updater.WillCheckSoon());
1628 updater.CheckSoon();
1629 EXPECT_TRUE(updater.WillCheckSoon());
1630 RunUntilIdle();
1631 EXPECT_FALSE(updater.WillCheckSoon());
1632 updater.CheckSoon();
1633 EXPECT_TRUE(updater.WillCheckSoon());
1634 updater.Stop();
1635 EXPECT_FALSE(updater.WillCheckSoon());
1636 }
1637
1638 // TODO(asargent) - (http://crbug.com/12780) add tests for:
1639 // -prodversionmin (shouldn't update if browser version too old)
1640 // -manifests & updates arriving out of order / interleaved
1641 // -malformed update url (empty, file://, has query, has a # fragment, etc.)
1642 // -An extension gets uninstalled while updates are in progress (so it doesn't
1643 // "come back from the dead")
1644 // -An extension gets manually updated to v3 while we're downloading v2 (ie
1645 // you don't get downgraded accidentally)
1646 // -An update manifest mentions multiple updates
1647
1648 } // namespace extensions
1649