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