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