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.
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
;
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
{
46 MOCK_METHOD1(OnUpdateError
, void(int error
));
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());
55 ~MockInstaller() override
;
58 class MockUpdateClient
: public UpdateClient
{
61 MOCK_METHOD1(AddObserver
, void(Observer
* observer
));
62 MOCK_METHOD1(RemoveObserver
, void(Observer
* observer
));
64 void(const std::string
& id
,
65 const CrxDataCallback
& crx_data_callback
,
66 const CompletionCallback
& completion_callback
));
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
));
76 ~MockUpdateClient() override
;
79 class MockServiceObserver
: public ServiceObserver
{
81 MockServiceObserver();
82 ~MockServiceObserver() override
;
84 MOCK_METHOD2(OnEvent
, void(Events event
, const std::string
&));
87 class ComponentUpdaterTest
: public testing::Test
{
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() {}
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
{
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
) {
155 return scoped_ptr
<ComponentUpdateService
>(
156 new CrxUpdateService(config
, new MockUpdateClient()));
159 ComponentUpdaterTest::ComponentUpdaterTest()
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() {
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
) {
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
) {
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
;
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
));
259 EXPECT_TRUE(component_updater().UnregisterComponent(id1
));
262 // Tests that on-demand updates invoke UpdateClient::Install.
263 TEST_F(ComponentUpdaterTest
, OnDemandUpdate
) {
266 LoopHandler(int max_cnt
, const base::Closure
& quit_closure
)
267 : max_cnt_(max_cnt
), quit_closure_(quit_closure
) {}
270 const std::string
& ids
,
271 const UpdateClient::CrxDataCallback
& crx_data_callback
,
272 const UpdateClient::CompletionCallback
& completion_callback
) {
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
));
311 // Tests that throttling an update invokes UpdateClient::Install.
312 TEST_F(ComponentUpdaterTest
, MaybeThrottle
) {
315 LoopHandler(int max_cnt
, const base::Closure
& quit_closure
)
316 : max_cnt_(max_cnt
), quit_closure_(quit_closure
) {}
319 const std::string
& ids
,
320 const UpdateClient::CrxDataCallback
& crx_data_callback
,
321 const UpdateClient::CompletionCallback
& completion_callback
) {
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
));
357 } // namespace component_updater