blob: 0a16c03ce94e183bd065426c4c256bc818eb45f8 [file] [log] [blame]
Yifan Hongd22459d2019-09-13 14:49:53 -07001//
2// Copyright (C) 2019 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "snapshot_metadata_updater.h"
18
19#include <memory>
20#include <string>
21
Alessio Balsinifce02742020-01-30 16:02:13 +000022#include <android-base/properties.h>
Yifan Hongd22459d2019-09-13 14:49:53 -070023#include <gmock/gmock.h>
24#include <gtest/gtest.h>
25#include <liblp/builder.h>
26#include <storage_literals/storage_literals.h>
27
Yifan Hong0daaa722019-12-06 15:57:54 -080028#include <libsnapshot/test_helpers.h>
Yifan Hongd22459d2019-09-13 14:49:53 -070029
30using namespace android::storage_literals;
31using android::fs_mgr::LpMetadata;
32using android::fs_mgr::MetadataBuilder;
33using android::fs_mgr::SlotSuffixForSlotNumber;
34using chromeos_update_engine::DeltaArchiveManifest;
35using chromeos_update_engine::DynamicPartitionGroup;
36using chromeos_update_engine::PartitionUpdate;
37using testing::AssertionFailure;
38using testing::AssertionResult;
39using testing::AssertionSuccess;
40
41namespace android {
42namespace snapshot {
43
44class SnapshotMetadataUpdaterTest : public ::testing::TestWithParam<uint32_t> {
45 public:
Yifan Honga7c00a02020-08-06 16:12:37 -070046 SnapshotMetadataUpdaterTest() = default;
Alessio Balsinifce02742020-01-30 16:02:13 +000047
Yifan Hongd22459d2019-09-13 14:49:53 -070048 void SetUp() override {
Yifan Honga7c00a02020-08-06 16:12:37 -070049 SKIP_IF_NON_VIRTUAL_AB();
50
Yifan Hongd22459d2019-09-13 14:49:53 -070051 target_slot_ = GetParam();
52 target_suffix_ = SlotSuffixForSlotNumber(target_slot_);
Yifan Hong30adb652019-09-23 18:12:01 -070053 SnapshotTestPropertyFetcher::SetUp(SlotSuffixForSlotNumber(1 - target_slot_));
Yifan Hongd22459d2019-09-13 14:49:53 -070054 builder_ = MetadataBuilder::New(4_GiB + 1_MiB, 4_KiB, 2);
55
56 group_ = manifest_.mutable_dynamic_partition_metadata()->add_groups();
57 group_->set_name("group");
58 group_->set_size(4_GiB);
59 group_->add_partition_names("system");
60 group_->add_partition_names("vendor");
61 system_ = manifest_.add_partitions();
62 system_->set_partition_name("system");
63 SetSize(system_, 2_GiB);
64 vendor_ = manifest_.add_partitions();
65 vendor_->set_partition_name("vendor");
66 SetSize(vendor_, 1_GiB);
67
68 ASSERT_TRUE(FillFakeMetadata(builder_.get(), manifest_, target_suffix_));
69 }
70
Yifan Honga7c00a02020-08-06 16:12:37 -070071 void TearDown() override {
72 RETURN_IF_NON_VIRTUAL_AB();
73
74 SnapshotTestPropertyFetcher::TearDown();
75 }
Yifan Hong30adb652019-09-23 18:12:01 -070076
Yifan Hongd22459d2019-09-13 14:49:53 -070077 // Append suffix to name.
78 std::string T(std::string_view name) { return std::string(name) + target_suffix_; }
79
80 AssertionResult UpdateAndExport() {
81 SnapshotMetadataUpdater updater(builder_.get(), target_slot_, manifest_);
82 if (!updater.Update()) {
83 return AssertionFailure() << "Update failed.";
84 }
85
86 exported_ = builder_->Export();
87 if (exported_ == nullptr) {
88 return AssertionFailure() << "Export failed.";
89 }
90 return AssertionSuccess();
91 }
92
93 // Check that in |builder_|, partition |name| + |target_suffix_| has the given |size|.
94 AssertionResult CheckSize(std::string_view name, uint64_t size) {
95 auto p = builder_->FindPartition(T(name));
96 if (p == nullptr) {
97 return AssertionFailure() << "Cannot find partition " << T(name);
98 }
99 if (p->size() != size) {
100 return AssertionFailure() << "Partition " << T(name) << " should be " << size
101 << " bytes, but is " << p->size() << " bytes.";
102 }
103 return AssertionSuccess() << "Partition" << T(name) << " is " << size << " bytes.";
104 }
105
106 // Check that in |builder_|, group |name| + |target_suffix_| has the given |size|.
107 AssertionResult CheckGroupSize(std::string_view name, uint64_t size) {
108 auto g = builder_->FindGroup(T(name));
109 if (g == nullptr) {
110 return AssertionFailure() << "Cannot find group " << T(name);
111 }
112 if (g->maximum_size() != size) {
113 return AssertionFailure() << "Group " << T(name) << " should be " << size
114 << " bytes, but is " << g->maximum_size() << " bytes.";
115 }
116 return AssertionSuccess() << "Group" << T(name) << " is " << size << " bytes.";
117 }
118
119 // Check that in |builder_|, partition |partition_name| + |target_suffix_| is in group
120 // |group_name| + |target_suffix_|;
121 AssertionResult CheckGroupName(std::string_view partition_name, std::string_view group_name) {
122 auto p = builder_->FindPartition(T(partition_name));
123 if (p == nullptr) {
124 return AssertionFailure() << "Cannot find partition " << T(partition_name);
125 }
126 if (p->group_name() != T(group_name)) {
127 return AssertionFailure() << "Partition " << T(partition_name) << " should be in "
128 << T(group_name) << ", but is in " << p->group_name() << ".";
129 }
130 return AssertionSuccess() << "Partition" << T(partition_name) << " is in " << T(group_name)
131 << ".";
132 }
133
134 std::unique_ptr<MetadataBuilder> builder_;
135 uint32_t target_slot_;
136 std::string target_suffix_;
137 DeltaArchiveManifest manifest_;
138 std::unique_ptr<LpMetadata> exported_;
139 DynamicPartitionGroup* group_ = nullptr;
140 PartitionUpdate* system_ = nullptr;
141 PartitionUpdate* vendor_ = nullptr;
142};
143
144TEST_P(SnapshotMetadataUpdaterTest, NoChange) {
145 EXPECT_TRUE(UpdateAndExport());
146
147 EXPECT_TRUE(CheckGroupSize("group", 4_GiB));
148 EXPECT_TRUE(CheckSize("system", 2_GiB));
149 EXPECT_TRUE(CheckGroupName("system", "group"));
150 EXPECT_TRUE(CheckSize("vendor", 1_GiB));
151 EXPECT_TRUE(CheckGroupName("vendor", "group"));
152}
153
154TEST_P(SnapshotMetadataUpdaterTest, GrowWithinBounds) {
155 SetSize(system_, 2_GiB + 512_MiB);
156 SetSize(vendor_, 1_GiB + 512_MiB);
157
158 ASSERT_TRUE(UpdateAndExport());
159
160 EXPECT_TRUE(CheckSize("system", 2_GiB + 512_MiB));
161 EXPECT_TRUE(CheckSize("vendor", 1_GiB + 512_MiB));
162}
163
164TEST_P(SnapshotMetadataUpdaterTest, GrowOverSuper) {
165 SetSize(system_, 3_GiB);
166 SetSize(vendor_, 1_GiB + 512_MiB);
167
168 EXPECT_FALSE(UpdateAndExport());
169}
170
171TEST_P(SnapshotMetadataUpdaterTest, GrowOverGroup) {
172 SetSize(system_, 3_GiB);
173 SetSize(vendor_, 1_GiB + 4_KiB);
174
175 EXPECT_FALSE(UpdateAndExport());
176}
177
178TEST_P(SnapshotMetadataUpdaterTest, Add) {
179 group_->add_partition_names("product");
180 auto product = manifest_.add_partitions();
181 product->set_partition_name("product");
182 SetSize(product, 1_GiB);
183
184 EXPECT_TRUE(UpdateAndExport());
185
186 EXPECT_TRUE(CheckSize("system", 2_GiB));
187 EXPECT_TRUE(CheckSize("vendor", 1_GiB));
188 EXPECT_TRUE(CheckSize("product", 1_GiB));
189}
190
191TEST_P(SnapshotMetadataUpdaterTest, AddTooBig) {
192 group_->add_partition_names("product");
193 auto product = manifest_.add_partitions();
194 product->set_partition_name("product");
195 SetSize(product, 1_GiB + 4_KiB);
196
197 EXPECT_FALSE(UpdateAndExport());
198}
199
200TEST_P(SnapshotMetadataUpdaterTest, ShrinkAll) {
201 SetSize(system_, 1_GiB);
202 SetSize(vendor_, 512_MiB);
203
204 ASSERT_TRUE(UpdateAndExport());
205
206 EXPECT_TRUE(CheckSize("system", 1_GiB));
207 EXPECT_TRUE(CheckSize("vendor", 512_MiB));
208}
209
210TEST_P(SnapshotMetadataUpdaterTest, ShrinkAndGrow) {
211 SetSize(system_, 3_GiB + 512_MiB);
212 SetSize(vendor_, 512_MiB);
213
214 ASSERT_TRUE(UpdateAndExport());
215
216 EXPECT_TRUE(CheckSize("system", 3_GiB + 512_MiB));
217 EXPECT_TRUE(CheckSize("vendor", 512_MiB));
218}
219
220TEST_P(SnapshotMetadataUpdaterTest, ShrinkAndAdd) {
221 SetSize(system_, 2_GiB);
222 SetSize(vendor_, 512_MiB);
223 group_->add_partition_names("product");
224 auto product = manifest_.add_partitions();
225 product->set_partition_name("product");
226 SetSize(product, 1_GiB + 512_MiB);
227
228 ASSERT_TRUE(UpdateAndExport());
229
230 EXPECT_TRUE(CheckSize("system", 2_GiB));
231 EXPECT_TRUE(CheckSize("vendor", 512_MiB));
232 EXPECT_TRUE(CheckSize("product", 1_GiB + 512_MiB));
233}
234
235TEST_P(SnapshotMetadataUpdaterTest, Delete) {
236 group_->mutable_partition_names()->RemoveLast();
237 // No need to delete it from manifest.partitions as SnapshotMetadataUpdater
238 // should ignore them (treat them as static partitions).
239
240 EXPECT_TRUE(UpdateAndExport());
241
242 EXPECT_TRUE(CheckSize("system", 2_GiB));
243 EXPECT_EQ(nullptr, builder_->FindPartition(T("vendor")));
244}
245
246TEST_P(SnapshotMetadataUpdaterTest, DeleteAndGrow) {
247 group_->mutable_partition_names()->RemoveLast();
248 SetSize(system_, 4_GiB);
249
250 EXPECT_TRUE(UpdateAndExport());
251
252 EXPECT_TRUE(CheckSize("system", 4_GiB));
253}
254
255TEST_P(SnapshotMetadataUpdaterTest, DeleteAndAdd) {
256 group_->mutable_partition_names()->RemoveLast();
257 group_->add_partition_names("product");
258 auto product = manifest_.add_partitions();
259 product->set_partition_name("product");
260 SetSize(product, 2_GiB);
261
262 EXPECT_TRUE(UpdateAndExport());
263
264 EXPECT_TRUE(CheckSize("system", 2_GiB));
265 EXPECT_EQ(nullptr, builder_->FindPartition(T("vendor")));
266 EXPECT_TRUE(CheckSize("product", 2_GiB));
267}
268
269TEST_P(SnapshotMetadataUpdaterTest, GrowGroup) {
270 group_->set_size(4_GiB + 512_KiB);
271 SetSize(system_, 2_GiB + 256_KiB);
272 SetSize(vendor_, 2_GiB + 256_KiB);
273
274 EXPECT_TRUE(UpdateAndExport());
275
276 EXPECT_TRUE(CheckSize("system", 2_GiB + 256_KiB));
277 EXPECT_TRUE(CheckSize("vendor", 2_GiB + 256_KiB));
278}
279
280TEST_P(SnapshotMetadataUpdaterTest, ShrinkGroup) {
281 group_->set_size(1_GiB);
282 SetSize(system_, 512_MiB);
283 SetSize(vendor_, 512_MiB);
284
285 EXPECT_TRUE(UpdateAndExport());
286
287 EXPECT_TRUE(CheckSize("system", 512_MiB));
288 EXPECT_TRUE(CheckSize("vendor", 512_MiB));
289}
290
291TEST_P(SnapshotMetadataUpdaterTest, MoveToNewGroup) {
292 group_->mutable_partition_names()->RemoveLast();
293 group_->set_size(2_GiB);
294
295 auto another_group = manifest_.mutable_dynamic_partition_metadata()->add_groups();
296 another_group->set_name("another_group");
297 another_group->set_size(2_GiB);
298 another_group->add_partition_names("vendor");
299 SetSize(vendor_, 2_GiB);
300
301 EXPECT_TRUE(UpdateAndExport());
302
303 EXPECT_TRUE(CheckGroupSize("group", 2_GiB));
304 EXPECT_TRUE(CheckGroupSize("another_group", 2_GiB));
305 EXPECT_TRUE(CheckSize("system", 2_GiB));
306 EXPECT_TRUE(CheckGroupName("system", "group"));
307 EXPECT_TRUE(CheckSize("vendor", 2_GiB));
308 EXPECT_TRUE(CheckGroupName("vendor", "another_group"));
309}
310
311TEST_P(SnapshotMetadataUpdaterTest, DeleteAndAddGroup) {
312 manifest_.mutable_dynamic_partition_metadata()->mutable_groups()->RemoveLast();
313 group_ = nullptr;
314
315 auto another_group = manifest_.mutable_dynamic_partition_metadata()->add_groups();
316 another_group->set_name("another_group");
317 another_group->set_size(4_GiB);
318 another_group->add_partition_names("system");
319 another_group->add_partition_names("vendor");
320 another_group->add_partition_names("product");
321 auto product = manifest_.add_partitions();
322 product->set_partition_name("product");
323 SetSize(product, 1_GiB);
324
325 EXPECT_TRUE(UpdateAndExport());
326
327 EXPECT_EQ(nullptr, builder_->FindGroup(T("group")));
328 EXPECT_TRUE(CheckGroupSize("another_group", 4_GiB));
329 EXPECT_TRUE(CheckSize("system", 2_GiB));
330 EXPECT_TRUE(CheckGroupName("system", "another_group"));
331 EXPECT_TRUE(CheckSize("vendor", 1_GiB));
332 EXPECT_TRUE(CheckGroupName("vendor", "another_group"));
333 EXPECT_TRUE(CheckSize("product", 1_GiB));
334 EXPECT_TRUE(CheckGroupName("product", "another_group"));
335}
336
Haibo Huangcf8a5b02019-11-08 12:15:11 -0800337INSTANTIATE_TEST_SUITE_P(Snapshot, SnapshotMetadataUpdaterTest, testing::Values(0, 1));
Yifan Hongd22459d2019-09-13 14:49:53 -0700338
339} // namespace snapshot
340} // namespace android