component_updater_service_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// Copyright 2012 The Chromium Authors. All rights reserved. 2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// Use of this source code is governed by a BSD-style license that can be 3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// found in the LICENSE file. 4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <vector> 6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "chrome/browser/component_updater/test/component_updater_service_unittest.h" 8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "base/file_util.h" 9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "base/path_service.h" 10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "base/run_loop.h" 11e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "base/strings/string_number_conversions.h" 12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "base/strings/string_util.h" 13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "base/strings/stringprintf.h" 14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "base/values.h" 15e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "chrome/browser/component_updater/component_updater_utils.h" 16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "chrome/browser/component_updater/test/test_configurator.h" 17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "chrome/browser/component_updater/test/test_installer.h" 18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "chrome/common/chrome_paths.h" 19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "content/public/browser/browser_thread.h" 20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "content/public/browser/resource_controller.h" 21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "content/public/browser/resource_request_info.h" 22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "content/public/browser/resource_throttle.h" 23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "libxml/globals.h" 24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "net/base/upload_bytes_element_reader.h" 25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "net/url_request/url_fetcher.h" 26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "net/url_request/url_request_test_util.h" 27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "url/gurl.h" 28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgusing content::BrowserThread; 30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgusing ::testing::_; 32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgusing ::testing::AnyNumber; 33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgusing ::testing::InSequence; 34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgusing ::testing::Mock; 35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgnamespace component_updater { 37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgMockServiceObserver::MockServiceObserver() { 39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgMockServiceObserver::~MockServiceObserver() { 42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgbool PartialMatch::Match(const std::string& actual) const { 45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return actual.find(expected_) != std::string::npos; 46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgInterceptorFactory::InterceptorFactory() 49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org : URLRequestPostInterceptorFactory(POST_INTERCEPT_SCHEME, 50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org POST_INTERCEPT_HOSTNAME) { 51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgInterceptorFactory::~InterceptorFactory() { 54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgURLRequestPostInterceptor* InterceptorFactory::CreateInterceptor() { 57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return URLRequestPostInterceptorFactory::CreateInterceptor( 58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org base::FilePath::FromUTF8Unsafe(POST_INTERCEPT_PATH)); 59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgComponentUpdaterTest::ComponentUpdaterTest() 62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org : test_config_(NULL), 63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) { 64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org // The component updater instance under test. 65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org test_config_ = new TestConfigurator; 66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org component_updater_.reset(ComponentUpdateServiceFactory(test_config_)); 67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org // The test directory is chrome/test/data/components. 69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); 70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org test_data_dir_ = test_data_dir_.AppendASCII("components"); 71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org net::URLFetcher::SetEnableInterceptionForTests(true); 73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgComponentUpdaterTest::~ComponentUpdaterTest() { 76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org net::URLFetcher::SetEnableInterceptionForTests(false); 77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid ComponentUpdaterTest::SetUp() { 80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org get_interceptor_.reset(new GetInterceptor); 81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org interceptor_factory_.reset(new InterceptorFactory); 82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org post_interceptor_ = interceptor_factory_->CreateInterceptor(); 83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org EXPECT_TRUE(post_interceptor_); 84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid ComponentUpdaterTest::TearDown() { 87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org interceptor_factory_.reset(); 88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org get_interceptor_.reset(); 89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xmlCleanupGlobals(); 90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgComponentUpdateService* ComponentUpdaterTest::component_updater() { 93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return component_updater_.get(); 94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// Makes the full path to a component updater test file. 97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgconst base::FilePath ComponentUpdaterTest::test_file(const char* file) { 98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return test_data_dir_.AppendASCII(file); 99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgTestConfigurator* ComponentUpdaterTest::test_configurator() { 102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return test_config_; 103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 104 105ComponentUpdateService::Status ComponentUpdaterTest::RegisterComponent( 106 CrxComponent* com, 107 TestComponents component, 108 const Version& version, 109 TestInstaller* installer) { 110 if (component == kTestComponent_abag) { 111 com->name = "test_abag"; 112 com->pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash)); 113 } else if (component == kTestComponent_jebg) { 114 com->name = "test_jebg"; 115 com->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash)); 116 } else { 117 com->name = "test_ihfo"; 118 com->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash)); 119 } 120 com->version = version; 121 com->installer = installer; 122 return component_updater_->RegisterComponent(*com); 123} 124 125void ComponentUpdaterTest::RunThreads() { 126 base::RunLoop runloop; 127 test_configurator()->SetQuitClosure(runloop.QuitClosure()); 128 runloop.Run(); 129 130 // Since some tests need to drain currently enqueued tasks such as network 131 // intercepts on the IO thread, run the threads until they are 132 // idle. The component updater service won't loop again until the loop count 133 // is set and the service is started. 134 RunThreadsUntilIdle(); 135} 136 137void ComponentUpdaterTest::RunThreadsUntilIdle() { 138 base::RunLoop().RunUntilIdle(); 139} 140 141ComponentUpdateService::Status OnDemandTester::OnDemand( 142 ComponentUpdateService* cus, 143 const std::string& component_id) { 144 return cus->GetOnDemandUpdater().OnDemandUpdate(component_id); 145} 146 147// Verify that our test fixture work and the component updater can 148// be created and destroyed with no side effects. 149TEST_F(ComponentUpdaterTest, VerifyFixture) { 150 EXPECT_TRUE(component_updater() != NULL); 151} 152 153// Verify that the component updater can be caught in a quick 154// start-shutdown situation. Failure of this test will be a crash. 155TEST_F(ComponentUpdaterTest, StartStop) { 156 component_updater()->Start(); 157 RunThreadsUntilIdle(); 158 component_updater()->Stop(); 159} 160 161// Verify that when the server has no updates, we go back to sleep and 162// the COMPONENT_UPDATER_STARTED and COMPONENT_UPDATER_SLEEPING notifications 163// are generated. No pings are sent. 164TEST_F(ComponentUpdaterTest, CheckCrxSleep) { 165 MockServiceObserver observer; 166 167 EXPECT_CALL(observer, 168 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 169 .Times(1); 170 EXPECT_CALL(observer, 171 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 172 .Times(2); 173 EXPECT_CALL(observer, 174 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 175 "abagagagagagagagagagagagagagagag")) 176 .Times(2); 177 178 EXPECT_TRUE(post_interceptor_->ExpectRequest( 179 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 180 EXPECT_TRUE(post_interceptor_->ExpectRequest( 181 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 182 183 TestInstaller installer; 184 CrxComponent com; 185 component_updater()->AddObserver(&observer); 186 EXPECT_EQ( 187 ComponentUpdateService::kOk, 188 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 189 190 // We loop twice, but there are no updates so we expect two sleep messages. 191 test_configurator()->SetLoopCount(2); 192 component_updater()->Start(); 193 RunThreads(); 194 195 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 196 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 197 198 // Expect to see the two update check requests and no other requests, 199 // including pings. 200 EXPECT_EQ(2, post_interceptor_->GetHitCount()) 201 << post_interceptor_->GetRequestsAsString(); 202 EXPECT_EQ(2, post_interceptor_->GetCount()) 203 << post_interceptor_->GetRequestsAsString(); 204 EXPECT_NE( 205 string::npos, 206 post_interceptor_->GetRequests()[0].find( 207 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">" 208 "<updatecheck /></app>")) 209 << post_interceptor_->GetRequestsAsString(); 210 EXPECT_NE( 211 string::npos, 212 post_interceptor_->GetRequests()[1].find( 213 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">" 214 "<updatecheck /></app>")) 215 << post_interceptor_->GetRequestsAsString(); 216 217 component_updater()->Stop(); 218 219 // Loop twice again but this case we simulate a server error by returning 220 // an empty file. Expect the behavior of the service to be the same as before. 221 EXPECT_CALL(observer, OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 222 .Times(1); 223 EXPECT_CALL(observer, 224 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 225 .Times(2); 226 EXPECT_CALL(observer, 227 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 228 "abagagagagagagagagagagagagagagag")) 229 .Times(2); 230 231 post_interceptor_->Reset(); 232 EXPECT_TRUE(post_interceptor_->ExpectRequest( 233 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty"))); 234 EXPECT_TRUE(post_interceptor_->ExpectRequest( 235 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty"))); 236 237 test_configurator()->SetLoopCount(2); 238 component_updater()->Start(); 239 RunThreads(); 240 241 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 242 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 243 244 EXPECT_EQ(2, post_interceptor_->GetHitCount()) 245 << post_interceptor_->GetRequestsAsString(); 246 EXPECT_EQ(2, post_interceptor_->GetCount()) 247 << post_interceptor_->GetRequestsAsString(); 248 EXPECT_NE( 249 string::npos, 250 post_interceptor_->GetRequests()[0].find( 251 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">" 252 "<updatecheck /></app>")) 253 << post_interceptor_->GetRequestsAsString(); 254 EXPECT_NE( 255 string::npos, 256 post_interceptor_->GetRequests()[1].find( 257 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">" 258 "<updatecheck /></app>")) 259 << post_interceptor_->GetRequestsAsString(); 260 261 component_updater()->Stop(); 262} 263 264// Verify that we can check for updates and install one component. Besides 265// the notifications above COMPONENT_UPDATE_FOUND and COMPONENT_UPDATE_READY 266// should have been fired. We do two loops so the second time around there 267// should be nothing left to do. 268// We also check that the following network requests are issued: 269// 1- update check 270// 2- download crx 271// 3- ping 272// 4- second update check. 273TEST_F(ComponentUpdaterTest, InstallCrx) { 274 MockServiceObserver observer; 275 { 276 InSequence seq; 277 EXPECT_CALL(observer, 278 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 279 .Times(1); 280 EXPECT_CALL(observer, 281 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND, 282 "jebgalgnebhfojomionfpkfelancnnkf")) 283 .Times(1); 284 EXPECT_CALL(observer, 285 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 286 "abagagagagagagagagagagagagagagag")) 287 .Times(1); 288 EXPECT_CALL(observer, 289 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING, 290 "jebgalgnebhfojomionfpkfelancnnkf")) 291 .Times(AnyNumber()); 292 EXPECT_CALL(observer, 293 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY, 294 "jebgalgnebhfojomionfpkfelancnnkf")) 295 .Times(1); 296 EXPECT_CALL(observer, 297 OnEvent(ServiceObserver::COMPONENT_UPDATED, 298 "jebgalgnebhfojomionfpkfelancnnkf")) 299 .Times(1); 300 EXPECT_CALL(observer, 301 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 302 .Times(1); 303 EXPECT_CALL(observer, 304 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 305 "jebgalgnebhfojomionfpkfelancnnkf")) 306 .Times(1); 307 EXPECT_CALL(observer, 308 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 309 "abagagagagagagagagagagagagagagag")) 310 .Times(1); 311 EXPECT_CALL(observer, 312 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 313 .Times(1); 314 } 315 316 EXPECT_TRUE(post_interceptor_->ExpectRequest( 317 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 318 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 319 EXPECT_TRUE(post_interceptor_->ExpectRequest( 320 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 321 322 get_interceptor_->SetResponse( 323 GURL(expected_crx_url), 324 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 325 326 component_updater()->AddObserver(&observer); 327 328 TestInstaller installer1; 329 CrxComponent com1; 330 RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1); 331 TestInstaller installer2; 332 CrxComponent com2; 333 RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2); 334 335 test_configurator()->SetLoopCount(2); 336 component_updater()->Start(); 337 RunThreads(); 338 339 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 340 EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count()); 341 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 342 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); 343 344 // Expect three request in total: two update checks and one ping. 345 EXPECT_EQ(3, post_interceptor_->GetHitCount()) 346 << post_interceptor_->GetRequestsAsString(); 347 EXPECT_EQ(3, post_interceptor_->GetCount()) 348 << post_interceptor_->GetRequestsAsString(); 349 350 // Expect one component download. 351 EXPECT_EQ(1, get_interceptor_->GetHitCount()); 352 353 EXPECT_NE( 354 string::npos, 355 post_interceptor_->GetRequests()[0].find( 356 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 357 "<updatecheck /></app>")) 358 << post_interceptor_->GetRequestsAsString(); 359 EXPECT_NE( 360 string::npos, 361 post_interceptor_->GetRequests()[0].find( 362 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">" 363 "<updatecheck /></app>")) 364 << post_interceptor_->GetRequestsAsString(); 365 366 EXPECT_NE( 367 string::npos, 368 post_interceptor_->GetRequests()[1].find( 369 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 370 "version=\"0.9\" nextversion=\"1.0\">" 371 "<event eventtype=\"3\" eventresult=\"1\"/>")) 372 << post_interceptor_->GetRequestsAsString(); 373 374 EXPECT_NE( 375 string::npos, 376 post_interceptor_->GetRequests()[2].find( 377 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">" 378 "<updatecheck /></app>")); 379 EXPECT_NE( 380 string::npos, 381 post_interceptor_->GetRequests()[2].find( 382 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">" 383 "<updatecheck /></app>")) 384 << post_interceptor_->GetRequestsAsString(); 385 386 // Test the protocol version is correct and the extra request attributes 387 // are included in the request. 388 EXPECT_NE( 389 string::npos, 390 post_interceptor_->GetRequests()[0].find( 391 "request protocol=\"3.0\" extra=\"foo\"")) 392 << post_interceptor_->GetRequestsAsString(); 393 394 // Tokenize the request string to look for specific attributes, which 395 // are important for backward compatibility with the version v2 of the update 396 // protocol. In this case, inspect the <request>, which is the first element 397 // after the xml declaration of the update request body. 398 // Expect to find the |os|, |arch|, |prodchannel|, and |prodversion| 399 // attributes: 400 // <?xml version="1.0" encoding="UTF-8"?> 401 // <request... os=... arch=... prodchannel=... prodversion=...> 402 // ... 403 // </request> 404 const std::string update_request(post_interceptor_->GetRequests()[0]); 405 std::vector<base::StringPiece> elements; 406 Tokenize(update_request, "<>", &elements); 407 EXPECT_NE(string::npos, elements[1].find(" os=")); 408 EXPECT_NE(string::npos, elements[1].find(" arch=")); 409 EXPECT_NE(string::npos, elements[1].find(" prodchannel=")); 410 EXPECT_NE(string::npos, elements[1].find(" prodversion=")); 411 412 // Look for additional attributes of the request, such as |version|, 413 // |requestid|, |lang|, and |nacl_arch|. 414 EXPECT_NE(string::npos, elements[1].find(" version=")); 415 EXPECT_NE(string::npos, elements[1].find(" requestid=")); 416 EXPECT_NE(string::npos, elements[1].find(" lang=")); 417 EXPECT_NE(string::npos, elements[1].find(" nacl_arch=")); 418 419 component_updater()->Stop(); 420} 421 422// This test checks that the "prodversionmin" value is handled correctly. In 423// particular there should not be an install because the minimum product 424// version is much higher than of chrome. 425TEST_F(ComponentUpdaterTest, ProdVersionCheck) { 426 EXPECT_TRUE(post_interceptor_->ExpectRequest( 427 new PartialMatch("updatecheck"), test_file("updatecheck_reply_2.xml"))); 428 429 get_interceptor_->SetResponse( 430 GURL(expected_crx_url), 431 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 432 433 TestInstaller installer; 434 CrxComponent com; 435 RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); 436 437 test_configurator()->SetLoopCount(1); 438 component_updater()->Start(); 439 RunThreads(); 440 441 // Expect one update check and no ping. 442 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 443 << post_interceptor_->GetRequestsAsString(); 444 EXPECT_EQ(1, post_interceptor_->GetCount()) 445 << post_interceptor_->GetRequestsAsString(); 446 447 // Expect no download to occur. 448 EXPECT_EQ(0, get_interceptor_->GetHitCount()); 449 450 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 451 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 452 453 component_updater()->Stop(); 454} 455 456// Test that a update check due to an on demand call can cause installs. 457// Here is the timeline: 458// - First loop: we return a reply that indicates no update, so 459// nothing happens. 460// - We make an on demand call. 461// - This triggers a second loop, which has a reply that triggers an install. 462TEST_F(ComponentUpdaterTest, OnDemandUpdate) { 463 MockServiceObserver observer; 464 { 465 InSequence seq; 466 EXPECT_CALL(observer, 467 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 468 .Times(1); 469 EXPECT_CALL(observer, 470 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 471 "abagagagagagagagagagagagagagagag")) 472 .Times(1); 473 EXPECT_CALL(observer, 474 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 475 "jebgalgnebhfojomionfpkfelancnnkf")) 476 .Times(1); 477 EXPECT_CALL(observer, 478 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 479 .Times(1); 480 EXPECT_CALL(observer, 481 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 482 .Times(1); 483 EXPECT_CALL(observer, 484 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND, 485 "jebgalgnebhfojomionfpkfelancnnkf")) 486 .Times(1); 487 EXPECT_CALL(observer, 488 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 489 "abagagagagagagagagagagagagagagag")) 490 .Times(1); 491 EXPECT_CALL(observer, 492 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING, 493 "jebgalgnebhfojomionfpkfelancnnkf")) 494 .Times(AnyNumber()); 495 EXPECT_CALL(observer, 496 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY, 497 "jebgalgnebhfojomionfpkfelancnnkf")) 498 .Times(1); 499 EXPECT_CALL(observer, 500 OnEvent(ServiceObserver::COMPONENT_UPDATED, 501 "jebgalgnebhfojomionfpkfelancnnkf")) 502 .Times(1); 503 EXPECT_CALL(observer, 504 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 505 .Times(1); 506 } 507 508 EXPECT_TRUE(post_interceptor_->ExpectRequest( 509 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty"))); 510 511 get_interceptor_->SetResponse( 512 GURL(expected_crx_url), 513 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 514 515 component_updater()->AddObserver(&observer); 516 517 TestInstaller installer1; 518 CrxComponent com1; 519 RegisterComponent(&com1, kTestComponent_abag, Version("2.2"), &installer1); 520 TestInstaller installer2; 521 CrxComponent com2; 522 RegisterComponent(&com2, kTestComponent_jebg, Version("0.9"), &installer2); 523 524 // No update normally. 525 test_configurator()->SetLoopCount(1); 526 component_updater()->Start(); 527 RunThreads(); 528 component_updater()->Stop(); 529 530 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 531 << post_interceptor_->GetRequestsAsString(); 532 EXPECT_EQ(1, post_interceptor_->GetCount()) 533 << post_interceptor_->GetRequestsAsString(); 534 535 EXPECT_EQ(0, get_interceptor_->GetHitCount()); 536 537 // Update after an on-demand check is issued. 538 post_interceptor_->Reset(); 539 EXPECT_TRUE(post_interceptor_->ExpectRequest( 540 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 541 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 542 543 EXPECT_EQ( 544 ComponentUpdateService::kOk, 545 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 546 test_configurator()->SetLoopCount(1); 547 component_updater()->Start(); 548 RunThreads(); 549 550 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 551 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count()); 552 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 553 EXPECT_EQ(1, static_cast<TestInstaller*>(com2.installer)->install_count()); 554 555 EXPECT_EQ(2, post_interceptor_->GetHitCount()) 556 << post_interceptor_->GetRequestsAsString(); 557 EXPECT_EQ(2, post_interceptor_->GetCount()) 558 << post_interceptor_->GetRequestsAsString(); 559 560 EXPECT_EQ(1, get_interceptor_->GetHitCount()); 561 562 // Expect the update check to contain an "ondemand" request for the 563 // second component (com2) and a normal request for the other component. 564 EXPECT_NE( 565 string::npos, 566 post_interceptor_->GetRequests()[0].find( 567 "<app appid=\"abagagagagagagagagagagagagagagag\" " 568 "version=\"2.2\"><updatecheck /></app>")) 569 << post_interceptor_->GetRequestsAsString(); 570 EXPECT_NE( 571 string::npos, 572 post_interceptor_->GetRequests()[0].find( 573 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 574 "version=\"0.9\" installsource=\"ondemand\"><updatecheck /></app>")) 575 << post_interceptor_->GetRequestsAsString(); 576 EXPECT_NE( 577 string::npos, 578 post_interceptor_->GetRequests()[1].find( 579 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 580 "version=\"0.9\" nextversion=\"1.0\">" 581 "<event eventtype=\"3\" eventresult=\"1\"/>")) 582 << post_interceptor_->GetRequestsAsString(); 583 584 // Also check what happens if previous check too soon. It works, since this 585 // direct OnDemand call does not implement a cooldown. 586 test_configurator()->SetOnDemandTime(60 * 60); 587 EXPECT_EQ( 588 ComponentUpdateService::kOk, 589 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 590 // Okay, now reset to 0 for the other tests. 591 test_configurator()->SetOnDemandTime(0); 592 component_updater()->Stop(); 593 594 // Test a few error cases. NOTE: We don't have callbacks for 595 // when the updates failed yet. 596 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); 597 { 598 InSequence seq; 599 EXPECT_CALL(observer, 600 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 601 .Times(1); 602 EXPECT_CALL(observer, 603 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 604 "abagagagagagagagagagagagagagagag")) 605 .Times(1); 606 EXPECT_CALL(observer, 607 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 608 "jebgalgnebhfojomionfpkfelancnnkf")) 609 .Times(1); 610 EXPECT_CALL(observer, 611 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 612 .Times(1); 613 } 614 615 // No update: error from no server response 616 post_interceptor_->Reset(); 617 EXPECT_TRUE(post_interceptor_->ExpectRequest( 618 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty"))); 619 620 test_configurator()->SetLoopCount(1); 621 component_updater()->Start(); 622 EXPECT_EQ( 623 ComponentUpdateService::kOk, 624 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 625 RunThreads(); 626 component_updater()->Stop(); 627 628 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 629 << post_interceptor_->GetRequestsAsString(); 630 EXPECT_EQ(1, post_interceptor_->GetCount()) 631 << post_interceptor_->GetRequestsAsString(); 632 633 // No update: already updated to 1.0 so nothing new 634 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); 635 { 636 InSequence seq; 637 EXPECT_CALL(observer, 638 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 639 .Times(1); 640 EXPECT_CALL(observer, 641 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 642 "jebgalgnebhfojomionfpkfelancnnkf")) 643 .Times(1); 644 EXPECT_CALL(observer, 645 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 646 "abagagagagagagagagagagagagagagag")) 647 .Times(1); 648 EXPECT_CALL(observer, 649 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 650 .Times(1); 651 } 652 653 post_interceptor_->Reset(); 654 EXPECT_TRUE(post_interceptor_->ExpectRequest( 655 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 656 657 test_configurator()->SetLoopCount(1); 658 component_updater()->Start(); 659 EXPECT_EQ( 660 ComponentUpdateService::kOk, 661 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2))); 662 RunThreads(); 663 664 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 665 << post_interceptor_->GetRequestsAsString(); 666 EXPECT_EQ(1, post_interceptor_->GetCount()) 667 << post_interceptor_->GetRequestsAsString(); 668 669 component_updater()->Stop(); 670} 671 672// Verify that a previously registered component can get re-registered 673// with a different version. 674TEST_F(ComponentUpdaterTest, CheckReRegistration) { 675 MockServiceObserver observer; 676 { 677 InSequence seq; 678 EXPECT_CALL(observer, 679 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 680 .Times(1); 681 EXPECT_CALL(observer, 682 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND, 683 "jebgalgnebhfojomionfpkfelancnnkf")) 684 .Times(1); 685 EXPECT_CALL(observer, 686 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 687 "abagagagagagagagagagagagagagagag")) 688 .Times(1); 689 EXPECT_CALL(observer, 690 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING, 691 "jebgalgnebhfojomionfpkfelancnnkf")) 692 .Times(AnyNumber()); 693 EXPECT_CALL(observer, 694 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY, 695 "jebgalgnebhfojomionfpkfelancnnkf")) 696 .Times(1); 697 EXPECT_CALL(observer, 698 OnEvent(ServiceObserver::COMPONENT_UPDATED, 699 "jebgalgnebhfojomionfpkfelancnnkf")) 700 .Times(1); 701 EXPECT_CALL(observer, 702 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 703 .Times(1); 704 EXPECT_CALL(observer, 705 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 706 "jebgalgnebhfojomionfpkfelancnnkf")) 707 .Times(1); 708 EXPECT_CALL(observer, 709 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 710 "abagagagagagagagagagagagagagagag")) 711 .Times(1); 712 EXPECT_CALL(observer, 713 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 714 .Times(1); 715 } 716 717 EXPECT_TRUE(post_interceptor_->ExpectRequest( 718 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 719 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 720 EXPECT_TRUE(post_interceptor_->ExpectRequest( 721 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 722 723 get_interceptor_->SetResponse( 724 GURL(expected_crx_url), 725 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 726 727 component_updater()->AddObserver(&observer); 728 729 TestInstaller installer1; 730 CrxComponent com1; 731 RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1); 732 TestInstaller installer2; 733 CrxComponent com2; 734 RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2); 735 736 // Loop twice to issue two checks: (1) with original 0.9 version, update to 737 // 1.0, and do the second check (2) with the updated 1.0 version. 738 test_configurator()->SetLoopCount(2); 739 component_updater()->Start(); 740 RunThreads(); 741 742 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 743 EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count()); 744 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 745 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); 746 747 EXPECT_EQ(3, post_interceptor_->GetHitCount()) 748 << post_interceptor_->GetRequestsAsString(); 749 EXPECT_EQ(1, get_interceptor_->GetHitCount()); 750 751 EXPECT_NE( 752 string::npos, 753 post_interceptor_->GetRequests()[0].find( 754 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 755 "<updatecheck /></app>")) 756 << post_interceptor_->GetRequestsAsString(); 757 EXPECT_NE( 758 string::npos, 759 post_interceptor_->GetRequests()[1].find( 760 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 761 "version=\"0.9\" nextversion=\"1.0\">" 762 "<event eventtype=\"3\" eventresult=\"1\"/>")) 763 << post_interceptor_->GetRequestsAsString(); 764 EXPECT_NE( 765 string::npos, 766 post_interceptor_->GetRequests()[2].find( 767 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">" 768 "<updatecheck /></app>")) 769 << post_interceptor_->GetRequestsAsString(); 770 771 component_updater()->Stop(); 772 773 // Now re-register, pretending to be an even newer version (2.2) 774 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); 775 { 776 InSequence seq; 777 EXPECT_CALL(observer, 778 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 779 .Times(1); 780 EXPECT_CALL(observer, 781 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 782 "jebgalgnebhfojomionfpkfelancnnkf")) 783 .Times(1); 784 EXPECT_CALL(observer, 785 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 786 "abagagagagagagagagagagagagagagag")) 787 .Times(1); 788 EXPECT_CALL(observer, 789 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 790 .Times(1); 791 } 792 793 post_interceptor_->Reset(); 794 EXPECT_TRUE(post_interceptor_->ExpectRequest( 795 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 796 797 TestInstaller installer3; 798 EXPECT_EQ(ComponentUpdateService::kReplaced, 799 RegisterComponent( 800 &com1, kTestComponent_jebg, Version("2.2"), &installer3)); 801 802 // Loop once just to notice the check happening with the re-register version. 803 test_configurator()->SetLoopCount(1); 804 component_updater()->Start(); 805 RunThreads(); 806 807 // We created a new installer, so the counts go back to 0. 808 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error()); 809 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count()); 810 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error()); 811 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count()); 812 813 // One update check and no additional pings are expected. 814 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 815 << post_interceptor_->GetRequestsAsString(); 816 EXPECT_EQ(1, post_interceptor_->GetCount()) 817 << post_interceptor_->GetRequestsAsString(); 818 819 EXPECT_NE( 820 string::npos, 821 post_interceptor_->GetRequests()[0].find( 822 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"2.2\">" 823 "<updatecheck /></app>")); 824 825 component_updater()->Stop(); 826} 827 828// Verify that we can download and install a component and a differential 829// update to that component. We do three loops; the final loop should do 830// nothing. 831// We also check that exactly 5 non-ping network requests are issued: 832// 1- update check (response: v1 available) 833// 2- download crx (v1) 834// 3- update check (response: v2 available) 835// 4- download differential crx (v1 to v2) 836// 5- update check (response: no further update available) 837// There should be two pings, one for each update. The second will bear a 838// diffresult=1, while the first will not. 839TEST_F(ComponentUpdaterTest, DifferentialUpdate) { 840 EXPECT_TRUE(post_interceptor_->ExpectRequest( 841 new PartialMatch("updatecheck"), 842 test_file("updatecheck_diff_reply_1.xml"))); 843 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 844 EXPECT_TRUE(post_interceptor_->ExpectRequest( 845 new PartialMatch("updatecheck"), 846 test_file("updatecheck_diff_reply_2.xml"))); 847 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 848 EXPECT_TRUE(post_interceptor_->ExpectRequest( 849 new PartialMatch("updatecheck"), 850 test_file("updatecheck_diff_reply_3.xml"))); 851 852 get_interceptor_->SetResponse( 853 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 854 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 855 get_interceptor_->SetResponse( 856 GURL("http://localhost/download/" 857 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 858 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); 859 860 VersionedTestInstaller installer; 861 CrxComponent com; 862 RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); 863 864 test_configurator()->SetLoopCount(3); 865 component_updater()->Start(); 866 RunThreads(); 867 868 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 869 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 870 871 EXPECT_EQ(5, post_interceptor_->GetHitCount()) 872 << post_interceptor_->GetRequestsAsString(); 873 EXPECT_EQ(5, post_interceptor_->GetCount()) 874 << post_interceptor_->GetRequestsAsString(); 875 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 876 877 EXPECT_NE( 878 string::npos, 879 post_interceptor_->GetRequests()[0].find( 880 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">" 881 "<updatecheck /></app>")) 882 << post_interceptor_->GetRequestsAsString(); 883 EXPECT_NE( 884 string::npos, 885 post_interceptor_->GetRequests()[1].find( 886 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 887 "version=\"0.0\" nextversion=\"1.0\">" 888 "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>")) 889 << post_interceptor_->GetRequestsAsString(); 890 EXPECT_NE( 891 string::npos, 892 post_interceptor_->GetRequests()[2].find( 893 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 894 "<updatecheck /><packages><package fp=\"1\"/></packages></app>")) 895 << post_interceptor_->GetRequestsAsString(); 896 EXPECT_NE( 897 string::npos, 898 post_interceptor_->GetRequests()[3].find( 899 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 900 "version=\"1.0\" nextversion=\"2.0\">" 901 "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"1\" " 902 "previousfp=\"1\" nextfp=\"22\"/>")) 903 << post_interceptor_->GetRequestsAsString(); 904 EXPECT_NE( 905 string::npos, 906 post_interceptor_->GetRequests()[4].find( 907 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 908 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 909 << post_interceptor_->GetRequestsAsString(); 910 component_updater()->Stop(); 911} 912 913// Verify that component installation falls back to downloading and installing 914// a full update if the differential update fails (in this case, because the 915// installer does not know about the existing files). We do two loops; the final 916// loop should do nothing. 917// We also check that exactly 4 non-ping network requests are issued: 918// 1- update check (loop 1) 919// 2- download differential crx 920// 3- download full crx 921// 4- update check (loop 2 - no update available) 922// There should be one ping for the first attempted update. 923// This test is flaky on Android. crbug.com/329883 924#if defined(OS_ANDROID) 925#define MAYBE_DifferentialUpdateFails DISABLED_DifferentialUpdateFails 926#else 927#define MAYBE_DifferentialUpdateFails DifferentialUpdateFails 928#endif 929TEST_F(ComponentUpdaterTest, MAYBE_DifferentialUpdateFails) { 930 EXPECT_TRUE(post_interceptor_->ExpectRequest( 931 new PartialMatch("updatecheck"), 932 test_file("updatecheck_diff_reply_2.xml"))); 933 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 934 EXPECT_TRUE(post_interceptor_->ExpectRequest( 935 new PartialMatch("updatecheck"), 936 test_file("updatecheck_diff_reply_3.xml"))); 937 938 get_interceptor_->SetResponse( 939 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 940 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 941 get_interceptor_->SetResponse( 942 GURL("http://localhost/download/" 943 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 944 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx")); 945 get_interceptor_->SetResponse( 946 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), 947 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); 948 949 TestInstaller installer; 950 CrxComponent com; 951 RegisterComponent(&com, kTestComponent_ihfo, Version("1.0"), &installer); 952 953 test_configurator()->SetLoopCount(2); 954 component_updater()->Start(); 955 RunThreads(); 956 957 // A failed differential update does not count as a failed install. 958 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 959 EXPECT_EQ(1, static_cast<TestInstaller*>(com.installer)->install_count()); 960 961 EXPECT_EQ(3, post_interceptor_->GetHitCount()) 962 << post_interceptor_->GetRequestsAsString(); 963 EXPECT_EQ(3, post_interceptor_->GetCount()) 964 << post_interceptor_->GetRequestsAsString(); 965 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 966 967 EXPECT_NE( 968 string::npos, 969 post_interceptor_->GetRequests()[0].find( 970 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 971 "<updatecheck /></app>")) 972 << post_interceptor_->GetRequestsAsString(); 973 EXPECT_NE( 974 string::npos, 975 post_interceptor_->GetRequests()[1].find( 976 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 977 "version=\"1.0\" nextversion=\"2.0\">" 978 "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"0\" " 979 "differrorcat=\"2\" differrorcode=\"16\" nextfp=\"22\"/>")) 980 << post_interceptor_->GetRequestsAsString(); 981 EXPECT_NE( 982 string::npos, 983 post_interceptor_->GetRequests()[2].find( 984 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 985 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 986 << post_interceptor_->GetRequestsAsString(); 987 988 component_updater()->Stop(); 989} 990 991// Test is flakey on Android bots. See crbug.com/331420. 992#if defined(OS_ANDROID) 993#define MAYBE_CheckFailedInstallPing DISABLED_CheckFailedInstallPing 994#else 995#define MAYBE_CheckFailedInstallPing CheckFailedInstallPing 996#endif 997// Verify that a failed installation causes an install failure ping. 998TEST_F(ComponentUpdaterTest, MAYBE_CheckFailedInstallPing) { 999 // This test installer reports installation failure. 1000 class : public TestInstaller { 1001 virtual bool Install(const base::DictionaryValue& manifest, 1002 const base::FilePath& unpack_path) OVERRIDE { 1003 ++install_count_; 1004 base::DeleteFile(unpack_path, true); 1005 return false; 1006 } 1007 } installer; 1008 1009 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1010 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1011 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1012 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1013 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1014 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1015 get_interceptor_->SetResponse( 1016 GURL(expected_crx_url), 1017 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx")); 1018 1019 // Start with 0.9, and attempt update to 1.0. 1020 // Loop twice to issue two checks: (1) with original 0.9 version 1021 // and (2), which should retry with 0.9. 1022 CrxComponent com; 1023 RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer); 1024 1025 test_configurator()->SetLoopCount(2); 1026 component_updater()->Start(); 1027 RunThreads(); 1028 1029 EXPECT_EQ(4, post_interceptor_->GetHitCount()) 1030 << post_interceptor_->GetRequestsAsString(); 1031 EXPECT_EQ(2, get_interceptor_->GetHitCount()); 1032 1033 EXPECT_NE( 1034 string::npos, 1035 post_interceptor_->GetRequests()[0].find( 1036 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1037 "<updatecheck /></app>")) 1038 << post_interceptor_->GetRequestsAsString(); 1039 EXPECT_NE( 1040 string::npos, 1041 post_interceptor_->GetRequests()[1].find( 1042 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 1043 "version=\"0.9\" nextversion=\"1.0\">" 1044 "<event eventtype=\"3\" eventresult=\"0\" " 1045 "errorcat=\"3\" errorcode=\"9\"/>")) 1046 << post_interceptor_->GetRequestsAsString(); 1047 EXPECT_NE( 1048 string::npos, 1049 post_interceptor_->GetRequests()[2].find( 1050 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1051 "<updatecheck /></app>")) 1052 << post_interceptor_->GetRequestsAsString(); 1053 EXPECT_NE( 1054 string::npos, 1055 post_interceptor_->GetRequests()[3].find( 1056 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" " 1057 "version=\"0.9\" nextversion=\"1.0\">" 1058 "<event eventtype=\"3\" eventresult=\"0\" " 1059 "errorcat=\"3\" errorcode=\"9\"/>")) 1060 << post_interceptor_->GetRequestsAsString(); 1061 1062 // Loop once more, but expect no ping because a noupdate response is issued. 1063 // This is necessary to clear out the fire-and-forget ping from the previous 1064 // iteration. 1065 post_interceptor_->Reset(); 1066 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1067 new PartialMatch("updatecheck"), 1068 test_file("updatecheck_reply_noupdate.xml"))); 1069 1070 test_configurator()->SetLoopCount(1); 1071 component_updater()->Start(); 1072 RunThreads(); 1073 1074 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1075 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 1076 1077 EXPECT_EQ(1, post_interceptor_->GetHitCount()) 1078 << post_interceptor_->GetRequestsAsString(); 1079 EXPECT_EQ(1, post_interceptor_->GetCount()) 1080 << post_interceptor_->GetRequestsAsString(); 1081 1082 EXPECT_NE( 1083 string::npos, 1084 post_interceptor_->GetRequests()[0].find( 1085 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">" 1086 "<updatecheck /></app>")) 1087 << post_interceptor_->GetRequestsAsString(); 1088 1089 component_updater()->Stop(); 1090} 1091 1092// Verify that we successfully propagate a patcher error. 1093// ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx contains an incorrect 1094// patching instruction that should fail. 1095TEST_F(ComponentUpdaterTest, DifferentialUpdateFailErrorcode) { 1096 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1097 new PartialMatch("updatecheck"), 1098 test_file("updatecheck_diff_reply_1.xml"))); 1099 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1100 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1101 new PartialMatch("updatecheck"), 1102 test_file("updatecheck_diff_reply_2.xml"))); 1103 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event"))); 1104 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1105 new PartialMatch("updatecheck"), 1106 test_file("updatecheck_diff_reply_3.xml"))); 1107 1108 get_interceptor_->SetResponse( 1109 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), 1110 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx")); 1111 // This intercept returns a different file than what is specified in the 1112 // update check response and requested in the download. The file that is 1113 // actually dowloaded contains a patching error, an therefore, an error 1114 // is injected at the time of patching. 1115 get_interceptor_->SetResponse( 1116 GURL("http://localhost/download/" 1117 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), 1118 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx")); 1119 get_interceptor_->SetResponse( 1120 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), 1121 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx")); 1122 1123 VersionedTestInstaller installer; 1124 CrxComponent com; 1125 RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer); 1126 1127 test_configurator()->SetLoopCount(3); 1128 component_updater()->Start(); 1129 RunThreads(); 1130 component_updater()->Stop(); 1131 1132 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1133 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count()); 1134 1135 EXPECT_EQ(5, post_interceptor_->GetHitCount()) 1136 << post_interceptor_->GetRequestsAsString(); 1137 EXPECT_EQ(5, post_interceptor_->GetCount()) 1138 << post_interceptor_->GetRequestsAsString(); 1139 EXPECT_EQ(3, get_interceptor_->GetHitCount()); 1140 1141 EXPECT_NE( 1142 string::npos, 1143 post_interceptor_->GetRequests()[0].find( 1144 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">" 1145 "<updatecheck /></app>")) 1146 << post_interceptor_->GetRequestsAsString(); 1147 EXPECT_NE( 1148 string::npos, 1149 post_interceptor_->GetRequests()[1].find( 1150 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1151 "version=\"0.0\" nextversion=\"1.0\">" 1152 "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>")) 1153 << post_interceptor_->GetRequestsAsString(); 1154 EXPECT_NE( 1155 string::npos, 1156 post_interceptor_->GetRequests()[2].find( 1157 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">" 1158 "<updatecheck /><packages><package fp=\"1\"/></packages></app>")) 1159 << post_interceptor_->GetRequestsAsString(); 1160 EXPECT_NE( 1161 string::npos, 1162 post_interceptor_->GetRequests()[3].find( 1163 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" " 1164 "version=\"1.0\" nextversion=\"2.0\">" 1165 "<event eventtype=\"3\" eventresult=\"1\" " 1166 "diffresult=\"0\" differrorcat=\"2\" " 1167 "differrorcode=\"14\" diffextracode1=\"305\" " 1168 "previousfp=\"1\" nextfp=\"22\"/>")) 1169 << post_interceptor_->GetRequestsAsString(); 1170 EXPECT_NE( 1171 string::npos, 1172 post_interceptor_->GetRequests()[4].find( 1173 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">" 1174 "<updatecheck /><packages><package fp=\"22\"/></packages></app>")) 1175 << post_interceptor_->GetRequestsAsString(); 1176} 1177 1178class TestResourceController : public content::ResourceController { 1179 public: 1180 virtual void SetThrottle(content::ResourceThrottle* throttle) {} 1181}; 1182 1183content::ResourceThrottle* RequestTestResourceThrottle( 1184 ComponentUpdateService* cus, 1185 TestResourceController* controller, 1186 const char* crx_id) { 1187 net::TestURLRequestContext context; 1188 net::TestURLRequest url_request(GURL("http://foo.example.com/thing.bin"), 1189 net::DEFAULT_PRIORITY, 1190 NULL, 1191 &context); 1192 1193 content::ResourceThrottle* rt = 1194 cus->GetOnDemandUpdater().GetOnDemandResourceThrottle(&url_request, 1195 crx_id); 1196 rt->set_controller_for_testing(controller); 1197 controller->SetThrottle(rt); 1198 return rt; 1199} 1200 1201void RequestAndDeleteResourceThrottle(ComponentUpdateService* cus, 1202 const char* crx_id) { 1203 // By requesting a throttle and deleting it immediately we ensure that we 1204 // hit the case where the component updater tries to use the weak 1205 // pointer to a dead Resource throttle. 1206 class NoCallResourceController : public TestResourceController { 1207 public: 1208 virtual ~NoCallResourceController() {} 1209 virtual void Cancel() OVERRIDE { CHECK(false); } 1210 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); } 1211 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); } 1212 virtual void Resume() OVERRIDE { CHECK(false); } 1213 } controller; 1214 1215 delete RequestTestResourceThrottle(cus, &controller, crx_id); 1216} 1217 1218TEST_F(ComponentUpdaterTest, ResourceThrottleDeletedNoUpdate) { 1219 MockServiceObserver observer; 1220 { 1221 InSequence seq; 1222 EXPECT_CALL(observer, 1223 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1224 .Times(1); 1225 EXPECT_CALL(observer, 1226 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1227 "abagagagagagagagagagagagagagagag")) 1228 .Times(1); 1229 EXPECT_CALL(observer, 1230 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1231 .Times(1); 1232 } 1233 1234 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1235 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1236 1237 TestInstaller installer; 1238 CrxComponent com; 1239 component_updater()->AddObserver(&observer); 1240 EXPECT_EQ( 1241 ComponentUpdateService::kOk, 1242 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 1243 // The following two calls ensure that we don't do an update check via the 1244 // timer, so the only update check should be the on-demand one. 1245 test_configurator()->SetInitialDelay(1000000); 1246 test_configurator()->SetRecheckTime(1000000); 1247 test_configurator()->SetLoopCount(1); 1248 component_updater()->Start(); 1249 1250 RunThreadsUntilIdle(); 1251 1252 EXPECT_EQ(0, post_interceptor_->GetHitCount()); 1253 1254 BrowserThread::PostTask(BrowserThread::IO, 1255 FROM_HERE, 1256 base::Bind(&RequestAndDeleteResourceThrottle, 1257 component_updater(), 1258 "abagagagagagagagagagagagagagagag")); 1259 1260 RunThreads(); 1261 1262 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1263 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1264 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1265 1266 component_updater()->Stop(); 1267} 1268 1269class CancelResourceController : public TestResourceController { 1270 public: 1271 CancelResourceController() : throttle_(NULL), resume_called_(0) {} 1272 virtual ~CancelResourceController() { 1273 // Check that the throttle has been resumed by the time we 1274 // exit the test. 1275 CHECK_EQ(1, resume_called_); 1276 delete throttle_; 1277 } 1278 virtual void Cancel() OVERRIDE { CHECK(false); } 1279 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); } 1280 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); } 1281 virtual void Resume() OVERRIDE { 1282 BrowserThread::PostTask(BrowserThread::IO, 1283 FROM_HERE, 1284 base::Bind(&CancelResourceController::ResumeCalled, 1285 base::Unretained(this))); 1286 } 1287 virtual void SetThrottle(content::ResourceThrottle* throttle) OVERRIDE { 1288 throttle_ = throttle; 1289 bool defer = false; 1290 // Initially the throttle is blocked. The CUS needs to run a 1291 // task on the UI thread to decide if it should unblock. 1292 throttle_->WillStartRequest(&defer); 1293 CHECK(defer); 1294 } 1295 1296 private: 1297 void ResumeCalled() { ++resume_called_; } 1298 1299 content::ResourceThrottle* throttle_; 1300 int resume_called_; 1301}; 1302 1303// Tests the on-demand update with resource throttle, including the 1304// cooldown interval between calls. 1305TEST_F(ComponentUpdaterTest, ResourceThrottleLiveNoUpdate) { 1306 MockServiceObserver observer; 1307 { 1308 InSequence seq; 1309 EXPECT_CALL(observer, 1310 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1311 .Times(1); 1312 EXPECT_CALL(observer, 1313 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1314 "abagagagagagagagagagagagagagagag")) 1315 .Times(1); 1316 EXPECT_CALL(observer, 1317 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1318 .Times(1); 1319 EXPECT_CALL(observer, 1320 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1321 .Times(1); 1322 EXPECT_CALL(observer, 1323 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1324 "abagagagagagagagagagagagagagagag")) 1325 .Times(1); 1326 EXPECT_CALL(observer, 1327 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1328 .Times(1); 1329 EXPECT_CALL(observer, 1330 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1331 .Times(1); 1332 } 1333 1334 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1335 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1336 1337 TestInstaller installer; 1338 CrxComponent com; 1339 component_updater()->AddObserver(&observer); 1340 EXPECT_EQ( 1341 ComponentUpdateService::kOk, 1342 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 1343 // The following two calls ensure that we don't do an update check via the 1344 // timer, so the only update check should be the on-demand one. 1345 test_configurator()->SetInitialDelay(1000000); 1346 test_configurator()->SetRecheckTime(1000000); 1347 test_configurator()->SetLoopCount(1); 1348 component_updater()->Start(); 1349 1350 RunThreadsUntilIdle(); 1351 1352 EXPECT_EQ(0, post_interceptor_->GetHitCount()); 1353 1354 { 1355 // First on-demand update check is expected to succeeded. 1356 CancelResourceController controller; 1357 1358 BrowserThread::PostTask( 1359 BrowserThread::IO, 1360 FROM_HERE, 1361 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle), 1362 component_updater(), 1363 &controller, 1364 "abagagagagagagagagagagagagagagag")); 1365 1366 RunThreads(); 1367 1368 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1369 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1370 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1371 1372 component_updater()->Stop(); 1373 } 1374 1375 { 1376 // Second on-demand update check is expected to succeed as well, since there 1377 // is no cooldown interval between calls, due to calling SetOnDemandTime. 1378 test_configurator()->SetOnDemandTime(0); 1379 test_configurator()->SetLoopCount(1); 1380 component_updater()->Start(); 1381 1382 CancelResourceController controller; 1383 1384 BrowserThread::PostTask( 1385 BrowserThread::IO, 1386 FROM_HERE, 1387 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle), 1388 component_updater(), 1389 &controller, 1390 "abagagagagagagagagagagagagagagag")); 1391 1392 RunThreads(); 1393 1394 EXPECT_EQ(1, post_interceptor_->GetHitCount()); 1395 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error()); 1396 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count()); 1397 1398 component_updater()->Stop(); 1399 } 1400 1401 { 1402 // This on-demand call is expected not to trigger a component update check. 1403 test_configurator()->SetOnDemandTime(1000000); 1404 component_updater()->Start(); 1405 1406 CancelResourceController controller; 1407 1408 BrowserThread::PostTask( 1409 BrowserThread::IO, 1410 FROM_HERE, 1411 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle), 1412 component_updater(), 1413 &controller, 1414 "abagagagagagagagagagagagagagagag")); 1415 RunThreadsUntilIdle(); 1416 } 1417} 1418 1419// Tests adding and removing observers. 1420TEST_F(ComponentUpdaterTest, Observer) { 1421 MockServiceObserver observer1, observer2; 1422 1423 // Expect that two observers see the events. 1424 { 1425 InSequence seq; 1426 EXPECT_CALL(observer1, 1427 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1428 .Times(1); 1429 EXPECT_CALL(observer2, 1430 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1431 .Times(1); 1432 EXPECT_CALL(observer1, 1433 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1434 "abagagagagagagagagagagagagagagag")) 1435 .Times(1); 1436 EXPECT_CALL(observer2, 1437 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1438 "abagagagagagagagagagagagagagagag")) 1439 .Times(1); 1440 EXPECT_CALL(observer1, 1441 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1442 .Times(1); 1443 EXPECT_CALL(observer2, 1444 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1445 .Times(1); 1446 } 1447 1448 EXPECT_TRUE(post_interceptor_->ExpectRequest( 1449 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml"))); 1450 1451 component_updater()->AddObserver(&observer1); 1452 component_updater()->AddObserver(&observer2); 1453 1454 TestInstaller installer; 1455 CrxComponent com; 1456 EXPECT_EQ( 1457 ComponentUpdateService::kOk, 1458 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer)); 1459 test_configurator()->SetLoopCount(1); 1460 component_updater()->Start(); 1461 RunThreads(); 1462 1463 // After removing the first observer, it's only the second observer that 1464 // gets the events. 1465 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1)); 1466 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2)); 1467 { 1468 InSequence seq; 1469 EXPECT_CALL(observer2, 1470 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, "")) 1471 .Times(1); 1472 EXPECT_CALL(observer2, 1473 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED, 1474 "abagagagagagagagagagagagagagagag")) 1475 .Times(1); 1476 EXPECT_CALL(observer2, 1477 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, "")) 1478 .Times(1); 1479 } 1480 1481 component_updater()->RemoveObserver(&observer1); 1482 1483 test_configurator()->SetLoopCount(1); 1484 component_updater()->Start(); 1485 RunThreads(); 1486 1487 // Both observers are removed and no one gets the events. 1488 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1)); 1489 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2)); 1490 component_updater()->RemoveObserver(&observer2); 1491 1492 test_configurator()->SetLoopCount(1); 1493 component_updater()->Start(); 1494 RunThreads(); 1495 1496 component_updater()->Stop(); 1497} 1498 1499} // namespace component_updater 1500