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_mock_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
7 #include "common/bit_vector.hpp"
8 #include "librbd/internal.h"
9 #include "librbd/ObjectMap.h"
10 #include "librbd/object_map/ResizeRequest.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
15 namespace object_map {
18 using ::testing::DoDefault;
19 using ::testing::Return;
20 using ::testing::StrEq;
22 class TestMockObjectMapResizeRequest : public TestMockFixture {
24 void expect_resize(librbd::ImageCtx *ictx, uint64_t snap_id, int r) {
25 std::string oid(ObjectMap<>::object_map_name(ictx->id, snap_id));
26 if (snap_id == CEPH_NOSNAP) {
27 EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
28 exec(oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
29 .WillOnce(DoDefault());
33 EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
34 exec(oid, _, StrEq("rbd"), StrEq("object_map_resize"), _, _, _))
37 EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
38 exec(oid, _, StrEq("rbd"), StrEq("object_map_resize"), _, _, _))
39 .WillOnce(DoDefault());
43 void expect_invalidate(librbd::ImageCtx *ictx) {
44 EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
45 exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
46 .WillOnce(DoDefault());
50 TEST_F(TestMockObjectMapResizeRequest, UpdateInMemory) {
51 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
53 librbd::ImageCtx *ictx;
54 ASSERT_EQ(0, open_image(m_image_name, &ictx));
55 ASSERT_EQ(0, acquire_exclusive_lock(*ictx));
57 ceph::BitVector<2> object_map;
61 AsyncRequest<> *req = new ResizeRequest(
62 *ictx, &object_map, CEPH_NOSNAP, object_map.size(), OBJECT_EXISTS,
65 ASSERT_EQ(0, cond_ctx.wait());
67 for (uint64_t i = 0; i < object_map.size(); ++i) {
68 ASSERT_EQ(i == 0 ? OBJECT_NONEXISTENT : OBJECT_EXISTS,
73 TEST_F(TestMockObjectMapResizeRequest, UpdateHeadOnDisk) {
74 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
76 librbd::ImageCtx *ictx;
77 ASSERT_EQ(0, open_image(m_image_name, &ictx));
78 ASSERT_EQ(0, acquire_exclusive_lock(*ictx));
80 expect_resize(ictx, CEPH_NOSNAP, 0);
82 ceph::BitVector<2> object_map;
86 AsyncRequest<> *req = new ResizeRequest(
87 *ictx, &object_map, CEPH_NOSNAP, object_map.size(), OBJECT_EXISTS,
90 ASSERT_EQ(0, cond_ctx.wait());
92 expect_unlock_exclusive_lock(*ictx);
95 TEST_F(TestMockObjectMapResizeRequest, UpdateSnapOnDisk) {
96 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
98 librbd::ImageCtx *ictx;
99 ASSERT_EQ(0, open_image(m_image_name, &ictx));
100 ASSERT_EQ(0, snap_create(*ictx, "snap1"));
101 ASSERT_EQ(0, librbd::snap_set(ictx,
102 cls::rbd::UserSnapshotNamespace(),
105 uint64_t snap_id = ictx->snap_id;
106 expect_resize(ictx, snap_id, 0);
108 ceph::BitVector<2> object_map;
109 object_map.resize(1);
111 C_SaferCond cond_ctx;
112 AsyncRequest<> *req = new ResizeRequest(
113 *ictx, &object_map, snap_id, object_map.size(), OBJECT_EXISTS,
116 ASSERT_EQ(0, cond_ctx.wait());
118 expect_unlock_exclusive_lock(*ictx);
121 TEST_F(TestMockObjectMapResizeRequest, UpdateOnDiskError) {
122 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
124 librbd::ImageCtx *ictx;
125 ASSERT_EQ(0, open_image(m_image_name, &ictx));
126 ASSERT_EQ(0, acquire_exclusive_lock(*ictx));
128 expect_resize(ictx, CEPH_NOSNAP, -EINVAL);
129 expect_invalidate(ictx);
131 ceph::BitVector<2> object_map;
132 object_map.resize(1);
134 C_SaferCond cond_ctx;
135 AsyncRequest<> *req = new ResizeRequest(
136 *ictx, &object_map, CEPH_NOSNAP, object_map.size(), OBJECT_EXISTS,
139 ASSERT_EQ(0, cond_ctx.wait());
141 expect_unlock_exclusive_lock(*ictx);
144 } // namespace object_map
145 } // namespace librbd