1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "chrome/browser/component_updater/test/component_updater_service_unittest.h"
8 #include "base/file_util.h"
9 #include "base/path_service.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/values.h"
15 #include "chrome/browser/component_updater/component_updater_resource_throttle.h"
16 #include "chrome/browser/component_updater/component_updater_utils.h"
17 #include "chrome/browser/component_updater/test/test_configurator.h"
18 #include "chrome/browser/component_updater/test/test_installer.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/resource_controller.h"
22 #include "content/public/browser/resource_request_info.h"
23 #include "content/public/browser/resource_throttle.h"
24 #include "libxml/globals.h"
25 #include "net/base/upload_bytes_element_reader.h"
26 #include "net/url_request/url_fetcher.h"
27 #include "net/url_request/url_request_test_util.h"
30 using content::BrowserThread;
33 using ::testing::AnyNumber;
34 using ::testing::InSequence;
35 using ::testing::Mock;
37 namespace component_updater {
39 MockServiceObserver::MockServiceObserver() {
42 MockServiceObserver::~MockServiceObserver() {
45 bool PartialMatch::Match(const std::string& actual) const {
46 return actual.find(expected_) != std::string::npos;
49 InterceptorFactory::InterceptorFactory()
50 : URLRequestPostInterceptorFactory(POST_INTERCEPT_SCHEME,
51 POST_INTERCEPT_HOSTNAME) {
54 InterceptorFactory::~InterceptorFactory() {
57 URLRequestPostInterceptor* InterceptorFactory::CreateInterceptor() {
58 return URLRequestPostInterceptorFactory::CreateInterceptor(
59 base::FilePath::FromUTF8Unsafe(POST_INTERCEPT_PATH));
62 ComponentUpdaterTest::ComponentUpdaterTest()
64 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
65 // The component updater instance under test.
66 test_config_ = new TestConfigurator;
67 component_updater_.reset(ComponentUpdateServiceFactory(test_config_));
69 // The test directory is chrome/test/data/components.
70 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
71 test_data_dir_ = test_data_dir_.AppendASCII("components");
73 net::URLFetcher::SetEnableInterceptionForTests(true);
76 ComponentUpdaterTest::~ComponentUpdaterTest() {
77 net::URLFetcher::SetEnableInterceptionForTests(false);
80 void ComponentUpdaterTest::SetUp() {
81 get_interceptor_.reset(new GetInterceptor);
82 interceptor_factory_.reset(new InterceptorFactory);
83 post_interceptor_ = interceptor_factory_->CreateInterceptor();
84 EXPECT_TRUE(post_interceptor_);
87 void ComponentUpdaterTest::TearDown() {
88 interceptor_factory_.reset();
89 get_interceptor_.reset();
93 ComponentUpdateService* ComponentUpdaterTest::component_updater() {
94 return component_updater_.get();
97 // Makes the full path to a component updater test file.
98 const base::FilePath ComponentUpdaterTest::test_file(const char* file) {
99 return test_data_dir_.AppendASCII(file);
102 TestConfigurator* ComponentUpdaterTest::test_configurator() {
106 ComponentUpdateService::Status ComponentUpdaterTest::RegisterComponent(
108 TestComponents component,
109 const Version& version,
110 TestInstaller* installer) {
111 if (component == kTestComponent_abag) {
112 com->name = "test_abag";
113 com->pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash));
114 } else if (component == kTestComponent_jebg) {
115 com->name = "test_jebg";
116 com->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
118 com->name = "test_ihfo";
119 com->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
121 com->version = version;
122 com->installer = installer;
123 return component_updater_->RegisterComponent(*com);
126 void ComponentUpdaterTest::RunThreads() {
127 base::RunLoop runloop;
128 test_configurator()->SetQuitClosure(runloop.QuitClosure());
131 // Since some tests need to drain currently enqueued tasks such as network
132 // intercepts on the IO thread, run the threads until they are
133 // idle. The component updater service won't loop again until the loop count
134 // is set and the service is started.
135 RunThreadsUntilIdle();
138 void ComponentUpdaterTest::RunThreadsUntilIdle() {
139 base::RunLoop().RunUntilIdle();
142 ComponentUpdateService::Status OnDemandTester::OnDemand(
143 ComponentUpdateService* cus,
144 const std::string& component_id) {
145 return cus->GetOnDemandUpdater().OnDemandUpdate(component_id);
148 // Verify that our test fixture work and the component updater can
149 // be created and destroyed with no side effects.
150 TEST_F(ComponentUpdaterTest, VerifyFixture) {
151 EXPECT_TRUE(component_updater() != NULL);
154 // Verify that the component updater can be caught in a quick
155 // start-shutdown situation. Failure of this test will be a crash.
156 TEST_F(ComponentUpdaterTest, StartStop) {
157 component_updater()->Start();
158 RunThreadsUntilIdle();
159 component_updater()->Stop();
162 // Verify that when the server has no updates, we go back to sleep and
163 // the COMPONENT_UPDATER_STARTED and COMPONENT_UPDATER_SLEEPING notifications
164 // are generated. No pings are sent.
165 TEST_F(ComponentUpdaterTest, CheckCrxSleep) {
166 MockServiceObserver observer;
168 EXPECT_CALL(observer,
169 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
171 EXPECT_CALL(observer,
172 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
174 EXPECT_CALL(observer,
175 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
176 "abagagagagagagagagagagagagagagag"))
179 EXPECT_TRUE(post_interceptor_->ExpectRequest(
180 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
181 EXPECT_TRUE(post_interceptor_->ExpectRequest(
182 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
184 TestInstaller installer;
186 component_updater()->AddObserver(&observer);
188 ComponentUpdateService::kOk,
189 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
191 // We loop twice, but there are no updates so we expect two sleep messages.
192 test_configurator()->SetLoopCount(2);
193 component_updater()->Start();
196 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
197 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
199 // Expect to see the two update check requests and no other requests,
201 EXPECT_EQ(2, post_interceptor_->GetHitCount())
202 << post_interceptor_->GetRequestsAsString();
203 EXPECT_EQ(2, post_interceptor_->GetCount())
204 << post_interceptor_->GetRequestsAsString();
207 post_interceptor_->GetRequests()[0].find(
208 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
209 "<updatecheck /></app>"))
210 << post_interceptor_->GetRequestsAsString();
213 post_interceptor_->GetRequests()[1].find(
214 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
215 "<updatecheck /></app>"))
216 << post_interceptor_->GetRequestsAsString();
218 component_updater()->Stop();
220 // Loop twice again but this case we simulate a server error by returning
221 // an empty file. Expect the behavior of the service to be the same as before.
222 EXPECT_CALL(observer, OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
224 EXPECT_CALL(observer,
225 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
227 EXPECT_CALL(observer,
228 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
229 "abagagagagagagagagagagagagagagag"))
232 post_interceptor_->Reset();
233 EXPECT_TRUE(post_interceptor_->ExpectRequest(
234 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
235 EXPECT_TRUE(post_interceptor_->ExpectRequest(
236 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
238 test_configurator()->SetLoopCount(2);
239 component_updater()->Start();
242 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
243 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
245 EXPECT_EQ(2, post_interceptor_->GetHitCount())
246 << post_interceptor_->GetRequestsAsString();
247 EXPECT_EQ(2, post_interceptor_->GetCount())
248 << post_interceptor_->GetRequestsAsString();
251 post_interceptor_->GetRequests()[0].find(
252 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
253 "<updatecheck /></app>"))
254 << post_interceptor_->GetRequestsAsString();
257 post_interceptor_->GetRequests()[1].find(
258 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
259 "<updatecheck /></app>"))
260 << post_interceptor_->GetRequestsAsString();
262 component_updater()->Stop();
265 // Verify that we can check for updates and install one component. Besides
266 // the notifications above COMPONENT_UPDATE_FOUND and COMPONENT_UPDATE_READY
267 // should have been fired. We do two loops so the second time around there
268 // should be nothing left to do.
269 // We also check that the following network requests are issued:
273 // 4- second update check.
274 TEST_F(ComponentUpdaterTest, InstallCrx) {
275 MockServiceObserver observer;
278 EXPECT_CALL(observer,
279 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
281 EXPECT_CALL(observer,
282 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
283 "jebgalgnebhfojomionfpkfelancnnkf"))
285 EXPECT_CALL(observer,
286 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
287 "abagagagagagagagagagagagagagagag"))
289 EXPECT_CALL(observer,
290 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
291 "jebgalgnebhfojomionfpkfelancnnkf"))
293 EXPECT_CALL(observer,
294 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
295 "jebgalgnebhfojomionfpkfelancnnkf"))
297 EXPECT_CALL(observer,
298 OnEvent(ServiceObserver::COMPONENT_UPDATED,
299 "jebgalgnebhfojomionfpkfelancnnkf"))
301 EXPECT_CALL(observer,
302 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
304 EXPECT_CALL(observer,
305 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
306 "jebgalgnebhfojomionfpkfelancnnkf"))
308 EXPECT_CALL(observer,
309 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
310 "abagagagagagagagagagagagagagagag"))
312 EXPECT_CALL(observer,
313 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
317 EXPECT_TRUE(post_interceptor_->ExpectRequest(
318 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
319 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
320 EXPECT_TRUE(post_interceptor_->ExpectRequest(
321 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
323 get_interceptor_->SetResponse(
324 GURL(expected_crx_url),
325 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
327 component_updater()->AddObserver(&observer);
329 TestInstaller installer1;
331 RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1);
332 TestInstaller installer2;
334 RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2);
336 test_configurator()->SetLoopCount(2);
337 component_updater()->Start();
340 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error());
341 EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count());
342 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error());
343 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count());
345 // Expect three request in total: two update checks and one ping.
346 EXPECT_EQ(3, post_interceptor_->GetHitCount())
347 << post_interceptor_->GetRequestsAsString();
348 EXPECT_EQ(3, post_interceptor_->GetCount())
349 << post_interceptor_->GetRequestsAsString();
351 // Expect one component download.
352 EXPECT_EQ(1, get_interceptor_->GetHitCount());
356 post_interceptor_->GetRequests()[0].find(
357 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
358 "<updatecheck /></app>"))
359 << post_interceptor_->GetRequestsAsString();
362 post_interceptor_->GetRequests()[0].find(
363 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
364 "<updatecheck /></app>"))
365 << post_interceptor_->GetRequestsAsString();
369 post_interceptor_->GetRequests()[1].find(
370 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
371 "version=\"0.9\" nextversion=\"1.0\">"
372 "<event eventtype=\"3\" eventresult=\"1\"/>"))
373 << post_interceptor_->GetRequestsAsString();
377 post_interceptor_->GetRequests()[2].find(
378 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
379 "<updatecheck /></app>"));
382 post_interceptor_->GetRequests()[2].find(
383 "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
384 "<updatecheck /></app>"))
385 << post_interceptor_->GetRequestsAsString();
387 // Test the protocol version is correct and the extra request attributes
388 // are included in the request.
391 post_interceptor_->GetRequests()[0].find(
392 "request protocol=\"3.0\" extra=\"foo\""))
393 << post_interceptor_->GetRequestsAsString();
395 // Tokenize the request string to look for specific attributes, which
396 // are important for backward compatibility with the version v2 of the update
397 // protocol. In this case, inspect the <request>, which is the first element
398 // after the xml declaration of the update request body.
399 // Expect to find the |os|, |arch|, |prodchannel|, and |prodversion|
401 // <?xml version="1.0" encoding="UTF-8"?>
402 // <request... os=... arch=... prodchannel=... prodversion=...>
405 const std::string update_request(post_interceptor_->GetRequests()[0]);
406 std::vector<base::StringPiece> elements;
407 Tokenize(update_request, "<>", &elements);
408 EXPECT_NE(string::npos, elements[1].find(" os="));
409 EXPECT_NE(string::npos, elements[1].find(" arch="));
410 EXPECT_NE(string::npos, elements[1].find(" prodchannel="));
411 EXPECT_NE(string::npos, elements[1].find(" prodversion="));
413 // Look for additional attributes of the request, such as |version|,
414 // |requestid|, |lang|, and |nacl_arch|.
415 EXPECT_NE(string::npos, elements[1].find(" version="));
416 EXPECT_NE(string::npos, elements[1].find(" requestid="));
417 EXPECT_NE(string::npos, elements[1].find(" lang="));
418 EXPECT_NE(string::npos, elements[1].find(" nacl_arch="));
420 component_updater()->Stop();
423 // This test checks that the "prodversionmin" value is handled correctly. In
424 // particular there should not be an install because the minimum product
425 // version is much higher than of chrome.
426 TEST_F(ComponentUpdaterTest, ProdVersionCheck) {
427 EXPECT_TRUE(post_interceptor_->ExpectRequest(
428 new PartialMatch("updatecheck"), test_file("updatecheck_reply_2.xml")));
430 get_interceptor_->SetResponse(
431 GURL(expected_crx_url),
432 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
434 TestInstaller installer;
436 RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer);
438 test_configurator()->SetLoopCount(1);
439 component_updater()->Start();
442 // Expect one update check and no ping.
443 EXPECT_EQ(1, post_interceptor_->GetHitCount())
444 << post_interceptor_->GetRequestsAsString();
445 EXPECT_EQ(1, post_interceptor_->GetCount())
446 << post_interceptor_->GetRequestsAsString();
448 // Expect no download to occur.
449 EXPECT_EQ(0, get_interceptor_->GetHitCount());
451 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
452 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
454 component_updater()->Stop();
457 // Test that a update check due to an on demand call can cause installs.
458 // Here is the timeline:
459 // - First loop: we return a reply that indicates no update, so
461 // - We make an on demand call.
462 // - This triggers a second loop, which has a reply that triggers an install.
463 #if defined(OS_LINUX)
464 // http://crbug.com/396488
465 #define MAYBE_OnDemandUpdate DISABLED_OnDemandUpdate
467 #define MAYBE_OnDemandUpdate OnDemandUpdate
469 TEST_F(ComponentUpdaterTest, MAYBE_OnDemandUpdate) {
470 MockServiceObserver observer;
473 EXPECT_CALL(observer,
474 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
476 EXPECT_CALL(observer,
477 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
478 "abagagagagagagagagagagagagagagag"))
480 EXPECT_CALL(observer,
481 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
482 "jebgalgnebhfojomionfpkfelancnnkf"))
484 EXPECT_CALL(observer,
485 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
487 EXPECT_CALL(observer,
488 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
490 EXPECT_CALL(observer,
491 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
492 "jebgalgnebhfojomionfpkfelancnnkf"))
494 EXPECT_CALL(observer,
495 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
496 "abagagagagagagagagagagagagagagag"))
498 EXPECT_CALL(observer,
499 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
500 "jebgalgnebhfojomionfpkfelancnnkf"))
502 EXPECT_CALL(observer,
503 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
504 "jebgalgnebhfojomionfpkfelancnnkf"))
506 EXPECT_CALL(observer,
507 OnEvent(ServiceObserver::COMPONENT_UPDATED,
508 "jebgalgnebhfojomionfpkfelancnnkf"))
510 EXPECT_CALL(observer,
511 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
515 EXPECT_TRUE(post_interceptor_->ExpectRequest(
516 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
518 get_interceptor_->SetResponse(
519 GURL(expected_crx_url),
520 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
522 component_updater()->AddObserver(&observer);
524 TestInstaller installer1;
526 RegisterComponent(&com1, kTestComponent_abag, Version("2.2"), &installer1);
527 TestInstaller installer2;
529 RegisterComponent(&com2, kTestComponent_jebg, Version("0.9"), &installer2);
531 // No update normally.
532 test_configurator()->SetLoopCount(1);
533 component_updater()->Start();
535 component_updater()->Stop();
537 EXPECT_EQ(1, post_interceptor_->GetHitCount())
538 << post_interceptor_->GetRequestsAsString();
539 EXPECT_EQ(1, post_interceptor_->GetCount())
540 << post_interceptor_->GetRequestsAsString();
542 EXPECT_EQ(0, get_interceptor_->GetHitCount());
544 // Update after an on-demand check is issued.
545 post_interceptor_->Reset();
546 EXPECT_TRUE(post_interceptor_->ExpectRequest(
547 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
548 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
551 ComponentUpdateService::kOk,
552 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
553 test_configurator()->SetLoopCount(1);
554 component_updater()->Start();
557 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error());
558 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count());
559 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error());
560 EXPECT_EQ(1, static_cast<TestInstaller*>(com2.installer)->install_count());
562 EXPECT_EQ(2, post_interceptor_->GetHitCount())
563 << post_interceptor_->GetRequestsAsString();
564 EXPECT_EQ(2, post_interceptor_->GetCount())
565 << post_interceptor_->GetRequestsAsString();
567 EXPECT_EQ(1, get_interceptor_->GetHitCount());
569 // Expect the update check to contain an "ondemand" request for the
570 // second component (com2) and a normal request for the other component.
573 post_interceptor_->GetRequests()[0].find(
574 "<app appid=\"abagagagagagagagagagagagagagagag\" "
575 "version=\"2.2\"><updatecheck /></app>"))
576 << post_interceptor_->GetRequestsAsString();
579 post_interceptor_->GetRequests()[0].find(
580 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
581 "version=\"0.9\" installsource=\"ondemand\"><updatecheck /></app>"))
582 << post_interceptor_->GetRequestsAsString();
585 post_interceptor_->GetRequests()[1].find(
586 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
587 "version=\"0.9\" nextversion=\"1.0\">"
588 "<event eventtype=\"3\" eventresult=\"1\"/>"))
589 << post_interceptor_->GetRequestsAsString();
591 // Also check what happens if previous check too soon. It works, since this
592 // direct OnDemand call does not implement a cooldown.
593 test_configurator()->SetOnDemandTime(60 * 60);
595 ComponentUpdateService::kOk,
596 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
597 // Okay, now reset to 0 for the other tests.
598 test_configurator()->SetOnDemandTime(0);
599 component_updater()->Stop();
601 // Test a few error cases. NOTE: We don't have callbacks for
602 // when the updates failed yet.
603 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
606 EXPECT_CALL(observer,
607 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
609 EXPECT_CALL(observer,
610 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
611 "abagagagagagagagagagagagagagagag"))
613 EXPECT_CALL(observer,
614 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
615 "jebgalgnebhfojomionfpkfelancnnkf"))
617 EXPECT_CALL(observer,
618 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
622 // No update: error from no server response
623 post_interceptor_->Reset();
624 EXPECT_TRUE(post_interceptor_->ExpectRequest(
625 new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
627 test_configurator()->SetLoopCount(1);
628 component_updater()->Start();
630 ComponentUpdateService::kOk,
631 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
633 component_updater()->Stop();
635 EXPECT_EQ(1, post_interceptor_->GetHitCount())
636 << post_interceptor_->GetRequestsAsString();
637 EXPECT_EQ(1, post_interceptor_->GetCount())
638 << post_interceptor_->GetRequestsAsString();
640 // No update: already updated to 1.0 so nothing new
641 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
644 EXPECT_CALL(observer,
645 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
647 EXPECT_CALL(observer,
648 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
649 "jebgalgnebhfojomionfpkfelancnnkf"))
651 EXPECT_CALL(observer,
652 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
653 "abagagagagagagagagagagagagagagag"))
655 EXPECT_CALL(observer,
656 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
660 post_interceptor_->Reset();
661 EXPECT_TRUE(post_interceptor_->ExpectRequest(
662 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
664 test_configurator()->SetLoopCount(1);
665 component_updater()->Start();
667 ComponentUpdateService::kOk,
668 OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
671 EXPECT_EQ(1, post_interceptor_->GetHitCount())
672 << post_interceptor_->GetRequestsAsString();
673 EXPECT_EQ(1, post_interceptor_->GetCount())
674 << post_interceptor_->GetRequestsAsString();
676 component_updater()->Stop();
679 // Verify that a previously registered component can get re-registered
680 // with a different version.
681 TEST_F(ComponentUpdaterTest, CheckReRegistration) {
682 MockServiceObserver observer;
685 EXPECT_CALL(observer,
686 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
688 EXPECT_CALL(observer,
689 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
690 "jebgalgnebhfojomionfpkfelancnnkf"))
692 EXPECT_CALL(observer,
693 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
694 "abagagagagagagagagagagagagagagag"))
696 EXPECT_CALL(observer,
697 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
698 "jebgalgnebhfojomionfpkfelancnnkf"))
700 EXPECT_CALL(observer,
701 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
702 "jebgalgnebhfojomionfpkfelancnnkf"))
704 EXPECT_CALL(observer,
705 OnEvent(ServiceObserver::COMPONENT_UPDATED,
706 "jebgalgnebhfojomionfpkfelancnnkf"))
708 EXPECT_CALL(observer,
709 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
711 EXPECT_CALL(observer,
712 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
713 "jebgalgnebhfojomionfpkfelancnnkf"))
715 EXPECT_CALL(observer,
716 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
717 "abagagagagagagagagagagagagagagag"))
719 EXPECT_CALL(observer,
720 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
724 EXPECT_TRUE(post_interceptor_->ExpectRequest(
725 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
726 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
727 EXPECT_TRUE(post_interceptor_->ExpectRequest(
728 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
730 get_interceptor_->SetResponse(
731 GURL(expected_crx_url),
732 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
734 component_updater()->AddObserver(&observer);
736 TestInstaller installer1;
738 RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1);
739 TestInstaller installer2;
741 RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2);
743 // Loop twice to issue two checks: (1) with original 0.9 version, update to
744 // 1.0, and do the second check (2) with the updated 1.0 version.
745 test_configurator()->SetLoopCount(2);
746 component_updater()->Start();
749 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error());
750 EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count());
751 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error());
752 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count());
754 EXPECT_EQ(3, post_interceptor_->GetHitCount())
755 << post_interceptor_->GetRequestsAsString();
756 EXPECT_EQ(1, get_interceptor_->GetHitCount());
760 post_interceptor_->GetRequests()[0].find(
761 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
762 "<updatecheck /></app>"))
763 << post_interceptor_->GetRequestsAsString();
766 post_interceptor_->GetRequests()[1].find(
767 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
768 "version=\"0.9\" nextversion=\"1.0\">"
769 "<event eventtype=\"3\" eventresult=\"1\"/>"))
770 << post_interceptor_->GetRequestsAsString();
773 post_interceptor_->GetRequests()[2].find(
774 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
775 "<updatecheck /></app>"))
776 << post_interceptor_->GetRequestsAsString();
778 component_updater()->Stop();
780 // Now re-register, pretending to be an even newer version (2.2)
781 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
784 EXPECT_CALL(observer,
785 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
787 EXPECT_CALL(observer,
788 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
789 "jebgalgnebhfojomionfpkfelancnnkf"))
791 EXPECT_CALL(observer,
792 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
793 "abagagagagagagagagagagagagagagag"))
795 EXPECT_CALL(observer,
796 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
800 post_interceptor_->Reset();
801 EXPECT_TRUE(post_interceptor_->ExpectRequest(
802 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
804 TestInstaller installer3;
805 EXPECT_EQ(ComponentUpdateService::kReplaced,
807 &com1, kTestComponent_jebg, Version("2.2"), &installer3));
809 // Loop once just to notice the check happening with the re-register version.
810 test_configurator()->SetLoopCount(1);
811 component_updater()->Start();
814 // We created a new installer, so the counts go back to 0.
815 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error());
816 EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count());
817 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error());
818 EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count());
820 // One update check and no additional pings are expected.
821 EXPECT_EQ(1, post_interceptor_->GetHitCount())
822 << post_interceptor_->GetRequestsAsString();
823 EXPECT_EQ(1, post_interceptor_->GetCount())
824 << post_interceptor_->GetRequestsAsString();
828 post_interceptor_->GetRequests()[0].find(
829 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"2.2\">"
830 "<updatecheck /></app>"));
832 component_updater()->Stop();
835 // Verify that we can download and install a component and a differential
836 // update to that component. We do three loops; the final loop should do
838 // We also check that exactly 5 non-ping network requests are issued:
839 // 1- update check (response: v1 available)
840 // 2- download crx (v1)
841 // 3- update check (response: v2 available)
842 // 4- download differential crx (v1 to v2)
843 // 5- update check (response: no further update available)
844 // There should be two pings, one for each update. The second will bear a
845 // diffresult=1, while the first will not.
846 TEST_F(ComponentUpdaterTest, DifferentialUpdate) {
847 EXPECT_TRUE(post_interceptor_->ExpectRequest(
848 new PartialMatch("updatecheck"),
849 test_file("updatecheck_diff_reply_1.xml")));
850 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
851 EXPECT_TRUE(post_interceptor_->ExpectRequest(
852 new PartialMatch("updatecheck"),
853 test_file("updatecheck_diff_reply_2.xml")));
854 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
855 EXPECT_TRUE(post_interceptor_->ExpectRequest(
856 new PartialMatch("updatecheck"),
857 test_file("updatecheck_diff_reply_3.xml")));
859 get_interceptor_->SetResponse(
860 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"),
861 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"));
862 get_interceptor_->SetResponse(
863 GURL("http://localhost/download/"
864 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"),
865 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"));
867 VersionedTestInstaller installer;
869 RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer);
871 test_configurator()->SetLoopCount(3);
872 component_updater()->Start();
875 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
876 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
878 EXPECT_EQ(5, post_interceptor_->GetHitCount())
879 << post_interceptor_->GetRequestsAsString();
880 EXPECT_EQ(5, post_interceptor_->GetCount())
881 << post_interceptor_->GetRequestsAsString();
882 EXPECT_EQ(2, get_interceptor_->GetHitCount());
886 post_interceptor_->GetRequests()[0].find(
887 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
888 "<updatecheck /></app>"))
889 << post_interceptor_->GetRequestsAsString();
892 post_interceptor_->GetRequests()[1].find(
893 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
894 "version=\"0.0\" nextversion=\"1.0\">"
895 "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>"))
896 << post_interceptor_->GetRequestsAsString();
899 post_interceptor_->GetRequests()[2].find(
900 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
901 "<updatecheck /><packages><package fp=\"1\"/></packages></app>"))
902 << post_interceptor_->GetRequestsAsString();
905 post_interceptor_->GetRequests()[3].find(
906 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
907 "version=\"1.0\" nextversion=\"2.0\">"
908 "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"1\" "
909 "previousfp=\"1\" nextfp=\"22\"/>"))
910 << post_interceptor_->GetRequestsAsString();
913 post_interceptor_->GetRequests()[4].find(
914 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
915 "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
916 << post_interceptor_->GetRequestsAsString();
917 component_updater()->Stop();
920 // Verify that component installation falls back to downloading and installing
921 // a full update if the differential update fails (in this case, because the
922 // installer does not know about the existing files). We do two loops; the final
923 // loop should do nothing.
924 // We also check that exactly 4 non-ping network requests are issued:
925 // 1- update check (loop 1)
926 // 2- download differential crx
927 // 3- download full crx
928 // 4- update check (loop 2 - no update available)
929 // There should be one ping for the first attempted update.
930 // This test is flaky on Android. crbug.com/329883
931 #if defined(OS_ANDROID)
932 #define MAYBE_DifferentialUpdateFails DISABLED_DifferentialUpdateFails
934 #define MAYBE_DifferentialUpdateFails DifferentialUpdateFails
936 TEST_F(ComponentUpdaterTest, MAYBE_DifferentialUpdateFails) {
937 EXPECT_TRUE(post_interceptor_->ExpectRequest(
938 new PartialMatch("updatecheck"),
939 test_file("updatecheck_diff_reply_2.xml")));
940 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
941 EXPECT_TRUE(post_interceptor_->ExpectRequest(
942 new PartialMatch("updatecheck"),
943 test_file("updatecheck_diff_reply_3.xml")));
945 get_interceptor_->SetResponse(
946 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"),
947 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"));
948 get_interceptor_->SetResponse(
949 GURL("http://localhost/download/"
950 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"),
951 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"));
952 get_interceptor_->SetResponse(
953 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"),
954 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"));
956 TestInstaller installer;
958 RegisterComponent(&com, kTestComponent_ihfo, Version("1.0"), &installer);
960 test_configurator()->SetLoopCount(2);
961 component_updater()->Start();
964 // A failed differential update does not count as a failed install.
965 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
966 EXPECT_EQ(1, static_cast<TestInstaller*>(com.installer)->install_count());
968 EXPECT_EQ(3, post_interceptor_->GetHitCount())
969 << post_interceptor_->GetRequestsAsString();
970 EXPECT_EQ(3, post_interceptor_->GetCount())
971 << post_interceptor_->GetRequestsAsString();
972 EXPECT_EQ(2, get_interceptor_->GetHitCount());
976 post_interceptor_->GetRequests()[0].find(
977 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
978 "<updatecheck /></app>"))
979 << post_interceptor_->GetRequestsAsString();
982 post_interceptor_->GetRequests()[1].find(
983 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
984 "version=\"1.0\" nextversion=\"2.0\">"
985 "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"0\" "
986 "differrorcat=\"2\" differrorcode=\"16\" nextfp=\"22\"/>"))
987 << post_interceptor_->GetRequestsAsString();
990 post_interceptor_->GetRequests()[2].find(
991 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
992 "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
993 << post_interceptor_->GetRequestsAsString();
995 component_updater()->Stop();
998 // Test is flakey on Android bots. See crbug.com/331420.
999 #if defined(OS_ANDROID)
1000 #define MAYBE_CheckFailedInstallPing DISABLED_CheckFailedInstallPing
1002 #define MAYBE_CheckFailedInstallPing CheckFailedInstallPing
1004 // Verify that a failed installation causes an install failure ping.
1005 TEST_F(ComponentUpdaterTest, MAYBE_CheckFailedInstallPing) {
1006 // This test installer reports installation failure.
1007 class : public TestInstaller {
1008 virtual bool Install(const base::DictionaryValue& manifest,
1009 const base::FilePath& unpack_path) OVERRIDE {
1011 base::DeleteFile(unpack_path, true);
1016 EXPECT_TRUE(post_interceptor_->ExpectRequest(
1017 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
1018 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
1019 EXPECT_TRUE(post_interceptor_->ExpectRequest(
1020 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
1021 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
1022 get_interceptor_->SetResponse(
1023 GURL(expected_crx_url),
1024 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
1026 // Start with 0.9, and attempt update to 1.0.
1027 // Loop twice to issue two checks: (1) with original 0.9 version
1028 // and (2), which should retry with 0.9.
1030 RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer);
1032 test_configurator()->SetLoopCount(2);
1033 component_updater()->Start();
1036 EXPECT_EQ(4, post_interceptor_->GetHitCount())
1037 << post_interceptor_->GetRequestsAsString();
1038 EXPECT_EQ(2, get_interceptor_->GetHitCount());
1042 post_interceptor_->GetRequests()[0].find(
1043 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
1044 "<updatecheck /></app>"))
1045 << post_interceptor_->GetRequestsAsString();
1048 post_interceptor_->GetRequests()[1].find(
1049 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
1050 "version=\"0.9\" nextversion=\"1.0\">"
1051 "<event eventtype=\"3\" eventresult=\"0\" "
1052 "errorcat=\"3\" errorcode=\"9\"/>"))
1053 << post_interceptor_->GetRequestsAsString();
1056 post_interceptor_->GetRequests()[2].find(
1057 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
1058 "<updatecheck /></app>"))
1059 << post_interceptor_->GetRequestsAsString();
1062 post_interceptor_->GetRequests()[3].find(
1063 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
1064 "version=\"0.9\" nextversion=\"1.0\">"
1065 "<event eventtype=\"3\" eventresult=\"0\" "
1066 "errorcat=\"3\" errorcode=\"9\"/>"))
1067 << post_interceptor_->GetRequestsAsString();
1069 // Loop once more, but expect no ping because a noupdate response is issued.
1070 // This is necessary to clear out the fire-and-forget ping from the previous
1072 post_interceptor_->Reset();
1073 EXPECT_TRUE(post_interceptor_->ExpectRequest(
1074 new PartialMatch("updatecheck"),
1075 test_file("updatecheck_reply_noupdate.xml")));
1077 test_configurator()->SetLoopCount(1);
1078 component_updater()->Start();
1081 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
1082 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
1084 EXPECT_EQ(1, post_interceptor_->GetHitCount())
1085 << post_interceptor_->GetRequestsAsString();
1086 EXPECT_EQ(1, post_interceptor_->GetCount())
1087 << post_interceptor_->GetRequestsAsString();
1091 post_interceptor_->GetRequests()[0].find(
1092 "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
1093 "<updatecheck /></app>"))
1094 << post_interceptor_->GetRequestsAsString();
1096 component_updater()->Stop();
1099 // Verify that we successfully propagate a patcher error.
1100 // ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx contains an incorrect
1101 // patching instruction that should fail.
1102 TEST_F(ComponentUpdaterTest, DifferentialUpdateFailErrorcode) {
1103 EXPECT_TRUE(post_interceptor_->ExpectRequest(
1104 new PartialMatch("updatecheck"),
1105 test_file("updatecheck_diff_reply_1.xml")));
1106 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
1107 EXPECT_TRUE(post_interceptor_->ExpectRequest(
1108 new PartialMatch("updatecheck"),
1109 test_file("updatecheck_diff_reply_2.xml")));
1110 EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
1111 EXPECT_TRUE(post_interceptor_->ExpectRequest(
1112 new PartialMatch("updatecheck"),
1113 test_file("updatecheck_diff_reply_3.xml")));
1115 get_interceptor_->SetResponse(
1116 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"),
1117 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"));
1118 // This intercept returns a different file than what is specified in the
1119 // update check response and requested in the download. The file that is
1120 // actually dowloaded contains a patching error, an therefore, an error
1121 // is injected at the time of patching.
1122 get_interceptor_->SetResponse(
1123 GURL("http://localhost/download/"
1124 "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"),
1125 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx"));
1126 get_interceptor_->SetResponse(
1127 GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"),
1128 test_file("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"));
1130 VersionedTestInstaller installer;
1132 RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer);
1134 test_configurator()->SetLoopCount(3);
1135 component_updater()->Start();
1137 component_updater()->Stop();
1139 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
1140 EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
1142 EXPECT_EQ(5, post_interceptor_->GetHitCount())
1143 << post_interceptor_->GetRequestsAsString();
1144 EXPECT_EQ(5, post_interceptor_->GetCount())
1145 << post_interceptor_->GetRequestsAsString();
1146 EXPECT_EQ(3, get_interceptor_->GetHitCount());
1150 post_interceptor_->GetRequests()[0].find(
1151 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
1152 "<updatecheck /></app>"))
1153 << post_interceptor_->GetRequestsAsString();
1156 post_interceptor_->GetRequests()[1].find(
1157 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
1158 "version=\"0.0\" nextversion=\"1.0\">"
1159 "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>"))
1160 << post_interceptor_->GetRequestsAsString();
1163 post_interceptor_->GetRequests()[2].find(
1164 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
1165 "<updatecheck /><packages><package fp=\"1\"/></packages></app>"))
1166 << post_interceptor_->GetRequestsAsString();
1169 post_interceptor_->GetRequests()[3].find(
1170 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
1171 "version=\"1.0\" nextversion=\"2.0\">"
1172 "<event eventtype=\"3\" eventresult=\"1\" "
1173 "diffresult=\"0\" differrorcat=\"2\" "
1174 "differrorcode=\"14\" diffextracode1=\"305\" "
1175 "previousfp=\"1\" nextfp=\"22\"/>"))
1176 << post_interceptor_->GetRequestsAsString();
1179 post_interceptor_->GetRequests()[4].find(
1180 "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
1181 "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
1182 << post_interceptor_->GetRequestsAsString();
1185 class TestResourceController : public content::ResourceController {
1187 virtual void SetThrottle(content::ResourceThrottle* throttle) {}
1190 content::ResourceThrottle* RequestTestResourceThrottle(
1191 ComponentUpdateService* cus,
1192 TestResourceController* controller,
1193 const char* crx_id) {
1194 net::TestURLRequestContext context;
1195 net::TestURLRequest url_request(GURL("http://foo.example.com/thing.bin"),
1196 net::DEFAULT_PRIORITY,
1200 content::ResourceThrottle* rt = GetOnDemandResourceThrottle(cus, crx_id);
1201 rt->set_controller_for_testing(controller);
1202 controller->SetThrottle(rt);
1206 void RequestAndDeleteResourceThrottle(ComponentUpdateService* cus,
1207 const char* crx_id) {
1208 // By requesting a throttle and deleting it immediately we ensure that we
1209 // hit the case where the component updater tries to use the weak
1210 // pointer to a dead Resource throttle.
1211 class NoCallResourceController : public TestResourceController {
1213 virtual ~NoCallResourceController() {}
1214 virtual void Cancel() OVERRIDE { CHECK(false); }
1215 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); }
1216 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); }
1217 virtual void Resume() OVERRIDE { CHECK(false); }
1220 delete RequestTestResourceThrottle(cus, &controller, crx_id);
1223 TEST_F(ComponentUpdaterTest, ResourceThrottleDeletedNoUpdate) {
1224 MockServiceObserver observer;
1227 EXPECT_CALL(observer,
1228 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1230 EXPECT_CALL(observer,
1231 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1232 "abagagagagagagagagagagagagagagag"))
1234 EXPECT_CALL(observer,
1235 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1239 EXPECT_TRUE(post_interceptor_->ExpectRequest(
1240 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
1242 TestInstaller installer;
1244 component_updater()->AddObserver(&observer);
1246 ComponentUpdateService::kOk,
1247 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
1248 // The following two calls ensure that we don't do an update check via the
1249 // timer, so the only update check should be the on-demand one.
1250 test_configurator()->SetInitialDelay(1000000);
1251 test_configurator()->SetRecheckTime(1000000);
1252 test_configurator()->SetLoopCount(1);
1253 component_updater()->Start();
1255 RunThreadsUntilIdle();
1257 EXPECT_EQ(0, post_interceptor_->GetHitCount());
1259 BrowserThread::PostTask(BrowserThread::IO,
1261 base::Bind(&RequestAndDeleteResourceThrottle,
1262 component_updater(),
1263 "abagagagagagagagagagagagagagagag"));
1267 EXPECT_EQ(1, post_interceptor_->GetHitCount());
1268 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
1269 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
1271 component_updater()->Stop();
1274 class CancelResourceController : public TestResourceController {
1276 CancelResourceController() : throttle_(NULL), resume_called_(0) {}
1277 virtual ~CancelResourceController() {
1278 // Check that the throttle has been resumed by the time we
1280 CHECK_EQ(1, resume_called_);
1283 virtual void Cancel() OVERRIDE { CHECK(false); }
1284 virtual void CancelAndIgnore() OVERRIDE { CHECK(false); }
1285 virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); }
1286 virtual void Resume() OVERRIDE {
1287 BrowserThread::PostTask(BrowserThread::IO,
1289 base::Bind(&CancelResourceController::ResumeCalled,
1290 base::Unretained(this)));
1292 virtual void SetThrottle(content::ResourceThrottle* throttle) OVERRIDE {
1293 throttle_ = throttle;
1295 // Initially the throttle is blocked. The CUS needs to run a
1296 // task on the UI thread to decide if it should unblock.
1297 throttle_->WillStartRequest(&defer);
1302 void ResumeCalled() { ++resume_called_; }
1304 content::ResourceThrottle* throttle_;
1308 // Tests the on-demand update with resource throttle, including the
1309 // cooldown interval between calls.
1310 TEST_F(ComponentUpdaterTest, ResourceThrottleLiveNoUpdate) {
1311 MockServiceObserver observer;
1314 EXPECT_CALL(observer,
1315 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1317 EXPECT_CALL(observer,
1318 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1319 "abagagagagagagagagagagagagagagag"))
1321 EXPECT_CALL(observer,
1322 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1324 EXPECT_CALL(observer,
1325 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1327 EXPECT_CALL(observer,
1328 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1329 "abagagagagagagagagagagagagagagag"))
1331 EXPECT_CALL(observer,
1332 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1334 EXPECT_CALL(observer,
1335 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1339 EXPECT_TRUE(post_interceptor_->ExpectRequest(
1340 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
1342 TestInstaller installer;
1344 component_updater()->AddObserver(&observer);
1346 ComponentUpdateService::kOk,
1347 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
1348 // The following two calls ensure that we don't do an update check via the
1349 // timer, so the only update check should be the on-demand one.
1350 test_configurator()->SetInitialDelay(1000000);
1351 test_configurator()->SetRecheckTime(1000000);
1352 test_configurator()->SetLoopCount(1);
1353 component_updater()->Start();
1355 RunThreadsUntilIdle();
1357 EXPECT_EQ(0, post_interceptor_->GetHitCount());
1360 // First on-demand update check is expected to succeeded.
1361 CancelResourceController controller;
1363 BrowserThread::PostTask(
1366 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle),
1367 component_updater(),
1369 "abagagagagagagagagagagagagagagag"));
1373 EXPECT_EQ(1, post_interceptor_->GetHitCount());
1374 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
1375 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
1377 component_updater()->Stop();
1381 // Second on-demand update check is expected to succeed as well, since there
1382 // is no cooldown interval between calls, due to calling SetOnDemandTime.
1383 test_configurator()->SetOnDemandTime(0);
1384 test_configurator()->SetLoopCount(1);
1385 component_updater()->Start();
1387 CancelResourceController controller;
1389 BrowserThread::PostTask(
1392 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle),
1393 component_updater(),
1395 "abagagagagagagagagagagagagagagag"));
1399 EXPECT_EQ(1, post_interceptor_->GetHitCount());
1400 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
1401 EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
1403 component_updater()->Stop();
1407 // This on-demand call is expected not to trigger a component update check.
1408 test_configurator()->SetOnDemandTime(1000000);
1409 component_updater()->Start();
1411 CancelResourceController controller;
1413 BrowserThread::PostTask(
1416 base::Bind(base::IgnoreResult(&RequestTestResourceThrottle),
1417 component_updater(),
1419 "abagagagagagagagagagagagagagagag"));
1420 RunThreadsUntilIdle();
1424 // Tests adding and removing observers.
1425 TEST_F(ComponentUpdaterTest, Observer) {
1426 MockServiceObserver observer1, observer2;
1428 // Expect that two observers see the events.
1431 EXPECT_CALL(observer1,
1432 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1434 EXPECT_CALL(observer2,
1435 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1437 EXPECT_CALL(observer1,
1438 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1439 "abagagagagagagagagagagagagagagag"))
1441 EXPECT_CALL(observer2,
1442 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1443 "abagagagagagagagagagagagagagagag"))
1445 EXPECT_CALL(observer1,
1446 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1448 EXPECT_CALL(observer2,
1449 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1453 EXPECT_TRUE(post_interceptor_->ExpectRequest(
1454 new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
1456 component_updater()->AddObserver(&observer1);
1457 component_updater()->AddObserver(&observer2);
1459 TestInstaller installer;
1462 ComponentUpdateService::kOk,
1463 RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
1464 test_configurator()->SetLoopCount(1);
1465 component_updater()->Start();
1468 // After removing the first observer, it's only the second observer that
1470 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
1471 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2));
1474 EXPECT_CALL(observer2,
1475 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1477 EXPECT_CALL(observer2,
1478 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1479 "abagagagagagagagagagagagagagagag"))
1481 EXPECT_CALL(observer2,
1482 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1486 component_updater()->RemoveObserver(&observer1);
1488 test_configurator()->SetLoopCount(1);
1489 component_updater()->Start();
1492 // Both observers are removed and no one gets the events.
1493 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
1494 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2));
1495 component_updater()->RemoveObserver(&observer2);
1497 test_configurator()->SetLoopCount(1);
1498 component_updater()->Start();
1501 component_updater()->Stop();
1504 } // namespace component_updater