]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/test/librados/watch_notify.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / test / librados / watch_notify.cc
index d9bf58c5d1bdef7985a897ff41d70716cb8075ac..4d880f2c2504ff89e885d7abac13c35dbb2f0f17 100644 (file)
@@ -2,6 +2,7 @@
 #include "include/rados/rados_types.h"
 #include "test/librados/test.h"
 #include "test/librados/TestCase.h"
+#include "crimson_utils.h"
 
 #include <errno.h>
 #include <fcntl.h>
@@ -33,6 +34,7 @@ protected:
   rados_ioctx_t notify_io;
   const char *notify_oid = nullptr;
   int notify_err = 0;
+  rados_completion_t notify_comp;
 
   static void watch_notify2_test_cb(void *arg,
                                     uint64_t notify_id,
@@ -41,6 +43,8 @@ protected:
                                     void *data,
                                     size_t data_len);
   static void watch_notify2_test_errcb(void *arg, uint64_t cookie, int err);
+  static void watch_notify2_test_errcb_reconnect(void *arg, uint64_t cookie, int err);
+  static void watch_notify2_test_errcb_aio_reconnect(void *arg, uint64_t cookie, int err);
 };
 
 
@@ -61,6 +65,7 @@ void LibRadosWatchNotify::watch_notify2_test_cb(void *arg,
   thiz->notify_bl.append((char*)data, data_len);
   if (notify_sleep)
     sleep(notify_sleep);
+  thiz->notify_err = 0;
   rados_notify_ack(thiz->notify_io, thiz->notify_oid, notify_id, cookie,
                    "reply", 5);
 }
@@ -76,6 +81,49 @@ void LibRadosWatchNotify::watch_notify2_test_errcb(void *arg,
   thiz->notify_err = err;
 }
 
+void LibRadosWatchNotify::watch_notify2_test_errcb_reconnect(void *arg,
+                                                   uint64_t cookie,
+                                                   int err)
+{
+  std::cout << __func__ << " cookie " << cookie << " err " << err << std::endl;
+  ceph_assert(cookie > 1000);
+  auto thiz = reinterpret_cast<LibRadosWatchNotify*>(arg);
+  ceph_assert(thiz);
+  thiz->notify_err = rados_unwatch2(thiz->ioctx, cookie);
+  thiz->notify_cookies.erase(cookie); //delete old cookie
+  thiz->notify_err = rados_watch2(thiz->ioctx, thiz->notify_oid, &cookie,
+                  watch_notify2_test_cb, watch_notify2_test_errcb_reconnect, thiz);
+  if (thiz->notify_err < 0) {
+    std::cout << __func__ << " reconnect watch failed with error " << thiz->notify_err << std::endl;
+    return;
+  }
+  return;
+}
+
+
+void LibRadosWatchNotify::watch_notify2_test_errcb_aio_reconnect(void *arg,
+                                                   uint64_t cookie,
+                                                   int err)
+{
+  std::cout << __func__ << " cookie " << cookie << " err " << err << std::endl;
+  ceph_assert(cookie > 1000);
+  auto thiz = reinterpret_cast<LibRadosWatchNotify*>(arg);
+  ceph_assert(thiz);
+  thiz->notify_err = rados_aio_unwatch(thiz->ioctx, cookie, thiz->notify_comp);
+  ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr, &thiz->notify_comp));
+  thiz->notify_cookies.erase(cookie); //delete old cookie
+  thiz->notify_err = rados_aio_watch(thiz->ioctx, thiz->notify_oid, thiz->notify_comp, &cookie,
+                  watch_notify2_test_cb, watch_notify2_test_errcb_aio_reconnect, thiz);
+  ASSERT_EQ(0, rados_aio_wait_for_complete(thiz->notify_comp));
+  ASSERT_EQ(0, rados_aio_get_return_value(thiz->notify_comp));
+  rados_aio_release(thiz->notify_comp);
+  if (thiz->notify_err < 0) {
+    std::cout << __func__ << " reconnect watch failed with error " << thiz->notify_err << std::endl;
+    return;
+  }
+  return;
+}
+
 class WatchNotifyTestCtx2;
 
 // --
