libsnapshot:snapuserd:Add unit test for read-ahead code path.

Add overlapping copy ops to test the read-ahead logic.

Bug: 183863613
Test: cow_snapuserd_test
Signed-off-by: Akilesh Kailash <akailash@google.com>
Change-Id: Ie96bc644c5f2eaae45cf048d9ba8a206930c3ce8
This commit is contained in:
Akilesh Kailash 2021-03-29 22:58:32 +00:00
parent 150bcbf7c6
commit 936e9ce79d

View file

@ -96,6 +96,7 @@ class TempDevice {
class CowSnapuserdTest final {
public:
bool Setup();
bool SetupCopyOverlap();
bool Merge();
void ValidateMerge();
void ReadSnapshotDeviceAndValidate();
@ -114,6 +115,7 @@ class CowSnapuserdTest final {
void StartMerge();
void CreateCowDevice();
void CreateCowDeviceWithCopyOverlap();
void CreateBaseDevice();
void InitCowDevice();
void SetDeviceControlName();
@ -191,6 +193,24 @@ bool CowSnapuserdTest::Setup() {
return setup_ok_;
}
bool CowSnapuserdTest::SetupCopyOverlap() {
CreateBaseDevice();
CreateCowDeviceWithCopyOverlap();
SetDeviceControlName();
StartSnapuserdDaemon();
InitCowDevice();
CreateDmUserDevice();
InitDaemon();
CreateSnapshotDevice();
setup_ok_ = true;
return setup_ok_;
}
void CowSnapuserdTest::StartSnapuserdDaemon() {
pid_t pid = fork();
ASSERT_GE(pid, 0);
@ -255,6 +275,49 @@ void CowSnapuserdTest::ReadSnapshotDeviceAndValidate() {
ASSERT_EQ(memcmp(snapuserd_buffer.get(), (char*)orig_buffer_.get() + (size_ * 3), size_), 0);
}
void CowSnapuserdTest::CreateCowDeviceWithCopyOverlap() {
std::string path = android::base::GetExecutableDirectory();
cow_system_ = std::make_unique<TemporaryFile>(path);
CowOptions options;
options.compression = "gz";
CowWriter writer(options);
ASSERT_TRUE(writer.Initialize(cow_system_->fd));
size_t num_blocks = size_ / options.block_size;
size_t x = num_blocks;
size_t blk_src_copy = num_blocks - 1;
// Create overlapping copy operations
while (1) {
ASSERT_TRUE(writer.AddCopy(blk_src_copy + 1, blk_src_copy));
x -= 1;
if (x == 0) {
ASSERT_EQ(blk_src_copy, 0);
break;
}
blk_src_copy -= 1;
}
// Flush operations
ASSERT_TRUE(writer.Finalize());
// Construct the buffer required for validation
orig_buffer_ = std::make_unique<uint8_t[]>(total_base_size_);
// Read the entire base device
ASSERT_EQ(android::base::ReadFullyAtOffset(base_fd_, orig_buffer_.get(), total_base_size_, 0),
true);
// Merged operations
ASSERT_EQ(android::base::ReadFullyAtOffset(base_fd_, orig_buffer_.get(), options.block_size, 0),
true);
ASSERT_EQ(android::base::ReadFullyAtOffset(
base_fd_, (char*)orig_buffer_.get() + options.block_size, size_, 0),
true);
}
void CowSnapuserdTest::CreateCowDevice() {
unique_fd rnd_fd;
loff_t offset = 0;
@ -707,17 +770,17 @@ void CowSnapuserdMetadataTest::ValidateMetadata() {
de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
ASSERT_EQ(de->old_chunk, 21);
ASSERT_EQ(de->new_chunk, 537);
ASSERT_EQ(de->new_chunk, 536);
offset += sizeof(struct disk_exception);
de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
ASSERT_EQ(de->old_chunk, 22);
ASSERT_EQ(de->new_chunk, 538);
ASSERT_EQ(de->new_chunk, 537);
offset += sizeof(struct disk_exception);
de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
ASSERT_EQ(de->old_chunk, 23);
ASSERT_EQ(de->new_chunk, 539);
ASSERT_EQ(de->new_chunk, 538);
offset += sizeof(struct disk_exception);
// End of metadata
@ -757,6 +820,23 @@ TEST(Snapuserd_Test, Snapshot_IO_TEST) {
harness.ValidateMerge();
harness.Shutdown();
}
TEST(Snapuserd_Test, Snapshot_COPY_Overlap_TEST) {
CowSnapuserdTest harness;
ASSERT_TRUE(harness.SetupCopyOverlap());
ASSERT_TRUE(harness.Merge());
harness.ValidateMerge();
harness.Shutdown();
}
TEST(Snapuserd_Test, Snapshot_COPY_Overlap_Merge_Resume_TEST) {
CowSnapuserdTest harness;
ASSERT_TRUE(harness.SetupCopyOverlap());
harness.MergeInterrupt();
harness.ValidateMerge();
harness.Shutdown();
}
} // namespace snapshot
} // namespace android