diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp index 5b377ae1e..2b11da262 100644 --- a/fs_mgr/liblp/Android.bp +++ b/fs_mgr/liblp/Android.bp @@ -69,6 +69,7 @@ cc_test { stl: "libc++_static", srcs: [ "builder_test.cpp", + "device_test.cpp", "io_test.cpp", "test_partition_opener.cpp", "utility_test.cpp", diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp index b3c13e650..ecad7d49e 100644 --- a/fs_mgr/liblp/builder_test.cpp +++ b/fs_mgr/liblp/builder_test.cpp @@ -14,11 +14,11 @@ * limitations under the License. */ -#include #include #include #include +#include "liblp_test.h" #include "mock_property_fetcher.h" #include "utility.h" @@ -31,7 +31,7 @@ using ::testing::ElementsAre; using ::testing::NiceMock; using ::testing::Return; -static void ResetPropertyFetcher() { +void ResetPropertyFetcher() { IPropertyFetcher::OverrideForTesting(std::make_unique>()); } @@ -49,11 +49,7 @@ int main(int argc, char** argv) { return RUN_ALL_TESTS(); } -class BuilderTest : public ::testing::Test { - public: - void SetUp() override { ResetPropertyFetcher(); } - void TearDown() override { ResetPropertyFetcher(); } -}; +class BuilderTest : public LiblpTest {}; TEST_F(BuilderTest, BuildBasic) { unique_ptr builder = MetadataBuilder::New(1024 * 1024, 1024, 2); @@ -460,23 +456,6 @@ TEST_F(BuilderTest, MetadataTooLarge) { EXPECT_EQ(builder, nullptr); } -TEST_F(BuilderTest, block_device_info) { - PartitionOpener opener; - - BlockDeviceInfo device_info; - ASSERT_TRUE(opener.GetInfo(fs_mgr_get_super_partition_name(), &device_info)); - - // Sanity check that the device doesn't give us some weird inefficient - // alignment. - ASSERT_EQ(device_info.alignment % LP_SECTOR_SIZE, 0); - ASSERT_EQ(device_info.alignment_offset % LP_SECTOR_SIZE, 0); - ASSERT_LE(device_info.alignment_offset, INT_MAX); - ASSERT_EQ(device_info.logical_block_size % LP_SECTOR_SIZE, 0); - - // Having an alignment offset > alignment doesn't really make sense. - ASSERT_LT(device_info.alignment_offset, device_info.alignment); -} - TEST_F(BuilderTest, UpdateBlockDeviceInfo) { BlockDeviceInfo device_info("super", 1024 * 1024, 4096, 1024, 4096); unique_ptr builder = MetadataBuilder::New(device_info, 1024, 1); diff --git a/fs_mgr/liblp/device_test.cpp b/fs_mgr/liblp/device_test.cpp new file mode 100644 index 000000000..b759fd11f --- /dev/null +++ b/fs_mgr/liblp/device_test.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019 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 +#include +#include +#include +#include +#include +#include +#include + +#include "liblp_test.h" +#include "mock_property_fetcher.h" + +using namespace android::fs_mgr; +using ::testing::Return; + +// Compliance test on the actual device with dynamic partitions. +class DeviceTest : public LiblpTest { + public: + void SetUp() override { + // Read real properties. + IPropertyFetcher::OverrideForTesting(std::make_unique()); + if (!IPropertyFetcher::GetInstance()->GetBoolProperty("ro.boot.dynamic_partitions", + false)) { + GTEST_SKIP() << "Device doesn't have dynamic partitions enabled, skipping"; + } + } +}; + +TEST_F(DeviceTest, BlockDeviceInfo) { + PartitionOpener opener; + BlockDeviceInfo device_info; + ASSERT_TRUE(opener.GetInfo(fs_mgr_get_super_partition_name(), &device_info)); + + // Sanity check that the device doesn't give us some weird inefficient + // alignment. + EXPECT_EQ(device_info.alignment % LP_SECTOR_SIZE, 0); + EXPECT_EQ(device_info.alignment_offset % LP_SECTOR_SIZE, 0); + EXPECT_LE(device_info.alignment_offset, INT_MAX); + EXPECT_EQ(device_info.logical_block_size % LP_SECTOR_SIZE, 0); + + // Having an alignment offset > alignment doesn't really make sense. + EXPECT_LT(device_info.alignment_offset, device_info.alignment); +} + +TEST_F(DeviceTest, ReadSuperPartitionCurrentSlot) { + auto slot_suffix = fs_mgr_get_slot_suffix(); + auto slot_number = SlotNumberForSlotSuffix(slot_suffix); + auto super_name = fs_mgr_get_super_partition_name(slot_number); + auto metadata = ReadMetadata(super_name, slot_number); + EXPECT_NE(metadata, nullptr); +} + +TEST_F(DeviceTest, ReadSuperPartitionOtherSlot) { + auto other_slot_suffix = fs_mgr_get_other_slot_suffix(); + if (other_slot_suffix.empty()) { + GTEST_SKIP() << "No other slot, skipping"; + } + if (IPropertyFetcher::GetInstance()->GetBoolProperty("ro.boot.dynamic_partitions_retrofit", + false)) { + GTEST_SKIP() << "Device with retrofit dynamic partition may not have metadata at other " + << "slot, skipping"; + } + + auto other_slot_number = SlotNumberForSlotSuffix(other_slot_suffix); + auto other_super_name = fs_mgr_get_super_partition_name(other_slot_number); + auto other_metadata = ReadMetadata(other_super_name, other_slot_number); + EXPECT_NE(other_metadata, nullptr); +} diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp index 3dace25da..4d0094486 100644 --- a/fs_mgr/liblp/io_test.cpp +++ b/fs_mgr/liblp/io_test.cpp @@ -21,13 +21,12 @@ #include #include -#include -#include #include #include #include #include "images.h" +#include "liblp_test.h" #include "mock_property_fetcher.h" #include "reader.h" #include "test_partition_opener.h" @@ -124,7 +123,7 @@ static unique_fd CreateFlashedDisk() { } // Test that our CreateFakeDisk() function works. -TEST(liblp, CreateFakeDisk) { +TEST_F(LiblpTest, CreateFakeDisk) { unique_fd fd = CreateFakeDisk(); ASSERT_GE(fd, 0); @@ -140,7 +139,7 @@ TEST(liblp, CreateFakeDisk) { // Flashing metadata should not work if the metadata was created for a larger // disk than the destination disk. -TEST(liblp, ExportDiskTooSmall) { +TEST_F(LiblpTest, ExportDiskTooSmall) { unique_ptr builder = MetadataBuilder::New(kDiskSize + 4096, 512, 2); ASSERT_NE(builder, nullptr); unique_ptr exported = builder->Export(); @@ -157,7 +156,7 @@ TEST(liblp, ExportDiskTooSmall) { } // Test the basics of flashing a partition and reading it back. -TEST(liblp, FlashAndReadback) { +TEST_F(LiblpTest, FlashAndReadback) { unique_ptr builder = CreateDefaultBuilder(); ASSERT_NE(builder, nullptr); ASSERT_TRUE(AddDefaultPartitions(builder.get())); @@ -207,7 +206,7 @@ TEST(liblp, FlashAndReadback) { } // Test that we can update metadata slots without disturbing others. -TEST(liblp, UpdateAnyMetadataSlot) { +TEST_F(LiblpTest, UpdateAnyMetadataSlot) { unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0); @@ -252,7 +251,7 @@ TEST(liblp, UpdateAnyMetadataSlot) { } } -TEST(liblp, InvalidMetadataSlot) { +TEST_F(LiblpTest, InvalidMetadataSlot) { unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0); @@ -271,7 +270,7 @@ TEST(liblp, InvalidMetadataSlot) { // Test that updating a metadata slot does not allow it to be computed based // on mismatching geometry. -TEST(liblp, NoChangingGeometry) { +TEST_F(LiblpTest, NoChangingGeometry) { unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0); @@ -300,7 +299,7 @@ TEST(liblp, NoChangingGeometry) { } // Test that changing one bit of metadata is enough to break the checksum. -TEST(liblp, BitFlipGeometry) { +TEST_F(LiblpTest, BitFlipGeometry) { unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0); @@ -319,7 +318,7 @@ TEST(liblp, BitFlipGeometry) { EXPECT_EQ(metadata->geometry.metadata_slot_count, 2); } -TEST(liblp, ReadBackupGeometry) { +TEST_F(LiblpTest, ReadBackupGeometry) { unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0); @@ -339,7 +338,7 @@ TEST(liblp, ReadBackupGeometry) { EXPECT_EQ(ReadMetadata(opener, "super", 0), nullptr); } -TEST(liblp, ReadBackupMetadata) { +TEST_F(LiblpTest, ReadBackupMetadata) { unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0); @@ -366,7 +365,7 @@ TEST(liblp, ReadBackupMetadata) { // Test that we don't attempt to write metadata if it would overflow its // reserved space. -TEST(liblp, TooManyPartitions) { +TEST_F(LiblpTest, TooManyPartitions) { unique_ptr builder = CreateDefaultBuilder(); ASSERT_NE(builder, nullptr); @@ -420,7 +419,7 @@ TEST(liblp, TooManyPartitions) { } // Test that we can read and write image files. -TEST(liblp, ImageFiles) { +TEST_F(LiblpTest, ImageFiles) { unique_ptr builder = CreateDefaultBuilder(); ASSERT_NE(builder, nullptr); ASSERT_TRUE(AddDefaultPartitions(builder.get())); @@ -436,7 +435,7 @@ TEST(liblp, ImageFiles) { } // Test that we can read images from buffers. -TEST(liblp, ImageFilesInMemory) { +TEST_F(LiblpTest, ImageFilesInMemory) { unique_ptr builder = CreateDefaultBuilder(); ASSERT_NE(builder, nullptr); ASSERT_TRUE(AddDefaultPartitions(builder.get())); @@ -496,7 +495,7 @@ class BadWriter { // Test that an interrupted flash operation on the "primary" copy of metadata // is not fatal. -TEST(liblp, UpdatePrimaryMetadataFailure) { +TEST_F(LiblpTest, UpdatePrimaryMetadataFailure) { unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0); @@ -524,7 +523,7 @@ TEST(liblp, UpdatePrimaryMetadataFailure) { // Test that an interrupted flash operation on the "backup" copy of metadata // is not fatal. -TEST(liblp, UpdateBackupMetadataFailure) { +TEST_F(LiblpTest, UpdateBackupMetadataFailure) { unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0); @@ -553,7 +552,7 @@ TEST(liblp, UpdateBackupMetadataFailure) { // Test that an interrupted write *in between* writing metadata will read // the correct metadata copy. The primary is always considered newer than // the backup. -TEST(liblp, UpdateMetadataCleanFailure) { +TEST_F(LiblpTest, UpdateMetadataCleanFailure) { unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0); @@ -590,7 +589,7 @@ TEST(liblp, UpdateMetadataCleanFailure) { } // Test that writing a sparse image can be read back. -TEST(liblp, FlashSparseImage) { +TEST_F(LiblpTest, FlashSparseImage) { unique_fd fd = CreateFakeDisk(); ASSERT_GE(fd, 0); @@ -624,7 +623,7 @@ TEST(liblp, FlashSparseImage) { ASSERT_NE(ReadBackupMetadata(fd.get(), geometry, 0), nullptr); } -TEST(liblp, AutoSlotSuffixing) { +TEST_F(LiblpTest, AutoSlotSuffixing) { unique_ptr builder = CreateDefaultBuilder(); ASSERT_NE(builder, nullptr); ASSERT_TRUE(AddDefaultPartitions(builder.get())); @@ -667,7 +666,7 @@ TEST(liblp, AutoSlotSuffixing) { EXPECT_EQ(metadata->groups[1].flags, 0); } -TEST(liblp, UpdateRetrofit) { +TEST_F(LiblpTest, UpdateRetrofit) { ON_CALL(*GetMockedPropertyFetcher(), GetBoolProperty("ro.boot.dynamic_partitions_retrofit", _)) .WillByDefault(Return(true)); @@ -699,7 +698,7 @@ TEST(liblp, UpdateRetrofit) { ASSERT_TRUE(updated->extents.empty()); } -TEST(liblp, UpdateNonRetrofit) { +TEST_F(LiblpTest, UpdateNonRetrofit) { ON_CALL(*GetMockedPropertyFetcher(), GetBoolProperty("ro.boot.dynamic_partitions_retrofit", _)) .WillByDefault(Return(false)); @@ -714,19 +713,3 @@ TEST(liblp, UpdateNonRetrofit) { ASSERT_EQ(updated->block_devices.size(), static_cast(1)); EXPECT_EQ(GetBlockDevicePartitionName(updated->block_devices[0]), "super"); } - -TEST(liblp, ReadSuperPartition) { - auto slot_suffix = fs_mgr_get_slot_suffix(); - auto slot_number = SlotNumberForSlotSuffix(slot_suffix); - auto super_name = fs_mgr_get_super_partition_name(slot_number); - auto metadata = ReadMetadata(super_name, slot_number); - ASSERT_NE(metadata, nullptr); - - if (!slot_suffix.empty()) { - auto other_slot_suffix = fs_mgr_get_other_slot_suffix(); - auto other_slot_number = SlotNumberForSlotSuffix(other_slot_suffix); - auto other_super_name = fs_mgr_get_super_partition_name(other_slot_number); - auto other_metadata = ReadMetadata(other_super_name, other_slot_number); - ASSERT_NE(other_metadata, nullptr); - } -} diff --git a/fs_mgr/liblp/liblp_test.h b/fs_mgr/liblp/liblp_test.h new file mode 100644 index 000000000..892f43d12 --- /dev/null +++ b/fs_mgr/liblp/liblp_test.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 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. + */ + +#pragma once + +#include + +#include "mock_property_fetcher.h" + +class LiblpTest : public ::testing::Test { + public: + void SetUp() override { ResetPropertyFetcher(); } + void TearDown() override { ResetPropertyFetcher(); } +}; diff --git a/fs_mgr/liblp/mock_property_fetcher.h b/fs_mgr/liblp/mock_property_fetcher.h index 0c28710e2..4612c5290 100644 --- a/fs_mgr/liblp/mock_property_fetcher.h +++ b/fs_mgr/liblp/mock_property_fetcher.h @@ -45,3 +45,4 @@ class MockPropertyFetcher : public IPropertyFetcher { } // namespace android android::fs_mgr::MockPropertyFetcher* GetMockedPropertyFetcher(); +void ResetPropertyFetcher();