Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 936e9ce7 authored by Akilesh Kailash's avatar Akilesh Kailash
Browse files

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: default avatarAkilesh Kailash <akailash@google.com>
Change-Id: Ie96bc644c5f2eaae45cf048d9ba8a206930c3ce8
parent 150bcbf7
Loading
Loading
Loading
Loading
+83 −3
Original line number Diff line number Diff line
@@ -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