blob: f963f8b243486b2cad4fc578790a446731fa7c38 [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"
fdorayb26583c2017-05-16 18:47:0122#include "base/test/scoped_task_environment.h"
23#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:
sorin2adb2ca2016-06-29 01:44:3575 MockUpdateClient() {}
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,
Daniel Cheng67848522018-04-27 22:04:4179 Callback callback) override {
Sorin Jianua8ef73d2017-11-02 16:55:1780 DoInstall(id, std::move(crx_data_callback));
Vladislav Kuzkokov12eca792017-10-20 12:45:3881 std::move(callback).Run(update_client::Error::NONE);
82 }
83
84 void Update(const std::vector<std::string>& ids,
Sorin Jianua8ef73d2017-11-02 16:55:1785 CrxDataCallback crx_data_callback,
Sorin Jianub41a592a2018-03-02 16:30:2786 bool is_foreground,
Daniel Cheng67848522018-04-27 22:04:4187 Callback callback) override {
Sorin Jianua8ef73d2017-11-02 16:55:1788 DoUpdate(ids, std::move(crx_data_callback));
Vladislav Kuzkokov12eca792017-10-20 12:45:3889 std::move(callback).Run(update_client::Error::NONE);
90 }
91
92 void SendUninstallPing(const std::string& id,
93 const base::Version& version,
94 int reason,
Daniel Cheng67848522018-04-27 22:04:4195 Callback callback) override {
Vladislav Kuzkokov12eca792017-10-20 12:45:3896 DoSendUninstallPing(id, version, reason);
97 std::move(callback).Run(update_client::Error::NONE);
98 }
99
sorin6a57db92016-06-27 22:28:15100 MOCK_METHOD1(AddObserver, void(Observer* observer));
101 MOCK_METHOD1(RemoveObserver, void(Observer* observer));
Vladislav Kuzkokov12eca792017-10-20 12:45:38102 MOCK_METHOD2(DoInstall,
sorin6a57db92016-06-27 22:28:15103 void(const std::string& id,
Vladislav Kuzkokov12eca792017-10-20 12:45:38104 const CrxDataCallback& crx_data_callback));
105 MOCK_METHOD2(DoUpdate,
sorin6a57db92016-06-27 22:28:15106 void(const std::vector<std::string>& ids,
Vladislav Kuzkokov12eca792017-10-20 12:45:38107 const CrxDataCallback& crx_data_callback));
sorin6a57db92016-06-27 22:28:15108 MOCK_CONST_METHOD2(GetCrxUpdateState,
109 bool(const std::string& id, CrxUpdateItem* update_item));
110 MOCK_CONST_METHOD1(IsUpdating, bool(const std::string& id));
111 MOCK_METHOD0(Stop, void());
Vladislav Kuzkokov12eca792017-10-20 12:45:38112 MOCK_METHOD3(DoSendUninstallPing,
sorin8037ac8c2017-04-19 16:28:00113 void(const std::string& id,
114 const base::Version& version,
Vladislav Kuzkokov12eca792017-10-20 12:45:38115 int reason));
sorin6a57db92016-06-27 22:28:15116
117 private:
sorin2adb2ca2016-06-29 01:44:35118 ~MockUpdateClient() override {}
sorin6a57db92016-06-27 22:28:15119};
120
Sorin Jianua8926bf2018-03-09 21:02:53121class MockInstallerPolicy : public ComponentInstallerPolicy {
sorin6a57db92016-06-27 22:28:15122 public:
Sorin Jianua8926bf2018-03-09 21:02:53123 MockInstallerPolicy() {}
124 ~MockInstallerPolicy() override {}
sorin6a57db92016-06-27 22:28:15125
126 bool VerifyInstallation(const base::DictionaryValue& manifest,
127 const base::FilePath& dir) const override {
128 return true;
129 }
130
sorin3574ef92016-08-03 16:46:01131 bool SupportsGroupPolicyEnabledComponentUpdates() const override {
sorin098a4a72016-08-30 04:43:24132 return true;
sorin3574ef92016-08-03 16:46:01133 }
sorin6a57db92016-06-27 22:28:15134
135 bool RequiresNetworkEncryption() const override { return true; }
136
sorin2892f7212016-11-07 18:59:43137 update_client::CrxInstaller::Result OnCustomInstall(
138 const base::DictionaryValue& manifest,
139 const base::FilePath& install_dir) override {
140 return update_client::CrxInstaller::Result(0);
sorin6a57db92016-06-27 22:28:15141 }
142
Xiaochu Liu1e306a32017-11-08 18:57:34143 void OnCustomUninstall() override {}
144
sorin6a57db92016-06-27 22:28:15145 void ComponentReady(
146 const base::Version& version,
147 const base::FilePath& install_dir,
148 std::unique_ptr<base::DictionaryValue> manifest) override {}
149
150 base::FilePath GetRelativeInstallDir() const override {
Sorin Jianu316232a2017-05-26 20:22:30151 return base::FilePath(relative_install_dir);
sorin6a57db92016-06-27 22:28:15152 }
153
154 void GetHash(std::vector<uint8_t>* hash) const override { GetPkHash(hash); }
155
156 std::string GetName() const override { return "fake name"; }
157
sorin2adb2ca2016-06-29 01:44:35158 update_client::InstallerAttributes GetInstallerAttributes() const override {
159 update_client::InstallerAttributes installer_attributes;
160 installer_attributes["ap"] = "fake-ap";
161 installer_attributes["is-enterprise"] = "1";
162 return installer_attributes;
163 }
sorin6a57db92016-06-27 22:28:15164
waffles77255cc2016-08-02 17:25:12165 std::vector<std::string> GetMimeTypes() const override {
166 return std::vector<std::string>();
167 }
168
sorin6a57db92016-06-27 22:28:15169 private:
170 static void GetPkHash(std::vector<uint8_t>* hash) {
171 hash->assign(std::begin(kSha256Hash), std::end(kSha256Hash));
172 }
173};
174
Tibor Goldschwendt5f173cb2018-06-21 22:50:40175class MockUpdateScheduler : public UpdateScheduler {
176 public:
177 MOCK_METHOD4(Schedule,
178 void(const base::TimeDelta& initial_delay,
179 const base::TimeDelta& delay,
180 const UserTask& user_task,
181 const OnStopTaskCallback& on_stop));
182 MOCK_METHOD0(Stop, void());
183};
184
Sorin Jianu08f92b3c2017-09-25 16:17:12185class ComponentInstallerTest : public testing::Test {
sorin6a57db92016-06-27 22:28:15186 public:
Sorin Jianu08f92b3c2017-09-25 16:17:12187 ComponentInstallerTest();
188 ~ComponentInstallerTest() override;
sorin6a57db92016-06-27 22:28:15189
190 MockUpdateClient& update_client() { return *update_client_; }
191 ComponentUpdateService* component_updater() {
192 return component_updater_.get();
193 }
194 scoped_refptr<TestConfigurator> configurator() const { return config_; }
Sorin Jianua8ef73d2017-11-02 16:55:17195 base::OnceClosure quit_closure() { return runloop_.QuitClosure(); }
Tibor Goldschwendt5f173cb2018-06-21 22:50:40196 MockUpdateScheduler& scheduler() { return *scheduler_; }
sorin6a57db92016-06-27 22:28:15197
198 protected:
199 void RunThreads();
Sorin Jianu316232a2017-05-26 20:22:30200 void Unpack(const base::FilePath& crx_path);
201 ComponentUnpacker::Result result() const { return result_; }
sorin6a57db92016-06-27 22:28:15202
Sorin Jianuf40ab4b32017-10-06 22:53:41203 base::test::ScopedTaskEnvironment scoped_task_environment_;
204
sorin6a57db92016-06-27 22:28:15205 private:
Sorin Jianu316232a2017-05-26 20:22:30206 void UnpackComplete(const ComponentUnpacker::Result& result);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40207 void Schedule(const base::TimeDelta& initial_delay,
208 const base::TimeDelta& delay,
209 const UpdateScheduler::UserTask& user_task,
210 const UpdateScheduler::OnStopTaskCallback& on_stop);
Sorin Jianu316232a2017-05-26 20:22:30211
Sorin Jianu316232a2017-05-26 20:22:30212 const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_ =
213 base::ThreadTaskRunnerHandle::Get();
sorin6a57db92016-06-27 22:28:15214 base::RunLoop runloop_;
sorin6a57db92016-06-27 22:28:15215
Sorin Jianucc048f892017-07-26 02:05:54216 scoped_refptr<TestConfigurator> config_ =
217 base::MakeRefCounted<TestConfigurator>();
Tibor Goldschwendt5f173cb2018-06-21 22:50:40218 MockUpdateScheduler* scheduler_ = nullptr;
Sorin Jianucc048f892017-07-26 02:05:54219 scoped_refptr<MockUpdateClient> update_client_ =
220 base::MakeRefCounted<MockUpdateClient>();
sorin6a57db92016-06-27 22:28:15221 std::unique_ptr<ComponentUpdateService> component_updater_;
Sorin Jianu316232a2017-05-26 20:22:30222 ComponentUnpacker::Result result_;
sorin6a57db92016-06-27 22:28:15223};
224
Sorin Jianu08f92b3c2017-09-25 16:17:12225ComponentInstallerTest::ComponentInstallerTest() {
sorin6a57db92016-06-27 22:28:15226 EXPECT_CALL(update_client(), AddObserver(_)).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40227 auto scheduler = std::make_unique<MockUpdateScheduler>();
228 scheduler_ = scheduler.get();
229 ON_CALL(*scheduler_, Schedule(_, _, _, _))
230 .WillByDefault(Invoke(this, &ComponentInstallerTest::Schedule));
231 component_updater_ = std::make_unique<CrxUpdateService>(
232 config_, std::move(scheduler), update_client_);
sorin6a57db92016-06-27 22:28:15233}
234
Sorin Jianu08f92b3c2017-09-25 16:17:12235ComponentInstallerTest::~ComponentInstallerTest() {
sorin6a57db92016-06-27 22:28:15236 EXPECT_CALL(update_client(), RemoveObserver(_)).Times(1);
237 component_updater_.reset();
238}
239
Sorin Jianu08f92b3c2017-09-25 16:17:12240void ComponentInstallerTest::RunThreads() {
sorin6a57db92016-06-27 22:28:15241 runloop_.Run();
242}
243
Sorin Jianu08f92b3c2017-09-25 16:17:12244void ComponentInstallerTest::Unpack(const base::FilePath& crx_path) {
Joshua Pawlicki6d764422018-02-21 15:23:10245 auto config = base::MakeRefCounted<TestConfigurator>();
Sorin Jianu316232a2017-05-26 20:22:30246 auto component_unpacker = base::MakeRefCounted<ComponentUnpacker>(
247 std::vector<uint8_t>(std::begin(kSha256Hash), std::end(kSha256Hash)),
Joshua Pawlickid5409e12019-04-06 00:23:11248 crx_path, nullptr, config->GetUnzipperFactory()->Create(),
249 config->GetPatcherFactory()->Create(),
Joshua Pawlickif4b33f382018-08-17 17:36:51250 crx_file::VerifierFormat::CRX2_OR_CRX3);
Sorin Jianua8ef73d2017-11-02 16:55:17251 component_unpacker->Unpack(base::BindOnce(
252 &ComponentInstallerTest::UnpackComplete, base::Unretained(this)));
Sorin Jianu316232a2017-05-26 20:22:30253 RunThreads();
254}
255
Sorin Jianu08f92b3c2017-09-25 16:17:12256void ComponentInstallerTest::UnpackComplete(
Sorin Jianu316232a2017-05-26 20:22:30257 const ComponentUnpacker::Result& result) {
258 result_ = result;
259
260 EXPECT_EQ(update_client::UnpackerError::kNone, result_.error);
261 EXPECT_EQ(0, result_.extended_error);
262
Sorin Jianua8ef73d2017-11-02 16:55:17263 main_thread_task_runner_->PostTask(FROM_HERE, quit_closure());
Sorin Jianu316232a2017-05-26 20:22:30264}
265
Tibor Goldschwendt5f173cb2018-06-21 22:50:40266void ComponentInstallerTest::Schedule(
267 const base::TimeDelta& initial_delay,
268 const base::TimeDelta& delay,
269 const UpdateScheduler::UserTask& user_task,
270 const UpdateScheduler::OnStopTaskCallback& on_stop) {
271 user_task.Run(base::DoNothing());
272}
273
sorin6a57db92016-06-27 22:28:15274} // namespace
275
Sorin Jianu08f92b3c2017-09-25 16:17:12276// Tests that the component metadata is propagated from the component installer
277// and its component policy, through the instance of the CrxComponent, to the
278// component updater service.
279TEST_F(ComponentInstallerTest, RegisterComponent) {
sorin6a57db92016-06-27 22:28:15280 class LoopHandler {
281 public:
Sorin Jianua8ef73d2017-11-02 16:55:17282 LoopHandler(int max_cnt, base::OnceClosure quit_closure)
283 : max_cnt_(max_cnt), quit_closure_(std::move(quit_closure)) {}
sorin6a57db92016-06-27 22:28:15284
285 void OnUpdate(const std::vector<std::string>& ids,
Vladislav Kuzkokov12eca792017-10-20 12:45:38286 const UpdateClient::CrxDataCallback& crx_data_callback) {
sorin6a57db92016-06-27 22:28:15287 static int cnt = 0;
288 ++cnt;
289 if (cnt >= max_cnt_)
Sorin Jianua8ef73d2017-11-02 16:55:17290 std::move(quit_closure_).Run();
sorin6a57db92016-06-27 22:28:15291 }
292
293 private:
294 const int max_cnt_;
Sorin Jianua8ef73d2017-11-02 16:55:17295 base::OnceClosure quit_closure_;
sorin6a57db92016-06-27 22:28:15296 };
297
Sorin Jianu0bf4bd3f2017-06-01 23:42:32298 base::ScopedPathOverride scoped_path_override(DIR_COMPONENT_USER);
299
sorin6a57db92016-06-27 22:28:15300 const std::string id("jebgalgnebhfojomionfpkfelancnnkf");
301
302 // Quit after one update check has been fired.
303 LoopHandler loop_handler(1, quit_closure());
Vladislav Kuzkokov12eca792017-10-20 12:45:38304 EXPECT_CALL(update_client(), DoUpdate(_, _))
sorin6a57db92016-06-27 22:28:15305 .WillRepeatedly(Invoke(&loop_handler, &LoopHandler::OnUpdate));
306
307 EXPECT_CALL(update_client(), GetCrxUpdateState(id, _)).Times(1);
308 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40309 EXPECT_CALL(scheduler(), Schedule(_, _, _, _)).Times(1);
310 EXPECT_CALL(scheduler(), Stop()).Times(1);
sorin6a57db92016-06-27 22:28:15311
Sorin Jianu08f92b3c2017-09-25 16:17:12312 auto installer = base::MakeRefCounted<ComponentInstaller>(
Sorin Jianua8926bf2018-03-09 21:02:53313 std::make_unique<MockInstallerPolicy>());
Sorin Jianua8ef73d2017-11-02 16:55:17314 installer->Register(component_updater(), base::OnceClosure());
sorin6a57db92016-06-27 22:28:15315
316 RunThreads();
317
318 CrxUpdateItem item;
319 EXPECT_TRUE(component_updater()->GetComponentDetails(id, &item));
Sorin Jianu73900242018-08-17 01:11:53320 ASSERT_TRUE(item.component);
321 const CrxComponent& component = *item.component;
sorin2adb2ca2016-06-29 01:44:35322
323 update_client::InstallerAttributes expected_attrs;
324 expected_attrs["ap"] = "fake-ap";
325 expected_attrs["is-enterprise"] = "1";
326
sorin6a57db92016-06-27 22:28:15327 EXPECT_EQ(
328 std::vector<uint8_t>(std::begin(kSha256Hash), std::end(kSha256Hash)),
329 component.pk_hash);
330 EXPECT_EQ(base::Version("0.0.0.0"), component.version);
331 EXPECT_TRUE(component.fingerprint.empty());
332 EXPECT_STREQ("fake name", component.name.c_str());
sorin2adb2ca2016-06-29 01:44:35333 EXPECT_EQ(expected_attrs, component.installer_attributes);
sorin6a57db92016-06-27 22:28:15334 EXPECT_TRUE(component.requires_network_encryption);
sorin098a4a72016-08-30 04:43:24335 EXPECT_TRUE(component.supports_group_policy_enable_component_updates);
sorin6a57db92016-06-27 22:28:15336}
337
Sorin Jianu316232a2017-05-26 20:22:30338// Tests that the unpack path is removed when the install succeeded.
Sorin Jianu08f92b3c2017-09-25 16:17:12339TEST_F(ComponentInstallerTest, UnpackPathInstallSuccess) {
340 auto installer = base::MakeRefCounted<ComponentInstaller>(
Sorin Jianua8926bf2018-03-09 21:02:53341 std::make_unique<MockInstallerPolicy>());
Sorin Jianu316232a2017-05-26 20:22:30342
343 Unpack(test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
344
345 const auto unpack_path = result().unpack_path;
346 EXPECT_TRUE(base::DirectoryExists(unpack_path));
Minh X. Nguyenaafd7632017-10-19 21:12:35347 EXPECT_EQ(update_client::jebg_public_key, result().public_key);
Sorin Jianu316232a2017-05-26 20:22:30348
Sorin Jianu316232a2017-05-26 20:22:30349 base::ScopedPathOverride scoped_path_override(DIR_COMPONENT_USER);
350 base::FilePath base_dir;
Avi Drissmanf617d012018-05-02 18:48:53351 EXPECT_TRUE(base::PathService::Get(DIR_COMPONENT_USER, &base_dir));
Sorin Jianu316232a2017-05-26 20:22:30352 base_dir = base_dir.Append(relative_install_dir);
353 EXPECT_TRUE(base::CreateDirectory(base_dir));
Sorin Jianuf40ab4b32017-10-06 22:53:41354 installer->Install(
Sorin Jianuea5534e92017-10-27 01:40:28355 unpack_path, update_client::jebg_public_key,
Sorin Jianua8ef73d2017-11-02 16:55:17356 base::BindOnce([](const update_client::CrxInstaller::Result& result) {
Sorin Jianuf40ab4b32017-10-06 22:53:41357 EXPECT_EQ(0, result.error);
358 }));
Sorin Jianu316232a2017-05-26 20:22:30359
Sorin Jianuf40ab4b32017-10-06 22:53:41360 scoped_task_environment_.RunUntilIdle();
361
362 EXPECT_FALSE(base::PathExists(unpack_path));
Sorin Jianu316232a2017-05-26 20:22:30363 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40364 EXPECT_CALL(scheduler(), Stop()).Times(1);
Sorin Jianu316232a2017-05-26 20:22:30365}
366
367// Tests that the unpack path is removed when the install failed.
Sorin Jianu08f92b3c2017-09-25 16:17:12368TEST_F(ComponentInstallerTest, UnpackPathInstallError) {
369 auto installer = base::MakeRefCounted<ComponentInstaller>(
Sorin Jianua8926bf2018-03-09 21:02:53370 std::make_unique<MockInstallerPolicy>());
Sorin Jianu316232a2017-05-26 20:22:30371
372 Unpack(test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
373
374 const auto unpack_path = result().unpack_path;
375 EXPECT_TRUE(base::DirectoryExists(unpack_path));
376
Sorin Jianu316232a2017-05-26 20:22:30377 // Test the precondition that DIR_COMPONENT_USER is not registered with
378 // the path service.
379 base::FilePath base_dir;
Avi Drissmanea15ea02018-05-07 18:55:12380 EXPECT_FALSE(base::PathService::Get(DIR_COMPONENT_USER, &base_dir));
Sorin Jianu316232a2017-05-26 20:22:30381
382 // Calling |Install| fails since DIR_COMPONENT_USER does not exist.
Sorin Jianuf40ab4b32017-10-06 22:53:41383 installer->Install(
Sorin Jianuea5534e92017-10-27 01:40:28384 unpack_path, update_client::jebg_public_key,
Sorin Jianua8ef73d2017-11-02 16:55:17385 base::BindOnce([](const update_client::CrxInstaller::Result& result) {
Sorin Jianuf40ab4b32017-10-06 22:53:41386 EXPECT_EQ(static_cast<int>(
387 update_client::InstallError::NO_DIR_COMPONENT_USER),
388 result.error);
389 }));
Sorin Jianu316232a2017-05-26 20:22:30390
Sorin Jianuf40ab4b32017-10-06 22:53:41391 scoped_task_environment_.RunUntilIdle();
392
393 EXPECT_FALSE(base::PathExists(unpack_path));
Sorin Jianu316232a2017-05-26 20:22:30394 EXPECT_CALL(update_client(), Stop()).Times(1);
Tibor Goldschwendt5f173cb2018-06-21 22:50:40395 EXPECT_CALL(scheduler(), Stop()).Times(1);
Sorin Jianu316232a2017-05-26 20:22:30396}
397
sorin6a57db92016-06-27 22:28:15398} // namespace component_updater