blob: 714b6b439ed7aa0791fa52c887634a1b969262a0 [file] [log] [blame]
//
// Copyright (C) 2023 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <liblp/builder.h>
#include <liblp/super_layout_builder.h>
#include <storage_literals/storage_literals.h>
#include "images.h"
#include "writer.h"
using namespace android::fs_mgr;
using namespace android::storage_literals;
TEST(SuperImageTool, Layout) {
auto builder = MetadataBuilder::New(4_MiB, 8_KiB, 2);
ASSERT_NE(builder, nullptr);
Partition* p = builder->AddPartition("system_a", LP_PARTITION_ATTR_READONLY);
ASSERT_NE(p, nullptr);
auto metadata = builder->Export();
ASSERT_NE(metadata, nullptr);
SuperLayoutBuilder tool;
ASSERT_TRUE(tool.Open(*metadata.get()));
ASSERT_TRUE(tool.AddPartition("system_a", "system.img", 16_KiB));
// Get a copy of the metadata we'd expect if flashing.
ASSERT_TRUE(builder->ResizePartition(p, 16_KiB));
metadata = builder->Export();
ASSERT_NE(metadata, nullptr);
auto geometry_blob = std::make_shared<std::string>(SerializeGeometry(metadata->geometry));
auto metadata_blob = std::make_shared<std::string>(SerializeMetadata(*metadata.get()));
metadata_blob->resize(4_KiB, '\0');
auto extents = tool.GetImageLayout();
ASSERT_EQ(extents.size(), 12);
EXPECT_EQ(extents[0], SuperImageExtent(0, 4096, SuperImageExtent::Type::ZERO));
EXPECT_EQ(extents[1], SuperImageExtent(4096, geometry_blob));
EXPECT_EQ(extents[2], SuperImageExtent(8192, geometry_blob));
EXPECT_EQ(extents[3], SuperImageExtent(12288, metadata_blob));
EXPECT_EQ(extents[4], SuperImageExtent(16384, 4096, SuperImageExtent::Type::DONTCARE));
EXPECT_EQ(extents[5], SuperImageExtent(20480, metadata_blob));
EXPECT_EQ(extents[6], SuperImageExtent(24576, 4096, SuperImageExtent::Type::DONTCARE));
EXPECT_EQ(extents[7], SuperImageExtent(28672, metadata_blob));
EXPECT_EQ(extents[8], SuperImageExtent(32768, 4096, SuperImageExtent::Type::DONTCARE));
EXPECT_EQ(extents[9], SuperImageExtent(36864, metadata_blob));
EXPECT_EQ(extents[10], SuperImageExtent(40960, 4096, SuperImageExtent::Type::DONTCARE));
EXPECT_EQ(extents[11], SuperImageExtent(45056, 16384, "system.img", 0));
}
TEST(SuperImageTool, NoWritablePartitions) {
auto builder = MetadataBuilder::New(4_MiB, 8_KiB, 2);
ASSERT_NE(builder, nullptr);
Partition* p = builder->AddPartition("system_a", 0);
ASSERT_NE(p, nullptr);
auto metadata = builder->Export();
ASSERT_NE(metadata, nullptr);
SuperLayoutBuilder tool;
ASSERT_FALSE(tool.Open(*metadata.get()));
}
TEST(SuperImageTool, NoRetrofit) {
auto builder = MetadataBuilder::New(4_MiB, 8_KiB, 2);
ASSERT_NE(builder, nullptr);
Partition* p = builder->AddPartition("system_a", LP_PARTITION_ATTR_READONLY);
ASSERT_NE(p, nullptr);
auto metadata = builder->Export();
ASSERT_NE(metadata, nullptr);
// Add an extra block device.
metadata->block_devices.emplace_back(metadata->block_devices[0]);
SuperLayoutBuilder tool;
ASSERT_FALSE(tool.Open(*metadata.get()));
}
TEST(SuperImageTool, NoRetrofit2) {
auto builder = MetadataBuilder::New(4_MiB, 8_KiB, 2);
ASSERT_NE(builder, nullptr);
Partition* p = builder->AddPartition(
"system_a", LP_PARTITION_ATTR_READONLY | LP_PARTITION_ATTR_SLOT_SUFFIXED);
ASSERT_NE(p, nullptr);
auto metadata = builder->Export();
ASSERT_NE(metadata, nullptr);
SuperLayoutBuilder tool;
ASSERT_FALSE(tool.Open(*metadata.get()));
}
TEST(SuperImageTool, NoFixedPartitions) {
auto builder = MetadataBuilder::New(4_MiB, 8_KiB, 2);
ASSERT_NE(builder, nullptr);
Partition* p = builder->AddPartition("system_a", LP_PARTITION_ATTR_READONLY);
ASSERT_NE(p, nullptr);
ASSERT_TRUE(builder->ResizePartition(p, 4_KiB));
auto metadata = builder->Export();
ASSERT_NE(metadata, nullptr);
SuperLayoutBuilder tool;
ASSERT_FALSE(tool.Open(*metadata.get()));
}
TEST(SuperImageTool, LargeAlignedMetadata) {
auto builder = MetadataBuilder::New(4_MiB, 512, 2);
ASSERT_NE(builder, nullptr);
auto metadata = builder->Export();
ASSERT_NE(metadata, nullptr);
SuperLayoutBuilder tool;
ASSERT_TRUE(tool.Open(*metadata.get()));
auto extents = tool.GetImageLayout();
ASSERT_TRUE(extents.empty());
}