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

Commit 5169ec88 authored by David Anderson's avatar David Anderson
Browse files

snapuserd: Use fixtures in snapuserd_test.

This refactors snapuserd_test to use SnapuserdTest as a fixture, to
avoid needing a separate harness instance.

Bug: 269361087
Test: snapuserd_test
Change-Id: Iffdc7b621dbe0aff72eff790e7af3f6bb33036ee
parent d14a7551
Loading
Loading
Loading
Loading
+110 −117
Original line number Original line Diff line number Diff line
@@ -99,9 +99,9 @@ class Tempdevice {
    bool valid_;
    bool valid_;
};
};


class SnapuserTest final {
class SnapuserdTest : public ::testing::Test {
  public:
  public:
    bool Setup();
    bool SetupDefault();
    bool SetupOrderedOps();
    bool SetupOrderedOps();
    bool SetupOrderedOpsInverted();
    bool SetupOrderedOpsInverted();
    bool SetupCopyOverlap_1();
    bool SetupCopyOverlap_1();
@@ -118,6 +118,10 @@ class SnapuserTest final {


    static const uint64_t kSectorSize = 512;
    static const uint64_t kSectorSize = 512;


  protected:
    void SetUp() override {}
    void TearDown() override { Shutdown(); }

  private:
  private:
    void SetupImpl();
    void SetupImpl();


@@ -172,7 +176,7 @@ static unique_fd CreateTempFile(const std::string& name, size_t size) {
    return fd;
    return fd;
}
}


void SnapuserTest::Shutdown() {
void SnapuserdTest::Shutdown() {
    ASSERT_TRUE(dmuser_dev_->Destroy());
    ASSERT_TRUE(dmuser_dev_->Destroy());


    auto misc_device = "/dev/dm-user/" + system_device_ctrl_name_;
    auto misc_device = "/dev/dm-user/" + system_device_ctrl_name_;
@@ -181,36 +185,36 @@ void SnapuserTest::Shutdown() {
    ASSERT_TRUE(client_->DetachSnapuserd());
    ASSERT_TRUE(client_->DetachSnapuserd());
}
}


bool SnapuserTest::Setup() {
bool SnapuserdTest::SetupDefault() {
    SetupImpl();
    SetupImpl();
    return setup_ok_;
    return setup_ok_;
}
}


bool SnapuserTest::SetupOrderedOps() {
bool SnapuserdTest::SetupOrderedOps() {
    CreateBaseDevice();
    CreateBaseDevice();
    CreateCowDeviceOrderedOps();
    CreateCowDeviceOrderedOps();
    return SetupDaemon();
    return SetupDaemon();
}
}


bool SnapuserTest::SetupOrderedOpsInverted() {
bool SnapuserdTest::SetupOrderedOpsInverted() {
    CreateBaseDevice();
    CreateBaseDevice();
    CreateCowDeviceOrderedOpsInverted();
    CreateCowDeviceOrderedOpsInverted();
    return SetupDaemon();
    return SetupDaemon();
}
}


bool SnapuserTest::SetupCopyOverlap_1() {
bool SnapuserdTest::SetupCopyOverlap_1() {
    CreateBaseDevice();
    CreateBaseDevice();
    CreateCowDeviceWithCopyOverlap_1();
    CreateCowDeviceWithCopyOverlap_1();
    return SetupDaemon();
    return SetupDaemon();
}
}


bool SnapuserTest::SetupCopyOverlap_2() {
bool SnapuserdTest::SetupCopyOverlap_2() {
    CreateBaseDevice();
    CreateBaseDevice();
    CreateCowDeviceWithCopyOverlap_2();
    CreateCowDeviceWithCopyOverlap_2();
    return SetupDaemon();
    return SetupDaemon();
}
}


bool SnapuserTest::SetupDaemon() {
bool SnapuserdTest::SetupDaemon() {
    SetDeviceControlName();
    SetDeviceControlName();


    StartSnapuserdDaemon();
    StartSnapuserdDaemon();
@@ -224,7 +228,7 @@ bool SnapuserTest::SetupDaemon() {
    return setup_ok_;
    return setup_ok_;
}
}


void SnapuserTest::StartSnapuserdDaemon() {
void SnapuserdTest::StartSnapuserdDaemon() {
    pid_t pid = fork();
    pid_t pid = fork();
    ASSERT_GE(pid, 0);
    ASSERT_GE(pid, 0);
    if (pid == 0) {
    if (pid == 0) {
@@ -238,7 +242,7 @@ void SnapuserTest::StartSnapuserdDaemon() {
    }
    }
}
}


void SnapuserTest::CreateBaseDevice() {
void SnapuserdTest::CreateBaseDevice() {
    unique_fd rnd_fd;
    unique_fd rnd_fd;


    total_base_size_ = (size_ * 5);
    total_base_size_ = (size_ * 5);
@@ -261,7 +265,7 @@ void SnapuserTest::CreateBaseDevice() {
    ASSERT_TRUE(base_loop_->valid());
    ASSERT_TRUE(base_loop_->valid());
}
}


void SnapuserTest::ReadSnapshotDeviceAndValidate() {
void SnapuserdTest::ReadSnapshotDeviceAndValidate() {
    unique_fd fd(open(dmuser_dev_->path().c_str(), O_RDONLY));
    unique_fd fd(open(dmuser_dev_->path().c_str(), O_RDONLY));
    ASSERT_GE(fd, 0);
    ASSERT_GE(fd, 0);
    std::unique_ptr<uint8_t[]> snapuserd_buffer = std::make_unique<uint8_t[]>(size_);
    std::unique_ptr<uint8_t[]> snapuserd_buffer = std::make_unique<uint8_t[]>(size_);
@@ -292,7 +296,7 @@ void SnapuserTest::ReadSnapshotDeviceAndValidate() {
    ASSERT_EQ(memcmp(snapuserd_buffer.get(), (char*)orig_buffer_.get() + (size_ * 4), size_), 0);
    ASSERT_EQ(memcmp(snapuserd_buffer.get(), (char*)orig_buffer_.get() + (size_ * 4), size_), 0);
}
}


void SnapuserTest::CreateCowDeviceWithCopyOverlap_2() {
void SnapuserdTest::CreateCowDeviceWithCopyOverlap_2() {
    std::string path = android::base::GetExecutableDirectory();
    std::string path = android::base::GetExecutableDirectory();
    cow_system_ = std::make_unique<TemporaryFile>(path);
    cow_system_ = std::make_unique<TemporaryFile>(path);


@@ -344,7 +348,7 @@ void SnapuserTest::CreateCowDeviceWithCopyOverlap_2() {
    }
    }
}
}


void SnapuserTest::CreateCowDeviceWithCopyOverlap_1() {
void SnapuserdTest::CreateCowDeviceWithCopyOverlap_1() {
    std::string path = android::base::GetExecutableDirectory();
    std::string path = android::base::GetExecutableDirectory();
    cow_system_ = std::make_unique<TemporaryFile>(path);
    cow_system_ = std::make_unique<TemporaryFile>(path);


@@ -387,7 +391,7 @@ void SnapuserTest::CreateCowDeviceWithCopyOverlap_1() {
              true);
              true);
}
}


void SnapuserTest::CreateCowDeviceOrderedOpsInverted() {
void SnapuserdTest::CreateCowDeviceOrderedOpsInverted() {
    unique_fd rnd_fd;
    unique_fd rnd_fd;
    loff_t offset = 0;
    loff_t offset = 0;


@@ -450,7 +454,7 @@ void SnapuserTest::CreateCowDeviceOrderedOpsInverted() {
    }
    }
}
}


void SnapuserTest::CreateCowDeviceOrderedOps() {
void SnapuserdTest::CreateCowDeviceOrderedOps() {
    unique_fd rnd_fd;
    unique_fd rnd_fd;
    loff_t offset = 0;
    loff_t offset = 0;


@@ -511,7 +515,7 @@ void SnapuserTest::CreateCowDeviceOrderedOps() {
    }
    }
}
}


void SnapuserTest::CreateCowDevice() {
void SnapuserdTest::CreateCowDevice() {
    unique_fd rnd_fd;
    unique_fd rnd_fd;
    loff_t offset = 0;
    loff_t offset = 0;


@@ -601,13 +605,13 @@ void SnapuserTest::CreateCowDevice() {
    }
    }
}
}


void SnapuserTest::InitCowDevice() {
void SnapuserdTest::InitCowDevice() {
    uint64_t num_sectors = client_->InitDmUserCow(system_device_ctrl_name_, cow_system_->path,
    uint64_t num_sectors = client_->InitDmUserCow(system_device_ctrl_name_, cow_system_->path,
                                                  base_loop_->device(), base_loop_->device());
                                                  base_loop_->device(), base_loop_->device());
    ASSERT_NE(num_sectors, 0);
    ASSERT_NE(num_sectors, 0);
}
}


void SnapuserTest::SetDeviceControlName() {
void SnapuserdTest::SetDeviceControlName() {
    system_device_name_.clear();
    system_device_name_.clear();
    system_device_ctrl_name_.clear();
    system_device_ctrl_name_.clear();


@@ -619,7 +623,7 @@ void SnapuserTest::SetDeviceControlName() {
    system_device_ctrl_name_ = system_device_name_ + "-ctrl";
    system_device_ctrl_name_ = system_device_name_ + "-ctrl";
}
}


void SnapuserTest::CreateDmUserDevice() {
void SnapuserdTest::CreateDmUserDevice() {
    unique_fd fd(TEMP_FAILURE_RETRY(open(base_loop_->device().c_str(), O_RDONLY | O_CLOEXEC)));
    unique_fd fd(TEMP_FAILURE_RETRY(open(base_loop_->device().c_str(), O_RDONLY | O_CLOEXEC)));
    ASSERT_TRUE(fd > 0);
    ASSERT_TRUE(fd > 0);


@@ -641,12 +645,12 @@ void SnapuserTest::CreateDmUserDevice() {
    ASSERT_TRUE(android::fs_mgr::WaitForFile(misc_device, 10s));
    ASSERT_TRUE(android::fs_mgr::WaitForFile(misc_device, 10s));
}
}


void SnapuserTest::InitDaemon() {
void SnapuserdTest::InitDaemon() {
    bool ok = client_->AttachDmUser(system_device_ctrl_name_);
    bool ok = client_->AttachDmUser(system_device_ctrl_name_);
    ASSERT_TRUE(ok);
    ASSERT_TRUE(ok);
}
}


void SnapuserTest::CheckMergeCompletion() {
void SnapuserdTest::CheckMergeCompletion() {
    while (true) {
    while (true) {
        double percentage = client_->GetMergePercent();
        double percentage = client_->GetMergePercent();
        if ((int)percentage == 100) {
        if ((int)percentage == 100) {
@@ -657,7 +661,7 @@ void SnapuserTest::CheckMergeCompletion() {
    }
    }
}
}


void SnapuserTest::SetupImpl() {
void SnapuserdTest::SetupImpl() {
    CreateBaseDevice();
    CreateBaseDevice();
    CreateCowDevice();
    CreateCowDevice();


@@ -672,26 +676,26 @@ void SnapuserTest::SetupImpl() {
    setup_ok_ = true;
    setup_ok_ = true;
}
}


bool SnapuserTest::Merge() {
bool SnapuserdTest::Merge() {
    StartMerge();
    StartMerge();
    CheckMergeCompletion();
    CheckMergeCompletion();
    merge_ok_ = true;
    merge_ok_ = true;
    return merge_ok_;
    return merge_ok_;
}
}


void SnapuserTest::StartMerge() {
void SnapuserdTest::StartMerge() {
    bool ok = client_->InitiateMerge(system_device_ctrl_name_);
    bool ok = client_->InitiateMerge(system_device_ctrl_name_);
    ASSERT_TRUE(ok);
    ASSERT_TRUE(ok);
}
}


void SnapuserTest::ValidateMerge() {
void SnapuserdTest::ValidateMerge() {
    merged_buffer_ = std::make_unique<uint8_t[]>(total_base_size_);
    merged_buffer_ = std::make_unique<uint8_t[]>(total_base_size_);
    ASSERT_EQ(android::base::ReadFullyAtOffset(base_fd_, merged_buffer_.get(), total_base_size_, 0),
    ASSERT_EQ(android::base::ReadFullyAtOffset(base_fd_, merged_buffer_.get(), total_base_size_, 0),
              true);
              true);
    ASSERT_EQ(memcmp(merged_buffer_.get(), orig_buffer_.get(), total_base_size_), 0);
    ASSERT_EQ(memcmp(merged_buffer_.get(), orig_buffer_.get(), total_base_size_), 0);
}
}


void SnapuserTest::SimulateDaemonRestart() {
void SnapuserdTest::SimulateDaemonRestart() {
    Shutdown();
    Shutdown();
    std::this_thread::sleep_for(500ms);
    std::this_thread::sleep_for(500ms);
    SetDeviceControlName();
    SetDeviceControlName();
@@ -701,7 +705,7 @@ void SnapuserTest::SimulateDaemonRestart() {
    InitDaemon();
    InitDaemon();
}
}


void SnapuserTest::MergeInterruptRandomly(int max_duration) {
void SnapuserdTest::MergeInterruptRandomly(int max_duration) {
    std::srand(std::time(nullptr));
    std::srand(std::time(nullptr));
    StartMerge();
    StartMerge();


@@ -716,7 +720,7 @@ void SnapuserTest::MergeInterruptRandomly(int max_duration) {
    ASSERT_TRUE(Merge());
    ASSERT_TRUE(Merge());
}
}


void SnapuserTest::MergeInterruptFixed(int duration) {
void SnapuserdTest::MergeInterruptFixed(int duration) {
    StartMerge();
    StartMerge();


    for (int i = 0; i < 25; i++) {
    for (int i = 0; i < 25; i++) {
@@ -729,7 +733,7 @@ void SnapuserTest::MergeInterruptFixed(int duration) {
    ASSERT_TRUE(Merge());
    ASSERT_TRUE(Merge());
}
}


void SnapuserTest::MergeInterrupt() {
void SnapuserdTest::MergeInterrupt() {
    // Interrupt merge at various intervals
    // Interrupt merge at various intervals
    StartMerge();
    StartMerge();
    std::this_thread::sleep_for(250ms);
    std::this_thread::sleep_for(250ms);
@@ -758,104 +762,93 @@ void SnapuserTest::MergeInterrupt() {
    ASSERT_TRUE(Merge());
    ASSERT_TRUE(Merge());
}
}


TEST(Snapuserd_Test, Snapshot_IO_TEST) {
TEST_F(SnapuserdTest, Snapshot_IO_TEST) {
    SnapuserTest harness;
    ASSERT_TRUE(SetupDefault());
    ASSERT_TRUE(harness.Setup());
    // I/O before merge
    // I/O before merge
    harness.ReadSnapshotDeviceAndValidate();
    ReadSnapshotDeviceAndValidate();
    ASSERT_TRUE(harness.Merge());
    ASSERT_TRUE(Merge());
    harness.ValidateMerge();
    ValidateMerge();
    // I/O after merge - daemon should read directly
    // I/O after merge - daemon should read directly
    // from base device
    // from base device
    harness.ReadSnapshotDeviceAndValidate();
    ReadSnapshotDeviceAndValidate();
    harness.Shutdown();
    Shutdown();
}
}


TEST(Snapuserd_Test, Snapshot_MERGE_IO_TEST) {
TEST_F(SnapuserdTest, Snapshot_MERGE_IO_TEST) {
    SnapuserTest harness;
    ASSERT_TRUE(SetupDefault());
    ASSERT_TRUE(harness.Setup());
    // Issue I/O before merge begins
    // Issue I/O before merge begins
    std::async(std::launch::async, &SnapuserTest::ReadSnapshotDeviceAndValidate, &harness);
    std::async(std::launch::async, &SnapuserdTest::ReadSnapshotDeviceAndValidate, this);
    // Start the merge
    // Start the merge
    ASSERT_TRUE(harness.Merge());
    ASSERT_TRUE(Merge());
    harness.ValidateMerge();
    ValidateMerge();
    harness.Shutdown();
    Shutdown();
}
}


TEST(Snapuserd_Test, Snapshot_MERGE_IO_TEST_1) {
TEST_F(SnapuserdTest, Snapshot_MERGE_IO_TEST_1) {
    SnapuserTest harness;
    ASSERT_TRUE(SetupDefault());
    ASSERT_TRUE(harness.Setup());
    // Start the merge
    // Start the merge
    harness.StartMerge();
    StartMerge();
    // Issue I/O in parallel when merge is in-progress
    // Issue I/O in parallel when merge is in-progress
    std::async(std::launch::async, &SnapuserTest::ReadSnapshotDeviceAndValidate, &harness);
    std::async(std::launch::async, &SnapuserdTest::ReadSnapshotDeviceAndValidate, this);
    harness.CheckMergeCompletion();
    CheckMergeCompletion();
    harness.ValidateMerge();
    ValidateMerge();
    harness.Shutdown();
    Shutdown();
}
}


TEST(Snapuserd_Test, Snapshot_Merge_Resume) {
TEST_F(SnapuserdTest, Snapshot_Merge_Resume) {
    SnapuserTest harness;
    ASSERT_TRUE(SetupDefault());
    ASSERT_TRUE(harness.Setup());
    MergeInterrupt();
    harness.MergeInterrupt();
    ValidateMerge();
    harness.ValidateMerge();
    Shutdown();
    harness.Shutdown();
}
}


TEST_F(SnapuserdTest, Snapshot_COPY_Overlap_TEST_1) {
TEST(Snapuserd_Test, Snapshot_COPY_Overlap_TEST_1) {
    ASSERT_TRUE(SetupCopyOverlap_1());
    SnapuserTest harness;
    ASSERT_TRUE(Merge());
    ASSERT_TRUE(harness.SetupCopyOverlap_1());
    ValidateMerge();
    ASSERT_TRUE(harness.Merge());
    Shutdown();
    harness.ValidateMerge();
}
    harness.Shutdown();

}
TEST_F(SnapuserdTest, Snapshot_COPY_Overlap_TEST_2) {

    ASSERT_TRUE(SetupCopyOverlap_2());
TEST(Snapuserd_Test, Snapshot_COPY_Overlap_TEST_2) {
    ASSERT_TRUE(Merge());
    SnapuserTest harness;
    ValidateMerge();
    ASSERT_TRUE(harness.SetupCopyOverlap_2());
    Shutdown();
    ASSERT_TRUE(harness.Merge());
}
    harness.ValidateMerge();

    harness.Shutdown();
TEST_F(SnapuserdTest, Snapshot_COPY_Overlap_Merge_Resume_TEST) {
}
    ASSERT_TRUE(SetupCopyOverlap_1());

    MergeInterrupt();
TEST(Snapuserd_Test, Snapshot_COPY_Overlap_Merge_Resume_TEST) {
    ValidateMerge();
    SnapuserTest harness;
    Shutdown();
    ASSERT_TRUE(harness.SetupCopyOverlap_1());
}
    harness.MergeInterrupt();

    harness.ValidateMerge();
TEST_F(SnapuserdTest, Snapshot_Merge_Crash_Fixed_Ordered) {
    harness.Shutdown();
    ASSERT_TRUE(SetupOrderedOps());
}
    MergeInterruptFixed(300);

    ValidateMerge();
TEST(Snapuserd_Test, Snapshot_Merge_Crash_Fixed_Ordered) {
    Shutdown();
    SnapuserTest harness;
}
    ASSERT_TRUE(harness.SetupOrderedOps());

    harness.MergeInterruptFixed(300);
TEST_F(SnapuserdTest, Snapshot_Merge_Crash_Random_Ordered) {
    harness.ValidateMerge();
    ASSERT_TRUE(SetupOrderedOps());
    harness.Shutdown();
    MergeInterruptRandomly(500);
}
    ValidateMerge();

    Shutdown();
TEST(Snapuserd_Test, Snapshot_Merge_Crash_Random_Ordered) {
}
    SnapuserTest harness;

    ASSERT_TRUE(harness.SetupOrderedOps());
TEST_F(SnapuserdTest, Snapshot_Merge_Crash_Fixed_Inverted) {
    harness.MergeInterruptRandomly(500);
    ASSERT_TRUE(SetupOrderedOpsInverted());
    harness.ValidateMerge();
    MergeInterruptFixed(50);
    harness.Shutdown();
    ValidateMerge();
}
    Shutdown();

}
TEST(Snapuserd_Test, Snapshot_Merge_Crash_Fixed_Inverted) {

    SnapuserTest harness;
TEST_F(SnapuserdTest, Snapshot_Merge_Crash_Random_Inverted) {
    ASSERT_TRUE(harness.SetupOrderedOpsInverted());
    ASSERT_TRUE(SetupOrderedOpsInverted());
    harness.MergeInterruptFixed(50);
    MergeInterruptRandomly(50);
    harness.ValidateMerge();
    ValidateMerge();
    harness.Shutdown();
    Shutdown();
}

TEST(Snapuserd_Test, Snapshot_Merge_Crash_Random_Inverted) {
    SnapuserTest harness;
    ASSERT_TRUE(harness.SetupOrderedOpsInverted());
    harness.MergeInterruptRandomly(50);
    harness.ValidateMerge();
    harness.Shutdown();
}
}


}  // namespace snapshot
}  // namespace snapshot