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