1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #include "test/librbd/test_fixture.h"
4 #include "test/librbd/test_support.h"
5 #include "librbd/ExclusiveLock.h"
6 #include "librbd/ImageCtx.h"
7 #include "librbd/ImageWatcher.h"
8 #include "librbd/internal.h"
9 #include "librbd/ObjectMap.h"
10 #include "cls/rbd/cls_rbd_client.h"
13 void register_test_object_map() {
16 class TestObjectMap
: public TestFixture
{
19 int when_open_object_map(librbd::ImageCtx
*ictx
) {
21 librbd::ObjectMap
<> object_map(*ictx
, ictx
->snap_id
);
22 object_map
.open(&ctx
);
27 TEST_F(TestObjectMap
, RefreshInvalidatesWhenCorrupt
) {
28 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP
);
30 librbd::ImageCtx
*ictx
;
31 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
32 ASSERT_FALSE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));
36 RWLock::WLocker
owner_locker(ictx
->owner_lock
);
37 ictx
->exclusive_lock
->try_acquire_lock(&lock_ctx
);
39 ASSERT_EQ(0, lock_ctx
.wait());
41 std::string oid
= librbd::ObjectMap
<>::object_map_name(ictx
->id
, CEPH_NOSNAP
);
44 ASSERT_EQ(0, ictx
->md_ctx
.write_full(oid
, bl
));
46 ASSERT_EQ(0, when_open_object_map(ictx
));
47 ASSERT_TRUE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));
50 TEST_F(TestObjectMap
, RefreshInvalidatesWhenTooSmall
) {
51 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP
);
53 librbd::ImageCtx
*ictx
;
54 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
55 ASSERT_FALSE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));
59 RWLock::WLocker
owner_locker(ictx
->owner_lock
);
60 ictx
->exclusive_lock
->try_acquire_lock(&lock_ctx
);
62 ASSERT_EQ(0, lock_ctx
.wait());
64 librados::ObjectWriteOperation op
;
65 librbd::cls_client::object_map_resize(&op
, 0, OBJECT_NONEXISTENT
);
67 std::string oid
= librbd::ObjectMap
<>::object_map_name(ictx
->id
, CEPH_NOSNAP
);
68 ASSERT_EQ(0, ictx
->md_ctx
.operate(oid
, &op
));
70 ASSERT_EQ(0, when_open_object_map(ictx
));
71 ASSERT_TRUE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));
74 TEST_F(TestObjectMap
, InvalidateFlagOnDisk
) {
75 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP
);
77 librbd::ImageCtx
*ictx
;
78 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
79 ASSERT_FALSE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));
83 RWLock::WLocker
owner_locker(ictx
->owner_lock
);
84 ictx
->exclusive_lock
->try_acquire_lock(&lock_ctx
);
86 ASSERT_EQ(0, lock_ctx
.wait());
88 std::string oid
= librbd::ObjectMap
<>::object_map_name(ictx
->id
, CEPH_NOSNAP
);
91 ASSERT_EQ(0, ictx
->md_ctx
.write_full(oid
, bl
));
93 ASSERT_EQ(0, when_open_object_map(ictx
));
94 ASSERT_TRUE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));
96 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
97 ASSERT_TRUE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));
100 TEST_F(TestObjectMap
, InvalidateFlagInMemoryOnly
) {
101 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP
);
103 librbd::ImageCtx
*ictx
;
104 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
105 ASSERT_FALSE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));
107 std::string oid
= librbd::ObjectMap
<>::object_map_name(ictx
->id
, CEPH_NOSNAP
);
109 ASSERT_LT(0, ictx
->md_ctx
.read(oid
, valid_bl
, 0, 0));
111 bufferlist corrupt_bl
;
112 corrupt_bl
.append("corrupt");
113 ASSERT_EQ(0, ictx
->md_ctx
.write_full(oid
, corrupt_bl
));
115 ASSERT_EQ(0, when_open_object_map(ictx
));
116 ASSERT_TRUE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));
118 ASSERT_EQ(0, ictx
->md_ctx
.write_full(oid
, valid_bl
));
119 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
120 ASSERT_FALSE(ictx
->test_flags(RBD_FLAG_OBJECT_MAP_INVALID
));