blob: f957b4dc98bf17f098ba9e0db617e578b820a6f6 [file] [log] [blame]
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -07001// Copyright 2020 The Chromium OS 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
Jae Hoon Kimc5482f92019-12-04 17:52:23 -08005#include <base/files/file_util.h>
6#include <gmock/gmock.h>
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -07007#include <gtest/gtest.h>
Andrew4d454002020-05-06 09:59:17 -07008#include <metrics/metrics_library_mock.h>
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -07009
Jae Hoon Kimc5482f92019-12-04 17:52:23 -080010#include "dlcservice/boot/mock_boot_device.h"
Andrew4d454002020-05-06 09:59:17 -070011#include "dlcservice/metrics.h"
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -070012#include "dlcservice/prefs.h"
13#include "dlcservice/system_state.h"
14#include "dlcservice/test_utils.h"
Jae Hoon Kimc5482f92019-12-04 17:52:23 -080015#include "dlcservice/utils.h"
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -070016
Andrew0a534ed2020-05-06 09:59:17 -070017using dlcservice::metrics::InstallResult;
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -070018using testing::_;
Mike Frysinger0cc18562021-01-04 02:16:54 -050019using testing::DoAll;
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -070020using testing::ElementsAre;
21using testing::Return;
22using testing::SetArgPointee;
23
24namespace dlcservice {
25
26class DlcBaseTest : public BaseTest {
27 public:
28 DlcBaseTest() = default;
29
Jae Hoon Kimf9b2c9d2020-07-22 12:09:13 -070030 std::unique_ptr<DlcBase> Install(const DlcId& id) {
31 auto dlc = std::make_unique<DlcBase>(id);
32 dlc->Initialize();
33 EXPECT_CALL(*mock_update_engine_proxy_ptr_, SetDlcActiveValue(_, id, _, _))
34 .WillRepeatedly(Return(true));
35 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
36 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
37 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
38 EXPECT_CALL(*mock_metrics_,
39 SendInstallResult(InstallResult::kSuccessNewInstall));
40 EXPECT_TRUE(dlc->Install(&err_));
41 InstallWithUpdateEngine({id});
42 dlc->InstallCompleted(&err_);
43 dlc->FinishInstall(/*installed_by_ue=*/true, &err_);
44 return dlc;
45 }
46
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -070047 private:
Amin Hassani6b010bf2020-06-04 17:26:58 -070048 DlcBaseTest(const DlcBaseTest&) = delete;
49 DlcBaseTest& operator=(const DlcBaseTest&) = delete;
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -070050};
51
Jae Hoon Kimc5482f92019-12-04 17:52:23 -080052class DlcBaseTestRemovable : public DlcBaseTest {
53 public:
54 DlcBaseTestRemovable() = default;
55
56 void SetUp() override {
Jae Hoon Kim23c7f492020-06-26 10:30:09 -070057 ON_CALL(*mock_boot_device_ptr_, IsRemovableDevice(_))
58 .WillByDefault(Return(true));
59 DlcBaseTest::SetUp();
Jae Hoon Kimc5482f92019-12-04 17:52:23 -080060 }
61
62 private:
Amin Hassani6b010bf2020-06-04 17:26:58 -070063 DlcBaseTestRemovable(const DlcBaseTestRemovable&) = delete;
64 DlcBaseTestRemovable& operator=(const DlcBaseTestRemovable&) = delete;
Jae Hoon Kimc5482f92019-12-04 17:52:23 -080065};
66
Jae Hoon Kim46304202020-07-17 15:15:45 -070067TEST_F(DlcBaseTest, InitializationClearsMountFile) {
68 Prefs prefs(
69 JoinPaths(SystemState::Get()->dlc_prefs_dir(), kFirstDlc, kPackage));
70 EXPECT_TRUE(prefs.Create(kDlcRootMount));
71 DlcBase dlc(kFirstDlc);
72 dlc.Initialize();
73 EXPECT_FALSE(prefs.Exists(kDlcRootMount));
74}
75
Amin Hassani9a3f20c2020-05-25 16:38:33 -070076TEST_F(DlcBaseTest, CreateDlc) {
77 DlcBase dlc(kFirstDlc);
78 dlc.Initialize();
79
80 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);
81
82 EXPECT_TRUE(dlc.Install(&err_));
83
84 constexpr int expected_permissions = 0755;
85 int permissions;
86 base::FilePath module_path = JoinPaths(content_path_, kFirstDlc, kPackage);
87 base::GetPosixFilePermissions(module_path, &permissions);
88 EXPECT_EQ(permissions, expected_permissions);
89 base::FilePath image_a_path =
90 GetDlcImagePath(content_path_, kFirstDlc, kPackage, BootSlot::Slot::A);
91 base::GetPosixFilePermissions(image_a_path.DirName(), &permissions);
92 EXPECT_EQ(permissions, expected_permissions);
93 base::FilePath image_b_path =
94 GetDlcImagePath(content_path_, kFirstDlc, kPackage, BootSlot::Slot::B);
95 base::GetPosixFilePermissions(image_b_path.DirName(), &permissions);
96 EXPECT_EQ(permissions, expected_permissions);
97
98 base::FilePath dlc_prefs_path = JoinPaths(prefs_path_, "dlc", kFirstDlc);
99 EXPECT_TRUE(base::PathExists(dlc_prefs_path));
100 base::GetPosixFilePermissions(dlc_prefs_path, &permissions);
101 EXPECT_EQ(permissions, expected_permissions);
102
103 EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);
104}
105
106TEST_F(DlcBaseTest, InstallWithUECompletion) {
107 DlcBase dlc(kFirstDlc);
108 dlc.Initialize();
109
110 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
111 SetDlcActiveValue(_, kFirstDlc, _, _))
112 .WillRepeatedly(Return(true));
113 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
114 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
115 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700116 EXPECT_CALL(*mock_metrics_,
117 SendInstallResult(InstallResult::kSuccessNewInstall));
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700118
119 EXPECT_TRUE(dlc.Install(&err_));
120 InstallWithUpdateEngine({kFirstDlc});
121 // UE calls this.
122 dlc.InstallCompleted(&err_);
123 EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);
124
Andrew0a534ed2020-05-06 09:59:17 -0700125 dlc.FinishInstall(/*installed_by_ue=*/true, &err_);
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700126 EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLED);
127 EXPECT_TRUE(dlc.IsVerified());
128}
129
130TEST_F(DlcBaseTest, InstallWithoutUECompletion) {
131 DlcBase dlc(kFirstDlc);
132 dlc.Initialize();
133
134 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
135 SetDlcActiveValue(_, kFirstDlc, _, _))
136 .WillRepeatedly(Return(true));
137 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
138 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
139 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700140 EXPECT_CALL(*mock_metrics_,
141 SendInstallResult(InstallResult::kSuccessNewInstall));
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700142
143 EXPECT_TRUE(dlc.Install(&err_));
144 InstallWithUpdateEngine({kFirstDlc});
145 // UE doesn't call InstallComplete anymore. But we still verify.
146 EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);
147
Andrew0a534ed2020-05-06 09:59:17 -0700148 dlc.FinishInstall(/*installed_by_ue=*/true, &err_);
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700149 EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLED);
150 EXPECT_TRUE(dlc.IsVerified());
151}
152
153TEST_F(DlcBaseTest, InstallWhenInstalling) {
154 DlcBase dlc(kFirstDlc);
155 dlc.Initialize();
156
157 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);
158
159 EXPECT_TRUE(dlc.Install(&err_));
160 EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);
161
162 // A second install should do nothing.
163 EXPECT_TRUE(dlc.Install(&err_));
164 EXPECT_EQ(dlc.GetState().state(), DlcState::INSTALLING);
165}
166
Amin Hassanif27aac02020-04-23 21:56:26 -0700167TEST_F(DlcBaseTest, VerifiedOnInitialization) {
168 DlcBase dlc(kSecondDlc);
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -0700169
170 // Explicitly set |kDlcPrefVerified| here.
Amin Hassanif27aac02020-04-23 21:56:26 -0700171 EXPECT_TRUE(Prefs(dlc, SystemState::Get()->active_boot_slot())
172 .Create(kDlcPrefVerified));
173 EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -0700174
Amin Hassanif27aac02020-04-23 21:56:26 -0700175 dlc.Initialize();
176 EXPECT_TRUE(dlc.IsVerified());
177}
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -0700178
Amin Hassanif27aac02020-04-23 21:56:26 -0700179TEST_F(DlcBaseTest, InstallCompleted) {
180 DlcBase dlc(kSecondDlc);
181 dlc.Initialize();
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -0700182
Amin Hassanif27aac02020-04-23 21:56:26 -0700183 EXPECT_FALSE(dlc.IsVerified());
184 EXPECT_TRUE(dlc.InstallCompleted(&err_));
185 EXPECT_TRUE(dlc.IsVerified());
186}
187
188TEST_F(DlcBaseTest, UpdateCompleted) {
189 DlcBase dlc(kSecondDlc);
190 dlc.Initialize();
191
192 EXPECT_TRUE(dlc.UpdateCompleted(&err_));
193 EXPECT_TRUE(Prefs(dlc, SystemState::Get()->inactive_boot_slot())
194 .Exists(kDlcPrefVerified));
195}
196
197TEST_F(DlcBaseTest, MakeReadyForUpdate) {
198 DlcBase dlc(kSecondDlc);
199 dlc.Initialize();
Vyshu Khota32388f92020-11-10 09:13:29 -0800200 dlc.MarkVerified();
Amin Hassani48567772020-05-20 16:21:11 -0700201 // Make sure the function recreates the inactive image.
202 auto inactive_image_path =
203 dlc.GetImagePath(SystemState::Get()->inactive_boot_slot());
hscham53cf73a2020-11-30 15:58:42 +0900204 base::DeleteFile(inactive_image_path);
Amin Hassani48567772020-05-20 16:21:11 -0700205 EXPECT_FALSE(base::PathExists(inactive_image_path));
Amin Hassanif27aac02020-04-23 21:56:26 -0700206
Jae Hoon Kim71bc9bc2020-07-14 11:12:43 -0700207 Prefs prefs(dlc, SystemState::Get()->inactive_boot_slot());
Amin Hassanif27aac02020-04-23 21:56:26 -0700208 EXPECT_TRUE(prefs.Create(kDlcPrefVerified));
Amin Hassani48567772020-05-20 16:21:11 -0700209 EXPECT_TRUE(dlc.MakeReadyForUpdate());
210 EXPECT_TRUE(base::PathExists(inactive_image_path));
211 EXPECT_FALSE(prefs.Exists(kDlcPrefVerified));
212}
213
214TEST_F(DlcBaseTest, MakeReadyForUpdateNotVerfied) {
215 DlcBase dlc(kSecondDlc);
216 dlc.Initialize();
217
Jae Hoon Kim71bc9bc2020-07-14 11:12:43 -0700218 Prefs prefs(dlc, SystemState::Get()->inactive_boot_slot());
Amin Hassani48567772020-05-20 16:21:11 -0700219 EXPECT_TRUE(prefs.Create(kDlcPrefVerified));
220 // Since DLC is not verfied, it should return false.
221 EXPECT_FALSE(dlc.MakeReadyForUpdate());
Amin Hassanif27aac02020-04-23 21:56:26 -0700222 EXPECT_FALSE(prefs.Exists(kDlcPrefVerified));
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -0700223}
224
Jae Hoon Kim9318f342020-09-10 14:38:13 -0700225TEST_F(DlcBaseTest, OfficialBuildsDoNotPreloadDLCs) {
226 DlcBase dlc(kThirdDlc);
227 dlc.Initialize();
228 // Place preloaded images.
229 base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);
230
231 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
232 SetDlcActiveValue(_, kThirdDlc, _, _))
233 .WillRepeatedly(Return(true));
234 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);
235 EXPECT_CALL(*mock_system_properties_, IsOfficialBuild())
236 .WillOnce(Return(true));
237
238 EXPECT_TRUE(dlc.Install(&err_));
239
240 // Instead of being preloaded, it should start installing.
241 EXPECT_TRUE(dlc.IsInstalling());
242}
243
Jae Hoon Kim23c7f492020-06-26 10:30:09 -0700244// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
Jae Hoon Kim92e43e42020-06-12 15:26:30 -0700245TEST_F(DlcBaseTest, BootingFromNonRemovableDeviceKeepsPreloadedDLCs) {
Jae Hoon Kim0d4ff622020-05-14 14:47:40 -0700246 DlcBase dlc(kThirdDlc);
Jae Hoon Kimc5482f92019-12-04 17:52:23 -0800247 dlc.Initialize();
Jae Hoon Kim3d1b1252020-05-18 16:00:55 -0700248 // Place preloaded images.
Amin Hassani28ed9002020-05-28 12:37:01 -0700249 base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);
Jae Hoon Kimc5482f92019-12-04 17:52:23 -0800250
251 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
Jae Hoon Kim0d4ff622020-05-14 14:47:40 -0700252 SetDlcActiveValue(_, kThirdDlc, _, _))
Jae Hoon Kimc5482f92019-12-04 17:52:23 -0800253 .WillRepeatedly(Return(true));
254 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
255 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700256 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700257 EXPECT_CALL(*mock_metrics_,
258 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
Jae Hoon Kim9318f342020-09-10 14:38:13 -0700259 EXPECT_CALL(*mock_system_properties_, IsOfficialBuild())
260 .WillOnce(Return(false));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700261
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700262 EXPECT_TRUE(dlc.Install(&err_));
Jae Hoon Kimc5482f92019-12-04 17:52:23 -0800263
Jae Hoon Kim92e43e42020-06-12 15:26:30 -0700264 // Preloaded DLC image should still exists.
265 EXPECT_TRUE(base::PathExists(image_path));
Jae Hoon Kimc5482f92019-12-04 17:52:23 -0800266}
267
Jae Hoon Kim23c7f492020-06-26 10:30:09 -0700268// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
Jae Hoon Kim0d4ff622020-05-14 14:47:40 -0700269TEST_F(DlcBaseTestRemovable, BootingFromRemovableDeviceKeepsPreloadedDLCs) {
270 DlcBase dlc(kThirdDlc);
Jae Hoon Kimc5482f92019-12-04 17:52:23 -0800271 dlc.Initialize();
Jae Hoon Kim3d1b1252020-05-18 16:00:55 -0700272 // Place preloaded images.
Amin Hassani28ed9002020-05-28 12:37:01 -0700273 base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);
Jae Hoon Kimc5482f92019-12-04 17:52:23 -0800274
275 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
Jae Hoon Kim0d4ff622020-05-14 14:47:40 -0700276 SetDlcActiveValue(_, kThirdDlc, _, _))
Jae Hoon Kimc5482f92019-12-04 17:52:23 -0800277 .WillRepeatedly(Return(true));
278 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
279 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700280 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700281 EXPECT_CALL(*mock_metrics_,
282 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
Jae Hoon Kim9318f342020-09-10 14:38:13 -0700283 EXPECT_CALL(*mock_system_properties_, IsOfficialBuild())
284 .WillOnce(Return(false));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700285
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700286 EXPECT_TRUE(dlc.Install(&err_));
Jae Hoon Kimc5482f92019-12-04 17:52:23 -0800287
288 // Preloaded DLC image should still exists.
289 EXPECT_TRUE(base::PathExists(image_path));
290}
291
Jae Hoon Kim23c7f492020-06-26 10:30:09 -0700292// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
Amin Hassani28ed9002020-05-28 12:37:01 -0700293TEST_F(DlcBaseTest, PreloadCopyShouldMarkUnverified) {
294 DlcBase dlc(kThirdDlc);
295 dlc.Initialize();
296 SetUpDlcPreloadedImage(kThirdDlc);
297
298 // Don't preload the image so we can simulate a preload failure.
Amin Hassani6b7a9aa2020-05-29 14:23:47 -0700299 EXPECT_TRUE(dlc.MarkVerified());
Amin Hassani28ed9002020-05-28 12:37:01 -0700300 EXPECT_FALSE(dlc.PreloadedCopier(&err_));
301 EXPECT_FALSE(dlc.IsVerified());
302}
303
Jae Hoon Kim23c7f492020-06-26 10:30:09 -0700304// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
Amin Hassani28ed9002020-05-28 12:37:01 -0700305TEST_F(DlcBaseTest, PreloadCopyFailOnInvalidFileSize) {
306 DlcBase dlc(kThirdDlc);
307 dlc.Initialize();
308 base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);
309 EXPECT_TRUE(ResizeFile(image_path, 10));
310
Amin Hassani6b7a9aa2020-05-29 14:23:47 -0700311 EXPECT_TRUE(dlc.MarkVerified());
Amin Hassani28ed9002020-05-28 12:37:01 -0700312 EXPECT_FALSE(dlc.PreloadedCopier(&err_));
313 // This failure should not render the image as unverified.
314 EXPECT_TRUE(dlc.IsVerified());
315}
316
Jae Hoon Kim23c7f492020-06-26 10:30:09 -0700317// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
Jae Hoon Kim13e61512020-06-26 16:36:10 -0700318TEST_F(DlcBaseTest, InstallingCorruptPreloadedImageCleansUp) {
319 DlcBase dlc(kThirdDlc);
320 dlc.Initialize();
321 base::FilePath image_path = SetUpDlcPreloadedImage(kThirdDlc);
322 EXPECT_TRUE(ResizeFile(image_path, 10));
323
324 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Jae Hoon Kim9318f342020-09-10 14:38:13 -0700325 EXPECT_CALL(*mock_system_properties_, IsOfficialBuild())
326 .WillOnce(Return(false));
Jae Hoon Kim13e61512020-06-26 16:36:10 -0700327
328 EXPECT_FALSE(dlc.Install(&err_));
329 for (const auto& path : {dlc.GetImagePath(BootSlot::Slot::A),
330 dlc.GetImagePath(BootSlot::Slot::B)})
331 EXPECT_FALSE(base::PathExists(path));
332}
333
334// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
Jae Hoon Kimf49b6d72020-06-15 11:29:24 -0700335TEST_F(DlcBaseTest, PreloadingSkippedOnAlreadyVerifiedDlc) {
336 DlcBase dlc(kThirdDlc);
337 dlc.Initialize();
338
339 // Cause |PreloadedCopier()| to fail due to size mismatch in manifest if it
340 // were to be called.
341 EXPECT_TRUE(ResizeFile(SetUpDlcPreloadedImage(kThirdDlc), 1));
342 SetUpDlcWithSlots(kThirdDlc);
343 InstallWithUpdateEngine({kThirdDlc});
344
345 EXPECT_TRUE(dlc.MarkVerified());
346 EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);
347 EXPECT_CALL(*mock_image_loader_proxy_ptr_,
348 LoadDlcImage(kThirdDlc, _, _, _, _, _))
349 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
350 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
351 SetDlcActiveValue(_, kThirdDlc, _, _))
352 .WillOnce(Return(true));
353 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700354 EXPECT_CALL(*mock_metrics_,
355 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
Jae Hoon Kimf49b6d72020-06-15 11:29:24 -0700356
357 EXPECT_TRUE(dlc.Install(&err_));
358 EXPECT_TRUE(dlc.IsInstalled());
359}
360
Jae Hoon Kim23c7f492020-06-26 10:30:09 -0700361// TODO(crbug.com/1042704): Deprecate after DLCs are provisioned using TLS API.
Jae Hoon Kimf49b6d72020-06-15 11:29:24 -0700362TEST_F(DlcBaseTest, PreloadingSkippedOnAlreadyExistingAndVerifiableDlc) {
363 DlcBase dlc(kThirdDlc);
364 dlc.Initialize();
365
366 // Cause |PreloadedCopier()| to fail due to size mismatch in manifest if it
367 // were to be called.
368 EXPECT_TRUE(ResizeFile(SetUpDlcPreloadedImage(kThirdDlc), 1));
369 SetUpDlcWithSlots(kThirdDlc);
370 InstallWithUpdateEngine({kThirdDlc});
371
372 EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);
373 EXPECT_CALL(*mock_image_loader_proxy_ptr_,
374 LoadDlcImage(kThirdDlc, _, _, _, _, _))
375 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
376 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
377 SetDlcActiveValue(_, kThirdDlc, _, _))
378 .WillOnce(Return(true));
379 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700380 EXPECT_CALL(*mock_metrics_,
381 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
Jae Hoon Kimf49b6d72020-06-15 11:29:24 -0700382
383 EXPECT_TRUE(dlc.Install(&err_));
384 EXPECT_TRUE(dlc.IsInstalled());
385}
386
Amin Hassanid5fc8b22020-04-29 12:44:52 -0700387TEST_F(DlcBaseTest, HasContent) {
388 DlcBase dlc(kSecondDlc);
389 dlc.Initialize();
390
391 EXPECT_FALSE(dlc.HasContent());
392
393 SetUpDlcWithSlots(kSecondDlc);
394 EXPECT_TRUE(dlc.HasContent());
395}
396
397TEST_F(DlcBaseTest, GetUsedBytesOnDisk) {
398 DlcBase dlc(kSecondDlc);
399 dlc.Initialize();
400
401 EXPECT_EQ(dlc.GetUsedBytesOnDisk(), 0);
402
403 SetUpDlcWithSlots(kSecondDlc);
404 uint64_t expected_size = 0;
405 for (const auto& path : {dlc.GetImagePath(BootSlot::Slot::A),
406 dlc.GetImagePath(BootSlot::Slot::B)}) {
407 expected_size += GetFileSize(path);
408 }
409 EXPECT_GT(expected_size, 0);
410
411 EXPECT_EQ(dlc.GetUsedBytesOnDisk(), expected_size);
412}
413
Amin Hassani6b7a9aa2020-05-29 14:23:47 -0700414TEST_F(DlcBaseTest, MarkVerified) {
415 DlcBase dlc(kFirstDlc);
416 dlc.Initialize();
417
418 EXPECT_FALSE(dlc.IsVerified());
419 EXPECT_TRUE(dlc.MarkVerified());
420 EXPECT_TRUE(dlc.IsVerified());
421 EXPECT_TRUE(Prefs(DlcBase(kFirstDlc), SystemState::Get()->active_boot_slot())
422 .Exists(kDlcPrefVerified));
423}
424
Amin Hassani28ed9002020-05-28 12:37:01 -0700425TEST_F(DlcBaseTest, MarkUnverified) {
426 DlcBase dlc(kFirstDlc);
427 dlc.Initialize();
428
Amin Hassani6b7a9aa2020-05-29 14:23:47 -0700429 EXPECT_TRUE(dlc.MarkVerified());
430 EXPECT_TRUE(dlc.MarkUnverified());
Amin Hassani28ed9002020-05-28 12:37:01 -0700431 EXPECT_FALSE(dlc.IsVerified());
Amin Hassani6b7a9aa2020-05-29 14:23:47 -0700432 EXPECT_FALSE(Prefs(DlcBase(kFirstDlc), SystemState::Get()->active_boot_slot())
433 .Exists(kDlcPrefVerified));
Amin Hassani28ed9002020-05-28 12:37:01 -0700434}
435
Jae Hoon Kim8ab26492020-05-07 13:49:36 -0700436TEST_F(DlcBaseTest, ImageOnDiskButNotVerifiedInstalls) {
437 DlcBase dlc(kSecondDlc);
438 dlc.Initialize();
439
440 SetUpDlcWithSlots(kSecondDlc);
Amin Hassanif2efc5a2020-05-25 21:22:57 -0700441 InstallWithUpdateEngine({kSecondDlc});
Jae Hoon Kim8ab26492020-05-07 13:49:36 -0700442
443 EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);
Jae Hoon Kime9a5e132020-06-03 11:55:05 -0700444 EXPECT_CALL(*mock_image_loader_proxy_ptr_,
445 LoadDlcImage(kSecondDlc, _, _, _, _, _))
446 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
447 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
448 SetDlcActiveValue(_, kSecondDlc, _, _))
449 .WillOnce(Return(true));
450 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700451 EXPECT_CALL(*mock_metrics_,
452 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700453
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700454 EXPECT_TRUE(dlc.Install(&err_));
Jae Hoon Kime9a5e132020-06-03 11:55:05 -0700455 EXPECT_TRUE(dlc.IsInstalled());
Jae Hoon Kim8ab26492020-05-07 13:49:36 -0700456}
457
458TEST_F(DlcBaseTest, ImageOnDiskVerifiedInstalls) {
459 DlcBase dlc(kSecondDlc);
Jae Hoon Kim8ab26492020-05-07 13:49:36 -0700460 EXPECT_TRUE(Prefs(dlc, SystemState::Get()->active_boot_slot())
461 .Create(kDlcPrefVerified));
462 SetUpDlcWithSlots(kSecondDlc);
Amin Hassanif2efc5a2020-05-25 21:22:57 -0700463 InstallWithUpdateEngine({kSecondDlc});
Jae Hoon Kim8ab26492020-05-07 13:49:36 -0700464
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700465 dlc.Initialize();
466
Jae Hoon Kim8ab26492020-05-07 13:49:36 -0700467 EXPECT_EQ(dlc.GetState().state(), DlcState::NOT_INSTALLED);
468 EXPECT_CALL(*mock_image_loader_proxy_ptr_,
469 LoadDlcImage(kSecondDlc, _, _, _, _, _))
470 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
471 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
472 SetDlcActiveValue(_, kSecondDlc, _, _))
473 .WillOnce(Return(true));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700474 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700475 EXPECT_CALL(*mock_metrics_,
476 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700477
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700478 EXPECT_TRUE(dlc.Install(&err_));
Jae Hoon Kim8ab26492020-05-07 13:49:36 -0700479 EXPECT_TRUE(dlc.IsInstalled());
480}
481
Jae Hoon Kim2019b002020-05-19 19:58:00 -0700482TEST_F(DlcBaseTest, VerifyDlcImageOnUEFailureToCompleteInstall) {
483 DlcBase dlc(kSecondDlc);
484 dlc.Initialize();
485
486 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
487 SetDlcActiveValue(_, kSecondDlc, _, _))
488 .WillOnce(Return(true));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700489 EXPECT_CALL(*mock_image_loader_proxy_ptr_,
490 LoadDlcImage(kSecondDlc, _, _, _, _, _))
491 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
492 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700493 EXPECT_CALL(*mock_metrics_,
494 SendInstallResult(InstallResult::kSuccessNewInstall));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700495
Amin Hassani9a3f20c2020-05-25 16:38:33 -0700496 EXPECT_TRUE(dlc.Install(&err_));
Jae Hoon Kim2019b002020-05-19 19:58:00 -0700497 EXPECT_TRUE(dlc.IsInstalling());
498
499 // Intentionally skip over setting verified mark before |FinishInstall()|.
Amin Hassanif2efc5a2020-05-25 21:22:57 -0700500 InstallWithUpdateEngine({kSecondDlc});
Amin Hassani78a5ec82020-05-19 09:47:49 -0700501
Andrew0a534ed2020-05-06 09:59:17 -0700502 EXPECT_TRUE(dlc.FinishInstall(/*installed_by_ue=*/true, &err_));
Jae Hoon Kim2019b002020-05-19 19:58:00 -0700503 EXPECT_TRUE(dlc.IsInstalled());
504}
505
Jae Hoon Kim92530422021-03-08 15:51:45 -0800506TEST_F(DlcBaseTest, NoImageFoundOnUEFailureToDownloadDlc) {
507 DlcBase dlc(kSecondDlc);
508 dlc.Initialize();
509
510 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
511 EXPECT_CALL(*mock_metrics_,
512 SendInstallResult(InstallResult::kFailedNoImageFound));
513
514 EXPECT_TRUE(dlc.Install(&err_));
515 EXPECT_TRUE(dlc.IsInstalling());
516
517 // Make sure the `last_attempt_error` in update_engine is set to `kNoUpdate`.
518 update_engine::StatusResult ue_status;
519 ue_status.set_last_attempt_error(
520 static_cast<int32_t>(update_engine::ErrorCode::kNoUpdate));
521 SystemState::Get()->set_update_engine_status(ue_status);
522
523 EXPECT_FALSE(dlc.FinishInstall(/*installed_by_ue=*/true, &err_));
524}
525
Amin Hassani78a5ec82020-05-19 09:47:49 -0700526TEST_F(DlcBaseTest, DefaultState) {
527 DlcBase dlc(kFirstDlc);
528 dlc.Initialize();
529 dlc.mount_point_ = base::FilePath("foo-path");
530
531 DlcState state = dlc.GetState();
532 EXPECT_EQ(state.id(), kFirstDlc);
533 EXPECT_EQ(state.state(), DlcState::NOT_INSTALLED);
534 EXPECT_EQ(state.progress(), 0);
535 EXPECT_EQ(state.root_path(), "");
536}
537
538TEST_F(DlcBaseTest, ChangeStateNotInstalled) {
539 DlcBase dlc(kFirstDlc);
540 dlc.Initialize();
541 dlc.mount_point_ = base::FilePath("foo-path");
542
543 EXPECT_CALL(
544 mock_state_change_reporter_,
545 DlcStateChanged(CheckDlcStateProto(DlcState::NOT_INSTALLED, 0, "")));
546 dlc.ChangeState(DlcState::NOT_INSTALLED);
547}
548
549TEST_F(DlcBaseTest, ChangeStateInstalling) {
550 DlcBase dlc(kFirstDlc);
551 dlc.Initialize();
552 dlc.mount_point_ = base::FilePath("foo-path");
553
554 EXPECT_CALL(mock_state_change_reporter_,
555 DlcStateChanged(CheckDlcStateProto(DlcState::INSTALLING, 0, "")));
556 dlc.ChangeState(DlcState::INSTALLING);
557}
558
559TEST_F(DlcBaseTest, ChangeStateInstalled) {
560 DlcBase dlc(kFirstDlc);
561 dlc.Initialize();
562 dlc.mount_point_ = base::FilePath("foo-path");
563
Jae Hoon Kim5b1d0152020-08-03 11:23:44 -0700564 // The |root_path| in |DlcState| should point to the root of the mount point.
Amin Hassani78a5ec82020-05-19 09:47:49 -0700565 EXPECT_CALL(mock_state_change_reporter_,
Jae Hoon Kim5b1d0152020-08-03 11:23:44 -0700566 DlcStateChanged(CheckDlcStateProto(DlcState::INSTALLED, 1.0,
567 "foo-path/root")));
Amin Hassani78a5ec82020-05-19 09:47:49 -0700568 dlc.ChangeState(DlcState::INSTALLED);
569}
570
571TEST_F(DlcBaseTest, ChangeProgress) {
572 DlcBase dlc(kFirstDlc);
573 dlc.Initialize();
574
575 // Any state other than installing should not change the progress.
576 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(0);
577 dlc.ChangeProgress(0.5);
578
579 EXPECT_CALL(mock_state_change_reporter_,
580 DlcStateChanged(CheckDlcStateProto(DlcState::INSTALLING, 0, "")));
581 dlc.ChangeState(DlcState::INSTALLING);
582
583 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(CheckDlcStateProto(
584 DlcState::INSTALLING, 0.5, "")));
585 dlc.ChangeProgress(0.5);
586
587 // Lower progress should not send signal.
588 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(0);
589 dlc.ChangeProgress(0.3);
590
591 // Same progress should not send the signal.
592 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(0);
593 dlc.ChangeProgress(0.5);
594}
595
Amin Hassani40c0f112020-04-15 09:55:00 -0700596TEST_F(DlcBaseTest, InstallIncreasesRefCount) {
597 DlcBase dlc(kFirstDlc);
598 dlc.Initialize();
599
600 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
601 SetDlcActiveValue(_, kFirstDlc, _, _))
602 .WillRepeatedly(Return(true));
603 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
604 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
605 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
Andrew0a534ed2020-05-06 09:59:17 -0700606 EXPECT_CALL(*mock_metrics_,
607 SendInstallResult(InstallResult::kSuccessNewInstall));
Amin Hassani40c0f112020-04-15 09:55:00 -0700608
609 EXPECT_TRUE(dlc.Install(&err_));
610 InstallWithUpdateEngine({kFirstDlc});
611 dlc.InstallCompleted(&err_);
Andrew0a534ed2020-05-06 09:59:17 -0700612 dlc.FinishInstall(/*installed_by_ue=*/true, &err_);
Amin Hassani40c0f112020-04-15 09:55:00 -0700613
614 EXPECT_TRUE(dlc.IsInstalled());
615 auto ref_count_file = JoinPaths(SystemState::Get()->dlc_prefs_dir(),
616 kFirstDlc, kRefCountFileName);
617 EXPECT_TRUE(base::PathExists(ref_count_file));
618}
619
Jae Hoon Kimdcadbd42020-06-25 09:21:03 -0700620TEST_F(DlcBaseTest, MountFileCreated) {
621 // |kFirstDlc| has 'mount-file-required' as true in the manifest.
622 DlcBase dlc(kFirstDlc);
623 SetUpDlcWithSlots(kFirstDlc);
624 InstallWithUpdateEngine({kFirstDlc});
625 dlc.Initialize();
626
627 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
628 SetDlcActiveValue(_, kFirstDlc, _, _))
629 .WillRepeatedly(Return(true));
630 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
631 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
632 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
633 EXPECT_CALL(*mock_metrics_,
634 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
635
636 EXPECT_TRUE(dlc.Install(&err_));
637 EXPECT_TRUE(
638 Prefs(JoinPaths(SystemState::Get()->dlc_prefs_dir(), kFirstDlc, kPackage))
639 .Exists(kDlcRootMount));
640}
641
642TEST_F(DlcBaseTest, MountFileNotCreated) {
643 // |kSecondDlc| has 'mount-file-required' as false in the manifest.
644 DlcBase dlc(kSecondDlc);
645 SetUpDlcWithSlots(kSecondDlc);
646 InstallWithUpdateEngine({kSecondDlc});
647 dlc.Initialize();
648
649 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
650 SetDlcActiveValue(_, kSecondDlc, _, _))
651 .WillRepeatedly(Return(true));
652 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
653 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
654 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
655 EXPECT_CALL(*mock_metrics_,
656 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
657
658 EXPECT_TRUE(dlc.Install(&err_));
659 EXPECT_FALSE(Prefs(JoinPaths(SystemState::Get()->dlc_prefs_dir(), kSecondDlc,
660 kPackage))
661 .Exists(kDlcRootMount));
662}
663
664TEST_F(DlcBaseTest, MountFileRequiredDeletionOnUninstall) {
665 DlcBase dlc(kFirstDlc);
666 SetUpDlcWithSlots(kFirstDlc);
667 InstallWithUpdateEngine({kFirstDlc});
668 dlc.Initialize();
669
670 // Process |Install()|.
671 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
672 SetDlcActiveValue(_, kFirstDlc, _, _))
673 .WillRepeatedly(Return(true));
674 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
675 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
676 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
677 EXPECT_CALL(*mock_metrics_,
678 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
679 EXPECT_TRUE(dlc.Install(&err_));
680
681 // Process |Uninstall()| + check.
682 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);
683 EXPECT_CALL(*mock_image_loader_proxy_ptr_, UnloadDlcImage(_, _, _, _, _))
684 .WillOnce(DoAll(SetArgPointee<2>(true), Return(true)));
685 EXPECT_TRUE(dlc.Uninstall(&err_));
686 EXPECT_FALSE(
687 Prefs(JoinPaths(SystemState::Get()->dlc_prefs_dir(), kFirstDlc, kPackage))
688 .Exists(kDlcRootMount));
689}
690
691TEST_F(DlcBaseTest, MountFileRequiredDeletionOnPurge) {
692 DlcBase dlc(kFirstDlc);
693 SetUpDlcWithSlots(kFirstDlc);
694 InstallWithUpdateEngine({kFirstDlc});
695 dlc.Initialize();
696
697 // Process |Install()|.
698 EXPECT_CALL(*mock_update_engine_proxy_ptr_,
699 SetDlcActiveValue(_, kFirstDlc, _, _))
700 .WillRepeatedly(Return(true));
701 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(2);
702 EXPECT_CALL(*mock_image_loader_proxy_ptr_, LoadDlcImage(_, _, _, _, _, _))
703 .WillOnce(DoAll(SetArgPointee<3>(mount_path_.value()), Return(true)));
704 EXPECT_CALL(*mock_metrics_,
705 SendInstallResult(InstallResult::kSuccessAlreadyInstalled));
706 EXPECT_TRUE(dlc.Install(&err_));
707
708 // Process |Purge()| + check.
709 EXPECT_CALL(mock_state_change_reporter_, DlcStateChanged(_)).Times(1);
710 EXPECT_CALL(*mock_image_loader_proxy_ptr_, UnloadDlcImage(_, _, _, _, _))
711 .WillOnce(DoAll(SetArgPointee<2>(true), Return(true)));
712 EXPECT_TRUE(dlc.Purge(&err_));
713 EXPECT_FALSE(
714 Prefs(JoinPaths(SystemState::Get()->dlc_prefs_dir(), kFirstDlc, kPackage))
715 .Exists(kDlcRootMount));
716}
717
Jae Hoon Kimf9b2c9d2020-07-22 12:09:13 -0700718TEST_F(DlcBaseTest, UnmountClearsMountPoint) {
719 auto dlc = Install(kFirstDlc);
720
721 EXPECT_CALL(*mock_image_loader_proxy_ptr_, UnloadDlcImage(_, _, _, _, _))
722 .WillOnce(DoAll(SetArgPointee<2>(true), Return(true)));
723 EXPECT_TRUE(dlc->Unmount(&err_));
724 EXPECT_TRUE(dlc->GetRoot().empty());
725}
726
Jae Hoon Kim0d057fb2020-04-13 17:44:38 -0700727} // namespace dlcservice