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