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/values.h"
18 #include "base/version.h"
19 #include "components/update_client/crx_update_item.h"
20 #include "components/update_client/ping_manager.h"
21 #include "components/update_client/test_configurator.h"
22 #include "components/update_client/test_installer.h"
23 #include "components/update_client/update_checker.h"
24 #include "components/update_client/update_client_internal.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
29 namespace update_client
{
35 // Makes a copy of the file specified by |from_path| in a temporary directory
36 // and returns the path of the copy. Returns true if successful. Cleans up if
37 // there was an error creating the copy.
38 bool MakeTestFile(const FilePath
& from_path
, FilePath
* to_path
) {
41 CreateNewTempDirectory(FILE_PATH_LITERAL("update_client"), &temp_dir
);
46 result
= CreateTemporaryFileInDir(temp_dir
, &temp_file
);
50 result
= CopyFile(from_path
, temp_file
);
52 DeleteFile(temp_file
, false);
60 using Events
= UpdateClient::Observer::Events
;
62 class MockObserver
: public UpdateClient::Observer
{
64 MOCK_METHOD2(OnEvent
, void(Events event
, const std::string
&));
67 class OnDemandTester
{
69 OnDemandTester(const scoped_refptr
<UpdateClient
>& update_client
,
72 void CheckOnDemand(Events event
, const std::string
&);
75 const scoped_refptr
<UpdateClient
> update_client_
;
76 const bool expected_value_
;
79 OnDemandTester::OnDemandTester(const scoped_refptr
<UpdateClient
>& update_client
,
81 : update_client_(update_client
), expected_value_(expected_value
) {
84 void OnDemandTester::CheckOnDemand(Events event
, const std::string
& id
) {
85 if (event
== Events::COMPONENT_CHECKING_FOR_UPDATES
) {
86 CrxUpdateItem update_item
;
87 EXPECT_TRUE(update_client_
->GetCrxUpdateState(id
, &update_item
));
88 EXPECT_EQ(update_item
.on_demand
, expected_value_
);
92 class FakePingManagerImpl
: public PingManager
{
94 explicit FakePingManagerImpl(const Configurator
& config
);
95 ~FakePingManagerImpl() override
;
97 void OnUpdateComplete(const CrxUpdateItem
* item
) override
;
99 const std::vector
<CrxUpdateItem
>& items() const;
102 std::vector
<CrxUpdateItem
> items_
;
103 DISALLOW_COPY_AND_ASSIGN(FakePingManagerImpl
);
106 FakePingManagerImpl::FakePingManagerImpl(const Configurator
& config
)
107 : PingManager(config
) {
110 FakePingManagerImpl::~FakePingManagerImpl() {
113 void FakePingManagerImpl::OnUpdateComplete(const CrxUpdateItem
* item
) {
114 items_
.push_back(*item
);
117 const std::vector
<CrxUpdateItem
>& FakePingManagerImpl::items() const {
124 using ::testing::AnyNumber
;
125 using ::testing::DoAll
;
126 using ::testing::InSequence
;
127 using ::testing::Invoke
;
128 using ::testing::Mock
;
129 using ::testing::Return
;
133 class UpdateClientTest
: public testing::Test
{
136 ~UpdateClientTest() override
;
140 void StopWorkerPool();
142 // Returns the full path to a test file.
143 static base::FilePath
TestFilePath(const char* file
);
145 scoped_refptr
<update_client::Configurator
> config() { return config_
; }
147 base::Closure
quit_closure() { return quit_closure_
; }
150 static const int kNumWorkerThreads_
= 2;
152 base::MessageLoopForUI message_loop_
;
153 base::RunLoop runloop_
;
154 base::Closure quit_closure_
;
156 scoped_ptr
<base::SequencedWorkerPoolOwner
> worker_pool_
;
158 scoped_refptr
<update_client::Configurator
> config_
;
160 DISALLOW_COPY_AND_ASSIGN(UpdateClientTest
);
163 UpdateClientTest::UpdateClientTest()
165 new base::SequencedWorkerPoolOwner(kNumWorkerThreads_
, "test")) {
166 quit_closure_
= runloop_
.QuitClosure();
168 auto pool
= worker_pool_
->pool();
169 config_
= new TestConfigurator(
170 pool
->GetSequencedTaskRunner(pool
->GetSequenceToken()),
171 message_loop_
.task_runner());
174 UpdateClientTest::~UpdateClientTest() {
177 void UpdateClientTest::RunThreads() {
181 void UpdateClientTest::StopWorkerPool() {
182 worker_pool_
->pool()->Shutdown();
185 base::FilePath
UpdateClientTest::TestFilePath(const char* file
) {
187 PathService::Get(base::DIR_SOURCE_ROOT
, &path
);
188 return path
.AppendASCII("components")
191 .AppendASCII("update_client")
195 // Tests the scenario where one update check is done for one CRX. The CRX
197 TEST_F(UpdateClientTest
, OneCrxNoUpdate
) {
198 class DataCallbackFake
{
200 static void Callback(const std::vector
<std::string
>& ids
,
201 std::vector
<CrxComponent
>* components
) {
203 crx
.name
= "test_jebg";
204 crx
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
205 crx
.version
= Version("0.9");
206 crx
.installer
= new TestInstaller
;
207 components
->push_back(crx
);
211 class CompletionCallbackFake
{
213 static void Callback(const base::Closure
& quit_closure
, int error
) {
219 class FakeUpdateChecker
: public UpdateChecker
{
221 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
222 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
225 bool CheckForUpdates(
226 const std::vector
<CrxUpdateItem
*>& items_to_check
,
227 const std::string
& additional_attributes
,
228 const UpdateCheckCallback
& update_check_callback
) override
{
229 base::ThreadTaskRunnerHandle::Get()->PostTask(
230 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "",
231 UpdateResponse::Results()));
236 class FakeCrxDownloader
: public CrxDownloader
{
238 static scoped_ptr
<CrxDownloader
> Create(
239 bool is_background_download
,
240 net::URLRequestContextGetter
* context_getter
,
241 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
242 const scoped_refptr
<base::SingleThreadTaskRunner
>&
243 background_task_runner
) {
244 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
248 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
249 ~FakeCrxDownloader() override
{}
251 void DoStartDownload(const GURL
& url
) override
{ EXPECT_TRUE(false); }
254 class FakePingManager
: public FakePingManagerImpl
{
256 explicit FakePingManager(const Configurator
& config
)
257 : FakePingManagerImpl(config
) {}
258 ~FakePingManager() override
{ EXPECT_TRUE(items().empty()); }
261 scoped_ptr
<PingManager
> ping_manager(new FakePingManager(*config()));
262 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
263 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
264 &FakeCrxDownloader::Create
));
266 // Verify that calling Update does not set ondemand.
267 OnDemandTester
ondemand_tester(update_client
, false);
269 MockObserver observer
;
270 ON_CALL(observer
, OnEvent(_
, _
))
271 .WillByDefault(Invoke(&ondemand_tester
, &OnDemandTester::CheckOnDemand
));
274 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
275 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
276 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_NOT_UPDATED
,
277 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
279 update_client
->AddObserver(&observer
);
281 std::vector
<std::string
> ids
;
282 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
284 update_client
->Update(
285 ids
, base::Bind(&DataCallbackFake::Callback
),
286 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
290 update_client
->RemoveObserver(&observer
);
295 // Tests the scenario where two CRXs are checked for updates. On CRX has
296 // an update, the other CRX does not.
297 TEST_F(UpdateClientTest
, TwoCrxUpdateNoUpdate
) {
298 class DataCallbackFake
{
300 static void Callback(const std::vector
<std::string
>& ids
,
301 std::vector
<CrxComponent
>* components
) {
303 crx1
.name
= "test_jebg";
304 crx1
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
305 crx1
.version
= Version("0.9");
306 crx1
.installer
= new TestInstaller
;
309 crx2
.name
= "test_abag";
310 crx2
.pk_hash
.assign(abag_hash
, abag_hash
+ arraysize(abag_hash
));
311 crx2
.version
= Version("2.2");
312 crx2
.installer
= new TestInstaller
;
314 components
->push_back(crx1
);
315 components
->push_back(crx2
);
319 class CompletionCallbackFake
{
321 static void Callback(const base::Closure
& quit_closure
, int error
) {
327 class FakeUpdateChecker
: public UpdateChecker
{
329 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
330 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
333 bool CheckForUpdates(
334 const std::vector
<CrxUpdateItem
*>& items_to_check
,
335 const std::string
& additional_attributes
,
336 const UpdateCheckCallback
& update_check_callback
) override
{
338 Fake the following response:
340 <?xml version='1.0' encoding='UTF-8'?>
341 <response protocol='3.0'>
342 <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
343 <updatecheck status='ok'>
345 <url codebase='http://localhost/download/'/>
347 <manifest version='1.0' prodversionmin='11.0.1.0'>
349 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
356 UpdateResponse::Result::Manifest::Package package
;
357 package
.name
= "jebgalgnebhfojomionfpkfelancnnkf.crx";
359 UpdateResponse::Result result
;
360 result
.extension_id
= "jebgalgnebhfojomionfpkfelancnnkf";
361 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
362 result
.manifest
.version
= "1.0";
363 result
.manifest
.browser_min_version
= "11.0.1.0";
364 result
.manifest
.packages
.push_back(package
);
366 UpdateResponse::Results results
;
367 results
.list
.push_back(result
);
369 base::ThreadTaskRunnerHandle::Get()->PostTask(
370 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
375 class FakeCrxDownloader
: public CrxDownloader
{
377 static scoped_ptr
<CrxDownloader
> Create(
378 bool is_background_download
,
379 net::URLRequestContextGetter
* context_getter
,
380 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
381 const scoped_refptr
<base::SingleThreadTaskRunner
>&
382 background_task_runner
) {
383 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
387 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
388 ~FakeCrxDownloader() override
{}
390 void DoStartDownload(const GURL
& url
) override
{
391 DownloadMetrics download_metrics
;
392 download_metrics
.url
= url
;
393 download_metrics
.downloader
= DownloadMetrics::kNone
;
394 download_metrics
.error
= 0;
395 download_metrics
.downloaded_bytes
= 1843;
396 download_metrics
.total_bytes
= 1843;
397 download_metrics
.download_time_ms
= 1000;
400 EXPECT_TRUE(MakeTestFile(
401 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path
));
405 result
.response
= path
;
406 result
.downloaded_bytes
= 1843;
407 result
.total_bytes
= 1843;
409 base::ThreadTaskRunnerHandle::Get()->PostTask(
410 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
411 base::Unretained(this), result
));
413 base::ThreadTaskRunnerHandle::Get()->PostTask(
415 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
416 base::Unretained(this), true, result
, download_metrics
));
420 class FakePingManager
: public FakePingManagerImpl
{
422 explicit FakePingManager(const Configurator
& config
)
423 : FakePingManagerImpl(config
) {}
424 ~FakePingManager() override
{
425 const auto& ping_items
= items();
426 EXPECT_EQ(1U, ping_items
.size());
427 EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items
[0].id
);
428 EXPECT_TRUE(base::Version("0.9").Equals(ping_items
[0].previous_version
));
429 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
430 EXPECT_EQ(0, ping_items
[0].error_category
);
431 EXPECT_EQ(0, ping_items
[0].error_code
);
435 scoped_ptr
<PingManager
> ping_manager(new FakePingManager(*config()));
436 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
437 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
438 &FakeCrxDownloader::Create
));
440 MockObserver observer
;
443 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
444 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
445 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
446 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
447 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
448 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
449 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
450 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
451 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
452 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
456 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
457 "abagagagagagagagagagagagagagagag")).Times(1);
458 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_NOT_UPDATED
,
459 "abagagagagagagagagagagagagagagag")).Times(1);
462 update_client
->AddObserver(&observer
);
464 std::vector
<std::string
> ids
;
465 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
466 ids
.push_back(std::string("abagagagagagagagagagagagagagagag"));
468 update_client
->Update(
469 ids
, base::Bind(&DataCallbackFake::Callback
),
470 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
474 update_client
->RemoveObserver(&observer
);
479 // Tests the update check for two CRXs scenario. Both CRXs have updates.
480 TEST_F(UpdateClientTest
, TwoCrxUpdate
) {
481 class DataCallbackFake
{
483 static void Callback(const std::vector
<std::string
>& ids
,
484 std::vector
<CrxComponent
>* components
) {
486 crx1
.name
= "test_jebg";
487 crx1
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
488 crx1
.version
= Version("0.9");
489 crx1
.installer
= new TestInstaller
;
492 crx2
.name
= "test_ihfo";
493 crx2
.pk_hash
.assign(ihfo_hash
, ihfo_hash
+ arraysize(ihfo_hash
));
494 crx2
.version
= Version("0.8");
495 crx2
.installer
= new TestInstaller
;
497 components
->push_back(crx1
);
498 components
->push_back(crx2
);
502 class CompletionCallbackFake
{
504 static void Callback(const base::Closure
& quit_closure
, int error
) {
510 class FakeUpdateChecker
: public UpdateChecker
{
512 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
513 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
516 bool CheckForUpdates(
517 const std::vector
<CrxUpdateItem
*>& items_to_check
,
518 const std::string
& additional_attributes
,
519 const UpdateCheckCallback
& update_check_callback
) override
{
521 Fake the following response:
523 <?xml version='1.0' encoding='UTF-8'?>
524 <response protocol='3.0'>
525 <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
526 <updatecheck status='ok'>
528 <url codebase='http://localhost/download/'/>
530 <manifest version='1.0' prodversionmin='11.0.1.0'>
532 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
537 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
538 <updatecheck status='ok'>
540 <url codebase='http://localhost/download/'/>
542 <manifest version='1.0' prodversionmin='11.0.1.0'>
544 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
551 UpdateResponse::Result::Manifest::Package package1
;
552 package1
.name
= "jebgalgnebhfojomionfpkfelancnnkf.crx";
554 UpdateResponse::Result result1
;
555 result1
.extension_id
= "jebgalgnebhfojomionfpkfelancnnkf";
556 result1
.crx_urls
.push_back(GURL("http://localhost/download/"));
557 result1
.manifest
.version
= "1.0";
558 result1
.manifest
.browser_min_version
= "11.0.1.0";
559 result1
.manifest
.packages
.push_back(package1
);
561 UpdateResponse::Result::Manifest::Package package2
;
562 package2
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
564 UpdateResponse::Result result2
;
565 result2
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
566 result2
.crx_urls
.push_back(GURL("http://localhost/download/"));
567 result2
.manifest
.version
= "1.0";
568 result2
.manifest
.browser_min_version
= "11.0.1.0";
569 result2
.manifest
.packages
.push_back(package2
);
571 UpdateResponse::Results results
;
572 results
.list
.push_back(result1
);
573 results
.list
.push_back(result2
);
575 base::ThreadTaskRunnerHandle::Get()->PostTask(
576 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
581 class FakeCrxDownloader
: public CrxDownloader
{
583 static scoped_ptr
<CrxDownloader
> Create(
584 bool is_background_download
,
585 net::URLRequestContextGetter
* context_getter
,
586 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
587 const scoped_refptr
<base::SingleThreadTaskRunner
>&
588 background_task_runner
) {
589 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
593 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
594 ~FakeCrxDownloader() override
{}
596 void DoStartDownload(const GURL
& url
) override
{
597 DownloadMetrics download_metrics
;
600 if (url
.path() == "/download/jebgalgnebhfojomionfpkfelancnnkf.crx") {
601 download_metrics
.url
= url
;
602 download_metrics
.downloader
= DownloadMetrics::kNone
;
603 download_metrics
.error
= 0;
604 download_metrics
.downloaded_bytes
= 1843;
605 download_metrics
.total_bytes
= 1843;
606 download_metrics
.download_time_ms
= 1000;
608 EXPECT_TRUE(MakeTestFile(
609 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path
));
612 result
.response
= path
;
613 result
.downloaded_bytes
= 1843;
614 result
.total_bytes
= 1843;
615 } else if (url
.path() ==
616 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
617 download_metrics
.url
= url
;
618 download_metrics
.downloader
= DownloadMetrics::kNone
;
619 download_metrics
.error
= 0;
620 download_metrics
.downloaded_bytes
= 53638;
621 download_metrics
.total_bytes
= 53638;
622 download_metrics
.download_time_ms
= 2000;
624 EXPECT_TRUE(MakeTestFile(
625 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path
));
628 result
.response
= path
;
629 result
.downloaded_bytes
= 53638;
630 result
.total_bytes
= 53638;
635 base::ThreadTaskRunnerHandle::Get()->PostTask(
636 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
637 base::Unretained(this), result
));
639 base::ThreadTaskRunnerHandle::Get()->PostTask(
641 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
642 base::Unretained(this), true, result
, download_metrics
));
646 class FakePingManager
: public FakePingManagerImpl
{
648 explicit FakePingManager(const Configurator
& config
)
649 : FakePingManagerImpl(config
) {}
650 ~FakePingManager() override
{
651 const auto& ping_items
= items();
652 EXPECT_EQ(2U, ping_items
.size());
653 EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items
[0].id
);
654 EXPECT_TRUE(base::Version("0.9").Equals(ping_items
[0].previous_version
));
655 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
656 EXPECT_EQ(0, ping_items
[0].error_category
);
657 EXPECT_EQ(0, ping_items
[0].error_code
);
658 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[1].id
);
659 EXPECT_TRUE(base::Version("0.8").Equals(ping_items
[1].previous_version
));
660 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[1].next_version
));
661 EXPECT_EQ(0, ping_items
[1].error_category
);
662 EXPECT_EQ(0, ping_items
[1].error_code
);
666 scoped_ptr
<FakePingManager
> ping_manager(new FakePingManager(*config()));
667 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
668 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
669 &FakeCrxDownloader::Create
));
671 MockObserver observer
;
674 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
675 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
676 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
677 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
678 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
679 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
680 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
681 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
682 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
683 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
687 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
688 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
689 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
690 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
691 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_WAIT
,
692 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
693 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
694 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
695 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
696 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
697 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
698 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
701 update_client
->AddObserver(&observer
);
703 std::vector
<std::string
> ids
;
704 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
705 ids
.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
707 update_client
->Update(
708 ids
, base::Bind(&DataCallbackFake::Callback
),
709 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
713 update_client
->RemoveObserver(&observer
);
718 // Tests the scenario where there is a download timeout for the first
719 // CRX. The update for the first CRX fails. The update client waits before
720 // attempting the update for the second CRX. This update succeeds.
721 TEST_F(UpdateClientTest
, TwoCrxUpdateDownloadTimeout
) {
722 class DataCallbackFake
{
724 static void Callback(const std::vector
<std::string
>& ids
,
725 std::vector
<CrxComponent
>* components
) {
727 crx1
.name
= "test_jebg";
728 crx1
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
729 crx1
.version
= Version("0.9");
730 crx1
.installer
= new TestInstaller
;
733 crx2
.name
= "test_ihfo";
734 crx2
.pk_hash
.assign(ihfo_hash
, ihfo_hash
+ arraysize(ihfo_hash
));
735 crx2
.version
= Version("0.8");
736 crx2
.installer
= new TestInstaller
;
738 components
->push_back(crx1
);
739 components
->push_back(crx2
);
743 class CompletionCallbackFake
{
745 static void Callback(const base::Closure
& quit_closure
, int error
) {
751 class FakeUpdateChecker
: public UpdateChecker
{
753 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
754 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
757 bool CheckForUpdates(
758 const std::vector
<CrxUpdateItem
*>& items_to_check
,
759 const std::string
& additional_attributes
,
760 const UpdateCheckCallback
& update_check_callback
) override
{
762 Fake the following response:
764 <?xml version='1.0' encoding='UTF-8'?>
765 <response protocol='3.0'>
766 <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
767 <updatecheck status='ok'>
769 <url codebase='http://localhost/download/'/>
771 <manifest version='1.0' prodversionmin='11.0.1.0'>
773 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
778 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
779 <updatecheck status='ok'>
781 <url codebase='http://localhost/download/'/>
783 <manifest version='1.0' prodversionmin='11.0.1.0'>
785 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
792 UpdateResponse::Result::Manifest::Package package1
;
793 package1
.name
= "jebgalgnebhfojomionfpkfelancnnkf.crx";
795 UpdateResponse::Result result1
;
796 result1
.extension_id
= "jebgalgnebhfojomionfpkfelancnnkf";
797 result1
.crx_urls
.push_back(GURL("http://localhost/download/"));
798 result1
.manifest
.version
= "1.0";
799 result1
.manifest
.browser_min_version
= "11.0.1.0";
800 result1
.manifest
.packages
.push_back(package1
);
802 UpdateResponse::Result::Manifest::Package package2
;
803 package2
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
805 UpdateResponse::Result result2
;
806 result2
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
807 result2
.crx_urls
.push_back(GURL("http://localhost/download/"));
808 result2
.manifest
.version
= "1.0";
809 result2
.manifest
.browser_min_version
= "11.0.1.0";
810 result2
.manifest
.packages
.push_back(package2
);
812 UpdateResponse::Results results
;
813 results
.list
.push_back(result1
);
814 results
.list
.push_back(result2
);
816 base::ThreadTaskRunnerHandle::Get()->PostTask(
817 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
822 class FakeCrxDownloader
: public CrxDownloader
{
824 static scoped_ptr
<CrxDownloader
> Create(
825 bool is_background_download
,
826 net::URLRequestContextGetter
* context_getter
,
827 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
828 const scoped_refptr
<base::SingleThreadTaskRunner
>&
829 background_task_runner
) {
830 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
834 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
835 ~FakeCrxDownloader() override
{}
837 void DoStartDownload(const GURL
& url
) override
{
838 DownloadMetrics download_metrics
;
841 if (url
.path() == "/download/jebgalgnebhfojomionfpkfelancnnkf.crx") {
842 download_metrics
.url
= url
;
843 download_metrics
.downloader
= DownloadMetrics::kNone
;
844 download_metrics
.error
= -118;
845 download_metrics
.downloaded_bytes
= 0;
846 download_metrics
.total_bytes
= 0;
847 download_metrics
.download_time_ms
= 1000;
849 EXPECT_TRUE(MakeTestFile(
850 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path
));
853 result
.response
= path
;
854 result
.downloaded_bytes
= 0;
855 result
.total_bytes
= 0;
856 } else if (url
.path() ==
857 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
858 download_metrics
.url
= url
;
859 download_metrics
.downloader
= DownloadMetrics::kNone
;
860 download_metrics
.error
= 0;
861 download_metrics
.downloaded_bytes
= 53638;
862 download_metrics
.total_bytes
= 53638;
863 download_metrics
.download_time_ms
= 2000;
865 EXPECT_TRUE(MakeTestFile(
866 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path
));
869 result
.response
= path
;
870 result
.downloaded_bytes
= 53638;
871 result
.total_bytes
= 53638;
876 base::ThreadTaskRunnerHandle::Get()->PostTask(
877 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
878 base::Unretained(this), result
));
880 base::ThreadTaskRunnerHandle::Get()->PostTask(
882 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
883 base::Unretained(this), true, result
, download_metrics
));
887 class FakePingManager
: public FakePingManagerImpl
{
889 explicit FakePingManager(const Configurator
& config
)
890 : FakePingManagerImpl(config
) {}
891 ~FakePingManager() override
{
892 const auto& ping_items
= items();
893 EXPECT_EQ(2U, ping_items
.size());
894 EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items
[0].id
);
895 EXPECT_TRUE(base::Version("0.9").Equals(ping_items
[0].previous_version
));
896 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
897 EXPECT_EQ(1, ping_items
[0].error_category
); // Network error.
898 EXPECT_EQ(-118, ping_items
[0].error_code
);
899 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[1].id
);
900 EXPECT_TRUE(base::Version("0.8").Equals(ping_items
[1].previous_version
));
901 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[1].next_version
));
902 EXPECT_EQ(0, ping_items
[1].error_category
);
903 EXPECT_EQ(0, ping_items
[1].error_code
);
907 scoped_ptr
<FakePingManager
> ping_manager(new FakePingManager(*config()));
908 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
909 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
910 &FakeCrxDownloader::Create
));
912 MockObserver observer
;
915 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
916 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
917 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
918 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
919 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
920 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
921 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_NOT_UPDATED
,
922 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
926 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
927 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
928 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
929 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
930 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_WAIT
,
931 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
932 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
933 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
934 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
935 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
936 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
937 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
940 update_client
->AddObserver(&observer
);
942 std::vector
<std::string
> ids
;
943 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
944 ids
.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
946 update_client
->Update(
947 ids
, base::Bind(&DataCallbackFake::Callback
),
948 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
952 update_client
->RemoveObserver(&observer
);
957 // Tests the differential update scenario for one CRX.
958 TEST_F(UpdateClientTest
, OneCrxDiffUpdate
) {
959 class DataCallbackFake
{
961 static void Callback(const std::vector
<std::string
>& ids
,
962 std::vector
<CrxComponent
>* components
) {
963 static int num_calls
= 0;
965 // Must use the same stateful installer object.
966 static scoped_refptr
<CrxInstaller
> installer(
967 new VersionedTestInstaller());
972 crx
.name
= "test_ihfo";
973 crx
.pk_hash
.assign(ihfo_hash
, ihfo_hash
+ arraysize(ihfo_hash
));
974 crx
.installer
= installer
;
975 if (num_calls
== 1) {
976 crx
.version
= Version("0.8");
977 } else if (num_calls
== 2) {
978 crx
.version
= Version("1.0");
983 components
->push_back(crx
);
987 class CompletionCallbackFake
{
989 static void Callback(const base::Closure
& quit_closure
, int error
) {
995 class FakeUpdateChecker
: public UpdateChecker
{
997 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
998 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
1001 bool CheckForUpdates(
1002 const std::vector
<CrxUpdateItem
*>& items_to_check
,
1003 const std::string
& additional_attributes
,
1004 const UpdateCheckCallback
& update_check_callback
) override
{
1005 static int num_call
= 0;
1008 UpdateResponse::Results results
;
1010 if (num_call
== 1) {
1012 Fake the following response:
1013 <?xml version='1.0' encoding='UTF-8'?>
1014 <response protocol='3.0'>
1015 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
1016 <updatecheck status='ok'>
1018 <url codebase='http://localhost/download/'/>
1020 <manifest version='1.0' prodversionmin='11.0.1.0'>
1022 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
1029 UpdateResponse::Result::Manifest::Package package
;
1030 package
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
1031 package
.fingerprint
= "1";
1032 UpdateResponse::Result result
;
1033 result
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
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
);
1038 results
.list
.push_back(result
);
1039 } else if (num_call
== 2) {
1041 Fake the following response:
1042 <?xml version='1.0' encoding='UTF-8'?>
1043 <response protocol='3.0'>
1044 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
1045 <updatecheck status='ok'>
1047 <url codebase='http://localhost/download/'/>
1048 <url codebasediff='http://localhost/download/'/>
1050 <manifest version='2.0' prodversionmin='11.0.1.0'>
1052 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_2.crx'
1053 namediff='ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx'
1061 UpdateResponse::Result::Manifest::Package package
;
1062 package
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
1063 package
.namediff
= "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
1064 package
.fingerprint
= "22";
1065 UpdateResponse::Result result
;
1066 result
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
1067 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
1068 result
.crx_diffurls
.push_back(GURL("http://localhost/download/"));
1069 result
.manifest
.version
= "2.0";
1070 result
.manifest
.browser_min_version
= "11.0.1.0";
1071 result
.manifest
.packages
.push_back(package
);
1072 results
.list
.push_back(result
);
1077 base::ThreadTaskRunnerHandle::Get()->PostTask(
1078 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
1083 class FakeCrxDownloader
: public CrxDownloader
{
1085 static scoped_ptr
<CrxDownloader
> Create(
1086 bool is_background_download
,
1087 net::URLRequestContextGetter
* context_getter
,
1088 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
1089 const scoped_refptr
<base::SingleThreadTaskRunner
>&
1090 background_task_runner
) {
1091 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
1095 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
1096 ~FakeCrxDownloader() override
{}
1098 void DoStartDownload(const GURL
& url
) override
{
1099 DownloadMetrics download_metrics
;
1102 if (url
.path() == "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
1103 download_metrics
.url
= url
;
1104 download_metrics
.downloader
= DownloadMetrics::kNone
;
1105 download_metrics
.error
= 0;
1106 download_metrics
.downloaded_bytes
= 53638;
1107 download_metrics
.total_bytes
= 53638;
1108 download_metrics
.download_time_ms
= 2000;
1110 EXPECT_TRUE(MakeTestFile(
1111 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path
));
1114 result
.response
= path
;
1115 result
.downloaded_bytes
= 53638;
1116 result
.total_bytes
= 53638;
1117 } else if (url
.path() ==
1118 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx") {
1119 download_metrics
.url
= url
;
1120 download_metrics
.downloader
= DownloadMetrics::kNone
;
1121 download_metrics
.error
= 0;
1122 download_metrics
.downloaded_bytes
= 2105;
1123 download_metrics
.total_bytes
= 2105;
1124 download_metrics
.download_time_ms
= 1000;
1126 EXPECT_TRUE(MakeTestFile(
1127 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), &path
));
1130 result
.response
= path
;
1131 result
.downloaded_bytes
= 2105;
1132 result
.total_bytes
= 2105;
1137 base::ThreadTaskRunnerHandle::Get()->PostTask(
1138 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
1139 base::Unretained(this), result
));
1141 base::ThreadTaskRunnerHandle::Get()->PostTask(
1143 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
1144 base::Unretained(this), true, result
, download_metrics
));
1148 class FakePingManager
: public FakePingManagerImpl
{
1150 explicit FakePingManager(const Configurator
& config
)
1151 : FakePingManagerImpl(config
) {}
1152 ~FakePingManager() override
{
1153 const auto& ping_items
= items();
1154 EXPECT_EQ(2U, ping_items
.size());
1155 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[0].id
);
1156 EXPECT_TRUE(base::Version("0.8").Equals(ping_items
[0].previous_version
));
1157 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
1158 EXPECT_EQ(0, ping_items
[0].error_category
);
1159 EXPECT_EQ(0, ping_items
[0].error_code
);
1160 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[1].id
);
1161 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[1].previous_version
));
1162 EXPECT_TRUE(base::Version("2.0").Equals(ping_items
[1].next_version
));
1163 EXPECT_EQ(0, ping_items
[1].diff_error_category
);
1164 EXPECT_EQ(0, ping_items
[1].diff_error_code
);
1168 scoped_ptr
<FakePingManager
> ping_manager(new FakePingManager(*config()));
1169 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
1170 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
1171 &FakeCrxDownloader::Create
));
1173 MockObserver observer
;
1176 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1177 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1178 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
1179 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1180 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1181 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1182 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
1183 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1184 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
1185 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1186 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1187 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1188 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
1189 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1190 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1191 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1192 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
1193 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1194 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
1195 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1198 update_client
->AddObserver(&observer
);
1200 std::vector
<std::string
> ids
;
1201 ids
.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
1204 base::RunLoop runloop
;
1205 update_client
->Update(
1206 ids
, base::Bind(&DataCallbackFake::Callback
),
1207 base::Bind(&CompletionCallbackFake::Callback
, runloop
.QuitClosure()));
1212 base::RunLoop runloop
;
1213 update_client
->Update(
1214 ids
, base::Bind(&DataCallbackFake::Callback
),
1215 base::Bind(&CompletionCallbackFake::Callback
, runloop
.QuitClosure()));
1219 update_client
->RemoveObserver(&observer
);
1224 // Tests the update scenario for one CRX where the CRX installer returns
1226 TEST_F(UpdateClientTest
, OneCrxInstallError
) {
1227 class MockInstaller
: public CrxInstaller
{
1229 MOCK_METHOD1(OnUpdateError
, void(int error
));
1230 MOCK_METHOD2(Install
,
1231 bool(const base::DictionaryValue
& manifest
,
1232 const base::FilePath
& unpack_path
));
1233 MOCK_METHOD2(GetInstalledFile
,
1234 bool(const std::string
& file
, base::FilePath
* installed_file
));
1235 MOCK_METHOD0(Uninstall
, bool());
1237 static void OnInstall(const base::DictionaryValue
& manifest
,
1238 const base::FilePath
& unpack_path
) {
1239 base::DeleteFile(unpack_path
, true);
1243 ~MockInstaller() override
{}
1246 class DataCallbackFake
{
1248 static void Callback(const std::vector
<std::string
>& ids
,
1249 std::vector
<CrxComponent
>* components
) {
1250 scoped_refptr
<MockInstaller
> installer(new MockInstaller());
1252 EXPECT_CALL(*installer
, OnUpdateError(_
)).Times(0);
1253 EXPECT_CALL(*installer
, Install(_
, _
))
1254 .WillOnce(DoAll(Invoke(MockInstaller::OnInstall
), Return(false)));
1255 EXPECT_CALL(*installer
, GetInstalledFile(_
, _
)).Times(0);
1256 EXPECT_CALL(*installer
, Uninstall()).Times(0);
1259 crx
.name
= "test_jebg";
1260 crx
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
1261 crx
.version
= Version("0.9");
1262 crx
.installer
= installer
;
1263 components
->push_back(crx
);
1267 class CompletionCallbackFake
{
1269 static void Callback(const base::Closure
& quit_closure
, int error
) {
1270 EXPECT_EQ(0, error
);
1275 class FakeUpdateChecker
: public UpdateChecker
{
1277 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
1278 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
1281 bool CheckForUpdates(
1282 const std::vector
<CrxUpdateItem
*>& items_to_check
,
1283 const std::string
& additional_attributes
,
1284 const UpdateCheckCallback
& update_check_callback
) override
{
1286 Fake the following response:
1288 <?xml version='1.0' encoding='UTF-8'?>
1289 <response protocol='3.0'>
1290 <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
1291 <updatecheck status='ok'>
1293 <url codebase='http://localhost/download/'/>
1295 <manifest version='1.0' prodversionmin='11.0.1.0'>
1297 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
1304 UpdateResponse::Result::Manifest::Package package
;
1305 package
.name
= "jebgalgnebhfojomionfpkfelancnnkf.crx";
1307 UpdateResponse::Result result
;
1308 result
.extension_id
= "jebgalgnebhfojomionfpkfelancnnkf";
1309 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
1310 result
.manifest
.version
= "1.0";
1311 result
.manifest
.browser_min_version
= "11.0.1.0";
1312 result
.manifest
.packages
.push_back(package
);
1314 UpdateResponse::Results results
;
1315 results
.list
.push_back(result
);
1317 base::ThreadTaskRunnerHandle::Get()->PostTask(
1318 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
1323 class FakeCrxDownloader
: public CrxDownloader
{
1325 static scoped_ptr
<CrxDownloader
> Create(
1326 bool is_background_download
,
1327 net::URLRequestContextGetter
* context_getter
,
1328 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
1329 const scoped_refptr
<base::SingleThreadTaskRunner
>&
1330 background_task_runner
) {
1331 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
1335 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
1336 ~FakeCrxDownloader() override
{}
1338 void DoStartDownload(const GURL
& url
) override
{
1339 DownloadMetrics download_metrics
;
1340 download_metrics
.url
= url
;
1341 download_metrics
.downloader
= DownloadMetrics::kNone
;
1342 download_metrics
.error
= 0;
1343 download_metrics
.downloaded_bytes
= 1843;
1344 download_metrics
.total_bytes
= 1843;
1345 download_metrics
.download_time_ms
= 1000;
1348 EXPECT_TRUE(MakeTestFile(
1349 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path
));
1353 result
.response
= path
;
1354 result
.downloaded_bytes
= 1843;
1355 result
.total_bytes
= 1843;
1357 base::ThreadTaskRunnerHandle::Get()->PostTask(
1358 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
1359 base::Unretained(this), result
));
1361 base::ThreadTaskRunnerHandle::Get()->PostTask(
1363 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
1364 base::Unretained(this), true, result
, download_metrics
));
1368 class FakePingManager
: public FakePingManagerImpl
{
1370 explicit FakePingManager(const Configurator
& config
)
1371 : FakePingManagerImpl(config
) {}
1372 ~FakePingManager() override
{
1373 const auto& ping_items
= items();
1374 EXPECT_EQ(1U, ping_items
.size());
1375 EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items
[0].id
);
1376 EXPECT_TRUE(base::Version("0.9").Equals(ping_items
[0].previous_version
));
1377 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
1378 EXPECT_EQ(3, ping_items
[0].error_category
); // kInstallError.
1379 EXPECT_EQ(9, ping_items
[0].error_code
); // kInstallerError.
1383 scoped_ptr
<PingManager
> ping_manager(new FakePingManager(*config()));
1384 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
1385 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
1386 &FakeCrxDownloader::Create
));
1388 MockObserver observer
;
1391 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1392 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1393 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
1394 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1395 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1396 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1397 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
1398 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1399 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_NOT_UPDATED
,
1400 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1403 update_client
->AddObserver(&observer
);
1405 std::vector
<std::string
> ids
;
1406 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
1408 update_client
->Update(
1409 ids
, base::Bind(&DataCallbackFake::Callback
),
1410 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
1414 update_client
->RemoveObserver(&observer
);
1419 // Tests the fallback from differential to full update scenario for one CRX.
1420 TEST_F(UpdateClientTest
, OneCrxDiffUpdateFailsFullUpdateSucceeds
) {
1421 class DataCallbackFake
{
1423 static void Callback(const std::vector
<std::string
>& ids
,
1424 std::vector
<CrxComponent
>* components
) {
1425 static int num_calls
= 0;
1427 // Must use the same stateful installer object.
1428 static scoped_refptr
<CrxInstaller
> installer(
1429 new VersionedTestInstaller());
1434 crx
.name
= "test_ihfo";
1435 crx
.pk_hash
.assign(ihfo_hash
, ihfo_hash
+ arraysize(ihfo_hash
));
1436 crx
.installer
= installer
;
1437 if (num_calls
== 1) {
1438 crx
.version
= Version("0.8");
1439 } else if (num_calls
== 2) {
1440 crx
.version
= Version("1.0");
1445 components
->push_back(crx
);
1449 class CompletionCallbackFake
{
1451 static void Callback(const base::Closure
& quit_closure
, int error
) {
1452 EXPECT_EQ(0, error
);
1457 class FakeUpdateChecker
: public UpdateChecker
{
1459 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
1460 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
1463 bool CheckForUpdates(
1464 const std::vector
<CrxUpdateItem
*>& items_to_check
,
1465 const std::string
& additional_attributes
,
1466 const UpdateCheckCallback
& update_check_callback
) override
{
1467 static int num_call
= 0;
1470 UpdateResponse::Results results
;
1472 if (num_call
== 1) {
1474 Fake the following response:
1475 <?xml version='1.0' encoding='UTF-8'?>
1476 <response protocol='3.0'>
1477 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
1478 <updatecheck status='ok'>
1480 <url codebase='http://localhost/download/'/>
1482 <manifest version='1.0' prodversionmin='11.0.1.0'>
1484 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
1491 UpdateResponse::Result::Manifest::Package package
;
1492 package
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
1493 package
.fingerprint
= "1";
1494 UpdateResponse::Result result
;
1495 result
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
1496 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
1497 result
.manifest
.version
= "1.0";
1498 result
.manifest
.browser_min_version
= "11.0.1.0";
1499 result
.manifest
.packages
.push_back(package
);
1500 results
.list
.push_back(result
);
1501 } else if (num_call
== 2) {
1503 Fake the following response:
1504 <?xml version='1.0' encoding='UTF-8'?>
1505 <response protocol='3.0'>
1506 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
1507 <updatecheck status='ok'>
1509 <url codebase='http://localhost/download/'/>
1510 <url codebasediff='http://localhost/download/'/>
1512 <manifest version='2.0' prodversionmin='11.0.1.0'>
1514 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_2.crx'
1515 namediff='ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx'
1523 UpdateResponse::Result::Manifest::Package package
;
1524 package
.name
= "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
1525 package
.namediff
= "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
1526 package
.fingerprint
= "22";
1527 UpdateResponse::Result result
;
1528 result
.extension_id
= "ihfokbkgjpifnbbojhneepfflplebdkc";
1529 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
1530 result
.crx_diffurls
.push_back(GURL("http://localhost/download/"));
1531 result
.manifest
.version
= "2.0";
1532 result
.manifest
.browser_min_version
= "11.0.1.0";
1533 result
.manifest
.packages
.push_back(package
);
1534 results
.list
.push_back(result
);
1539 base::ThreadTaskRunnerHandle::Get()->PostTask(
1540 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
1545 class FakeCrxDownloader
: public CrxDownloader
{
1547 static scoped_ptr
<CrxDownloader
> Create(
1548 bool is_background_download
,
1549 net::URLRequestContextGetter
* context_getter
,
1550 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
1551 const scoped_refptr
<base::SingleThreadTaskRunner
>&
1552 background_task_runner
) {
1553 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
1557 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
1558 ~FakeCrxDownloader() override
{}
1560 void DoStartDownload(const GURL
& url
) override
{
1561 DownloadMetrics download_metrics
;
1564 if (url
.path() == "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
1565 download_metrics
.url
= url
;
1566 download_metrics
.downloader
= DownloadMetrics::kNone
;
1567 download_metrics
.error
= 0;
1568 download_metrics
.downloaded_bytes
= 53638;
1569 download_metrics
.total_bytes
= 53638;
1570 download_metrics
.download_time_ms
= 2000;
1572 EXPECT_TRUE(MakeTestFile(
1573 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path
));
1576 result
.response
= path
;
1577 result
.downloaded_bytes
= 53638;
1578 result
.total_bytes
= 53638;
1579 } else if (url
.path() ==
1580 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx") {
1581 // A download error is injected on this execution path.
1582 download_metrics
.url
= url
;
1583 download_metrics
.downloader
= DownloadMetrics::kNone
;
1584 download_metrics
.error
= -1;
1585 download_metrics
.downloaded_bytes
= 0;
1586 download_metrics
.total_bytes
= 2105;
1587 download_metrics
.download_time_ms
= 1000;
1589 EXPECT_TRUE(MakeTestFile(
1590 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), &path
));
1593 result
.response
= path
;
1594 result
.downloaded_bytes
= 0;
1595 result
.total_bytes
= 2105;
1596 } else if (url
.path() ==
1597 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx") {
1598 download_metrics
.url
= url
;
1599 download_metrics
.downloader
= DownloadMetrics::kNone
;
1600 download_metrics
.error
= 0;
1601 download_metrics
.downloaded_bytes
= 53855;
1602 download_metrics
.total_bytes
= 53855;
1603 download_metrics
.download_time_ms
= 1000;
1605 EXPECT_TRUE(MakeTestFile(
1606 TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), &path
));
1609 result
.response
= path
;
1610 result
.downloaded_bytes
= 53855;
1611 result
.total_bytes
= 53855;
1614 base::ThreadTaskRunnerHandle::Get()->PostTask(
1615 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
1616 base::Unretained(this), result
));
1618 base::ThreadTaskRunnerHandle::Get()->PostTask(
1620 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
1621 base::Unretained(this), true, result
, download_metrics
));
1625 class FakePingManager
: public FakePingManagerImpl
{
1627 explicit FakePingManager(const Configurator
& config
)
1628 : FakePingManagerImpl(config
) {}
1629 ~FakePingManager() override
{
1630 const auto& ping_items
= items();
1631 EXPECT_EQ(2U, ping_items
.size());
1632 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[0].id
);
1633 EXPECT_TRUE(base::Version("0.8").Equals(ping_items
[0].previous_version
));
1634 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
1635 EXPECT_EQ(0, ping_items
[0].error_category
);
1636 EXPECT_EQ(0, ping_items
[0].error_code
);
1637 EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items
[1].id
);
1638 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[1].previous_version
));
1639 EXPECT_TRUE(base::Version("2.0").Equals(ping_items
[1].next_version
));
1640 EXPECT_TRUE(ping_items
[1].diff_update_failed
);
1641 EXPECT_EQ(1, ping_items
[1].diff_error_category
); // kNetworkError.
1642 EXPECT_EQ(-1, ping_items
[1].diff_error_code
);
1646 scoped_ptr
<FakePingManager
> ping_manager(new FakePingManager(*config()));
1647 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
1648 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
1649 &FakeCrxDownloader::Create
));
1651 MockObserver observer
;
1654 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1655 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1656 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
1657 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1658 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1659 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1660 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
1661 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1662 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
1663 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1665 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1666 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1667 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
1668 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1669 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1670 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1671 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1672 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1673 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
1674 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1675 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
1676 "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
1679 update_client
->AddObserver(&observer
);
1681 std::vector
<std::string
> ids
;
1682 ids
.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
1685 base::RunLoop runloop
;
1686 update_client
->Update(
1687 ids
, base::Bind(&DataCallbackFake::Callback
),
1688 base::Bind(&CompletionCallbackFake::Callback
, runloop
.QuitClosure()));
1693 base::RunLoop runloop
;
1694 update_client
->Update(
1695 ids
, base::Bind(&DataCallbackFake::Callback
),
1696 base::Bind(&CompletionCallbackFake::Callback
, runloop
.QuitClosure()));
1700 update_client
->RemoveObserver(&observer
);
1705 // Tests the queuing of update checks. In this scenario, two update checks are
1706 // done for one CRX. The second update check call is queued up and will run
1707 // after the first check has completed. The CRX has no updates.
1708 TEST_F(UpdateClientTest
, OneCrxNoUpdateQueuedCall
) {
1709 class DataCallbackFake
{
1711 static void Callback(const std::vector
<std::string
>& ids
,
1712 std::vector
<CrxComponent
>* components
) {
1714 crx
.name
= "test_jebg";
1715 crx
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
1716 crx
.version
= Version("0.9");
1717 crx
.installer
= new TestInstaller
;
1718 components
->push_back(crx
);
1722 class CompletionCallbackFake
{
1724 static void Callback(const base::Closure
& quit_closure
, int error
) {
1725 static int num_call
= 0;
1728 EXPECT_EQ(0, error
);
1735 class FakeUpdateChecker
: public UpdateChecker
{
1737 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
1738 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
1741 bool CheckForUpdates(
1742 const std::vector
<CrxUpdateItem
*>& items_to_check
,
1743 const std::string
& additional_attributes
,
1744 const UpdateCheckCallback
& update_check_callback
) override
{
1745 base::ThreadTaskRunnerHandle::Get()->PostTask(
1746 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "",
1747 UpdateResponse::Results()));
1752 class FakeCrxDownloader
: public CrxDownloader
{
1754 static scoped_ptr
<CrxDownloader
> Create(
1755 bool is_background_download
,
1756 net::URLRequestContextGetter
* context_getter
,
1757 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
1758 const scoped_refptr
<base::SingleThreadTaskRunner
>&
1759 background_task_runner
) {
1760 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
1764 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
1765 ~FakeCrxDownloader() override
{}
1767 void DoStartDownload(const GURL
& url
) override
{ EXPECT_TRUE(false); }
1770 class FakePingManager
: public FakePingManagerImpl
{
1772 explicit FakePingManager(const Configurator
& config
)
1773 : FakePingManagerImpl(config
) {}
1774 ~FakePingManager() override
{ EXPECT_TRUE(items().empty()); }
1777 scoped_ptr
<PingManager
> ping_manager(new FakePingManager(*config()));
1778 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
1779 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
1780 &FakeCrxDownloader::Create
));
1782 MockObserver observer
;
1784 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1785 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1786 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_NOT_UPDATED
,
1787 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1788 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1789 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1790 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_NOT_UPDATED
,
1791 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1793 update_client
->AddObserver(&observer
);
1795 std::vector
<std::string
> ids
;
1796 ids
.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
1798 update_client
->Update(
1799 ids
, base::Bind(&DataCallbackFake::Callback
),
1800 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
1801 update_client
->Update(
1802 ids
, base::Bind(&DataCallbackFake::Callback
),
1803 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
1807 update_client
->RemoveObserver(&observer
);
1812 // Tests the install of one CRX.
1813 TEST_F(UpdateClientTest
, OneCrxInstall
) {
1814 class DataCallbackFake
{
1816 static void Callback(const std::vector
<std::string
>& ids
,
1817 std::vector
<CrxComponent
>* components
) {
1819 crx
.name
= "test_jebg";
1820 crx
.pk_hash
.assign(jebg_hash
, jebg_hash
+ arraysize(jebg_hash
));
1821 crx
.version
= Version("0.0");
1822 crx
.installer
= new TestInstaller
;
1824 components
->push_back(crx
);
1828 class CompletionCallbackFake
{
1830 static void Callback(const base::Closure
& quit_closure
, int error
) {
1831 EXPECT_EQ(0, error
);
1836 class FakeUpdateChecker
: public UpdateChecker
{
1838 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
1839 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
1842 bool CheckForUpdates(
1843 const std::vector
<CrxUpdateItem
*>& items_to_check
,
1844 const std::string
& additional_attributes
,
1845 const UpdateCheckCallback
& update_check_callback
) override
{
1847 Fake the following response:
1849 <?xml version='1.0' encoding='UTF-8'?>
1850 <response protocol='3.0'>
1851 <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
1852 <updatecheck status='ok'>
1854 <url codebase='http://localhost/download/'/>
1856 <manifest version='1.0' prodversionmin='11.0.1.0'>
1858 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
1865 UpdateResponse::Result::Manifest::Package package
;
1866 package
.name
= "jebgalgnebhfojomionfpkfelancnnkf.crx";
1868 UpdateResponse::Result result
;
1869 result
.extension_id
= "jebgalgnebhfojomionfpkfelancnnkf";
1870 result
.crx_urls
.push_back(GURL("http://localhost/download/"));
1871 result
.manifest
.version
= "1.0";
1872 result
.manifest
.browser_min_version
= "11.0.1.0";
1873 result
.manifest
.packages
.push_back(package
);
1875 UpdateResponse::Results results
;
1876 results
.list
.push_back(result
);
1878 base::ThreadTaskRunnerHandle::Get()->PostTask(
1879 FROM_HERE
, base::Bind(update_check_callback
, GURL(), 0, "", results
));
1884 class FakeCrxDownloader
: public CrxDownloader
{
1886 static scoped_ptr
<CrxDownloader
> Create(
1887 bool is_background_download
,
1888 net::URLRequestContextGetter
* context_getter
,
1889 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
1890 const scoped_refptr
<base::SingleThreadTaskRunner
>&
1891 background_task_runner
) {
1892 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
1896 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
1897 ~FakeCrxDownloader() override
{}
1899 void DoStartDownload(const GURL
& url
) override
{
1900 DownloadMetrics download_metrics
;
1903 if (url
.path() == "/download/jebgalgnebhfojomionfpkfelancnnkf.crx") {
1904 download_metrics
.url
= url
;
1905 download_metrics
.downloader
= DownloadMetrics::kNone
;
1906 download_metrics
.error
= 0;
1907 download_metrics
.downloaded_bytes
= 1843;
1908 download_metrics
.total_bytes
= 1843;
1909 download_metrics
.download_time_ms
= 1000;
1911 EXPECT_TRUE(MakeTestFile(
1912 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path
));
1915 result
.response
= path
;
1916 result
.downloaded_bytes
= 1843;
1917 result
.total_bytes
= 1843;
1922 base::ThreadTaskRunnerHandle::Get()->PostTask(
1923 FROM_HERE
, base::Bind(&FakeCrxDownloader::OnDownloadProgress
,
1924 base::Unretained(this), result
));
1926 base::ThreadTaskRunnerHandle::Get()->PostTask(
1928 base::Bind(&FakeCrxDownloader::OnDownloadComplete
,
1929 base::Unretained(this), true, result
, download_metrics
));
1933 class FakePingManager
: public FakePingManagerImpl
{
1935 explicit FakePingManager(const Configurator
& config
)
1936 : FakePingManagerImpl(config
) {}
1937 ~FakePingManager() override
{
1938 const auto& ping_items
= items();
1939 EXPECT_EQ(1U, ping_items
.size());
1940 EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items
[0].id
);
1941 EXPECT_TRUE(base::Version("0.0").Equals(ping_items
[0].previous_version
));
1942 EXPECT_TRUE(base::Version("1.0").Equals(ping_items
[0].next_version
));
1943 EXPECT_EQ(0, ping_items
[0].error_category
);
1944 EXPECT_EQ(0, ping_items
[0].error_code
);
1948 scoped_ptr
<FakePingManager
> ping_manager(new FakePingManager(*config()));
1949 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
1950 config(), ping_manager
.Pass(), &FakeUpdateChecker::Create
,
1951 &FakeCrxDownloader::Create
));
1953 // Verify that calling Install sets ondemand.
1954 OnDemandTester
ondemand_tester(update_client
, true);
1956 MockObserver observer
;
1957 ON_CALL(observer
, OnEvent(_
, _
))
1958 .WillByDefault(Invoke(&ondemand_tester
, &OnDemandTester::CheckOnDemand
));
1961 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES
,
1962 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1963 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_FOUND
,
1964 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1965 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING
,
1966 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1967 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATE_READY
,
1968 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1969 EXPECT_CALL(observer
, OnEvent(Events::COMPONENT_UPDATED
,
1970 "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
1972 update_client
->AddObserver(&observer
);
1974 update_client
->Install(
1975 std::string("jebgalgnebhfojomionfpkfelancnnkf"),
1976 base::Bind(&DataCallbackFake::Callback
),
1977 base::Bind(&CompletionCallbackFake::Callback
, quit_closure()));
1981 update_client
->RemoveObserver(&observer
);
1986 // Make sure that we don't get any crashes when trying to update an empty list
1988 TEST_F(UpdateClientTest
, EmptyIdList
) {
1989 class DataCallbackFake
{
1991 static void Callback(const std::vector
<std::string
>& ids
,
1992 std::vector
<CrxComponent
>* components
) {}
1995 class CompletionCallbackFake
{
1997 static void Callback(const base::Closure
& quit_closure
, int error
) {
2001 class FakeUpdateChecker
: public UpdateChecker
{
2003 static scoped_ptr
<UpdateChecker
> Create(const Configurator
& config
) {
2004 return scoped_ptr
<UpdateChecker
>(new FakeUpdateChecker());
2007 bool CheckForUpdates(
2008 const std::vector
<CrxUpdateItem
*>& items_to_check
,
2009 const std::string
& additional_attributes
,
2010 const UpdateCheckCallback
& update_check_callback
) override
{
2015 class FakeCrxDownloader
: public CrxDownloader
{
2017 static scoped_ptr
<CrxDownloader
> Create(
2018 bool is_background_download
,
2019 net::URLRequestContextGetter
* context_getter
,
2020 const scoped_refptr
<base::SequencedTaskRunner
>& url_fetcher_task_runner
,
2021 const scoped_refptr
<base::SingleThreadTaskRunner
>&
2022 background_task_runner
) {
2023 return scoped_ptr
<CrxDownloader
>(new FakeCrxDownloader());
2027 FakeCrxDownloader() : CrxDownloader(scoped_ptr
<CrxDownloader
>().Pass()) {}
2028 ~FakeCrxDownloader() override
{}
2030 void DoStartDownload(const GURL
& url
) override
{ EXPECT_TRUE(false); }
2033 scoped_refptr
<UpdateClient
> update_client(new UpdateClientImpl(
2034 config(), make_scoped_ptr(new FakePingManagerImpl(*config())),
2035 &FakeUpdateChecker::Create
, &FakeCrxDownloader::Create
));
2037 std::vector
<std::string
> empty_id_list
;
2038 base::RunLoop runloop
;
2039 update_client
->Update(
2040 empty_id_list
, base::Bind(&DataCallbackFake::Callback
),
2041 base::Bind(&CompletionCallbackFake::Callback
, runloop
.QuitClosure()));
2047 } // namespace update_client