blob: c9237593778255c2b01532629b3a2b437ac1d1ea [file] [log] [blame]
sorin7c717622015-05-26 19:59:091// 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.
4
dchenga0ee5fb82016-04-26 02:46:555#include "components/component_updater/component_updater_service.h"
6
sorin7c717622015-05-26 19:59:097#include <limits>
Sorin Jianu990ee142017-06-02 22:34:088#include <memory>
sorin7c717622015-05-26 19:59:099#include <string>
Sorin Jianua8ef73d2017-11-02 16:55:1710#include <utility>
sorin7c717622015-05-26 19:59:0911#include <vector>
12
13#include "base/bind.h"
Tibor Goldschwendt5f173cb2018-06-21 22:50:4014#include "base/bind_helpers.h"
sorin7c717622015-05-26 19:59:0915#include "base/files/file_path.h"
16#include "base/files/file_util.h"
17#include "base/macros.h"
18#include "base/memory/ref_counted.h"
sorin7c717622015-05-26 19:59:0919#include "base/run_loop.h"
Sorin Jianud20ed8532018-06-28 17:24:3120#include "base/stl_util.h"
Gabriel Charette44db1422018-08-06 11:19:3321#include "base/task/post_task.h"
Devlin Cronin69228f42018-06-01 17:25:1022#include "base/test/metrics/histogram_tester.h"
Gabriel Charettec7108742019-08-23 03:31:4023#include "base/test/task_environment.h"
gab7966d312016-05-11 20:35:0124#include "base/threading/thread_task_runner_handle.h"
sorin7c717622015-05-26 19:59:0925#include "base/values.h"
sorin7c717622015-05-26 19:59:0926#include "components/component_updater/component_updater_service_internal.h"
27#include "components/update_client/test_configurator.h"
28#include "components/update_client/test_installer.h"
29#include "components/update_client/update_client.h"
sorin7b8650522016-11-02 18:23:4130#include "components/update_client/update_client_errors.h"
sorin7c717622015-05-26 19:59:0931#include "testing/gmock/include/gmock/gmock.h"
32#include "testing/gtest/include/gtest/gtest.h"
33
34using Configurator = update_client::Configurator;
sorin2892f7212016-11-07 18:59:4335using Result = update_client::CrxInstaller::Result;
sorin7c717622015-05-26 19:59:0936using TestConfigurator = update_client::TestConfigurator;
37using UpdateClient = update_client::UpdateClient;
38
39using ::testing::_;
40using ::testing::AnyNumber;
41using ::testing::Invoke;
42using ::testing::Mock;
43using ::testing::Return;
Sorin Jianua8ef73d2017-11-02 16:55:1744using ::testing::Unused;
sorin7c717622015-05-26 19:59:0945
46namespace component_updater {
47
48class MockInstaller : public CrxInstaller {
49 public:
50 MockInstaller();
51
Sorin Jianua8ef73d2017-11-02 16:55:1752 // gMock does not support mocking functions with parameters which have
53 // move semantics. This function is a shim to work around it.
54 void Install(const base::FilePath& unpack_path,
55 const std::string& public_key,
Sorin Jianu9d64af672020-02-05 19:14:3456 std::unique_ptr<InstallParams> install_params,
Daniel Cheng67848522018-04-27 22:04:4157 update_client::CrxInstaller::Callback callback) override {
Sorin Jianua8ef73d2017-11-02 16:55:1758 DoInstall(unpack_path, callback);
59 }
60
sorin7c717622015-05-26 19:59:0961 MOCK_METHOD1(OnUpdateError, void(int error));
Sorin Jianua8ef73d2017-11-02 16:55:1762 MOCK_METHOD2(DoInstall,
Sorin Jianu7aa6d1f2017-10-13 20:29:2963 void(const base::FilePath& unpack_path,
Sorin Jianuf40ab4b32017-10-06 22:53:4164 const update_client::CrxInstaller::Callback& callback));
sorin7c717622015-05-26 19:59:0965 MOCK_METHOD2(GetInstalledFile,
66 bool(const std::string& file, base::FilePath* installed_file));
67 MOCK_METHOD0(Uninstall, bool());
68
69 private:
70 ~MockInstaller() override;
71};
72
73class MockUpdateClient : public UpdateClient {
74 public:
75 MockUpdateClient();
Vladislav Kuzkokov12eca792017-10-20 12:45:3876
Sorin Jianua8ef73d2017-11-02 16:55:1777 // gMock does not support mocking functions with parameters which have
78 // move semantics. This function is a shim to work around it.
Vladislav Kuzkokov12eca792017-10-20 12:45:3879 void Install(const std::string& id,
Sorin Jianua8ef73d2017-11-02 16:55:1780 CrxDataCallback crx_data_callback,
Sorin Jianudfb12a42020-03-10 04:12:0381 CrxStateChangeCallback crx_state_change_callback,
Vladislav Kuzkokov12eca792017-10-20 12:45:3882 Callback callback) override {
Sorin Jianud20ed8532018-06-28 17:24:3183 DoInstall(id);
Vladislav Kuzkokov12eca792017-10-20 12:45:3884 std::move(callback).Run(update_client::Error::NONE);
85 }
86
87 void Update(const std::vector<std::string>& ids,
Sorin Jianua8ef73d2017-11-02 16:55:1788 CrxDataCallback crx_data_callback,
Sorin Jianudfb12a42020-03-10 04:12:0389 CrxStateChangeCallback crx_state_change_callback,
Sorin Jianub41a592a2018-03-02 16:30:2790 bool is_foreground,
Vladislav Kuzkokov12eca792017-10-20 12:45:3891 Callback callback) override {
Sorin Jianub41a592a2018-03-02 16:30:2792 // All update calls initiated by the component update service are
93 // automatically triggered as background updates without user intervention.
94 EXPECT_FALSE(is_foreground);
Sorin Jianud20ed8532018-06-28 17:24:3195 DoUpdate(ids);
Vladislav Kuzkokov12eca792017-10-20 12:45:3896 std::move(callback).Run(update_client::Error::NONE);
97 }
98
99 void SendUninstallPing(const std::string& id,
100 const base::Version& version,
101 int reason,
Daniel Cheng67848522018-04-27 22:04:41102 Callback callback) override {
Vladislav Kuzkokov12eca792017-10-20 12:45:38103 DoSendUninstallPing(id, version, reason);
104 std::move(callback).Run(update_client::Error::NONE);
105 }
106
sorin7c717622015-05-26 19:59:09107 MOCK_METHOD1(AddObserver, void(Observer* observer));
108 MOCK_METHOD1(RemoveObserver, void(Observer* observer));
Sorin Jianud20ed8532018-06-28 17:24:31109 MOCK_METHOD1(DoInstall, void(const std::string& id));
110 MOCK_METHOD1(DoUpdate, void(const std::vector<std::string>& ids));
sorin7c717622015-05-26 19:59:09111 MOCK_CONST_METHOD2(GetCrxUpdateState,
112 bool(const std::string& id, CrxUpdateItem* update_item));
113 MOCK_CONST_METHOD1(IsUpdating, bool(const std::string& id));
sorinecaad3e2015-11-13 19:15:52114 MOCK_METHOD0(Stop, void());
Vladislav Kuzkokov12eca792017-10-20 12:45:38115 MOCK_METHOD3(DoSendUninstallPing,
sorin8037ac8c2017-04-19 16:28:00116 void(const std::string& id,
117 const base::Version& version,
Vladislav Kuzkokov12eca792017-10-20 12:45:38118 int reason));
sorin7c717622015-05-26 19:59:09119
120 private:
121 ~MockUpdateClient() override;
122};
123
124class MockServiceObserver : public ServiceObserver {
125 public:
126 MockServiceObserver();
127 ~MockServiceObserver() override;
128
129 MOCK_METHOD2(OnEvent, void(Events event, const std::string&));
130};
131
Tibor Goldschwendt5f173cb2018-06-21 22:50:40132class MockUpdateScheduler : public UpdateScheduler {
133 public:
134 MOCK_METHOD4(Schedule,
135 void(const base::TimeDelta& initial_delay,
136 const base::TimeDelta& delay,
137 const UserTask& user_task,
138 const OnStopTaskCallback& on_stop));
139 MOCK_METHOD0(Stop, void());
140};
141
sorin7c717622015-05-26 19:59:09142class ComponentUpdaterTest : public testing::Test {
143 public:
144 ComponentUpdaterTest();
145 ~ComponentUpdaterTest() override;
146
sorin7c717622015-05-26 19:59:09147 // Makes the full path to a component updater test file.
148 const base::FilePath test_file(const char* file);
149
150 MockUpdateClient& update_client() { return *update_client_; }
151 ComponentUpdateService& component_updater() { return *component_updater_; }
152 scoped_refptr<TestConfigurator> configurator() const { return config_; }
Sorin Jianua8ef73d2017-11-02 16:55:17153 base::OnceClosure quit_closure() { return runloop_.QuitClosure(); }
Tibor Goldschwendt5f173cb2018-06-21 22:50:40154 MockUpdateScheduler& scheduler() { return *scheduler_; }
sorin7c717622015-05-26 19:59:09155
156 protected:
157 void RunThreads();
158
159 private:
Tibor Goldschwendt5f173cb2018-06-21 22:50:40160 void RunUpdateTask(const UpdateScheduler::UserTask& user_task);
161 void Schedule(const base::TimeDelta& initial_delay,
162 const base::TimeDelta& delay,
163 const UpdateScheduler::UserTask& user_task,
164 const UpdateScheduler::OnStopTaskCallback& on_stop);
165
Gabriel Charettedfa36042019-08-19 17:30:11166 base::test::TaskEnvironment task_environment_;
sorin7c717622015-05-26 19:59:09167 base::RunLoop runloop_;
sorin7c717622015-05-26 19:59:09168
Sorin Jianucc048f892017-07-26 02:05:54169 scoped_refptr<TestConfigurator> config_ =
170 base::MakeRefCounted<TestConfigurator>();
Tibor Goldschwendt5f173cb2018-06-21 22:50:40171 MockUpdateScheduler* scheduler_;
Sorin Jianucc048f892017-07-26 02:05:54172 scoped_refptr<MockUpdateClient> update_client_ =
173 base::MakeRefCounted<MockUpdateClient>();
dchenga0ee5fb82016-04-26 02:46:55174 std::unique_ptr<ComponentUpdateService> component_updater_;
sorin7c717622015-05-26 19:59:09175
176 DISALLOW_COPY_AND_ASSIGN(ComponentUpdaterTest);
177};
178
179class OnDemandTester {
180 public:
Sorin Jianud20ed8532018-06-28 17:24:31181 void OnDemand(ComponentUpdateService* cus,
182 const std::string& id,
183 OnDemandUpdater::Priority priority);
sorin7b8650522016-11-02 18:23:41184 update_client::Error error() const { return error_; }
sorin4c520182016-08-19 17:27:44185
186 private:
sorin7b8650522016-11-02 18:23:41187 void OnDemandComplete(update_client::Error error);
sorin4c520182016-08-19 17:27:44188
sorin7b8650522016-11-02 18:23:41189 update_client::Error error_ = update_client::Error::NONE;
sorin7c717622015-05-26 19:59:09190};
191
Sorin Jianudfb12a42020-03-10 04:12:03192MockInstaller::MockInstaller() = default;
193MockInstaller::~MockInstaller() = default;
194MockUpdateClient::MockUpdateClient() = default;
195MockUpdateClient::~MockUpdateClient() = default;
196MockServiceObserver::MockServiceObserver() = default;
197MockServiceObserver::~MockServiceObserver() = default;
sorin7c717622015-05-26 19:59:09198
sorin4c520182016-08-19 17:27:44199void OnDemandTester::OnDemand(ComponentUpdateService* cus,
Sorin Jianud20ed8532018-06-28 17:24:31200 const std::string& id,
201 OnDemandUpdater::Priority priority) {
sorin4c520182016-08-19 17:27:44202 cus->GetOnDemandUpdater().OnDemandUpdate(
Sorin Jianud20ed8532018-06-28 17:24:31203 id, priority,
204 base::BindOnce(&OnDemandTester::OnDemandComplete,
205 base::Unretained(this)));
sorin4c520182016-08-19 17:27:44206}
207
sorin7b8650522016-11-02 18:23:41208void OnDemandTester::OnDemandComplete(update_client::Error error) {
sorin4c520182016-08-19 17:27:44209 error_ = error;
sorin7c717622015-05-26 19:59:09210}
211
dchenga0ee5fb82016-04-26 02:46:55212std::unique_ptr<ComponentUpdateService> TestComponentUpdateServiceFactory(
Sorin Jianu49126332018-02-13 17:07:42213 scoped_refptr<Configurator> config) {
sorin7c717622015-05-26 19:59:09214 DCHECK(config);
Gyuyoung Kim6afb5082018-01-19 13:35:57215 return std::make_unique<CrxUpdateService>(
Tibor Goldschwendt5f173cb2018-06-21 22:50:40216 config, std::make_unique<MockUpdateScheduler>(),
217 base::MakeRefCounted<MockUpdateClient>());
sorin7c717622015-05-26 19:59:09218}
219
Sorin Jianucc048f892017-07-26 02:05:54220ComponentUpdaterTest::ComponentUpdaterTest() {
sorin7c717622015-05-26 19:59:09221 EXPECT_CALL(update_client(), AddObserver(_)).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40222 auto scheduler = std::make_unique<MockUpdateScheduler>();
223 scheduler_ = scheduler.get();
224 ON_CALL(*scheduler_, Schedule(_, _, _, _))
225 .WillByDefault(Invoke(this, &ComponentUpdaterTest::Schedule));
226 component_updater_ = std::make_unique<CrxUpdateService>(
227 config_, std::move(scheduler), update_client_);
sorin7c717622015-05-26 19:59:09228}
229
230ComponentUpdaterTest::~ComponentUpdaterTest() {
231 EXPECT_CALL(update_client(), RemoveObserver(_)).Times(1);
sorin7c717622015-05-26 19:59:09232 component_updater_.reset();
233}
234
sorin7c717622015-05-26 19:59:09235void ComponentUpdaterTest::RunThreads() {
236 runloop_.Run();
237}
238
Tibor Goldschwendt5f173cb2018-06-21 22:50:40239void ComponentUpdaterTest::RunUpdateTask(
240 const UpdateScheduler::UserTask& user_task) {
Gabriel Charettedfa36042019-08-19 17:30:11241 task_environment_.GetMainThreadTaskRunner()->PostTask(
Tibor Goldschwendt5f173cb2018-06-21 22:50:40242 FROM_HERE, base::BindRepeating(
243 [](const UpdateScheduler::UserTask& user_task,
244 ComponentUpdaterTest* test) {
245 user_task.Run(base::BindOnce(
246 [](const UpdateScheduler::UserTask& user_task,
247 ComponentUpdaterTest* test) {
248 test->RunUpdateTask(user_task);
249 },
250 user_task, base::Unretained(test)));
251 },
252 user_task, base::Unretained(this)));
253}
254
255void ComponentUpdaterTest::Schedule(
256 const base::TimeDelta& initial_delay,
257 const base::TimeDelta& delay,
258 const UpdateScheduler::UserTask& user_task,
259 const UpdateScheduler::OnStopTaskCallback& on_stop) {
260 RunUpdateTask(user_task);
261}
262
sorin7c717622015-05-26 19:59:09263TEST_F(ComponentUpdaterTest, AddObserver) {
264 MockServiceObserver observer;
265 EXPECT_CALL(update_client(), AddObserver(&observer)).Times(1);
sorinecaad3e2015-11-13 19:15:52266 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40267 EXPECT_CALL(scheduler(), Stop()).Times(1);
sorin7c717622015-05-26 19:59:09268 component_updater().AddObserver(&observer);
269}
270
271TEST_F(ComponentUpdaterTest, RemoveObserver) {
272 MockServiceObserver observer;
273 EXPECT_CALL(update_client(), RemoveObserver(&observer)).Times(1);
sorinecaad3e2015-11-13 19:15:52274 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40275 EXPECT_CALL(scheduler(), Stop()).Times(1);
sorin7c717622015-05-26 19:59:09276 component_updater().RemoveObserver(&observer);
277}
278
279// Tests that UpdateClient::Update is called by the timer loop when
280// components are registered, and the component update starts.
281// Also tests that Uninstall is called when a component is unregistered.
282TEST_F(ComponentUpdaterTest, RegisterComponent) {
283 class LoopHandler {
284 public:
Sorin Jianua8ef73d2017-11-02 16:55:17285 LoopHandler(int max_cnt, base::OnceClosure quit_closure)
286 : max_cnt_(max_cnt), quit_closure_(std::move(quit_closure)) {}
sorin7c717622015-05-26 19:59:09287
Sorin Jianud20ed8532018-06-28 17:24:31288 void OnUpdate(const std::vector<std::string>& ids) {
sorin7c717622015-05-26 19:59:09289 static int cnt = 0;
290 ++cnt;
291 if (cnt >= max_cnt_)
Sorin Jianua8ef73d2017-11-02 16:55:17292 std::move(quit_closure_).Run();
sorin7c717622015-05-26 19:59:09293 }
294
295 private:
296 const int max_cnt_;
Sorin Jianua8ef73d2017-11-02 16:55:17297 base::OnceClosure quit_closure_;
sorin7c717622015-05-26 19:59:09298 };
299
sorin85953dc2016-03-10 00:32:48300 base::HistogramTester ht;
301
Sorin Jianua8ef73d2017-11-02 16:55:17302 scoped_refptr<MockInstaller> installer =
303 base::MakeRefCounted<MockInstaller>();
sorin7c717622015-05-26 19:59:09304 EXPECT_CALL(*installer, Uninstall()).WillOnce(Return(true));
305
306 using update_client::jebg_hash;
307 using update_client::abag_hash;
308
309 const std::string id1 = "abagagagagagagagagagagagagagagag";
310 const std::string id2 = "jebgalgnebhfojomionfpkfelancnnkf";
311 std::vector<std::string> ids;
312 ids.push_back(id1);
313 ids.push_back(id2);
314
315 CrxComponent crx_component1;
Joshua Pawlicki9656e3922019-09-16 16:34:51316 crx_component1.app_id = id1;
Sorin Jianud20ed8532018-06-28 17:24:31317 crx_component1.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
pwnall15745b312016-08-19 21:45:29318 crx_component1.version = base::Version("1.0");
sorin7c717622015-05-26 19:59:09319 crx_component1.installer = installer;
320
321 CrxComponent crx_component2;
Joshua Pawlicki9656e3922019-09-16 16:34:51322 crx_component2.app_id = id2;
Sorin Jianud20ed8532018-06-28 17:24:31323 crx_component2.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
pwnall15745b312016-08-19 21:45:29324 crx_component2.version = base::Version("0.9");
sorin7c717622015-05-26 19:59:09325 crx_component2.installer = installer;
326
327 // Quit after two update checks have fired.
328 LoopHandler loop_handler(2, quit_closure());
Sorin Jianud20ed8532018-06-28 17:24:31329 EXPECT_CALL(update_client(), DoUpdate(ids))
sorin7c717622015-05-26 19:59:09330 .WillRepeatedly(Invoke(&loop_handler, &LoopHandler::OnUpdate));
331
332 EXPECT_CALL(update_client(), IsUpdating(id1)).Times(1);
sorinecaad3e2015-11-13 19:15:52333 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40334 EXPECT_CALL(scheduler(), Schedule(_, _, _, _)).Times(1);
335 EXPECT_CALL(scheduler(), Stop()).Times(1);
sorin7c717622015-05-26 19:59:09336
337 EXPECT_TRUE(component_updater().RegisterComponent(crx_component1));
338 EXPECT_TRUE(component_updater().RegisterComponent(crx_component2));
339
340 RunThreads();
sorin7c717622015-05-26 19:59:09341 EXPECT_TRUE(component_updater().UnregisterComponent(id1));
sorin85953dc2016-03-10 00:32:48342
343 ht.ExpectUniqueSample("ComponentUpdater.Calls", 1, 2);
344 ht.ExpectUniqueSample("ComponentUpdater.UpdateCompleteResult", 0, 2);
345 ht.ExpectTotalCount("ComponentUpdater.UpdateCompleteTime", 2);
sorin7c717622015-05-26 19:59:09346}
347
348// Tests that on-demand updates invoke UpdateClient::Install.
349TEST_F(ComponentUpdaterTest, OnDemandUpdate) {
350 class LoopHandler {
351 public:
sorin7b8650522016-11-02 18:23:41352 explicit LoopHandler(int max_cnt) : max_cnt_(max_cnt) {}
sorin7c717622015-05-26 19:59:09353
Sorin Jianud20ed8532018-06-28 17:24:31354 void OnInstall(const std::string& ids) {
355 ++cnt_;
356 if (cnt_ >= max_cnt_) {
357 base::ThreadTaskRunnerHandle::Get()->PostTask(
358 FROM_HERE,
359 base::BindOnce(&LoopHandler::Quit, base::Unretained(this)));
360 }
361 }
362
363 void OnUpdate(const std::vector<std::string>& ids) {
364 ++cnt_;
365 if (cnt_ >= max_cnt_) {
sorin4c520182016-08-19 17:27:44366 base::ThreadTaskRunnerHandle::Get()->PostTask(
Sorin Jianuebd652462017-07-23 02:00:58367 FROM_HERE,
368 base::BindOnce(&LoopHandler::Quit, base::Unretained(this)));
sorin4c520182016-08-19 17:27:44369 }
sorin7c717622015-05-26 19:59:09370 }
371
372 private:
Gabriel Charette53a9ef812017-07-26 12:36:23373 void Quit() { base::RunLoop::QuitCurrentWhenIdleDeprecated(); }
sorin4c520182016-08-19 17:27:44374
Sorin Jianud20ed8532018-06-28 17:24:31375 int cnt_ = 0;
sorin7c717622015-05-26 19:59:09376 const int max_cnt_;
sorin7c717622015-05-26 19:59:09377 };
378
sorin85953dc2016-03-10 00:32:48379 base::HistogramTester ht;
380
Tibor Goldschwendt5f173cb2018-06-21 22:50:40381 // Don't run periodic update task.
382 ON_CALL(scheduler(), Schedule(_, _, _, _)).WillByDefault(Return());
sorin7c717622015-05-26 19:59:09383
384 auto& cus = component_updater();
385
sorin4c520182016-08-19 17:27:44386 // Tests calling OnDemand for an unregistered component. This call results in
387 // an error, which is recorded by the OnDemandTester instance. Since the
388 // component was not registered, the call is ignored for UMA metrics.
389 OnDemandTester ondemand_tester_component_not_registered;
390 ondemand_tester_component_not_registered.OnDemand(
Sorin Jianud20ed8532018-06-28 17:24:31391 &cus, "ihfokbkgjpifnbbojhneepfflplebdkc",
392 OnDemandUpdater::Priority::FOREGROUND);
sorin7c717622015-05-26 19:59:09393
Sorin Jianud20ed8532018-06-28 17:24:31394 // Register two components, then call |OnDemand| for each component, with
395 // foreground and background priorities. Expect calls to |Schedule| because
396 // components have registered, calls to |Install| and |Update| corresponding
397 // to each |OnDemand| invocation, and calls to |Stop| when the mocks are
398 // torn down.
399 LoopHandler loop_handler(2);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40400 EXPECT_CALL(scheduler(), Schedule(_, _, _, _)).Times(1);
Sorin Jianud20ed8532018-06-28 17:24:31401 EXPECT_CALL(update_client(), DoInstall("jebgalgnebhfojomionfpkfelancnnkf"))
402 .WillOnce(Invoke(&loop_handler, &LoopHandler::OnInstall));
403 EXPECT_CALL(
404 update_client(),
405 DoUpdate(std::vector<std::string>({"abagagagagagagagagagagagagagagag"})))
406 .WillOnce(Invoke(&loop_handler, &LoopHandler::OnUpdate));
407 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40408 EXPECT_CALL(scheduler(), Stop()).Times(1);
sorin7c717622015-05-26 19:59:09409
Sorin Jianud20ed8532018-06-28 17:24:31410 {
411 using update_client::jebg_hash;
412 CrxComponent crx_component;
Joshua Pawlicki9656e3922019-09-16 16:34:51413 crx_component.app_id = "jebgalgnebhfojomionfpkfelancnnkf";
Sorin Jianud20ed8532018-06-28 17:24:31414 crx_component.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
415 crx_component.version = base::Version("0.9");
416 crx_component.installer = base::MakeRefCounted<MockInstaller>();
417 EXPECT_TRUE(cus.RegisterComponent(crx_component));
418 }
419 {
420 using update_client::abag_hash;
421 CrxComponent crx_component;
Joshua Pawlicki9656e3922019-09-16 16:34:51422 crx_component.app_id = "abagagagagagagagagagagagagagagag";
Sorin Jianud20ed8532018-06-28 17:24:31423 crx_component.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
424 crx_component.version = base::Version("0.9");
425 crx_component.installer = base::MakeRefCounted<MockInstaller>();
426 EXPECT_TRUE(cus.RegisterComponent(crx_component));
427 }
sorin7c717622015-05-26 19:59:09428
Sorin Jianud20ed8532018-06-28 17:24:31429 OnDemandTester ondemand_tester;
430 ondemand_tester.OnDemand(&cus, "jebgalgnebhfojomionfpkfelancnnkf",
431 OnDemandUpdater::Priority::FOREGROUND);
432 ondemand_tester.OnDemand(&cus, "abagagagagagagagagagagagagagagag",
433 OnDemandUpdater::Priority::BACKGROUND);
sorin4c520182016-08-19 17:27:44434 base::RunLoop().Run();
435
sorin7b8650522016-11-02 18:23:41436 EXPECT_EQ(update_client::Error::INVALID_ARGUMENT,
437 ondemand_tester_component_not_registered.error());
438 EXPECT_EQ(update_client::Error::NONE, ondemand_tester.error());
sorin85953dc2016-03-10 00:32:48439
Sorin Jianud20ed8532018-06-28 17:24:31440 ht.ExpectUniqueSample("ComponentUpdater.Calls", 0, 2);
441 ht.ExpectUniqueSample("ComponentUpdater.UpdateCompleteResult", 0, 2);
442 ht.ExpectTotalCount("ComponentUpdater.UpdateCompleteTime", 2);
sorin7c717622015-05-26 19:59:09443}
444
445// Tests that throttling an update invokes UpdateClient::Install.
446TEST_F(ComponentUpdaterTest, MaybeThrottle) {
447 class LoopHandler {
448 public:
Sorin Jianua8ef73d2017-11-02 16:55:17449 LoopHandler(int max_cnt, base::OnceClosure quit_closure)
450 : max_cnt_(max_cnt), quit_closure_(std::move(quit_closure)) {}
sorin7c717622015-05-26 19:59:09451
Sorin Jianud20ed8532018-06-28 17:24:31452 void OnInstall(const std::string& ids) {
sorin7c717622015-05-26 19:59:09453 static int cnt = 0;
454 ++cnt;
455 if (cnt >= max_cnt_)
Sorin Jianua8ef73d2017-11-02 16:55:17456 std::move(quit_closure_).Run();
sorin7c717622015-05-26 19:59:09457 }
458
459 private:
460 const int max_cnt_;
Sorin Jianua8ef73d2017-11-02 16:55:17461 base::OnceClosure quit_closure_;
sorin7c717622015-05-26 19:59:09462 };
463
sorin85953dc2016-03-10 00:32:48464 base::HistogramTester ht;
465
Tibor Goldschwendt5f173cb2018-06-21 22:50:40466 // Don't run periodic update task.
467 ON_CALL(scheduler(), Schedule(_, _, _, _)).WillByDefault(Return());
sorin7c717622015-05-26 19:59:09468
Sorin Jianua8ef73d2017-11-02 16:55:17469 scoped_refptr<MockInstaller> installer =
470 base::MakeRefCounted<MockInstaller>();
sorin7c717622015-05-26 19:59:09471
472 using update_client::jebg_hash;
473 CrxComponent crx_component;
Joshua Pawlicki9656e3922019-09-16 16:34:51474 crx_component.app_id = "jebgalgnebhfojomionfpkfelancnnkf";
Sorin Jianud20ed8532018-06-28 17:24:31475 crx_component.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
pwnall15745b312016-08-19 21:45:29476 crx_component.version = base::Version("0.9");
sorin7c717622015-05-26 19:59:09477 crx_component.installer = installer;
478
479 LoopHandler loop_handler(1, quit_closure());
Sorin Jianud20ed8532018-06-28 17:24:31480 EXPECT_CALL(update_client(), DoInstall("jebgalgnebhfojomionfpkfelancnnkf"))
sorin7c717622015-05-26 19:59:09481 .WillOnce(Invoke(&loop_handler, &LoopHandler::OnInstall));
sorinecaad3e2015-11-13 19:15:52482 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40483 EXPECT_CALL(scheduler(), Schedule(_, _, _, _)).Times(1);
484 EXPECT_CALL(scheduler(), Stop()).Times(1);
sorin7c717622015-05-26 19:59:09485
486 EXPECT_TRUE(component_updater().RegisterComponent(crx_component));
Sorin Jianu30881152020-03-16 14:31:19487 component_updater().MaybeThrottle("jebgalgnebhfojomionfpkfelancnnkf",
488 base::BindOnce([]() {}));
sorin7c717622015-05-26 19:59:09489
490 RunThreads();
sorin85953dc2016-03-10 00:32:48491
492 ht.ExpectUniqueSample("ComponentUpdater.Calls", 0, 1);
493 ht.ExpectUniqueSample("ComponentUpdater.UpdateCompleteResult", 0, 1);
494 ht.ExpectTotalCount("ComponentUpdater.UpdateCompleteTime", 1);
sorin7c717622015-05-26 19:59:09495}
496
497} // namespace component_updater