diff options
| author | David Anderson <dvander@google.com> | 2018-07-10 21:07:23 -0700 |
|---|---|---|
| committer | David Anderson <dvander@google.com> | 2018-07-11 13:37:52 -0700 |
| commit | 451694e29d4865f41d1097eba0f0c8d7551567d4 (patch) | |
| tree | adb03900680d428d8eb4c91192bfb4efd0596dd0 /fs_mgr/liblp/io_test.cpp | |
| parent | 21671eda3e2561a326cf27acc4cdc4f5911bfc61 (diff) | |
| download | system_core-451694e29d4865f41d1097eba0f0c8d7551567d4.tar.gz system_core-451694e29d4865f41d1097eba0f0c8d7551567d4.tar.bz2 system_core-451694e29d4865f41d1097eba0f0c8d7551567d4.zip | |
liblp: Make it easier to test UpdatePartitionTable.
This change makes the internal UpdatePartitionTable function more
testable by parameterizing its write functions. It also adds two tests,
one of which exposes a flaw in the current implementation.
Bug: 79173901
Test: liblp_test gtest
Change-Id: I3c4112794b97d577a27f035baeac2d42ac75f552
Diffstat (limited to 'fs_mgr/liblp/io_test.cpp')
| -rw-r--r-- | fs_mgr/liblp/io_test.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp index 29d8ca5b5..c3f8f369d 100644 --- a/fs_mgr/liblp/io_test.cpp +++ b/fs_mgr/liblp/io_test.cpp @@ -393,3 +393,85 @@ TEST(liblp, ImageFiles) { unique_ptr<LpMetadata> imported = ReadFromImageFile(fd); ASSERT_NE(imported, nullptr); } + +class BadWriter { + public: + // When requested, write garbage instead of the requested bytes, then + // return false. + bool operator()(int fd, const std::string& blob) { + if (++write_count_ == fail_on_write_) { + std::unique_ptr<char[]> new_data = std::make_unique<char[]>(blob.size()); + memset(new_data.get(), 0xe5, blob.size()); + EXPECT_TRUE(android::base::WriteFully(fd, new_data.get(), blob.size())); + return false; + } else { + return android::base::WriteFully(fd, blob.data(), blob.size()); + } + } + void FailOnWrite(int number) { + fail_on_write_ = number; + write_count_ = 0; + } + + private: + int fail_on_write_ = 0; + int write_count_ = 0; +}; + +// Test that an interrupted flash operation on the "primary" copy of metadata +// is not fatal. +TEST(liblp, FlashPrimaryMetadataFailure) { + // Initial state. + unique_fd fd = CreateFlashedDisk(); + ASSERT_GE(fd, 0); + + BadWriter writer; + + // Read and write it back. + writer.FailOnWrite(1); + unique_ptr<LpMetadata> imported = ReadMetadata(fd, 0); + ASSERT_NE(imported, nullptr); + ASSERT_FALSE(UpdatePartitionTable(fd, *imported.get(), 0, writer)); + + // We should still be able to read the backup copy. + imported = ReadMetadata(fd, 0); + ASSERT_NE(imported, nullptr); + + // Flash again, this time fail the backup copy. We should still be able + // to read the primary. + writer.FailOnWrite(2); + ASSERT_FALSE(UpdatePartitionTable(fd, *imported.get(), 0, writer)); + imported = ReadMetadata(fd, 0); + ASSERT_NE(imported, nullptr); +} + +// Test that an interrupted flash operation on the "backup" copy of metadata +// is not fatal. +TEST(liblp, FlashBackupMetadataFailure) { + // Initial state. + unique_fd fd = CreateFlashedDisk(); + ASSERT_GE(fd, 0); + + BadWriter writer; + + // Read and write it back. + writer.FailOnWrite(2); + unique_ptr<LpMetadata> imported = ReadMetadata(fd, 0); + ASSERT_NE(imported, nullptr); + ASSERT_FALSE(UpdatePartitionTable(fd, *imported.get(), 0, writer)); + + // We should still be able to read the primary copy. + imported = ReadMetadata(fd, 0); + ASSERT_NE(imported, nullptr); + + // Flash again, this time fail the primary copy. We should still be able + // to read the primary. + // + // TODO(dvander): This is currently not handled correctly. liblp does not + // guarantee both copies are in sync before the update. The ASSERT_EQ + // will change to an ASSERT_NE when this is fixed. + writer.FailOnWrite(1); + ASSERT_FALSE(UpdatePartitionTable(fd, *imported.get(), 0, writer)); + imported = ReadMetadata(fd, 0); + ASSERT_EQ(imported, nullptr); +} |
