1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "test/librbd/test_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "librbd/BlockGuard.h"
10 class TestIOBlockGuard : public TestFixture {
12 static uint32_t s_index;
16 Operation() : index(++s_index) {
18 Operation(Operation &&rhs) : index(rhs.index) {
20 Operation(const Operation &) = delete;
22 Operation& operator=(Operation &&rhs) {
27 bool operator==(const Operation &rhs) const {
28 return index == rhs.index;
32 typedef std::list<Operation> Operations;
34 typedef BlockGuard<Operation> OpBlockGuard;
36 void SetUp() override {
38 m_cct = reinterpret_cast<CephContext*>(m_ioctx.cct());
44 TEST_F(TestIOBlockGuard, NonDetainedOps) {
45 OpBlockGuard op_block_guard(m_cct);
48 BlockGuardCell *cell1;
49 ASSERT_EQ(0, op_block_guard.detain({1, 3}, &op1, &cell1));
52 BlockGuardCell *cell2;
53 ASSERT_EQ(0, op_block_guard.detain({0, 1}, &op2, &cell2));
56 BlockGuardCell *cell3;
57 ASSERT_EQ(0, op_block_guard.detain({3, 6}, &op3, &cell3));
59 Operations released_ops;
60 op_block_guard.release(cell1, &released_ops);
61 ASSERT_TRUE(released_ops.empty());
63 op_block_guard.release(cell2, &released_ops);
64 ASSERT_TRUE(released_ops.empty());
66 op_block_guard.release(cell3, &released_ops);
67 ASSERT_TRUE(released_ops.empty());
70 TEST_F(TestIOBlockGuard, DetainedOps) {
71 OpBlockGuard op_block_guard(m_cct);
74 BlockGuardCell *cell1;
75 ASSERT_EQ(0, op_block_guard.detain({1, 3}, &op1, &cell1));
78 BlockGuardCell *cell2;
79 ASSERT_EQ(1, op_block_guard.detain({2, 6}, &op2, &cell2));
80 ASSERT_EQ(nullptr, cell2);
83 BlockGuardCell *cell3;
84 ASSERT_EQ(2, op_block_guard.detain({0, 2}, &op3, &cell3));
85 ASSERT_EQ(nullptr, cell3);
87 Operations expected_ops;
88 expected_ops.push_back(std::move(op2));
89 expected_ops.push_back(std::move(op3));
90 Operations released_ops;
91 op_block_guard.release(cell1, &released_ops);
92 ASSERT_EQ(expected_ops, released_ops);
95 uint32_t TestIOBlockGuard::s_index = 0;