Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: ceph_test_rados_api_watch_notify: test timeout using rados_wat… #14061

Merged
merged 1 commit into from Mar 22, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
182 changes: 97 additions & 85 deletions src/test/librados/watch_notify.cc
Expand Up @@ -319,91 +319,6 @@ TEST_F(LibRadosWatchNotify, AioWatchDelete) {
rados_aio_release(comp);
}

TEST_F(LibRadosWatchNotify, Watch2Timeout) {
notify_io = ioctx;
notify_oid = "foo";
notify_cookies.clear();
notify_err = 0;
char buf[128];
memset(buf, 0xcc, sizeof(buf));
ASSERT_EQ(0, rados_write(ioctx, notify_oid, buf, sizeof(buf), 0));
uint64_t handle;
time_t start = time(0);
ASSERT_EQ(0,
rados_watch2(ioctx, notify_oid, &handle,
watch_notify2_test_cb,
watch_notify2_test_errcb, this));
int age = rados_watch_check(ioctx, handle);
time_t age_bound = time(0) + 1 - start;
ASSERT_LT(age, age_bound * 1000);
ASSERT_GT(age, 0);
rados_conf_set(cluster, "objecter_inject_no_watch_ping", "true");
int left = 900;
std::cout << "waiting up to " << left << " for osd to time us out ..."
<< std::endl;
while (notify_err == 0 && --left) {
sleep(1);
}
ASSERT_TRUE(left > 0);
rados_conf_set(cluster, "objecter_inject_no_watch_ping", "false");
ASSERT_EQ(-ENOTCONN, notify_err);
ASSERT_EQ(-ENOTCONN, rados_watch_check(ioctx, handle));

// a subsequent notify should not reach us
char *reply_buf = 0;
size_t reply_buf_len;
ASSERT_EQ(0, rados_notify2(ioctx, notify_oid,
"notify", 6, 300000,
&reply_buf, &reply_buf_len));
{
bufferlist reply;
reply.append(reply_buf, reply_buf_len);
std::map<std::pair<uint64_t,uint64_t>, bufferlist> reply_map;
std::set<std::pair<uint64_t,uint64_t> > missed_map;
bufferlist::iterator reply_p = reply.begin();
::decode(reply_map, reply_p);
::decode(missed_map, reply_p);
ASSERT_EQ(0u, reply_map.size());
ASSERT_EQ(0u, missed_map.size());
}
ASSERT_EQ(0u, notify_cookies.size());
ASSERT_EQ(-ENOTCONN, rados_watch_check(ioctx, handle));
rados_buffer_free(reply_buf);

// re-watch
rados_unwatch2(ioctx, handle);
handle = 0;
ASSERT_EQ(0,
rados_watch2(ioctx, notify_oid, &handle,
watch_notify2_test_cb,
watch_notify2_test_errcb, this));
ASSERT_GT(rados_watch_check(ioctx, handle), 0);

// and now a notify will work.
ASSERT_EQ(0, rados_notify2(ioctx, notify_oid,
"notify", 6, 300000,
&reply_buf, &reply_buf_len));
{
bufferlist reply;
reply.append(reply_buf, reply_buf_len);
std::map<std::pair<uint64_t,uint64_t>, bufferlist> reply_map;
std::set<std::pair<uint64_t,uint64_t> > missed_map;
bufferlist::iterator reply_p = reply.begin();
::decode(reply_map, reply_p);
::decode(missed_map, reply_p);
ASSERT_EQ(1u, reply_map.size());
ASSERT_EQ(0u, missed_map.size());
ASSERT_EQ(1u, notify_cookies.count(handle));
ASSERT_EQ(5u, reply_map.begin()->second.length());
ASSERT_EQ(0, strncmp("reply", reply_map.begin()->second.c_str(), 5));
}
ASSERT_EQ(1u, notify_cookies.size());
ASSERT_GT(rados_watch_check(ioctx, handle), 0);

rados_buffer_free(reply_buf);
rados_unwatch2(ioctx, handle);
}

// --

