cache_ioctx.aio_operate(
it->get_oid(), completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL);
- completion->wait_for_safe();
+ completion->wait_for_complete();
completion->get_return_value();
completion->release();
}
cache_ioctx.aio_operate(
it->get_oid(), completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL);
- completion->wait_for_safe();
+ completion->wait_for_complete();
completion->get_return_value();
completion->release();
}
}
}
+static string _get_required_osd_release(Rados& cluster)
+{
+ bufferlist inbl;
+ string cmd = string("{\"prefix\": \"osd dump\",\"format\":\"json\"}");
+ bufferlist outbl;
+ int r = cluster.mon_command(cmd, inbl, &outbl, NULL);
+ ceph_assert(r >= 0);
+ string outstr(outbl.c_str(), outbl.length());
+ json_spirit::Value v;
+ if (!json_spirit::read(outstr, v)) {
+ cerr <<" unable to parse json " << outstr << std::endl;
+ return "";
+ }
+
+ json_spirit::Object& o = v.get_obj();
+ for (json_spirit::Object::size_type i=0; i<o.size(); i++) {
+ json_spirit::Pair& p = o[i];
+ if (p.name_ == "require_osd_release") {
+ cout << "require_osd_release = " << p.value_.get_str() << std::endl;
+ return p.value_.get_str();
+ }
+ }
+ cerr << "didn't find require_osd_release in " << outstr << std::endl;
+ return "";
+}
+
class LibRadosTwoPoolsPP : public RadosTestPP
{
public:
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
ASSERT_EQ('b', bl[0]);
ioctx.snap_set_read(my_snaps[0]);
- // read foo snap
+ // read foo snap. the OSD may or may not realize that this snap has
+ // been logically deleted; either response is valid.
{
bufferlist bl;
- ASSERT_EQ(-ENOENT, ioctx.read("foo", bl, 1, 0));
+ int r = ioctx.read("foo", bl, 1, 0);
+ ASSERT_TRUE(r == 1 || r == -ENOENT);
}
// cleanup
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("bar", completion, &op,
librados::OPERATION_IGNORE_CACHE));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op,
librados::OPERATION_IGNORE_CACHE,
NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EPERM, completion->get_return_value());
completion->release();
}
op.cache_unpin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op,
librados::OPERATION_IGNORE_CACHE,
NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EBUSY, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"bam", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"bam", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-ENOENT, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-ENOENT, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EBUSY, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-ENOENT, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-ENOENT, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
0, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, snap_ret);
ASSERT_LT(0u, snap_set.clones.size());
for (vector<librados::clone_info_t>::const_iterator r = snap_set.clones.begin();
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EPERM, completion->get_return_value());
completion->release();
}
op.cache_unpin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op, librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EPERM, completion->get_return_value());
completion->release();
}
op.cache_unpin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op, librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op, librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EBUSY, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EBUSY, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion2, &op2, 0));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
ASSERT_EQ(0, completion2->get_return_value());
completion->release();
librados::AioCompletion *completion2 = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion2, &op2, 0));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
int r = completion->get_return_value();
ASSERT_TRUE(r == -EBUSY || r == 0);
ASSERT_EQ(0, completion2->get_return_value());
"foo", completion2, &op2,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
ASSERT_EQ(0, completion2->get_return_value());
completion->release();
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
ASSERT_EQ(0, completion2->get_return_value());
completion->release();
"foo", completion2, &op2,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
int r = completion->get_return_value();
ASSERT_TRUE(r == -EBUSY || r == 0);
ASSERT_EQ(0, completion2->get_return_value());
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
ASSERT_EQ(0, completion2->get_return_value());
completion->release();
IoCtx *read_ioctx = 0;
-Mutex test_lock("FlushReadRaces::lock");
-Cond cond;
+ceph::mutex test_lock = ceph::make_mutex("FlushReadRaces::lock");
+ceph::condition_variable cond;
int max_reads = 100;
int num_reads = 0; // in progress
void flush_read_race_cb(completion_t cb, void *arg)
{
//cout << " finished read" << std::endl;
- test_lock.Lock();
+ std::lock_guard l{test_lock};
if (num_reads > max_reads) {
num_reads--;
- cond.Signal();
+ cond.notify_all();
} else {
start_flush_read();
}
- test_lock.Unlock();
}
TEST_F(LibRadosTwoPoolsPP, TryFlushReadRace) {
// start a continuous stream of reads
read_ioctx = &ioctx;
- test_lock.Lock();
+ test_lock.lock();
for (int i = 0; i < max_reads; ++i) {
start_flush_read();
num_reads++;
}
- test_lock.Unlock();
+ test_lock.unlock();
// try-flush
ObjectReadOperation op;
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
// stop reads
- test_lock.Lock();
- max_reads = 0;
- while (num_reads > 0)
- cond.Wait(test_lock);
- test_lock.Unlock();
+ std::unique_lock locker{test_lock};
+ max_reads = 0;
+ cond.wait(locker, [] { return num_reads == 0;});
}
TEST_F(LibRadosTierPP, HitSetNone) {
return -1;
}
-
TEST_F(LibRadosTwoPoolsPP, HitSetWrite) {
int num_pg = _get_pg_num(cluster, pool_name);
ceph_assert(num_pg > 0);
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("baz", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.set_redirect("bar", cache_ioctx, 0);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
TEST_F(LibRadosTwoPoolsPP, SetChunkRead) {
// skip test if not yet mimic
- {
- bufferlist inbl, outbl;
- ASSERT_EQ(0, cluster.mon_command(
- "{\"prefix\": \"osd dump\"}",
- inbl, &outbl, NULL));
- string s(outbl.c_str(), outbl.length());
- if (s.find("mimic") == std::string::npos) {
- cout << "cluster is not yet mimic, skipping test" << std::endl;
- return;
- }
+ if (_get_required_osd_release(cluster) < "mimic") {
+ GTEST_SKIP() << "cluster is not yet mimic, skipping test";
}
// create object
}
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
TEST_F(LibRadosTwoPoolsPP, ManifestPromoteRead) {
// skip test if not yet mimic
- {
- bufferlist inbl, outbl;
- ASSERT_EQ(0, cluster.mon_command(
- "{\"prefix\": \"osd dump\"}",
- inbl, &outbl, NULL));
- string s(outbl.c_str(), outbl.length());
- if (s.find("mimic") == std::string::npos) {
- cout << "cluster is not yet mimic, skipping test" << std::endl;
- return;
- }
+ if (_get_required_osd_release(cluster) < "mimic") {
+ GTEST_SKIP() << "cluster is not yet mimic, skipping test";
}
// create object
op.set_redirect("bar", cache_ioctx, 0);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.set_chunk(0, 2, cache_ioctx, "bar-chunk", 0);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.tier_promote();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.tier_promote();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.set_redirect("bar", cache_ioctx, 0, CEPH_OSD_OP_FLAG_WITH_REFERENCE);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.set_chunk(0, 2, cache_ioctx, "bar-chunk", 0, CEPH_OSD_OP_FLAG_WITH_REFERENCE);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
TEST_F(LibRadosTwoPoolsPP, ManifestUnset) {
// skip test if not yet nautilus
- {
- bufferlist inbl, outbl;
- ASSERT_EQ(0, cluster.mon_command(
- "{\"prefix\": \"osd dump\"}",
- inbl, &outbl, NULL));
- string s(outbl.c_str(), outbl.length());
- if (s.find("nautilus") == std::string::npos) {
- cout << "cluster is not yet nautilus, skipping test" << std::endl;
- return;
- }
+ if (_get_required_osd_release(cluster) < "nautilus") {
+ GTEST_SKIP() << "cluster is not yet nautilus, skipping test";
}
// create object
op.set_redirect("bar", cache_ioctx, 0, CEPH_OSD_OP_FLAG_WITH_REFERENCE);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.set_chunk(0, 2, cache_ioctx, "bar-chunk", 0, CEPH_OSD_OP_FLAG_WITH_REFERENCE);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.unset_manifest();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.unset_manifest();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.unset_manifest();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EOPNOTSUPP, completion->get_return_value());
completion->release();
}
op.unset_manifest();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EOPNOTSUPP, completion->get_return_value());
completion->release();
}
#include "rgw/rgw_common.h"
TEST_F(LibRadosTwoPoolsPP, ManifestDedupRefRead) {
// skip test if not yet nautilus
- {
- bufferlist inbl, outbl;
- ASSERT_EQ(0, cluster.mon_command(
- "{\"prefix\": \"osd dump\"}",
- inbl, &outbl, NULL));
- string s(outbl.c_str(), outbl.length());
- if (s.find("nautilus") == std::string::npos) {
- cout << "cluster is not yet nautilus, skipping test" << std::endl;
- return;
- }
+ if (_get_required_osd_release(cluster) < "nautilus") {
+ GTEST_SKIP() << "cluster is not yet nautilus, skipping test";
}
+
bufferlist inbl;
ASSERT_EQ(0, cluster.mon_command(
set_pool_str(pool_name, "fingerprint_algorithm", "sha1"),
CEPH_OSD_OP_FLAG_WITH_REFERENCE);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo-dedup", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
CEPH_OSD_OP_FLAG_WITH_REFERENCE);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
cluster.wait_for_latest_osdmap();
}
+TEST_F(LibRadosTwoPoolsPP, ManifestFlushRead) {
+ // skip test if not yet octopus
+ if (_get_required_osd_release(cluster) < "octopus") {
+ GTEST_SKIP() << "cluster is not yet octopus, skipping test";
+ }
+
+ // create object
+ {
+ bufferlist bl;
+ bl.append("base chunk");
+ ObjectWriteOperation op;
+ op.write_full(bl);
+ ASSERT_EQ(0, ioctx.operate("foo-chunk", &op));
+ }
+ {
+ bufferlist bl;
+ bl.append("CHUNKS");
+ ObjectWriteOperation op;
+ op.write_full(bl);
+ ASSERT_EQ(0, cache_ioctx.operate("bar-chunk", &op));
+ }
+
+ // configure tier
+ bufferlist inbl;
+ ASSERT_EQ(0, cluster.mon_command(
+ "{\"prefix\": \"osd tier add\", \"pool\": \"" + pool_name +
+ "\", \"tierpool\": \"" + cache_pool_name +
+ "\", \"force_nonempty\": \"--force-nonempty\" }",
+ inbl, NULL, NULL));
+
+ // wait for maps to settle
+ cluster.wait_for_latest_osdmap();
+
+ // set-chunk
+ {
+ ObjectWriteOperation op;
+ op.set_chunk(0, 2, cache_ioctx, "bar-chunk", 0);
+ librados::AioCompletion *completion = cluster.aio_create_completion();
+ ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
+ completion->wait_for_complete();
+ ASSERT_EQ(0, completion->get_return_value());
+ completion->release();
+ }
+ // set-chunk
+ {
+ ObjectWriteOperation op;
+ op.set_chunk(2, 2, cache_ioctx, "bar-chunk", 2);
+ librados::AioCompletion *completion = cluster.aio_create_completion();
+ ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
+ completion->wait_for_complete();
+ ASSERT_EQ(0, completion->get_return_value());
+ completion->release();
+ }
+ // make chunked object dirty
+ {
+ bufferlist bl;
+ bl.append("DD");
+ ObjectWriteOperation op;
+ op.write(0, bl);
+ ASSERT_EQ(0, ioctx.operate("foo-chunk", &op));
+ }
+ // flush
+ {
+ ObjectWriteOperation op;
+ op.tier_flush();
+ librados::AioCompletion *completion = cluster.aio_create_completion();
+ ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
+ completion->wait_for_complete();
+ ASSERT_EQ(0, completion->get_return_value());
+ completion->release();
+ }
+ // read and verify the chunked object
+ {
+ bufferlist bl;
+ ASSERT_EQ(1, cache_ioctx.read("bar-chunk", bl, 1, 0));
+ ASSERT_EQ('D', bl[0]);
+ }
+
+ ASSERT_EQ(0, cluster.mon_command(
+ "{\"prefix\": \"osd tier remove\", \"pool\": \"" + pool_name +
+ "\", \"tierpool\": \"" + cache_pool_name + "\"}",
+ inbl, NULL, NULL));
+
+ // wait for maps to settle before next test
+ cluster.wait_for_latest_osdmap();
+}
+
class LibRadosTwoPoolsECPP : public RadosTestECPP
{
public:
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
ASSERT_EQ('b', bl[0]);
ioctx.snap_set_read(my_snaps[0]);
- // read foo snap
+ // read foo snap. the OSD may or may not realize that this snap has
+ // been logically deleted; either response is valid.
{
bufferlist bl;
- ASSERT_EQ(-ENOENT, ioctx.read("foo", bl, 1, 0));
+ int r = ioctx.read("foo", bl, 1, 0);
+ ASSERT_TRUE(r == 1 || r == -ENOENT);
}
// cleanup
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("bar", completion, &op,
librados::OPERATION_IGNORE_CACHE));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op,
librados::OPERATION_IGNORE_CACHE,
NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EPERM, completion->get_return_value());
completion->release();
}
op.cache_unpin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op,
librados::OPERATION_IGNORE_CACHE,
NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EBUSY, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"bam", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"bam", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-ENOENT, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-ENOENT, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EBUSY, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"bar", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EPERM, completion->get_return_value());
completion->release();
}
op.cache_unpin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op, librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.omap_set(omap);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_NE(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op, librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EPERM, completion->get_return_value());
completion->release();
}
op.cache_unpin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op, librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op, librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EBUSY, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(-EBUSY, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_CACHE, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, ioctx.aio_operate(
"foo", completion2, &op2, 0));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
ASSERT_EQ(0, completion2->get_return_value());
completion->release();
librados::AioCompletion *completion2 = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion2, &op2, 0));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
int r = completion->get_return_value();
ASSERT_TRUE(r == -EBUSY || r == 0);
ASSERT_EQ(0, completion2->get_return_value());
"foo", completion2, &op2,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
ASSERT_EQ(0, completion2->get_return_value());
completion->release();
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
ASSERT_EQ(0, completion2->get_return_value());
completion->release();
"foo", completion2, &op2,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
int r = completion->get_return_value();
ASSERT_TRUE(r == -EBUSY || r == 0);
ASSERT_EQ(0, completion2->get_return_value());
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
- completion2->wait_for_safe();
+ completion->wait_for_complete();
+ completion2->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
ASSERT_EQ(0, completion2->get_return_value());
completion->release();
// start a continuous stream of reads
read_ioctx = &ioctx;
- test_lock.Lock();
+ test_lock.lock();
for (int i = 0; i < max_reads; ++i) {
start_flush_read();
num_reads++;
}
- test_lock.Unlock();
+ test_lock.unlock();
// try-flush
ObjectReadOperation op;
librados::OPERATION_IGNORE_OVERLAY |
librados::OPERATION_SKIPRWLOCKS, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
// stop reads
- test_lock.Lock();
- max_reads = 0;
- while (num_reads > 0)
- cond.Wait(test_lock);
- test_lock.Unlock();
+ std::unique_lock locker{test_lock};
+ max_reads = 0;
+ cond.wait(locker, [] { return num_reads == 0;});
}
TEST_F(LibRadosTierECPP, CallForcesPromote) {
ASSERT_EQ(0, cache_ioctx.aio_operate(
"foo", completion, &op,
librados::OPERATION_IGNORE_OVERLAY, NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op,
librados::OPERATION_IGNORE_CACHE,
NULL));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
cluster.wait_for_latest_osdmap();
ASSERT_EQ(0, cluster.pool_delete(cache_pool_name.c_str()));
- ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
+ ASSERT_EQ(0, destroy_one_ec_pool_pp(pool_name, cluster));
}
TEST_F(LibRadosTierECPP, HitSetNone) {
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.cache_pin();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, cache_ioctx.aio_operate("baz", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.set_redirect("bar", cache_ioctx, 0);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.set_chunk(0, 8, cache_ioctx, "bar", 0);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.set_redirect("bar", cache_ioctx, 0);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.set_chunk(0, 10, cache_ioctx, "bar-chunk", 0);
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.tier_promote();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
op.tier_promote();
librados::AioCompletion *completion = cluster.aio_create_completion();
ASSERT_EQ(0, ioctx.aio_operate("foo-chunk", completion, &op));
- completion->wait_for_safe();
+ completion->wait_for_complete();
ASSERT_EQ(0, completion->get_return_value());
completion->release();
}
ASSERT_EQ(-ECANCELED, ioctx.operate("propagate-base-tier-error", &op2));
}
+
+TEST_F(LibRadosTwoPoolsPP, HelloWriteReturn) {
+ // configure cache
+ bufferlist inbl;
+ ASSERT_EQ(0, cluster.mon_command(
+ "{\"prefix\": \"osd tier add\", \"pool\": \"" + pool_name +
+ "\", \"tierpool\": \"" + cache_pool_name +
+ "\", \"force_nonempty\": \"--force-nonempty\" }",
+ inbl, NULL, NULL));
+ ASSERT_EQ(0, cluster.mon_command(
+ "{\"prefix\": \"osd tier set-overlay\", \"pool\": \"" + pool_name +
+ "\", \"overlaypool\": \"" + cache_pool_name + "\"}",
+ inbl, NULL, NULL));
+ ASSERT_EQ(0, cluster.mon_command(
+ "{\"prefix\": \"osd tier cache-mode\", \"pool\": \"" + cache_pool_name +
+ "\", \"mode\": \"writeback\"}",
+ inbl, NULL, NULL));
+
+ // set things up such that the op would normally be proxied
+ ASSERT_EQ(0, cluster.mon_command(
+ set_pool_str(cache_pool_name, "hit_set_count", 2),
+ inbl, NULL, NULL));
+ ASSERT_EQ(0, cluster.mon_command(
+ set_pool_str(cache_pool_name, "hit_set_period", 600),
+ inbl, NULL, NULL));
+ ASSERT_EQ(0, cluster.mon_command(
+ set_pool_str(cache_pool_name, "hit_set_type",
+ "explicit_object"),
+ inbl, NULL, NULL));
+ ASSERT_EQ(0, cluster.mon_command(
+ set_pool_str(cache_pool_name, "min_read_recency_for_promote",
+ "10000"),
+ inbl, NULL, NULL));
+
+ // wait for maps to settle
+ cluster.wait_for_latest_osdmap();
+
+ // this *will* return data due to the RETURNVEC flag
+ {
+ bufferlist in, out;
+ int rval;
+ ObjectWriteOperation o;
+ o.exec("hello", "write_return_data", in, &out, &rval);
+ librados::AioCompletion *completion = cluster.aio_create_completion();
+ ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &o,
+ librados::OPERATION_RETURNVEC));
+ completion->wait_for_complete();
+ ASSERT_EQ(42, completion->get_return_value());
+ ASSERT_EQ(42, rval);
+ out.hexdump(std::cout);
+ ASSERT_EQ("you might see this", std::string(out.c_str(), out.length()));
+ }
+
+ // this will overflow because the return data is too big
+ {
+ bufferlist in, out;
+ int rval;
+ ObjectWriteOperation o;
+ o.exec("hello", "write_too_much_return_data", in, &out, &rval);
+ librados::AioCompletion *completion = cluster.aio_create_completion();
+ ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &o,
+ librados::OPERATION_RETURNVEC));
+ completion->wait_for_complete();
+ ASSERT_EQ(-EOVERFLOW, completion->get_return_value());
+ ASSERT_EQ(-EOVERFLOW, rval);
+ ASSERT_EQ("", std::string(out.c_str(), out.length()));
+ }
+}