• 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 <fs_mgr.h>
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 #include <liblp/builder.h>
21 
22 #include "utility.h"
23 
24 using namespace std;
25 using namespace android::fs_mgr;
26 using ::testing::ElementsAre;
27 
28 class Environment : public ::testing::Environment {
29   public:
SetUp()30     void SetUp() override { MetadataBuilder::OverrideABForTesting(false); }
31 };
32 
main(int argc,char ** argv)33 int main(int argc, char** argv) {
34     std::unique_ptr<Environment> env(new Environment);
35     ::testing::AddGlobalTestEnvironment(env.get());
36     ::testing::InitGoogleTest(&argc, argv);
37     return RUN_ALL_TESTS();
38 }
39 
40 class BuilderTest : public ::testing::Test {
41   public:
SetUp()42     void SetUp() override { MetadataBuilder::OverrideABForTesting(false); }
TearDown()43     void TearDown() override { MetadataBuilder::OverrideABForTesting(false); }
44 };
45 
TEST_F(BuilderTest,BuildBasic)46 TEST_F(BuilderTest, BuildBasic) {
47     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
48     ASSERT_NE(builder, nullptr);
49 
50     Partition* partition = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
51     ASSERT_NE(partition, nullptr);
52     EXPECT_EQ(partition->name(), "system");
53     EXPECT_EQ(partition->attributes(), LP_PARTITION_ATTR_READONLY);
54     EXPECT_EQ(partition->size(), 0);
55     EXPECT_EQ(builder->FindPartition("system"), partition);
56 
57     builder->RemovePartition("system");
58     EXPECT_EQ(builder->FindPartition("system"), nullptr);
59 }
60 
TEST_F(BuilderTest,ResizePartition)61 TEST_F(BuilderTest, ResizePartition) {
62     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
63     ASSERT_NE(builder, nullptr);
64 
65     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
66     ASSERT_NE(system, nullptr);
67     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
68     EXPECT_EQ(system->size(), 65536);
69     ASSERT_EQ(system->extents().size(), 1);
70 
71     LinearExtent* extent = system->extents()[0]->AsLinearExtent();
72     ASSERT_NE(extent, nullptr);
73     EXPECT_EQ(extent->num_sectors(), 65536 / LP_SECTOR_SIZE);
74     // The first logical sector will be:
75     //      (LP_PARTITION_RESERVED_BYTES + 4096*2 + 1024*4) / 512
76     // Or, in terms of sectors (reserved + geometry + metadata):
77     //      (8 + 16 + 8) = 32
78     EXPECT_EQ(extent->physical_sector(), 32);
79 
80     // Test resizing to the same size.
81     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
82     EXPECT_EQ(system->size(), 65536);
83     EXPECT_EQ(system->extents().size(), 1);
84     EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
85     // Test resizing to a smaller size.
86     EXPECT_EQ(builder->ResizePartition(system, 0), true);
87     EXPECT_EQ(system->size(), 0);
88     EXPECT_EQ(system->extents().size(), 0);
89     // Test resizing to a greater size.
90     builder->ResizePartition(system, 131072);
91     EXPECT_EQ(system->size(), 131072);
92     EXPECT_EQ(system->extents().size(), 1);
93     EXPECT_EQ(system->extents()[0]->num_sectors(), 131072 / LP_SECTOR_SIZE);
94     // Test resizing again, that the extents are merged together.
95     builder->ResizePartition(system, 1024 * 256);
96     EXPECT_EQ(system->size(), 1024 * 256);
97     EXPECT_EQ(system->extents().size(), 1);
98     EXPECT_EQ(system->extents()[0]->num_sectors(), (1024 * 256) / LP_SECTOR_SIZE);
99 
100     // Test shrinking within the same extent.
101     builder->ResizePartition(system, 32768);
102     EXPECT_EQ(system->size(), 32768);
103     EXPECT_EQ(system->extents().size(), 1);
104     extent = system->extents()[0]->AsLinearExtent();
105     ASSERT_NE(extent, nullptr);
106     EXPECT_EQ(extent->num_sectors(), 32768 / LP_SECTOR_SIZE);
107     EXPECT_EQ(extent->physical_sector(), 32);
108 
109     // Test shrinking to 0.
110     builder->ResizePartition(system, 0);
111     EXPECT_EQ(system->size(), 0);
112     EXPECT_EQ(system->extents().size(), 0);
113 }
114 
TEST_F(BuilderTest,PartitionAlignment)115 TEST_F(BuilderTest, PartitionAlignment) {
116     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
117     ASSERT_NE(builder, nullptr);
118 
119     // Test that we align up to one sector.
120     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
121     ASSERT_NE(system, nullptr);
122     EXPECT_EQ(builder->ResizePartition(system, 10000), true);
123     EXPECT_EQ(system->size(), 12288);
124     EXPECT_EQ(system->extents().size(), 1);
125 
126     builder->ResizePartition(system, 7000);
127     EXPECT_EQ(system->size(), 8192);
128     EXPECT_EQ(system->extents().size(), 1);
129 }
130 
TEST_F(BuilderTest,DiskAlignment)131 TEST_F(BuilderTest, DiskAlignment) {
132     static const uint64_t kDiskSize = 1000000;
133     static const uint32_t kMetadataSize = 1024;
134     static const uint32_t kMetadataSlots = 2;
135 
136     unique_ptr<MetadataBuilder> builder =
137             MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
138     ASSERT_EQ(builder, nullptr);
139 }
140 
TEST_F(BuilderTest,MetadataAlignment)141 TEST_F(BuilderTest, MetadataAlignment) {
142     // Make sure metadata sizes get aligned up.
143     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1000, 2);
144     ASSERT_NE(builder, nullptr);
145     unique_ptr<LpMetadata> exported = builder->Export();
146     ASSERT_NE(exported, nullptr);
147     EXPECT_EQ(exported->geometry.metadata_max_size, 1024);
148 }
149 
TEST_F(BuilderTest,InternalAlignment)150 TEST_F(BuilderTest, InternalAlignment) {
151     // Test the metadata fitting within alignment.
152     BlockDeviceInfo device_info("super", 1024 * 1024, 768 * 1024, 0, 4096);
153     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 2);
154     ASSERT_NE(builder, nullptr);
155     unique_ptr<LpMetadata> exported = builder->Export();
156     ASSERT_NE(exported, nullptr);
157     auto super_device = GetMetadataSuperBlockDevice(*exported.get());
158     ASSERT_NE(super_device, nullptr);
159     EXPECT_EQ(super_device->first_logical_sector, 1536);
160 
161     // Test a large alignment offset thrown in.
162     device_info.alignment_offset = 753664;
163     builder = MetadataBuilder::New(device_info, 1024, 2);
164     ASSERT_NE(builder, nullptr);
165     exported = builder->Export();
166     ASSERT_NE(exported, nullptr);
167     super_device = GetMetadataSuperBlockDevice(*exported.get());
168     ASSERT_NE(super_device, nullptr);
169     EXPECT_EQ(super_device->first_logical_sector, 1472);
170 
171     // Alignment offset without alignment doesn't mean anything.
172     device_info.alignment = 0;
173     builder = MetadataBuilder::New(device_info, 1024, 2);
174     ASSERT_EQ(builder, nullptr);
175 
176     // Test a small alignment with an alignment offset.
177     device_info.alignment = 12 * 1024;
178     device_info.alignment_offset = 3 * 1024;
179     builder = MetadataBuilder::New(device_info, 16 * 1024, 2);
180     ASSERT_NE(builder, nullptr);
181     exported = builder->Export();
182     ASSERT_NE(exported, nullptr);
183     super_device = GetMetadataSuperBlockDevice(*exported.get());
184     ASSERT_NE(super_device, nullptr);
185     EXPECT_EQ(super_device->first_logical_sector, 174);
186 
187     // Test a small alignment with no alignment offset.
188     device_info.alignment = 11 * 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, 160);
196 }
197 
TEST_F(BuilderTest,InternalPartitionAlignment)198 TEST_F(BuilderTest, InternalPartitionAlignment) {
199     BlockDeviceInfo device_info("super", 512 * 1024 * 1024, 768 * 1024, 753664, 4096);
200     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 32 * 1024, 2);
201 
202     Partition* a = builder->AddPartition("a", 0);
203     ASSERT_NE(a, nullptr);
204     Partition* b = builder->AddPartition("b", 0);
205     ASSERT_NE(b, nullptr);
206 
207     // Add a bunch of small extents to each, interleaving.
208     for (size_t i = 0; i < 10; i++) {
209         ASSERT_TRUE(builder->ResizePartition(a, a->size() + 4096));
210         ASSERT_TRUE(builder->ResizePartition(b, b->size() + 4096));
211     }
212     EXPECT_EQ(a->size(), 40960);
213     EXPECT_EQ(b->size(), 40960);
214 
215     unique_ptr<LpMetadata> exported = builder->Export();
216     ASSERT_NE(exported, nullptr);
217 
218     // Check that each starting sector is aligned.
219     for (const auto& extent : exported->extents) {
220         ASSERT_EQ(extent.target_type, LP_TARGET_TYPE_LINEAR);
221         EXPECT_EQ(extent.num_sectors, 80);
222 
223         uint64_t lba = extent.target_data * LP_SECTOR_SIZE;
224         uint64_t aligned_lba = AlignTo(lba, device_info.alignment, device_info.alignment_offset);
225         EXPECT_EQ(lba, aligned_lba);
226     }
227 
228     // Sanity check one extent.
229     EXPECT_EQ(exported->extents.back().target_data, 3008);
230 }
231 
TEST_F(BuilderTest,UseAllDiskSpace)232 TEST_F(BuilderTest, UseAllDiskSpace) {
233     static constexpr uint64_t total = 1024 * 1024;
234     static constexpr uint64_t metadata = 1024;
235     static constexpr uint64_t slots = 2;
236     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(total, metadata, slots);
237     // We reserve a geometry block (4KB) plus space for each copy of the
238     // maximum size of a metadata blob. Then, we double that space since
239     // we store a backup copy of everything.
240     static constexpr uint64_t geometry = 4 * 1024;
241     static constexpr uint64_t allocatable =
242             total - (metadata * slots + geometry) * 2 - LP_PARTITION_RESERVED_BYTES;
243     EXPECT_EQ(builder->AllocatableSpace(), allocatable);
244     EXPECT_EQ(builder->UsedSpace(), 0);
245 
246     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
247     ASSERT_NE(system, nullptr);
248     EXPECT_EQ(builder->ResizePartition(system, allocatable), true);
249     EXPECT_EQ(system->size(), allocatable);
250     EXPECT_EQ(builder->UsedSpace(), allocatable);
251     EXPECT_EQ(builder->AllocatableSpace(), allocatable);
252     EXPECT_EQ(builder->ResizePartition(system, allocatable + 1), false);
253     EXPECT_EQ(system->size(), allocatable);
254     EXPECT_EQ(builder->UsedSpace(), allocatable);
255     EXPECT_EQ(builder->AllocatableSpace(), allocatable);
256 }
257 
TEST_F(BuilderTest,BuildComplex)258 TEST_F(BuilderTest, BuildComplex) {
259     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
260 
261     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
262     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
263     ASSERT_NE(system, nullptr);
264     ASSERT_NE(vendor, nullptr);
265     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
266     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
267     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
268     EXPECT_EQ(system->size(), 98304);
269     EXPECT_EQ(vendor->size(), 32768);
270 
271     // We now expect to have 3 extents total: 2 for system, 1 for vendor, since
272     // our allocation strategy is greedy/first-fit.
273     ASSERT_EQ(system->extents().size(), 2);
274     ASSERT_EQ(vendor->extents().size(), 1);
275 
276     LinearExtent* system1 = system->extents()[0]->AsLinearExtent();
277     LinearExtent* system2 = system->extents()[1]->AsLinearExtent();
278     LinearExtent* vendor1 = vendor->extents()[0]->AsLinearExtent();
279     ASSERT_NE(system1, nullptr);
280     ASSERT_NE(system2, nullptr);
281     ASSERT_NE(vendor1, nullptr);
282     EXPECT_EQ(system1->num_sectors(), 65536 / LP_SECTOR_SIZE);
283     EXPECT_EQ(system1->physical_sector(), 32);
284     EXPECT_EQ(system2->num_sectors(), 32768 / LP_SECTOR_SIZE);
285     EXPECT_EQ(system2->physical_sector(), 224);
286     EXPECT_EQ(vendor1->num_sectors(), 32768 / LP_SECTOR_SIZE);
287     EXPECT_EQ(vendor1->physical_sector(), 160);
288     EXPECT_EQ(system1->physical_sector() + system1->num_sectors(), vendor1->physical_sector());
289     EXPECT_EQ(vendor1->physical_sector() + vendor1->num_sectors(), system2->physical_sector());
290 }
291 
TEST_F(BuilderTest,AddInvalidPartition)292 TEST_F(BuilderTest, AddInvalidPartition) {
293     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
294 
295     Partition* partition = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
296     ASSERT_NE(partition, nullptr);
297 
298     // Duplicate name.
299     partition = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
300     EXPECT_EQ(partition, nullptr);
301 
302     // Empty name.
303     partition = builder->AddPartition("", LP_PARTITION_ATTR_READONLY);
304     EXPECT_EQ(partition, nullptr);
305 }
306 
TEST_F(BuilderTest,BuilderExport)307 TEST_F(BuilderTest, BuilderExport) {
308     static const uint64_t kDiskSize = 1024 * 1024;
309     static const uint32_t kMetadataSize = 1024;
310     static const uint32_t kMetadataSlots = 2;
311     unique_ptr<MetadataBuilder> builder =
312             MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
313 
314     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
315     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
316     ASSERT_NE(system, nullptr);
317     ASSERT_NE(vendor, nullptr);
318     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
319     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
320     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
321 
322     unique_ptr<LpMetadata> exported = builder->Export();
323     EXPECT_NE(exported, nullptr);
324 
325     auto super_device = GetMetadataSuperBlockDevice(*exported.get());
326     ASSERT_NE(super_device, nullptr);
327 
328     // Verify geometry. Some details of this may change if we change the
329     // metadata structures. So in addition to checking the exact values, we
330     // also check that they are internally consistent after.
331     const LpMetadataGeometry& geometry = exported->geometry;
332     EXPECT_EQ(geometry.magic, LP_METADATA_GEOMETRY_MAGIC);
333     EXPECT_EQ(geometry.struct_size, sizeof(geometry));
334     EXPECT_EQ(geometry.metadata_max_size, 1024);
335     EXPECT_EQ(geometry.metadata_slot_count, 2);
336     EXPECT_EQ(super_device->first_logical_sector, 32);
337 
338     static const size_t kMetadataSpace =
339             ((kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE) * 2;
340     EXPECT_GE(super_device->first_logical_sector * LP_SECTOR_SIZE, kMetadataSpace);
341 
342     // Verify header.
343     const LpMetadataHeader& header = exported->header;
344     EXPECT_EQ(header.magic, LP_METADATA_HEADER_MAGIC);
345     EXPECT_EQ(header.major_version, LP_METADATA_MAJOR_VERSION);
346     EXPECT_EQ(header.minor_version, LP_METADATA_MINOR_VERSION);
347 
348     ASSERT_EQ(exported->partitions.size(), 2);
349     ASSERT_EQ(exported->extents.size(), 3);
350 
351     for (const auto& partition : exported->partitions) {
352         Partition* original = builder->FindPartition(GetPartitionName(partition));
353         ASSERT_NE(original, nullptr);
354         for (size_t i = 0; i < partition.num_extents; i++) {
355             const auto& extent = exported->extents[partition.first_extent_index + i];
356             LinearExtent* original_extent = original->extents()[i]->AsLinearExtent();
357             EXPECT_EQ(extent.num_sectors, original_extent->num_sectors());
358             EXPECT_EQ(extent.target_type, LP_TARGET_TYPE_LINEAR);
359             EXPECT_EQ(extent.target_data, original_extent->physical_sector());
360         }
361         EXPECT_EQ(partition.attributes, original->attributes());
362     }
363 }
364 
TEST_F(BuilderTest,BuilderImport)365 TEST_F(BuilderTest, BuilderImport) {
366     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
367 
368     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
369     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
370     ASSERT_NE(system, nullptr);
371     ASSERT_NE(vendor, nullptr);
372     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
373     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
374     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
375 
376     unique_ptr<LpMetadata> exported = builder->Export();
377     ASSERT_NE(exported, nullptr);
378 
379     builder = MetadataBuilder::New(*exported.get());
380     ASSERT_NE(builder, nullptr);
381     system = builder->FindPartition("system");
382     ASSERT_NE(system, nullptr);
383     vendor = builder->FindPartition("vendor");
384     ASSERT_NE(vendor, nullptr);
385 
386     EXPECT_EQ(system->size(), 98304);
387     ASSERT_EQ(system->extents().size(), 2);
388     EXPECT_EQ(system->attributes(), LP_PARTITION_ATTR_READONLY);
389     EXPECT_EQ(vendor->size(), 32768);
390     ASSERT_EQ(vendor->extents().size(), 1);
391     EXPECT_EQ(vendor->attributes(), LP_PARTITION_ATTR_READONLY);
392 
393     LinearExtent* system1 = system->extents()[0]->AsLinearExtent();
394     LinearExtent* system2 = system->extents()[1]->AsLinearExtent();
395     LinearExtent* vendor1 = vendor->extents()[0]->AsLinearExtent();
396     EXPECT_EQ(system1->num_sectors(), 65536 / LP_SECTOR_SIZE);
397     EXPECT_EQ(system1->physical_sector(), 32);
398     EXPECT_EQ(system2->num_sectors(), 32768 / LP_SECTOR_SIZE);
399     EXPECT_EQ(system2->physical_sector(), 224);
400     EXPECT_EQ(vendor1->num_sectors(), 32768 / LP_SECTOR_SIZE);
401 }
402 
TEST_F(BuilderTest,ExportNameTooLong)403 TEST_F(BuilderTest, ExportNameTooLong) {
404     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
405 
406     std::string name = "abcdefghijklmnopqrstuvwxyz0123456789";
407     Partition* system = builder->AddPartition(name + name, LP_PARTITION_ATTR_READONLY);
408     EXPECT_NE(system, nullptr);
409 
410     unique_ptr<LpMetadata> exported = builder->Export();
411     EXPECT_EQ(exported, nullptr);
412 }
413 
TEST_F(BuilderTest,MetadataTooLarge)414 TEST_F(BuilderTest, MetadataTooLarge) {
415     static const size_t kDiskSize = 128 * 1024;
416     static const size_t kMetadataSize = 64 * 1024;
417 
418     // No space to store metadata + geometry.
419     BlockDeviceInfo device_info("super", kDiskSize, 0, 0, 4096);
420     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
421     EXPECT_EQ(builder, nullptr);
422 
423     // No space to store metadata + geometry + one free sector.
424     device_info.size += LP_PARTITION_RESERVED_BYTES + (LP_METADATA_GEOMETRY_SIZE * 2);
425     builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
426     EXPECT_EQ(builder, nullptr);
427 
428     // Space for metadata + geometry + one free block.
429     device_info.size += device_info.logical_block_size;
430     builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
431     EXPECT_NE(builder, nullptr);
432 
433     // Test with alignment.
434     device_info.alignment = 131072;
435     builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
436     EXPECT_EQ(builder, nullptr);
437 
438     device_info.alignment = 0;
439     device_info.alignment_offset = 32768 - LP_SECTOR_SIZE;
440     builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
441     EXPECT_EQ(builder, nullptr);
442 }
443 
TEST_F(BuilderTest,block_device_info)444 TEST_F(BuilderTest, block_device_info) {
445     PartitionOpener opener;
446 
447     BlockDeviceInfo device_info;
448     ASSERT_TRUE(opener.GetInfo(fs_mgr_get_super_partition_name(), &device_info));
449 
450     // Sanity check that the device doesn't give us some weird inefficient
451     // alignment.
452     ASSERT_EQ(device_info.alignment % LP_SECTOR_SIZE, 0);
453     ASSERT_EQ(device_info.alignment_offset % LP_SECTOR_SIZE, 0);
454     ASSERT_LE(device_info.alignment_offset, INT_MAX);
455     ASSERT_EQ(device_info.logical_block_size % LP_SECTOR_SIZE, 0);
456 
457     // Having an alignment offset > alignment doesn't really make sense.
458     ASSERT_LT(device_info.alignment_offset, device_info.alignment);
459 }
460 
TEST_F(BuilderTest,UpdateBlockDeviceInfo)461 TEST_F(BuilderTest, UpdateBlockDeviceInfo) {
462     BlockDeviceInfo device_info("super", 1024 * 1024, 4096, 1024, 4096);
463     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
464     ASSERT_NE(builder, nullptr);
465 
466     BlockDeviceInfo new_info;
467     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
468 
469     EXPECT_EQ(new_info.size, device_info.size);
470     EXPECT_EQ(new_info.alignment, device_info.alignment);
471     EXPECT_EQ(new_info.alignment_offset, device_info.alignment_offset);
472     EXPECT_EQ(new_info.logical_block_size, device_info.logical_block_size);
473 
474     device_info.alignment = 0;
475     device_info.alignment_offset = 2048;
476     ASSERT_TRUE(builder->UpdateBlockDeviceInfo("super", device_info));
477     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
478     EXPECT_EQ(new_info.alignment, 4096);
479     EXPECT_EQ(new_info.alignment_offset, device_info.alignment_offset);
480 
481     device_info.alignment = 8192;
482     device_info.alignment_offset = 0;
483     ASSERT_TRUE(builder->UpdateBlockDeviceInfo("super", device_info));
484     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
485     EXPECT_EQ(new_info.alignment, 8192);
486     EXPECT_EQ(new_info.alignment_offset, 2048);
487 
488     new_info.size += 4096;
489     ASSERT_FALSE(builder->UpdateBlockDeviceInfo("super", new_info));
490     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
491     EXPECT_EQ(new_info.size, 1024 * 1024);
492 
493     new_info.logical_block_size = 512;
494     ASSERT_TRUE(builder->UpdateBlockDeviceInfo("super", new_info));
495     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
496     EXPECT_EQ(new_info.logical_block_size, 4096);
497 
498     new_info.logical_block_size = 7;
499     ASSERT_FALSE(builder->UpdateBlockDeviceInfo("super", new_info));
500     ASSERT_TRUE(builder->GetBlockDeviceInfo("super", &new_info));
501     EXPECT_EQ(new_info.logical_block_size, 4096);
502 }
503 
TEST_F(BuilderTest,InvalidBlockSize)504 TEST_F(BuilderTest, InvalidBlockSize) {
505     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 513);
506     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
507     EXPECT_EQ(builder, nullptr);
508 }
509 
TEST_F(BuilderTest,AlignedExtentSize)510 TEST_F(BuilderTest, AlignedExtentSize) {
511     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
512     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
513     ASSERT_NE(builder, nullptr);
514 
515     Partition* partition = builder->AddPartition("system", 0);
516     ASSERT_NE(partition, nullptr);
517     ASSERT_TRUE(builder->ResizePartition(partition, 512));
518     EXPECT_EQ(partition->size(), 4096);
519 }
520 
TEST_F(BuilderTest,AlignedFreeSpace)521 TEST_F(BuilderTest, AlignedFreeSpace) {
522     // Only one sector free - at least one block is required.
523     BlockDeviceInfo device_info("super", 10240, 0, 0, 4096);
524     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 512, 1);
525     ASSERT_EQ(builder, nullptr);
526 }
527 
TEST_F(BuilderTest,HasDefaultGroup)528 TEST_F(BuilderTest, HasDefaultGroup) {
529     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
530     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
531     ASSERT_NE(builder, nullptr);
532 
533     EXPECT_FALSE(builder->AddGroup("default", 0));
534 }
535 
TEST_F(BuilderTest,GroupSizeLimits)536 TEST_F(BuilderTest, GroupSizeLimits) {
537     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
538     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
539     ASSERT_NE(builder, nullptr);
540 
541     ASSERT_TRUE(builder->AddGroup("google", 16384));
542 
543     Partition* partition = builder->AddPartition("system", "google", 0);
544     ASSERT_NE(partition, nullptr);
545     EXPECT_TRUE(builder->ResizePartition(partition, 8192));
546     EXPECT_EQ(partition->size(), 8192);
547     EXPECT_TRUE(builder->ResizePartition(partition, 16384));
548     EXPECT_EQ(partition->size(), 16384);
549     EXPECT_FALSE(builder->ResizePartition(partition, 32768));
550     EXPECT_EQ(partition->size(), 16384);
551 }
552 
TEST_F(BuilderTest,ListPartitionsInGroup)553 TEST_F(BuilderTest, ListPartitionsInGroup) {
554     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
555     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
556     ASSERT_NE(builder, nullptr);
557 
558     ASSERT_TRUE(builder->AddGroup("groupA", 16384));
559     ASSERT_TRUE(builder->AddGroup("groupB", 16384));
560 
561     Partition* system = builder->AddPartition("system", "groupA", 0);
562     Partition* vendor = builder->AddPartition("vendor", "groupA", 0);
563     Partition* product = builder->AddPartition("product", "groupB", 0);
564     ASSERT_NE(system, nullptr);
565     ASSERT_NE(vendor, nullptr);
566     ASSERT_NE(product, nullptr);
567 
568     auto groupA = builder->ListPartitionsInGroup("groupA");
569     auto groupB = builder->ListPartitionsInGroup("groupB");
570     auto groupC = builder->ListPartitionsInGroup("groupC");
571     ASSERT_THAT(groupA, ElementsAre(system, vendor));
572     ASSERT_THAT(groupB, ElementsAre(product));
573     ASSERT_TRUE(groupC.empty());
574 }
575 
TEST_F(BuilderTest,ChangeGroups)576 TEST_F(BuilderTest, ChangeGroups) {
577     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
578     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
579     ASSERT_NE(builder, nullptr);
580 
581     ASSERT_TRUE(builder->AddGroup("groupA", 16384));
582     ASSERT_TRUE(builder->AddGroup("groupB", 32768));
583 
584     Partition* system = builder->AddPartition("system", "groupA", 0);
585     Partition* vendor = builder->AddPartition("vendor", "groupB", 0);
586     ASSERT_NE(system, nullptr);
587     ASSERT_NE(vendor, nullptr);
588     ASSERT_NE(builder->Export(), nullptr);
589 
590     ASSERT_FALSE(builder->ChangePartitionGroup(system, "groupXYZ"));
591     ASSERT_TRUE(builder->ChangePartitionGroup(system, "groupB"));
592     ASSERT_NE(builder->Export(), nullptr);
593 
594     // Violate group constraint by reassigning groups.
595     ASSERT_TRUE(builder->ResizePartition(system, 16384 + 4096));
596     ASSERT_TRUE(builder->ChangePartitionGroup(system, "groupA"));
597     ASSERT_EQ(builder->Export(), nullptr);
598 
599     ASSERT_FALSE(builder->ChangeGroupSize("default", 2));
600     ASSERT_FALSE(builder->ChangeGroupSize("unknown", 2));
601     ASSERT_TRUE(builder->ChangeGroupSize("groupA", 32768));
602     ASSERT_NE(builder->Export(), nullptr);
603 }
604 
operator ""_GiB(unsigned long long x)605 constexpr unsigned long long operator"" _GiB(unsigned long long x) {  // NOLINT
606     return x << 30;
607 }
operator ""_MiB(unsigned long long x)608 constexpr unsigned long long operator"" _MiB(unsigned long long x) {  // NOLINT
609     return x << 20;
610 }
611 
TEST_F(BuilderTest,RemoveAndAddFirstPartition)612 TEST_F(BuilderTest, RemoveAndAddFirstPartition) {
613     auto builder = MetadataBuilder::New(10_GiB, 65536, 2);
614     ASSERT_NE(nullptr, builder);
615     ASSERT_TRUE(builder->AddGroup("foo_a", 5_GiB));
616     ASSERT_TRUE(builder->AddGroup("foo_b", 5_GiB));
617     android::fs_mgr::Partition* p;
618     p = builder->AddPartition("system_a", "foo_a", 0);
619     ASSERT_TRUE(p && builder->ResizePartition(p, 2_GiB));
620     p = builder->AddPartition("vendor_a", "foo_a", 0);
621     ASSERT_TRUE(p && builder->ResizePartition(p, 1_GiB));
622     p = builder->AddPartition("system_b", "foo_b", 0);
623     ASSERT_TRUE(p && builder->ResizePartition(p, 2_GiB));
624     p = builder->AddPartition("vendor_b", "foo_b", 0);
625     ASSERT_TRUE(p && builder->ResizePartition(p, 1_GiB));
626 
627     builder->RemovePartition("system_a");
628     builder->RemovePartition("vendor_a");
629     p = builder->AddPartition("system_a", "foo_a", 0);
630     ASSERT_TRUE(p && builder->ResizePartition(p, 3_GiB));
631     p = builder->AddPartition("vendor_a", "foo_a", 0);
632     ASSERT_TRUE(p && builder->ResizePartition(p, 1_GiB));
633 }
634 
TEST_F(BuilderTest,ListGroups)635 TEST_F(BuilderTest, ListGroups) {
636     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
637     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
638     ASSERT_NE(builder, nullptr);
639     ASSERT_TRUE(builder->AddGroup("example", 0));
640 
641     std::vector<std::string> groups = builder->ListGroups();
642     ASSERT_THAT(groups, ElementsAre("default", "example"));
643 }
644 
TEST_F(BuilderTest,RemoveGroupAndPartitions)645 TEST_F(BuilderTest, RemoveGroupAndPartitions) {
646     BlockDeviceInfo device_info("super", 1024 * 1024, 0, 0, 4096);
647     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
648     ASSERT_NE(builder, nullptr);
649     ASSERT_TRUE(builder->AddGroup("example", 0));
650     ASSERT_NE(builder->AddPartition("system", "default", 0), nullptr);
651     ASSERT_NE(builder->AddPartition("vendor", "example", 0), nullptr);
652 
653     builder->RemoveGroupAndPartitions("example");
654     ASSERT_NE(builder->FindPartition("system"), nullptr);
655     ASSERT_EQ(builder->FindPartition("vendor"), nullptr);
656     ASSERT_THAT(builder->ListGroups(), ElementsAre("default"));
657 
658     builder->RemoveGroupAndPartitions("default");
659     ASSERT_NE(builder->FindPartition("system"), nullptr);
660 }
661 
TEST_F(BuilderTest,MultipleBlockDevices)662 TEST_F(BuilderTest, MultipleBlockDevices) {
663     std::vector<BlockDeviceInfo> partitions = {
664             BlockDeviceInfo("system_a", 256_MiB, 786432, 229376, 4096),
665             BlockDeviceInfo("vendor_a", 128_MiB, 786432, 753664, 4096),
666             BlockDeviceInfo("product_a", 64_MiB, 786432, 753664, 4096),
667     };
668     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(partitions, "system_a", 65536, 2);
669     ASSERT_NE(builder, nullptr);
670     EXPECT_EQ(builder->AllocatableSpace(), 467238912);
671 
672     // Create a partition that spans 3 devices.
673     Partition* p = builder->AddPartition("system_a", 0);
674     ASSERT_NE(p, nullptr);
675     ASSERT_TRUE(builder->ResizePartition(p, 466976768));
676 
677     unique_ptr<LpMetadata> metadata = builder->Export();
678     ASSERT_NE(metadata, nullptr);
679     ASSERT_EQ(metadata->block_devices.size(), 3);
680     EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[0]), "system_a");
681     EXPECT_EQ(metadata->block_devices[0].size, 256_MiB);
682     EXPECT_EQ(metadata->block_devices[0].alignment, 786432);
683     EXPECT_EQ(metadata->block_devices[0].alignment_offset, 229376);
684     EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[1]), "vendor_a");
685     EXPECT_EQ(metadata->block_devices[1].size, 128_MiB);
686     EXPECT_EQ(metadata->block_devices[1].alignment, 786432);
687     EXPECT_EQ(metadata->block_devices[1].alignment_offset, 753664);
688     EXPECT_EQ(GetBlockDevicePartitionName(metadata->block_devices[2]), "product_a");
689     EXPECT_EQ(metadata->block_devices[2].size, 64_MiB);
690     EXPECT_EQ(metadata->block_devices[2].alignment, 786432);
691     EXPECT_EQ(metadata->block_devices[2].alignment_offset, 753664);
692     ASSERT_EQ(metadata->extents.size(), 3);
693     EXPECT_EQ(metadata->extents[0].num_sectors, 522304);
694     EXPECT_EQ(metadata->extents[0].target_type, LP_TARGET_TYPE_LINEAR);
695     EXPECT_EQ(metadata->extents[0].target_data, 1984);
696     EXPECT_EQ(metadata->extents[0].target_source, 0);
697     EXPECT_EQ(metadata->extents[1].num_sectors, 260672);
698     EXPECT_EQ(metadata->extents[1].target_type, LP_TARGET_TYPE_LINEAR);
699     EXPECT_EQ(metadata->extents[1].target_data, 1472);
700     EXPECT_EQ(metadata->extents[1].target_source, 1);
701     EXPECT_EQ(metadata->extents[2].num_sectors, 129088);
702     EXPECT_EQ(metadata->extents[2].target_type, LP_TARGET_TYPE_LINEAR);
703     EXPECT_EQ(metadata->extents[2].target_data, 1472);
704     EXPECT_EQ(metadata->extents[2].target_source, 2);
705 }
706 
TEST_F(BuilderTest,ImportPartitionsOk)707 TEST_F(BuilderTest, ImportPartitionsOk) {
708     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
709     ASSERT_NE(builder, nullptr);
710 
711     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
712     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
713     ASSERT_NE(system, nullptr);
714     ASSERT_NE(vendor, nullptr);
715     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
716     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
717     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
718 
719     unique_ptr<LpMetadata> exported = builder->Export();
720     ASSERT_NE(exported, nullptr);
721 
722     builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
723     ASSERT_NE(builder, nullptr);
724 
725     ASSERT_TRUE(builder->ImportPartitions(*exported.get(), {"vendor"}));
726     EXPECT_NE(builder->FindPartition("vendor"), nullptr);
727     EXPECT_EQ(builder->FindPartition("system"), nullptr);
728 
729     unique_ptr<LpMetadata> new_metadata = builder->Export();
730     ASSERT_NE(new_metadata, nullptr);
731 
732     ASSERT_EQ(exported->partitions.size(), static_cast<size_t>(2));
733     ASSERT_EQ(GetPartitionName(exported->partitions[1]), "vendor");
734     ASSERT_EQ(new_metadata->partitions.size(), static_cast<size_t>(1));
735     ASSERT_EQ(GetPartitionName(new_metadata->partitions[0]), "vendor");
736 
737     const LpMetadataExtent& extent_a =
738             exported->extents[exported->partitions[1].first_extent_index];
739     const LpMetadataExtent& extent_b =
740             new_metadata->extents[new_metadata->partitions[0].first_extent_index];
741     EXPECT_EQ(extent_a.num_sectors, extent_b.num_sectors);
742     EXPECT_EQ(extent_a.target_type, extent_b.target_type);
743     EXPECT_EQ(extent_a.target_data, extent_b.target_data);
744     EXPECT_EQ(extent_a.target_source, extent_b.target_source);
745 }
746 
TEST_F(BuilderTest,ImportPartitionsFail)747 TEST_F(BuilderTest, ImportPartitionsFail) {
748     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
749     ASSERT_NE(builder, nullptr);
750 
751     Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
752     Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
753     ASSERT_NE(system, nullptr);
754     ASSERT_NE(vendor, nullptr);
755     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
756     EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
757     EXPECT_EQ(builder->ResizePartition(system, 98304), true);
758 
759     unique_ptr<LpMetadata> exported = builder->Export();
760     ASSERT_NE(exported, nullptr);
761 
762     // Different device size.
763     builder = MetadataBuilder::New(1024 * 2048, 1024, 2);
764     ASSERT_NE(builder, nullptr);
765     EXPECT_FALSE(builder->ImportPartitions(*exported.get(), {"system"}));
766 }
767 
TEST_F(BuilderTest,UnsuffixedPartitions)768 TEST_F(BuilderTest, UnsuffixedPartitions) {
769     MetadataBuilder::OverrideABForTesting(true);
770     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
771     ASSERT_NE(builder, nullptr);
772 
773     ASSERT_EQ(builder->AddPartition("system", 0), nullptr);
774     ASSERT_NE(builder->AddPartition("system_a", 0), nullptr);
775 }
776 
TEST_F(BuilderTest,ABExtents)777 TEST_F(BuilderTest, ABExtents) {
778     BlockDeviceInfo device_info("super", 10_GiB, 768 * 1024, 0, 4096);
779 
780     // A and B slots should be allocated from separate halves of the partition,
781     // to mitigate allocating too many extents. (b/120433288)
782     MetadataBuilder::OverrideABForTesting(true);
783     auto builder = MetadataBuilder::New(device_info, 65536, 2);
784     ASSERT_NE(builder, nullptr);
785     Partition* system_a = builder->AddPartition("system_a", 0);
786     ASSERT_NE(system_a, nullptr);
787     Partition* system_b = builder->AddPartition("system_b", 0);
788     ASSERT_NE(system_b, nullptr);
789     ASSERT_TRUE(builder->ResizePartition(system_a, 2_GiB));
790     ASSERT_TRUE(builder->ResizePartition(system_b, 2_GiB));
791 
792     builder->RemovePartition("system_a");
793     system_a = builder->AddPartition("system_a", 0);
794     ASSERT_NE(system_a, nullptr);
795     ASSERT_TRUE(builder->ResizePartition(system_a, 3_GiB));
796 
797     EXPECT_EQ(system_a->extents().size(), static_cast<size_t>(1));
798     EXPECT_EQ(system_b->extents().size(), static_cast<size_t>(1));
799     ASSERT_TRUE(builder->ResizePartition(system_b, 6_GiB));
800     EXPECT_EQ(system_b->extents().size(), static_cast<size_t>(2));
801 
802     unique_ptr<LpMetadata> exported = builder->Export();
803     ASSERT_NE(exported, nullptr);
804     ASSERT_EQ(exported->extents.size(), static_cast<size_t>(3));
805     EXPECT_EQ(exported->extents[0].target_data, 10487808);
806     EXPECT_EQ(exported->extents[0].num_sectors, 10483712);
807     EXPECT_EQ(exported->extents[1].target_data, 6292992);
808     EXPECT_EQ(exported->extents[1].num_sectors, 2099200);
809     EXPECT_EQ(exported->extents[2].target_data, 1536);
810     EXPECT_EQ(exported->extents[2].num_sectors, 6291456);
811 }
812 
TEST_F(BuilderTest,PartialExtents)813 TEST_F(BuilderTest, PartialExtents) {
814     // super has a minimum extent size of 768KiB.
815     BlockDeviceInfo device_info("super", 1_GiB, 768 * 1024, 0, 4096);
816     auto builder = MetadataBuilder::New(device_info, 65536, 1);
817     ASSERT_NE(builder, nullptr);
818     Partition* system = builder->AddPartition("system", 0);
819     ASSERT_NE(system, nullptr);
820     Partition* vendor = builder->AddPartition("vendor", 0);
821     ASSERT_NE(vendor, nullptr);
822     ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment + 4096));
823     ASSERT_TRUE(builder->ResizePartition(vendor, device_info.alignment));
824     ASSERT_EQ(system->size(), device_info.alignment + 4096);
825     ASSERT_EQ(vendor->size(), device_info.alignment);
826 
827     ASSERT_TRUE(builder->ResizePartition(system, device_info.alignment * 2));
828     ASSERT_EQ(system->extents().size(), static_cast<size_t>(1));
829 
830     unique_ptr<LpMetadata> exported = builder->Export();
831     ASSERT_NE(exported, nullptr);
832     ASSERT_EQ(exported->extents.size(), static_cast<size_t>(2));
833     EXPECT_EQ(exported->extents[0].target_data, 1536);
834     EXPECT_EQ(exported->extents[0].num_sectors, 3072);
835     EXPECT_EQ(exported->extents[1].target_data, 4608);
836     EXPECT_EQ(exported->extents[1].num_sectors, 1536);
837 }
838 
TEST_F(BuilderTest,UpdateSuper)839 TEST_F(BuilderTest, UpdateSuper) {
840     // Build the on-disk metadata that we saw before flashing.
841     auto builder = MetadataBuilder::New(8145338368ULL, 65536, 3);
842     ASSERT_NE(builder, nullptr);
843 
844     ASSERT_TRUE(builder->AddGroup("google_dynamic_partitions_a", 4068474880ULL));
845     ASSERT_TRUE(builder->AddGroup("google_dynamic_partitions_b", 4068474880ULL));
846 
847     Partition* partition = builder->AddPartition("system_a", "google_dynamic_partitions_a",
848                                                  LP_PARTITION_ATTR_READONLY);
849     ASSERT_NE(partition, nullptr);
850     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 1901568, 3608576));
851 
852     partition = builder->AddPartition("vendor_a", "google_dynamic_partitions_a",
853                                       LP_PARTITION_ATTR_READONLY);
854     ASSERT_NE(partition, nullptr);
855     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 1521664, 5510144));
856 
857     partition = builder->AddPartition("product_a", "google_dynamic_partitions_a",
858                                       LP_PARTITION_ATTR_READONLY);
859     ASSERT_NE(partition, nullptr);
860     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 3606528, 2048));
861 
862     partition = builder->AddPartition("system_b", "google_dynamic_partitions_b",
863                                       LP_PARTITION_ATTR_READONLY);
864     ASSERT_NE(partition, nullptr);
865     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 1901568, 7955456));
866 
867     partition = builder->AddPartition("vendor_b", "google_dynamic_partitions_b",
868                                       LP_PARTITION_ATTR_READONLY);
869     ASSERT_NE(partition, nullptr);
870     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 1521664, 9857024));
871 
872     partition = builder->AddPartition("product_b", "google_dynamic_partitions_b",
873                                       LP_PARTITION_ATTR_READONLY);
874     ASSERT_NE(partition, nullptr);
875     ASSERT_TRUE(builder->AddLinearExtent(partition, "super", 3606528, 11378688));
876 
877     auto on_disk = builder->Export();
878     ASSERT_NE(on_disk, nullptr);
879 
880     // Build the super_empty from the new build.
881     builder = MetadataBuilder::New(8145338368ULL, 65536, 3);
882     ASSERT_NE(builder, nullptr);
883 
884     ASSERT_TRUE(builder->AddGroup("google_dynamic_partitions_a", 4068474880ULL));
885     ASSERT_TRUE(builder->AddGroup("google_dynamic_partitions_b", 4068474880ULL));
886     ASSERT_NE(builder->AddPartition("system_a", "google_dynamic_partitions_a",
887                                     LP_PARTITION_ATTR_READONLY),
888               nullptr);
889     ASSERT_NE(builder->AddPartition("system_b", "google_dynamic_partitions_b",
890                                     LP_PARTITION_ATTR_READONLY),
891               nullptr);
892     ASSERT_NE(builder->AddPartition("vendor_a", "google_dynamic_partitions_a",
893                                     LP_PARTITION_ATTR_READONLY),
894               nullptr);
895     ASSERT_NE(builder->AddPartition("vendor_b", "google_dynamic_partitions_b",
896                                     LP_PARTITION_ATTR_READONLY),
897               nullptr);
898     ASSERT_NE(builder->AddPartition("product_a", "google_dynamic_partitions_a",
899                                     LP_PARTITION_ATTR_READONLY),
900               nullptr);
901     ASSERT_NE(builder->AddPartition("product_b", "google_dynamic_partitions_b",
902                                     LP_PARTITION_ATTR_READONLY),
903               nullptr);
904 
905     std::set<std::string> partitions_to_keep{"system_a", "vendor_a", "product_a"};
906     ASSERT_TRUE(builder->ImportPartitions(*on_disk.get(), partitions_to_keep));
907 }
908