This source file includes following definitions.
- Wait
- Quit
- DelegateTo
- StartedCount
- UpdatedCount
- Updated
- Wait
- Observe
- pending_extension_manager_
- pending_extension_manager
- profile
- request_context
- extension_prefs
- pref_service
- CreateTestExtensions
- ShouldInstallExtensionsOnly
- ShouldInstallThemesOnly
- ShouldAlwaysInstall
- SetupPendingExtensionManagerForTest
- registry_
- GetExtensionById
- extensions
- pending_extension_manager
- GetPendingExtensionUpdate
- IsExtensionEnabled
- set_extensions
- AddFakeCrxInstaller
- UpdateExtension
- pending_extension_manager
- GetExtensionById
- extension_id
- install_path
- download_url
- ExtractParameters
- VerifyQueryAndExtractParameters
- SetUp
- TearDown
- RunUntilIdle
- SimulateTimerFired
- AddParseResult
- ResetDownloader
- StartUpdateCheck
- ManifestFetchersCount
- TestExtensionUpdateCheckRequests
- TestUpdateUrlDataEmpty
- TestUpdateUrlDataSimple
- TestUpdateUrlDataCompound
- TestUpdateUrlDataFromGallery
- TestInstallSource
- TestDetermineUpdates
- TestDetermineUpdatesPending
- TestMultipleManifestDownloading
- TestManifestRetryDownloading
- TestSingleExtensionDownloading
- TestSingleProtectedExtensionDownloading
- TestMultipleExtensionDownloading
- TestGalleryRequestsWithBrand
- TestGalleryRequests
- TestHandleManifestResults
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include <list>
#include <map>
#include <set>
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
#include "base/version.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_sync_data.h"
#include "chrome/browser/extensions/test_extension_prefs.h"
#include "chrome/browser/extensions/test_extension_service.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/extensions/updater/extension_downloader.h"
#include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
#include "chrome/browser/extensions/updater/extension_updater.h"
#include "chrome/browser/extensions/updater/manifest_fetch_data.h"
#include "chrome/browser/extensions/updater/request_queue_impl.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/omaha_query_params/omaha_query_params.h"
#include "chrome/browser/prefs/pref_service_syncable.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
#include "extensions/common/id_util.h"
#include "extensions/common/manifest_constants.h"
#include "libxml/globals.h"
#include "net/base/backoff_entry.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_status.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h"
#endif
using base::Time;
using base::TimeDelta;
using content::BrowserThread;
using testing::DoAll;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::Mock;
using testing::Return;
using testing::SetArgPointee;
using testing::_;
namespace extensions {
typedef ExtensionDownloaderDelegate::Error Error;
typedef ExtensionDownloaderDelegate::PingResult PingResult;
namespace {
const net::BackoffEntry::Policy kNoBackoffPolicy = {
1000,
0,
0,
0,
0,
-1,
false,
};
const char kEmptyUpdateUrlData[] = "";
int kExpectedLoadFlags =
net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DISABLE_CACHE;
int kExpectedLoadFlagsForProtectedDownload = net::LOAD_DISABLE_CACHE;
const ManifestFetchData::PingData kNeverPingedData(
ManifestFetchData::kNeverPinged, ManifestFetchData::kNeverPinged, true);
class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate {
public:
MOCK_METHOD4(OnExtensionDownloadFailed, void(const std::string&,
Error,
const PingResult&,
const std::set<int>&));
MOCK_METHOD7(OnExtensionDownloadFinished, void(const std::string&,
const base::FilePath&,
bool,
const GURL&,
const std::string&,
const PingResult&,
const std::set<int>&));
MOCK_METHOD2(GetPingDataForExtension,
bool(const std::string&, ManifestFetchData::PingData*));
MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&));
MOCK_METHOD1(IsExtensionPending, bool(const std::string&));
MOCK_METHOD2(GetExtensionExistingVersion,
bool(const std::string&, std::string*));
void Wait() {
scoped_refptr<content::MessageLoopRunner> runner =
new content::MessageLoopRunner;
quit_closure_ = runner->QuitClosure();
runner->Run();
quit_closure_.Reset();
}
void Quit() {
quit_closure_.Run();
}
void DelegateTo(ExtensionDownloaderDelegate* delegate) {
ON_CALL(*this, OnExtensionDownloadFailed(_, _, _, _))
.WillByDefault(Invoke(delegate,
&ExtensionDownloaderDelegate::OnExtensionDownloadFailed));
ON_CALL(*this, OnExtensionDownloadFinished(_, _, _, _, _, _, _))
.WillByDefault(Invoke(delegate,
&ExtensionDownloaderDelegate::OnExtensionDownloadFinished));
ON_CALL(*this, GetPingDataForExtension(_, _))
.WillByDefault(Invoke(delegate,
&ExtensionDownloaderDelegate::GetPingDataForExtension));
ON_CALL(*this, GetUpdateUrlData(_))
.WillByDefault(Invoke(delegate,
&ExtensionDownloaderDelegate::GetUpdateUrlData));
ON_CALL(*this, IsExtensionPending(_))
.WillByDefault(Invoke(delegate,
&ExtensionDownloaderDelegate::IsExtensionPending));
ON_CALL(*this, GetExtensionExistingVersion(_, _))
.WillByDefault(Invoke(delegate,
&ExtensionDownloaderDelegate::GetExtensionExistingVersion));
}
private:
base::Closure quit_closure_;
};
const int kNotificationsObserved[] = {
chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED,
chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
};
class NotificationsObserver : public content::NotificationObserver {
public:
NotificationsObserver() {
for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
count_[i] = 0;
registrar_.Add(this,
kNotificationsObserved[i],
content::NotificationService::AllSources());
}
}
virtual ~NotificationsObserver() {
for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
registrar_.Remove(this,
kNotificationsObserved[i],
content::NotificationService::AllSources());
}
}
size_t StartedCount() { return count_[0]; }
size_t UpdatedCount() { return count_[1]; }
bool Updated(const std::string& id) {
return updated_.find(id) != updated_.end();
}
void Wait() {
scoped_refptr<content::MessageLoopRunner> runner =
new content::MessageLoopRunner;
quit_closure_ = runner->QuitClosure();
runner->Run();
quit_closure_.Reset();
}
private:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE {
if (!quit_closure_.is_null())
quit_closure_.Run();
for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
if (kNotificationsObserved[i] == type) {
count_[i]++;
if (type == chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND) {
updated_.insert(
content::Details<UpdateDetails>(details)->id);
}
return;
}
}
NOTREACHED();
}
content::NotificationRegistrar registrar_;
size_t count_[arraysize(kNotificationsObserved)];
std::set<std::string> updated_;
base::Closure quit_closure_;
DISALLOW_COPY_AND_ASSIGN(NotificationsObserver);
};
}
class MockService : public TestExtensionService {
public:
explicit MockService(TestExtensionPrefs* prefs)
: prefs_(prefs), pending_extension_manager_(*this, &profile_) {}
virtual ~MockService() {}
virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
ADD_FAILURE() << "Subclass should override this if it will "
<< "be accessed by a test.";
return &pending_extension_manager_;
}
Profile* profile() { return &profile_; }
net::URLRequestContextGetter* request_context() {
return profile_.GetRequestContext();
}
ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
PrefService* pref_service() { return prefs_->pref_service(); }
void CreateTestExtensions(int id, int count, ExtensionList *list,
const std::string* update_url,
Manifest::Location location) {
for (int i = 1; i <= count; i++) {
base::DictionaryValue manifest;
manifest.SetString(manifest_keys::kVersion,
base::StringPrintf("%d.0.0.0", i));
manifest.SetString(manifest_keys::kName,
base::StringPrintf("Extension %d.%d", id, i));
if (update_url)
manifest.SetString(manifest_keys::kUpdateURL, *update_url);
scoped_refptr<Extension> e =
prefs_->AddExtensionWithManifest(manifest, location);
ASSERT_TRUE(e.get() != NULL);
list->push_back(e);
}
}
protected:
TestExtensionPrefs* const prefs_;
TestingProfile profile_;
PendingExtensionManager pending_extension_manager_;
private:
DISALLOW_COPY_AND_ASSIGN(MockService);
};
bool ShouldInstallExtensionsOnly(const Extension* extension) {
return extension->GetType() == Manifest::TYPE_EXTENSION;
}
bool ShouldInstallThemesOnly(const Extension* extension) {
return extension->is_theme();
}
bool ShouldAlwaysInstall(const Extension* extension) {
return true;
}
void SetupPendingExtensionManagerForTest(
int count,
const GURL& update_url,
PendingExtensionManager* pending_extension_manager) {
for (int i = 1; i <= count; ++i) {
PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
(i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
const bool kIsFromSync = true;
const bool kInstallSilently = true;
const bool kMarkAcknowledged = false;
std::string id = id_util::GenerateId(base::StringPrintf("extension%i", i));
pending_extension_manager->AddForTesting(
PendingExtensionInfo(id,
std::string(),
update_url,
Version(),
should_allow_install,
kIsFromSync,
kInstallSilently,
Manifest::INTERNAL,
Extension::NO_FLAGS,
kMarkAcknowledged));
}
}
class ServiceForManifestTests : public MockService {
public:
explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
: MockService(prefs), registry_(ExtensionRegistry::Get(profile())) {}
virtual ~ServiceForManifestTests() {}
virtual const Extension* GetExtensionById(
const std::string& id, bool include_disabled) const OVERRIDE {
const Extension* result = registry_->enabled_extensions().GetByID(id);
if (result || !include_disabled)
return result;
return registry_->disabled_extensions().GetByID(id);
}
virtual const ExtensionSet* extensions() const OVERRIDE {
return ®istry_->enabled_extensions();
}
virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
return &pending_extension_manager_;
}
virtual const Extension* GetPendingExtensionUpdate(
const std::string& id) const OVERRIDE {
return NULL;
}
virtual bool IsExtensionEnabled(const std::string& id) const OVERRIDE {
return !registry_->disabled_extensions().Contains(id);
}
void set_extensions(ExtensionList extensions,
ExtensionList disabled_extensions) {
registry_->ClearAll();
for (ExtensionList::const_iterator it = extensions.begin();
it != extensions.end(); ++it) {
registry_->AddEnabled(*it);
}
for (ExtensionList::const_iterator it = disabled_extensions.begin();
it != disabled_extensions.end(); ++it) {
registry_->AddDisabled(*it);
}
}
private:
ExtensionRegistry* registry_;
};
class ServiceForDownloadTests : public MockService {
public:
explicit ServiceForDownloadTests(TestExtensionPrefs* prefs)
: MockService(prefs) {
}
void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) {
fake_crx_installers_[id] = crx_installer;
}
virtual bool UpdateExtension(
const std::string& id,
const base::FilePath& extension_path,
bool file_ownership_passed,
const GURL& download_url,
CrxInstaller** out_crx_installer) OVERRIDE {
extension_id_ = id;
install_path_ = extension_path;
download_url_ = download_url;
if (ContainsKey(fake_crx_installers_, id)) {
*out_crx_installer = fake_crx_installers_[id];
return true;
}
return false;
}
virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
return &pending_extension_manager_;
}
virtual const Extension* GetExtensionById(
const std::string& id, bool) const OVERRIDE {
last_inquired_extension_id_ = id;
return NULL;
}
const std::string& extension_id() const { return extension_id_; }
const base::FilePath& install_path() const { return install_path_; }
const GURL& download_url() const { return download_url_; }
private:
std::map<std::string, CrxInstaller*> fake_crx_installers_;
std::string extension_id_;
base::FilePath install_path_;
GURL download_url_;
mutable std::string last_inquired_extension_id_;
};
static const int kUpdateFrequencySecs = 15;
static void ExtractParameters(const std::string& params,
std::map<std::string, std::string>* result) {
std::vector<std::string> pairs;
base::SplitString(params, '&', &pairs);
for (size_t i = 0; i < pairs.size(); i++) {
std::vector<std::string> key_val;
base::SplitString(pairs[i], '=', &key_val);
if (!key_val.empty()) {
std::string key = key_val[0];
EXPECT_TRUE(result->find(key) == result->end());
(*result)[key] = (key_val.size() == 2) ? key_val[1] : std::string();
} else {
NOTREACHED();
}
}
}
static void VerifyQueryAndExtractParameters(
const std::string& query,
std::map<std::string, std::string>* result) {
std::map<std::string, std::string> params;
ExtractParameters(query, ¶ms);
std::string omaha_params =
chrome::OmahaQueryParams::Get(chrome::OmahaQueryParams::CRX);
std::map<std::string, std::string> expected;
ExtractParameters(omaha_params, &expected);
for (std::map<std::string, std::string>::iterator it = expected.begin();
it != expected.end(); ++it) {
EXPECT_EQ(it->second, params[it->first]);
}
EXPECT_EQ(1U, params.count("x"));
std::string decoded = net::UnescapeURLComponent(
params["x"], net::UnescapeRule::URL_SPECIAL_CHARS);
ExtractParameters(decoded, result);
}
class ExtensionUpdaterTest : public testing::Test {
public:
ExtensionUpdaterTest()
: thread_bundle_(
content::TestBrowserThreadBundle::IO_MAINLOOP) {
}
virtual void SetUp() OVERRIDE {
prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
}
virtual void TearDown() OVERRIDE {
RunUntilIdle();
prefs_.reset();
}
void RunUntilIdle() {
prefs_->pref_service()->CommitPendingWrite();
base::RunLoop().RunUntilIdle();
}
void SimulateTimerFired(ExtensionUpdater* updater) {
EXPECT_TRUE(updater->timer_.IsRunning());
updater->timer_.Stop();
updater->TimerFired();
}
void AddParseResult(const std::string& id,
const std::string& version,
const std::string& url,
UpdateManifest::Results* results) {
UpdateManifest::Result result;
result.extension_id = id;
result.version = version;
result.crx_url = GURL(url);
results->list.push_back(result);
}
void ResetDownloader(ExtensionUpdater* updater,
ExtensionDownloader* downloader) {
EXPECT_FALSE(updater->downloader_.get());
updater->downloader_.reset(downloader);
}
void StartUpdateCheck(ExtensionDownloader* downloader,
ManifestFetchData* fetch_data) {
downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data));
}
size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
return downloader->manifests_queue_.size() +
(downloader->manifest_fetcher_.get() ? 1 : 0);
}
void TestExtensionUpdateCheckRequests(bool pending) {
ServiceForManifestTests service(prefs_.get());
std::string update_url("http://foo.com/bar");
ExtensionList extensions;
NotificationsObserver observer;
PendingExtensionManager* pending_extension_manager =
service.pending_extension_manager();
if (pending) {
SetupPendingExtensionManagerForTest(1, GURL(update_url),
pending_extension_manager);
} else {
service.CreateTestExtensions(1, 1, &extensions, &update_url,
Manifest::INTERNAL);
service.set_extensions(extensions, ExtensionList());
}
net::TestURLFetcherFactory factory;
ExtensionUpdater updater(
&service, service.extension_prefs(), service.pref_service(),
service.profile(), 60*60*24, NULL);
updater.Start();
EXPECT_EQ(0u, observer.StartedCount());
SimulateTimerFired(&updater);
EXPECT_EQ(1u, observer.StartedCount());
net::TestURLFetcher* fetcher =
factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
const GURL& url = fetcher->GetOriginalURL();
EXPECT_FALSE(url.is_empty());
EXPECT_TRUE(url.is_valid());
EXPECT_TRUE(url.SchemeIs("http"));
EXPECT_EQ("foo.com", url.host());
EXPECT_EQ("/bar", url.path());
EXPECT_TRUE(url.has_query());
std::map<std::string, std::string> params;
VerifyQueryAndExtractParameters(url.query(), ¶ms);
if (pending) {
EXPECT_TRUE(pending_extension_manager->IsIdPending(params["id"]));
EXPECT_EQ("0.0.0.0", params["v"]);
} else {
EXPECT_EQ(extensions[0]->id(), params["id"]);
EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
}
EXPECT_EQ("", params["uc"]);
}
void TestUpdateUrlDataEmpty() {
const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const std::string version = "1.0";
ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
fetch_data.AddExtension(
id, version, &kNeverPingedData, std::string(), std::string());
std::map<std::string, std::string> params;
VerifyQueryAndExtractParameters(fetch_data.full_url().query(), ¶ms);
EXPECT_EQ(id, params["id"]);
EXPECT_EQ(version, params["v"]);
EXPECT_EQ(0U, params.count("ap"));
}
void TestUpdateUrlDataSimple() {
const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const std::string version = "1.0";
ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
fetch_data.AddExtension(
id, version, &kNeverPingedData, "bar", std::string());
std::map<std::string, std::string> params;
VerifyQueryAndExtractParameters(fetch_data.full_url().query(), ¶ms);
EXPECT_EQ(id, params["id"]);
EXPECT_EQ(version, params["v"]);
EXPECT_EQ("bar", params["ap"]);
}
void TestUpdateUrlDataCompound() {
const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const std::string version = "1.0";
ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
fetch_data.AddExtension(
id, version, &kNeverPingedData, "a=1&b=2&c", std::string());
std::map<std::string, std::string> params;
VerifyQueryAndExtractParameters(fetch_data.full_url().query(), ¶ms);
EXPECT_EQ(id, params["id"]);
EXPECT_EQ(version, params["v"]);
EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]);
}
void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
net::TestURLFetcherFactory factory;
MockService service(prefs_.get());
MockExtensionDownloaderDelegate delegate;
ExtensionDownloader downloader(&delegate, service.request_context());
ExtensionList extensions;
std::string url(gallery_url);
service.CreateTestExtensions(1, 1, &extensions, &url, Manifest::INTERNAL);
const std::string& id = extensions[0]->id();
EXPECT_CALL(delegate, GetPingDataForExtension(id, _));
downloader.AddExtension(*extensions[0].get(), 0);
downloader.StartAllPending(NULL);
net::TestURLFetcher* fetcher =
factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
ASSERT_TRUE(fetcher);
const std::string& update_url = fetcher->GetOriginalURL().spec();
std::string::size_type x = update_url.find("x=");
EXPECT_NE(std::string::npos, x);
std::string::size_type ap = update_url.find("ap%3D", x);
EXPECT_EQ(std::string::npos, ap);
}
void TestInstallSource() {
const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const std::string version = "1.0";
const std::string install_source = "instally";
ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
fetch_data.AddExtension(id, version, &kNeverPingedData,
kEmptyUpdateUrlData, install_source);
std::map<std::string, std::string> params;
VerifyQueryAndExtractParameters(fetch_data.full_url().query(), ¶ms);
EXPECT_EQ(id, params["id"]);
EXPECT_EQ(version, params["v"]);
EXPECT_EQ(install_source, params["installsource"]);
}
void TestDetermineUpdates() {
TestingProfile profile;
MockExtensionDownloaderDelegate delegate;
ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
UpdateManifest::Results updates;
std::vector<int> updateable;
downloader.DetermineUpdates(fetch_data, updates, &updateable);
EXPECT_TRUE(updateable.empty());
const std::string id1 = id_util::GenerateId("1");
const std::string id2 = id_util::GenerateId("2");
fetch_data.AddExtension(
id1, "1.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string());
AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);
fetch_data.AddExtension(
id2, "2.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string());
AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);
EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
.WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"),
Return(true)));
EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
.WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"),
Return(true)));
downloader.DetermineUpdates(fetch_data, updates, &updateable);
EXPECT_EQ(1u, updateable.size());
EXPECT_EQ(0, updateable[0]);
}
void TestDetermineUpdatesPending() {
ServiceForManifestTests service(prefs_.get());
PendingExtensionManager* pending_extension_manager =
service.pending_extension_manager();
SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
TestingProfile profile;
MockExtensionDownloaderDelegate delegate;
ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
ManifestFetchData fetch_data(GURL("http://localhost/foo"), 0);
UpdateManifest::Results updates;
std::list<std::string> ids_for_update_check;
pending_extension_manager->GetPendingIdsForUpdateCheck(
&ids_for_update_check);
std::list<std::string>::const_iterator it;
for (it = ids_for_update_check.begin();
it != ids_for_update_check.end(); ++it) {
fetch_data.AddExtension(*it,
"1.0.0.0",
&kNeverPingedData,
kEmptyUpdateUrlData,
std::string());
AddParseResult(*it, "1.1", "http://localhost/e1_1.1.crx", &updates);
}
EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(true));
std::vector<int> updateable;
downloader.DetermineUpdates(fetch_data, updates, &updateable);
EXPECT_EQ(3u, updateable.size());
for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) {
EXPECT_EQ(static_cast<int>(i), updateable[i]);
}
}
void TestMultipleManifestDownloading() {
net::TestURLFetcherFactory factory;
net::TestURLFetcher* fetcher = NULL;
NotificationsObserver observer;
MockService service(prefs_.get());
MockExtensionDownloaderDelegate delegate;
ExtensionDownloader downloader(&delegate, service.request_context());
downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
GURL kUpdateUrl("http://localhost/manifest1");
scoped_ptr<ManifestFetchData> fetch1(new ManifestFetchData(kUpdateUrl, 0));
scoped_ptr<ManifestFetchData> fetch2(new ManifestFetchData(kUpdateUrl, 0));
scoped_ptr<ManifestFetchData> fetch3(new ManifestFetchData(kUpdateUrl, 0));
scoped_ptr<ManifestFetchData> fetch4(new ManifestFetchData(kUpdateUrl, 0));
ManifestFetchData::PingData zeroDays(0, 0, true);
fetch1->AddExtension(
"1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
fetch2->AddExtension(
"2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string());
fetch3->AddExtension(
"3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string());
fetch4->AddExtension(
"4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string());
downloader.StartUpdateCheck(fetch1.Pass());
downloader.StartUpdateCheck(fetch2.Pass());
downloader.StartUpdateCheck(fetch3.Pass());
downloader.StartUpdateCheck(fetch4.Pass());
RunUntilIdle();
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
EXPECT_CALL(delegate, OnExtensionDownloadFailed(
"1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
fetcher->set_url(kUpdateUrl);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(400);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
Mock::VerifyAndClearExpectations(&delegate);
const std::string kInvalidXml = "invalid xml";
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
EXPECT_CALL(delegate, OnExtensionDownloadFailed(
"2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _))
.WillOnce(InvokeWithoutArgs(&delegate,
&MockExtensionDownloaderDelegate::Quit));
fetcher->set_url(kUpdateUrl);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(200);
fetcher->SetResponseString(kInvalidXml);
fetcher->delegate()->OnURLFetchComplete(fetcher);
delegate.Wait();
Mock::VerifyAndClearExpectations(&delegate);
const std::string kNoUpdate =
"<?xml version='1.0' encoding='UTF-8'?>"
"<gupdate xmlns='http://www.google.com/update2/response'"
" protocol='2.0'>"
" <app appid='3333'>"
" <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'"
" version='3.0.0.0' prodversionmin='3.0.0.0' />"
" </app>"
"</gupdate>";
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
EXPECT_CALL(delegate, IsExtensionPending("3333")).WillOnce(Return(false));
EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _))
.WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"),
Return(true)));
EXPECT_CALL(delegate, OnExtensionDownloadFailed(
"3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _))
.WillOnce(InvokeWithoutArgs(&delegate,
&MockExtensionDownloaderDelegate::Quit));
fetcher->set_url(kUpdateUrl);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(200);
fetcher->SetResponseString(kNoUpdate);
fetcher->delegate()->OnURLFetchComplete(fetcher);
delegate.Wait();
Mock::VerifyAndClearExpectations(&delegate);
const std::string kUpdateAvailable =
"<?xml version='1.0' encoding='UTF-8'?>"
"<gupdate xmlns='http://www.google.com/update2/response'"
" protocol='2.0'>"
" <app appid='4444'>"
" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
" version='4.0.42.0' prodversionmin='4.0.42.0' />"
" </app>"
"</gupdate>";
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
EXPECT_CALL(delegate, IsExtensionPending("4444")).WillOnce(Return(false));
EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _))
.WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"),
Return(true)));
fetcher->set_url(kUpdateUrl);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(200);
fetcher->SetResponseString(kUpdateAvailable);
fetcher->delegate()->OnURLFetchComplete(fetcher);
observer.Wait();
Mock::VerifyAndClearExpectations(&delegate);
EXPECT_EQ(1u, observer.UpdatedCount());
EXPECT_TRUE(observer.Updated("4444"));
}
void TestManifestRetryDownloading() {
net::TestURLFetcherFactory factory;
net::TestURLFetcher* fetcher = NULL;
NotificationsObserver observer;
MockService service(prefs_.get());
MockExtensionDownloaderDelegate delegate;
ExtensionDownloader downloader(&delegate, service.request_context());
downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
GURL kUpdateUrl("http://localhost/manifest1");
scoped_ptr<ManifestFetchData> fetch(new ManifestFetchData(kUpdateUrl, 0));
ManifestFetchData::PingData zeroDays(0, 0, true);
fetch->AddExtension(
"1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
downloader.StartUpdateCheck(fetch.Pass());
RunUntilIdle();
EXPECT_CALL(delegate, OnExtensionDownloadFailed(
"1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
for (int i = 0; i <= ExtensionDownloader::kMaxRetries; ++i) {
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
fetcher->set_url(kUpdateUrl);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(500);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
}
Mock::VerifyAndClearExpectations(&delegate);
fetch.reset(new ManifestFetchData(kUpdateUrl, 0));
fetch->AddExtension(
"1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string());
downloader.StartUpdateCheck(fetch.Pass());
RunUntilIdle();
EXPECT_CALL(delegate, OnExtensionDownloadFailed(
"1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
fetcher->set_url(kUpdateUrl);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(500);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
fetcher->set_url(kUpdateUrl);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(400);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
Mock::VerifyAndClearExpectations(&delegate);
}
void TestSingleExtensionDownloading(bool pending, bool retry, bool fail) {
net::TestURLFetcherFactory factory;
net::TestURLFetcher* fetcher = NULL;
scoped_ptr<ServiceForDownloadTests> service(
new ServiceForDownloadTests(prefs_.get()));
ExtensionUpdater updater(service.get(), service->extension_prefs(),
service->pref_service(),
service->profile(),
kUpdateFrequencySecs,
NULL);
updater.Start();
MockExtensionDownloaderDelegate delegate;
delegate.DelegateTo(&updater);
ResetDownloader(
&updater,
new ExtensionDownloader(&delegate, service->request_context()));
updater.downloader_->extensions_queue_.set_backoff_policy(
&kNoBackoffPolicy);
GURL test_url("http://localhost/extension.crx");
std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
std::string hash;
Version version("0.0.1");
std::set<int> requests;
requests.insert(0);
scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
new ExtensionDownloader::ExtensionFetch(
id, test_url, hash, version.GetString(), requests));
updater.downloader_->FetchUpdatedExtension(fetch.Pass());
if (pending) {
const bool kIsFromSync = true;
const bool kInstallSilently = true;
const bool kMarkAcknowledged = false;
PendingExtensionManager* pending_extension_manager =
service->pending_extension_manager();
pending_extension_manager->AddForTesting(
PendingExtensionInfo(id,
std::string(),
test_url,
version,
&ShouldAlwaysInstall,
kIsFromSync,
kInstallSilently,
Manifest::INTERNAL,
Extension::NO_FLAGS,
kMarkAcknowledged));
}
base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
if (retry) {
fetcher->set_url(test_url);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(500);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
fetcher = factory.GetFetcherByID(
ExtensionDownloader::kExtensionFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
}
fetcher->set_url(test_url);
fetcher->set_status(net::URLRequestStatus());
if (fail) {
fetcher->set_response_code(404);
EXPECT_CALL(delegate, OnExtensionDownloadFailed(id, _, _, requests));
} else {
fetcher->set_response_code(200);
fetcher->SetResponseFilePath(extension_file_path);
EXPECT_CALL(delegate, OnExtensionDownloadFinished(
id, _, _, _, version.GetString(), _, requests));
}
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
if (fail) {
EXPECT_TRUE(service->extension_id().empty());
} else {
EXPECT_EQ(id, service->extension_id());
base::FilePath tmpfile_path = service->install_path();
EXPECT_FALSE(tmpfile_path.empty());
EXPECT_EQ(test_url, service->download_url());
EXPECT_EQ(extension_file_path, tmpfile_path);
}
}
void TestSingleProtectedExtensionDownloading(bool use_https, bool fail) {
net::TestURLFetcherFactory factory;
net::TestURLFetcher* fetcher = NULL;
scoped_ptr<ServiceForDownloadTests> service(
new ServiceForDownloadTests(prefs_.get()));
ExtensionUpdater updater(service.get(), service->extension_prefs(),
service->pref_service(),
service->profile(),
kUpdateFrequencySecs,
NULL);
updater.Start();
ResetDownloader(
&updater,
new ExtensionDownloader(&updater, service->request_context()));
updater.downloader_->extensions_queue_.set_backoff_policy(
&kNoBackoffPolicy);
GURL test_url(use_https ? "https://localhost/extension.crx" :
"http://localhost/extension.crx");
std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
std::string hash;
Version version("0.0.1");
std::set<int> requests;
requests.insert(0);
scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
new ExtensionDownloader::ExtensionFetch(
id, test_url, hash, version.GetString(), requests));
updater.downloader_->FetchUpdatedExtension(fetch.Pass());
fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
fetcher->set_url(test_url);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(403);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
if (use_https) {
EXPECT_TRUE(
fetcher->GetLoadFlags() == kExpectedLoadFlagsForProtectedDownload);
} else {
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
}
if (fail) {
fetcher->set_url(test_url);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(403);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
EXPECT_EQ(0U, updater.downloader_->extensions_queue_.active_request());
} else {
base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
fetcher->set_url(test_url);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(200);
fetcher->SetResponseFilePath(extension_file_path);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
EXPECT_EQ(id, service->extension_id());
base::FilePath tmpfile_path = service->install_path();
EXPECT_FALSE(tmpfile_path.empty());
EXPECT_EQ(test_url, service->download_url());
EXPECT_EQ(extension_file_path, tmpfile_path);
}
}
void TestMultipleExtensionDownloading(bool updates_start_running) {
net::TestURLFetcherFactory factory;
net::TestURLFetcher* fetcher = NULL;
ServiceForDownloadTests service(prefs_.get());
ExtensionUpdater updater(
&service, service.extension_prefs(), service.pref_service(),
service.profile(), kUpdateFrequencySecs, NULL);
updater.Start();
ResetDownloader(
&updater,
new ExtensionDownloader(&updater, service.request_context()));
updater.downloader_->extensions_queue_.set_backoff_policy(
&kNoBackoffPolicy);
EXPECT_FALSE(updater.crx_install_is_running_);
GURL url1("http://localhost/extension1.crx");
GURL url2("http://localhost/extension2.crx");
std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
std::string hash1;
std::string hash2;
std::string version1 = "0.1";
std::string version2 = "0.1";
std::set<int> requests;
requests.insert(0);
scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch1(
new ExtensionDownloader::ExtensionFetch(
id1, url1, hash1, version1, requests));
scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch2(
new ExtensionDownloader::ExtensionFetch(
id2, url2, hash2, version2, requests));
updater.downloader_->FetchUpdatedExtension(fetch1.Pass());
updater.downloader_->FetchUpdatedExtension(fetch2.Pass());
base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
TestingProfile profile;
static_cast<TestExtensionSystem*>(
ExtensionSystem::Get(&profile))->
CreateExtensionService(
CommandLine::ForCurrentProcess(),
base::FilePath(),
false);
ExtensionService* extension_service =
ExtensionSystem::Get(&profile)->extension_service();
extension_service->set_extensions_enabled(true);
extension_service->set_show_extensions_prompts(false);
scoped_refptr<CrxInstaller> fake_crx1(
CrxInstaller::CreateSilent(extension_service));
scoped_refptr<CrxInstaller> fake_crx2(
CrxInstaller::CreateSilent(extension_service));
if (updates_start_running) {
service.AddFakeCrxInstaller(id1, fake_crx1.get());
service.AddFakeCrxInstaller(id2, fake_crx2.get());
} else {
}
fetcher->set_url(url1);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(200);
fetcher->SetResponseFilePath(extension_file_path);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
base::FilePath tmpfile_path = service.install_path();
EXPECT_FALSE(tmpfile_path.empty());
EXPECT_EQ(id1, service.extension_id());
EXPECT_EQ(url1, service.download_url());
RunUntilIdle();
base::FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2"));
fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
fetcher->set_url(url2);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(200);
fetcher->SetResponseFilePath(extension_file_path2);
fetcher->delegate()->OnURLFetchComplete(fetcher);
RunUntilIdle();
if (updates_start_running) {
EXPECT_TRUE(updater.crx_install_is_running_);
EXPECT_EQ(id1, service.extension_id());
EXPECT_EQ(url1, service.download_url());
fake_crx1->NotifyCrxInstallComplete(false);
EXPECT_TRUE(updater.crx_install_is_running_);
}
EXPECT_EQ(id2, service.extension_id());
EXPECT_EQ(url2, service.download_url());
EXPECT_FALSE(service.install_path().empty());
EXPECT_EQ(extension_file_path2, service.install_path());
if (updates_start_running) {
EXPECT_TRUE(updater.crx_install_is_running_);
fake_crx2->NotifyCrxInstallComplete(false);
}
EXPECT_FALSE(updater.crx_install_is_running_);
}
void TestGalleryRequestsWithBrand(bool use_organic_brand_code) {
google_util::BrandForTesting brand_for_testing(
use_organic_brand_code ? "GGLS" : "TEST");
int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
for (size_t i = 0; i < arraysize(ping_cases); i++) {
for (size_t j = 0; j < arraysize(ping_cases); j++) {
for (size_t k = 0; k < 2; k++) {
int rollcall_ping_days = ping_cases[i];
int active_ping_days = ping_cases[j];
if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
active_ping_days > 0)
continue;
bool active_bit = k > 0;
TestGalleryRequests(rollcall_ping_days, active_ping_days, active_bit,
!use_organic_brand_code);
ASSERT_FALSE(HasFailure()) <<
" rollcall_ping_days=" << ping_cases[i] <<
" active_ping_days=" << ping_cases[j] <<
" active_bit=" << active_bit;
}
}
}
}
void TestGalleryRequests(int rollcall_ping_days,
int active_ping_days,
bool active_bit,
bool expect_brand_code) {
net::TestURLFetcherFactory factory;
prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
ServiceForManifestTests service(prefs_.get());
ExtensionList tmp;
GURL url1("http://clients2.google.com/service/update2/crx");
GURL url2("http://www.somewebsite.com");
service.CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
Manifest::INTERNAL);
service.CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
Manifest::INTERNAL);
EXPECT_EQ(2u, tmp.size());
service.set_extensions(tmp, ExtensionList());
ExtensionPrefs* prefs = service.extension_prefs();
const std::string& id = tmp[0]->id();
Time now = Time::Now();
if (rollcall_ping_days == 0) {
prefs->SetLastPingDay(id, now - TimeDelta::FromSeconds(15));
} else if (rollcall_ping_days > 0) {
Time last_ping_day = now -
TimeDelta::FromDays(rollcall_ping_days) -
TimeDelta::FromSeconds(15);
prefs->SetLastPingDay(id, last_ping_day);
}
if (active_ping_days == 0) {
prefs->SetLastActivePingDay(id, now - TimeDelta::FromSeconds(15));
} else if (active_ping_days > 0) {
Time last_active_ping_day = now -
TimeDelta::FromDays(active_ping_days) -
TimeDelta::FromSeconds(15);
prefs->SetLastActivePingDay(id, last_active_ping_day);
}
if (active_bit)
prefs->SetActiveBit(id, true);
ExtensionUpdater updater(
&service, service.extension_prefs(), service.pref_service(),
service.profile(), kUpdateFrequencySecs, NULL);
ExtensionUpdater::CheckParams params;
updater.Start();
updater.CheckNow(params);
std::vector<GURL> fetched_urls;
net::TestURLFetcher* fetcher =
factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
fetched_urls.push_back(fetcher->GetOriginalURL());
fetcher->set_url(fetched_urls[0]);
fetcher->set_status(net::URLRequestStatus());
fetcher->set_response_code(500);
fetcher->SetResponseString(std::string());
fetcher->delegate()->OnURLFetchComplete(fetcher);
fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
fetched_urls.push_back(fetcher->GetOriginalURL());
std::string url1_query;
std::string url2_query;
if (fetched_urls[0].host() == url1.host()) {
url1_query = fetched_urls[0].query();
url2_query = fetched_urls[1].query();
} else if (fetched_urls[0].host() == url2.host()) {
url1_query = fetched_urls[1].query();
url2_query = fetched_urls[0].query();
} else {
NOTREACHED();
}
std::string search_string = "ping%3D";
EXPECT_TRUE(url2_query.find(search_string) == std::string::npos);
bool ping_expected = false;
bool did_rollcall = false;
if (rollcall_ping_days != 0) {
search_string += "r%253D" + base::IntToString(rollcall_ping_days);
did_rollcall = true;
ping_expected = true;
}
if (active_bit && active_ping_days != 0) {
if (did_rollcall)
search_string += "%2526";
search_string += "a%253D" + base::IntToString(active_ping_days);
ping_expected = true;
}
bool ping_found = url1_query.find(search_string) != std::string::npos;
EXPECT_EQ(ping_expected, ping_found) << "query was: " << url1_query
<< " was looking for " << search_string;
const std::string brand_string = "brand%3D";
EXPECT_TRUE(url2_query.find(brand_string) == std::string::npos);
#if defined(GOOGLE_CHROME_BUILD)
if (expect_brand_code) {
EXPECT_TRUE(url1_query.find(brand_string) != std::string::npos);
} else {
EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
}
#else
EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
#endif
RunUntilIdle();
}
void TestHandleManifestResults() {
ServiceForManifestTests service(prefs_.get());
GURL update_url("http://www.google.com/manifest");
ExtensionList tmp;
service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
Manifest::INTERNAL);
service.set_extensions(tmp, ExtensionList());
ExtensionUpdater updater(
&service, service.extension_prefs(), service.pref_service(),
service.profile(), kUpdateFrequencySecs, NULL);
updater.Start();
ResetDownloader(
&updater,
new ExtensionDownloader(&updater, service.request_context()));
ManifestFetchData fetch_data(update_url, 0);
const Extension* extension = tmp[0].get();
fetch_data.AddExtension(extension->id(),
extension->VersionString(),
&kNeverPingedData,
kEmptyUpdateUrlData,
std::string());
UpdateManifest::Results results;
results.daystart_elapsed_seconds = 750;
updater.downloader_->HandleManifestResults(fetch_data, &results);
Time last_ping_day =
service.extension_prefs()->LastPingDay(extension->id());
EXPECT_FALSE(last_ping_day.is_null());
int64 seconds_diff = (Time::Now() - last_ping_day).InSeconds();
EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
}
protected:
scoped_ptr<TestExtensionPrefs> prefs_;
private:
content::TestBrowserThreadBundle thread_bundle_;
content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
#if defined OS_CHROMEOS
chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
chromeos::ScopedTestCrosSettings test_cros_settings_;
chromeos::ScopedTestUserManager test_user_manager_;
#endif
};
TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
TestExtensionUpdateCheckRequests(false);
}
TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
TestExtensionUpdateCheckRequests(true);
}
TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
TestUpdateUrlDataEmpty();
TestUpdateUrlDataSimple();
TestUpdateUrlDataCompound();
TestUpdateUrlDataFromGallery(
extension_urls::GetWebstoreUpdateUrl().spec());
}
TEST_F(ExtensionUpdaterTest, TestInstallSource) {
TestInstallSource();
}
TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
TestDetermineUpdates();
}
TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
TestDetermineUpdatesPending();
}
TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
TestMultipleManifestDownloading();
}
TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
TestSingleExtensionDownloading(false, false, false);
}
TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
TestSingleExtensionDownloading(true, false, false);
}
TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
TestSingleExtensionDownloading(false, true, false);
}
TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
TestSingleExtensionDownloading(true, true, false);
}
TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailure) {
TestSingleExtensionDownloading(false, false, true);
}
TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailureWithRetry) {
TestSingleExtensionDownloading(false, true, true);
}
TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailurePending) {
TestSingleExtensionDownloading(true, false, true);
}
TEST_F(ExtensionUpdaterTest, TestSingleProtectedExtensionDownloading) {
TestSingleProtectedExtensionDownloading(true, false);
}
TEST_F(ExtensionUpdaterTest, TestSingleProtectedExtensionDownloadingFailure) {
TestSingleProtectedExtensionDownloading(true, true);
}
TEST_F(ExtensionUpdaterTest, TestSingleProtectedExtensionDownloadingNoHTTPS) {
TestSingleProtectedExtensionDownloading(false, false);
}
TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
TestMultipleExtensionDownloading(false);
}
TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
TestMultipleExtensionDownloading(true);
}
TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
TestManifestRetryDownloading();
}
TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) {
TestGalleryRequestsWithBrand(true);
}
TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) {
TestGalleryRequestsWithBrand(false);
}
TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
TestHandleManifestResults();
}
TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
net::TestURLFetcherFactory factory;
ServiceForManifestTests service(prefs_.get());
ExtensionUpdater updater(&service, service.extension_prefs(),
service.pref_service(), service.profile(),
kUpdateFrequencySecs, NULL);
MockExtensionDownloaderDelegate delegate;
ExtensionDownloader* downloader =
new ExtensionDownloader(&delegate, service.request_context());
ResetDownloader(&updater, downloader);
ExtensionList extensions;
service.CreateTestExtensions(1, 1, &extensions, NULL,
Manifest::INVALID_LOCATION);
service.CreateTestExtensions(2, 1, &extensions, NULL, Manifest::INTERNAL);
ASSERT_EQ(2u, extensions.size());
const std::string& updateable_id = extensions[1]->id();
EXPECT_CALL(delegate, GetUpdateUrlData(updateable_id)).WillOnce(Return(""));
EXPECT_CALL(delegate, GetPingDataForExtension(updateable_id, _));
service.set_extensions(extensions, ExtensionList());
ExtensionUpdater::CheckParams params;
updater.Start();
updater.CheckNow(params);
}
TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
net::TestURLFetcherFactory factory;
ServiceForManifestTests service(prefs_.get());
ExtensionUpdater updater(&service, service.extension_prefs(),
service.pref_service(), service.profile(),
kUpdateFrequencySecs, NULL);
MockExtensionDownloaderDelegate delegate;
ExtensionDownloader* downloader =
new ExtensionDownloader(&delegate, service.request_context());
ResetDownloader(&updater, downloader);
ExtensionList enabled_extensions;
ExtensionList disabled_extensions;
service.CreateTestExtensions(1, 1, &enabled_extensions, NULL,
Manifest::INTERNAL);
service.CreateTestExtensions(2, 1, &disabled_extensions, NULL,
Manifest::INTERNAL);
ASSERT_EQ(1u, enabled_extensions.size());
ASSERT_EQ(1u, disabled_extensions.size());
const std::string& enabled_id = enabled_extensions[0]->id();
const std::string& disabled_id = disabled_extensions[0]->id();
EXPECT_CALL(delegate, GetUpdateUrlData(enabled_id)).WillOnce(Return(""));
EXPECT_CALL(delegate, GetPingDataForExtension(enabled_id, _));
EXPECT_CALL(delegate, GetUpdateUrlData(disabled_id)).WillOnce(Return(""));
EXPECT_CALL(delegate, GetPingDataForExtension(disabled_id, _));
service.set_extensions(enabled_extensions, disabled_extensions);
ExtensionUpdater::CheckParams params;
updater.Start();
updater.CheckNow(params);
}
TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
net::TestURLFetcherFactory factory;
MockService service(prefs_.get());
MockExtensionDownloaderDelegate delegate;
scoped_ptr<ExtensionDownloader> downloader(
new ExtensionDownloader(&delegate, service.request_context()));
EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
std::string id = id_util::GenerateId("foo");
EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
EXPECT_TRUE(
downloader->AddPendingExtension(id, GURL("http://example.com/update"),
0));
downloader->StartAllPending(NULL);
Mock::VerifyAndClearExpectations(&delegate);
EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
id = id_util::GenerateId("foo2");
EXPECT_FALSE(
downloader->AddPendingExtension(id, GURL("http:google.com:foo"), 0));
downloader->StartAllPending(NULL);
EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
EXPECT_FALSE(downloader->AddPendingExtension(std::string(), GURL(), 0));
downloader->StartAllPending(NULL);
EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
downloader.reset(
new ExtensionDownloader(&delegate, service.request_context()));
EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
id = id_util::GenerateId("foo3");
EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
EXPECT_TRUE(downloader->AddPendingExtension(id, GURL(), 0));
downloader->StartAllPending(NULL);
EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
net::TestURLFetcher* fetcher =
factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
ASSERT_TRUE(fetcher);
EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
}
TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
net::TestURLFetcherFactory factory;
MockService service(prefs_.get());
MockExtensionDownloaderDelegate delegate;
ExtensionDownloader downloader(&delegate, service.request_context());
StartUpdateCheck(&downloader, new ManifestFetchData(GURL(), 0));
StartUpdateCheck(&downloader, new ManifestFetchData(GURL(), 0));
StartUpdateCheck(&downloader, new ManifestFetchData(GURL(
GURL("http://www.google.com")), 0));
}
TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
ServiceForManifestTests service(prefs_.get());
net::TestURLFetcherFactory factory;
ExtensionUpdater updater(
&service, service.extension_prefs(), service.pref_service(),
service.profile(), kUpdateFrequencySecs, NULL);
EXPECT_FALSE(updater.WillCheckSoon());
updater.Start();
EXPECT_FALSE(updater.WillCheckSoon());
updater.CheckSoon();
EXPECT_TRUE(updater.WillCheckSoon());
updater.CheckSoon();
EXPECT_TRUE(updater.WillCheckSoon());
RunUntilIdle();
EXPECT_FALSE(updater.WillCheckSoon());
updater.CheckSoon();
EXPECT_TRUE(updater.WillCheckSoon());
updater.Stop();
EXPECT_FALSE(updater.WillCheckSoon());
}
}