Fix broken path in extensions/common/PRESUBMIT.py
[chromium-blink-merge.git] / components / update_client / update_client_unittest.cc
blob52f43fa6e97f832275d13fd72859935098dc751a
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.
5 #include "base/bind.h"
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"
28 #include "url/gurl.h"
30 namespace update_client {
32 namespace {
34 using base::FilePath;
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) {
40 FilePath temp_dir;
41 bool result =
42 CreateNewTempDirectory(FILE_PATH_LITERAL("update_client"), &temp_dir);
43 if (!result)
44 return false;
46 FilePath temp_file;
47 result = CreateTemporaryFileInDir(temp_dir, &temp_file);
48 if (!result)
49 return false;
51 result = CopyFile(from_path, temp_file);
52 if (!result) {
53 DeleteFile(temp_file, false);
54 return false;
57 *to_path = temp_file;
58 return true;
61 using Events = UpdateClient::Observer::Events;
63 class MockObserver : public UpdateClient::Observer {
64 public:
65 MOCK_METHOD2(OnEvent, void(Events event, const std::string&));
68 class FakePingManagerImpl : public PingManager {
69 public:
70 explicit FakePingManagerImpl(const Configurator& config);
71 ~FakePingManagerImpl() override;
73 void OnUpdateComplete(const CrxUpdateItem* item) override;
75 const std::vector<CrxUpdateItem>& items() const;
77 private:
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 {
94 return items_;
97 } // namespace
99 using ::testing::_;
100 using ::testing::AnyNumber;
101 using ::testing::DoAll;
102 using ::testing::InSequence;
103 using ::testing::Invoke;
104 using ::testing::Mock;
105 using ::testing::Return;
107 using std::string;
109 class UpdateClientTest : public testing::Test {
110 public:
111 UpdateClientTest();
112 ~UpdateClientTest() override;
114 protected:
115 void RunThreads();
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_; }
124 private:
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()
140 : worker_pool_(
141 new base::SequencedWorkerPoolOwner(kNumWorkerThreads_, "test")),
142 thread_(new base::Thread("test")) {
143 quit_closure_ = runloop_.QuitClosure();
145 thread_->Start();
147 auto pool = worker_pool_->pool();
148 config_ = new TestConfigurator(
149 pool->GetSequencedTaskRunner(pool->GetSequenceToken()),
150 thread_->task_runner());
153 UpdateClientTest::~UpdateClientTest() {
154 config_ = nullptr;
155 thread_->Stop();
156 worker_pool_->pool()->Shutdown();
159 void UpdateClientTest::RunThreads() {
160 runloop_.Run();
163 base::FilePath UpdateClientTest::TestFilePath(const char* file) {
164 base::FilePath path;
165 PathService::Get(base::DIR_SOURCE_ROOT, &path);
166 return path.AppendASCII("components")
167 .AppendASCII("test")
168 .AppendASCII("data")
169 .AppendASCII("update_client")
170 .AppendASCII(file);
173 // Tests the scenario where one update check is done for one CRX. The CRX
174 // has no update.
175 TEST_F(UpdateClientTest, OneCrxNoUpdate) {
176 class DataCallbackFake {
177 public:
178 static void Callback(const std::vector<std::string>& ids,
179 std::vector<CrxComponent>* components) {
180 CrxComponent crx;
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 {
190 public:
191 static void Callback(const base::Closure& quit_closure, int error) {
192 EXPECT_EQ(0, error);
193 quit_closure.Run();
197 class FakeUpdateChecker : public UpdateChecker {
198 public:
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()));
210 return true;
214 class FakeCrxDownloader : public CrxDownloader {
215 public:
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());
225 private:
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 {
233 public:
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;
245 InSequence seq;
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()));
260 RunThreads();
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 {
269 public:
270 static void Callback(const std::vector<std::string>& ids,
271 std::vector<CrxComponent>* components) {
272 CrxComponent crx1;
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;
278 CrxComponent crx2;
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 {
290 public:
291 static void Callback(const base::Closure& quit_closure, int error) {
292 EXPECT_EQ(0, error);
293 quit_closure.Run();
297 class FakeUpdateChecker : public UpdateChecker {
298 public:
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'>
314 <urls>
315 <url codebase='http://localhost/download/'/>
316 </urls>
317 <manifest version='1.0' prodversionmin='11.0.1.0'>
318 <packages>
319 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
320 </packages>
321 </manifest>
322 </updatecheck>
323 </app>
324 </response>
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));
341 return true;
345 class FakeCrxDownloader : public CrxDownloader {
346 public:
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());
356 private:
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;
369 FilePath path;
370 EXPECT_TRUE(MakeTestFile(
371 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path));
373 Result result;
374 result.error = 0;
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(
384 FROM_HERE,
385 base::Bind(&FakeCrxDownloader::OnDownloadComplete,
386 base::Unretained(this), true, result, download_metrics));
390 class FakePingManager : public FakePingManagerImpl {
391 public:
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;
412 InSequence seq;
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);
425 InSequence seq;
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()));
442 RunThreads();
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 {
450 public:
451 static void Callback(const std::vector<std::string>& ids,
452 std::vector<CrxComponent>* components) {
453 CrxComponent crx1;
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;
459 CrxComponent crx2;
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 {
471 public:
472 static void Callback(const base::Closure& quit_closure, int error) {
473 EXPECT_EQ(0, error);
474 quit_closure.Run();
478 class FakeUpdateChecker : public UpdateChecker {
479 public:
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'>
495 <urls>
496 <url codebase='http://localhost/download/'/>
497 </urls>
498 <manifest version='1.0' prodversionmin='11.0.1.0'>
499 <packages>
500 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
501 </packages>
502 </manifest>
503 </updatecheck>
504 </app>
505 <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
506 <updatecheck status='ok'>
507 <urls>
508 <url codebase='http://localhost/download/'/>
509 </urls>
510 <manifest version='1.0' prodversionmin='11.0.1.0'>
511 <packages>
512 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
513 </packages>
514 </manifest>
515 </updatecheck>
516 </app>
517 </response>
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));
545 return true;
549 class FakeCrxDownloader : public CrxDownloader {
550 public:
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());
560 private:
561 FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
562 ~FakeCrxDownloader() override {}
564 void DoStartDownload(const GURL& url) override {
565 DownloadMetrics download_metrics;
566 FilePath path;
567 Result result;
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));
579 result.error = 0;
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));
595 result.error = 0;
596 result.response = path;
597 result.downloaded_bytes = 53638;
598 result.total_bytes = 53638;
599 } else {
600 NOTREACHED();
603 base::ThreadTaskRunnerHandle::Get()->PostTask(
604 FROM_HERE, base::Bind(&FakeCrxDownloader::OnDownloadProgress,
605 base::Unretained(this), result));
607 base::ThreadTaskRunnerHandle::Get()->PostTask(
608 FROM_HERE,
609 base::Bind(&FakeCrxDownloader::OnDownloadComplete,
610 base::Unretained(this), true, result, download_metrics));
614 class FakePingManager : public FakePingManagerImpl {
615 public:
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;
641 InSequence seq;
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);
654 InSequence seq;
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()));
679 RunThreads();
681 update_client->RemoveObserver(&observer);
684 // Tests the differential update scenario for one CRX.
685 TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
686 class DataCallbackFake {
687 public:
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());
696 ++num_calls;
698 CrxComponent crx;
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");
706 } else {
707 NOTREACHED();
710 components->push_back(crx);
714 class CompletionCallbackFake {
715 public:
716 static void Callback(const base::Closure& quit_closure, int error) {
717 EXPECT_EQ(0, error);
718 quit_closure.Run();
722 class FakeUpdateChecker : public UpdateChecker {
723 public:
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;
733 ++num_call;
735 UpdateResponse::Results results;
737 if (num_call == 1) {
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'>
744 <urls>
745 <url codebase='http://localhost/download/'/>
746 </urls>
747 <manifest version='1.0' prodversionmin='11.0.1.0'>
748 <packages>
749 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
750 </packages>
751 </manifest>
752 </updatecheck>
753 </app>
754 </response>
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'>
773 <urls>
774 <url codebase='http://localhost/download/'/>
775 <url codebasediff='http://localhost/download/'/>
776 </urls>
777 <manifest version='2.0' prodversionmin='11.0.1.0'>
778 <packages>
779 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_2.crx'
780 namediff='ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx'
781 fp='22'/>
782 </packages>
783 </manifest>
784 </updatecheck>
785 </app>
786 </response>
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);
800 } else {
801 NOTREACHED();
804 base::ThreadTaskRunnerHandle::Get()->PostTask(
805 FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
806 return true;
810 class FakeCrxDownloader : public CrxDownloader {
811 public:
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());
821 private:
822 FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
823 ~FakeCrxDownloader() override {}
825 void DoStartDownload(const GURL& url) override {
826 DownloadMetrics download_metrics;
827 FilePath path;
828 Result result;
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));
840 result.error = 0;
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));
856 result.error = 0;
857 result.response = path;
858 result.downloaded_bytes = 2105;
859 result.total_bytes = 2105;
860 } else {
861 NOTREACHED();
864 base::ThreadTaskRunnerHandle::Get()->PostTask(
865 FROM_HERE, base::Bind(&FakeCrxDownloader::OnDownloadProgress,
866 base::Unretained(this), result));
868 base::ThreadTaskRunnerHandle::Get()->PostTask(
869 FROM_HERE,
870 base::Bind(&FakeCrxDownloader::OnDownloadComplete,
871 base::Unretained(this), true, result, download_metrics));
875 class FakePingManager : public FakePingManagerImpl {
876 public:
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;
902 InSequence seq;
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()));
935 runloop.Run();
939 base::RunLoop runloop;
940 update_client->Update(
941 ids, base::Bind(&DataCallbackFake::Callback),
942 base::Bind(&CompletionCallbackFake::Callback, runloop.QuitClosure()));
943 runloop.Run();
946 update_client->RemoveObserver(&observer);
949 // Tests the update scenario for one CRX where the CRX installer returns
950 // an error.
951 TEST_F(UpdateClientTest, OneCrxInstallError) {
952 class MockInstaller : public CrxInstaller {
953 public:
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);
967 protected:
968 ~MockInstaller() override {}
971 class DataCallbackFake {
972 public:
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);
983 CrxComponent crx;
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 {
993 public:
994 static void Callback(const base::Closure& quit_closure, int error) {
995 EXPECT_EQ(0, error);
996 quit_closure.Run();
1000 class FakeUpdateChecker : public UpdateChecker {
1001 public:
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'>
1017 <urls>
1018 <url codebase='http://localhost/download/'/>
1019 </urls>
1020 <manifest version='1.0' prodversionmin='11.0.1.0'>
1021 <packages>
1022 <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
1023 </packages>
1024 </manifest>
1025 </updatecheck>
1026 </app>
1027 </response>
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));
1044 return true;
1048 class FakeCrxDownloader : public CrxDownloader {
1049 public:
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());
1059 private:
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;
1072 FilePath path;
1073 EXPECT_TRUE(MakeTestFile(
1074 TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path));
1076 Result result;
1077 result.error = 0;
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(
1087 FROM_HERE,
1088 base::Bind(&FakeCrxDownloader::OnDownloadComplete,
1089 base::Unretained(this), true, result, download_metrics));
1093 class FakePingManager : public FakePingManagerImpl {
1094 public:
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;
1115 InSequence seq;
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()));
1137 RunThreads();
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 {
1145 public:
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());
1154 ++num_calls;
1156 CrxComponent crx;
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");
1164 } else {
1165 NOTREACHED();
1168 components->push_back(crx);
1172 class CompletionCallbackFake {
1173 public:
1174 static void Callback(const base::Closure& quit_closure, int error) {
1175 EXPECT_EQ(0, error);
1176 quit_closure.Run();
1180 class FakeUpdateChecker : public UpdateChecker {
1181 public:
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;
1191 ++num_call;
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'>
1202 <urls>
1203 <url codebase='http://localhost/download/'/>
1204 </urls>
1205 <manifest version='1.0' prodversionmin='11.0.1.0'>
1206 <packages>
1207 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
1208 </packages>
1209 </manifest>
1210 </updatecheck>
1211 </app>
1212 </response>
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'>
1231 <urls>
1232 <url codebase='http://localhost/download/'/>
1233 <url codebasediff='http://localhost/download/'/>
1234 </urls>
1235 <manifest version='2.0' prodversionmin='11.0.1.0'>
1236 <packages>
1237 <package name='ihfokbkgjpifnbbojhneepfflplebdkc_2.crx'
1238 namediff='ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx'
1239 fp='22'/>
1240 </packages>
1241 </manifest>
1242 </updatecheck>
1243 </app>
1244 </response>
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);
1258 } else {
1259 NOTREACHED();
1262 base::ThreadTaskRunnerHandle::Get()->PostTask(
1263 FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
1264 return true;
1268 class FakeCrxDownloader : public CrxDownloader {
1269 public:
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());
1279 private:
1280 FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
1281 ~FakeCrxDownloader() override {}
1283 void DoStartDownload(const GURL& url) override {
1284 DownloadMetrics download_metrics;
1285 FilePath path;
1286 Result result;
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));
1298 result.error = 0;
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));
1315 result.error = -1;
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));
1331 result.error = 0;
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(
1342 FROM_HERE,
1343 base::Bind(&FakeCrxDownloader::OnDownloadComplete,
1344 base::Unretained(this), true, result, download_metrics));
1348 class FakePingManager : public FakePingManagerImpl {
1349 public:
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;
1376 InSequence seq;
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()));
1412 runloop.Run();
1416 base::RunLoop runloop;
1417 update_client->Update(
1418 ids, base::Bind(&DataCallbackFake::Callback),
1419 base::Bind(&CompletionCallbackFake::Callback, runloop.QuitClosure()));
1420 runloop.Run();
1423 update_client->RemoveObserver(&observer);
1426 } // namespace update_client