-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <vector>
+
#include "chrome/browser/component_updater/test/component_updater_service_unittest.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
+#include "chrome/browser/component_updater/component_updater_resource_throttle.h"
+#include "chrome/browser/component_updater/component_updater_utils.h"
+#include "chrome/browser/component_updater/test/test_configurator.h"
#include "chrome/browser/component_updater/test/test_installer.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/browser/browser_thread.h"
-#include "content/test/net/url_request_prepackaged_interceptor.h"
+#include "content/public/browser/resource_controller.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/browser/resource_throttle.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_test_util.h"
#include "url/gurl.h"
using content::BrowserThread;
using ::testing::_;
+using ::testing::AnyNumber;
using ::testing::InSequence;
using ::testing::Mock;
-MockComponentObserver::MockComponentObserver() {
-}
-
-MockComponentObserver::~MockComponentObserver() {
-}
-
-TestConfigurator::TestConfigurator()
- : times_(1),
- recheck_time_(0),
- ondemand_time_(0),
- cus_(NULL),
- context_(new net::TestURLRequestContextGetter(
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))) {
-}
-
-TestConfigurator::~TestConfigurator() {
-}
-
-int TestConfigurator::InitialDelay() { return 0; }
-
-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) {
- quit_closure_.Run();
- return 0;
- }
- return 1;
-}
-
-int TestConfigurator::StepDelay() {
- return 0;
-}
-
-int TestConfigurator::StepDelayMedium() {
- return NextCheckDelay();
-}
-
-int TestConfigurator::MinimumReCheckWait() {
- return recheck_time_;
-}
-
-int TestConfigurator::OnDemandDelay() {
- return ondemand_time_;
-}
-
-GURL TestConfigurator::UpdateUrl() {
- return GURL("http://localhost/upd");
-}
-
-GURL TestConfigurator::PingUrl() {
- return GURL("http://localhost2/ping");
-}
-
-const char* TestConfigurator::ExtraRequestParams() { return "extra=foo"; }
+namespace component_updater {
-size_t TestConfigurator::UrlSizeLimit() { return 256; }
-
-net::URLRequestContextGetter* TestConfigurator::RequestContext() {
- return context_.get();
+MockServiceObserver::MockServiceObserver() {
}
-// Don't use the utility process to decode files.
-bool TestConfigurator::InProcess() { return true; }
-
-ComponentPatcher* TestConfigurator::CreateComponentPatcher() {
- return new MockComponentPatcher();
+MockServiceObserver::~MockServiceObserver() {
}
-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;
+bool PartialMatch::Match(const std::string& actual) const {
+ return actual.find(expected_) != std::string::npos;
}
-void TestConfigurator::SetOnDemandTime(int seconds) {
- ondemand_time_ = seconds;
+InterceptorFactory::InterceptorFactory()
+ : URLRequestPostInterceptorFactory(POST_INTERCEPT_SCHEME,
+ POST_INTERCEPT_HOSTNAME) {
}
-void TestConfigurator::SetComponentUpdateService(ComponentUpdateService* cus) {
- cus_ = cus;
+InterceptorFactory::~InterceptorFactory() {
}
-void TestConfigurator::SetQuitClosure(const base::Closure& quit_closure) {
- quit_closure_ = quit_closure;
+URLRequestPostInterceptor* InterceptorFactory::CreateInterceptor() {
+ return URLRequestPostInterceptorFactory::CreateInterceptor(
+ base::FilePath::FromUTF8Unsafe(POST_INTERCEPT_PATH));
}
ComponentUpdaterTest::ComponentUpdaterTest()
// 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_);
net::URLFetcher::SetEnableInterceptionForTests(false);
}
+void ComponentUpdaterTest::SetUp() {
+ get_interceptor_.reset(new GetInterceptor);
+ interceptor_factory_.reset(new InterceptorFactory);
+ post_interceptor_ = interceptor_factory_->CreateInterceptor();
+ EXPECT_TRUE(post_interceptor_);
+}
+
void ComponentUpdaterTest::TearDown() {
+ interceptor_factory_.reset();
+ get_interceptor_.reset();
xmlCleanupGlobals();
}
return component_updater_.get();
}
- // Makes the full path to a component updater test file.
+// 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);
}
base::RunLoop runloop;
test_configurator()->SetQuitClosure(runloop.QuitClosure());
runloop.Run();
+
+ // Since some tests need to drain currently enqueued tasks such as network
+ // intercepts on the IO thread, run the threads until they are
+ // idle. The component updater service won't loop again until the loop count
+ // is set and the service is started.
+ RunThreadsUntilIdle();
}
void ComponentUpdaterTest::RunThreadsUntilIdle() {
base::RunLoop().RunUntilIdle();
}
-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());
- pings_.push_back(data);
- // 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;
-}
-
-std::string PingChecker::GetPings() const {
- std::string pings_str = "Pings are:";
- int i = 0;
- for (std::vector<std::string>::const_iterator it = pings_.begin();
- it != pings_.end(); ++it) {
- pings_str.append(base::StringPrintf("\n (%d): %s", ++i, it->c_str()));
- }
- return pings_str;
-}
-
ComponentUpdateService::Status OnDemandTester::OnDemand(
- ComponentUpdateService* cus, const std::string& component_id) {
- return cus->OnDemandUpdate(component_id);
+ ComponentUpdateService* cus,
+ const std::string& component_id) {
+ return cus->GetOnDemandUpdater().OnDemandUpdate(component_id);
}
// Verify that our test fixture work and the component updater can
// Verify that when the server has no updates, we go back to sleep and
// the COMPONENT_UPDATER_STARTED and COMPONENT_UPDATER_SLEEPING notifications
-// are generated.
+// are generated. No pings are sent.
TEST_F(ComponentUpdaterTest, CheckCrxSleep) {
- content::URLLocalHostRequestPrepackagedInterceptor interceptor;
+ MockServiceObserver observer;
+
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(2);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(2);
- MockComponentObserver observer;
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
TestInstaller installer;
CrxComponent com;
- com.observer = &observer;
- EXPECT_EQ(ComponentUpdateService::kOk,
- RegisterComponent(&com,
- kTestComponent_abag,
- Version("1.1"),
- &installer));
-
- const GURL expected_update_url(
- "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"));
+ component_updater()->AddObserver(&observer);
+ EXPECT_EQ(
+ ComponentUpdateService::kOk,
+ RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
// We loop twice, but there are no updates so we expect two sleep messages.
test_configurator()->SetLoopCount(2);
-
- EXPECT_CALL(observer,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
component_updater()->Start();
-
- EXPECT_CALL(observer,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(2);
-
- EXPECT_CALL(observer,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(2);
RunThreads();
- EXPECT_EQ(2, interceptor.GetHitCount());
-
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
+ // Expect to see the two update check requests and no other requests,
+ // including pings.
+ EXPECT_EQ(2, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(2, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[1].find(
+ "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+
component_updater()->Stop();
// Loop twice again but this case we simulate a server error by returning
- // an empty file.
+ // an empty file. Expect the behavior of the service to be the same as before.
+ EXPECT_CALL(observer, OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(2);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(2);
- interceptor.SetResponse(expected_update_url,
- test_file("updatecheck_reply_empty"));
+ post_interceptor_->Reset();
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
test_configurator()->SetLoopCount(2);
-
- EXPECT_CALL(observer,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
component_updater()->Start();
-
- EXPECT_CALL(observer,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(2);
- EXPECT_CALL(observer,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(2);
RunThreads();
- EXPECT_EQ(4, interceptor.GetHitCount());
-
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
+ EXPECT_EQ(2, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(2, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[1].find(
+ "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+
component_updater()->Stop();
}
// the notifications above COMPONENT_UPDATE_FOUND and 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 non-ping network requests are issued:
-// 1- manifest check
+// We also check that the following network requests are issued:
+// 1- update check
// 2- download crx
-// 3- second manifest check.
+// 3- ping
+// 4- second update check.
TEST_F(ComponentUpdaterTest, InstallCrx) {
- 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;
-
- MockComponentObserver observer1;
+ MockServiceObserver observer;
{
InSequence seq;
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATE_FOUND, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATE_READY, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(AnyNumber());
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
}
- MockComponentObserver observer2;
- {
- InSequence seq;
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- }
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+
+ get_interceptor_->SetResponse(
+ GURL(expected_crx_url),
+ test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
+
+ component_updater()->AddObserver(&observer);
TestInstaller installer1;
CrxComponent com1;
- com1.observer = &observer1;
RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1);
TestInstaller installer2;
CrxComponent com2;
- com2.observer = &observer2;
RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2);
- const GURL expected_update_url_1(
- "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%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"));
- interceptor.SetResponse(expected_update_url_2,
- test_file("updatecheck_reply_1.xml"));
- interceptor.SetResponse(GURL(expected_crx_url),
- test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
-
test_configurator()->SetLoopCount(2);
-
component_updater()->Start();
RunThreads();
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error());
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count());
- EXPECT_EQ(3, interceptor.GetHitCount());
- EXPECT_EQ(1, ping_checker.NumHits()) << ping_checker.GetPings();
- EXPECT_EQ(0, ping_checker.NumMisses()) << ping_checker.GetPings();
+ // Expect three request in total: two update checks and one ping.
+ EXPECT_EQ(3, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(3, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+
+ // Expect one component download.
+ EXPECT_EQ(1, get_interceptor_->GetHitCount());
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[1].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+ "version=\"0.9\" nextversion=\"1.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[2].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
+ "<updatecheck /></app>"));
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[2].find(
+ "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+
+ // Test the protocol version is correct and the extra request attributes
+ // are included in the request.
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "request protocol=\"3.0\" extra=\"foo\""))
+ << post_interceptor_->GetRequestsAsString();
+
+ // Tokenize the request string to look for specific attributes, which
+ // are important for backward compatibility with the version v2 of the update
+ // protocol. In this case, inspect the <request>, which is the first element
+ // after the xml declaration of the update request body.
+ // Expect to find the |os|, |arch|, |prodchannel|, and |prodversion|
+ // attributes:
+ // <?xml version="1.0" encoding="UTF-8"?>
+ // <request... os=... arch=... prodchannel=... prodversion=...>
+ // ...
+ // </request>
+ const std::string update_request(post_interceptor_->GetRequests()[0]);
+ std::vector<base::StringPiece> elements;
+ Tokenize(update_request, "<>", &elements);
+ EXPECT_NE(string::npos, elements[1].find(" os="));
+ EXPECT_NE(string::npos, elements[1].find(" arch="));
+ EXPECT_NE(string::npos, elements[1].find(" prodchannel="));
+ EXPECT_NE(string::npos, elements[1].find(" prodversion="));
+
+ // Look for additional attributes of the request, such as |version|,
+ // |requestid|, |lang|, and |nacl_arch|.
+ EXPECT_NE(string::npos, elements[1].find(" version="));
+ EXPECT_NE(string::npos, elements[1].find(" requestid="));
+ EXPECT_NE(string::npos, elements[1].find(" lang="));
+ EXPECT_NE(string::npos, elements[1].find(" nacl_arch="));
component_updater()->Stop();
}
// particular there should not be an install because the minimum product
// version is much higher than of chrome.
TEST_F(ComponentUpdaterTest, ProdVersionCheck) {
- std::map<std::string, std::string> map;
- PingChecker ping_checker(map);
- URLRequestPostInterceptor post_interceptor(&ping_checker);
- content::URLLocalHostRequestPrepackagedInterceptor interceptor;
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_2.xml")));
+
+ get_interceptor_->SetResponse(
+ GURL(expected_crx_url),
+ test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
TestInstaller installer;
CrxComponent com;
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%26fp%3D%26uc");
-
- interceptor.SetResponse(expected_update_url,
- test_file("updatecheck_reply_2.xml"));
- interceptor.SetResponse(GURL(expected_crx_url),
- test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
-
test_configurator()->SetLoopCount(1);
component_updater()->Start();
RunThreads();
- EXPECT_EQ(0, ping_checker.NumHits()) << ping_checker.GetPings();
- EXPECT_EQ(0, ping_checker.NumMisses()) << ping_checker.GetPings();
- EXPECT_EQ(1, interceptor.GetHitCount());
+ // Expect one update check and no ping.
+ EXPECT_EQ(1, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(1, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+
+ // Expect no download to occur.
+ EXPECT_EQ(0, get_interceptor_->GetHitCount());
+
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
component_updater()->Stop();
}
-// Test that a ping for an update check can cause installs.
+// Test that a update check due to an on demand call can cause installs.
// Here is the timeline:
// - First loop: we return a reply that indicates no update, so
// nothing happens.
-// - We ping.
+// - We make an on demand call.
// - This triggers a second loop, which has a reply that triggers an install.
-TEST_F(ComponentUpdaterTest, OnDemandUpdate) {
- 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;
-
- MockComponentObserver observer1;
+#if defined(OS_LINUX)
+// http://crbug.com/396488
+#define MAYBE_OnDemandUpdate DISABLED_OnDemandUpdate
+#else
+#define MAYBE_OnDemandUpdate OnDemandUpdate
+#endif
+TEST_F(ComponentUpdaterTest, MAYBE_OnDemandUpdate) {
+ MockServiceObserver observer;
{
InSequence seq;
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(AnyNumber());
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
}
- MockComponentObserver observer2;
- {
- InSequence seq;
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATE_FOUND, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATE_READY, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- }
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
+
+ get_interceptor_->SetResponse(
+ GURL(expected_crx_url),
+ test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
+
+ component_updater()->AddObserver(&observer);
TestInstaller installer1;
CrxComponent com1;
- com1.observer = &observer1;
RegisterComponent(&com1, kTestComponent_abag, Version("2.2"), &installer1);
TestInstaller installer2;
CrxComponent com2;
- com2.observer = &observer2;
RegisterComponent(&com2, kTestComponent_jebg, Version("0.9"), &installer2);
- const GURL expected_update_url_1(
- "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%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26fp%3D%26uc"
- "%26installsource%3Dondemand"
- "&x=id%3Dabagagagagagagagagagagagagagagag%26v%3D2.2%26fp%3D%26uc");
-
- interceptor.SetResponse(expected_update_url_1,
- test_file("updatecheck_reply_empty"));
- interceptor.SetResponse(expected_update_url_2,
- test_file("updatecheck_reply_1.xml"));
- interceptor.SetResponse(GURL(expected_crx_url),
- test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
// No update normally.
test_configurator()->SetLoopCount(1);
component_updater()->Start();
RunThreads();
component_updater()->Stop();
+ EXPECT_EQ(1, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(1, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+
+ EXPECT_EQ(0, get_interceptor_->GetHitCount());
+
// Update after an on-demand check is issued.
- EXPECT_EQ(ComponentUpdateService::kOk,
- OnDemandTester::OnDemand(component_updater(),
- GetCrxComponentID(com2)));
+ post_interceptor_->Reset();
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+
+ EXPECT_EQ(
+ ComponentUpdateService::kOk,
+ OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
test_configurator()->SetLoopCount(1);
component_updater()->Start();
RunThreads();
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error());
EXPECT_EQ(1, static_cast<TestInstaller*>(com2.installer)->install_count());
- EXPECT_EQ(3, interceptor.GetHitCount());
-
- // Also check what happens if previous check too soon.
+ EXPECT_EQ(2, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(2, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+
+ EXPECT_EQ(1, get_interceptor_->GetHitCount());
+
+ // Expect the update check to contain an "ondemand" request for the
+ // second component (com2) and a normal request for the other component.
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"abagagagagagagagagagagagagagagag\" "
+ "version=\"2.2\"><updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+ "version=\"0.9\" installsource=\"ondemand\"><updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[1].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+ "version=\"0.9\" nextversion=\"1.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+
+ // Also check what happens if previous check too soon. It works, since this
+ // direct OnDemand call does not implement a cooldown.
test_configurator()->SetOnDemandTime(60 * 60);
- EXPECT_EQ(ComponentUpdateService::kError,
- OnDemandTester::OnDemand(component_updater(),
- GetCrxComponentID(com2)));
+ EXPECT_EQ(
+ ComponentUpdateService::kOk,
+ OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
// Okay, now reset to 0 for the other tests.
test_configurator()->SetOnDemandTime(0);
component_updater()->Stop();
// Test a few error cases. NOTE: We don't have callbacks for
// when the updates failed yet.
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
{
InSequence seq;
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- }
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2));
- {
- InSequence seq;
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
}
- const GURL expected_update_url_3(
- "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,
- test_file("updatecheck_reply_empty"));
+ post_interceptor_->Reset();
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
+
test_configurator()->SetLoopCount(1);
component_updater()->Start();
- EXPECT_EQ(ComponentUpdateService::kOk,
- OnDemandTester::OnDemand(component_updater(),
- GetCrxComponentID(com2)));
-
+ EXPECT_EQ(
+ ComponentUpdateService::kOk,
+ OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
RunThreads();
-
component_updater()->Stop();
+ EXPECT_EQ(1, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(1, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+
// No update: already updated to 1.0 so nothing new
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
{
InSequence seq;
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- }
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2));
- {
- InSequence seq;
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
}
- interceptor.SetResponse(expected_update_url_3,
- test_file("updatecheck_reply_1.xml"));
+ post_interceptor_->Reset();
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+
test_configurator()->SetLoopCount(1);
component_updater()->Start();
- EXPECT_EQ(ComponentUpdateService::kOk,
- OnDemandTester::OnDemand(component_updater(),
- GetCrxComponentID(com2)));
-
+ EXPECT_EQ(
+ ComponentUpdateService::kOk,
+ OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
RunThreads();
- EXPECT_EQ(1, ping_checker.NumHits()) << ping_checker.GetPings();
- EXPECT_EQ(0, ping_checker.NumMisses()) << ping_checker.GetPings();
+ EXPECT_EQ(1, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(1, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
component_updater()->Stop();
}
// Verify that a previously registered component can get re-registered
// with a different version.
TEST_F(ComponentUpdaterTest, CheckReRegistration) {
- 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;
-
- MockComponentObserver observer1;
+ MockServiceObserver observer;
{
InSequence seq;
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATE_FOUND, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATE_READY, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(AnyNumber());
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
}
- MockComponentObserver observer2;
- {
- InSequence seq;
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- }
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+
+ get_interceptor_->SetResponse(
+ GURL(expected_crx_url),
+ test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
+
+ component_updater()->AddObserver(&observer);
TestInstaller installer1;
CrxComponent com1;
- com1.observer = &observer1;
RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1);
TestInstaller installer2;
CrxComponent com2;
- com2.observer = &observer2;
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%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%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"));
- interceptor.SetResponse(expected_update_url_2,
- 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) with the updated 1.0 version.
+ // Loop twice to issue two checks: (1) with original 0.9 version, update to
+ // 1.0, and do the second check (2) with the updated 1.0 version.
test_configurator()->SetLoopCount(2);
-
component_updater()->Start();
RunThreads();
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()) << ping_checker.GetPings();
- EXPECT_EQ(0, ping_checker.NumMisses()) << ping_checker.GetPings();
- EXPECT_EQ(3, interceptor.GetHitCount());
+ EXPECT_EQ(3, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(1, get_interceptor_->GetHitCount());
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[1].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+ "version=\"0.9\" nextversion=\"1.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[2].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
component_updater()->Stop();
// Now re-register, pretending to be an even newer version (2.2)
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
{
InSequence seq;
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer1,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
}
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2));
- {
- InSequence seq;
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_STARTED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0))
- .Times(1);
- EXPECT_CALL(observer2,
- OnEvent(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0))
- .Times(1);
- }
+ post_interceptor_->Reset();
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
TestInstaller installer3;
EXPECT_EQ(ComponentUpdateService::kReplaced,
- 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%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"));
+ RegisterComponent(
+ &com1, kTestComponent_jebg, Version("2.2"), &installer3));
// Loop once just to notice the check happening with the re-register version.
test_configurator()->SetLoopCount(1);
component_updater()->Start();
RunThreads();
- EXPECT_EQ(4, interceptor.GetHitCount());
-
// 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());
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count());
+ // One update check and no additional pings are expected.
+ EXPECT_EQ(1, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(1, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"2.2\">"
+ "<updatecheck /></app>"));
+
component_updater()->Stop();
}
// 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) {
- 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;
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_diff_reply_1.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_diff_reply_2.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_diff_reply_3.xml")));
+
+ get_interceptor_->SetResponse(
+ GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"),
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"));
+ get_interceptor_->SetResponse(
+ GURL("http://localhost/download/"
+ "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"),
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"));
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();
RunThreads();
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
- // One ping has the diffresult=1, the other does not.
- EXPECT_EQ(1, ping_checker.NumHits()) << ping_checker.GetPings();
- EXPECT_EQ(1, ping_checker.NumMisses()) << ping_checker.GetPings();
-
- EXPECT_EQ(5, interceptor.GetHitCount());
-
+ EXPECT_EQ(5, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(5, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(2, get_interceptor_->GetHitCount());
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[1].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+ "version=\"0.0\" nextversion=\"1.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[2].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
+ "<updatecheck /><packages><package fp=\"1\"/></packages></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[3].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+ "version=\"1.0\" nextversion=\"2.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"1\" "
+ "previousfp=\"1\" nextfp=\"22\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[4].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
+ "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
+ << post_interceptor_->GetRequestsAsString();
component_updater()->Stop();
}
// 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) {
- 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;
+// This test is flaky on Android. crbug.com/329883
+#if defined(OS_ANDROID)
+#define MAYBE_DifferentialUpdateFails DISABLED_DifferentialUpdateFails
+#else
+#define MAYBE_DifferentialUpdateFails DifferentialUpdateFails
+#endif
+TEST_F(ComponentUpdaterTest, MAYBE_DifferentialUpdateFails) {
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_diff_reply_2.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_diff_reply_3.xml")));
+
+ get_interceptor_->SetResponse(
+ GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"),
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"));
+ get_interceptor_->SetResponse(
+ GURL("http://localhost/download/"
+ "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"),
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"));
+ get_interceptor_->SetResponse(
+ GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"),
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"));
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();
RunThreads();
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()) << ping_checker.GetPings();
- EXPECT_EQ(0, ping_checker.NumMisses()) << ping_checker.GetPings();
- EXPECT_EQ(4, interceptor.GetHitCount());
+ EXPECT_EQ(3, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(3, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(2, get_interceptor_->GetHitCount());
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[1].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+ "version=\"1.0\" nextversion=\"2.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"0\" "
+ "differrorcat=\"2\" differrorcode=\"16\" nextfp=\"22\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[2].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
+ "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
+ << post_interceptor_->GetRequestsAsString();
component_updater()->Stop();
}
+// Test is flakey on Android bots. See crbug.com/331420.
+#if defined(OS_ANDROID)
+#define MAYBE_CheckFailedInstallPing DISABLED_CheckFailedInstallPing
+#else
+#define MAYBE_CheckFailedInstallPing CheckFailedInstallPing
+#endif
// Verify that a failed installation causes an install failure ping.
-TEST_F(ComponentUpdaterTest, CheckFailedInstallPing) {
- 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;
-
+TEST_F(ComponentUpdaterTest, MAYBE_CheckFailedInstallPing) {
// This test installer reports installation failure.
class : public TestInstaller {
virtual bool Install(const base::DictionaryValue& manifest,
}
} installer;
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+ get_interceptor_->SetResponse(
+ GURL(expected_crx_url),
+ test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
+
+ // Start with 0.9, and attempt update to 1.0.
+ // Loop twice to issue two checks: (1) with original 0.9 version
+ // and (2), which should retry with 0.9.
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();
RunThreads();
+ EXPECT_EQ(4, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(2, get_interceptor_->GetHitCount());
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[1].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+ "version=\"0.9\" nextversion=\"1.0\">"
+ "<event eventtype=\"3\" eventresult=\"0\" "
+ "errorcat=\"3\" errorcode=\"9\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[2].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[3].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+ "version=\"0.9\" nextversion=\"1.0\">"
+ "<event eventtype=\"3\" eventresult=\"0\" "
+ "errorcat=\"3\" errorcode=\"9\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+
// 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"));
+ post_interceptor_->Reset();
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_reply_noupdate.xml")));
+
test_configurator()->SetLoopCount(1);
component_updater()->Start();
RunThreads();
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()) << ping_checker.GetPings();
- EXPECT_EQ(0, ping_checker.NumMisses()) << ping_checker.GetPings();
- EXPECT_EQ(5, interceptor.GetHitCount());
+ EXPECT_EQ(1, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(1, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
component_updater()->Stop();
}
// ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx contains an incorrect
// patching instruction that should fail.
TEST_F(ComponentUpdaterTest, DifferentialUpdateFailErrorcode) {
- 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;
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_diff_reply_1.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_diff_reply_2.xml")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_diff_reply_3.xml")));
+
+ get_interceptor_->SetResponse(
+ GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"),
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"));
+ // This intercept returns a different file than what is specified in the
+ // update check response and requested in the download. The file that is
+ // actually dowloaded contains a patching error, an therefore, an error
+ // is injected at the time of patching.
+ get_interceptor_->SetResponse(
+ GURL("http://localhost/download/"
+ "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"),
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx"));
+ get_interceptor_->SetResponse(
+ GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"),
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"));
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();
+ RunThreads();
+ component_updater()->Stop();
- test_configurator()->SetLoopCount(2);
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
+ EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
+
+ EXPECT_EQ(5, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(5, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_EQ(3, get_interceptor_->GetHitCount());
+
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[0].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
+ "<updatecheck /></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[1].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+ "version=\"0.0\" nextversion=\"1.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[2].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
+ "<updatecheck /><packages><package fp=\"1\"/></packages></app>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[3].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+ "version=\"1.0\" nextversion=\"2.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\" "
+ "diffresult=\"0\" differrorcat=\"2\" "
+ "differrorcode=\"14\" diffextracode1=\"305\" "
+ "previousfp=\"1\" nextfp=\"22\"/>"))
+ << post_interceptor_->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ post_interceptor_->GetRequests()[4].find(
+ "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
+ "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
+ << post_interceptor_->GetRequestsAsString();
+}
+
+class TestResourceController : public content::ResourceController {
+ public:
+ virtual void SetThrottle(content::ResourceThrottle* throttle) {}
+};
+
+content::ResourceThrottle* RequestTestResourceThrottle(
+ ComponentUpdateService* cus,
+ TestResourceController* controller,
+ const char* crx_id) {
+ net::TestURLRequestContext context;
+ net::TestURLRequest url_request(GURL("http://foo.example.com/thing.bin"),
+ net::DEFAULT_PRIORITY,
+ NULL,
+ &context);
+
+ content::ResourceThrottle* rt = GetOnDemandResourceThrottle(cus, crx_id);
+ rt->set_controller_for_testing(controller);
+ controller->SetThrottle(rt);
+ return rt;
+}
+
+void RequestAndDeleteResourceThrottle(ComponentUpdateService* cus,
+ const char* crx_id) {
+ // By requesting a throttle and deleting it immediately we ensure that we
+ // hit the case where the component updater tries to use the weak
+ // pointer to a dead Resource throttle.
+ class NoCallResourceController : public TestResourceController {
+ public:
+ virtual ~NoCallResourceController() {}
+ virtual void Cancel() OVERRIDE { CHECK(false); }
+ virtual void CancelAndIgnore() OVERRIDE { CHECK(false); }
+ virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); }
+ virtual void Resume() OVERRIDE { CHECK(false); }
+ } controller;
+
+ delete RequestTestResourceThrottle(cus, &controller, crx_id);
+}
+
+TEST_F(ComponentUpdaterTest, ResourceThrottleDeletedNoUpdate) {
+ MockServiceObserver observer;
+ {
+ InSequence seq;
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
+ }
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+
+ TestInstaller installer;
+ CrxComponent com;
+ component_updater()->AddObserver(&observer);
+ EXPECT_EQ(
+ ComponentUpdateService::kOk,
+ RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
+ // The following two calls ensure that we don't do an update check via the
+ // timer, so the only update check should be the on-demand one.
+ test_configurator()->SetInitialDelay(1000000);
+ test_configurator()->SetRecheckTime(1000000);
+ test_configurator()->SetLoopCount(1);
component_updater()->Start();
+
+ RunThreadsUntilIdle();
+
+ EXPECT_EQ(0, post_interceptor_->GetHitCount());
+
+ BrowserThread::PostTask(BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&RequestAndDeleteResourceThrottle,
+ component_updater(),
+ "abagagagagagagagagagagagagagagag"));
+
RunThreads();
+
+ EXPECT_EQ(1, post_interceptor_->GetHitCount());
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
+
component_updater()->Stop();
- // There may still be pings in the queue.
+}
+
+class CancelResourceController : public TestResourceController {
+ public:
+ CancelResourceController() : throttle_(NULL), resume_called_(0) {}
+ virtual ~CancelResourceController() {
+ // Check that the throttle has been resumed by the time we
+ // exit the test.
+ CHECK_EQ(1, resume_called_);
+ delete throttle_;
+ }
+ virtual void Cancel() OVERRIDE { CHECK(false); }
+ virtual void CancelAndIgnore() OVERRIDE { CHECK(false); }
+ virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); }
+ virtual void Resume() OVERRIDE {
+ BrowserThread::PostTask(BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&CancelResourceController::ResumeCalled,
+ base::Unretained(this)));
+ }
+ virtual void SetThrottle(content::ResourceThrottle* throttle) OVERRIDE {
+ throttle_ = throttle;
+ bool defer = false;
+ // Initially the throttle is blocked. The CUS needs to run a
+ // task on the UI thread to decide if it should unblock.
+ throttle_->WillStartRequest(&defer);
+ CHECK(defer);
+ }
+
+ private:
+ void ResumeCalled() { ++resume_called_; }
+
+ content::ResourceThrottle* throttle_;
+ int resume_called_;
+};
+
+// Tests the on-demand update with resource throttle, including the
+// cooldown interval between calls.
+TEST_F(ComponentUpdaterTest, ResourceThrottleLiveNoUpdate) {
+ MockServiceObserver observer;
+ {
+ InSequence seq;
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
+ EXPECT_CALL(observer,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ }
+
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+
+ TestInstaller installer;
+ CrxComponent com;
+ component_updater()->AddObserver(&observer);
+ EXPECT_EQ(
+ ComponentUpdateService::kOk,
+ RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
+ // The following two calls ensure that we don't do an update check via the
+ // timer, so the only update check should be the on-demand one.
+ test_configurator()->SetInitialDelay(1000000);
+ test_configurator()->SetRecheckTime(1000000);
+ test_configurator()->SetLoopCount(1);
+ component_updater()->Start();
+
RunThreadsUntilIdle();
- EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
- EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
+ EXPECT_EQ(0, post_interceptor_->GetHitCount());
+
+ {
+ // First on-demand update check is expected to succeeded.
+ CancelResourceController controller;
- EXPECT_EQ(1, ping_checker.NumHits()) << ping_checker.GetPings();
- EXPECT_EQ(1, ping_checker.NumMisses()) << ping_checker.GetPings();
- EXPECT_EQ(5, interceptor.GetHitCount());
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(&RequestTestResourceThrottle),
+ component_updater(),
+ &controller,
+ "abagagagagagagagagagagagagagagag"));
+
+ RunThreads();
+
+ EXPECT_EQ(1, post_interceptor_->GetHitCount());
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
+
+ component_updater()->Stop();
+ }
+
+ {
+ // Second on-demand update check is expected to succeed as well, since there
+ // is no cooldown interval between calls, due to calling SetOnDemandTime.
+ test_configurator()->SetOnDemandTime(0);
+ test_configurator()->SetLoopCount(1);
+ component_updater()->Start();
+
+ CancelResourceController controller;
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(&RequestTestResourceThrottle),
+ component_updater(),
+ &controller,
+ "abagagagagagagagagagagagagagagag"));
+
+ RunThreads();
+
+ EXPECT_EQ(1, post_interceptor_->GetHitCount());
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
+
+ component_updater()->Stop();
+ }
+
+ {
+ // This on-demand call is expected not to trigger a component update check.
+ test_configurator()->SetOnDemandTime(1000000);
+ component_updater()->Start();
+
+ CancelResourceController controller;
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(&RequestTestResourceThrottle),
+ component_updater(),
+ &controller,
+ "abagagagagagagagagagagagagagagag"));
+ RunThreadsUntilIdle();
+ }
}
+
+// Tests adding and removing observers.
+TEST_F(ComponentUpdaterTest, Observer) {
+ MockServiceObserver observer1, observer2;
+
+ // Expect that two observers see the events.
+ {
+ InSequence seq;
+ EXPECT_CALL(observer1,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer2,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer1,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer2,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer1,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
+ EXPECT_CALL(observer2,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
+ }
+
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+
+ component_updater()->AddObserver(&observer1);
+ component_updater()->AddObserver(&observer2);
+
+ TestInstaller installer;
+ CrxComponent com;
+ EXPECT_EQ(
+ ComponentUpdateService::kOk,
+ RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
+ test_configurator()->SetLoopCount(1);
+ component_updater()->Start();
+ RunThreads();
+
+ // After removing the first observer, it's only the second observer that
+ // gets the events.
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2));
+ {
+ InSequence seq;
+ EXPECT_CALL(observer2,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+ .Times(1);
+ EXPECT_CALL(observer2,
+ OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer2,
+ OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
+ .Times(1);
+ }
+
+ component_updater()->RemoveObserver(&observer1);
+
+ test_configurator()->SetLoopCount(1);
+ component_updater()->Start();
+ RunThreads();
+
+ // Both observers are removed and no one gets the events.
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2));
+ component_updater()->RemoveObserver(&observer2);
+
+ test_configurator()->SetLoopCount(1);
+ component_updater()->Start();
+ RunThreads();
+
+ component_updater()->Stop();
+}
+
+} // namespace component_updater