Upstream version 9.38.198.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 <vector>
6
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"
28 #include "url/gurl.h"
29
30 using content::BrowserThread;
31
32 using ::testing::_;
33 using ::testing::AnyNumber;
34 using ::testing::InSequence;
35 using ::testing::Mock;
36
37 namespace component_updater {
38
39 MockServiceObserver::MockServiceObserver() {
40 }
41
42 MockServiceObserver::~MockServiceObserver() {
43 }
44
45 bool PartialMatch::Match(const std::string& actual) const {
46   return actual.find(expected_) != std::string::npos;
47 }
48
49 InterceptorFactory::InterceptorFactory()
50     : URLRequestPostInterceptorFactory(POST_INTERCEPT_SCHEME,
51                                        POST_INTERCEPT_HOSTNAME) {
52 }
53
54 InterceptorFactory::~InterceptorFactory() {
55 }
56
57 URLRequestPostInterceptor* InterceptorFactory::CreateInterceptor() {
58   return URLRequestPostInterceptorFactory::CreateInterceptor(
59       base::FilePath::FromUTF8Unsafe(POST_INTERCEPT_PATH));
60 }
61
62 ComponentUpdaterTest::ComponentUpdaterTest()
63     : test_config_(NULL),
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_));
68
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");
72
73   net::URLFetcher::SetEnableInterceptionForTests(true);
74 }
75
76 ComponentUpdaterTest::~ComponentUpdaterTest() {
77   net::URLFetcher::SetEnableInterceptionForTests(false);
78 }
79
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_);
85 }
86
87 void ComponentUpdaterTest::TearDown() {
88   interceptor_factory_.reset();
89   get_interceptor_.reset();
90   xmlCleanupGlobals();
91 }
92
93 ComponentUpdateService* ComponentUpdaterTest::component_updater() {
94   return component_updater_.get();
95 }
96
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);
100 }
101
102 TestConfigurator* ComponentUpdaterTest::test_configurator() {
103   return test_config_;
104 }
105
106 ComponentUpdateService::Status ComponentUpdaterTest::RegisterComponent(
107     CrxComponent* com,
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));
117   } else {
118     com->name = "test_ihfo";
119     com->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
120   }
121   com->version = version;
122   com->installer = installer;
123   return component_updater_->RegisterComponent(*com);
124 }
125
126 void ComponentUpdaterTest::RunThreads() {
127   base::RunLoop runloop;
128   test_configurator()->SetQuitClosure(runloop.QuitClosure());
129   runloop.Run();
130
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();
136 }
137
138 void ComponentUpdaterTest::RunThreadsUntilIdle() {
139   base::RunLoop().RunUntilIdle();
140 }
141
142 ComponentUpdateService::Status OnDemandTester::OnDemand(
143     ComponentUpdateService* cus,
144     const std::string& component_id) {
145   return cus->GetOnDemandUpdater().OnDemandUpdate(component_id);
146 }
147
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);
152 }
153
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();
160 }
161
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;
167
168   EXPECT_CALL(observer,
169               OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
170       .Times(1);
171   EXPECT_CALL(observer,
172               OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
173       .Times(2);
174   EXPECT_CALL(observer,
175               OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
176                       "abagagagagagagagagagagagagagagag"))
177       .Times(2);
178
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")));
183
184   TestInstaller installer;
185   CrxComponent com;
186   component_updater()->AddObserver(&observer);
187   EXPECT_EQ(
188       ComponentUpdateService::kOk,
189       RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
190
191   // We loop twice, but there are no updates so we expect two sleep messages.
192   test_configurator()->SetLoopCount(2);
193   component_updater()->Start();
194   RunThreads();
195
196   EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
197   EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
198
199   // Expect to see the two update check requests and no other requests,
200   // including pings.
201   EXPECT_EQ(2, post_interceptor_->GetHitCount())
202       << post_interceptor_->GetRequestsAsString();
203   EXPECT_EQ(2, post_interceptor_->GetCount())
204       << post_interceptor_->GetRequestsAsString();
205   EXPECT_NE(
206       string::npos,
207       post_interceptor_->GetRequests()[0].find(
208           "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
209           "<updatecheck /></app>"))
210       << post_interceptor_->GetRequestsAsString();
211   EXPECT_NE(
212       string::npos,
213       post_interceptor_->GetRequests()[1].find(
214           "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
215           "<updatecheck /></app>"))
216       << post_interceptor_->GetRequestsAsString();
217
218   component_updater()->Stop();
219
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, ""))
223       .Times(1);
224   EXPECT_CALL(observer,
225               OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
226       .Times(2);
227   EXPECT_CALL(observer,
228               OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
229                       "abagagagagagagagagagagagagagagag"))
230       .Times(2);
231
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")));
237
238   test_configurator()->SetLoopCount(2);
239   component_updater()->Start();
240   RunThreads();
241
242   EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
243   EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
244
245   EXPECT_EQ(2, post_interceptor_->GetHitCount())
246       << post_interceptor_->GetRequestsAsString();
247   EXPECT_EQ(2, post_interceptor_->GetCount())
248       << post_interceptor_->GetRequestsAsString();
249   EXPECT_NE(
250       string::npos,
251       post_interceptor_->GetRequests()[0].find(
252           "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
253           "<updatecheck /></app>"))
254       << post_interceptor_->GetRequestsAsString();
255   EXPECT_NE(
256       string::npos,
257       post_interceptor_->GetRequests()[1].find(
258           "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
259           "<updatecheck /></app>"))
260       << post_interceptor_->GetRequestsAsString();
261
262   component_updater()->Stop();
263 }
264
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:
270 // 1- update check
271 // 2- download crx
272 // 3- ping
273 // 4- second update check.
274 TEST_F(ComponentUpdaterTest, InstallCrx) {
275   MockServiceObserver observer;
276   {
277     InSequence seq;
278     EXPECT_CALL(observer,
279                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
280         .Times(1);
281     EXPECT_CALL(observer,
282                 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
283                         "jebgalgnebhfojomionfpkfelancnnkf"))
284         .Times(1);
285     EXPECT_CALL(observer,
286                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
287                         "abagagagagagagagagagagagagagagag"))
288         .Times(1);
289     EXPECT_CALL(observer,
290                 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
291                         "jebgalgnebhfojomionfpkfelancnnkf"))
292                 .Times(AnyNumber());
293     EXPECT_CALL(observer,
294                 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
295                         "jebgalgnebhfojomionfpkfelancnnkf"))
296         .Times(1);
297     EXPECT_CALL(observer,
298                 OnEvent(ServiceObserver::COMPONENT_UPDATED,
299                         "jebgalgnebhfojomionfpkfelancnnkf"))
300         .Times(1);
301     EXPECT_CALL(observer,
302                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
303         .Times(1);
304     EXPECT_CALL(observer,
305                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
306                         "jebgalgnebhfojomionfpkfelancnnkf"))
307         .Times(1);
308     EXPECT_CALL(observer,
309                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
310                         "abagagagagagagagagagagagagagagag"))
311         .Times(1);
312     EXPECT_CALL(observer,
313                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
314         .Times(1);
315   }
316
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")));
322
323   get_interceptor_->SetResponse(
324       GURL(expected_crx_url),
325       test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
326
327   component_updater()->AddObserver(&observer);
328
329   TestInstaller installer1;
330   CrxComponent com1;
331   RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1);
332   TestInstaller installer2;
333   CrxComponent com2;
334   RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2);
335
336   test_configurator()->SetLoopCount(2);
337   component_updater()->Start();
338   RunThreads();
339
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());
344
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();
350
351   // Expect one component download.
352   EXPECT_EQ(1, get_interceptor_->GetHitCount());
353
354   EXPECT_NE(
355       string::npos,
356       post_interceptor_->GetRequests()[0].find(
357           "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
358           "<updatecheck /></app>"))
359       << post_interceptor_->GetRequestsAsString();
360   EXPECT_NE(
361       string::npos,
362       post_interceptor_->GetRequests()[0].find(
363           "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
364           "<updatecheck /></app>"))
365       << post_interceptor_->GetRequestsAsString();
366
367   EXPECT_NE(
368       string::npos,
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();
374
375   EXPECT_NE(
376       string::npos,
377       post_interceptor_->GetRequests()[2].find(
378           "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
379           "<updatecheck /></app>"));
380   EXPECT_NE(
381       string::npos,
382       post_interceptor_->GetRequests()[2].find(
383           "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
384           "<updatecheck /></app>"))
385       << post_interceptor_->GetRequestsAsString();
386
387   // Test the protocol version is correct and the extra request attributes
388   // are included in the request.
389   EXPECT_NE(
390       string::npos,
391       post_interceptor_->GetRequests()[0].find(
392           "request protocol=\"3.0\" extra=\"foo\""))
393       << post_interceptor_->GetRequestsAsString();
394
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|
400   // attributes:
401   // <?xml version="1.0" encoding="UTF-8"?>
402   // <request... os=... arch=... prodchannel=... prodversion=...>
403   // ...
404   // </request>
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="));
412
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="));
419
420   component_updater()->Stop();
421 }
422
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")));
429
430   get_interceptor_->SetResponse(
431       GURL(expected_crx_url),
432       test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
433
434   TestInstaller installer;
435   CrxComponent com;
436   RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer);
437
438   test_configurator()->SetLoopCount(1);
439   component_updater()->Start();
440   RunThreads();
441
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();
447
448   // Expect no download to occur.
449   EXPECT_EQ(0, get_interceptor_->GetHitCount());
450
451   EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
452   EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
453
454   component_updater()->Stop();
455 }
456
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
460 //    nothing happens.
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
466 #else
467 #define MAYBE_OnDemandUpdate OnDemandUpdate
468 #endif
469 TEST_F(ComponentUpdaterTest, MAYBE_OnDemandUpdate) {
470   MockServiceObserver observer;
471   {
472     InSequence seq;
473     EXPECT_CALL(observer,
474                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
475         .Times(1);
476     EXPECT_CALL(observer,
477                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
478                         "abagagagagagagagagagagagagagagag"))
479         .Times(1);
480     EXPECT_CALL(observer,
481                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
482                         "jebgalgnebhfojomionfpkfelancnnkf"))
483         .Times(1);
484     EXPECT_CALL(observer,
485                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
486         .Times(1);
487     EXPECT_CALL(observer,
488                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
489         .Times(1);
490     EXPECT_CALL(observer,
491                 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
492                         "jebgalgnebhfojomionfpkfelancnnkf"))
493         .Times(1);
494     EXPECT_CALL(observer,
495                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
496                         "abagagagagagagagagagagagagagagag"))
497         .Times(1);
498     EXPECT_CALL(observer,
499                 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
500                         "jebgalgnebhfojomionfpkfelancnnkf"))
501                 .Times(AnyNumber());
502     EXPECT_CALL(observer,
503                 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
504                         "jebgalgnebhfojomionfpkfelancnnkf"))
505         .Times(1);
506     EXPECT_CALL(observer,
507                 OnEvent(ServiceObserver::COMPONENT_UPDATED,
508                         "jebgalgnebhfojomionfpkfelancnnkf"))
509         .Times(1);
510     EXPECT_CALL(observer,
511                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
512         .Times(1);
513   }
514
515   EXPECT_TRUE(post_interceptor_->ExpectRequest(
516       new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
517
518   get_interceptor_->SetResponse(
519       GURL(expected_crx_url),
520       test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
521
522   component_updater()->AddObserver(&observer);
523
524   TestInstaller installer1;
525   CrxComponent com1;
526   RegisterComponent(&com1, kTestComponent_abag, Version("2.2"), &installer1);
527   TestInstaller installer2;
528   CrxComponent com2;
529   RegisterComponent(&com2, kTestComponent_jebg, Version("0.9"), &installer2);
530
531   // No update normally.
532   test_configurator()->SetLoopCount(1);
533   component_updater()->Start();
534   RunThreads();
535   component_updater()->Stop();
536
537   EXPECT_EQ(1, post_interceptor_->GetHitCount())
538       << post_interceptor_->GetRequestsAsString();
539   EXPECT_EQ(1, post_interceptor_->GetCount())
540       << post_interceptor_->GetRequestsAsString();
541
542   EXPECT_EQ(0, get_interceptor_->GetHitCount());
543
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")));
549
550   EXPECT_EQ(
551       ComponentUpdateService::kOk,
552       OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
553   test_configurator()->SetLoopCount(1);
554   component_updater()->Start();
555   RunThreads();
556
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());
561
562   EXPECT_EQ(2, post_interceptor_->GetHitCount())
563       << post_interceptor_->GetRequestsAsString();
564   EXPECT_EQ(2, post_interceptor_->GetCount())
565       << post_interceptor_->GetRequestsAsString();
566
567   EXPECT_EQ(1, get_interceptor_->GetHitCount());
568
569   // Expect the update check to contain an "ondemand" request for the
570   // second component (com2) and a normal request for the other component.
571   EXPECT_NE(
572       string::npos,
573       post_interceptor_->GetRequests()[0].find(
574           "<app appid=\"abagagagagagagagagagagagagagagag\" "
575           "version=\"2.2\"><updatecheck /></app>"))
576       << post_interceptor_->GetRequestsAsString();
577   EXPECT_NE(
578       string::npos,
579       post_interceptor_->GetRequests()[0].find(
580           "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
581           "version=\"0.9\" installsource=\"ondemand\"><updatecheck /></app>"))
582       << post_interceptor_->GetRequestsAsString();
583   EXPECT_NE(
584       string::npos,
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();
590
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);
594   EXPECT_EQ(
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();
600
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));
604   {
605     InSequence seq;
606     EXPECT_CALL(observer,
607                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
608         .Times(1);
609     EXPECT_CALL(observer,
610                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
611                         "abagagagagagagagagagagagagagagag"))
612         .Times(1);
613     EXPECT_CALL(observer,
614                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
615                         "jebgalgnebhfojomionfpkfelancnnkf"))
616         .Times(1);
617     EXPECT_CALL(observer,
618                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
619         .Times(1);
620   }
621
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")));
626
627   test_configurator()->SetLoopCount(1);
628   component_updater()->Start();
629   EXPECT_EQ(
630       ComponentUpdateService::kOk,
631       OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
632   RunThreads();
633   component_updater()->Stop();
634
635   EXPECT_EQ(1, post_interceptor_->GetHitCount())
636       << post_interceptor_->GetRequestsAsString();
637   EXPECT_EQ(1, post_interceptor_->GetCount())
638       << post_interceptor_->GetRequestsAsString();
639
640   // No update: already updated to 1.0 so nothing new
641   EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
642   {
643     InSequence seq;
644     EXPECT_CALL(observer,
645                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
646         .Times(1);
647     EXPECT_CALL(observer,
648                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
649                         "jebgalgnebhfojomionfpkfelancnnkf"))
650         .Times(1);
651     EXPECT_CALL(observer,
652                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
653                         "abagagagagagagagagagagagagagagag"))
654         .Times(1);
655     EXPECT_CALL(observer,
656                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
657         .Times(1);
658   }
659
660   post_interceptor_->Reset();
661   EXPECT_TRUE(post_interceptor_->ExpectRequest(
662       new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
663
664   test_configurator()->SetLoopCount(1);
665   component_updater()->Start();
666   EXPECT_EQ(
667       ComponentUpdateService::kOk,
668       OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
669   RunThreads();
670
671   EXPECT_EQ(1, post_interceptor_->GetHitCount())
672       << post_interceptor_->GetRequestsAsString();
673   EXPECT_EQ(1, post_interceptor_->GetCount())
674       << post_interceptor_->GetRequestsAsString();
675
676   component_updater()->Stop();
677 }
678
679 // Verify that a previously registered component can get re-registered
680 // with a different version.
681 TEST_F(ComponentUpdaterTest, CheckReRegistration) {
682   MockServiceObserver observer;
683   {
684     InSequence seq;
685     EXPECT_CALL(observer,
686                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
687         .Times(1);
688     EXPECT_CALL(observer,
689                 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
690                         "jebgalgnebhfojomionfpkfelancnnkf"))
691         .Times(1);
692     EXPECT_CALL(observer,
693                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
694                         "abagagagagagagagagagagagagagagag"))
695         .Times(1);
696     EXPECT_CALL(observer,
697                 OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
698                         "jebgalgnebhfojomionfpkfelancnnkf"))
699                 .Times(AnyNumber());
700     EXPECT_CALL(observer,
701                 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
702                         "jebgalgnebhfojomionfpkfelancnnkf"))
703         .Times(1);
704     EXPECT_CALL(observer,
705                 OnEvent(ServiceObserver::COMPONENT_UPDATED,
706                         "jebgalgnebhfojomionfpkfelancnnkf"))
707         .Times(1);
708     EXPECT_CALL(observer,
709                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
710         .Times(1);
711     EXPECT_CALL(observer,
712                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
713                         "jebgalgnebhfojomionfpkfelancnnkf"))
714         .Times(1);
715     EXPECT_CALL(observer,
716                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
717                         "abagagagagagagagagagagagagagagag"))
718         .Times(1);
719     EXPECT_CALL(observer,
720                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
721         .Times(1);
722   }
723
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")));
729
730   get_interceptor_->SetResponse(
731       GURL(expected_crx_url),
732       test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
733
734   component_updater()->AddObserver(&observer);
735
736   TestInstaller installer1;
737   CrxComponent com1;
738   RegisterComponent(&com1, kTestComponent_jebg, Version("0.9"), &installer1);
739   TestInstaller installer2;
740   CrxComponent com2;
741   RegisterComponent(&com2, kTestComponent_abag, Version("2.2"), &installer2);
742
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();
747   RunThreads();
748
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());
753
754   EXPECT_EQ(3, post_interceptor_->GetHitCount())
755       << post_interceptor_->GetRequestsAsString();
756   EXPECT_EQ(1, get_interceptor_->GetHitCount());
757
758   EXPECT_NE(
759       string::npos,
760       post_interceptor_->GetRequests()[0].find(
761           "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
762           "<updatecheck /></app>"))
763       << post_interceptor_->GetRequestsAsString();
764   EXPECT_NE(
765       string::npos,
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();
771   EXPECT_NE(
772       string::npos,
773       post_interceptor_->GetRequests()[2].find(
774           "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
775           "<updatecheck /></app>"))
776       << post_interceptor_->GetRequestsAsString();
777
778   component_updater()->Stop();
779
780   // Now re-register, pretending to be an even newer version (2.2)
781   EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
782   {
783     InSequence seq;
784     EXPECT_CALL(observer,
785                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
786         .Times(1);
787     EXPECT_CALL(observer,
788                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
789                         "jebgalgnebhfojomionfpkfelancnnkf"))
790         .Times(1);
791     EXPECT_CALL(observer,
792                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
793                         "abagagagagagagagagagagagagagagag"))
794         .Times(1);
795     EXPECT_CALL(observer,
796                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
797         .Times(1);
798   }
799
800   post_interceptor_->Reset();
801   EXPECT_TRUE(post_interceptor_->ExpectRequest(
802       new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
803
804   TestInstaller installer3;
805   EXPECT_EQ(ComponentUpdateService::kReplaced,
806             RegisterComponent(
807                 &com1, kTestComponent_jebg, Version("2.2"), &installer3));
808
809   // Loop once just to notice the check happening with the re-register version.
810   test_configurator()->SetLoopCount(1);
811   component_updater()->Start();
812   RunThreads();
813
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());
819
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();
825
826   EXPECT_NE(
827       string::npos,
828       post_interceptor_->GetRequests()[0].find(
829           "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"2.2\">"
830           "<updatecheck /></app>"));
831
832   component_updater()->Stop();
833 }
834
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
837 // nothing.
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")));
858
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"));
866
867   VersionedTestInstaller installer;
868   CrxComponent com;
869   RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer);
870
871   test_configurator()->SetLoopCount(3);
872   component_updater()->Start();
873   RunThreads();
874
875   EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
876   EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
877
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());
883
884   EXPECT_NE(
885       string::npos,
886       post_interceptor_->GetRequests()[0].find(
887           "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
888           "<updatecheck /></app>"))
889       << post_interceptor_->GetRequestsAsString();
890   EXPECT_NE(
891       string::npos,
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();
897   EXPECT_NE(
898       string::npos,
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();
903   EXPECT_NE(
904       string::npos,
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();
911   EXPECT_NE(
912       string::npos,
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();
918 }
919
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
933 #else
934 #define MAYBE_DifferentialUpdateFails DifferentialUpdateFails
935 #endif
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")));
944
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"));
955
956   TestInstaller installer;
957   CrxComponent com;
958   RegisterComponent(&com, kTestComponent_ihfo, Version("1.0"), &installer);
959
960   test_configurator()->SetLoopCount(2);
961   component_updater()->Start();
962   RunThreads();
963
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());
967
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());
973
974   EXPECT_NE(
975       string::npos,
976       post_interceptor_->GetRequests()[0].find(
977           "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
978           "<updatecheck /></app>"))
979       << post_interceptor_->GetRequestsAsString();
980   EXPECT_NE(
981       string::npos,
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();
988   EXPECT_NE(
989       string::npos,
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();
994
995   component_updater()->Stop();
996 }
997
998 // Test is flakey on Android bots. See crbug.com/331420.
999 #if defined(OS_ANDROID)
1000 #define MAYBE_CheckFailedInstallPing DISABLED_CheckFailedInstallPing
1001 #else
1002 #define MAYBE_CheckFailedInstallPing CheckFailedInstallPing
1003 #endif
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 {
1010       ++install_count_;
1011       base::DeleteFile(unpack_path, true);
1012       return false;
1013     }
1014   } installer;
1015
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"));
1025
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.
1029   CrxComponent com;
1030   RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer);
1031
1032   test_configurator()->SetLoopCount(2);
1033   component_updater()->Start();
1034   RunThreads();
1035
1036   EXPECT_EQ(4, post_interceptor_->GetHitCount())
1037       << post_interceptor_->GetRequestsAsString();
1038   EXPECT_EQ(2, get_interceptor_->GetHitCount());
1039
1040   EXPECT_NE(
1041       string::npos,
1042       post_interceptor_->GetRequests()[0].find(
1043           "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
1044           "<updatecheck /></app>"))
1045       << post_interceptor_->GetRequestsAsString();
1046   EXPECT_NE(
1047       string::npos,
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();
1054   EXPECT_NE(
1055       string::npos,
1056       post_interceptor_->GetRequests()[2].find(
1057           "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
1058           "<updatecheck /></app>"))
1059       << post_interceptor_->GetRequestsAsString();
1060   EXPECT_NE(
1061       string::npos,
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();
1068
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
1071   // iteration.
1072   post_interceptor_->Reset();
1073   EXPECT_TRUE(post_interceptor_->ExpectRequest(
1074       new PartialMatch("updatecheck"),
1075       test_file("updatecheck_reply_noupdate.xml")));
1076
1077   test_configurator()->SetLoopCount(1);
1078   component_updater()->Start();
1079   RunThreads();
1080
1081   EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
1082   EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
1083
1084   EXPECT_EQ(1, post_interceptor_->GetHitCount())
1085       << post_interceptor_->GetRequestsAsString();
1086   EXPECT_EQ(1, post_interceptor_->GetCount())
1087       << post_interceptor_->GetRequestsAsString();
1088
1089   EXPECT_NE(
1090       string::npos,
1091       post_interceptor_->GetRequests()[0].find(
1092           "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
1093           "<updatecheck /></app>"))
1094       << post_interceptor_->GetRequestsAsString();
1095
1096   component_updater()->Stop();
1097 }
1098
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")));
1114
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"));
1129
1130   VersionedTestInstaller installer;
1131   CrxComponent com;
1132   RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer);
1133
1134   test_configurator()->SetLoopCount(3);
1135   component_updater()->Start();
1136   RunThreads();
1137   component_updater()->Stop();
1138
1139   EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
1140   EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
1141
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());
1147
1148   EXPECT_NE(
1149       string::npos,
1150       post_interceptor_->GetRequests()[0].find(
1151           "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
1152           "<updatecheck /></app>"))
1153       << post_interceptor_->GetRequestsAsString();
1154   EXPECT_NE(
1155       string::npos,
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();
1161   EXPECT_NE(
1162       string::npos,
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();
1167   EXPECT_NE(
1168       string::npos,
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();
1177   EXPECT_NE(
1178       string::npos,
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();
1183 }
1184
1185 class TestResourceController : public content::ResourceController {
1186  public:
1187   virtual void SetThrottle(content::ResourceThrottle* throttle) {}
1188 };
1189
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,
1197                                   NULL,
1198                                   &context);
1199
1200   content::ResourceThrottle* rt = GetOnDemandResourceThrottle(cus, crx_id);
1201   rt->set_controller_for_testing(controller);
1202   controller->SetThrottle(rt);
1203   return rt;
1204 }
1205
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 {
1212    public:
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); }
1218   } controller;
1219
1220   delete RequestTestResourceThrottle(cus, &controller, crx_id);
1221 }
1222
1223 TEST_F(ComponentUpdaterTest, ResourceThrottleDeletedNoUpdate) {
1224   MockServiceObserver observer;
1225   {
1226     InSequence seq;
1227     EXPECT_CALL(observer,
1228                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1229         .Times(1);
1230     EXPECT_CALL(observer,
1231                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1232                         "abagagagagagagagagagagagagagagag"))
1233         .Times(1);
1234     EXPECT_CALL(observer,
1235                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1236         .Times(1);
1237   }
1238
1239   EXPECT_TRUE(post_interceptor_->ExpectRequest(
1240       new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
1241
1242   TestInstaller installer;
1243   CrxComponent com;
1244   component_updater()->AddObserver(&observer);
1245   EXPECT_EQ(
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();
1254
1255   RunThreadsUntilIdle();
1256
1257   EXPECT_EQ(0, post_interceptor_->GetHitCount());
1258
1259   BrowserThread::PostTask(BrowserThread::IO,
1260                           FROM_HERE,
1261                           base::Bind(&RequestAndDeleteResourceThrottle,
1262                                      component_updater(),
1263                                      "abagagagagagagagagagagagagagagag"));
1264
1265   RunThreads();
1266
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());
1270
1271   component_updater()->Stop();
1272 }
1273
1274 class CancelResourceController : public TestResourceController {
1275  public:
1276   CancelResourceController() : throttle_(NULL), resume_called_(0) {}
1277   virtual ~CancelResourceController() {
1278     // Check that the throttle has been resumed by the time we
1279     // exit the test.
1280     CHECK_EQ(1, resume_called_);
1281     delete throttle_;
1282   }
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,
1288                             FROM_HERE,
1289                             base::Bind(&CancelResourceController::ResumeCalled,
1290                                        base::Unretained(this)));
1291   }
1292   virtual void SetThrottle(content::ResourceThrottle* throttle) OVERRIDE {
1293     throttle_ = throttle;
1294     bool defer = false;
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);
1298     CHECK(defer);
1299   }
1300
1301  private:
1302   void ResumeCalled() { ++resume_called_; }
1303
1304   content::ResourceThrottle* throttle_;
1305   int resume_called_;
1306 };
1307
1308 // Tests the on-demand update with resource throttle, including the
1309 // cooldown interval between calls.
1310 TEST_F(ComponentUpdaterTest, ResourceThrottleLiveNoUpdate) {
1311   MockServiceObserver observer;
1312   {
1313     InSequence seq;
1314     EXPECT_CALL(observer,
1315                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1316         .Times(1);
1317     EXPECT_CALL(observer,
1318                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1319                         "abagagagagagagagagagagagagagagag"))
1320         .Times(1);
1321     EXPECT_CALL(observer,
1322                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1323         .Times(1);
1324     EXPECT_CALL(observer,
1325                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1326         .Times(1);
1327     EXPECT_CALL(observer,
1328                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1329                         "abagagagagagagagagagagagagagagag"))
1330         .Times(1);
1331     EXPECT_CALL(observer,
1332                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1333         .Times(1);
1334     EXPECT_CALL(observer,
1335                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1336         .Times(1);
1337   }
1338
1339   EXPECT_TRUE(post_interceptor_->ExpectRequest(
1340       new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
1341
1342   TestInstaller installer;
1343   CrxComponent com;
1344   component_updater()->AddObserver(&observer);
1345   EXPECT_EQ(
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();
1354
1355   RunThreadsUntilIdle();
1356
1357   EXPECT_EQ(0, post_interceptor_->GetHitCount());
1358
1359   {
1360     // First on-demand update check is expected to succeeded.
1361     CancelResourceController controller;
1362
1363     BrowserThread::PostTask(
1364         BrowserThread::IO,
1365         FROM_HERE,
1366         base::Bind(base::IgnoreResult(&RequestTestResourceThrottle),
1367                    component_updater(),
1368                    &controller,
1369                    "abagagagagagagagagagagagagagagag"));
1370
1371     RunThreads();
1372
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());
1376
1377     component_updater()->Stop();
1378   }
1379
1380   {
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();
1386
1387     CancelResourceController controller;
1388
1389     BrowserThread::PostTask(
1390         BrowserThread::IO,
1391         FROM_HERE,
1392         base::Bind(base::IgnoreResult(&RequestTestResourceThrottle),
1393                    component_updater(),
1394                    &controller,
1395                    "abagagagagagagagagagagagagagagag"));
1396
1397     RunThreads();
1398
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());
1402
1403     component_updater()->Stop();
1404   }
1405
1406   {
1407     // This on-demand call is expected not to trigger a component update check.
1408     test_configurator()->SetOnDemandTime(1000000);
1409     component_updater()->Start();
1410
1411     CancelResourceController controller;
1412
1413     BrowserThread::PostTask(
1414         BrowserThread::IO,
1415         FROM_HERE,
1416         base::Bind(base::IgnoreResult(&RequestTestResourceThrottle),
1417                    component_updater(),
1418                    &controller,
1419                    "abagagagagagagagagagagagagagagag"));
1420     RunThreadsUntilIdle();
1421   }
1422 }
1423
1424 // Tests adding and removing observers.
1425 TEST_F(ComponentUpdaterTest, Observer) {
1426   MockServiceObserver observer1, observer2;
1427
1428   // Expect that two observers see the events.
1429   {
1430     InSequence seq;
1431     EXPECT_CALL(observer1,
1432                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1433         .Times(1);
1434     EXPECT_CALL(observer2,
1435                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1436         .Times(1);
1437     EXPECT_CALL(observer1,
1438                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1439                         "abagagagagagagagagagagagagagagag"))
1440         .Times(1);
1441     EXPECT_CALL(observer2,
1442                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1443                         "abagagagagagagagagagagagagagagag"))
1444         .Times(1);
1445     EXPECT_CALL(observer1,
1446                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1447         .Times(1);
1448     EXPECT_CALL(observer2,
1449                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1450         .Times(1);
1451   }
1452
1453   EXPECT_TRUE(post_interceptor_->ExpectRequest(
1454       new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
1455
1456   component_updater()->AddObserver(&observer1);
1457   component_updater()->AddObserver(&observer2);
1458
1459   TestInstaller installer;
1460   CrxComponent com;
1461   EXPECT_EQ(
1462       ComponentUpdateService::kOk,
1463       RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
1464   test_configurator()->SetLoopCount(1);
1465   component_updater()->Start();
1466   RunThreads();
1467
1468   // After removing the first observer, it's only the second observer that
1469   // gets the events.
1470   EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
1471   EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2));
1472   {
1473     InSequence seq;
1474     EXPECT_CALL(observer2,
1475                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
1476         .Times(1);
1477     EXPECT_CALL(observer2,
1478                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
1479                         "abagagagagagagagagagagagagagagag"))
1480         .Times(1);
1481     EXPECT_CALL(observer2,
1482                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
1483         .Times(1);
1484   }
1485
1486   component_updater()->RemoveObserver(&observer1);
1487
1488   test_configurator()->SetLoopCount(1);
1489   component_updater()->Start();
1490   RunThreads();
1491
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);
1496
1497   test_configurator()->SetLoopCount(1);
1498   component_updater()->Start();
1499   RunThreads();
1500
1501   component_updater()->Stop();
1502 }
1503
1504 }  // namespace component_updater