Index: chrome/browser/component_updater/test/component_updater_service_unittest.cc |
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest.cc b/chrome/browser/component_updater/test/component_updater_service_unittest.cc |
index 080b1d28c43ff8b1028384ef90934da81e286968..1771a6c866463974a5794b81fe105636c1c4a0af 100644 |
--- a/chrome/browser/component_updater/test/component_updater_service_unittest.cc |
+++ b/chrome/browser/component_updater/test/component_updater_service_unittest.cc |
@@ -2,8 +2,6 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "chrome/browser/component_updater/component_updater_service.h" |
- |
#include <list> |
#include <utility> |
@@ -13,7 +11,12 @@ |
#include "base/memory/scoped_vector.h" |
#include "base/message_loop.h" |
#include "base/path_service.h" |
+#include "base/stringprintf.h" |
+#include "base/strings/string_number_conversions.h" |
#include "base/values.h" |
+#include "chrome/browser/component_updater/component_updater_service.h" |
+#include "chrome/browser/component_updater/test/component_patcher_mock.h" |
+#include "chrome/browser/component_updater/test/test_installer.h" |
#include "chrome/common/chrome_notification_types.h" |
#include "chrome/common/chrome_paths.h" |
#include "content/public/browser/notification_observer.h" |
@@ -23,7 +26,11 @@ |
#include "content/test/net/url_request_prepackaged_interceptor.h" |
#include "googleurl/src/gurl.h" |
#include "libxml/globals.h" |
+#include "net/base/upload_bytes_element_reader.h" |
#include "net/url_request/url_fetcher.h" |
+#include "net/url_request/url_request.h" |
+#include "net/url_request/url_request_filter.h" |
+#include "net/url_request/url_request_simple_job.h" |
#include "net/url_request/url_request_test_util.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -31,98 +38,72 @@ using content::BrowserThread; |
using content::TestNotificationTracker; |
namespace { |
-// Overrides some of the component updater behaviors so it is easier to test |
-// and loops faster. In actual usage it takes hours do to a full cycle. |
+ |
+// component 1 has extension id "jebgalgnebhfojomionfpkfelancnnkf", and |
+// the RSA public key the following hash: |
+const uint8 jebg_hash[] = {0x94, 0x16, 0x0b, 0x6d, 0x41, 0x75, 0xe9, 0xec, |
+ 0x8e, 0xd5, 0xfa, 0x54, 0xb0, 0xd2, 0xdd, 0xa5, |
+ 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47, 0xf6, 0xc4, |
+ 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40}; |
+// component 2 has extension id "abagagagagagagagagagagagagagagag", and |
+// the RSA public key the following hash: |
+const uint8 abag_hash[] = {0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, |
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, |
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, |
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01}; |
+// component 3 has extension id "ihfokbkgjpifnbbojhneepfflplebdkc", and |
+// the RSA public key the following hash: |
+const uint8 ihfo_hash[] = {0x87, 0x5e, 0xa1, 0xa6, 0x9f, 0x85, 0xd1, 0x1e, |
+ 0x97, 0xd4, 0x4f, 0x55, 0xbf, 0xb4, 0x13, 0xa2, |
+ 0xe7, 0xc5, 0xc8, 0xf5, 0x60, 0x19, 0x78, 0x1b, |
+ 0x6d, 0xe9, 0x4c, 0xeb, 0x96, 0x05, 0x42, 0x17}; |
+ |
class TestConfigurator : public ComponentUpdateService::Configurator { |
public: |
- TestConfigurator() |
- : times_(1), recheck_time_(0), ondemand_time_(0), cus_(NULL) { |
- } |
+ TestConfigurator(); |
- virtual int InitialDelay() OVERRIDE { return 0; } |
+ virtual int InitialDelay() OVERRIDE; |
typedef std::pair<CrxComponent*, int> CheckAtLoopCount; |
- virtual int NextCheckDelay() OVERRIDE { |
- // This is called when a new full cycle of checking for updates is going |
- // to happen. In test we normally only test one cycle so it is a good |
- // time to break from the test messageloop Run() method so the test can |
- // finish. |
- if (--times_ <= 0) { |
- base::MessageLoop::current()->Quit(); |
- return 0; |
+ virtual int NextCheckDelay() OVERRIDE; |
- } |
+ virtual int StepDelay() OVERRIDE; |
- // Look for checks to issue in the middle of the loop. |
- for (std::list<CheckAtLoopCount>::iterator |
- i = components_to_check_.begin(); |
- i != components_to_check_.end(); ) { |
- if (i->second == times_) { |
- cus_->CheckForUpdateSoon(*i->first); |
- i = components_to_check_.erase(i); |
- } else { |
- ++i; |
- } |
- } |
- return 1; |
- } |
+ virtual int MinimumReCheckWait() OVERRIDE; |
- virtual int StepDelay() OVERRIDE { |
- return 0; |
- } |
+ virtual int OnDemandDelay() OVERRIDE; |
- virtual int MinimumReCheckWait() OVERRIDE { |
- return recheck_time_; |
- } |
+ virtual GURL UpdateUrl(CrxComponent::UrlSource source) OVERRIDE; |
- virtual int OnDemandDelay() OVERRIDE { |
- return ondemand_time_; |
- } |
+ virtual GURL PingUrl() OVERRIDE; |
- virtual GURL UpdateUrl(CrxComponent::UrlSource source) OVERRIDE { |
- switch (source) { |
- case CrxComponent::BANDAID: |
- return GURL("http://localhost/upd"); |
- case CrxComponent::CWS_PUBLIC: |
- return GURL("http://localhost/cws"); |
- default: |
- return GURL("http://wronghost/bad"); |
- }; |
- } |
+ virtual const char* ExtraRequestParams() OVERRIDE; |
- virtual const char* ExtraRequestParams() OVERRIDE { return "extra=foo"; } |
+ virtual size_t UrlSizeLimit() OVERRIDE; |
- virtual size_t UrlSizeLimit() OVERRIDE { return 256; } |
- |
- virtual net::URLRequestContextGetter* RequestContext() OVERRIDE { |
- return new net::TestURLRequestContextGetter( |
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); |
- } |
+ virtual net::URLRequestContextGetter* RequestContext() OVERRIDE; |
// Don't use the utility process to decode files. |
- virtual bool InProcess() OVERRIDE { return true; } |
+ virtual bool InProcess() OVERRIDE; |
- virtual void OnEvent(Events event, int extra) OVERRIDE { } |
+ virtual void OnEvent(Events event, int extra) OVERRIDE; |
- // Set how many update checks are called, the default value is just once. |
- void SetLoopCount(int times) { times_ = times; } |
+ virtual ComponentPatcher* CreateComponentPatcher() OVERRIDE; |
- void SetRecheckTime(int seconds) { |
- recheck_time_ = seconds; |
- } |
+ virtual bool PingsEnabled() const OVERRIDE; |
- void SetOnDemandTime(int seconds) { |
- ondemand_time_ = seconds; |
- } |
+ virtual bool DeltasEnabled() const OVERRIDE; |
- void AddComponentToCheck(CrxComponent* com, int at_loop_iter) { |
- components_to_check_.push_back(std::make_pair(com, at_loop_iter)); |
- } |
+ void SetLoopCount(int times); |
- void SetComponentUpdateService(ComponentUpdateService* cus) { |
- cus_ = cus; |
- } |
+ void SetRecheckTime(int seconds); |
+ |
+ void SetOnDemandTime(int seconds); |
+ |
+ void AddComponentToCheck(CrxComponent* com, int at_loop_iter); |
+ |
+ void SetComponentUpdateService(ComponentUpdateService* cus); |
private: |
int times_; |
@@ -133,132 +114,387 @@ class TestConfigurator : public ComponentUpdateService::Configurator { |
ComponentUpdateService* cus_; |
}; |
-class TestInstaller : public ComponentInstaller { |
- public : |
- explicit TestInstaller() |
- : error_(0), install_count_(0) { |
- } |
+class ComponentUpdaterTest : public testing::Test { |
+ public: |
+ enum TestComponents { |
+ kTestComponent_abag, |
+ kTestComponent_jebg, |
+ kTestComponent_ihfo, |
+ }; |
- virtual void OnUpdateError(int error) OVERRIDE { |
- EXPECT_NE(0, error); |
- error_ = error; |
- } |
+ ComponentUpdaterTest(); |
- virtual bool Install(const base::DictionaryValue& manifest, |
- const base::FilePath& unpack_path) OVERRIDE { |
- ++install_count_; |
- return file_util::Delete(unpack_path, true); |
- } |
+ virtual ~ComponentUpdaterTest(); |
+ |
+ virtual void TearDown(); |
+ |
+ ComponentUpdateService* component_updater(); |
- int error() const { return error_; } |
+ // Makes the full path to a component updater test file. |
+ const base::FilePath test_file(const char* file); |
+ |
+ TestNotificationTracker& notification_tracker(); |
+ |
+ TestConfigurator* test_configurator(); |
- int install_count() const { return install_count_; } |
+ ComponentUpdateService::Status RegisterComponent(CrxComponent* com, |
+ TestComponents component, |
+ const Version& version, |
+ TestInstaller* installer); |
private: |
- int error_; |
- int install_count_; |
+ scoped_ptr<ComponentUpdateService> component_updater_; |
+ base::FilePath test_data_dir_; |
+ TestNotificationTracker notification_tracker_; |
+ TestConfigurator* test_config_; |
}; |
-// component 1 has extension id "jebgalgnebhfojomionfpkfelancnnkf", and |
-// the RSA public key the following hash: |
-const uint8 jebg_hash[] = {0x94,0x16,0x0b,0x6d,0x41,0x75,0xe9,0xec,0x8e,0xd5, |
- 0xfa,0x54,0xb0,0xd2,0xdd,0xa5,0x6e,0x05,0x6b,0xe8, |
- 0x73,0x47,0xf6,0xc4,0x11,0x9f,0xbc,0xb3,0x09,0xb3, |
- 0x5b,0x40}; |
-// component 2 has extension id "abagagagagagagagagagagagagagagag", and |
-// the RSA public key the following hash: |
-const uint8 abag_hash[] = {0x01,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06, |
- 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06, |
- 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06, |
- 0x06,0x01}; |
- |
const char expected_crx_url[] = |
"http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx"; |
-} // namespace |
- |
-// Common fixture for all the component updater tests. |
-class ComponentUpdaterTest : public testing::Test { |
+class PingChecker { |
public: |
- enum TestComponents { |
- kTestComponent_abag, |
- kTestComponent_jebg |
- }; |
+ explicit PingChecker(const std::map<std::string, std::string>& attributes); |
- ComponentUpdaterTest() : test_config_(NULL) { |
- // The component updater instance under test. |
- test_config_ = new TestConfigurator; |
- component_updater_.reset(ComponentUpdateServiceFactory(test_config_)); |
- test_config_->SetComponentUpdateService(component_updater_.get()); |
- // The test directory is chrome/test/data/components. |
- PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); |
- test_data_dir_ = test_data_dir_.AppendASCII("components"); |
- |
- // Subscribe to all component updater notifications. |
- const int notifications[] = { |
- chrome::NOTIFICATION_COMPONENT_UPDATER_STARTED, |
- chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING, |
- chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, |
- chrome::NOTIFICATION_COMPONENT_UPDATE_READY |
- }; |
- |
- for (int ix = 0; ix != arraysize(notifications); ++ix) { |
- notification_tracker_.ListenFor( |
- notifications[ix], content::NotificationService::AllSources()); |
- } |
- net::URLFetcher::SetEnableInterceptionForTests(true); |
- } |
+ virtual ~PingChecker(); |
- virtual ~ComponentUpdaterTest() { |
- net::URLFetcher::SetEnableInterceptionForTests(false); |
- } |
+ void Trial(net::URLRequest* request); |
- virtual void TearDown() { |
- xmlCleanupGlobals(); |
+ int NumHits() const { |
+ return num_hits_; |
} |
- |
- ComponentUpdateService* component_updater() { |
- return component_updater_.get(); |
+ int NumMisses() const { |
+ return num_misses_; |
} |
- // Makes the full path to a component updater test file. |
- const base::FilePath test_file(const char* file) { |
- return test_data_dir_.AppendASCII(file); |
+ private: |
+ int num_hits_; |
+ int num_misses_; |
+ const std::map<std::string, std::string> attributes_; |
+ virtual bool Test(net::URLRequest* request); |
+}; |
+ |
+PingChecker::PingChecker(const std::map<std::string, std::string>& attributes) |
+ : num_hits_(0), num_misses_(0), attributes_(attributes) { |
+} |
+ |
+PingChecker::~PingChecker() {} |
+ |
+void PingChecker::Trial(net::URLRequest* request) { |
+ if (Test(request)) |
+ ++num_hits_; |
+ else |
+ ++num_misses_; |
+} |
+ |
+bool PingChecker::Test(net::URLRequest* request) { |
+ if (request->has_upload()) { |
+ const net::UploadDataStream* stream = request->get_upload(); |
+ const net::UploadBytesElementReader* reader = |
+ stream->element_readers()[0]->AsBytesReader(); |
+ int size = reader->length(); |
+ scoped_refptr <net::IOBuffer> buffer = new net::IOBuffer(size); |
+ std::string data(reader->bytes()); |
+ // For now, we assume that there is only one ping per POST. |
+ std::string::size_type start = data.find("<o:event"); |
+ if (start != std::string::npos) { |
+ std::string::size_type end = data.find(">", start); |
+ if (end != std::string::npos) { |
+ std::string ping = data.substr(start, end - start); |
+ std::map<std::string, std::string>::const_iterator iter; |
+ for (iter = attributes_.begin(); iter != attributes_.end(); ++iter) { |
+ // does the ping contain the specified attribute/value? |
+ if (ping.find(std::string(" ") + (iter->first) + |
+ std::string("=") + (iter->second)) == string::npos) { |
+ return false; |
+ } |
+ } |
+ return true; |
+ } |
+ } |
} |
+ return false; |
+} |
+ |
+class URLRequestPostInterceptor { |
+ public: |
+ explicit URLRequestPostInterceptor(PingChecker* counter); |
+ virtual ~URLRequestPostInterceptor(); |
+ |
+ private: |
+ class Delegate; |
+ |
+ // After creation, |delegate_| lives on the IO thread, and a task to delete it |
+ // is posted from ~URLRequestPostInterceptor(). |
+ Delegate* delegate_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(URLRequestPostInterceptor); |
+}; |
+ |
+class URLRequestPostInterceptor::Delegate |
+ : public net::URLRequestJobFactory::ProtocolHandler { |
+ public: |
+ explicit Delegate(PingChecker* counter); |
+ virtual ~Delegate() {} |
+ |
+ void Register(); |
+ |
+ void Unregister(); |
+ |
+ private: |
+ PingChecker* counter_; |
- TestNotificationTracker& notification_tracker() { |
- return notification_tracker_; |
+ virtual net::URLRequestJob* MaybeCreateJob( |
+ net::URLRequest* request, |
+ net::NetworkDelegate* network_delegate) const OVERRIDE; |
+}; |
+ |
+class URLRequestPingMockJob : public net::URLRequestSimpleJob { |
+ public: |
+ URLRequestPingMockJob(net::URLRequest* request, |
+ net::NetworkDelegate* network_delegate); |
+ |
+ protected: |
+ virtual int GetData(std::string* mime_type, |
+ std::string* charset, |
+ std::string* data, |
+ const net::CompletionCallback& callback) const OVERRIDE; |
+ |
+ private: |
+ virtual ~URLRequestPingMockJob() {} |
+ |
+ DISALLOW_COPY_AND_ASSIGN(URLRequestPingMockJob); |
+}; |
+ |
+URLRequestPostInterceptor::URLRequestPostInterceptor( |
+ PingChecker* counter) : delegate_(new Delegate(counter)) { |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&Delegate::Register, |
+ base::Unretained(delegate_))); |
+} |
+ |
+URLRequestPostInterceptor::~URLRequestPostInterceptor() { |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&Delegate::Unregister, |
+ base::Unretained(delegate_))); |
+} |
+ |
+URLRequestPostInterceptor::Delegate::Delegate( |
+ PingChecker* counter) : counter_(counter) { |
+} |
+ |
+void URLRequestPostInterceptor::Delegate::Register() { |
+ net::URLRequestFilter::GetInstance()->AddHostnameProtocolHandler( |
+ "http", "localhost2", |
+ scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(this)); |
+} |
+ |
+void URLRequestPostInterceptor::Delegate::Unregister() { |
+ net::URLRequestFilter::GetInstance()-> |
+ RemoveHostnameHandler("http", "localhost2"); |
+} |
+ |
+net::URLRequestJob* URLRequestPostInterceptor::Delegate::MaybeCreateJob( |
+ net::URLRequest* request, |
+ net::NetworkDelegate* network_delegate) const { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ if (request->has_upload()) { |
+ counter_->Trial(request); |
+ return new URLRequestPingMockJob(request, network_delegate); |
} |
+ return NULL; |
+} |
+ |
+URLRequestPingMockJob::URLRequestPingMockJob( |
+ net::URLRequest* request, |
+ net::NetworkDelegate* network_delegate) |
+ : net::URLRequestSimpleJob(request, network_delegate) { |
+} |
+ |
+int URLRequestPingMockJob::GetData( |
+ std::string* mime_type, |
+ std::string* charset, |
+ std::string* data, |
+ const net::CompletionCallback& callback) const { |
+ mime_type->assign("text/plain"); |
+ charset->assign("US-ASCII"); |
+ data->assign(""); // There is no reason to have a response body in this test. |
+ return net::OK; |
+} |
+ |
+} // namespace |
+ |
+TestConfigurator::TestConfigurator() |
+ : times_(1), recheck_time_(0), ondemand_time_(0), cus_(NULL) { |
+} |
+ |
+int TestConfigurator::InitialDelay() { return 0; } |
- TestConfigurator* test_configurator() { |
- return test_config_; |
+int TestConfigurator::NextCheckDelay() { |
+ // This is called when a new full cycle of checking for updates is going |
+ // to happen. In test we normally only test one cycle so it is a good |
+ // time to break from the test messageloop Run() method so the test can |
+ // finish. |
+ if (--times_ <= 0) { |
+ base::MessageLoop::current()->Quit(); |
+ return 0; |
} |
- ComponentUpdateService::Status RegisterComponent(CrxComponent* com, |
- TestComponents component, |
- const Version& version) { |
- if (component == kTestComponent_abag) { |
- com->name = "test_abag"; |
- com->pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash)); |
+ // Look for checks to issue in the middle of the loop. |
+ for (std::list<CheckAtLoopCount>::iterator |
+ i = components_to_check_.begin(); |
+ i != components_to_check_.end(); ) { |
+ if (i->second == times_) { |
+ cus_->CheckForUpdateSoon(*i->first); |
+ i = components_to_check_.erase(i); |
} else { |
- com->name = "test_jebg"; |
- com->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash)); |
+ ++i; |
} |
- com->version = version; |
- TestInstaller* installer = new TestInstaller; |
- com->installer = installer; |
- test_installers_.push_back(installer); |
- return component_updater_->RegisterComponent(*com); |
} |
+ return 1; |
+} |
- private: |
- scoped_ptr<ComponentUpdateService> component_updater_; |
- base::FilePath test_data_dir_; |
- TestNotificationTracker notification_tracker_; |
- TestConfigurator* test_config_; |
- // ComponentInstaller objects to delete after each test. |
- ScopedVector<TestInstaller> test_installers_; |
-}; |
+int TestConfigurator::StepDelay() { |
+ return 0; |
+} |
+ |
+int TestConfigurator::MinimumReCheckWait() { |
+ return recheck_time_; |
+} |
+ |
+int TestConfigurator::OnDemandDelay() { |
+ return ondemand_time_; |
+} |
+ |
+GURL TestConfigurator::UpdateUrl(CrxComponent::UrlSource source) { |
+ switch (source) { |
+ case CrxComponent::BANDAID: |
+ return GURL("http://localhost/upd"); |
+ case CrxComponent::CWS_PUBLIC: |
+ return GURL("http://localhost/cws"); |
+ default: |
+ return GURL("http://wronghost/bad"); |
+ }; |
+} |
+ |
+GURL TestConfigurator::PingUrl() { |
+ return GURL("http://localhost2/ping"); |
+} |
+ |
+const char* TestConfigurator::ExtraRequestParams() { return "extra=foo"; } |
+ |
+size_t TestConfigurator::UrlSizeLimit() { return 256; } |
+ |
+net::URLRequestContextGetter* TestConfigurator::RequestContext() { |
+ return new net::TestURLRequestContextGetter( |
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); |
+} |
+ |
+// Don't use the utility process to decode files. |
+bool TestConfigurator::InProcess() { return true; } |
+ |
+void TestConfigurator::OnEvent(Events event, int extra) { } |
+ |
+ComponentPatcher* TestConfigurator::CreateComponentPatcher() { |
+ return new MockComponentPatcher(); |
+} |
+ |
+bool TestConfigurator::PingsEnabled() const { |
+ return true; |
+} |
+ |
+bool TestConfigurator::DeltasEnabled() const { |
+ return true; |
+} |
+ |
+// Set how many update checks are called, the default value is just once. |
+void TestConfigurator::SetLoopCount(int times) { times_ = times; } |
+ |
+void TestConfigurator::SetRecheckTime(int seconds) { |
+ recheck_time_ = seconds; |
+} |
+ |
+void TestConfigurator::SetOnDemandTime(int seconds) { |
+ ondemand_time_ = seconds; |
+} |
+ |
+void TestConfigurator::AddComponentToCheck(CrxComponent* com, |
+ int at_loop_iter) { |
+ components_to_check_.push_back(std::make_pair(com, at_loop_iter)); |
+} |
+ |
+void TestConfigurator::SetComponentUpdateService(ComponentUpdateService* cus) { |
+ cus_ = cus; |
+} |
+ |
+ComponentUpdaterTest::ComponentUpdaterTest() : test_config_(NULL) { |
+ // The component updater instance under test. |
+ test_config_ = new TestConfigurator; |
+ component_updater_.reset(ComponentUpdateServiceFactory(test_config_)); |
+ test_config_->SetComponentUpdateService(component_updater_.get()); |
+ // The test directory is chrome/test/data/components. |
+ PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); |
+ test_data_dir_ = test_data_dir_.AppendASCII("components"); |
+ |
+ // Subscribe to all component updater notifications. |
+ const int notifications[] = { |
+ chrome::NOTIFICATION_COMPONENT_UPDATER_STARTED, |
+ chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING, |
+ chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, |
+ chrome::NOTIFICATION_COMPONENT_UPDATE_READY |
+ }; |
+ |
+ for (int ix = 0; ix != arraysize(notifications); ++ix) { |
+ notification_tracker_.ListenFor( |
+ notifications[ix], content::NotificationService::AllSources()); |
+ } |
+ net::URLFetcher::SetEnableInterceptionForTests(true); |
+} |
+ |
+ComponentUpdaterTest::~ComponentUpdaterTest() { |
+ net::URLFetcher::SetEnableInterceptionForTests(false); |
+} |
+ |
+void ComponentUpdaterTest::TearDown() { |
+ xmlCleanupGlobals(); |
+} |
+ |
+ComponentUpdateService* ComponentUpdaterTest::component_updater() { |
+ return component_updater_.get(); |
+} |
+ |
+ // Makes the full path to a component updater test file. |
+const base::FilePath ComponentUpdaterTest::test_file(const char* file) { |
+ return test_data_dir_.AppendASCII(file); |
+} |
+ |
+TestNotificationTracker& ComponentUpdaterTest::notification_tracker() { |
+ return notification_tracker_; |
+} |
+ |
+TestConfigurator* ComponentUpdaterTest::test_configurator() { |
+ return test_config_; |
+} |
+ |
+ComponentUpdateService::Status ComponentUpdaterTest::RegisterComponent( |
+ CrxComponent* com, |
+ TestComponents component, |
+ const Version& version, |
+ TestInstaller* installer) { |
+ if (component == kTestComponent_abag) { |
+ com->name = "test_abag"; |
+ com->pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash)); |
+ } else if (component == kTestComponent_jebg) { |
+ com->name = "test_jebg"; |
+ com->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash)); |
+ } else { |
+ com->name = "test_ihfo"; |
+ com->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash)); |
+ } |
+ com->version = version; |
+ com->installer = installer; |
+ return component_updater_->RegisterComponent(*com); |
+} |
// Verify that our test fixture work and the component updater can |
// be created and destroyed with no side effects. |
@@ -295,13 +531,17 @@ TEST_F(ComponentUpdaterTest, CheckCrxSleep) { |
content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ TestInstaller installer; |
CrxComponent com; |
EXPECT_EQ(ComponentUpdateService::kOk, |
- RegisterComponent(&com, kTestComponent_abag, Version("1.1"))); |
+ RegisterComponent(&com, |
+ kTestComponent_abag, |
+ Version("1.1"), |
+ &installer)); |
const GURL expected_update_url( |
- "http://localhost/upd?extra=foo&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D1.1%26uc"); |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D1.1%26fp%3D%26uc"); |
interceptor.SetResponse(expected_update_url, |
test_file("updatecheck_reply_1.xml")); |
@@ -359,7 +599,7 @@ TEST_F(ComponentUpdaterTest, CheckCrxSleep) { |
// the notifications above NOTIFICATION_COMPONENT_UPDATE_FOUND and |
// NOTIFICATION_COMPONENT_UPDATE_READY should have been fired. We do two loops |
// so the second time around there should be nothing left to do. |
-// We also check that only 3 network requests are issued: |
+// We also check that only 3 non-ping network requests are issued: |
// 1- manifest check |
// 2- download crx |
// 3- second manifest check. |
@@ -372,22 +612,32 @@ TEST_F(ComponentUpdaterTest, InstallCrx) { |
io_thread.StartIOThread(); |
file_thread.Start(); |
+ std::map<std::string, std::string> map; |
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\"")); |
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\"")); |
+ map.insert(std::pair<std::string, std::string>("previousversion", |
+ "\"0.9\"")); |
+ map.insert(std::pair<std::string, std::string>("nextversion", "\"1.0\"")); |
+ PingChecker ping_checker(map); |
+ URLRequestPostInterceptor post_interceptor(&ping_checker); |
content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ TestInstaller installer1; |
CrxComponent com1; |
- RegisterComponent(&com1, kTestComponent_jebg, Version("0.9")); |
+ RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1); |
+ TestInstaller installer2; |
CrxComponent com2; |
- RegisterComponent(&com2, kTestComponent_abag, Version("2.2")); |
+ RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2); |
const GURL expected_update_url_1( |
- "http://localhost/upd?extra=foo&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26uc&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D2.2%26uc"); |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26fp%3D%26uc" |
+ "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc"); |
const GURL expected_update_url_2( |
- "http://localhost/upd?extra=foo&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D2.2%26uc&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D1.0%26uc"); |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc" |
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D1.0%26fp%3D%26uc"); |
interceptor.SetResponse(expected_update_url_1, |
test_file("updatecheck_reply_1.xml")); |
@@ -407,6 +657,8 @@ TEST_F(ComponentUpdaterTest, InstallCrx) { |
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); |
EXPECT_EQ(3, interceptor.GetHitCount()); |
+ EXPECT_EQ(1, ping_checker.NumHits()); |
+ EXPECT_EQ(0, ping_checker.NumMisses()); |
ASSERT_EQ(5ul, notification_tracker().size()); |
@@ -437,21 +689,31 @@ TEST_F(ComponentUpdaterTest, InstallCrxTwoSources) { |
io_thread.StartIOThread(); |
file_thread.Start(); |
+ std::map<std::string, std::string> map; |
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\"")); |
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\"")); |
+ map.insert(std::pair<std::string, std::string>("previousversion", |
+ "\"0.9\"")); |
+ map.insert(std::pair<std::string, std::string>("nextversion", "\"1.0\"")); |
+ PingChecker ping_checker(map); |
+ URLRequestPostInterceptor post_interceptor(&ping_checker); |
content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ TestInstaller installer1; |
CrxComponent com1; |
- RegisterComponent(&com1, kTestComponent_abag, Version("2.2")); |
+ RegisterComponent(&com1, kTestComponent_abag, Version("2.2"), &installer1); |
+ TestInstaller installer2; |
CrxComponent com2; |
com2.source = CrxComponent::CWS_PUBLIC; |
- RegisterComponent(&com2, kTestComponent_jebg, Version("0.9")); |
+ RegisterComponent(&com2, kTestComponent_jebg, Version("0.9"), &installer2); |
const GURL expected_update_url_1( |
"http://localhost/upd?extra=foo&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D2.2%26uc"); |
+ "abagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc"); |
const GURL expected_update_url_2( |
"http://localhost/cws?extra=foo&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26uc"); |
+ "jebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26fp%3D%26uc"); |
interceptor.SetResponse(expected_update_url_1, |
test_file("updatecheck_reply_3.xml")); |
@@ -475,6 +737,8 @@ TEST_F(ComponentUpdaterTest, InstallCrxTwoSources) { |
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); |
EXPECT_EQ(1, static_cast<TestInstaller*>(com2.installer)->install_count()); |
+ EXPECT_EQ(1, ping_checker.NumHits()); |
+ EXPECT_EQ(0, ping_checker.NumMisses()); |
EXPECT_EQ(3, interceptor.GetHitCount()); |
ASSERT_EQ(6ul, notification_tracker().size()); |
@@ -509,14 +773,18 @@ TEST_F(ComponentUpdaterTest, ProdVersionCheck) { |
io_thread.StartIOThread(); |
file_thread.Start(); |
+ std::map<std::string, std::string> map; |
+ PingChecker ping_checker(map); |
+ URLRequestPostInterceptor post_interceptor(&ping_checker); |
content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ TestInstaller installer; |
CrxComponent com; |
- RegisterComponent(&com, kTestComponent_jebg, Version("0.9")); |
+ RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); |
const GURL expected_update_url( |
"http://localhost/upd?extra=foo&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26uc"); |
+ "jebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26fp%3D%26uc"); |
interceptor.SetResponse(expected_update_url, |
test_file("updatecheck_reply_2.xml")); |
@@ -527,6 +795,8 @@ TEST_F(ComponentUpdaterTest, ProdVersionCheck) { |
component_updater()->Start(); |
message_loop.Run(); |
+ EXPECT_EQ(0, ping_checker.NumHits()); |
+ EXPECT_EQ(0, ping_checker.NumMisses()); |
EXPECT_EQ(1, interceptor.GetHitCount()); |
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); |
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); |
@@ -549,22 +819,32 @@ TEST_F(ComponentUpdaterTest, CheckForUpdateSoon) { |
io_thread.StartIOThread(); |
file_thread.Start(); |
+ std::map<std::string, std::string> map; |
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\"")); |
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\"")); |
+ map.insert(std::pair<std::string, std::string>("previousversion", |
+ "\"0.9\"")); |
+ map.insert(std::pair<std::string, std::string>("nextversion", "\"1.0\"")); |
+ PingChecker ping_checker(map); |
+ URLRequestPostInterceptor post_interceptor(&ping_checker); |
content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ TestInstaller installer1; |
CrxComponent com1; |
- RegisterComponent(&com1, kTestComponent_abag, Version("2.2")); |
+ RegisterComponent(&com1, kTestComponent_abag, Version("2.2"), &installer1); |
+ TestInstaller installer2; |
CrxComponent com2; |
- RegisterComponent(&com2, kTestComponent_jebg, Version("0.9")); |
+ RegisterComponent(&com2, kTestComponent_jebg, Version("0.9"), &installer2); |
const GURL expected_update_url_1( |
- "http://localhost/upd?extra=foo&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D2.2%26uc&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26uc"); |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc" |
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26fp%3D%26uc"); |
const GURL expected_update_url_2( |
- "http://localhost/upd?extra=foo&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26uc&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D2.2%26uc"); |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26fp%3D%26uc" |
+ "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc"); |
interceptor.SetResponse(expected_update_url_1, |
test_file("updatecheck_reply_empty")); |
@@ -613,9 +893,9 @@ TEST_F(ComponentUpdaterTest, CheckForUpdateSoon) { |
// Test a few error cases. NOTE: We don't have callbacks for |
// when the updates failed yet. |
const GURL expected_update_url_3( |
- "http://localhost/upd?extra=foo&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D1.0%26uc&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D2.2%26uc"); |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D1.0%26fp%3D%26uc" |
+ "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc"); |
// No update: error from no server response |
interceptor.SetResponse(expected_update_url_3, |
@@ -646,6 +926,8 @@ TEST_F(ComponentUpdaterTest, CheckForUpdateSoon) { |
message_loop.Run(); |
+ EXPECT_EQ(1, ping_checker.NumHits()); |
+ EXPECT_EQ(0, ping_checker.NumMisses()); |
ASSERT_EQ(2ul, notification_tracker().size()); |
ev0 = notification_tracker().at(0); |
EXPECT_EQ(chrome::NOTIFICATION_COMPONENT_UPDATER_STARTED, ev0.type); |
@@ -665,23 +947,33 @@ TEST_F(ComponentUpdaterTest, CheckReRegistration) { |
io_thread.StartIOThread(); |
file_thread.Start(); |
+ std::map<std::string, std::string> map; |
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\"")); |
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\"")); |
+ map.insert(std::pair<std::string, std::string>("previousversion", |
+ "\"0.9\"")); |
+ map.insert(std::pair<std::string, std::string>("nextversion", "\"1.0\"")); |
+ PingChecker ping_checker(map); |
+ URLRequestPostInterceptor post_interceptor(&ping_checker); |
content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ TestInstaller installer1; |
CrxComponent com1; |
- RegisterComponent(&com1, kTestComponent_jebg, Version("0.9")); |
+ RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1); |
+ TestInstaller installer2; |
CrxComponent com2; |
- RegisterComponent(&com2, kTestComponent_abag, Version("2.2")); |
+ RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2); |
// Start with 0.9, and update to 1.0 |
const GURL expected_update_url_1( |
- "http://localhost/upd?extra=foo&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26uc&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D2.2%26uc"); |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26fp%3D%26uc" |
+ "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc"); |
const GURL expected_update_url_2( |
- "http://localhost/upd?extra=foo&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D2.2%26uc&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D1.0%26uc"); |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc" |
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D1.0%26fp%3D%26uc"); |
interceptor.SetResponse(expected_update_url_1, |
test_file("updatecheck_reply_1.xml")); |
@@ -702,6 +994,8 @@ TEST_F(ComponentUpdaterTest, CheckReRegistration) { |
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); |
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); |
+ EXPECT_EQ(1, ping_checker.NumHits()); |
+ EXPECT_EQ(0, ping_checker.NumMisses()); |
EXPECT_EQ(3, interceptor.GetHitCount()); |
ASSERT_EQ(5ul, notification_tracker().size()); |
@@ -722,16 +1016,20 @@ TEST_F(ComponentUpdaterTest, CheckReRegistration) { |
EXPECT_EQ(chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING, ev4.type); |
// Now re-register, pretending to be an even newer version (2.2) |
+ TestInstaller installer3; |
component_updater()->Stop(); |
EXPECT_EQ(ComponentUpdateService::kReplaced, |
- RegisterComponent(&com1, kTestComponent_jebg, Version("2.2"))); |
+ RegisterComponent(&com1, |
+ kTestComponent_jebg, |
+ Version("2.2"), |
+ &installer3)); |
// Check that we send out 2.2 as our version. |
// Interceptor's hit count should go up by 1. |
const GURL expected_update_url_3( |
- "http://localhost/upd?extra=foo&x=id%3D" |
- "jebgalgnebhfojomionfpkfelancnnkf%26v%3D2.2%26uc&x=id%3D" |
- "abagagagagagagagagagagagagagagag%26v%3D2.2%26uc"); |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D2.2%26fp%3D%26uc" |
+ "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc"); |
interceptor.SetResponse(expected_update_url_3, |
test_file("updatecheck_reply_1.xml")); |
@@ -753,8 +1051,7 @@ TEST_F(ComponentUpdaterTest, CheckReRegistration) { |
EXPECT_EQ(4, interceptor.GetHitCount()); |
- // The test harness's Register() function creates a new installer, |
- // so the counts go back to 0. |
+ // We created a new installer, so the counts go back to 0. |
EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); |
EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count()); |
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); |
@@ -762,3 +1059,289 @@ TEST_F(ComponentUpdaterTest, CheckReRegistration) { |
component_updater()->Stop(); |
} |
+ |
+// Verify that we can download and install a component and a differential |
+// update to that component. We do three loops; the final loop should do |
+// nothing. |
+// We also check that exactly 5 non-ping network requests are issued: |
+// 1- update check (response: v1 available) |
+// 2- download crx (v1) |
+// 3- update check (response: v2 available) |
+// 4- download differential crx (v1 to v2) |
+// 5- update check (response: no further update available) |
+// There should be two pings, one for each update. The second will bear a |
+// diffresult=1, while the first will not. |
+TEST_F(ComponentUpdaterTest, DifferentialUpdate) { |
+ base::MessageLoop message_loop; |
+ content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop); |
+ content::TestBrowserThread file_thread(BrowserThread::FILE); |
+ content::TestBrowserThread io_thread(BrowserThread::IO); |
+ |
+ io_thread.StartIOThread(); |
+ file_thread.Start(); |
+ |
+ std::map<std::string, std::string> map; |
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\"")); |
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\"")); |
+ map.insert(std::pair<std::string, std::string>("diffresult", "\"1\"")); |
+ PingChecker ping_checker(map); |
+ URLRequestPostInterceptor post_interceptor(&ping_checker); |
+ content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ |
+ VersionedTestInstaller installer; |
+ CrxComponent com; |
+ RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); |
+ |
+ const GURL expected_update_url_0( |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D0.0%26fp%3D%26uc"); |
+ const GURL expected_update_url_1( |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D1.0%26fp%3D1%26uc"); |
+ const GURL expected_update_url_2( |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D2.0%26fp%3Df22%26uc"); |
+ const GURL expected_crx_url_1( |
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"); |
+ const GURL expected_crx_url_1_diff_2( |
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"); |
+ |
+ interceptor.SetResponse(expected_update_url_0, |
+ test_file("updatecheck_diff_reply_1.xml")); |
+ interceptor.SetResponse(expected_update_url_1, |
+ test_file("updatecheck_diff_reply_2.xml")); |
+ interceptor.SetResponse(expected_update_url_2, |
+ test_file("updatecheck_diff_reply_3.xml")); |
+ interceptor.SetResponse(expected_crx_url_1, |
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); |
+ interceptor.SetResponse( |
+ expected_crx_url_1_diff_2, |
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); |
+ |
+ test_configurator()->SetLoopCount(3); |
+ |
+ component_updater()->Start(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); |
+ EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); |
+ |
+ EXPECT_EQ(1, ping_checker.NumHits()); |
+ EXPECT_EQ(1, ping_checker.NumMisses()); |
+ EXPECT_EQ(5, interceptor.GetHitCount()); |
+ |
+ component_updater()->Stop(); |
+} |
+ |
+// Verify that component installation falls back to downloading and installing |
+// a full update if the differential update fails (in this case, because the |
+// installer does not know about the existing files). We do two loops; the final |
+// loop should do nothing. |
+// We also check that exactly 4 non-ping network requests are issued: |
+// 1- update check (loop 1) |
+// 2- download differential crx |
+// 3- download full crx |
+// 4- update check (loop 2 - no update available) |
+// There should be one ping for the first attempted update. |
+TEST_F(ComponentUpdaterTest, DifferentialUpdateFails) { |
+ base::MessageLoop message_loop; |
+ content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop); |
+ content::TestBrowserThread file_thread(BrowserThread::FILE); |
+ content::TestBrowserThread io_thread(BrowserThread::IO); |
+ |
+ io_thread.StartIOThread(); |
+ file_thread.Start(); |
+ |
+ std::map<std::string, std::string> map; |
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\"")); |
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\"")); |
+ map.insert(std::pair<std::string, std::string>("diffresult", "\"0\"")); |
+ map.insert(std::pair<std::string, std::string>("differrorcode", "\"16\"")); |
+ PingChecker ping_checker(map); |
+ URLRequestPostInterceptor post_interceptor(&ping_checker); |
+ content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ |
+ TestInstaller installer; |
+ CrxComponent com; |
+ RegisterComponent(&com, kTestComponent_ihfo, Version("1.0"), &installer); |
+ |
+ const GURL expected_update_url_1( |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D1.0%26fp%3D%26uc"); |
+ const GURL expected_update_url_2( |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D2.0%26fp%3Df22%26uc"); |
+ const GURL expected_crx_url_1( |
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"); |
+ const GURL expected_crx_url_1_diff_2( |
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"); |
+ const GURL expected_crx_url_2( |
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"); |
+ |
+ interceptor.SetResponse(expected_update_url_1, |
+ test_file("updatecheck_diff_reply_2.xml")); |
+ interceptor.SetResponse(expected_update_url_2, |
+ test_file("updatecheck_diff_reply_3.xml")); |
+ interceptor.SetResponse(expected_crx_url_1, |
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); |
+ interceptor.SetResponse( |
+ expected_crx_url_1_diff_2, |
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); |
+ interceptor.SetResponse(expected_crx_url_2, |
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); |
+ |
+ test_configurator()->SetLoopCount(2); |
+ |
+ component_updater()->Start(); |
+ message_loop.Run(); |
+ |
+ // A failed differential update does not count as a failed install. |
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); |
+ EXPECT_EQ(1, static_cast<TestInstaller*>(com.installer)->install_count()); |
+ |
+ EXPECT_EQ(1, ping_checker.NumHits()); |
+ EXPECT_EQ(0, ping_checker.NumMisses()); |
+ EXPECT_EQ(4, interceptor.GetHitCount()); |
+ |
+ component_updater()->Stop(); |
+} |
+ |
+// Verify that a failed installation causes an install failure ping. |
+TEST_F(ComponentUpdaterTest, CheckFailedInstallPing) { |
+ base::MessageLoop message_loop; |
+ content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop); |
+ content::TestBrowserThread file_thread(BrowserThread::FILE); |
+ content::TestBrowserThread io_thread(BrowserThread::IO); |
+ |
+ io_thread.StartIOThread(); |
+ file_thread.Start(); |
+ |
+ std::map<std::string, std::string> map; |
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\"")); |
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"0\"")); |
+ map.insert(std::pair<std::string, std::string>("errorcode", "\"9\"")); |
+ map.insert(std::pair<std::string, std::string>("previousversion", |
+ "\"0.9\"")); |
+ map.insert(std::pair<std::string, std::string>("nextversion", "\"1.0\"")); |
+ PingChecker ping_checker(map); |
+ URLRequestPostInterceptor post_interceptor(&ping_checker); |
+ content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ |
+ // This test installer reports installation failure. |
+ class : public TestInstaller { |
+ virtual bool Install(const base::DictionaryValue& manifest, |
+ const base::FilePath& unpack_path) OVERRIDE { |
+ ++install_count_; |
+ file_util::Delete(unpack_path, true); |
+ return false; |
+ } |
+ } installer; |
+ |
+ CrxComponent com; |
+ RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); |
+ |
+ // Start with 0.9, and attempt update to 1.0 |
+ const GURL expected_update_url_1( |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26fp%3D%26uc"); |
+ |
+ interceptor.SetResponse(expected_update_url_1, |
+ test_file("updatecheck_reply_1.xml")); |
+ interceptor.SetResponse(GURL(expected_crx_url), |
+ test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); |
+ |
+ // Loop twice to issue two checks: (1) with original 0.9 version |
+ // and (2), which should retry with 0.9. |
+ test_configurator()->SetLoopCount(2); |
+ component_updater()->Start(); |
+ message_loop.Run(); |
+ |
+ // Loop once more, but expect no ping because a noupdate response is issued. |
+ // This is necessary to clear out the fire-and-forget ping from the previous |
+ // iteration. |
+ interceptor.SetResponse(expected_update_url_1, |
+ test_file("updatecheck_reply_noupdate.xml")); |
+ test_configurator()->SetLoopCount(1); |
+ component_updater()->Start(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); |
+ EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); |
+ |
+ EXPECT_EQ(2, ping_checker.NumHits()); |
+ EXPECT_EQ(0, ping_checker.NumMisses()); |
+ EXPECT_EQ(5, interceptor.GetHitCount()); |
+ |
+ component_updater()->Stop(); |
+} |
+ |
+// Verify that we successfully propagate a patcher error. |
+// ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx contains an incorrect |
+// patching instruction that should fail. |
+TEST_F(ComponentUpdaterTest, DifferentialUpdateFailErrorcode) { |
+ base::MessageLoop message_loop; |
+ content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop); |
+ content::TestBrowserThread file_thread(BrowserThread::FILE); |
+ content::TestBrowserThread io_thread(BrowserThread::IO); |
+ |
+ io_thread.StartIOThread(); |
+ file_thread.Start(); |
+ |
+ std::map<std::string, std::string> map; |
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\"")); |
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\"")); |
+ map.insert(std::pair<std::string, std::string>("diffresult", "\"0\"")); |
+ map.insert(std::pair<std::string, std::string>("differrorcode", "\"14\"")); |
+ map.insert(std::pair<std::string, std::string>("diffextracode1", "\"305\"")); |
+ PingChecker ping_checker(map); |
+ URLRequestPostInterceptor post_interceptor(&ping_checker); |
+ content::URLLocalHostRequestPrepackagedInterceptor interceptor; |
+ |
+ VersionedTestInstaller installer; |
+ CrxComponent com; |
+ RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); |
+ |
+ const GURL expected_update_url_0( |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D0.0%26fp%3D%26uc"); |
+ const GURL expected_update_url_1( |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D1.0%26fp%3D1%26uc"); |
+ const GURL expected_update_url_2( |
+ "http://localhost/upd?extra=foo" |
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D2.0%26fp%3Df22%26uc"); |
+ const GURL expected_crx_url_1( |
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"); |
+ const GURL expected_crx_url_1_diff_2( |
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"); |
+ const GURL expected_crx_url_2( |
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"); |
+ |
+ interceptor.SetResponse(expected_update_url_0, |
+ test_file("updatecheck_diff_reply_1.xml")); |
+ interceptor.SetResponse(expected_update_url_1, |
+ test_file("updatecheck_diff_reply_2.xml")); |
+ interceptor.SetResponse(expected_update_url_2, |
+ test_file("updatecheck_diff_reply_3.xml")); |
+ interceptor.SetResponse(expected_crx_url_1, |
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); |
+ interceptor.SetResponse( |
+ expected_crx_url_1_diff_2, |
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx")); |
+ interceptor.SetResponse(expected_crx_url_2, |
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); |
+ |
+ test_configurator()->SetLoopCount(3); |
+ |
+ component_updater()->Start(); |
+ message_loop.Run(); |
+ |
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); |
+ EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); |
+ |
+ EXPECT_EQ(1, ping_checker.NumHits()); |
+ EXPECT_EQ(1, ping_checker.NumMisses()); |
+ EXPECT_EQ(6, interceptor.GetHitCount()); |
+ |
+ component_updater()->Stop(); |
+} |