@@ -113,6 +161,7 @@ TEST_F(LibRadosWatchNotify, WatchNotify) {
 }
 
 TEST_F(LibRadosWatchNotifyEC, WatchNotify) {
+  SKIP_IF_CRIMSON();
   ASSERT_EQ(0, sem_init(&sem, 0, 0));
   char buf[128];
   memset(buf, 0xcc, sizeof(buf));
@@ -196,7 +245,10 @@ TEST_F(LibRadosWatchNotify, AioWatchDelete) {
   }
   ASSERT_TRUE(left > 0);
   ASSERT_EQ(-ENOTCONN, notify_err);
-  ASSERT_EQ(-ENOTCONN, rados_watch_check(ioctx, handle));
+  int rados_watch_check_err = rados_watch_check(ioctx, handle);
+  // We may hit ENOENT due to socket failure injection and a forced reconnect
+  EXPECT_TRUE(rados_watch_check_err == -ENOTCONN || rados_watch_check_err == -ENOENT)
+    << "Where rados_watch_check_err = " << rados_watch_check_err;
   ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr, &comp));
   rados_aio_unwatch(ioctx, handle, comp);
   ASSERT_EQ(0, rados_aio_wait_for_complete(comp));
@@ -217,7 +269,7 @@ TEST_F(LibRadosWatchNotify, WatchNotify2) {
   ASSERT_EQ(0,
       rados_watch2(ioctx, notify_oid, &handle,
                   watch_notify2_test_cb,
-                  watch_notify2_test_errcb, this));
+                  watch_notify2_test_errcb_reconnect, this));
   ASSERT_GT(rados_watch_check(ioctx, handle), 0);
   char *reply_buf = 0;
   size_t reply_buf_len;
@@ -234,6 +286,7 @@ TEST_F(LibRadosWatchNotify, WatchNotify2) {
   ASSERT_EQ(1u, reply_map.size());
   ASSERT_EQ(0u, missed_map.size());
   ASSERT_EQ(1u, notify_cookies.size());
+  handle = *notify_cookies.begin();
   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));
@@ -259,15 +312,14 @@ TEST_F(LibRadosWatchNotify, AioWatchNotify2) {
   char buf[128];
   memset(buf, 0xcc, sizeof(buf));
   ASSERT_EQ(0, rados_write(ioctx, notify_oid, buf, sizeof(buf), 0));
-
-  rados_completion_t comp;
   uint64_t handle;
-  ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr, &comp));
-  rados_aio_watch(ioctx, notify_oid, comp, &handle,
-                  watch_notify2_test_cb, watch_notify2_test_errcb, this);
-  ASSERT_EQ(0, rados_aio_wait_for_complete(comp));
-  ASSERT_EQ(0, rados_aio_get_return_value(comp));
-  rados_aio_release(comp);
+  ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr, &notify_comp));
+  rados_aio_watch(ioctx, notify_oid, notify_comp, &handle,
+                  watch_notify2_test_cb, watch_notify2_test_errcb_aio_reconnect, this);
+  
+  ASSERT_EQ(0, rados_aio_wait_for_complete(notify_comp));
+  ASSERT_EQ(0, rados_aio_get_return_value(notify_comp));
+  rados_aio_release(notify_comp);
 
   ASSERT_GT(rados_watch_check(ioctx, handle), 0);
   char *reply_buf = 0;
@@ -285,6 +337,7 @@ TEST_F(LibRadosWatchNotify, AioWatchNotify2) {
   ASSERT_EQ(1u, reply_map.size());
   ASSERT_EQ(0u, missed_map.size());
   ASSERT_EQ(1u, notify_cookies.size());
+  handle = *notify_cookies.begin();
   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));
@@ -299,11 +352,11 @@ TEST_F(LibRadosWatchNotify, AioWatchNotify2) {
   ASSERT_EQ((char*)0, reply_buf);
   ASSERT_EQ(0u, reply_buf_len);
 
-  ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr, &comp));
-  rados_aio_unwatch(ioctx, handle, comp);
-  ASSERT_EQ(0, rados_aio_wait_for_complete(comp));
-  ASSERT_EQ(0, rados_aio_get_return_value(comp));
-  rados_aio_release(comp);
+  ASSERT_EQ(0, rados_aio_create_completion2(nullptr, nullptr, &notify_comp));
+  rados_aio_unwatch(ioctx, handle, notify_comp);
+  ASSERT_EQ(0, rados_aio_wait_for_complete(notify_comp));
+  ASSERT_EQ(0, rados_aio_get_return_value(notify_comp));
+  rados_aio_release(notify_comp);
 }
 
 TEST_F(LibRadosWatchNotify, AioNotify) {