summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs_mgr/liblp/Android.bp16
-rw-r--r--fs_mgr/liblp/builder.cpp6
-rw-r--r--fs_mgr/liblp/builder_test.cpp308
-rw-r--r--fs_mgr/liblp/include/liblp/builder.h3
-rw-r--r--fs_mgr/liblp/include/liblp/metadata_format.h1
-rw-r--r--fs_mgr/liblp/utility.cpp2
-rw-r--r--fs_mgr/liblp/utility_test.cpp43
7 files changed, 377 insertions, 2 deletions
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index 0ca893883..98f364c22 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -42,3 +42,19 @@ cc_library_static {
42 ], 42 ],
43 export_include_dirs: ["include"], 43 export_include_dirs: ["include"],
44} 44}
45
46cc_test {
47 name: "liblp_test",
48 defaults: ["fs_mgr_defaults"],
49 static_libs: [
50 "libbase",
51 "liblog",
52 "libcrypto",
53 "libcrypto_utils",
54 "liblp",
55 ],
56 srcs: [
57 "builder_test.cpp",
58 "utility_test.cpp",
59 ],
60}
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index a08489322..0e4838c32 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -287,7 +287,7 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t requested_siz
287 DCHECK(first_sector <= geometry_.last_logical_sector); 287 DCHECK(first_sector <= geometry_.last_logical_sector);
288 288
289 // Note: the last usable sector is inclusive. 289 // Note: the last usable sector is inclusive.
290 if (first_sector + sectors_needed > geometry_.last_logical_sector) { 290 if (geometry_.last_logical_sector + 1 - first_sector < sectors_needed) {
291 LERROR << "Not enough free space to expand partition: " << partition->name(); 291 LERROR << "Not enough free space to expand partition: " << partition->name();
292 return false; 292 return false;
293 } 293 }
@@ -347,5 +347,9 @@ std::unique_ptr<LpMetadata> MetadataBuilder::Export() {
347 return metadata; 347 return metadata;
348} 348}
349 349
350uint64_t MetadataBuilder::AllocatableSpace() const {
351 return (geometry_.last_logical_sector - geometry_.first_logical_sector + 1) * LP_SECTOR_SIZE;
352}
353
350} // namespace fs_mgr 354} // namespace fs_mgr
351} // namespace android 355} // namespace android
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
new file mode 100644
index 000000000..c6e70e154
--- /dev/null
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -0,0 +1,308 @@
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 <gtest/gtest.h>
18#include <liblp/builder.h>
19
20using namespace std;
21using namespace android::fs_mgr;
22
23static const char* TEST_GUID = "A799D1D6-669F-41D8-A3F0-EBB7572D8302";
24static const char* TEST_GUID2 = "A799D1D6-669F-41D8-A3F0-EBB7572D8303";
25
26TEST(liblp, BuildBasic) {
27 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
28
29 Partition* partition = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
30 ASSERT_NE(partition, nullptr);
31 EXPECT_EQ(partition->name(), "system");
32 EXPECT_EQ(partition->guid(), TEST_GUID);
33 EXPECT_EQ(partition->attributes(), LP_PARTITION_ATTR_READONLY);
34 EXPECT_EQ(partition->size(), 0);
35 EXPECT_EQ(builder->FindPartition("system"), partition);
36
37 builder->RemovePartition("system");
38 EXPECT_EQ(builder->FindPartition("system"), nullptr);
39}
40
41TEST(liblp, ResizePartition) {
42 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
43
44 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
45 ASSERT_NE(system, nullptr);
46 EXPECT_EQ(builder->GrowPartition(system, 65536), true);
47 EXPECT_EQ(system->size(), 65536);
48 ASSERT_EQ(system->extents().size(), 1);
49
50 LinearExtent* extent = system->extents()[0]->AsLinearExtent();
51 ASSERT_NE(extent, nullptr);
52 EXPECT_EQ(extent->num_sectors(), 65536 / LP_SECTOR_SIZE);
53 // The first logical sector will be (4096+1024*2)/512 = 12.
54 EXPECT_EQ(extent->physical_sector(), 12);
55
56 // Test growing to the same size.
57 EXPECT_EQ(builder->GrowPartition(system, 65536), true);
58 EXPECT_EQ(system->size(), 65536);
59 EXPECT_EQ(system->extents().size(), 1);
60 EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
61 // Test growing to a smaller size.
62 EXPECT_EQ(builder->GrowPartition(system, 0), true);
63 EXPECT_EQ(system->size(), 65536);
64 EXPECT_EQ(system->extents().size(), 1);
65 EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
66 // Test shrinking to a greater size.
67 builder->ShrinkPartition(system, 131072);
68 EXPECT_EQ(system->size(), 65536);
69 EXPECT_EQ(system->extents().size(), 1);
70 EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
71
72 // Test shrinking within the same extent.
73 builder->ShrinkPartition(system, 32768);
74 EXPECT_EQ(system->size(), 32768);
75 EXPECT_EQ(system->extents().size(), 1);
76 extent = system->extents()[0]->AsLinearExtent();
77 ASSERT_NE(extent, nullptr);
78 EXPECT_EQ(extent->num_sectors(), 32768 / LP_SECTOR_SIZE);
79 EXPECT_EQ(extent->physical_sector(), 12);
80
81 // Test shrinking to 0.
82 builder->ShrinkPartition(system, 0);
83 EXPECT_EQ(system->size(), 0);
84 EXPECT_EQ(system->extents().size(), 0);
85}
86
87TEST(liblp, PartitionAlignment) {
88 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
89
90 // Test that we align up to one sector.
91 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
92 ASSERT_NE(system, nullptr);
93 EXPECT_EQ(builder->GrowPartition(system, 10000), true);
94 EXPECT_EQ(system->size(), 10240);
95 EXPECT_EQ(system->extents().size(), 1);
96
97 builder->ShrinkPartition(system, 9000);
98 EXPECT_EQ(system->size(), 9216);
99 EXPECT_EQ(system->extents().size(), 1);
100}
101
102TEST(liblp, DiskAlignment) {
103 static const uint64_t kDiskSize = 1000000;
104 static const uint32_t kMetadataSize = 1024;
105 static const uint32_t kMetadataSlots = 2;
106
107 // If the disk size is not aligned to 512 bytes, make sure it still leaves
108 // space at the end for backup metadata, and that it doesn't overlap with
109 // the space for logical partitions.
110 unique_ptr<MetadataBuilder> builder =
111 MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
112 unique_ptr<LpMetadata> exported = builder->Export();
113 ASSERT_NE(exported, nullptr);
114
115 static const size_t kMetadataSpace =
116 (kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE;
117 uint64_t space_at_end =
118 kDiskSize - (exported->geometry.last_logical_sector + 1) * LP_SECTOR_SIZE;
119 EXPECT_GE(space_at_end, kMetadataSpace);
120}
121
122TEST(liblp, MetadataAlignment) {
123 // Make sure metadata sizes get aligned up.
124 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1000, 2);
125 unique_ptr<LpMetadata> exported = builder->Export();
126 ASSERT_NE(exported, nullptr);
127 EXPECT_EQ(exported->geometry.metadata_max_size, 1024);
128}
129
130TEST(liblp, UseAllDiskSpace) {
131 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
132 EXPECT_EQ(builder->AllocatableSpace(), 1036288);
133
134 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
135 ASSERT_NE(system, nullptr);
136 EXPECT_EQ(builder->GrowPartition(system, 1036288), true);
137 EXPECT_EQ(system->size(), 1036288);
138 EXPECT_EQ(builder->GrowPartition(system, 1036289), false);
139}
140
141TEST(liblp, BuildComplex) {
142 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
143
144 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
145 Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
146 ASSERT_NE(system, nullptr);
147 ASSERT_NE(vendor, nullptr);
148 EXPECT_EQ(builder->GrowPartition(system, 65536), true);
149 EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
150 EXPECT_EQ(builder->GrowPartition(system, 98304), true);
151 EXPECT_EQ(system->size(), 98304);
152 EXPECT_EQ(vendor->size(), 32768);
153
154 // We now expect to have 3 extents total: 2 for system, 1 for vendor, since
155 // our allocation strategy is greedy/first-fit.
156 ASSERT_EQ(system->extents().size(), 2);
157 ASSERT_EQ(vendor->extents().size(), 1);
158
159 LinearExtent* system1 = system->extents()[0]->AsLinearExtent();
160 LinearExtent* system2 = system->extents()[1]->AsLinearExtent();
161 LinearExtent* vendor1 = vendor->extents()[0]->AsLinearExtent();
162 ASSERT_NE(system1, nullptr);
163 ASSERT_NE(system2, nullptr);
164 ASSERT_NE(vendor1, nullptr);
165 EXPECT_EQ(system1->num_sectors(), 65536 / LP_SECTOR_SIZE);
166 EXPECT_EQ(system1->physical_sector(), 12);
167 EXPECT_EQ(system2->num_sectors(), 32768 / LP_SECTOR_SIZE);
168 EXPECT_EQ(system2->physical_sector(), 204);
169 EXPECT_EQ(vendor1->num_sectors(), 32768 / LP_SECTOR_SIZE);
170 EXPECT_EQ(vendor1->physical_sector(), 140);
171 EXPECT_EQ(system1->physical_sector() + system1->num_sectors(), vendor1->physical_sector());
172 EXPECT_EQ(vendor1->physical_sector() + vendor1->num_sectors(), system2->physical_sector());
173}
174
175TEST(liblp, AddInvalidPartition) {
176 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
177
178 Partition* partition = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
179 ASSERT_NE(partition, nullptr);
180
181 // Duplicate name.
182 partition = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
183 EXPECT_EQ(partition, nullptr);
184
185 // Empty name.
186 partition = builder->AddPartition("", TEST_GUID, LP_PARTITION_ATTR_READONLY);
187 EXPECT_EQ(partition, nullptr);
188}
189
190TEST(liblp, BuilderExport) {
191 static const uint64_t kDiskSize = 1024 * 1024;
192 static const uint32_t kMetadataSize = 1024;
193 static const uint32_t kMetadataSlots = 2;
194 unique_ptr<MetadataBuilder> builder =
195 MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
196
197 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
198 Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
199 ASSERT_NE(system, nullptr);
200 ASSERT_NE(vendor, nullptr);
201 EXPECT_EQ(builder->GrowPartition(system, 65536), true);
202 EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
203 EXPECT_EQ(builder->GrowPartition(system, 98304), true);
204
205 unique_ptr<LpMetadata> exported = builder->Export();
206 EXPECT_NE(exported, nullptr);
207
208 // Verify geometry. Some details of this may change if we change the
209 // metadata structures. So in addition to checking the exact values, we
210 // also check that they are internally consistent after.
211 const LpMetadataGeometry& geometry = exported->geometry;
212 EXPECT_EQ(geometry.magic, LP_METADATA_GEOMETRY_MAGIC);
213 EXPECT_EQ(geometry.struct_size, sizeof(geometry));
214 EXPECT_EQ(geometry.metadata_max_size, 1024);
215 EXPECT_EQ(geometry.metadata_slot_count, 2);
216 EXPECT_EQ(geometry.first_logical_sector, 12);
217 EXPECT_EQ(geometry.last_logical_sector, 2035);
218
219 static const size_t kMetadataSpace =
220 (kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE;
221 uint64_t space_at_end = kDiskSize - (geometry.last_logical_sector + 1) * LP_SECTOR_SIZE;
222 EXPECT_GE(space_at_end, kMetadataSpace);
223 EXPECT_GE(geometry.first_logical_sector * LP_SECTOR_SIZE, kMetadataSpace);
224
225 // Verify header.
226 const LpMetadataHeader& header = exported->header;
227 EXPECT_EQ(header.magic, LP_METADATA_HEADER_MAGIC);
228 EXPECT_EQ(header.major_version, LP_METADATA_MAJOR_VERSION);
229 EXPECT_EQ(header.minor_version, LP_METADATA_MINOR_VERSION);
230
231 ASSERT_EQ(exported->partitions.size(), 2);
232 ASSERT_EQ(exported->extents.size(), 3);
233
234 for (const auto& partition : exported->partitions) {
235 Partition* original = builder->FindPartition(GetPartitionName(partition));
236 ASSERT_NE(original, nullptr);
237 EXPECT_EQ(original->guid(), GetPartitionGuid(partition));
238 for (size_t i = 0; i < partition.num_extents; i++) {
239 const auto& extent = exported->extents[partition.first_extent_index + i];
240 LinearExtent* original_extent = original->extents()[i]->AsLinearExtent();
241 EXPECT_EQ(extent.num_sectors, original_extent->num_sectors());
242 EXPECT_EQ(extent.target_type, LP_TARGET_TYPE_LINEAR);
243 EXPECT_EQ(extent.target_data, original_extent->physical_sector());
244 }
245 EXPECT_EQ(partition.attributes, original->attributes());
246 }
247}
248
249TEST(liblp, BuilderImport) {
250 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
251
252 Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
253 Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
254 ASSERT_NE(system, nullptr);
255 ASSERT_NE(vendor, nullptr);
256 EXPECT_EQ(builder->GrowPartition(system, 65536), true);
257 EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
258 EXPECT_EQ(builder->GrowPartition(system, 98304), true);
259
260 unique_ptr<LpMetadata> exported = builder->Export();
261 ASSERT_NE(exported, nullptr);
262
263 builder = MetadataBuilder::New(*exported.get());
264 ASSERT_NE(builder, nullptr);
265 system = builder->FindPartition("system");
266 ASSERT_NE(system, nullptr);
267 vendor = builder->FindPartition("vendor");
268 ASSERT_NE(vendor, nullptr);
269
270 EXPECT_EQ(system->size(), 98304);
271 ASSERT_EQ(system->extents().size(), 2);
272 EXPECT_EQ(system->guid(), TEST_GUID);
273 EXPECT_EQ(system->attributes(), LP_PARTITION_ATTR_READONLY);
274 EXPECT_EQ(vendor->size(), 32768);
275 ASSERT_EQ(vendor->extents().size(), 1);
276 EXPECT_EQ(vendor->guid(), TEST_GUID2);
277 EXPECT_EQ(vendor->attributes(), LP_PARTITION_ATTR_READONLY);
278
279 LinearExtent* system1 = system->extents()[0]->AsLinearExtent();
280 LinearExtent* system2 = system->extents()[1]->AsLinearExtent();
281 LinearExtent* vendor1 = vendor->extents()[0]->AsLinearExtent();
282 EXPECT_EQ(system1->num_sectors(), 65536 / LP_SECTOR_SIZE);
283 EXPECT_EQ(system1->physical_sector(), 12);
284 EXPECT_EQ(system2->num_sectors(), 32768 / LP_SECTOR_SIZE);
285 EXPECT_EQ(system2->physical_sector(), 204);
286 EXPECT_EQ(vendor1->num_sectors(), 32768 / LP_SECTOR_SIZE);
287}
288
289TEST(liblp, ExportNameTooLong) {
290 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
291
292 std::string name = "abcdefghijklmnopqrstuvwxyz0123456789";
293 Partition* system = builder->AddPartition(name + name, TEST_GUID, LP_PARTITION_ATTR_READONLY);
294 EXPECT_NE(system, nullptr);
295
296 unique_ptr<LpMetadata> exported = builder->Export();
297 EXPECT_EQ(exported, nullptr);
298}
299
300TEST(liblp, ExportInvalidGuid) {
301 unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
302
303 Partition* system = builder->AddPartition("system", "bad", LP_PARTITION_ATTR_READONLY);
304 EXPECT_NE(system, nullptr);
305
306 unique_ptr<LpMetadata> exported = builder->Export();
307 EXPECT_EQ(exported, nullptr);
308}
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index fb982e27a..671a3bd2b 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -153,6 +153,9 @@ class MetadataBuilder {
153 // underlying filesystem or contents of the partition on disk. 153 // underlying filesystem or contents of the partition on disk.
154 void ShrinkPartition(Partition* partition, uint64_t requested_size); 154 void ShrinkPartition(Partition* partition, uint64_t requested_size);
155 155
156 // Amount of space that can be allocated to logical partitions.
157 uint64_t AllocatableSpace() const;
158
156 private: 159 private:
157 MetadataBuilder(); 160 MetadataBuilder();
158 bool Init(uint64_t blockdevice_size, uint32_t metadata_max_size, uint32_t metadata_slot_count); 161 bool Init(uint64_t blockdevice_size, uint32_t metadata_max_size, uint32_t metadata_slot_count);
diff --git a/fs_mgr/liblp/include/liblp/metadata_format.h b/fs_mgr/liblp/include/liblp/metadata_format.h
index 6a2c65583..85224352e 100644
--- a/fs_mgr/liblp/include/liblp/metadata_format.h
+++ b/fs_mgr/liblp/include/liblp/metadata_format.h
@@ -46,6 +46,7 @@ extern "C" {
46 * READONLY - The partition should not be considered writable. When used with 46 * READONLY - The partition should not be considered writable. When used with
47 * device mapper, the block device will be created as read-only. 47 * device mapper, the block device will be created as read-only.
48 */ 48 */
49#define LP_PARTITION_ATTR_NONE 0x0
49#define LP_PARTITION_ATTR_READONLY 0x1 50#define LP_PARTITION_ATTR_READONLY 0x1
50 51
51/* Mask that defines all valid attributes. */ 52/* Mask that defines all valid attributes. */
diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp
index 217d80256..5310cabbc 100644
--- a/fs_mgr/liblp/utility.cpp
+++ b/fs_mgr/liblp/utility.cpp
@@ -84,7 +84,7 @@ std::string GetPartitionGuid(const LpMetadataPartition& partition) {
84 // macro to assist with buffer sizing. 84 // macro to assist with buffer sizing.
85 static const size_t kGuidLen = 36; 85 static const size_t kGuidLen = 36;
86 char buffer[kGuidLen + 1]; 86 char buffer[kGuidLen + 1];
87 uuid_unparse(partition.guid, buffer); 87 uuid_unparse_upper(partition.guid, buffer);
88 return buffer; 88 return buffer;
89} 89}
90 90
diff --git a/fs_mgr/liblp/utility_test.cpp b/fs_mgr/liblp/utility_test.cpp
new file mode 100644
index 000000000..25e8a254e
--- /dev/null
+++ b/fs_mgr/liblp/utility_test.cpp
@@ -0,0 +1,43 @@
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 "utility.h"
18#include <gtest/gtest.h>
19
20using namespace android;
21using namespace android::fs_mgr;
22
23TEST(liblp, SlotNumberForSlotSuffix) {
24 EXPECT_EQ(SlotNumberForSlotSuffix(""), 0);
25 EXPECT_EQ(SlotNumberForSlotSuffix("_a"), 0);
26 EXPECT_EQ(SlotNumberForSlotSuffix("_b"), 1);
27 EXPECT_EQ(SlotNumberForSlotSuffix("_c"), 2);
28 EXPECT_EQ(SlotNumberForSlotSuffix("_d"), 3);
29}
30
31TEST(liblp, GetMetadataOffset) {
32 LpMetadataGeometry geometry = {
33 LP_METADATA_GEOMETRY_MAGIC, sizeof(geometry), {0}, 16384, 4, 10000, 80000};
34 EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 0), 4096);
35 EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 1), 4096 + 16384);
36 EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 2), 4096 + 16384 * 2);
37 EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 3), 4096 + 16384 * 3);
38
39 EXPECT_EQ(GetBackupMetadataOffset(geometry, 3), -4096 - 16384 * 1);
40 EXPECT_EQ(GetBackupMetadataOffset(geometry, 2), -4096 - 16384 * 2);
41 EXPECT_EQ(GetBackupMetadataOffset(geometry, 1), -4096 - 16384 * 3);
42 EXPECT_EQ(GetBackupMetadataOffset(geometry, 0), -4096 - 16384 * 4);
43}