mirror of
https://github.com/ceph/ceph
synced 2024-12-17 17:05:42 +00:00
test/librbd: handle cmpext request in LibradosTestStub
Signed-off-by: Zhengyong Wang <wangzhengyong@cmss.chinamobile.com>
This commit is contained in:
parent
e70d48933c
commit
5891b57a6f
@ -689,6 +689,12 @@ int IoCtx::writesame(const std::string& oid, bufferlist& bl, size_t len,
|
||||
ctx->get_snap_context()));
|
||||
}
|
||||
|
||||
int IoCtx::cmpext(const std::string& oid, uint64_t off, bufferlist& cmp_bl) {
|
||||
TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
|
||||
return ctx->execute_operation(
|
||||
oid, boost::bind(&TestIoCtxImpl::cmpext, _1, _2, off, cmp_bl));
|
||||
}
|
||||
|
||||
int IoCtx::application_enable(const std::string& app_name, bool force) {
|
||||
return 0;
|
||||
}
|
||||
@ -765,6 +771,16 @@ size_t ObjectOperation::size() {
|
||||
return o->ops.size();
|
||||
}
|
||||
|
||||
void ObjectOperation::cmpext(uint64_t off, bufferlist& cmp_bl, int *prval) {
|
||||
TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
|
||||
ObjectOperationTestImpl op = boost::bind(&TestIoCtxImpl::cmpext, _1, _2, off, cmp_bl);
|
||||
if (prval != NULL) {
|
||||
op = boost::bind(save_operation_result,
|
||||
boost::bind(op, _1, _2, _3, _4), prval);
|
||||
}
|
||||
o->ops.push_back(op);
|
||||
}
|
||||
|
||||
void ObjectReadOperation::list_snaps(snap_set_t *out_snaps, int *prval) {
|
||||
TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
|
||||
|
||||
|
@ -147,6 +147,7 @@ public:
|
||||
const SnapContext &snapc) = 0;
|
||||
virtual int writesame(const std::string& oid, bufferlist& bl, size_t len,
|
||||
uint64_t off, const SnapContext &snapc) = 0;
|
||||
virtual int cmpext(const std::string& oid, uint64_t off, bufferlist& cmp_bl) = 0;
|
||||
virtual int xattr_get(const std::string& oid,
|
||||
std::map<std::string, bufferlist>* attrset) = 0;
|
||||
virtual int xattr_set(const std::string& oid, const std::string &name,
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "test/librados_test_stub/TestMemRadosClient.h"
|
||||
#include "common/Clock.h"
|
||||
#include "common/RWLock.h"
|
||||
#include "include/err.h"
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <errno.h>
|
||||
@ -557,7 +558,6 @@ int TestMemIoCtxImpl::writesame(const std::string& oid, bufferlist& bl, size_t l
|
||||
return -EBLACKLISTED;
|
||||
}
|
||||
|
||||
|
||||
if (len == 0 || (len % bl.length())) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -585,6 +585,36 @@ int TestMemIoCtxImpl::writesame(const std::string& oid, bufferlist& bl, size_t l
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TestMemIoCtxImpl::cmpext(const std::string& oid, uint64_t off,
|
||||
bufferlist& cmp_bl) {
|
||||
if (get_snap_read() != CEPH_NOSNAP) {
|
||||
return -EROFS;
|
||||
} else if (m_client->is_blacklisted()) {
|
||||
return -EBLACKLISTED;
|
||||
}
|
||||
|
||||
if (cmp_bl.length() == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
TestMemCluster::SharedFile file;
|
||||
{
|
||||
RWLock::WLocker l(m_pool->file_lock);
|
||||
file = get_file(oid, true, get_snap_context());
|
||||
}
|
||||
|
||||
RWLock::RLocker l(file->lock);
|
||||
size_t len = cmp_bl.length();
|
||||
ensure_minimum_length(off + len, &file->data);
|
||||
if (len > 0 && off <= len) {
|
||||
for (uint64_t p = off; p < len; p++) {
|
||||
if (file->data[p] != cmp_bl[p])
|
||||
return -MAX_ERRNO - p;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TestMemIoCtxImpl::xattr_get(const std::string& oid,
|
||||
std::map<std::string, bufferlist>* attrset) {
|
||||
if (m_client->is_blacklisted()) {
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
const SnapContext &snapc) override;
|
||||
int writesame(const std::string& oid, bufferlist& bl, size_t len,
|
||||
uint64_t off, const SnapContext &snapc) override;
|
||||
int cmpext(const std::string& oid, uint64_t off, bufferlist& cmp_bl) override;
|
||||
int xattr_get(const std::string& oid,
|
||||
std::map<std::string, bufferlist>* attrset) override;
|
||||
int xattr_set(const std::string& oid, const std::string &name,
|
||||
|
@ -97,6 +97,22 @@ struct ObjectRequest<librbd::MockTestImageCtx> : public ObjectRequestHandle {
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
static ObjectRequest* create_compare_and_write(librbd::MockTestImageCtx *ictx,
|
||||
const std::string &oid,
|
||||
uint64_t object_no,
|
||||
uint64_t object_off,
|
||||
const ceph::bufferlist &cmp_data,
|
||||
const ceph::bufferlist &write_data,
|
||||
const ::SnapContext &snapc,
|
||||
uint64_t *mismatch_offset,
|
||||
int op_flags,
|
||||
const ZTracer::Trace &parent_trace,
|
||||
Context *completion) {
|
||||
assert(s_instance != nullptr);
|
||||
s_instance->on_finish = completion;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
ObjectRequest() {
|
||||
assert(s_instance == nullptr);
|
||||
s_instance = this;
|
||||
@ -168,6 +184,7 @@ struct TestMockIoImageRequest : public TestMockFixture {
|
||||
typedef ImageDiscardRequest<librbd::MockTestImageCtx> MockImageDiscardRequest;
|
||||
typedef ImageFlushRequest<librbd::MockTestImageCtx> MockImageFlushRequest;
|
||||
typedef ImageWriteSameRequest<librbd::MockTestImageCtx> MockImageWriteSameRequest;
|
||||
typedef ImageCompareAndWriteRequest<librbd::MockTestImageCtx> MockImageCompareAndWriteRequest;
|
||||
typedef ObjectRequest<librbd::MockTestImageCtx> MockObjectRequest;
|
||||
typedef ObjectReadRequest<librbd::MockTestImageCtx> MockObjectReadRequest;
|
||||
|
||||
@ -334,5 +351,41 @@ TEST_F(TestMockIoImageRequest, AioWriteSameJournalAppendDisabled) {
|
||||
ASSERT_EQ(0, aio_comp_ctx.wait());
|
||||
}
|
||||
|
||||
TEST_F(TestMockIoImageRequest, AioCompareAndWriteJournalAppendDisabled) {
|
||||
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
|
||||
|
||||
librbd::ImageCtx *ictx;
|
||||
ASSERT_EQ(0, open_image(m_image_name, &ictx));
|
||||
|
||||
MockObjectRequest mock_aio_object_request;
|
||||
MockTestImageCtx mock_image_ctx(*ictx);
|
||||
MockJournal mock_journal;
|
||||
mock_image_ctx.journal = &mock_journal;
|
||||
|
||||
InSequence seq;
|
||||
expect_is_journal_appending(mock_journal, false);
|
||||
expect_object_request_send(mock_image_ctx, mock_aio_object_request, 0);
|
||||
|
||||
C_SaferCond aio_comp_ctx;
|
||||
AioCompletion *aio_comp = AioCompletion::create_and_start(
|
||||
&aio_comp_ctx, ictx, AIO_TYPE_COMPARE_AND_WRITE);
|
||||
|
||||
bufferlist cmp_bl;
|
||||
cmp_bl.append("1");
|
||||
bufferlist write_bl;
|
||||
write_bl.append("1");
|
||||
uint64_t mismatch_offset;
|
||||
MockImageCompareAndWriteRequest mock_aio_image_write(mock_image_ctx, aio_comp,
|
||||
{{0, 1}}, std::move(cmp_bl),
|
||||
std::move(write_bl),
|
||||
&mismatch_offset,
|
||||
0, {});
|
||||
{
|
||||
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
|
||||
mock_aio_image_write.send();
|
||||
}
|
||||
ASSERT_EQ(0, aio_comp_ctx.wait());
|
||||
}
|
||||
|
||||
} // namespace io
|
||||
} // namespace librbd
|
||||
|
Loading…
Reference in New Issue
Block a user