diff options
author | Sage Weil <sage@inktank.com> | 2012-11-04 12:54:35 +0100 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2012-11-04 12:54:35 +0100 |
commit | e4aa6d7ad70461da78d773c39ff4480cd12f9963 (patch) | |
tree | 138765d3b59ca220c286702a51222c09c2d2b644 /src/test/cls_lock | |
parent | cls_rgw: reorg test_cls_rgw (diff) | |
download | ceph-e4aa6d7ad70461da78d773c39ff4480cd12f9963.tar.xz ceph-e4aa6d7ad70461da78d773c39ff4480cd12f9963.zip |
cls_lock: reorg test_cls_lock
Signed-off-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'src/test/cls_lock')
-rw-r--r-- | src/test/cls_lock/test_cls_lock.cc | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/src/test/cls_lock/test_cls_lock.cc b/src/test/cls_lock/test_cls_lock.cc new file mode 100644 index 00000000000..316bc3f596c --- /dev/null +++ b/src/test/cls_lock/test_cls_lock.cc @@ -0,0 +1,291 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include <iostream> +#include <errno.h> + +#include "include/types.h" +#include "msg/msg_types.h" +#include "include/rados/librados.hpp" + +#include "test/rados-api/test.h" +#include "gtest/gtest.h" + +using namespace librados; + +#include "cls/lock/cls_lock_client.h" +#include "cls/lock/cls_lock_ops.h" + +using namespace rados::cls::lock; + +void lock_info(IoCtx *ioctx, string& oid, string& name, map<locker_id_t, locker_info_t>& lockers, + ClsLockType *assert_type, string *assert_tag) +{ + ClsLockType lock_type = LOCK_NONE; + string tag; + lockers.clear(); + ASSERT_EQ(0, get_lock_info(ioctx, oid, name, &lockers, &lock_type, &tag)); + cout << "lock: " << name << std::endl; + cout << " lock_type: " << cls_lock_type_str(lock_type) << std::endl; + cout << " tag: " << tag << std::endl; + cout << " lockers:" << std::endl; + + if (assert_type) + ASSERT_EQ(*assert_type, lock_type); + + if (assert_tag) + ASSERT_EQ(*assert_tag, tag); + + map<locker_id_t, locker_info_t>::iterator liter; + for (liter = lockers.begin(); liter != lockers.end(); ++liter) { + const locker_id_t& locker = liter->first; + cout << " " << locker.locker << " expiration=" << liter->second.expiration + << " addr=" << liter->second.addr << " cookie=" << locker.cookie << std::endl; + } +} + +void lock_info(IoCtx *ioctx, string& oid, string& name, map<locker_id_t, locker_info_t>& lockers) +{ + lock_info(ioctx, oid, name, lockers, NULL, NULL); +} + +TEST(ClsLock, TestMultiLocking) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + ClsLockType lock_type_shared = LOCK_SHARED; + ClsLockType lock_type_exclusive = LOCK_EXCLUSIVE; + + + Rados cluster2; + IoCtx ioctx2; + ASSERT_EQ("", connect_cluster_pp(cluster2)); + cluster2.ioctx_create(pool_name.c_str(), ioctx2); + + string oid = "foo"; + bufferlist bl; + string lock_name = "mylock"; + + ASSERT_EQ(0, ioctx.write(oid, bl, bl.length(), 0)); + + Lock l(lock_name); + + /* test lock object */ + + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + /* test exclusive lock */ + ASSERT_EQ(-EEXIST, l.lock_exclusive(&ioctx, oid)); + + /* test idempotency */ + l.set_renew(true); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + l.set_renew(false); + + /* test second client */ + Lock l2(lock_name); + ASSERT_EQ(-EBUSY, l2.lock_exclusive(&ioctx2, oid)); + ASSERT_EQ(-EBUSY, l2.lock_shared(&ioctx2, oid)); + + list<string> locks; + ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); + + ASSERT_EQ(1, (int)locks.size()); + list<string>::iterator iter = locks.begin(); + map<locker_id_t, locker_info_t> lockers; + lock_info(&ioctx, oid, *iter, lockers, &lock_type_exclusive, NULL); + + ASSERT_EQ(1, (int)lockers.size()); + + /* test unlock */ + ASSERT_EQ(0, l.unlock(&ioctx, oid)); + locks.clear(); + ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); + + /* test shared lock */ + ASSERT_EQ(0, l2.lock_shared(&ioctx2, oid)); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + + locks.clear(); + ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); + ASSERT_EQ(1, (int)locks.size()); + iter = locks.begin(); + lock_info(&ioctx, oid, *iter, lockers, &lock_type_shared, NULL); + ASSERT_EQ(2, (int)lockers.size()); + + /* test break locks */ + entity_name_t name = entity_name_t::CLIENT(cluster.get_instance_id()); + entity_name_t name2 = entity_name_t::CLIENT(cluster2.get_instance_id()); + + l2.break_lock(&ioctx2, oid, name); + lock_info(&ioctx, oid, *iter, lockers); + ASSERT_EQ(1, (int)lockers.size()); + map<locker_id_t, locker_info_t>::iterator liter = lockers.begin(); + const locker_id_t& id = liter->first; + ASSERT_EQ(name2, id.locker); + + /* test lock tag */ + Lock l_tag(lock_name); + l_tag.set_tag("non-default tag"); + ASSERT_EQ(-EBUSY, l_tag.lock_shared(&ioctx, oid)); + + + /* test modify description */ + string description = "new description"; + l.set_description(description); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} + +TEST(ClsLock, TestMeta) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + + + Rados cluster2; + IoCtx ioctx2; + ASSERT_EQ("", connect_cluster_pp(cluster2)); + cluster2.ioctx_create(pool_name.c_str(), ioctx2); + + string oid = "foo"; + bufferlist bl; + string lock_name = "mylock"; + + ASSERT_EQ(0, ioctx.write(oid, bl, bl.length(), 0)); + + Lock l(lock_name); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + + /* test lock tag */ + Lock l_tag(lock_name); + l_tag.set_tag("non-default tag"); + ASSERT_EQ(-EBUSY, l_tag.lock_shared(&ioctx2, oid)); + + + ASSERT_EQ(0, l.unlock(&ioctx, oid)); + + /* test description */ + Lock l2(lock_name); + string description = "new description"; + l2.set_description(description); + ASSERT_EQ(0, l2.lock_shared(&ioctx2, oid)); + + map<locker_id_t, locker_info_t> lockers; + lock_info(&ioctx, oid, lock_name, lockers, NULL, NULL); + ASSERT_EQ(1, (int)lockers.size()); + + map<locker_id_t, locker_info_t>::iterator iter = lockers.begin(); + locker_info_t locker = iter->second; + ASSERT_EQ("new description", locker.description); + + ASSERT_EQ(0, l2.unlock(&ioctx2, oid)); + + /* check new tag */ + string new_tag = "new_tag"; + l.set_tag(new_tag); + l.set_renew(true); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + lock_info(&ioctx, oid, lock_name, lockers, NULL, &new_tag); + ASSERT_EQ(1, (int)lockers.size()); + l.set_tag(""); + ASSERT_EQ(-EBUSY, l.lock_exclusive(&ioctx, oid)); + l.set_tag(new_tag); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} + +TEST(ClsLock, TestCookie) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + + string oid = "foo"; + string lock_name = "mylock"; + Lock l(lock_name); + + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + /* new cookie */ + string cookie = "new cookie"; + l.set_cookie(cookie); + ASSERT_EQ(-EBUSY, l.lock_exclusive(&ioctx, oid)); + ASSERT_EQ(-ENOENT, l.unlock(&ioctx, oid)); + l.set_cookie(""); + ASSERT_EQ(0, l.unlock(&ioctx, oid)); + + map<locker_id_t, locker_info_t> lockers; + lock_info(&ioctx, oid, lock_name, lockers); + ASSERT_EQ(0, (int)lockers.size()); + + l.set_cookie(cookie); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + l.set_cookie(""); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + + lock_info(&ioctx, oid, lock_name, lockers); + ASSERT_EQ(2, (int)lockers.size()); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} + +TEST(ClsLock, TestMultipleLocks) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + + string oid = "foo"; + Lock l("lock1"); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + Lock l2("lock2"); + ASSERT_EQ(0, l2.lock_exclusive(&ioctx, oid)); + + list<string> locks; + ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); + + ASSERT_EQ(2, (int)locks.size()); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} + +TEST(ClsLock, TestLockDuration) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + + string oid = "foo"; + Lock l("lock"); + l.set_duration(utime_t(5, 0)); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + ASSERT_EQ(-EEXIST, l.lock_exclusive(&ioctx, oid)); + + sleep(5); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} |