1 /*
2  * Copyright (C) 2018 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 <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <liblp/builder.h>
20 #include <storage_literals/storage_literals.h>
21 
22 #include "liblp_test.h"
23 #include "utility.h"
24 
25 using namespace std;
26 using namespace android::storage_literals;
27 using namespace android::fs_mgr;
28 using namespace android::fs_mgr::testing;
29 using ::testing::_;
30 using ::testing::AnyNumber;
31 using ::testing::ElementsAre;
32 using ::testing::NiceMock;
33 using ::testing::Return;
34 
35 class Environment : public ::testing::Environment {
36   public:
SetUp()37     void SetUp() override { ResetMockPropertyFetcher(); }
38 };
39 
main(int argc,char ** argv)40 int main(int argc, char** argv) {
41     ::testing::InitGoogleTest(&argc, argv);
42     return RUN_ALL_TESTS();
43 }
44 
45 class BuilderTest : public LiblpTest {};
46 
TEST_F(BuilderTest,BuildBasic)47 TEST_F(BuilderTest, BuildBasic) {
48     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
49     ASSERT_NE(builder, nullptr);
50 
51     Partition* partition = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
52     ASSERT_NE(partition, nullptr);
53     EXPECT_EQ(partition->name(), "system");
54     EXPECT_EQ(partition->attributes(), LP_PARTITION_ATTR_READONLY);
55     EXPECT_EQ(partition->size(), 0);
56     EXPECT_EQ(builder->FindPartition("system"), partition);
57 
58     builder->RemovePartition("system");
59     EXPECT_EQ(builder->FindPartition("system"), nullptr);
60 }
61 
TEST_F(BuilderTest,ResizePartition)62 TEST_F(BuilderTest, ResizePartition) {
63     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
64     ASSERT_NE(builder, nullptr);
65 
66     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
67     ASSERT_NE(system, nullptr);
68     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
69     EXPECT_EQ(system->size(), 65536);
70     ASSERT_EQ(system->extents().size(), 1);
71 
72     LinearExtent* extent = system->extents()[0]->AsLinearExtent();
73     ASSERT_NE(extent, nullptr);
74     EXPECT_EQ(extent->num_sectors(), 65536 / LP_SECTOR_SIZE);
75     // The first logical sector will be:
76     //      (LP_PARTITION_RESERVED_BYTES + 4096*2 + 1024*4) / 512
77     // Or, in terms of sectors (reserved + geometry + metadata):
78     //      (8 + 16 + 8) = 32
79     EXPECT_EQ(extent->physical_sector(), 32);
80 
81     // Test resizing to the same size.
82     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
83     EXPECT_EQ(system->size(), 65536);
84     EXPECT_EQ(system->extents().size(), 1);
85     EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
86     // Test resizing to a smaller size.
87     EXPECT_EQ(builder->ResizePartition(system, 0), true);
88     EXPECT_EQ(system->size(), 0);
89     EXPECT_EQ(system->extents().size(), 0);
90     // Test resizing to a greater size.
91     builder->ResizePartition(system, 131072);
92     EXPECT_EQ(system->size(), 131072);
93     EXPECT_EQ(system->extents().size(), 1);
94     EXPECT_EQ(system->extents()[0]->num_sectors(), 131072 / LP_SECTOR_SIZE);
95     // Test resizing again, that the extents are merged together.
96     builder->ResizePartition(system, 1024 * 256);
97     EXPECT_EQ(system->size(), 1024 * 256);
98     EXPECT_EQ(system->extents().size(), 1);
99     EXPECT_EQ(system->extents()[0]->num_sectors(), (1024 * 256) / LP_SECTOR_SIZE);
100 
101     // Test shrinking within the same extent.
102     builder->ResizePartition(system, 32768);
103     EXPECT_EQ(system->size(), 32768);
104     EXPECT_EQ(system->extents().size(), 1);
105     extent = system->extents()[0]->AsLinearExtent();
106     ASSERT_NE(extent, nullptr);
107     EXPECT_EQ(extent->num_sectors(), 32768 / LP_SECTOR_SIZE);
108     EXPECT_EQ(extent->physical_sector(), 32);
109 
110     auto exported = builder->Export();
111     ASSERT_NE(exported, nullptr);
112     ASSERT_EQ(FindPartition(*exported.get(), "not found"), nullptr);
113     auto entry = FindPartition(*exported.get(), "system");
114     ASSERT_NE(entry, nullptr);
115     ASSERT_EQ(GetPartitionSize(*exported.get(), *entry), 32768);
116 
117     // Test shrinking to 0.
118     builder->ResizePartition(system, 0);
119     EXPECT_EQ(system->size(), 0);
120     EXPECT_EQ(system->extents().size(), 0);
121 }
122 
TEST_F(BuilderTest,PartitionAlignment)123 TEST_F(BuilderTest, PartitionAlignment) {
124     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
125     ASSERT_NE(builder, nullptr);
126 
127     // Test that we align up to one sector.
128     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
129     ASSERT_NE(system, nullptr);
130     EXPECT_EQ(builder->ResizePartition(system, 10000), true);
131     EXPECT_EQ(system->size(), 12288);
132     EXPECT_EQ(system->extents().size(), 1);
133 
134     builder->ResizePartition(system, 7000);
135     EXPECT_EQ(system->size(), 8192);
136     EXPECT_EQ(system->extents().size(), 1);
137 }
138 
TEST_F(BuilderTest,DiskAlignment)139 TEST_F(BuilderTest, DiskAlignment) {
140     static const uint64_t kDiskSize = 1000000;
141     static const uint32_t kMetadataSize = 1024;
142     static const uint32_t kMetadataSlots = 2;
143 
144     unique_ptr<MetadataBuilder> builder =
145             MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
146     ASSERT_EQ(builder, nullptr);
147 }
148 
TEST_F(BuilderTest,MetadataAlignment)149 TEST_F(BuilderTest, MetadataAlignment) {
150     // Make sure metadata sizes get aligned up.
151     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1000, 2);
152     ASSERT_NE(builder, nullptr);
153     unique_ptr<LpMetadata> exported = builder->Export();
154     ASSERT_NE(exported, nullptr);
155     EXPECT_EQ(exported->geometry.metadata_max_size, 1024);
156 }
157 
TEST_F(BuilderTest,InternalAlignment)158 TEST_F(BuilderTest, InternalAlignment) {
159     // Test the metadata fitting within alignment.
160     BlockDeviceInfo device_info("super", 1024 * 1024, 768 * 1024, 0, 4096);
161     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 2);
162     ASSERT_NE(builder, nullptr);
163     unique_ptr<LpMetadata> exported = builder->Export();
164     ASSERT_NE(exported, nullptr);
165     auto super_device = GetMetadataSuperBlockDevice(*exported.get());
166     ASSERT_NE(super_device, nullptr);
167     EXPECT_EQ(super_device->first_logical_sector, 1536);
168 
169     // Test a large alignment offset thrown in.
170     device_info.alignment_offset = 753664;
171     builder = MetadataBuilder::New(device_info, 1024, 2);
172     ASSERT_NE(builder, nullptr);
173     exported = builder->Export();
174     ASSERT_NE(exported, nullptr);
175     super_device = GetMetadataSuperBlockDevice(*exported.get());
176     ASSERT_NE(super_device, nullptr);
177     EXPECT_EQ(super_device->first_logical_sector, 1536);
178 
179     // Alignment offset without alignment is ignored.
180     device_info.alignment = 0;
181     builder = MetadataBuilder::New(device_info, 1024, 2);
182     ASSERT_NE(builder, nullptr);
183 
184     // Test a small alignment with an alignment offset.
185     device_info.alignment = 12 * 1024;
186     device_info.alignment_offset = 3 * 1024;
187     builder = MetadataBuilder::New(device_info, 16 * 1024, 2);
188     ASSERT_NE(builder, nullptr);
189     exported = builder->Export();
190     ASSERT_NE(exported, nullptr);
191     super_device = GetMetadataSuperBlockDevice(*exported.get());
192     ASSERT_NE(super_device, nullptr);
193     EXPECT_EQ(super_device->first_logical_sector, 168);
194 
195     // Test a small alignment with no alignment offset.
196     device_info.alignment = 11 * 1024;
197     builder = MetadataBuilder::New(device_info, 16 * 1024, 2);
198     ASSERT_NE(builder, nullptr);
199     exported = builder->Export();
200     ASSERT_NE(exported, nullptr);
201     super_device = GetMetadataSuperBlockDevice(*exported.get());
202     ASSERT_NE(super_device, nullptr);
203     EXPECT_EQ(super_device->first_logical_sector, 154);
204 }
205 
TEST_F(BuilderTest,InternalPartitionAlignment)206 TEST_F(BuilderTest, InternalPartitionAlignment) {
207     BlockDeviceInfo device_info("super", 512 * 1024 * 1024, 768 * 1024, 753664, 4096);
208     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 32 * 1024, 2);
209 
210     Partition* a = builder->AddPartition("a", 0);
211     ASSERT_NE(a, nullptr);
212     Partition* b = builder->AddPartition("b", 0);
213     ASSERT_NE(b, nullptr);
214 
215     // Add a bunch of small extents to each, interleaving.
216     for (size_t i = 0; i < 10; i++) {
217         ASSERT_TRUE(builder->ResizePartition(a, a->size() + 4096));
218         ASSERT_TRUE(builder->ResizePartition(b, b->size() + 4096));
219     }
220     EXPECT_EQ(a->size(), 40960);
221     EXPECT_EQ(b->size(), 40960);
222 
223     unique_ptr<LpMetadata> exported = builder->Export();
224     ASSERT_NE(exported, nullptr);
225 
226     // Check that each starting sector is aligned.
227     for (const auto& extent : exported->extents) {
228         ASSERT_EQ(extent.target_type, LP_TARGET_TYPE_LINEAR);
229         EXPECT_EQ(extent.num_sectors, 80);
230 
231         uint64_t aligned_lba;
232         uint64_t lba = extent.target_data * LP_SECTOR_SIZE;
233         ASSERT_TRUE(AlignTo(lba, device_info.alignment, &aligned_lba));
234         EXPECT_EQ(lba, aligned_lba);
235     }
236 
237     // Check one extent.
238     EXPECT_EQ(exported->extents.back().target_data, 3072);
239 }
240 
TEST_F(BuilderTest,UseAllDiskSpace)241 TEST_F(BuilderTest, UseAllDiskSpace) {
242     static constexpr uint64_t total = 1024 * 1024;
243     static constexpr uint64_t metadata = 1024;
244     static constexpr uint64_t slots = 2;
245     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(total, metadata, slots);
246     // We reserve a geometry block (4KB) plus space for each copy of the
247     // maximum size of a metadata blob. Then, we double that space since
248     // we store a backup copy of everything.
249     static constexpr uint64_t geometry = 4 * 1024;
250     static constexpr uint64_t allocatable =
251             total - (metadata * slots + geometry) * 2 - LP_PARTITION_RESERVED_BYTES;
252     EXPECT_EQ(builder->AllocatableSpace(), allocatable);
253     EXPECT_EQ(builder->UsedSpace(), 0);
254 
255     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
256     ASSERT_NE(system, nullptr);
257     EXPECT_EQ(builder->ResizePartition(system, allocatable), true);
258     EXPECT_EQ(system->size(), allocatable);
259     EXPECT_EQ(builder->UsedSpace(), allocatable);
260     EXPECT_EQ(builder->AllocatableSpace(), allocatable);
261     EXPECT_EQ(builder->ResizePartition(system, allocatable + 1), false);
262     EXPECT_EQ(system->size(), allocatable);
263     EXPECT_EQ(builder->UsedSpace(), allocatable);
264     EXPECT_EQ(builder->AllocatableSpace(), allocatable);
265 }
266 
TEST_F(BuilderTest,BuildComplex)267 TEST_F(BuilderTest, BuildComplex) {
268     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
269 
270     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
271     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
272     ASSERT_NE(system, nullptr);
273     ASSERT_NE(vendor, nullptr);
274     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
275     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
276     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
277     EXPECT_EQ(system->size(), 98304);
278     EXPECT_EQ(vendor->size(), 32768);
279 
280     // We now expect to have 3 extents total: 2 for system, 1 for vendor, since
281     // our allocation strategy is greedy/first-fit.
282     ASSERT_EQ(system->extents().size(), 2);
283     ASSERT_EQ(vendor->extents().size(), 1);
284 
285     LinearExtent* system1 = system->extents()[0]->AsLinearExtent();
286     LinearExtent* system2 = system->extents()[1]->AsLinearExtent();
287     LinearExtent* vendor1 = vendor->extents()[0]->AsLinearExtent();
288     ASSERT_NE(system1, nullptr);
289     ASSERT_NE(system2, nullptr);
290     ASSERT_NE(vendor1, nullptr);
291     EXPECT_EQ(system1->num_sectors(), 65536 / LP_SECTOR_SIZE);
292     EXPECT_EQ(system1->physical_sector(), 32);
293     EXPECT_EQ(system2->num_sectors(), 32768 / LP_SECTOR_SIZE);
294     EXPECT_EQ(system2->physical_sector(), 224);
295     EXPECT_EQ(vendor1->num_sectors(), 32768 / LP_SECTOR_SIZE);
296     EXPECT_EQ(vendor1->physical_sector(), 160);
297     EXPECT_EQ(system1->physical_sector() + system1->num_sectors(), vendor1->physical_sector());
298     EXPECT_EQ(vendor1->physical_sector() + vendor1->num_sectors(), system2->physical_sector());
299 }
300 
TEST_F(BuilderTest,AddInvalidPartition)301 TEST_F(BuilderTest, AddInvalidPartition) {
302     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
303 
304     Partition* partition = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
305     ASSERT_NE(partition, nullptr);
306 
307     // Duplicate name.
308     partition = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
309     EXPECT_EQ(partition, nullptr);
310 
311     // Empty name.
312     partition = builder->AddPartition("", LP_PARTITION_ATTR_READONLY);
313     EXPECT_EQ(partition, nullptr);
314 }
315 
TEST_F(BuilderTest,BuilderExport)316 TEST_F(BuilderTest, BuilderExport) {
317     static const uint64_t kDiskSize = 1024 * 1024;
318     static const uint32_t kMetadataSize = 1024;
319     static const uint32_t kMetadataSlots = 2;
320     unique_ptr<MetadataBuilder> builder =
321             MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
322 
323     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
324     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
325     ASSERT_NE(system, nullptr);
326     ASSERT_NE(vendor, nullptr);
327     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
328     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
329     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
330 
331     unique_ptr<LpMetadata> exported = builder->Export();
332     EXPECT_NE(exported, nullptr);
333 
334     auto super_device = GetMetadataSuperBlockDevice(*exported.get());
335     ASSERT_NE(super_device, nullptr);
336 
337     // Verify geometry. Some details of this may change if we change the
338     // metadata structures. So in addition to checking the exact values, we
339     // also check that they are internally consistent after.
340     const LpMetadataGeometry& geometry = exported->geometry;
341     EXPECT_EQ(geometry.magic, LP_METADATA_GEOMETRY_MAGIC);
342     EXPECT_EQ(geometry.struct_size, sizeof(geometry));
343     EXPECT_EQ(geometry.metadata_max_size, 1024);
344     EXPECT_EQ(geometry.metadata_slot_count, 2);
345     EXPECT_EQ(super_device->first_logical_sector, 32);
346 
347     static const size_t kMetadataSpace =
348             ((kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE) * 2;
349     EXPECT_GE(super_device->first_logical_sector * LP_SECTOR_SIZE, kMetadataSpace);
350 
351     // Verify header.
352     const LpMetadataHeader& header = exported->header;
353     EXPECT_EQ(header.magic, LP_METADATA_HEADER_MAGIC);
354     EXPECT_EQ(header.major_version, LP_METADATA_MAJOR_VERSION);
355     EXPECT_EQ(header.minor_version, LP_METADATA_MINOR_VERSION_MIN);
356     EXPECT_EQ(header.header_size, sizeof(LpMetadataHeaderV1_0));
357 
358     ASSERT_EQ(exported->partitions.size(), 2);
359     ASSERT_EQ(exported->extents.size(), 3);
360 
361     for (const auto& partition : exported->partitions) {
362         Partition* original = builder->FindPartition(GetPartitionName(partition));
363         ASSERT_NE(original, nullptr);
364         for (size_t i = 0; i < partition.num_extents; i++) {
365             const auto& extent = exported->extents[partition.first_extent_index + i];
366             LinearExtent* original_extent = original->extents()[i]->AsLinearExtent();
367             EXPECT_EQ(extent.num_sectors, original_extent->num_sectors());
368             EXPECT_EQ(extent.target_type, LP_TARGET_TYPE_LINEAR);
369             EXPECT_EQ(extent.target_data, original_extent->physical_sector());
370         }
371         EXPECT_EQ(partition.attributes, original->attributes());
372     }
373 }
374 
TEST_F(BuilderTest,BuilderImport)375 TEST_F(BuilderTest, BuilderImport) {
376     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
377 
378     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
379     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
380     ASSERT_NE(system, nullptr);
381     ASSERT_NE(vendor, nullptr);
382     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
383     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
384     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
385 
386     unique_ptr<LpMetadata> exported = builder->Export();
387     ASSERT_NE(exported, nullptr);
388 
389     builder = MetadataBuilder::New(*exported.get());
390     ASSERT_NE(builder, nullptr);
391     system = builder->FindPartition("system");
392     ASSERT_NE(system, nullptr);
393     vendor = builder->FindPartition("vendor");
394     ASSERT_NE(vendor, nullptr);
395 
396     EXPECT_EQ(system->size(), 98304);
397     ASSERT_EQ(system->extents().size(), 2);
398     EXPECT_EQ(system->attributes(), LP_PARTITION_ATTR_READONLY);
399     EXPECT_EQ(vendor->size(), 32768);
400     ASSERT_EQ(vendor->extents().size(), 1);
401     EXPECT_EQ(vendor->attributes(), LP_PARTITION_ATTR_READONLY);
402 
403     LinearExtent* system1 = system->extents()[0]->AsLinearExtent();
404     LinearExtent* system2 = system->extents()[1]->AsLinearExtent();
405     LinearExtent* vendor1 = vendor->extents()[0]->AsLinearExtent();
406     EXPECT_EQ(system1->num_sectors(), 65536 / LP_SECTOR_SIZE);
407     EXPECT_EQ(system1->physical_sector(), 32);
408     EXPECT_EQ(system2->num_sectors(), 32768 / LP_SECTOR_SIZE);
409     EXPECT_EQ(system2->physical_sector(), 224);
410     EXPECT_EQ(vendor1->num_sectors(), 32768 / LP_SECTOR_SIZE);
411 }
412 
TEST_F(BuilderTest,ExportNameTooLong)413 TEST_F(BuilderTest, ExportNameTooLong) {
414     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
415 
416     std::string name = "abcdefghijklmnopqrstuvwxyz0123456789";
417     Partition* system = builder->AddPartition(name + name, LP_PARTITION_ATTR_READONLY);
418     EXPECT_NE(system, nullptr);
419 
420     unique_ptr<LpMetadata> exported = builder->Export();
421     EXPECT_EQ(exported, nullptr);
422 }
423 
TEST_F(BuilderTest,MetadataTooLarge)424 TEST_F(BuilderTest, MetadataTooLarge) {
425     static const size_t kDiskSize = 128 * 1024;
426     static const size_t kMetadataSize = 64 * 1024;
427 
428     // No space to store metadata + geometry.
429     BlockDeviceInfo device_info("super", kDiskSize, 0, 0, 4096);
430     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
431     EXPECT_EQ(builder, nullptr);
432 
433     // No space to store metadata + geometry + one free sector.
434     device_info.size += LP_PARTITION_RESERVED_BYTES + (LP_METADATA_GEOMETRY_SIZE * 2);
435     builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
436     EXPECT_EQ(builder, nullptr);
437 
438     // Space for metadata + geometry + one free block.
439     device_info.size += device_info.logical_block_size;
440     builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
441     EXPECT_NE(builder, nullptr);
442 
443     // Test with alignment.
444     device_info.alignment = 131072;
445     builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
446     EXPECT_EQ(builder, nullptr);
447 }
448 
TEST_F(BuilderTest,UpdateBlockDeviceInfo)449 TEST_F(BuilderTest, UpdateBlockDeviceInfo) {
450     BlockDeviceInfo device_info("super", 1024 * 1024, 4096, 1024, 4096);
451     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
452     ASSERT_NE(builder, nullptr);
453 
454     BlockDeviceInfo new_info;
455     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
456 
457     EXPECT_EQ(new_info.size, device_info.size);
458     EXPECT_EQ(new_info.alignment, device_info.alignment);
459     EXPECT_EQ(new_info.alignment_offset, device_info.alignment_offset);
460     EXPECT_EQ(new_info.logical_block_size, device_info.logical_block_size);
461 
462     device_info.alignment = 0;
463     device_info.alignment_offset = 2048;
464     ASSERT_TRUE(builder->UpdateBlockDeviceInfo("super", device_info));
465     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
466     EXPECT_EQ(new_info.alignment, 4096);
467     EXPECT_EQ(new_info.alignment_offset, device_info.alignment_offset);
468 
469     device_info.alignment = 8192;
470     device_info.alignment_offset = 0;
471     ASSERT_TRUE(builder->UpdateBlockDeviceInfo("super", device_info));
472     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
473     EXPECT_EQ(new_info.alignment, 8192);
474     EXPECT_EQ(new_info.alignment_offset, 2048);
475 
476     new_info.size += 4096;
477     ASSERT_FALSE(builder->UpdateBlockDeviceInfo("super", new_info));
478     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
479     EXPECT_EQ(new_info.size, 1024 * 1024);
480 
481     new_info.logical_block_size = 512;
482     ASSERT_TRUE(builder->UpdateBlockDeviceInfo("super", new_info));
483     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
484     EXPECT_EQ(new_info.logical_block_size, 4096);
485 
486     new_info.logical_block_size = 7;
487     ASSERT_FALSE(builder->UpdateBlockDeviceInfo("super", new_info));
488     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
489     EXPECT_EQ(new_info.logical_block_size, 4096);
490 }
491 
TEST_F(BuilderTest,InvalidBlockSize)492 TEST_F(BuilderTest, InvalidBlockSize) {
493     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 513);
494     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
495     EXPECT_EQ(builder, nullptr);
496 }
497 
TEST_F(BuilderTest,AlignedExtentSize)498 TEST_F(BuilderTest, AlignedExtentSize) {
499     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
500     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
501     ASSERT_NE(builder, nullptr);
502 
503     Partition* partition = builder->AddPartition("system", 0);
504     ASSERT_NE(partition, nullptr);
505     ASSERT_TRUE(builder->ResizePartition(partition, 512));
506     EXPECT_EQ(partition->size(), 4096);
507 }
508 
TEST_F(BuilderTest,AlignedFreeSpace)509 TEST_F(BuilderTest, AlignedFreeSpace) {
510     // Only one sector free - at least one block is required.
511     BlockDeviceInfo device_info("super", 10240, 0, 0, 4096);
512     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 512, 1);
513     ASSERT_EQ(builder, nullptr);
514 }
515 
TEST_F(BuilderTest,HasDefaultGroup)516 TEST_F(BuilderTest, HasDefaultGroup) {
517     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
518     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
519     ASSERT_NE(builder, nullptr);
520 
521     EXPECT_FALSE(builder->AddGroup("default", 0));
522 }
523 
TEST_F(BuilderTest,GroupSizeLimits)524 TEST_F(BuilderTest, GroupSizeLimits) {
525     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
526     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
527     ASSERT_NE(builder, nullptr);
528 
529     ASSERT_TRUE(builder->AddGroup("google", 16384));
530 
531     Partition* partition = builder->AddPartition("system", "google", 0);
532     ASSERT_NE(partition, nullptr);
533     EXPECT_TRUE(builder->ResizePartition(partition, 8192));
534     EXPECT_EQ(partition->size(), 8192);
535     EXPECT_TRUE(builder->ResizePartition(partition, 16384));
536     EXPECT_EQ(partition->size(), 16384);
537     EXPECT_FALSE(builder->ResizePartition(partition, 32768));
538     EXPECT_EQ(partition->size(), 16384);
539 }
540 
TEST_F(BuilderTest,ListPartitionsInGroup)541 TEST_F(BuilderTest, ListPartitionsInGroup) {
542     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
543     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
544     ASSERT_NE(builder, nullptr);
545 
546     ASSERT_TRUE(builder->AddGroup("groupA", 16384));
547     ASSERT_TRUE(builder->AddGroup("groupB", 16384));
548 
549     Partition* system = builder->AddPartition("system", "groupA", 0);
550     Partition* vendor = builder->AddPartition("vendor", "groupA", 0);
551     Partition* product = builder->AddPartition("product", "groupB", 0);
552     ASSERT_NE(system, nullptr);
553     ASSERT_NE(vendor, nullptr);
554     ASSERT_NE(product, nullptr);
555 
556     auto groupA = builder->ListPartitionsInGroup("groupA");
557     auto groupB = builder->ListPartitionsInGroup("groupB");
558     auto groupC = builder->ListPartitionsInGroup("groupC");
559     ASSERT_THAT(groupA, ElementsAre(system, vendor));
560     ASSERT_THAT(groupB, ElementsAre(product));
561     ASSERT_TRUE(groupC.empty());
562 }
563 
TEST_F(BuilderTest,ChangeGroups)564 TEST_F(BuilderTest, ChangeGroups) {
565     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
566     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
567     ASSERT_NE(builder, nullptr);
568 
569     ASSERT_TRUE(builder->AddGroup("groupA", 16384));
570     ASSERT_TRUE(builder->AddGroup("groupB", 32768));
571 
572     Partition* system = builder->AddPartition("system", "groupA", 0);
573     Partition* vendor = builder->AddPartition("vendor", "groupB", 0);
574     ASSERT_NE(system, nullptr);
575     ASSERT_NE(vendor, nullptr);
576     ASSERT_NE(builder->Export(), nullptr);
577 
578     ASSERT_FALSE(builder->ChangePartitionGroup(system, "groupXYZ"));
579     ASSERT_TRUE(builder->ChangePartitionGroup(system, "groupB"));
580     ASSERT_NE(builder->Export(), nullptr);
581 
582     // Violate group constraint by reassigning groups.
583     ASSERT_TRUE(builder->ResizePartition(system, 16384 + 4096));
584     ASSERT_TRUE(builder->ChangePartitionGroup(system, "groupA"));
585     ASSERT_EQ(builder->Export(), nullptr);
586 
587     ASSERT_FALSE(builder->ChangeGroupSize("default", 2));
588     ASSERT_FALSE(builder->ChangeGroupSize("unknown", 2));
589     ASSERT_TRUE(builder->ChangeGroupSize("groupA", 32768));
590     ASSERT_NE(builder->Export(), nullptr);
591 }
592 
TEST_F(BuilderTest,RemoveAndAddFirstPartition)593 TEST_F(BuilderTest, RemoveAndAddFirstPartition) {
594     auto builder = MetadataBuilder::New(10_GiB, 65536, 2);
595     ASSERT_NE(nullptr, builder);
596     ASSERT_TRUE(builder->AddGroup("foo_a", 5_GiB));
597     ASSERT_TRUE(builder->AddGroup("foo_b", 5_GiB));
598     android::fs_mgr::Partition* p;
599     p = builder->AddPartition("system_a", "foo_a", 0);
600     ASSERT_TRUE(p && builder->ResizePartition(p, 2_GiB));
601     p = builder->AddPartition("vendor_a", "foo_a", 0);
602     ASSERT_TRUE(p && builder->ResizePartition(p, 1_GiB));
603     p = builder->AddPartition("system_b", "foo_b", 0);
604     ASSERT_TRUE(p && builder->ResizePartition(p, 2_GiB));
605     p = builder->AddPartition("vendor_b", "foo_b", 0);
606     ASSERT_TRUE(p && builder->ResizePartition(p, 1_GiB));
607 
608     builder->RemovePartition("system_a");
609     builder->RemovePartition("vendor_a");
610     p = builder->AddPartition("system_a", "foo_a", 0);
611     ASSERT_TRUE(p && builder->ResizePartition(p, 3_GiB));
612     p = builder->AddPartition("vendor_a", "foo_a", 0);
613     ASSERT_TRUE(p && builder->ResizePartition(p, 1_GiB));
614 }
615 
TEST_F(BuilderTest,ListGroups)616 TEST_F(BuilderTest, ListGroups) {
617     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
618     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
619     ASSERT_NE(builder, nullptr);
620     ASSERT_TRUE(builder->AddGroup("example", 0));
621 
622     std::vector<std::string> groups = builder->ListGroups();
623     ASSERT_THAT(groups, ElementsAre("default", "example"));
624 }
625 
TEST_F(BuilderTest,RemoveGroupAndPartitions)626 TEST_F(BuilderTest, RemoveGroupAndPartitions) {
627     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
628     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
629     ASSERT_NE(builder, nullptr);
630     ASSERT_TRUE(builder->AddGroup("example", 0));
631     ASSERT_NE(builder->AddPartition("system", "default", 0), nullptr);
632     ASSERT_NE(builder->AddPartition("vendor", "example", 0), nullptr);
633 
634     builder->RemoveGroupAndPartitions("example");
635     ASSERT_NE(builder->FindPartition("system"), nullptr);
636     ASSERT_EQ(builder->FindPartition("vendor"), nullptr);
637     ASSERT_THAT(builder->ListGroups(), ElementsAre("default"));
638 
639     builder->RemoveGroupAndPartitions("default");
640     ASSERT_NE(builder->FindPartition("system"), nullptr);
641 }
642 
TEST_F(BuilderTest,MultipleBlockDevices)643 TEST_F(BuilderTest, MultipleBlockDevices) {
644     std::vector<BlockDeviceInfo> partitions = {
645             BlockDeviceInfo("system_a", 256_MiB, 786432, 229376, 4096),
646             BlockDeviceInfo("vendor_a", 128_MiB, 786432, 753664, 4096),
647             BlockDeviceInfo("product_a", 64_MiB, 786432, 753664, 4096),
648     };
649     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(partitions, "system_a", 65536, 2);
650     ASSERT_NE(builder, nullptr);
651     EXPECT_EQ(builder->AllocatableSpace(), 467402752);
652 
653     // Create a partition that spans 3 devices.
654     Partition* p = builder->AddPartition("system_a", 0);
655     ASSERT_NE(p, nullptr);
656     ASSERT_TRUE(builder->ResizePartition(p, 466976768));
657 
658     unique_ptr<LpMetadata> metadata = builder->Export();
659     ASSERT_NE(metadata, nullptr);
660     ASSERT_EQ(metadata->block_devices.size(), 3);
661     EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[0]), "system_a");
662     EXPECT_EQ(metadata->block_devices[0].size, 256_MiB);
663     EXPECT_EQ(metadata->block_devices[0].alignment, 786432);
664     EXPECT_EQ(metadata->block_devices[0].alignment_offset, 229376);
665     EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[1]), "vendor_a");
666     EXPECT_EQ(metadata->block_devices[1].size, 128_MiB);
667     EXPECT_EQ(metadata->block_devices[1].alignment, 786432);
668     EXPECT_EQ(metadata->block_devices[1].alignment_offset, 753664);
669     EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[2]), "product_a");
670     EXPECT_EQ(metadata->block_devices[2].size, 64_MiB);
671     EXPECT_EQ(metadata->block_devices[2].alignment, 786432);
672     EXPECT_EQ(metadata->block_devices[2].alignment_offset, 753664);
673     ASSERT_EQ(metadata->extents.size(), 3);
674     EXPECT_EQ(metadata->extents[0].num_sectors, 522752);
675     EXPECT_EQ(metadata->extents[0].target_type, LP_TARGET_TYPE_LINEAR);
676     EXPECT_EQ(metadata->extents[0].target_data, 1536);
677     EXPECT_EQ(metadata->extents[0].target_source, 0);
678     EXPECT_EQ(metadata->extents[1].num_sectors, 260608);
679     EXPECT_EQ(metadata->extents[1].target_type, LP_TARGET_TYPE_LINEAR);
680     EXPECT_EQ(metadata->extents[1].target_data, 1536);
681     EXPECT_EQ(metadata->extents[1].target_source, 1);
682     EXPECT_EQ(metadata->extents[2].num_sectors, 128704);
683     EXPECT_EQ(metadata->extents[2].target_type, LP_TARGET_TYPE_LINEAR);
684     EXPECT_EQ(metadata->extents[2].target_data, 1536);
685     EXPECT_EQ(metadata->extents[2].target_source, 2);
686 }
687 
TEST_F(BuilderTest,ImportPartitionsOk)688 TEST_F(BuilderTest, ImportPartitionsOk) {
689     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
690     ASSERT_NE(builder, nullptr);
691 
692     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
693     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
694     ASSERT_NE(system, nullptr);
695     ASSERT_NE(vendor, nullptr);
696     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
697     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
698     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
699 
700     unique_ptr<LpMetadata> exported = builder->Export();
701     ASSERT_NE(exported, nullptr);
702 
703     builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
704     ASSERT_NE(builder, nullptr);
705 
706     ASSERT_TRUE(builder->ImportPartitions(*exported.get(), {"vendor"}));
707     EXPECT_NE(builder->FindPartition("vendor"), nullptr);
708     EXPECT_EQ(builder->FindPartition("system"), nullptr);
709 
710     unique_ptr<LpMetadata> new_metadata = builder->Export();
711     ASSERT_NE(new_metadata, nullptr);
712 
713     ASSERT_EQ(exported->partitions.size(), static_cast<size_t>(2));
714     ASSERT_EQ(GetPartitionName(exported->partitions[1]), "vendor");
715     ASSERT_EQ(new_metadata->partitions.size(), static_cast<size_t>(1));
716     ASSERT_EQ(GetPartitionName(new_metadata->partitions[0]), "vendor");
717 
718     const LpMetadataExtent& extent_a =
719             exported->extents[exported->partitions[1].first_extent_index];
720     const LpMetadataExtent& extent_b =
721             new_metadata->extents[new_metadata->partitions[0].first_extent_index];
722     EXPECT_EQ(extent_a.num_sectors, extent_b.num_sectors);
723     EXPECT_EQ(extent_a.target_type, extent_b.target_type);
724     EXPECT_EQ(extent_a.target_data, extent_b.target_data);
725     EXPECT_EQ(extent_a.target_source, extent_b.target_source);
726 }
727 
TEST_F(BuilderTest,ImportPartitionsFail)728 TEST_F(BuilderTest, ImportPartitionsFail) {
729     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
730     ASSERT_NE(builder, nullptr);
731 
732     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
733     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
734     ASSERT_NE(system, nullptr);
735     ASSERT_NE(vendor, nullptr);
736     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
737     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
738     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
739 
740     unique_ptr<LpMetadata> exported = builder->Export();
741     ASSERT_NE(exported, nullptr);
742 
743     // Different device size.
744     builder = MetadataBuilder::New(1024 * 2048, 1024, 2);
745     ASSERT_NE(builder, nullptr);
746     EXPECT_FALSE(builder->ImportPartitions(*exported.get(), {"system"}));
747 }
748 
TEST_F(BuilderTest,ABExtents)749 TEST_F(BuilderTest, ABExtents) {
750     BlockDeviceInfo device_info("super", 10_GiB, 768 * 1024, 0, 4096);
751 
752     // A and B slots should be allocated from separate halves of the partition,
753     // to mitigate allocating too many extents. (b/120433288)
754     ON_CALL(*GetMockedPropertyFetcher(), GetProperty("ro.boot.slot_suffix", _))
755             .WillByDefault(Return("_a"));
756 
757     auto builder = MetadataBuilder::New(device_info, 65536, 2);
758     ASSERT_NE(builder, nullptr);
759     Partition* system_a = builder->AddPartition("system_a", 0);
760     ASSERT_NE(system_a, nullptr);
761     Partition* system_b = builder->AddPartition("system_b", 0);
762     ASSERT_NE(system_b, nullptr);
763     ASSERT_TRUE(builder->ResizePartition(system_a, 2_GiB));
764     ASSERT_TRUE(builder->ResizePartition(system_b, 2_GiB));
765 
766     builder->RemovePartition("system_a");
767     system_a = builder->AddPartition("system_a", 0);
768     ASSERT_NE(system_a, nullptr);
769     ASSERT_TRUE(builder->ResizePartition(system_a, 3_GiB));
770 
771     EXPECT_EQ(system_a->extents().size(), static_cast<size_t>(1));
772     EXPECT_EQ(system_b->extents().size(), static_cast<size_t>(1));
773     ASSERT_TRUE(builder->ResizePartition(system_b, 6_GiB));
774     EXPECT_EQ(system_b->extents().size(), static_cast<size_t>(2));
775 
776     unique_ptr<LpMetadata> exported = builder->Export();
777     ASSERT_NE(exported, nullptr);
778     ASSERT_EQ(exported->extents.size(), static_cast<size_t>(3));
779     EXPECT_EQ(exported->extents[0].target_data, 10487808);
780     EXPECT_EQ(exported->extents[0].num_sectors, 10483712);
781     EXPECT_EQ(exported->extents[1].target_data, 6292992);
782     EXPECT_EQ(exported->extents[1].num_sectors, 2099200);
783     EXPECT_EQ(exported->extents[2].target_data, 1536);
784     EXPECT_EQ(exported->extents[2].num_sectors, 6291456);
785 }
786 
TEST_F(BuilderTest,PartialExtents)787 TEST_F(BuilderTest, PartialExtents) {
788     // super has a minimum extent size of 768KiB.
789     BlockDeviceInfo device_info("super", 1_GiB, 768 * 1024, 0, 4096);
790     auto builder = MetadataBuilder::New(device_info, 65536, 1);
791     ASSERT_NE(builder, nullptr);
792     Partition* system = builder->AddPartition("system", 0);
793     ASSERT_NE(system, nullptr);
794     Partition* vendor = builder->AddPartition("vendor", 0);
795     ASSERT_NE(vendor, nullptr);
796     ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment + 4096));
797     ASSERT_TRUE(builder->ResizePartition(vendor, device_info.alignment));
798     ASSERT_EQ(system->size(), device_info.alignment + 4096);
799     ASSERT_EQ(vendor->size(), device_info.alignment);
800 
801     ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment * 2));
802     ASSERT_EQ(system->extents().size(), static_cast<size_t>(1));
803 
804     unique_ptr<LpMetadata> exported = builder->Export();
805     ASSERT_NE(exported, nullptr);
806     ASSERT_EQ(exported->extents.size(), static_cast<size_t>(2));
807     EXPECT_EQ(exported->extents[0].target_data, 1536);
808     EXPECT_EQ(exported->extents[0].num_sectors, 3072);
809     EXPECT_EQ(exported->extents[1].target_data, 4608);
810     EXPECT_EQ(exported->extents[1].num_sectors, 1536);
811 }
812 
TEST_F(BuilderTest,UpdateSuper)813 TEST_F(BuilderTest, UpdateSuper) {
814     // Build the on-disk metadata that we saw before flashing.
815     auto builder = MetadataBuilder::New(8145338368ULL, 65536, 3);
816     ASSERT_NE(builder, nullptr);
817 
818     ASSERT_TRUE(builder->AddGroup("google_dynamic_partitions_a", 4068474880ULL));
819     ASSERT_TRUE(builder->AddGroup("google_dynamic_partitions_b", 4068474880ULL));
820 
821     Partition* partition = builder->AddPartition("system_a", "google_dynamic_partitions_a",
822                                                  LP_PARTITION_ATTR_READONLY);
823     ASSERT_NE(partition, nullptr);
824     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 1901568, 3608576));
825 
826     partition = builder->AddPartition("vendor_a", "google_dynamic_partitions_a",
827                                       LP_PARTITION_ATTR_READONLY);
828     ASSERT_NE(partition, nullptr);
829     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 1521664, 5510144));
830 
831     partition = builder->AddPartition("product_a", "google_dynamic_partitions_a",
832                                       LP_PARTITION_ATTR_READONLY);
833     ASSERT_NE(partition, nullptr);
834     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 3606528, 2048));
835 
836     partition = builder->AddPartition("system_b", "google_dynamic_partitions_b",
837                                       LP_PARTITION_ATTR_READONLY);
838     ASSERT_NE(partition, nullptr);
839     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 1901568, 7955456));
840 
841     partition = builder->AddPartition("vendor_b", "google_dynamic_partitions_b",
842                                       LP_PARTITION_ATTR_READONLY);
843     ASSERT_NE(partition, nullptr);
844     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 1521664, 9857024));
845 
846     partition = builder->AddPartition("product_b", "google_dynamic_partitions_b",
847                                       LP_PARTITION_ATTR_READONLY);
848     ASSERT_NE(partition, nullptr);
849     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 3606528, 11378688));
850 
851     auto on_disk = builder->Export();
852     ASSERT_NE(on_disk, nullptr);
853 
854     // Build the super_empty from the new build.
855     builder = MetadataBuilder::New(8145338368ULL, 65536, 3);
856     ASSERT_NE(builder, nullptr);
857 
858     ASSERT_TRUE(builder->AddGroup("google_dynamic_partitions_a", 4068474880ULL));
859     ASSERT_TRUE(builder->AddGroup("google_dynamic_partitions_b", 4068474880ULL));
860     ASSERT_NE(builder->AddPartition("system_a", "google_dynamic_partitions_a",
861                                     LP_PARTITION_ATTR_READONLY),
862               nullptr);
863     ASSERT_NE(builder->AddPartition("system_b", "google_dynamic_partitions_b",
864                                     LP_PARTITION_ATTR_READONLY),
865               nullptr);
866     ASSERT_NE(builder->AddPartition("vendor_a", "google_dynamic_partitions_a",
867                                     LP_PARTITION_ATTR_READONLY),
868               nullptr);
869     ASSERT_NE(builder->AddPartition("vendor_b", "google_dynamic_partitions_b",
870                                     LP_PARTITION_ATTR_READONLY),
871               nullptr);
872     ASSERT_NE(builder->AddPartition("product_a", "google_dynamic_partitions_a",
873                                     LP_PARTITION_ATTR_READONLY),
874               nullptr);
875     ASSERT_NE(builder->AddPartition("product_b", "google_dynamic_partitions_b",
876                                     LP_PARTITION_ATTR_READONLY),
877               nullptr);
878 
879     std::set<std::string> partitions_to_keep{"system_a", "vendor_a", "product_a"};
880     ASSERT_TRUE(builder->ImportPartitions(*on_disk.get(), partitions_to_keep));
881 }
882 
883 // Interval has operator< defined; it is not appropriate to re-define Interval::operator== that
884 // compares device index.
885 namespace android {
886 namespace fs_mgr {
operator ==(const Interval & a,const Interval & b)887 bool operator==(const Interval& a, const Interval& b) {
888     return a.device_index == b.device_index && a.start == b.start && a.end == b.end;
889 }
890 }  // namespace fs_mgr
891 }  // namespace android
892 
TEST_F(BuilderTest,Interval)893 TEST_F(BuilderTest, Interval) {
894     EXPECT_EQ(0u, Interval::Intersect(Interval(0, 100, 200), Interval(0, 50, 100)).length());
895     EXPECT_EQ(Interval(0, 100, 150),
896               Interval::Intersect(Interval(0, 100, 200), Interval(0, 50, 150)));
897     EXPECT_EQ(Interval(0, 100, 200),
898               Interval::Intersect(Interval(0, 100, 200), Interval(0, 50, 200)));
899     EXPECT_EQ(Interval(0, 100, 200),
900               Interval::Intersect(Interval(0, 100, 200), Interval(0, 50, 250)));
901     EXPECT_EQ(Interval(0, 100, 200),
902               Interval::Intersect(Interval(0, 100, 200), Interval(0, 100, 200)));
903     EXPECT_EQ(Interval(0, 150, 200),
904               Interval::Intersect(Interval(0, 100, 200), Interval(0, 150, 250)));
905     EXPECT_EQ(0u, Interval::Intersect(Interval(0, 100, 200), Interval(0, 200, 250)).length());
906 
907     auto v = Interval::Intersect(std::vector<Interval>{Interval(0, 0, 50), Interval(0, 100, 150)},
908                                  std::vector<Interval>{Interval(0, 25, 125)});
909     ASSERT_EQ(2, v.size());
910     EXPECT_EQ(Interval(0, 25, 50), v[0]);
911     EXPECT_EQ(Interval(0, 100, 125), v[1]);
912 
913     EXPECT_EQ(0u, Interval::Intersect(std::vector<Interval>{Interval(0, 0, 50)},
914                                       std::vector<Interval>{Interval(0, 100, 150)})
915                           .size());
916 }
917 
TEST_F(BuilderTest,ExpandedHeader)918 TEST_F(BuilderTest, ExpandedHeader) {
919     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
920     ASSERT_NE(builder, nullptr);
921 
922     builder->RequireExpandedMetadataHeader();
923 
924     unique_ptr<LpMetadata> exported = builder->Export();
925     ASSERT_NE(exported, nullptr);
926     EXPECT_EQ(exported->header.header_size, sizeof(LpMetadataHeaderV1_2));
927 
928     exported->header.flags = 0x5e5e5e5e;
929 
930     builder = MetadataBuilder::New(*exported.get());
931     exported = builder->Export();
932     ASSERT_NE(exported, nullptr);
933     EXPECT_EQ(exported->header.header_size, sizeof(LpMetadataHeaderV1_2));
934     EXPECT_EQ(exported->header.flags, 0x5e5e5e5e);
935 }
936 
ToInterval(const std::unique_ptr<Extent> & extent)937 static Interval ToInterval(const std::unique_ptr<Extent>& extent) {
938     if (LinearExtent* le = extent->AsLinearExtent()) {
939         return le->AsInterval();
940     }
941     return {0, 0, 0};
942 }
943 
AddPartition(const std::unique_ptr<MetadataBuilder> & builder,const std::string & partition_name,const std::string & group_name,uint64_t num_sectors,uint64_t start_sector,std::vector<Interval> * intervals=nullptr)944 static void AddPartition(const std::unique_ptr<MetadataBuilder>& builder,
945                          const std::string& partition_name, const std::string& group_name,
946                          uint64_t num_sectors, uint64_t start_sector,
947                          std::vector<Interval>* intervals = nullptr) {
948     Partition* p = builder->AddPartition(partition_name, group_name, 0);
949     ASSERT_NE(p, nullptr);
950     ASSERT_TRUE(builder->AddLinearExtent(p, "super", num_sectors, start_sector));
951     ASSERT_EQ(p->extents().size(), 1);
952 
953     if (!intervals) {
954         return;
955     }
956 
957     auto new_interval = ToInterval(p->extents().back());
958     std::vector<Interval> new_intervals = {new_interval};
959 
960     auto overlap = Interval::Intersect(*intervals, new_intervals);
961     ASSERT_TRUE(overlap.empty());
962 
963     intervals->push_back(new_interval);
964 }
965 
TEST_F(BuilderTest,CollidedExtents)966 TEST_F(BuilderTest, CollidedExtents) {
967     BlockDeviceInfo super("super", 8_GiB, 786432, 229376, 4096);
968     std::vector<BlockDeviceInfo> block_devices = {super};
969 
970     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(block_devices, "super", 65536, 2);
971     ASSERT_NE(builder, nullptr);
972 
973     ASSERT_TRUE(builder->AddGroup("group", 0));
974 
975     std::vector<Interval> old_intervals;
976     AddPartition(builder, "system", "group", 10229008, 2048, &old_intervals);
977     AddPartition(builder, "test_a", "group", 648, 12709888, &old_intervals);
978     AddPartition(builder, "test_b", "group", 625184, 12711936, &old_intervals);
979     AddPartition(builder, "test_c", "group", 130912, 13338624, &old_intervals);
980     AddPartition(builder, "test_d", "group", 888, 13469696, &old_intervals);
981     AddPartition(builder, "test_e", "group", 888, 13471744, &old_intervals);
982     AddPartition(builder, "test_f", "group", 888, 13475840, &old_intervals);
983     AddPartition(builder, "test_g", "group", 888, 13477888, &old_intervals);
984 
985     // Don't track the first vendor interval, since it will get extended.
986     AddPartition(builder, "vendor", "group", 2477920, 10231808, nullptr);
987 
988     std::vector<Interval> new_intervals;
989 
990     Partition* p = builder->FindPartition("vendor");
991     ASSERT_NE(p, nullptr);
992     ASSERT_TRUE(builder->ResizePartition(p, 1282031616));
993     ASSERT_GE(p->extents().size(), 1);
994     for (const auto& extent : p->extents()) {
995         new_intervals.push_back(ToInterval(extent));
996     }
997 
998     std::vector<Interval> overlap = Interval::Intersect(old_intervals, new_intervals);
999     ASSERT_TRUE(overlap.empty());
1000 }
1001 
TEST_F(BuilderTest,LinearExtentOverlap)1002 TEST_F(BuilderTest, LinearExtentOverlap) {
1003     LinearExtent extent(20, 0, 10);
1004 
1005     EXPECT_TRUE(extent.OverlapsWith(LinearExtent{20, 0, 10}));
1006     EXPECT_TRUE(extent.OverlapsWith(LinearExtent{50, 0, 10}));
1007     EXPECT_FALSE(extent.OverlapsWith(LinearExtent{20, 0, 30}));
1008     EXPECT_FALSE(extent.OverlapsWith(LinearExtent{10, 0, 0}));
1009     EXPECT_TRUE(extent.OverlapsWith(LinearExtent{20, 0, 0}));
1010     EXPECT_TRUE(extent.OverlapsWith(LinearExtent{40, 0, 0}));
1011     EXPECT_TRUE(extent.OverlapsWith(LinearExtent{20, 0, 15}));
1012 
1013     EXPECT_FALSE(extent.OverlapsWith(LinearExtent{20, 1, 0}));
1014     EXPECT_FALSE(extent.OverlapsWith(LinearExtent{50, 1, 10}));
1015     EXPECT_FALSE(extent.OverlapsWith(LinearExtent{40, 1, 0}));
1016     EXPECT_FALSE(extent.OverlapsWith(LinearExtent{20, 1, 15}));
1017     EXPECT_FALSE(extent.OverlapsWith(LinearExtent{20, 1, 10}));
1018 }
1019 
TEST_F(BuilderTest,AlignFreeRegion)1020 TEST_F(BuilderTest, AlignFreeRegion) {
1021     BlockDeviceInfo super("super", 8_GiB, 786432, 0, 4096);
1022     std::vector<BlockDeviceInfo> block_devices = {super};
1023 
1024     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(block_devices, "super", 65536, 2);
1025     ASSERT_NE(builder, nullptr);
1026 
1027     Partition* p = builder->AddPartition("system", "default", 0);
1028     ASSERT_NE(p, nullptr);
1029     ASSERT_TRUE(builder->AddLinearExtent(p, "super", 64, (super.alignment + 4096) / 512));
1030 
1031     p = builder->AddPartition("vendor", "default", 0);
1032     ASSERT_NE(p, nullptr);
1033     ASSERT_TRUE(builder->ResizePartition(p, 2_GiB));
1034 
1035     const auto& extents = p->extents();
1036     ASSERT_EQ(extents.size(), 2);
1037 
1038     LinearExtent* e1 = extents[0]->AsLinearExtent();
1039     ASSERT_NE(e1, nullptr);
1040     LinearExtent* e2 = extents[1]->AsLinearExtent();
1041     ASSERT_NE(e2, nullptr);
1042 
1043     // The misaligned partition starting at sector 1544 should not cause any
1044     // overlap with previous extents. We should see vendor punch a hole where
1045     // "system" is, extending the hole up to the next aligned block.
1046     EXPECT_EQ(e1->physical_sector(), 1536);
1047     EXPECT_EQ(e1->end_sector(), 1544);
1048     EXPECT_EQ(e2->physical_sector(), 3072);
1049     EXPECT_EQ(e2->end_sector(), 4197368);
1050 }
1051 
TEST_F(BuilderTest,ResizeOverflow)1052 TEST_F(BuilderTest, ResizeOverflow) {
1053     BlockDeviceInfo super("super", 8_GiB, 786432, 229376, 4096);
1054     std::vector<BlockDeviceInfo> block_devices = {super};
1055 
1056     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(block_devices, "super", 65536, 2);
1057     ASSERT_NE(builder, nullptr);
1058 
1059     ASSERT_TRUE(builder->AddGroup("group", 0));
1060 
1061     Partition* p = builder->AddPartition("system", "default", 0);
1062     ASSERT_NE(p, nullptr);
1063     ASSERT_FALSE(builder->ResizePartition(p, 18446744073709551615ULL));
1064 }
1065 
TEST_F(BuilderTest,VerifyExtent)1066 TEST_F(BuilderTest, VerifyExtent) {
1067     auto source_builder = MetadataBuilder::New(4096 * 50, 40960, 2);
1068     ASSERT_NE(source_builder, nullptr);
1069     ASSERT_TRUE(source_builder->AddGroup("test_group_a", 40960));
1070     ASSERT_TRUE(source_builder->AddGroup("test_group_b", 40960));
1071     AddPartition(source_builder, "system_a", "test_group_a", 8192, 2048);
1072     AddPartition(source_builder, "vendor_a", "test_group_a", 10240, 10240);
1073     AddPartition(source_builder, "system_b", "test_group_b", 8192, 20480);
1074 
1075     auto target_builder = MetadataBuilder::New(4096 * 50, 40960, 2);
1076     ASSERT_NE(target_builder, nullptr);
1077     ASSERT_TRUE(target_builder->AddGroup("test_group_b", 40960));
1078     AddPartition(target_builder, "system_b", "test_group_b", 8192, 2048);
1079     AddPartition(target_builder, "vendor_b", "test_group_b", 10240, 10240);
1080 
1081     ASSERT_TRUE(MetadataBuilder::VerifyExtentsAgainstSourceMetadata(
1082             *source_builder, 0, *target_builder, 1, std::vector<std::string>{"system", "vendor"}));
1083 
1084     target_builder->RemovePartition("vendor_b");
1085     ASSERT_FALSE(target_builder->VerifyExtentsAgainstSourceMetadata(
1086             *source_builder, 0, *target_builder, 1, std::vector<std::string>{"vendor"}));
1087 
1088     AddPartition(target_builder, "vendor_b", "test_group_b", 1000, 10240);
1089     ASSERT_FALSE(target_builder->VerifyExtentsAgainstSourceMetadata(
1090             *source_builder, 0, *target_builder, 1, std::vector<std::string>{"vendor"}));
1091 }
1092