#include <sstream>
#include <string>
+#include "cls/cas/cls_cas_client.h"
+#include "cls/cas/cls_cas_internal.h"
+
using namespace librados;
using std::map;
using std::ostringstream;
return string();
}
+void is_intended_refcount_state(librados::IoCtx& src_ioctx,
+ std::string src_oid,
+ librados::IoCtx& dst_ioctx,
+ std::string dst_oid,
+ int expected_refcount)
+{
+ int src_refcount = 0, dst_refcount = 0;
+ bufferlist t;
+ int r = dst_ioctx.getxattr(dst_oid, CHUNK_REFCOUNT_ATTR, t);
+ if (r == -ENOENT) {
+ dst_refcount = 0;
+ } else {
+ chunk_refs_t refs;
+ try {
+ auto iter = t.cbegin();
+ decode(refs, iter);
+ } catch (buffer::error& err) {
+ ceph_assert(0);
+ }
+ dst_refcount = refs.count();
+ }
+ r = cls_cas_references_chunk(src_ioctx, src_oid, dst_oid);
+ if (r == -ENOENT || r == -ENOLINK) {
+ src_refcount = 0;
+ } else {
+ src_refcount = r;
+ }
+ ASSERT_TRUE(src_refcount >= 0);
+ ASSERT_TRUE(src_refcount == expected_refcount);
+ ASSERT_TRUE(src_refcount <= dst_refcount);
+}
+
class LibRadosTwoPoolsPP : public RadosTestPP
{
public:
sha1_gen.Update((const unsigned char *)"hi", size);
sha1_gen.Final(fingerprint);
buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
- cache_ioctx.getxattr(p_str, CHUNK_REFCOUNT_ATTR, t);
- chunk_refs_t refs;
- try {
- auto iter = t.cbegin();
- decode(refs, iter);
- } catch (buffer::error& err) {
- ASSERT_TRUE(0);
- }
- ASSERT_EQ(1u, refs.count());
+ is_intended_refcount_state(ioctx, "foo", cache_ioctx, p_str, 1);
}
// check chunk's refcount
sha1_gen.Update((const unsigned char *)"hi", size);
sha1_gen.Final(fingerprint);
buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
- cache_ioctx.getxattr(p_str, CHUNK_REFCOUNT_ATTR, t);
- chunk_refs_t refs;
- try {
- auto iter = t.cbegin();
- decode(refs, iter);
- } catch (buffer::error& err) {
- ASSERT_TRUE(0);
- }
- ASSERT_EQ(1u, refs.count());
+ is_intended_refcount_state(ioctx, "foo", cache_ioctx, p_str, 1);
}
// remove snap
sha1_gen.Update((const unsigned char *)"bb", size);
sha1_gen.Final(fingerprint);
buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
- cache_ioctx.getxattr(p_str, CHUNK_REFCOUNT_ATTR, t);
- chunk_refs_t refs;
- try {
- auto iter = t.cbegin();
- decode(refs, iter);
- } catch (buffer::error& err) {
- ASSERT_TRUE(0);
- }
- ASSERT_EQ(1u, refs.count());
+ is_intended_refcount_state(ioctx, "foo", cache_ioctx, p_str, 1);
}
// remove snap
sha1_gen.Update((const unsigned char *)"bb", size);
sha1_gen.Final(fingerprint);
buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
- cache_ioctx.getxattr(p_str, CHUNK_REFCOUNT_ATTR, t);
- chunk_refs_t refs;
- try {
- auto iter = t.cbegin();
- decode(refs, iter);
- } catch (buffer::error& err) {
- ASSERT_TRUE(0);
- }
- ASSERT_EQ(1u, refs.count());
+ is_intended_refcount_state(ioctx, "foo", cache_ioctx, p_str, 1);
}
// check chunk's refcount
sha1_gen.Update((const unsigned char *)"hi", size);
sha1_gen.Final(fingerprint);
buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
- cache_ioctx.getxattr(p_str, CHUNK_REFCOUNT_ATTR, t);
- chunk_refs_t refs;
- try {
- auto iter = t.cbegin();
- decode(refs, iter);
- } catch (buffer::error& err) {
- ASSERT_TRUE(0);
- }
- ASSERT_EQ(1u, refs.count());
+ is_intended_refcount_state(ioctx, "foo", cache_ioctx, p_str, 1);
}
}
sha1_gen.Update((const unsigned char *)"BB", size);
sha1_gen.Final(fingerprint);
buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
- int r = cache_ioctx.getxattr(p_str, CHUNK_REFCOUNT_ATTR, t);
- ASSERT_EQ(-ENOENT, r);
+ is_intended_refcount_state(ioctx, "foo", cache_ioctx, p_str, 0);
}
}
sha1_gen.Update((const unsigned char *)"ai", size);
sha1_gen.Final(fingerprint);
buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
- int r = cache_ioctx.getxattr(p_str, CHUNK_REFCOUNT_ATTR, t);
- ASSERT_EQ(-ENOENT, r);
+ is_intended_refcount_state(ioctx, "foo", cache_ioctx, p_str, 0);
}
// foo snap[0]: [er] [hi] [HI]
sha1_gen.Update((const unsigned char *)"Er", size);
sha1_gen.Final(fingerprint);
buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
- int r = cache_ioctx.getxattr(p_str, CHUNK_REFCOUNT_ATTR, t);
- ASSERT_EQ(-ENOENT, r);
+ is_intended_refcount_state(ioctx, "foo", cache_ioctx, p_str, 0);
}
}
sleep(10);
// check chunk's refcount
- check_fp_oid_refcount(cache_ioctx, "chunk4", 1u, "");
-
+ is_intended_refcount_state(ioctx, "foo", cache_ioctx, "chunk4", 1);
}
TEST_F(LibRadosTwoPoolsPP, ManifestEvict) {
sha1_gen.Update((const unsigned char *)chunk2.c_str(), size);
sha1_gen.Final(fingerprint);
buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
- tgt_oid = string(p_str);
- ASSERT_EQ(-ENOENT, ioctx.getxattr(p_str, CHUNK_REFCOUNT_ATTR, t));
+ is_intended_refcount_state(cache_ioctx, "foo", ioctx, p_str, 0);
}
}
}
-#include "cls/cas/cls_cas_client.h"
-#include "cls/cas/cls_cas_internal.h"
TEST_F(LibRadosTwoPoolsPP, ManifestSnapHasChunk) {
// skip test if not yet octopus
if (_get_required_osd_release(cluster) < "octopus") {