[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / components / component_updater / component_updater_service_unittest.cc
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/component_updater/component_updater_service.h"
6
7 #include <algorithm>
8 #include <cstdint>
9 #include <memory>
10 #include <string>
11 #include <utility>
12 #include <vector>
13
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/functional/bind.h"
17 #include "base/functional/callback_helpers.h"
18 #include "base/memory/raw_ptr.h"
19 #include "base/memory/ref_counted.h"
20 #include "base/run_loop.h"
21 #include "base/task/sequenced_task_runner.h"
22 #include "base/test/metrics/histogram_tester.h"
23 #include "base/test/task_environment.h"
24 #include "base/values.h"
25 #include "components/component_updater/component_updater_service_internal.h"
26 #include "components/prefs/testing_pref_service.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"
30 #include "components/update_client/update_client_errors.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 using Configurator = update_client::Configurator;
35 using Result = update_client::CrxInstaller::Result;
36 using TestConfigurator = update_client::TestConfigurator;
37 using UpdateClient = update_client::UpdateClient;
38
39 using ::testing::_;
40 using ::testing::AnyNumber;
41 using ::testing::Invoke;
42 using ::testing::Mock;
43 using ::testing::Return;
44 using ::testing::Unused;
45
46 namespace component_updater {
47
48 class MockInstaller : public update_client::CrxInstaller {
49  public:
50   MockInstaller() = default;
51   MOCK_METHOD1(OnUpdateError, void(int error));
52   MOCK_METHOD5(Install,
53                void(const base::FilePath& unpack_path,
54                     const std::string& public_key,
55                     std::unique_ptr<InstallParams> install_params,
56                     ProgressCallback progress_callback,
57                     Callback callback));
58   MOCK_METHOD2(GetInstalledFile,
59                bool(const std::string& file, base::FilePath* installed_file));
60   MOCK_METHOD0(Uninstall, bool());
61
62  private:
63   ~MockInstaller() override = default;
64 };
65
66 class MockUpdateClient : public UpdateClient {
67  public:
68   MockUpdateClient() = default;
69
70   MOCK_METHOD1(AddObserver, void(Observer* observer));
71   MOCK_METHOD1(RemoveObserver, void(Observer* observer));
72   MOCK_METHOD4(
73       Install,
74       base::RepeatingClosure(const std::string& id,
75                              CrxDataCallback crx_data_callback,
76                              CrxStateChangeCallback crx_state_change_callback,
77                              Callback callback));
78   MOCK_METHOD5(Update,
79                void(const std::vector<std::string>& ids,
80                     CrxDataCallback crx_data_callback,
81                     CrxStateChangeCallback crx_state_change_callback,
82                     bool is_foreground,
83                     Callback callback));
84   MOCK_METHOD5(CheckForUpdate,
85                void(const std::string& ids,
86                     CrxDataCallback crx_data_callback,
87                     CrxStateChangeCallback crx_state_change_callback,
88                     bool is_foreground,
89                     Callback callback));
90   MOCK_CONST_METHOD2(GetCrxUpdateState,
91                      bool(const std::string& id, CrxUpdateItem* update_item));
92   MOCK_CONST_METHOD1(IsUpdating, bool(const std::string& id));
93   MOCK_METHOD0(Stop, void());
94   MOCK_METHOD3(SendUninstallPing,
95                void(const CrxComponent& crx_component,
96                     int reason,
97                     Callback callback));
98   MOCK_METHOD5(SendInstallPing,
99                void(const CrxComponent& crx_component,
100                     bool success,
101                     int error_code,
102                     int extra_code1,
103                     Callback callback));
104   MOCK_METHOD2(SendRegistrationPing,
105                void(const CrxComponent& crx_component, Callback callback));
106
107  private:
108   ~MockUpdateClient() override = default;
109 };
110
111 class MockServiceObserver : public ServiceObserver {
112  public:
113   MockServiceObserver() = default;
114   ~MockServiceObserver() override = default;
115
116   MOCK_METHOD2(OnEvent, void(Events event, const std::string&));
117 };
118
119 class MockUpdateScheduler : public UpdateScheduler {
120  public:
121   MOCK_METHOD4(Schedule,
122                void(const base::TimeDelta& initial_delay,
123                     const base::TimeDelta& delay,
124                     const UserTask& user_task,
125                     const OnStopTaskCallback& on_stop));
126   MOCK_METHOD0(Stop, void());
127 };
128
129 class LoopHandler {
130  public:
131   explicit LoopHandler(int max_cnt, base::OnceClosure quit_closure)
132       : max_cnt_(max_cnt), quit_closure_(std::move(quit_closure)) {}
133
134   base::RepeatingClosure OnInstall(const std::string&,
135                                    UpdateClient::CrxDataCallback,
136                                    UpdateClient::CrxStateChangeCallback,
137                                    Callback callback) {
138     Handle(std::move(callback));
139     return base::DoNothing();
140   }
141
142   void OnUpdate(const std::vector<std::string>&,
143                 UpdateClient::CrxDataCallback,
144                 UpdateClient::CrxStateChangeCallback,
145                 bool is_foreground,
146                 Callback callback) {
147     EXPECT_FALSE(is_foreground);
148     Handle(std::move(callback));
149   }
150
151  private:
152   void Handle(Callback callback) {
153     ++cnt_;
154     if (cnt_ >= max_cnt_) {
155       base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
156           FROM_HERE, std::move(quit_closure_));
157     }
158     std::move(callback).Run(update_client::Error::NONE);
159   }
160
161   const int max_cnt_ = 0;
162   base::OnceClosure quit_closure_;
163   int cnt_ = 0;
164 };
165
166 class ComponentUpdaterTest : public testing::Test {
167  public:
168   ComponentUpdaterTest();
169   ComponentUpdaterTest(const ComponentUpdaterTest&) = delete;
170   ComponentUpdaterTest& operator=(const ComponentUpdaterTest&) = delete;
171   ~ComponentUpdaterTest() override;
172
173   // Makes the full path to a component updater test file.
174   const base::FilePath test_file(const char* file);
175
176   MockUpdateClient& update_client() { return *update_client_; }
177   ComponentUpdateService& component_updater() { return *component_updater_; }
178   scoped_refptr<TestConfigurator> configurator() const { return config_; }
179   base::OnceClosure quit_closure() { return runloop_.QuitClosure(); }
180   MockUpdateScheduler& scheduler() { return *scheduler_; }
181
182  protected:
183   void RunThreads();
184
185  private:
186   void RunUpdateTask(const UpdateScheduler::UserTask& user_task);
187   void Schedule(const base::TimeDelta& initial_delay,
188                 const base::TimeDelta& delay,
189                 const UpdateScheduler::UserTask& user_task,
190                 const UpdateScheduler::OnStopTaskCallback& on_stop);
191
192   base::test::TaskEnvironment task_environment_;
193   base::RunLoop runloop_;
194
195   std::unique_ptr<TestingPrefServiceSimple> pref_ =
196       std::make_unique<TestingPrefServiceSimple>();
197   scoped_refptr<TestConfigurator> config_ =
198       base::MakeRefCounted<TestConfigurator>(pref_.get());
199   scoped_refptr<MockUpdateClient> update_client_ =
200       base::MakeRefCounted<MockUpdateClient>();
201   std::unique_ptr<ComponentUpdateService> component_updater_;
202   raw_ptr<MockUpdateScheduler> scheduler_;
203 };
204
205 class OnDemandTester {
206  public:
207   void OnDemand(ComponentUpdateService* cus,
208                 const std::string& id,
209                 OnDemandUpdater::Priority priority);
210   update_client::Error error() const { return error_; }
211
212  private:
213   void OnDemandComplete(update_client::Error error);
214
215   update_client::Error error_ = update_client::Error::NONE;
216 };
217
218 void OnDemandTester::OnDemand(ComponentUpdateService* cus,
219                               const std::string& id,
220                               OnDemandUpdater::Priority priority) {
221   cus->GetOnDemandUpdater().OnDemandUpdate(
222       id, priority,
223       base::BindOnce(&OnDemandTester::OnDemandComplete,
224                      base::Unretained(this)));
225 }
226
227 void OnDemandTester::OnDemandComplete(update_client::Error error) {
228   error_ = error;
229 }
230
231 std::unique_ptr<ComponentUpdateService> TestComponentUpdateServiceFactory(
232     scoped_refptr<Configurator> config) {
233   DCHECK(config);
234   return std::make_unique<CrxUpdateService>(
235       config, std::make_unique<MockUpdateScheduler>(),
236       base::MakeRefCounted<MockUpdateClient>(), "");
237 }
238
239 ComponentUpdaterTest::ComponentUpdaterTest() {
240   EXPECT_CALL(update_client(), AddObserver(_)).Times(1);
241   auto scheduler = std::make_unique<MockUpdateScheduler>();
242   scheduler_ = scheduler.get();
243   ON_CALL(*scheduler_, Schedule(_, _, _, _))
244       .WillByDefault(Invoke(this, &ComponentUpdaterTest::Schedule));
245   component_updater_ = std::make_unique<CrxUpdateService>(
246       config_, std::move(scheduler), update_client_, "");
247   RegisterComponentUpdateServicePrefs(pref_->registry());
248 }
249
250 ComponentUpdaterTest::~ComponentUpdaterTest() {
251   EXPECT_CALL(update_client(), RemoveObserver(_)).Times(1);
252 }
253
254 void ComponentUpdaterTest::RunThreads() {
255   runloop_.Run();
256 }
257
258 void ComponentUpdaterTest::RunUpdateTask(
259     const UpdateScheduler::UserTask& user_task) {
260   task_environment_.GetMainThreadTaskRunner()->PostTask(
261       FROM_HERE, base::BindRepeating(
262                      [](const UpdateScheduler::UserTask& user_task,
263                         ComponentUpdaterTest* test) {
264                        user_task.Run(base::BindOnce(
265                            [](const UpdateScheduler::UserTask& user_task,
266                               ComponentUpdaterTest* test) {
267                              test->RunUpdateTask(user_task);
268                            },
269                            user_task, base::Unretained(test)));
270                      },
271                      user_task, base::Unretained(this)));
272 }
273
274 void ComponentUpdaterTest::Schedule(
275     const base::TimeDelta& initial_delay,
276     const base::TimeDelta& delay,
277     const UpdateScheduler::UserTask& user_task,
278     const UpdateScheduler::OnStopTaskCallback& on_stop) {
279   RunUpdateTask(user_task);
280 }
281
282 TEST_F(ComponentUpdaterTest, AddObserver) {
283   MockServiceObserver observer;
284   EXPECT_CALL(update_client(), AddObserver(&observer)).Times(1);
285   EXPECT_CALL(update_client(), Stop()).Times(1);
286   EXPECT_CALL(scheduler(), Stop()).Times(1);
287   component_updater().AddObserver(&observer);
288 }
289
290 TEST_F(ComponentUpdaterTest, RemoveObserver) {
291   MockServiceObserver observer;
292   EXPECT_CALL(update_client(), RemoveObserver(&observer)).Times(1);
293   EXPECT_CALL(update_client(), Stop()).Times(1);
294   EXPECT_CALL(scheduler(), Stop()).Times(1);
295   component_updater().RemoveObserver(&observer);
296 }
297
298 // Tests that UpdateClient::Update is called by the timer loop when
299 // components are registered, and the component update starts.
300 // Also tests that Uninstall is called when a component is unregistered.
301 TEST_F(ComponentUpdaterTest, RegisterComponent) {
302   base::HistogramTester ht;
303
304   scoped_refptr<MockInstaller> installer =
305       base::MakeRefCounted<MockInstaller>();
306   EXPECT_CALL(*installer, Uninstall()).WillOnce(Return(true));
307
308   using update_client::jebg_hash;
309   using update_client::abag_hash;
310
311   const std::string id1 = "abagagagagagagagagagagagagagagag";
312   const std::string id2 = "jebgalgnebhfojomionfpkfelancnnkf";
313   std::vector<std::string> ids;
314   ids.push_back(id1);
315   ids.push_back(id2);
316
317   std::vector<uint8_t> hash;
318   hash.assign(std::begin(abag_hash), std::end(abag_hash));
319   ComponentRegistration component1(id1, {}, hash, base::Version("1.0"), {}, {},
320                                    nullptr, installer, false, true);
321
322   hash.assign(std::begin(jebg_hash), std::end(jebg_hash));
323   ComponentRegistration component2(id2, {}, hash, base::Version("0.9"), {}, {},
324                                    nullptr, installer, false, true);
325
326   // Quit after two update checks have fired.
327   LoopHandler loop_handler(2, quit_closure());
328   EXPECT_CALL(update_client(), Update(_, _, _, _, _))
329       .WillRepeatedly(Invoke(&loop_handler, &LoopHandler::OnUpdate));
330
331   EXPECT_CALL(update_client(), IsUpdating(id1)).Times(1);
332   EXPECT_CALL(update_client(), Stop()).Times(1);
333   EXPECT_CALL(scheduler(), Schedule(_, _, _, _)).Times(1);
334   EXPECT_CALL(scheduler(), Stop()).Times(1);
335
336   EXPECT_TRUE(component_updater().RegisterComponent(component1));
337   EXPECT_TRUE(component_updater().RegisterComponent(component2));
338
339   RunThreads();
340   EXPECT_TRUE(component_updater().UnregisterComponent(id1));
341
342   ht.ExpectUniqueSample("ComponentUpdater.Calls", 1, 2);
343   ht.ExpectUniqueSample("ComponentUpdater.UpdateCompleteResult", 0, 2);
344   ht.ExpectTotalCount("ComponentUpdater.UpdateCompleteTime", 2);
345 }
346
347 // Tests that on-demand updates invoke UpdateClient::Install.
348 TEST_F(ComponentUpdaterTest, OnDemandUpdate) {
349   base::HistogramTester ht;
350
351   // Don't run periodic update task.
352   ON_CALL(scheduler(), Schedule(_, _, _, _)).WillByDefault(Return());
353
354   auto& cus = component_updater();
355
356   // Tests calling OnDemand for an unregistered component. This call results in
357   // an error, which is recorded by the OnDemandTester instance. Since the
358   // component was not registered, the call is ignored for UMA metrics.
359   OnDemandTester ondemand_tester_component_not_registered;
360   ondemand_tester_component_not_registered.OnDemand(
361       &cus, "ihfokbkgjpifnbbojhneepfflplebdkc",
362       OnDemandUpdater::Priority::FOREGROUND);
363
364   // Register two components, then call |OnDemand| for each component, with
365   // foreground and background priorities. Expect calls to |Schedule| because
366   // components have registered, calls to |Install| and |Update| corresponding
367   // to each |OnDemand| invocation, and calls to |Stop| when the mocks are
368   // torn down.
369   LoopHandler loop_handler(2, quit_closure());
370   EXPECT_CALL(scheduler(), Schedule(_, _, _, _)).Times(1);
371   EXPECT_CALL(update_client(), Install(_, _, _, _))
372       .WillOnce(Invoke(&loop_handler, &LoopHandler::OnInstall));
373   EXPECT_CALL(update_client(), Update(_, _, _, _, _))
374       .WillOnce(Invoke(&loop_handler, &LoopHandler::OnUpdate));
375   EXPECT_CALL(update_client(), Stop()).Times(1);
376   EXPECT_CALL(scheduler(), Stop()).Times(1);
377
378   {
379     using update_client::jebg_hash;
380     std::vector<uint8_t> hash;
381     hash.assign(std::begin(jebg_hash), std::end(jebg_hash));
382     EXPECT_TRUE(cus.RegisterComponent(ComponentRegistration(
383         "jebgalgnebhfojomionfpkfelancnnkf", {}, hash, base::Version("0.9"), {},
384         {}, nullptr, base::MakeRefCounted<MockInstaller>(), false, true)));
385   }
386   {
387     using update_client::abag_hash;
388     std::vector<uint8_t> hash;
389     hash.assign(std::begin(abag_hash), std::end(abag_hash));
390     EXPECT_TRUE(cus.RegisterComponent(ComponentRegistration(
391         "abagagagagagagagagagagagagagagag", {}, hash, base::Version("0.9"), {},
392         {}, nullptr, base::MakeRefCounted<MockInstaller>(), false, true)));
393   }
394
395   OnDemandTester ondemand_tester;
396   ondemand_tester.OnDemand(&cus, "jebgalgnebhfojomionfpkfelancnnkf",
397                            OnDemandUpdater::Priority::FOREGROUND);
398   ondemand_tester.OnDemand(&cus, "abagagagagagagagagagagagagagagag",
399                            OnDemandUpdater::Priority::BACKGROUND);
400   RunThreads();
401
402   EXPECT_EQ(update_client::Error::INVALID_ARGUMENT,
403             ondemand_tester_component_not_registered.error());
404   EXPECT_EQ(update_client::Error::NONE, ondemand_tester.error());
405
406   ht.ExpectUniqueSample("ComponentUpdater.Calls", 0, 2);
407   ht.ExpectUniqueSample("ComponentUpdater.UpdateCompleteResult", 0, 2);
408   ht.ExpectTotalCount("ComponentUpdater.UpdateCompleteTime", 2);
409 }
410
411 // Tests that throttling an update invokes UpdateClient::Install.
412 TEST_F(ComponentUpdaterTest, MaybeThrottle) {
413   base::HistogramTester ht;
414
415   // Don't run periodic update task.
416   ON_CALL(scheduler(), Schedule(_, _, _, _)).WillByDefault(Return());
417
418   using update_client::jebg_hash;
419   std::vector<uint8_t> hash;
420   hash.assign(std::begin(jebg_hash), std::end(jebg_hash));
421
422   LoopHandler loop_handler(1, quit_closure());
423   EXPECT_CALL(update_client(), Install(_, _, _, _))
424       .WillOnce(Invoke(&loop_handler, &LoopHandler::OnInstall));
425   EXPECT_CALL(update_client(), Stop()).Times(1);
426   EXPECT_CALL(scheduler(), Schedule(_, _, _, _)).Times(1);
427   EXPECT_CALL(scheduler(), Stop()).Times(1);
428
429   EXPECT_TRUE(component_updater().RegisterComponent(ComponentRegistration(
430       "jebgalgnebhfojomionfpkfelancnnkf", {}, hash, base::Version("0.9"), {},
431       {}, nullptr, base::MakeRefCounted<MockInstaller>(), false, true)));
432   component_updater().MaybeThrottle("jebgalgnebhfojomionfpkfelancnnkf",
433                                     base::DoNothing());
434
435   RunThreads();
436
437   ht.ExpectUniqueSample("ComponentUpdater.Calls", 0, 1);
438   ht.ExpectUniqueSample("ComponentUpdater.UpdateCompleteResult", 0, 1);
439   ht.ExpectTotalCount("ComponentUpdater.UpdateCompleteTime", 1);
440 }
441
442 }  // namespace component_updater