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 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 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: 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 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 184 size_t StartedCount() { return count_[0]; } 185 size_t UpdatedCount() { return count_[1]; } 186 187 bool Updated(const std::string& id) { 188 return updated_.find(id) != updated_.end(); 189 } 190 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: 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: 231 explicit MockService(TestExtensionPrefs* prefs) 232 : prefs_(prefs), pending_extension_manager_(*this) { 233 } 234 235 virtual ~MockService() {} 236 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 243 Profile* profile() { return &profile_; } 244 245 net::URLRequestContextGetter* request_context() { 246 return profile_.GetRequestContext(); 247 } 248 249 ExtensionPrefs* extension_prefs() { return prefs_->prefs(); } 250 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. 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 286 bool ShouldInstallExtensionsOnly(const Extension* extension) { 287 return extension->GetType() == Manifest::TYPE_EXTENSION; 288 } 289 290 bool ShouldInstallThemesOnly(const Extension* extension) { 291 return extension->is_theme(); 292 } 293 294 bool ShouldAlwaysInstall(const Extension* extension) { 295 return true; 296 } 297 298 // Loads some pending extension records into a 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: 326 explicit ServiceForManifestTests(TestExtensionPrefs* prefs) 327 : MockService(prefs) { 328 } 329 330 virtual ~ServiceForManifestTests() {} 331 332 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 340 virtual const ExtensionSet* extensions() const OVERRIDE { 341 return &extensions_; 342 } 343 344 virtual const ExtensionSet* disabled_extensions() const OVERRIDE { 345 return &disabled_extensions_; 346 } 347 348 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE { 349 return &pending_extension_manager_; 350 } 351 352 virtual const Extension* GetPendingExtensionUpdate( 353 const std::string& id) const OVERRIDE { 354 return NULL; 355 } 356 357 virtual bool IsExtensionEnabled(const std::string& id) const OVERRIDE { 358 return !disabled_extensions_.Contains(id); 359 } 360 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 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: 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|. 388 void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) { 389 fake_crx_installers_[id] = crx_installer; 390 } 391 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 409 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE { 410 return &pending_extension_manager_; 411 } 412 413 virtual const Extension* GetExtensionById( 414 const std::string& id, bool) const OVERRIDE { 415 last_inquired_extension_id_ = id; 416 return NULL; 417 } 418 419 const std::string& extension_id() const { return extension_id_; } 420 const base::FilePath& install_path() const { return install_path_; } 421 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 "". 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 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: 490 ExtensionUpdaterTest() 491 : thread_bundle_( 492 content::TestBrowserThreadBundle::IO_MAINLOOP) { 493 } 494 495 virtual void SetUp() OVERRIDE { 496 prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current())); 497 content::RenderProcessHost::SetRunRendererInProcess(true); 498 } 499 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 509 void RunUntilIdle() { 510 prefs_->pref_service()->CommitPendingWrite(); 511 base::RunLoop().RunUntilIdle(); 512 } 513 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. 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 532 void ResetDownloader(ExtensionUpdater* updater, 533 ExtensionDownloader* downloader) { 534 EXPECT_FALSE(updater->downloader_.get()); 535 updater->downloader_.reset(downloader); 536 } 537 538 void StartUpdateCheck(ExtensionDownloader* downloader, 539 ManifestFetchData* fetch_data) { 540 downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data)); 541 } 542 543 size_t ManifestFetchersCount(ExtensionDownloader* downloader) { 544 return downloader->manifests_queue_.size() + 545 (downloader->manifest_fetcher_.get() ? 1 : 0); 546 } 547 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 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 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 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 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 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 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 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 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 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 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. 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 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). 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. 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 1408 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) { 1409 TestExtensionUpdateCheckRequests(false); 1410 } 1411 1412 TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) { 1413 TestExtensionUpdateCheckRequests(true); 1414 } 1415 1416 TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) { 1417 TestUpdateUrlDataEmpty(); 1418 TestUpdateUrlDataSimple(); 1419 TestUpdateUrlDataCompound(); 1420 TestUpdateUrlDataFromGallery( 1421 extension_urls::GetWebstoreUpdateUrl().spec()); 1422 } 1423 1424 TEST_F(ExtensionUpdaterTest, TestInstallSource) { 1425 TestInstallSource(); 1426 } 1427 1428 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) { 1429 TestDetermineUpdates(); 1430 } 1431 1432 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) { 1433 TestDetermineUpdatesPending(); 1434 } 1435 1436 TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) { 1437 TestMultipleManifestDownloading(); 1438 } 1439 1440 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) { 1441 TestSingleExtensionDownloading(false, false); 1442 } 1443 1444 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) { 1445 TestSingleExtensionDownloading(true, false); 1446 } 1447 1448 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) { 1449 TestSingleExtensionDownloading(false, true); 1450 } 1451 1452 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) { 1453 TestSingleExtensionDownloading(true, true); 1454 } 1455 1456 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) { 1457 TestMultipleExtensionDownloading(false); 1458 } 1459 TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) { 1460 TestMultipleExtensionDownloading(true); 1461 } 1462 1463 TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) { 1464 TestManifestRetryDownloading(); 1465 } 1466 1467 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) { 1468 TestGalleryRequestsWithBrand(true); 1469 } 1470 1471 TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) { 1472 TestGalleryRequestsWithBrand(false); 1473 } 1474 1475 TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) { 1476 TestHandleManifestResults(); 1477 } 1478 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 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 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 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 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