blob: 1a9999c02f8d75b265faab3ffb649a79bdd24471 [file] [log] [blame]
sorin6a57db92016-06-27 22:28:151// Copyright 2016 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
5#include <iterator>
Gyuyoung Kim6afb5082018-01-19 13:35:576#include <memory>
sorin6a57db92016-06-27 22:28:157#include <string>
waffles77255cc2016-08-02 17:25:128#include <utility>
sorin6a57db92016-06-27 22:28:159#include <vector>
10
Sorin Jianuf40ab4b32017-10-06 22:53:4111#include "base/bind.h"
Sebastien Marchand17fa2782019-01-25 19:28:1012#include "base/bind_helpers.h"
sorin6a57db92016-06-27 22:28:1513#include "base/callback.h"
Sorin Jianu316232a2017-05-26 20:22:3014#include "base/files/file_path.h"
15#include "base/files/file_util.h"
sorin6a57db92016-06-27 22:28:1516#include "base/macros.h"
sorin6a57db92016-06-27 22:28:1517#include "base/memory/ref_counted.h"
Sorin Jianu316232a2017-05-26 20:22:3018#include "base/path_service.h"
sorin6a57db92016-06-27 22:28:1519#include "base/run_loop.h"
Gabriel Charette44db1422018-08-06 11:19:3320#include "base/task/post_task.h"
Sorin Jianu316232a2017-05-26 20:22:3021#include "base/test/scoped_path_override.h"
Gabriel Charettec7108742019-08-23 03:31:4022#include "base/test/task_environment.h"
fdorayb26583c2017-05-16 18:47:0123#include "base/threading/thread_task_runner_handle.h"
sorin6a57db92016-06-27 22:28:1524#include "base/version.h"
Sorin Jianu08f92b3c2017-09-25 16:17:1225#include "components/component_updater/component_installer.h"
Sorin Jianu316232a2017-05-26 20:22:3026#include "components/component_updater/component_updater_paths.h"
sorin6a57db92016-06-27 22:28:1527#include "components/component_updater/component_updater_service.h"
28#include "components/component_updater/component_updater_service_internal.h"
Joshua Pawlickif4b33f382018-08-17 17:36:5129#include "components/crx_file/crx_verifier.h"
Sorin Jianu316232a2017-05-26 20:22:3030#include "components/update_client/component_unpacker.h"
sorin6a57db92016-06-27 22:28:1531#include "components/update_client/crx_update_item.h"
Joshua Pawlickid5409e12019-04-06 00:23:1132#include "components/update_client/patcher.h"
sorin6a57db92016-06-27 22:28:1533#include "components/update_client/test_configurator.h"
Joshua Pawlickid5409e12019-04-06 00:23:1134#include "components/update_client/unzipper.h"
sorin6a57db92016-06-27 22:28:1535#include "components/update_client/update_client.h"
sorin7b8650522016-11-02 18:23:4136#include "components/update_client/update_client_errors.h"
Jay Civelli29f9b942017-11-08 20:07:2637#include "services/service_manager/public/cpp/connector.h"
sorin6a57db92016-06-27 22:28:1538#include "testing/gmock/include/gmock/gmock.h"
39#include "testing/gtest/include/gtest/gtest.h"
40
Sorin Jianu316232a2017-05-26 20:22:3041using ComponentUnpacker = update_client::ComponentUnpacker;
sorin6a57db92016-06-27 22:28:1542using Configurator = update_client::Configurator;
43using CrxUpdateItem = update_client::CrxUpdateItem;
44using TestConfigurator = update_client::TestConfigurator;
45using UpdateClient = update_client::UpdateClient;
46
47using ::testing::_;
48using ::testing::Invoke;
49
50namespace component_updater {
51
52namespace {
53
54// This hash corresponds to jebgalgnebhfojomionfpkfelancnnkf.crx.
55const uint8_t kSha256Hash[] = {0x94, 0x16, 0x0b, 0x6d, 0x41, 0x75, 0xe9, 0xec,
56 0x8e, 0xd5, 0xfa, 0x54, 0xb0, 0xd2, 0xdd, 0xa5,
57 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47, 0xf6, 0xc4,
58 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40};
59
Sorin Jianu316232a2017-05-26 20:22:3060constexpr base::FilePath::CharType relative_install_dir[] =
61 FILE_PATH_LITERAL("fake");
62
63base::FilePath test_file(const char* file) {
64 base::FilePath path;
Avi Drissmanf617d012018-05-02 18:48:5365 base::PathService::Get(base::DIR_SOURCE_ROOT, &path);
Sorin Jianu316232a2017-05-26 20:22:3066 return path.AppendASCII("components")
67 .AppendASCII("test")
68 .AppendASCII("data")
69 .AppendASCII("update_client")
70 .AppendASCII(file);
71}
72
sorin6a57db92016-06-27 22:28:1573class MockUpdateClient : public UpdateClient {
74 public:
Sorin Jianu30881152020-03-16 14:31:1975 MockUpdateClient() = default;
Vladislav Kuzkokov12eca792017-10-20 12:45:3876
77 void Install(const std::string& id,
Sorin Jianua8ef73d2017-11-02 16:55:1778 CrxDataCallback crx_data_callback,
Sorin Jianudfb12a42020-03-10 04:12:0379 CrxStateChangeCallback crx_state_change_callback,
Daniel Cheng67848522018-04-27 22:04:4180 Callback callback) override {
Sorin Jianua8ef73d2017-11-02 16:55:1781 DoInstall(id, std::move(crx_data_callback));
Vladislav Kuzkokov12eca792017-10-20 12:45:3882 std::move(callback).Run(update_client::Error::NONE);
83 }
84
85 void Update(const std::vector<std::string>& ids,
Sorin Jianua8ef73d2017-11-02 16:55:1786 CrxDataCallback crx_data_callback,
Sorin Jianudfb12a42020-03-10 04:12:0387 CrxStateChangeCallback crx_state_change_callback,
Sorin Jianub41a592a2018-03-02 16:30:2788 bool is_foreground,
Daniel Cheng67848522018-04-27 22:04:4189 Callback callback) override {
Sorin Jianua8ef73d2017-11-02 16:55:1790 DoUpdate(ids, std::move(crx_data_callback));
Vladislav Kuzkokov12eca792017-10-20 12:45:3891 std::move(callback).Run(update_client::Error::NONE);
92 }
93
94 void SendUninstallPing(const std::string& id,
95 const base::Version& version,
96 int reason,
Daniel Cheng67848522018-04-27 22:04:4197 Callback callback) override {
Vladislav Kuzkokov12eca792017-10-20 12:45:3898 DoSendUninstallPing(id, version, reason);
99 std::move(callback).Run(update_client::Error::NONE);
100 }
101
sorin6a57db92016-06-27 22:28:15102 MOCK_METHOD1(AddObserver, void(Observer* observer));
103 MOCK_METHOD1(RemoveObserver, void(Observer* observer));
Vladislav Kuzkokov12eca792017-10-20 12:45:38104 MOCK_METHOD2(DoInstall,
sorin6a57db92016-06-27 22:28:15105 void(const std::string& id,
Vladislav Kuzkokov12eca792017-10-20 12:45:38106 const CrxDataCallback& crx_data_callback));
107 MOCK_METHOD2(DoUpdate,
sorin6a57db92016-06-27 22:28:15108 void(const std::vector<std::string>& ids,
Vladislav Kuzkokov12eca792017-10-20 12:45:38109 const CrxDataCallback& crx_data_callback));
sorin6a57db92016-06-27 22:28:15110 MOCK_CONST_METHOD2(GetCrxUpdateState,
111 bool(const std::string& id, CrxUpdateItem* update_item));
112 MOCK_CONST_METHOD1(IsUpdating, bool(const std::string& id));
113 MOCK_METHOD0(Stop, void());
Vladislav Kuzkokov12eca792017-10-20 12:45:38114 MOCK_METHOD3(DoSendUninstallPing,
sorin8037ac8c2017-04-19 16:28:00115 void(const std::string& id,
116 const base::Version& version,
Vladislav Kuzkokov12eca792017-10-20 12:45:38117 int reason));
sorin6a57db92016-06-27 22:28:15118
119 private:
Sorin Jianu30881152020-03-16 14:31:19120 ~MockUpdateClient() override = default;
sorin6a57db92016-06-27 22:28:15121};
122
Sorin Jianua8926bf2018-03-09 21:02:53123class MockInstallerPolicy : public ComponentInstallerPolicy {
sorin6a57db92016-06-27 22:28:15124 public:
Sorin Jianu30881152020-03-16 14:31:19125 MockInstallerPolicy() = default;
126 ~MockInstallerPolicy() override = default;
sorin6a57db92016-06-27 22:28:15127
128 bool VerifyInstallation(const base::DictionaryValue& manifest,
129 const base::FilePath& dir) const override {
130 return true;
131 }
132
sorin3574ef92016-08-03 16:46:01133 bool SupportsGroupPolicyEnabledComponentUpdates() const override {
sorin098a4a72016-08-30 04:43:24134 return true;
sorin3574ef92016-08-03 16:46:01135 }
sorin6a57db92016-06-27 22:28:15136
137 bool RequiresNetworkEncryption() const override { return true; }
138
sorin2892f7212016-11-07 18:59:43139 update_client::CrxInstaller::Result OnCustomInstall(
140 const base::DictionaryValue& manifest,
141 const base::FilePath& install_dir) override {
142 return update_client::CrxInstaller::Result(0);
sorin6a57db92016-06-27 22:28:15143 }
144
Xiaochu Liu1e306a32017-11-08 18:57:34145 void OnCustomUninstall() override {}
146
sorin6a57db92016-06-27 22:28:15147 void ComponentReady(
148 const base::Version& version,
149 const base::FilePath& install_dir,
150 std::unique_ptr<base::DictionaryValue> manifest) override {}
151
152 base::FilePath GetRelativeInstallDir() const override {
Sorin Jianu316232a2017-05-26 20:22:30153 return base::FilePath(relative_install_dir);
sorin6a57db92016-06-27 22:28:15154 }
155
156 void GetHash(std::vector<uint8_t>* hash) const override { GetPkHash(hash); }
157
158 std::string GetName() const override { return "fake name"; }
159
sorin2adb2ca2016-06-29 01:44:35160 update_client::InstallerAttributes GetInstallerAttributes() const override {
161 update_client::InstallerAttributes installer_attributes;
162 installer_attributes["ap"] = "fake-ap";
163 installer_attributes["is-enterprise"] = "1";
164 return installer_attributes;
165 }
sorin6a57db92016-06-27 22:28:15166
waffles77255cc2016-08-02 17:25:12167 std::vector<std::string> GetMimeTypes() const override {
168 return std::vector<std::string>();
169 }
170
sorin6a57db92016-06-27 22:28:15171 private:
172 static void GetPkHash(std::vector<uint8_t>* hash) {
173 hash->assign(std::begin(kSha256Hash), std::end(kSha256Hash));
174 }
175};
176
Tibor Goldschwendt5f173cb2018-06-21 22:50:40177class MockUpdateScheduler : public UpdateScheduler {
178 public:
179 MOCK_METHOD4(Schedule,
180 void(const base::TimeDelta& initial_delay,
181 const base::TimeDelta& delay,
182 const UserTask& user_task,
183 const OnStopTaskCallback& on_stop));
184 MOCK_METHOD0(Stop, void());
185};
186
Sorin Jianu08f92b3c2017-09-25 16:17:12187class ComponentInstallerTest : public testing::Test {
sorin6a57db92016-06-27 22:28:15188 public:
Sorin Jianu08f92b3c2017-09-25 16:17:12189 ComponentInstallerTest();
190 ~ComponentInstallerTest() override;
sorin6a57db92016-06-27 22:28:15191
192 MockUpdateClient& update_client() { return *update_client_; }
193 ComponentUpdateService* component_updater() {
194 return component_updater_.get();
195 }
196 scoped_refptr<TestConfigurator> configurator() const { return config_; }
Sorin Jianua8ef73d2017-11-02 16:55:17197 base::OnceClosure quit_closure() { return runloop_.QuitClosure(); }
Tibor Goldschwendt5f173cb2018-06-21 22:50:40198 MockUpdateScheduler& scheduler() { return *scheduler_; }
sorin6a57db92016-06-27 22:28:15199
200 protected:
201 void RunThreads();
Sorin Jianu316232a2017-05-26 20:22:30202 void Unpack(const base::FilePath& crx_path);
203 ComponentUnpacker::Result result() const { return result_; }
sorin6a57db92016-06-27 22:28:15204
Gabriel Charettedfa36042019-08-19 17:30:11205 base::test::TaskEnvironment task_environment_;
Sorin Jianuf40ab4b32017-10-06 22:53:41206
sorin6a57db92016-06-27 22:28:15207 private:
Sorin Jianu316232a2017-05-26 20:22:30208 void UnpackComplete(const ComponentUnpacker::Result& result);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40209 void Schedule(const base::TimeDelta& initial_delay,
210 const base::TimeDelta& delay,
211 const UpdateScheduler::UserTask& user_task,
212 const UpdateScheduler::OnStopTaskCallback& on_stop);
Sorin Jianu316232a2017-05-26 20:22:30213
Sorin Jianu316232a2017-05-26 20:22:30214 const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_ =
215 base::ThreadTaskRunnerHandle::Get();
sorin6a57db92016-06-27 22:28:15216 base::RunLoop runloop_;
sorin6a57db92016-06-27 22:28:15217
Sorin Jianucc048f892017-07-26 02:05:54218 scoped_refptr<TestConfigurator> config_ =
219 base::MakeRefCounted<TestConfigurator>();
Tibor Goldschwendt5f173cb2018-06-21 22:50:40220 MockUpdateScheduler* scheduler_ = nullptr;
Sorin Jianucc048f892017-07-26 02:05:54221 scoped_refptr<MockUpdateClient> update_client_ =
222 base::MakeRefCounted<MockUpdateClient>();
sorin6a57db92016-06-27 22:28:15223 std::unique_ptr<ComponentUpdateService> component_updater_;
Sorin Jianu316232a2017-05-26 20:22:30224 ComponentUnpacker::Result result_;
sorin6a57db92016-06-27 22:28:15225};
226
Sorin Jianu08f92b3c2017-09-25 16:17:12227ComponentInstallerTest::ComponentInstallerTest() {
sorin6a57db92016-06-27 22:28:15228 EXPECT_CALL(update_client(), AddObserver(_)).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40229 auto scheduler = std::make_unique<MockUpdateScheduler>();
230 scheduler_ = scheduler.get();
231 ON_CALL(*scheduler_, Schedule(_, _, _, _))
232 .WillByDefault(Invoke(this, &ComponentInstallerTest::Schedule));
233 component_updater_ = std::make_unique<CrxUpdateService>(
234 config_, std::move(scheduler), update_client_);
sorin6a57db92016-06-27 22:28:15235}
236
Sorin Jianu08f92b3c2017-09-25 16:17:12237ComponentInstallerTest::~ComponentInstallerTest() {
sorin6a57db92016-06-27 22:28:15238 EXPECT_CALL(update_client(), RemoveObserver(_)).Times(1);
239 component_updater_.reset();
240}
241
Sorin Jianu08f92b3c2017-09-25 16:17:12242void ComponentInstallerTest::RunThreads() {
sorin6a57db92016-06-27 22:28:15243 runloop_.Run();
244}
245
Sorin Jianu08f92b3c2017-09-25 16:17:12246void ComponentInstallerTest::Unpack(const base::FilePath& crx_path) {
Joshua Pawlicki6d764422018-02-21 15:23:10247 auto config = base::MakeRefCounted<TestConfigurator>();
Sorin Jianu316232a2017-05-26 20:22:30248 auto component_unpacker = base::MakeRefCounted<ComponentUnpacker>(
249 std::vector<uint8_t>(std::begin(kSha256Hash), std::end(kSha256Hash)),
Joshua Pawlickid5409e12019-04-06 00:23:11250 crx_path, nullptr, config->GetUnzipperFactory()->Create(),
Joshua Pawlickiafaa2922019-09-03 18:50:23251 config->GetPatcherFactory()->Create(), crx_file::VerifierFormat::CRX3);
Sorin Jianua8ef73d2017-11-02 16:55:17252 component_unpacker->Unpack(base::BindOnce(
253 &ComponentInstallerTest::UnpackComplete, base::Unretained(this)));
Sorin Jianu316232a2017-05-26 20:22:30254 RunThreads();
255}
256
Sorin Jianu08f92b3c2017-09-25 16:17:12257void ComponentInstallerTest::UnpackComplete(
Sorin Jianu316232a2017-05-26 20:22:30258 const ComponentUnpacker::Result& result) {
259 result_ = result;
260
261 EXPECT_EQ(update_client::UnpackerError::kNone, result_.error);
262 EXPECT_EQ(0, result_.extended_error);
263
Sorin Jianua8ef73d2017-11-02 16:55:17264 main_thread_task_runner_->PostTask(FROM_HERE, quit_closure());
Sorin Jianu316232a2017-05-26 20:22:30265}
266
Tibor Goldschwendt5f173cb2018-06-21 22:50:40267void ComponentInstallerTest::Schedule(
268 const base::TimeDelta& initial_delay,
269 const base::TimeDelta& delay,
270 const UpdateScheduler::UserTask& user_task,
271 const UpdateScheduler::OnStopTaskCallback& on_stop) {
272 user_task.Run(base::DoNothing());
273}
274
sorin6a57db92016-06-27 22:28:15275} // namespace
276
Sorin Jianu08f92b3c2017-09-25 16:17:12277// Tests that the component metadata is propagated from the component installer
278// and its component policy, through the instance of the CrxComponent, to the
279// component updater service.
280TEST_F(ComponentInstallerTest, RegisterComponent) {
sorin6a57db92016-06-27 22:28:15281 class LoopHandler {
282 public:
Sorin Jianua8ef73d2017-11-02 16:55:17283 LoopHandler(int max_cnt, base::OnceClosure quit_closure)
284 : max_cnt_(max_cnt), quit_closure_(std::move(quit_closure)) {}
sorin6a57db92016-06-27 22:28:15285
286 void OnUpdate(const std::vector<std::string>& ids,
Vladislav Kuzkokov12eca792017-10-20 12:45:38287 const UpdateClient::CrxDataCallback& crx_data_callback) {
sorin6a57db92016-06-27 22:28:15288 static int cnt = 0;
289 ++cnt;
290 if (cnt >= max_cnt_)
Sorin Jianua8ef73d2017-11-02 16:55:17291 std::move(quit_closure_).Run();
sorin6a57db92016-06-27 22:28:15292 }
293
294 private:
295 const int max_cnt_;
Sorin Jianua8ef73d2017-11-02 16:55:17296 base::OnceClosure quit_closure_;
sorin6a57db92016-06-27 22:28:15297 };
298
Sorin Jianu0bf4bd3f2017-06-01 23:42:32299 base::ScopedPathOverride scoped_path_override(DIR_COMPONENT_USER);
300
sorin6a57db92016-06-27 22:28:15301 const std::string id("jebgalgnebhfojomionfpkfelancnnkf");
302
303 // Quit after one update check has been fired.
304 LoopHandler loop_handler(1, quit_closure());
Vladislav Kuzkokov12eca792017-10-20 12:45:38305 EXPECT_CALL(update_client(), DoUpdate(_, _))
sorin6a57db92016-06-27 22:28:15306 .WillRepeatedly(Invoke(&loop_handler, &LoopHandler::OnUpdate));
307
308 EXPECT_CALL(update_client(), GetCrxUpdateState(id, _)).Times(1);
309 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40310 EXPECT_CALL(scheduler(), Schedule(_, _, _, _)).Times(1);
311 EXPECT_CALL(scheduler(), Stop()).Times(1);
sorin6a57db92016-06-27 22:28:15312
Sorin Jianu08f92b3c2017-09-25 16:17:12313 auto installer = base::MakeRefCounted<ComponentInstaller>(
Sorin Jianua8926bf2018-03-09 21:02:53314 std::make_unique<MockInstallerPolicy>());
Sorin Jianua8ef73d2017-11-02 16:55:17315 installer->Register(component_updater(), base::OnceClosure());
sorin6a57db92016-06-27 22:28:15316
317 RunThreads();
318
319 CrxUpdateItem item;
320 EXPECT_TRUE(component_updater()->GetComponentDetails(id, &item));
Sorin Jianu73900242018-08-17 01:11:53321 ASSERT_TRUE(item.component);
322 const CrxComponent& component = *item.component;
sorin2adb2ca2016-06-29 01:44:35323
324 update_client::InstallerAttributes expected_attrs;
325 expected_attrs["ap"] = "fake-ap";
326 expected_attrs["is-enterprise"] = "1";
327
sorin6a57db92016-06-27 22:28:15328 EXPECT_EQ(
329 std::vector<uint8_t>(std::begin(kSha256Hash), std::end(kSha256Hash)),
330 component.pk_hash);
331 EXPECT_EQ(base::Version("0.0.0.0"), component.version);
332 EXPECT_TRUE(component.fingerprint.empty());
333 EXPECT_STREQ("fake name", component.name.c_str());
sorin2adb2ca2016-06-29 01:44:35334 EXPECT_EQ(expected_attrs, component.installer_attributes);
sorin6a57db92016-06-27 22:28:15335 EXPECT_TRUE(component.requires_network_encryption);
sorin098a4a72016-08-30 04:43:24336 EXPECT_TRUE(component.supports_group_policy_enable_component_updates);
sorin6a57db92016-06-27 22:28:15337}
338
Sorin Jianu316232a2017-05-26 20:22:30339// Tests that the unpack path is removed when the install succeeded.
Sorin Jianu08f92b3c2017-09-25 16:17:12340TEST_F(ComponentInstallerTest, UnpackPathInstallSuccess) {
341 auto installer = base::MakeRefCounted<ComponentInstaller>(
Sorin Jianua8926bf2018-03-09 21:02:53342 std::make_unique<MockInstallerPolicy>());
Sorin Jianu316232a2017-05-26 20:22:30343
344 Unpack(test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
345
346 const auto unpack_path = result().unpack_path;
347 EXPECT_TRUE(base::DirectoryExists(unpack_path));
Minh X. Nguyenaafd7632017-10-19 21:12:35348 EXPECT_EQ(update_client::jebg_public_key, result().public_key);
Sorin Jianu316232a2017-05-26 20:22:30349
Sorin Jianu316232a2017-05-26 20:22:30350 base::ScopedPathOverride scoped_path_override(DIR_COMPONENT_USER);
351 base::FilePath base_dir;
Avi Drissmanf617d012018-05-02 18:48:53352 EXPECT_TRUE(base::PathService::Get(DIR_COMPONENT_USER, &base_dir));
Sorin Jianu316232a2017-05-26 20:22:30353 base_dir = base_dir.Append(relative_install_dir);
354 EXPECT_TRUE(base::CreateDirectory(base_dir));
Sorin Jianuf40ab4b32017-10-06 22:53:41355 installer->Install(
Sorin Jianu9d64af672020-02-05 19:14:34356 unpack_path, update_client::jebg_public_key, nullptr,
Sorin Jianua8ef73d2017-11-02 16:55:17357 base::BindOnce([](const update_client::CrxInstaller::Result& result) {
Sorin Jianuf40ab4b32017-10-06 22:53:41358 EXPECT_EQ(0, result.error);
359 }));
Sorin Jianu316232a2017-05-26 20:22:30360
Gabriel Charettedfa36042019-08-19 17:30:11361 task_environment_.RunUntilIdle();
Sorin Jianuf40ab4b32017-10-06 22:53:41362
363 EXPECT_FALSE(base::PathExists(unpack_path));
Sorin Jianu316232a2017-05-26 20:22:30364 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40365 EXPECT_CALL(scheduler(), Stop()).Times(1);
Sorin Jianu316232a2017-05-26 20:22:30366}
367
368// Tests that the unpack path is removed when the install failed.
Sorin Jianu08f92b3c2017-09-25 16:17:12369TEST_F(ComponentInstallerTest, UnpackPathInstallError) {
370 auto installer = base::MakeRefCounted<ComponentInstaller>(
Sorin Jianua8926bf2018-03-09 21:02:53371 std::make_unique<MockInstallerPolicy>());
Sorin Jianu316232a2017-05-26 20:22:30372
373 Unpack(test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
374
375 const auto unpack_path = result().unpack_path;
376 EXPECT_TRUE(base::DirectoryExists(unpack_path));
377
Sorin Jianu316232a2017-05-26 20:22:30378 // Test the precondition that DIR_COMPONENT_USER is not registered with
379 // the path service.
380 base::FilePath base_dir;
Avi Drissmanea15ea02018-05-07 18:55:12381 EXPECT_FALSE(base::PathService::Get(DIR_COMPONENT_USER, &base_dir));
Sorin Jianu316232a2017-05-26 20:22:30382
383 // Calling |Install| fails since DIR_COMPONENT_USER does not exist.
Sorin Jianuf40ab4b32017-10-06 22:53:41384 installer->Install(
Sorin Jianu9d64af672020-02-05 19:14:34385 unpack_path, update_client::jebg_public_key, nullptr,
Sorin Jianua8ef73d2017-11-02 16:55:17386 base::BindOnce([](const update_client::CrxInstaller::Result& result) {
Sorin Jianuf40ab4b32017-10-06 22:53:41387 EXPECT_EQ(static_cast<int>(
388 update_client::InstallError::NO_DIR_COMPONENT_USER),
389 result.error);
390 }));
Sorin Jianu316232a2017-05-26 20:22:30391
Gabriel Charettedfa36042019-08-19 17:30:11392 task_environment_.RunUntilIdle();
Sorin Jianuf40ab4b32017-10-06 22:53:41393
394 EXPECT_FALSE(base::PathExists(unpack_path));
Sorin Jianu316232a2017-05-26 20:22:30395 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40396 EXPECT_CALL(scheduler(), Stop()).Times(1);
Sorin Jianu316232a2017-05-26 20:22:30397}
398
sorin6a57db92016-06-27 22:28:15399} // namespace component_updater