1 // Copyright 2015 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.
6 #include "base/bind_helpers.h"
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/location.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/path_service.h"
14 #include "base/run_loop.h"
15 #include "base/test/sequenced_worker_pool_owner.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "base/threading/thread.h"
18 #include "base/values.h"
19 #include "base/version.h"
20 #include "components/update_client/crx_update_item.h"
21 #include "components/update_client/ping_manager.h"
22 #include "components/update_client/test_configurator.h"
23 #include "components/update_client/test_installer.h"
24 #include "components/update_client/update_checker.h"
25 #include "components/update_client/update_client_internal.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
30 namespace update_client
{
36 // Makes a copy of the file specified by |from_path| in a temporary directory
37 // and returns the path of the copy. Returns true if successful. Cleans up if
38 // there was an error creating the copy.
39 bool MakeTestFile(const FilePath
& from_path
, FilePath
* to_path
) {
42 CreateNewTempDirectory(FILE_PATH_LITERAL("update_client"), &temp_dir
);
47 result
= CreateTemporaryFileInDir(temp_dir
, &temp_file
);
51 result
= CopyFile(from_path
, temp_file
);
53 DeleteFile(temp_file
, false);
61 using Events
= UpdateClient::Observer::Events
;
63 class MockObserver
: public UpdateClient::Observer
{
65 MOCK_METHOD2(OnEvent
, void(Events event
, const std::string
&));
68 class FakePingManagerImpl
: public PingManager
{
70 explicit FakePingManagerImpl(const Configurator
& config
);
71 ~FakePingManagerImpl() override
;
73 void OnUpdateComplete(const CrxUpdateItem
* item
) override
;
75 const std::vector
<CrxUpdateItem
>& items() const;
78 std::vector
<CrxUpdateItem
> items_
;
79 DISALLOW_COPY_AND_ASSIGN(FakePingManagerImpl
);
82 FakePingManagerImpl::FakePingManagerImpl(const Configurator
& config
)
83 : PingManager(config
) {
86 FakePingManagerImpl::~FakePingManagerImpl() {
89 void FakePingManagerImpl::OnUpdateComplete(const CrxUpdateItem
* item
) {
90 items_
.push_back(*item
);
93 const std::vector
<CrxUpdateItem
>& FakePingManagerImpl::items() const {
100 using ::testing::AnyNumber
;
101 using ::testing::DoAll
;
102 using ::testing::InSequence
;
103 using ::testing::Invoke
;
104 using ::testing::Mock
;
105 using ::testing::Return
;
109 class UpdateClientTest
: public testing::Test
{
112 ~UpdateClientTest() override
;
117 // Returns the full path to a test file.
118 static base::FilePath
TestFilePath(const char* file
);
120 scoped_refptr
<update_client::Configurator
> config() { return config_
; }
122 base::Closure
quit_closure() { return quit_closure_
; }
125 static const int kNumWorkerThreads_
= 2;
127 base::MessageLoopForUI message_loop_
;
128 base::RunLoop runloop_
;
129 base::Closure quit_closure_
;
131 scoped_ptr
<base::SequencedWorkerPoolOwner
> worker_pool_
;
132 scoped_ptr
<base::Thread
> thread_
;
134 scoped_refptr
<update_client::Configurator
> config_
;
136 DISALLOW_COPY_AND_ASSIGN(UpdateClientTest
);
139 UpdateClientTest::UpdateClientTest()
141 new base::SequencedWorkerPoolOwner(kNumWorkerThreads_
, "test")),
142 thread_(new base::Thread("test")) {
143 quit_closure_
= runloop_
.QuitClosure();
147 auto pool
= worker_pool_
->pool();
148 config_
= new TestConfigurator(
149 pool
->GetSequencedTaskRunner(pool
->GetSequenceToken()),
150 thread_
->task_runner());
153 UpdateClientTest::~UpdateClientTest() {
156 worker_pool_
->pool()->Shutdown();
159 void UpdateClientTest::RunThreads() {
163 base::FilePath
UpdateClientTest::TestFilePath(const char* file
) {
165 PathService::Get(base::DIR_SOURCE_ROOT
, &path
);
166 return path
.AppendASCII("components")
169 .AppendASCII("update_client")
173 // Tests the scenario where one update check is done for one CRX. The CRX
175 TEST_F(UpdateClientTest
, OneCrxNoUpdate
) {
176 class DataCallbackFake
{
178 static void Callback(const std::vector
<std::string
>& ids
,
179 std::vector
<CrxComponent
>* components
) {
181 crx
.name
= "test_jebg";
182 crx
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
183 crx
.version
= Version("0.9");
184 crx
.installer
= new TestInstaller
;
185 components
->push_back(crx
);
189 class CompletionCallbackFake
{
191 static void Callback(const base::Closure
& quit_closure
, int error
) {
197 class FakeUpdateChecker
: public UpdateChecker
{
199 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
200 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
203 bool CheckForUpdates(
204 const std::vector
<CrxUpdateItem
*>& items_to_check
,
205 const std::string
& additional_attributes
,
206 const UpdateCheckCallback
& update_check_callback
) override
{
207 base::ThreadTaskRunnerHandle::Get()->PostTask(
208 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "",
209 UpdateResponse::Results()));
214 class FakeCrxDownloader
: public CrxDownloader
{
216 static scoped_ptr
<CrxDownloader
> Create(
217 bool is_background_download
,
218 net::URLRequestContextGetter
* context_getter
,
219 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
220 const scoped_refptr
<base::SingleThreadTaskRunner
>&
221 background_task_runner
) {
222 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
226 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
227 ~FakeCrxDownloader() override
{}
229 void DoStartDownload(const GURL
& url
) override
{ EXPECT_TRUE(false); }
232 class FakePingManager
: public FakePingManagerImpl
{
234 explicit FakePingManager(const Configurator
& config
)
235 : FakePingManagerImpl(config
) {}
236 ~FakePingManager() override
{ EXPECT_TRUE(items().empty()); }
239 scoped_ptr
<PingManager
> ping_manager(new FakePingManager(*config()));
240 scoped_ptr
<UpdateClient
> update_client(new UpdateClientImpl(
241 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
242 &FakeCrxDownloader::Create
));
244 MockObserver observer
;
246 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
247 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
248 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_NOT_UPDATED
,
249 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
251 update_client
->AddObserver(&observer
);
253 std::vector
<std::string
> ids
;
254 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
256 update_client
->Update(
257 ids
, base::Bind(&DataCallbackFake::Callback
),
258 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
262 update_client
->RemoveObserver(&observer
);
265 // Tests the scenario where two CRXs are checked for updates. On CRX has
266 // an update, the other CRX does not.
267 TEST_F(UpdateClientTest
, TwoCrxUpdateNoUpdate
) {
268 class DataCallbackFake
{
270 static void Callback(const std::vector
<std::string
>& ids
,
271 std::vector
<CrxComponent
>* components
) {
273 crx1
.name
= "test_jebg";
274 crx1
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
275 crx1
.version
= Version("0.9");
276 crx1
.installer
= new TestInstaller
;
279 crx2
.name
= "test_abag";
280 crx2
.pk_hash
.assign(abag_hash
, abag_hash
+ arraysize(abag_hash
));
281 crx2
.version
= Version("2.2");
282 crx2
.installer
= new TestInstaller
;
284 components
->push_back(crx1
);
285 components
->push_back(crx2
);
289 class CompletionCallbackFake
{
291 static void Callback(const base::Closure
& quit_closure
, int error
) {
297 class FakeUpdateChecker
: public UpdateChecker
{
299 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
300 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
303 bool CheckForUpdates(
304 const std::vector
<CrxUpdateItem
*>& items_to_check
,
305 const std::string
& additional_attributes
,
306 const UpdateCheckCallback
& update_check_callback
) override
{
308 Fake the following response:
310 <?xml version='1.0' encoding='UTF-8'?>
311 <response protocol='3.0'>
312 <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
313 <updatecheck status='ok'>
315 <url codebase='http://localhost/download/'/>
317 <manifest version='1.0' prodversionmin='11.0.1.0'>
319 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
326 UpdateResponse::Result::Manifest::Package package
;
327 package
.name
= "jebgalgnebhfojomionfpkfelancnnkf.crx";
329 UpdateResponse::Result result
;
330 result
.extension_id
= "jebgalgnebhfojomionfpkfelancnnkf";
331 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
332 result
.manifest
.version
= "1.0";
333 result
.manifest
.browser_min_version
= "11.0.1.0";
334 result
.manifest
.packages
.push_back(package
);
336 UpdateResponse::Results results
;
337 results
.list
.push_back(result
);
339 base::ThreadTaskRunnerHandle::Get()->PostTask(
340 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
345 class FakeCrxDownloader
: public CrxDownloader
{
347 static scoped_ptr
<CrxDownloader
> Create(
348 bool is_background_download
,
349 net::URLRequestContextGetter
* context_getter
,
350 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
351 const scoped_refptr
<base::SingleThreadTaskRunner
>&
352 background_task_runner
) {
353 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
357 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
358 ~FakeCrxDownloader() override
{}
360 void DoStartDownload(const GURL
& url
) override
{
361 DownloadMetrics download_metrics
;
362 download_metrics
.url
= url
;
363 download_metrics
.downloader
= DownloadMetrics::kNone
;
364 download_metrics
.error
= 0;
365 download_metrics
.downloaded_bytes
= 1843;
366 download_metrics
.total_bytes
= 1843;
367 download_metrics
.download_time_ms
= 1000;
370 EXPECT_TRUE(MakeTestFile(
371 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path
));
375 result
.response
= path
;
376 result
.downloaded_bytes
= 1843;
377 result
.total_bytes
= 1843;
379 base::ThreadTaskRunnerHandle::Get()->PostTask(
380 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
381 base::Unretained(this), result
));
383 base::ThreadTaskRunnerHandle::Get()->PostTask(
385 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
386 base::Unretained(this), true, result
, download_metrics
));
390 class FakePingManager
: public FakePingManagerImpl
{
392 explicit FakePingManager(const Configurator
& config
)
393 : FakePingManagerImpl(config
) {}
394 ~FakePingManager() override
{
395 const auto& ping_items
= items();
396 EXPECT_EQ(1U, ping_items
.size());
397 EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items
[0].id
);
398 EXPECT_TRUE(base::Version("0.9").Equals(ping_items
[0].previous_version
));
399 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
400 EXPECT_EQ(0, ping_items
[0].error_category
);
401 EXPECT_EQ(0, ping_items
[0].error_code
);
405 scoped_ptr
<PingManager
> ping_manager(new FakePingManager(*config()));
406 scoped_ptr
<UpdateClient
> update_client(new UpdateClientImpl(
407 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
408 &FakeCrxDownloader::Create
));
410 MockObserver observer
;
413 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
414 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
415 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
416 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
417 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
418 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
419 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
420 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
421 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
422 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
426 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
427 "abagagagagagagagagagagagagagagag")).Times(1);
428 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_NOT_UPDATED
,
429 "abagagagagagagagagagagagagagagag")).Times(1);
432 update_client
->AddObserver(&observer
);
434 std::vector
<std::string
> ids
;
435 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
436 ids
.push_back(std::string("abagagagagagagagagagagagagagagag"));
438 update_client
->Update(
439 ids
, base::Bind(&DataCallbackFake::Callback
),
440 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
444 update_client
->RemoveObserver(&observer
);
447 // Tests the update check for two CRXs scenario. Both CRXs have updates.
448 TEST_F(UpdateClientTest
, TwoCrxUpdate
) {
449 class DataCallbackFake
{
451 static void Callback(const std::vector
<std::string
>& ids
,
452 std::vector
<CrxComponent
>* components
) {
454 crx1
.name
= "test_jebg";
455 crx1
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
456 crx1
.version
= Version("0.9");
457 crx1
.installer
= new TestInstaller
;
460 crx2
.name
= "test_ihfo";
461 crx2
.pk_hash
.assign(ihfo_hash
, ihfo_hash
+ arraysize(ihfo_hash
));
462 crx2
.version
= Version("0.8");
463 crx2
.installer
= new TestInstaller
;
465 components
->push_back(crx1
);
466 components
->push_back(crx2
);
470 class CompletionCallbackFake
{
472 static void Callback(const base::Closure
& quit_closure
, int error
) {
478 class FakeUpdateChecker
: public UpdateChecker
{
480 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
481 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
484 bool CheckForUpdates(
485 const std::vector
<CrxUpdateItem
*>& items_to_check
,
486 const std::string
& additional_attributes
,
487 const UpdateCheckCallback
& update_check_callback
) override
{
489 Fake the following response:
491 <?xml version='1.0' encoding='UTF-8'?>
492 <response protocol='3.0'>
493 <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
494 <updatecheck status='ok'>
496 <url codebase='http://localhost/download/'/>
498 <manifest version='1.0' prodversionmin='11.0.1.0'>
500 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
505 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
506 <updatecheck status='ok'>
508 <url codebase='http://localhost/download/'/>
510 <manifest version='1.0' prodversionmin='11.0.1.0'>
512 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
519 UpdateResponse::Result::Manifest::Package package1
;
520 package1
.name
= "jebgalgnebhfojomionfpkfelancnnkf.crx";
522 UpdateResponse::Result result1
;
523 result1
.extension_id
= "jebgalgnebhfojomionfpkfelancnnkf";
524 result1
.crx_urls
.push_back(GURL("http://localhost/download/"));
525 result1
.manifest
.version
= "1.0";
526 result1
.manifest
.browser_min_version
= "11.0.1.0";
527 result1
.manifest
.packages
.push_back(package1
);
529 UpdateResponse::Result::Manifest::Package package2
;
530 package2
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
532 UpdateResponse::Result result2
;
533 result2
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
534 result2
.crx_urls
.push_back(GURL("http://localhost/download/"));
535 result2
.manifest
.version
= "1.0";
536 result2
.manifest
.browser_min_version
= "11.0.1.0";
537 result2
.manifest
.packages
.push_back(package2
);
539 UpdateResponse::Results results
;
540 results
.list
.push_back(result1
);
541 results
.list
.push_back(result2
);
543 base::ThreadTaskRunnerHandle::Get()->PostTask(
544 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
549 class FakeCrxDownloader
: public CrxDownloader
{
551 static scoped_ptr
<CrxDownloader
> Create(
552 bool is_background_download
,
553 net::URLRequestContextGetter
* context_getter
,
554 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
555 const scoped_refptr
<base::SingleThreadTaskRunner
>&
556 background_task_runner
) {
557 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
561 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
562 ~FakeCrxDownloader() override
{}
564 void DoStartDownload(const GURL
& url
) override
{
565 DownloadMetrics download_metrics
;
568 if (url
.path() == "/download/jebgalgnebhfojomionfpkfelancnnkf.crx") {
569 download_metrics
.url
= url
;
570 download_metrics
.downloader
= DownloadMetrics::kNone
;
571 download_metrics
.error
= 0;
572 download_metrics
.downloaded_bytes
= 1843;
573 download_metrics
.total_bytes
= 1843;
574 download_metrics
.download_time_ms
= 1000;
576 EXPECT_TRUE(MakeTestFile(
577 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path
));
580 result
.response
= path
;
581 result
.downloaded_bytes
= 1843;
582 result
.total_bytes
= 1843;
583 } else if (url
.path() ==
584 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
585 download_metrics
.url
= url
;
586 download_metrics
.downloader
= DownloadMetrics::kNone
;
587 download_metrics
.error
= 0;
588 download_metrics
.downloaded_bytes
= 53638;
589 download_metrics
.total_bytes
= 53638;
590 download_metrics
.download_time_ms
= 2000;
592 EXPECT_TRUE(MakeTestFile(
593 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path
));
596 result
.response
= path
;
597 result
.downloaded_bytes
= 53638;
598 result
.total_bytes
= 53638;
603 base::ThreadTaskRunnerHandle::Get()->PostTask(
604 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
605 base::Unretained(this), result
));
607 base::ThreadTaskRunnerHandle::Get()->PostTask(
609 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
610 base::Unretained(this), true, result
, download_metrics
));
614 class FakePingManager
: public FakePingManagerImpl
{
616 explicit FakePingManager(const Configurator
& config
)
617 : FakePingManagerImpl(config
) {}
618 ~FakePingManager() override
{
619 const auto& ping_items
= items();
620 EXPECT_EQ(2U, ping_items
.size());
621 EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items
[0].id
);
622 EXPECT_TRUE(base::Version("0.9").Equals(ping_items
[0].previous_version
));
623 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
624 EXPECT_EQ(0, ping_items
[0].error_category
);
625 EXPECT_EQ(0, ping_items
[0].error_code
);
626 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[1].id
);
627 EXPECT_TRUE(base::Version("0.8").Equals(ping_items
[1].previous_version
));
628 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[1].next_version
));
629 EXPECT_EQ(0, ping_items
[1].error_category
);
630 EXPECT_EQ(0, ping_items
[1].error_code
);
634 scoped_ptr
<FakePingManager
> ping_manager(new FakePingManager(*config()));
635 scoped_ptr
<UpdateClient
> update_client(new UpdateClientImpl(
636 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
637 &FakeCrxDownloader::Create
));
639 MockObserver observer
;
642 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
643 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
644 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
645 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
646 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
647 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
648 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
649 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
650 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
651 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
655 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
656 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
657 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
658 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
659 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_WAIT
,
660 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
661 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
662 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
663 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
664 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
665 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
666 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
669 update_client
->AddObserver(&observer
);
671 std::vector
<std::string
> ids
;
672 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
673 ids
.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
675 update_client
->Update(
676 ids
, base::Bind(&DataCallbackFake::Callback
),
677 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
681 update_client
->RemoveObserver(&observer
);
684 // Tests the differential update scenario for one CRX.
685 TEST_F(UpdateClientTest
, OneCrxDiffUpdate
) {
686 class DataCallbackFake
{
688 static void Callback(const std::vector
<std::string
>& ids
,
689 std::vector
<CrxComponent
>* components
) {
690 static int num_calls
= 0;
692 // Must use the same stateful installer object.
693 static scoped_refptr
<CrxInstaller
> installer(
694 new VersionedTestInstaller());
699 crx
.name
= "test_ihfo";
700 crx
.pk_hash
.assign(ihfo_hash
, ihfo_hash
+ arraysize(ihfo_hash
));
701 crx
.installer
= installer
;
702 if (num_calls
== 1) {
703 crx
.version
= Version("0.8");
704 } else if (num_calls
== 2) {
705 crx
.version
= Version("1.0");
710 components
->push_back(crx
);
714 class CompletionCallbackFake
{
716 static void Callback(const base::Closure
& quit_closure
, int error
) {
722 class FakeUpdateChecker
: public UpdateChecker
{
724 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
725 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
728 bool CheckForUpdates(
729 const std::vector
<CrxUpdateItem
*>& items_to_check
,
730 const std::string
& additional_attributes
,
731 const UpdateCheckCallback
& update_check_callback
) override
{
732 static int num_call
= 0;
735 UpdateResponse::Results results
;
739 Fake the following response:
740 <?xml version='1.0' encoding='UTF-8'?>
741 <response protocol='3.0'>
742 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
743 <updatecheck status='ok'>
745 <url codebase='http://localhost/download/'/>
747 <manifest version='1.0' prodversionmin='11.0.1.0'>
749 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
756 UpdateResponse::Result::Manifest::Package package
;
757 package
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
758 package
.fingerprint
= "1";
759 UpdateResponse::Result result
;
760 result
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
761 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
762 result
.manifest
.version
= "1.0";
763 result
.manifest
.browser_min_version
= "11.0.1.0";
764 result
.manifest
.packages
.push_back(package
);
765 results
.list
.push_back(result
);
766 } else if (num_call
== 2) {
768 Fake the following response:
769 <?xml version='1.0' encoding='UTF-8'?>
770 <response protocol='3.0'>
771 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
772 <updatecheck status='ok'>
774 <url codebase='http://localhost/download/'/>
775 <url codebasediff='http://localhost/download/'/>
777 <manifest version='2.0' prodversionmin='11.0.1.0'>
779 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_2.crx'
780 namediff='ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx'
788 UpdateResponse::Result::Manifest::Package package
;
789 package
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
790 package
.namediff
= "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
791 package
.fingerprint
= "22";
792 UpdateResponse::Result result
;
793 result
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
794 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
795 result
.crx_diffurls
.push_back(GURL("http://localhost/download/"));
796 result
.manifest
.version
= "2.0";
797 result
.manifest
.browser_min_version
= "11.0.1.0";
798 result
.manifest
.packages
.push_back(package
);
799 results
.list
.push_back(result
);
804 base::ThreadTaskRunnerHandle::Get()->PostTask(
805 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
810 class FakeCrxDownloader
: public CrxDownloader
{
812 static scoped_ptr
<CrxDownloader
> Create(
813 bool is_background_download
,
814 net::URLRequestContextGetter
* context_getter
,
815 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
816 const scoped_refptr
<base::SingleThreadTaskRunner
>&
817 background_task_runner
) {
818 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
822 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
823 ~FakeCrxDownloader() override
{}
825 void DoStartDownload(const GURL
& url
) override
{
826 DownloadMetrics download_metrics
;
829 if (url
.path() == "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
830 download_metrics
.url
= url
;
831 download_metrics
.downloader
= DownloadMetrics::kNone
;
832 download_metrics
.error
= 0;
833 download_metrics
.downloaded_bytes
= 53638;
834 download_metrics
.total_bytes
= 53638;
835 download_metrics
.download_time_ms
= 2000;
837 EXPECT_TRUE(MakeTestFile(
838 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path
));
841 result
.response
= path
;
842 result
.downloaded_bytes
= 53638;
843 result
.total_bytes
= 53638;
844 } else if (url
.path() ==
845 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx") {
846 download_metrics
.url
= url
;
847 download_metrics
.downloader
= DownloadMetrics::kNone
;
848 download_metrics
.error
= 0;
849 download_metrics
.downloaded_bytes
= 2105;
850 download_metrics
.total_bytes
= 2105;
851 download_metrics
.download_time_ms
= 1000;
853 EXPECT_TRUE(MakeTestFile(
854 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), &path
));
857 result
.response
= path
;
858 result
.downloaded_bytes
= 2105;
859 result
.total_bytes
= 2105;
864 base::ThreadTaskRunnerHandle::Get()->PostTask(
865 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
866 base::Unretained(this), result
));
868 base::ThreadTaskRunnerHandle::Get()->PostTask(
870 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
871 base::Unretained(this), true, result
, download_metrics
));
875 class FakePingManager
: public FakePingManagerImpl
{
877 explicit FakePingManager(const Configurator
& config
)
878 : FakePingManagerImpl(config
) {}
879 ~FakePingManager() override
{
880 const auto& ping_items
= items();
881 EXPECT_EQ(2U, ping_items
.size());
882 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[0].id
);
883 EXPECT_TRUE(base::Version("0.8").Equals(ping_items
[0].previous_version
));
884 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
885 EXPECT_EQ(0, ping_items
[0].error_category
);
886 EXPECT_EQ(0, ping_items
[0].error_code
);
887 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[1].id
);
888 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[1].previous_version
));
889 EXPECT_TRUE(base::Version("2.0").Equals(ping_items
[1].next_version
));
890 EXPECT_EQ(0, ping_items
[1].diff_error_category
);
891 EXPECT_EQ(0, ping_items
[1].diff_error_code
);
895 scoped_ptr
<FakePingManager
> ping_manager(new FakePingManager(*config()));
896 scoped_ptr
<UpdateClient
> update_client(new UpdateClientImpl(
897 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
898 &FakeCrxDownloader::Create
));
900 MockObserver observer
;
903 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
904 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
905 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
906 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
907 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
908 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
909 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
910 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
911 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
912 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
913 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
914 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
915 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
916 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
917 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
918 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
919 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
920 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
921 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
922 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
925 update_client
->AddObserver(&observer
);
927 std::vector
<std::string
> ids
;
928 ids
.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
931 base::RunLoop runloop
;
932 update_client
->Update(
933 ids
, base::Bind(&DataCallbackFake::Callback
),
934 base::Bind(&CompletionCallbackFake::Callback
, runloop
.QuitClosure()));
939 base::RunLoop runloop
;
940 update_client
->Update(
941 ids
, base::Bind(&DataCallbackFake::Callback
),
942 base::Bind(&CompletionCallbackFake::Callback
, runloop
.QuitClosure()));
946 update_client
->RemoveObserver(&observer
);
949 // Tests the update scenario for one CRX where the CRX installer returns
951 TEST_F(UpdateClientTest
, OneCrxInstallError
) {
952 class MockInstaller
: public CrxInstaller
{
954 MOCK_METHOD1(OnUpdateError
, void(int error
));
955 MOCK_METHOD2(Install
,
956 bool(const base::DictionaryValue
& manifest
,
957 const base::FilePath
& unpack_path
));
958 MOCK_METHOD2(GetInstalledFile
,
959 bool(const std::string
& file
, base::FilePath
* installed_file
));
960 MOCK_METHOD0(Uninstall
, bool());
962 static void OnInstall(const base::DictionaryValue
& manifest
,
963 const base::FilePath
& unpack_path
) {
964 base::DeleteFile(unpack_path
, true);
968 ~MockInstaller() override
{}
971 class DataCallbackFake
{
973 static void Callback(const std::vector
<std::string
>& ids
,
974 std::vector
<CrxComponent
>* components
) {
975 scoped_refptr
<MockInstaller
> installer(new MockInstaller());
977 EXPECT_CALL(*installer
, OnUpdateError(_
)).Times(0);
978 EXPECT_CALL(*installer
, Install(_
, _
))
979 .WillOnce(DoAll(Invoke(MockInstaller::OnInstall
), Return(false)));
980 EXPECT_CALL(*installer
, GetInstalledFile(_
, _
)).Times(0);
981 EXPECT_CALL(*installer
, Uninstall()).Times(0);
984 crx
.name
= "test_jebg";
985 crx
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
986 crx
.version
= Version("0.9");
987 crx
.installer
= installer
;
988 components
->push_back(crx
);
992 class CompletionCallbackFake
{
994 static void Callback(const base::Closure
& quit_closure
, int error
) {
1000 class FakeUpdateChecker
: public UpdateChecker
{
1002 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
1003 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
1006 bool CheckForUpdates(
1007 const std::vector
<CrxUpdateItem
*>& items_to_check
,
1008 const std::string
& additional_attributes
,
1009 const UpdateCheckCallback
& update_check_callback
) override
{
1011 Fake the following response:
1013 <?xml version='1.0' encoding='UTF-8'?>
1014 <response protocol='3.0'>
1015 <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
1016 <updatecheck status='ok'>
1018 <url codebase='http://localhost/download/'/>
1020 <manifest version='1.0' prodversionmin='11.0.1.0'>
1022 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
1029 UpdateResponse::Result::Manifest::Package package
;
1030 package
.name
= "jebgalgnebhfojomionfpkfelancnnkf.crx";
1032 UpdateResponse::Result result
;
1033 result
.extension_id
= "jebgalgnebhfojomionfpkfelancnnkf";
1034 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
1035 result
.manifest
.version
= "1.0";
1036 result
.manifest
.browser_min_version
= "11.0.1.0";
1037 result
.manifest
.packages
.push_back(package
);
1039 UpdateResponse::Results results
;
1040 results
.list
.push_back(result
);
1042 base::ThreadTaskRunnerHandle::Get()->PostTask(
1043 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
1048 class FakeCrxDownloader
: public CrxDownloader
{
1050 static scoped_ptr
<CrxDownloader
> Create(
1051 bool is_background_download
,
1052 net::URLRequestContextGetter
* context_getter
,
1053 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
1054 const scoped_refptr
<base::SingleThreadTaskRunner
>&
1055 background_task_runner
) {
1056 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
1060 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
1061 ~FakeCrxDownloader() override
{}
1063 void DoStartDownload(const GURL
& url
) override
{
1064 DownloadMetrics download_metrics
;
1065 download_metrics
.url
= url
;
1066 download_metrics
.downloader
= DownloadMetrics::kNone
;
1067 download_metrics
.error
= 0;
1068 download_metrics
.downloaded_bytes
= 1843;
1069 download_metrics
.total_bytes
= 1843;
1070 download_metrics
.download_time_ms
= 1000;
1073 EXPECT_TRUE(MakeTestFile(
1074 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path
));
1078 result
.response
= path
;
1079 result
.downloaded_bytes
= 1843;
1080 result
.total_bytes
= 1843;
1082 base::ThreadTaskRunnerHandle::Get()->PostTask(
1083 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
1084 base::Unretained(this), result
));
1086 base::ThreadTaskRunnerHandle::Get()->PostTask(
1088 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
1089 base::Unretained(this), true, result
, download_metrics
));
1093 class FakePingManager
: public FakePingManagerImpl
{
1095 explicit FakePingManager(const Configurator
& config
)
1096 : FakePingManagerImpl(config
) {}
1097 ~FakePingManager() override
{
1098 const auto& ping_items
= items();
1099 EXPECT_EQ(1U, ping_items
.size());
1100 EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items
[0].id
);
1101 EXPECT_TRUE(base::Version("0.9").Equals(ping_items
[0].previous_version
));
1102 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
1103 EXPECT_EQ(3, ping_items
[0].error_category
); // kInstallError.
1104 EXPECT_EQ(9, ping_items
[0].error_code
); // kInstallerError.
1108 scoped_ptr
<PingManager
> ping_manager(new FakePingManager(*config()));
1109 scoped_ptr
<UpdateClient
> update_client(new UpdateClientImpl(
1110 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
1111 &FakeCrxDownloader::Create
));
1113 MockObserver observer
;
1116 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1117 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1118 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
1119 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1120 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1121 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1122 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
1123 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1124 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_NOT_UPDATED
,
1125 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1128 update_client
->AddObserver(&observer
);
1130 std::vector
<std::string
> ids
;
1131 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
1133 update_client
->Update(
1134 ids
, base::Bind(&DataCallbackFake::Callback
),
1135 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
1139 update_client
->RemoveObserver(&observer
);
1142 // Tests the fallback from differential to full update scenario for one CRX.
1143 TEST_F(UpdateClientTest
, OneCrxDiffUpdateFailsFullUpdateSucceeds
) {
1144 class DataCallbackFake
{
1146 static void Callback(const std::vector
<std::string
>& ids
,
1147 std::vector
<CrxComponent
>* components
) {
1148 static int num_calls
= 0;
1150 // Must use the same stateful installer object.
1151 static scoped_refptr
<CrxInstaller
> installer(
1152 new VersionedTestInstaller());
1157 crx
.name
= "test_ihfo";
1158 crx
.pk_hash
.assign(ihfo_hash
, ihfo_hash
+ arraysize(ihfo_hash
));
1159 crx
.installer
= installer
;
1160 if (num_calls
== 1) {
1161 crx
.version
= Version("0.8");
1162 } else if (num_calls
== 2) {
1163 crx
.version
= Version("1.0");
1168 components
->push_back(crx
);
1172 class CompletionCallbackFake
{
1174 static void Callback(const base::Closure
& quit_closure
, int error
) {
1175 EXPECT_EQ(0, error
);
1180 class FakeUpdateChecker
: public UpdateChecker
{
1182 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
1183 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
1186 bool CheckForUpdates(
1187 const std::vector
<CrxUpdateItem
*>& items_to_check
,
1188 const std::string
& additional_attributes
,
1189 const UpdateCheckCallback
& update_check_callback
) override
{
1190 static int num_call
= 0;
1193 UpdateResponse::Results results
;
1195 if (num_call
== 1) {
1197 Fake the following response:
1198 <?xml version='1.0' encoding='UTF-8'?>
1199 <response protocol='3.0'>
1200 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
1201 <updatecheck status='ok'>
1203 <url codebase='http://localhost/download/'/>
1205 <manifest version='1.0' prodversionmin='11.0.1.0'>
1207 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
1214 UpdateResponse::Result::Manifest::Package package
;
1215 package
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
1216 package
.fingerprint
= "1";
1217 UpdateResponse::Result result
;
1218 result
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
1219 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
1220 result
.manifest
.version
= "1.0";
1221 result
.manifest
.browser_min_version
= "11.0.1.0";
1222 result
.manifest
.packages
.push_back(package
);
1223 results
.list
.push_back(result
);
1224 } else if (num_call
== 2) {
1226 Fake the following response:
1227 <?xml version='1.0' encoding='UTF-8'?>
1228 <response protocol='3.0'>
1229 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
1230 <updatecheck status='ok'>
1232 <url codebase='http://localhost/download/'/>
1233 <url codebasediff='http://localhost/download/'/>
1235 <manifest version='2.0' prodversionmin='11.0.1.0'>
1237 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_2.crx'
1238 namediff='ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx'
1246 UpdateResponse::Result::Manifest::Package package
;
1247 package
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
1248 package
.namediff
= "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
1249 package
.fingerprint
= "22";
1250 UpdateResponse::Result result
;
1251 result
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
1252 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
1253 result
.crx_diffurls
.push_back(GURL("http://localhost/download/"));
1254 result
.manifest
.version
= "2.0";
1255 result
.manifest
.browser_min_version
= "11.0.1.0";
1256 result
.manifest
.packages
.push_back(package
);
1257 results
.list
.push_back(result
);
1262 base::ThreadTaskRunnerHandle::Get()->PostTask(
1263 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
1268 class FakeCrxDownloader
: public CrxDownloader
{
1270 static scoped_ptr
<CrxDownloader
> Create(
1271 bool is_background_download
,
1272 net::URLRequestContextGetter
* context_getter
,
1273 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
1274 const scoped_refptr
<base::SingleThreadTaskRunner
>&
1275 background_task_runner
) {
1276 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
1280 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
1281 ~FakeCrxDownloader() override
{}
1283 void DoStartDownload(const GURL
& url
) override
{
1284 DownloadMetrics download_metrics
;
1287 if (url
.path() == "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
1288 download_metrics
.url
= url
;
1289 download_metrics
.downloader
= DownloadMetrics::kNone
;
1290 download_metrics
.error
= 0;
1291 download_metrics
.downloaded_bytes
= 53638;
1292 download_metrics
.total_bytes
= 53638;
1293 download_metrics
.download_time_ms
= 2000;
1295 EXPECT_TRUE(MakeTestFile(
1296 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path
));
1299 result
.response
= path
;
1300 result
.downloaded_bytes
= 53638;
1301 result
.total_bytes
= 53638;
1302 } else if (url
.path() ==
1303 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx") {
1304 // A download error is injected on this execution path.
1305 download_metrics
.url
= url
;
1306 download_metrics
.downloader
= DownloadMetrics::kNone
;
1307 download_metrics
.error
= -1;
1308 download_metrics
.downloaded_bytes
= 0;
1309 download_metrics
.total_bytes
= 2105;
1310 download_metrics
.download_time_ms
= 1000;
1312 EXPECT_TRUE(MakeTestFile(
1313 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), &path
));
1316 result
.response
= path
;
1317 result
.downloaded_bytes
= 0;
1318 result
.total_bytes
= 2105;
1319 } else if (url
.path() ==
1320 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx") {
1321 download_metrics
.url
= url
;
1322 download_metrics
.downloader
= DownloadMetrics::kNone
;
1323 download_metrics
.error
= 0;
1324 download_metrics
.downloaded_bytes
= 53855;
1325 download_metrics
.total_bytes
= 53855;
1326 download_metrics
.download_time_ms
= 1000;
1328 EXPECT_TRUE(MakeTestFile(
1329 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), &path
));
1332 result
.response
= path
;
1333 result
.downloaded_bytes
= 53855;
1334 result
.total_bytes
= 53855;
1337 base::ThreadTaskRunnerHandle::Get()->PostTask(
1338 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
1339 base::Unretained(this), result
));
1341 base::ThreadTaskRunnerHandle::Get()->PostTask(
1343 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
1344 base::Unretained(this), true, result
, download_metrics
));
1348 class FakePingManager
: public FakePingManagerImpl
{
1350 explicit FakePingManager(const Configurator
& config
)
1351 : FakePingManagerImpl(config
) {}
1352 ~FakePingManager() override
{
1353 const auto& ping_items
= items();
1354 EXPECT_EQ(2U, ping_items
.size());
1355 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[0].id
);
1356 EXPECT_TRUE(base::Version("0.8").Equals(ping_items
[0].previous_version
));
1357 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
1358 EXPECT_EQ(0, ping_items
[0].error_category
);
1359 EXPECT_EQ(0, ping_items
[0].error_code
);
1360 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[1].id
);
1361 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[1].previous_version
));
1362 EXPECT_TRUE(base::Version("2.0").Equals(ping_items
[1].next_version
));
1363 EXPECT_TRUE(ping_items
[1].diff_update_failed
);
1364 EXPECT_EQ(1, ping_items
[1].diff_error_category
); // kNetworkError.
1365 EXPECT_EQ(-1, ping_items
[1].diff_error_code
);
1369 scoped_ptr
<FakePingManager
> ping_manager(new FakePingManager(*config()));
1370 scoped_ptr
<UpdateClient
> update_client(new UpdateClientImpl(
1371 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
1372 &FakeCrxDownloader::Create
));
1374 MockObserver observer
;
1377 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1378 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1379 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
1380 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1381 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1382 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1383 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
1384 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1385 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
1386 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1388 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1389 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1390 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
1391 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1392 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1393 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1394 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1395 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1396 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
1397 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1398 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
1399 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1402 update_client
->AddObserver(&observer
);
1404 std::vector
<std::string
> ids
;
1405 ids
.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
1408 base::RunLoop runloop
;
1409 update_client
->Update(
1410 ids
, base::Bind(&DataCallbackFake::Callback
),
1411 base::Bind(&CompletionCallbackFake::Callback
, runloop
.QuitClosure()));
1416 base::RunLoop runloop
;
1417 update_client
->Update(
1418 ids
, base::Bind(&DataCallbackFake::Callback
),
1419 base::Bind(&CompletionCallbackFake::Callback
, runloop
.QuitClosure()));
1423 update_client
->RemoveObserver(&observer
);
1426 } // namespace update_client