Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / component_updater / component_updater_service_unittest.cc
blobc44c63b7c1482c3efde1bb0c6d43c337b379c141
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 <limits>
6 #include <string>
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/run_loop.h"
18 #include "base/test/sequenced_worker_pool_owner.h"
19 #include "base/thread_task_runner_handle.h"
20 #include "base/values.h"
21 #include "components/component_updater/component_updater_service.h"
22 #include "components/component_updater/component_updater_service_internal.h"
23 #include "components/update_client/test_configurator.h"
24 #include "components/update_client/test_installer.h"
25 #include "components/update_client/update_client.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 using Configurator = update_client::Configurator;
31 using TestConfigurator = update_client::TestConfigurator;
32 using UpdateClient = update_client::UpdateClient;
34 using ::testing::_;
35 using ::testing::AnyNumber;
36 using ::testing::Invoke;
37 using ::testing::Mock;
38 using ::testing::Return;
40 namespace component_updater {
42 class MockInstaller : public CrxInstaller {
43 public:
44 MockInstaller();
46 MOCK_METHOD1(OnUpdateError, void(int error));
47 MOCK_METHOD2(Install,
48 bool(const base::DictionaryValue& manifest,
49 const base::FilePath& unpack_path));
50 MOCK_METHOD2(GetInstalledFile,
51 bool(const std::string& file, base::FilePath* installed_file));
52 MOCK_METHOD0(Uninstall, bool());
54 private:
55 ~MockInstaller() override;
58 class MockUpdateClient : public UpdateClient {
59 public:
60 MockUpdateClient();
61 MOCK_METHOD1(AddObserver, void(Observer* observer));
62 MOCK_METHOD1(RemoveObserver, void(Observer* observer));
63 MOCK_METHOD3(Install,
64 void(const std::string& id,
65 const CrxDataCallback& crx_data_callback,
66 const CompletionCallback& completion_callback));
67 MOCK_METHOD3(Update,
68 void(const std::vector<std::string>& ids,
69 const CrxDataCallback& crx_data_callback,
70 const CompletionCallback& completion_callback));
71 MOCK_CONST_METHOD2(GetCrxUpdateState,
72 bool(const std::string& id, CrxUpdateItem* update_item));
73 MOCK_CONST_METHOD1(IsUpdating, bool(const std::string& id));
75 private:
76 ~MockUpdateClient() override;
79 class MockServiceObserver : public ServiceObserver {
80 public:
81 MockServiceObserver();
82 ~MockServiceObserver() override;
84 MOCK_METHOD2(OnEvent, void(Events event, const std::string&));
87 class ComponentUpdaterTest : public testing::Test {
88 public:
89 ComponentUpdaterTest();
90 ~ComponentUpdaterTest() override;
92 void SetUp() override;
94 void TearDown() override;
96 // Makes the full path to a component updater test file.
97 const base::FilePath test_file(const char* file);
99 MockUpdateClient& update_client() { return *update_client_; }
100 ComponentUpdateService& component_updater() { return *component_updater_; }
101 scoped_refptr<TestConfigurator> configurator() const { return config_; }
102 base::Closure quit_closure() const { return quit_closure_; }
103 static void ReadyCallback() {}
105 protected:
106 void RunThreads();
108 private:
109 static const int kNumWorkerThreads_ = 2;
111 base::MessageLoopForUI message_loop_;
112 base::RunLoop runloop_;
113 base::Closure quit_closure_;
115 scoped_ptr<base::SequencedWorkerPoolOwner> worker_pool_;
117 scoped_refptr<TestConfigurator> config_;
118 scoped_refptr<MockUpdateClient> update_client_;
119 scoped_ptr<ComponentUpdateService> component_updater_;
121 DISALLOW_COPY_AND_ASSIGN(ComponentUpdaterTest);
124 class OnDemandTester {
125 public:
126 static bool OnDemand(ComponentUpdateService* cus, const std::string& id);
129 MockInstaller::MockInstaller() {
132 MockInstaller::~MockInstaller() {
135 MockUpdateClient::MockUpdateClient() {
138 MockUpdateClient::~MockUpdateClient() {
141 MockServiceObserver::MockServiceObserver() {
144 MockServiceObserver::~MockServiceObserver() {
147 bool OnDemandTester::OnDemand(ComponentUpdateService* cus,
148 const std::string& id) {
149 return cus->GetOnDemandUpdater().OnDemandUpdate(id);
152 scoped_ptr<ComponentUpdateService> TestComponentUpdateServiceFactory(
153 const scoped_refptr<Configurator>& config) {
154 DCHECK(config);
155 return scoped_ptr<ComponentUpdateService>(
156 new CrxUpdateService(config, new MockUpdateClient()));
159 ComponentUpdaterTest::ComponentUpdaterTest()
160 : worker_pool_(
161 new base::SequencedWorkerPoolOwner(kNumWorkerThreads_, "test")) {
162 quit_closure_ = runloop_.QuitClosure();
164 auto pool = worker_pool_->pool();
165 config_ = new TestConfigurator(
166 pool->GetSequencedTaskRunner(pool->GetSequenceToken()),
167 message_loop_.task_runner());
169 update_client_ = new MockUpdateClient();
170 EXPECT_CALL(update_client(), AddObserver(_)).Times(1);
171 component_updater_.reset(new CrxUpdateService(config_, update_client_));
174 ComponentUpdaterTest::~ComponentUpdaterTest() {
175 EXPECT_CALL(update_client(), RemoveObserver(_)).Times(1);
176 worker_pool_->pool()->Shutdown();
177 component_updater_.reset();
180 void ComponentUpdaterTest::SetUp() {
183 void ComponentUpdaterTest::TearDown() {
186 void ComponentUpdaterTest::RunThreads() {
187 runloop_.Run();
190 TEST_F(ComponentUpdaterTest, AddObserver) {
191 MockServiceObserver observer;
192 EXPECT_CALL(update_client(), AddObserver(&observer)).Times(1);
193 component_updater().AddObserver(&observer);
196 TEST_F(ComponentUpdaterTest, RemoveObserver) {
197 MockServiceObserver observer;
198 EXPECT_CALL(update_client(), RemoveObserver(&observer)).Times(1);
199 component_updater().RemoveObserver(&observer);
202 // Tests that UpdateClient::Update is called by the timer loop when
203 // components are registered, and the component update starts.
204 // Also tests that Uninstall is called when a component is unregistered.
205 TEST_F(ComponentUpdaterTest, RegisterComponent) {
206 class LoopHandler {
207 public:
208 LoopHandler(int max_cnt, const base::Closure& quit_closure)
209 : max_cnt_(max_cnt), quit_closure_(quit_closure) {}
211 void OnUpdate(const std::vector<std::string>& ids,
212 const UpdateClient::CrxDataCallback& crx_data_callback,
213 const UpdateClient::CompletionCallback& completion_callback) {
214 static int cnt = 0;
215 ++cnt;
216 if (cnt >= max_cnt_)
217 quit_closure_.Run();
220 private:
221 const int max_cnt_;
222 base::Closure quit_closure_;
225 scoped_refptr<MockInstaller> installer(new MockInstaller());
226 EXPECT_CALL(*installer, Uninstall()).WillOnce(Return(true));
228 using update_client::jebg_hash;
229 using update_client::abag_hash;
231 const std::string id1 = "abagagagagagagagagagagagagagagag";
232 const std::string id2 = "jebgalgnebhfojomionfpkfelancnnkf";
233 std::vector<std::string> ids;
234 ids.push_back(id1);
235 ids.push_back(id2);
237 CrxComponent crx_component1;
238 crx_component1.pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash));
239 crx_component1.version = Version("1.0");
240 crx_component1.installer = installer;
242 CrxComponent crx_component2;
243 crx_component2.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
244 crx_component2.version = Version("0.9");
245 crx_component2.installer = installer;
247 // Quit after two update checks have fired.
248 LoopHandler loop_handler(2, quit_closure());
249 EXPECT_CALL(update_client(), Update(ids, _, _))
250 .WillRepeatedly(Invoke(&loop_handler, &LoopHandler::OnUpdate));
252 EXPECT_CALL(update_client(), IsUpdating(id1)).Times(1);
254 EXPECT_TRUE(component_updater().RegisterComponent(crx_component1));
255 EXPECT_TRUE(component_updater().RegisterComponent(crx_component2));
257 RunThreads();
259 EXPECT_TRUE(component_updater().UnregisterComponent(id1));
262 // Tests that on-demand updates invoke UpdateClient::Install.
263 TEST_F(ComponentUpdaterTest, OnDemandUpdate) {
264 class LoopHandler {
265 public:
266 LoopHandler(int max_cnt, const base::Closure& quit_closure)
267 : max_cnt_(max_cnt), quit_closure_(quit_closure) {}
269 void OnInstall(
270 const std::string& ids,
271 const UpdateClient::CrxDataCallback& crx_data_callback,
272 const UpdateClient::CompletionCallback& completion_callback) {
273 static int cnt = 0;
274 ++cnt;
275 if (cnt >= max_cnt_)
276 quit_closure_.Run();
279 private:
280 const int max_cnt_;
281 base::Closure quit_closure_;
284 auto config = configurator();
285 config->SetInitialDelay(3600);
287 auto& cus = component_updater();
289 const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
290 EXPECT_FALSE(OnDemandTester::OnDemand(&cus, id));
292 scoped_refptr<MockInstaller> installer(new MockInstaller());
294 using update_client::jebg_hash;
295 CrxComponent crx_component;
296 crx_component.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
297 crx_component.version = Version("0.9");
298 crx_component.installer = installer;
300 LoopHandler loop_handler(1, quit_closure());
301 EXPECT_CALL(update_client(),
302 Install("jebgalgnebhfojomionfpkfelancnnkf", _, _))
303 .WillOnce(Invoke(&loop_handler, &LoopHandler::OnInstall));
305 EXPECT_TRUE(cus.RegisterComponent(crx_component));
306 EXPECT_TRUE(OnDemandTester::OnDemand(&cus, id));
308 RunThreads();
311 // Tests that throttling an update invokes UpdateClient::Install.
312 TEST_F(ComponentUpdaterTest, MaybeThrottle) {
313 class LoopHandler {
314 public:
315 LoopHandler(int max_cnt, const base::Closure& quit_closure)
316 : max_cnt_(max_cnt), quit_closure_(quit_closure) {}
318 void OnInstall(
319 const std::string& ids,
320 const UpdateClient::CrxDataCallback& crx_data_callback,
321 const UpdateClient::CompletionCallback& completion_callback) {
322 static int cnt = 0;
323 ++cnt;
324 if (cnt >= max_cnt_)
325 quit_closure_.Run();
328 private:
329 const int max_cnt_;
330 base::Closure quit_closure_;
333 auto config = configurator();
334 config->SetInitialDelay(3600);
336 scoped_refptr<MockInstaller> installer(new MockInstaller());
338 using update_client::jebg_hash;
339 CrxComponent crx_component;
340 crx_component.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
341 crx_component.version = Version("0.9");
342 crx_component.installer = installer;
344 LoopHandler loop_handler(1, quit_closure());
345 EXPECT_CALL(update_client(),
346 Install("jebgalgnebhfojomionfpkfelancnnkf", _, _))
347 .WillOnce(Invoke(&loop_handler, &LoopHandler::OnInstall));
349 EXPECT_TRUE(component_updater().RegisterComponent(crx_component));
350 component_updater().MaybeThrottle(
351 "jebgalgnebhfojomionfpkfelancnnkf",
352 base::Bind(&ComponentUpdaterTest::ReadyCallback));
354 RunThreads();
357 } // namespace component_updater