TEST_F(LibRadosWatchNotify, WatchNotify2) {
Expand Down Expand Up @@ -849,6 +764,103 @@ TEST_P(LibRadosWatchNotifyPP, WatchNotify3) {
ioctx.unwatch2(handle);
}

TEST_F(LibRadosWatchNotify, Watch3Timeout) {
notify_io = ioctx;
notify_oid = "foo";
notify_cookies.clear();
notify_err = 0;
char buf[128];
memset(buf, 0xcc, sizeof(buf));
ASSERT_EQ(0, rados_write(ioctx, notify_oid, buf, sizeof(buf), 0));
uint64_t handle;
time_t start = time(0);
const uint32_t timeout = 4;
{
// make sure i timeout before the messenger reconnects to the OSD,
// it will resend a watch request on behalf of the client, and the
// timer of timeout on OSD side will be reset by the new request.
char conf[128];
ASSERT_EQ(0, rados_conf_get(cluster,
"ms_tcp_read_timeout",
conf, sizeof(conf)));
auto tcp_read_timeout = std::stoll(conf);
ASSERT_LT(timeout, tcp_read_timeout);
}
ASSERT_EQ(0,
rados_watch3(ioctx, notify_oid, &handle,
watch_notify2_test_cb, watch_notify2_test_errcb,
timeout, this));
int age = rados_watch_check(ioctx, handle);
time_t age_bound = time(0) + 1 - start;
ASSERT_LT(age, age_bound * 1000);
ASSERT_GT(age, 0);
rados_conf_set(cluster, "objecter_inject_no_watch_ping", "true");
int left = 2 * timeout;
std::cout << "waiting up to " << left << " for osd to time us out ..."
<< std::endl;
while (notify_err == 0 && --left) {
sleep(1);
}
ASSERT_GT(left, 0);
rados_conf_set(cluster, "objecter_inject_no_watch_ping", "false");
ASSERT_EQ(-ENOTCONN, notify_err);
ASSERT_EQ(-ENOTCONN, rados_watch_check(ioctx, handle));

// a subsequent notify should not reach us
char *reply_buf = nullptr;
size_t reply_buf_len;
ASSERT_EQ(0, rados_notify2(ioctx, notify_oid,
"notify", 6, 300000,
&reply_buf, &reply_buf_len));
{
bufferlist reply;
reply.append(reply_buf, reply_buf_len);
std::map<std::pair<uint64_t,uint64_t>, bufferlist> reply_map;
std::set<std::pair<uint64_t,uint64_t> > missed_map;
bufferlist::iterator reply_p = reply.begin();
::decode(reply_map, reply_p);
::decode(missed_map, reply_p);
ASSERT_EQ(0u, reply_map.size());
ASSERT_EQ(0u, missed_map.size());
}
ASSERT_EQ(0u, notify_cookies.size());
ASSERT_EQ(-ENOTCONN, rados_watch_check(ioctx, handle));
rados_buffer_free(reply_buf);

// re-watch
rados_unwatch2(ioctx, handle);
handle = 0;
ASSERT_EQ(0,
rados_watch2(ioctx, notify_oid, &handle,
watch_notify2_test_cb,
watch_notify2_test_errcb, this));
ASSERT_GT(rados_watch_check(ioctx, handle), 0);

// and now a notify will work.
ASSERT_EQ(0, rados_notify2(ioctx, notify_oid,
"notify", 6, 300000,
&reply_buf, &reply_buf_len));
{
bufferlist reply;
reply.append(reply_buf, reply_buf_len);
std::map<std::pair<uint64_t,uint64_t>, bufferlist> reply_map;
std::set<std::pair<uint64_t,uint64_t> > missed_map;
bufferlist::iterator reply_p = reply.begin();
::decode(reply_map, reply_p);
::decode(missed_map, reply_p);
ASSERT_EQ(1u, reply_map.size());
ASSERT_EQ(0u, missed_map.size());
ASSERT_EQ(1u, notify_cookies.count(handle));
ASSERT_EQ(5u, reply_map.begin()->second.length());
ASSERT_EQ(0, strncmp("reply", reply_map.begin()->second.c_str(), 5));
}
ASSERT_EQ(1u, notify_cookies.size());
ASSERT_GT(rados_watch_check(ioctx, handle), 0);

rados_buffer_free(reply_buf);
rados_unwatch2(ioctx, handle);
}

TEST_F(LibRadosWatchNotify, AioWatchDelete2) {
notify_io = ioctx;
notify_oid = "foo";
Expand Down