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