]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
test/rgw: add unittest_rgw_reshard_wait 25357/head
authorCasey Bodley <cbodley@redhat.com>
Sat, 24 Nov 2018 23:15:09 +0000 (18:15 -0500)
committerCasey Bodley <cbodley@redhat.com>
Fri, 30 Nov 2018 19:37:03 +0000 (14:37 -0500)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/test/rgw/CMakeLists.txt
src/test/rgw/test_rgw_reshard_wait.cc [new file with mode: 0644]

index 9efb55866f8c2905be8309f553bbc9f9d7f9c674..efbc8a3b60ce9cbd6afa2826c3a00f079ed123ad 100644 (file)
@@ -20,6 +20,11 @@ add_executable(unittest_http_manager test_http_manager.cc)
 add_ceph_unittest(unittest_http_manager)
 target_link_libraries(unittest_http_manager rgw_a)
 
+# unitttest_rgw_reshard_wait
+add_executable(unittest_rgw_reshard_wait test_rgw_reshard_wait.cc)
+add_ceph_unittest(unittest_rgw_reshard_wait)
+target_link_libraries(unittest_rgw_reshard_wait rgw_a)
+
 set(test_rgw_a_src
   test_rgw_common.cc)
 add_library(test_rgw_a STATIC ${test_rgw_a_src})
diff --git a/src/test/rgw/test_rgw_reshard_wait.cc b/src/test/rgw/test_rgw_reshard_wait.cc
new file mode 100644 (file)
index 0000000..a0e4bd2
--- /dev/null
@@ -0,0 +1,161 @@
+// -*- 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) 2018 Red Hat, Inc.
+ *
+ * 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 "rgw/rgw_reshard.h"
+
+#include <gtest/gtest.h>
+
+using namespace std::chrono_literals;
+
+TEST(ReshardWait, wait_block)
+{
+  constexpr ceph::timespan wait_duration = 10ms;
+  RGWReshardWait waiter(wait_duration);
+
+  const ceph::real_time start = ceph::real_clock::now();
+  EXPECT_EQ(0, waiter.wait(null_yield));
+  const ceph::timespan elapsed = ceph::real_clock::now() - start;
+
+  EXPECT_LE(wait_duration, elapsed); // waited at least 10ms
+  waiter.stop();
+}
+
+TEST(ReshardWait, stop_block)
+{
+  constexpr ceph::timespan short_duration = 10ms;
+  constexpr ceph::timespan long_duration = 10s;
+
+  RGWReshardWait long_waiter(long_duration);
+  RGWReshardWait short_waiter(short_duration);
+
+  const ceph::real_time start = ceph::real_clock::now();
+  std::thread thread([&long_waiter] {
+    EXPECT_EQ(-ECANCELED, long_waiter.wait(null_yield));
+  });
+
+  EXPECT_EQ(0, short_waiter.wait(null_yield));
+
+  long_waiter.stop(); // cancel long waiter
+
+  thread.join();
+  const ceph::timespan elapsed = ceph::real_clock::now() - start;
+
+  EXPECT_LE(short_duration, elapsed); // waited at least 10ms
+  EXPECT_GT(long_duration, elapsed); // waited less than 10s
+  short_waiter.stop();
+}
+
+TEST(ReshardWait, wait_yield)
+{
+  constexpr ceph::timespan wait_duration = 10ms;
+  RGWReshardWait waiter(wait_duration);
+
+  boost::asio::io_context context;
+  boost::asio::spawn(context, [&] (boost::asio::yield_context yield) {
+      EXPECT_EQ(0, waiter.wait(optional_yield{context, yield}));
+    });
+
+  EXPECT_EQ(1u, context.poll()); // spawn
+  EXPECT_FALSE(context.stopped());
+
+  const ceph::real_time start = ceph::real_clock::now();
+  EXPECT_EQ(1u, context.run_one()); // timeout
+  EXPECT_TRUE(context.stopped());
+  const ceph::timespan elapsed = ceph::real_clock::now() - start;
+
+  EXPECT_LE(wait_duration, elapsed); // waited at least 10ms
+  waiter.stop();
+}
+
+TEST(ReshardWait, stop_yield)
+{
+  constexpr ceph::timespan short_duration = 10ms;
+  constexpr ceph::timespan long_duration = 10s;
+
+  RGWReshardWait long_waiter(long_duration);
+  RGWReshardWait short_waiter(short_duration);
+
+  boost::asio::io_context context;
+  boost::asio::spawn(context,
+    [&] (boost::asio::yield_context yield) {
+      EXPECT_EQ(-ECANCELED, long_waiter.wait(optional_yield{context, yield}));
+    });
+
+  EXPECT_EQ(1u, context.poll()); // spawn
+  EXPECT_FALSE(context.stopped());
+
+  const ceph::real_time start = ceph::real_clock::now();
+  EXPECT_EQ(0, short_waiter.wait(null_yield));
+
+  long_waiter.stop(); // cancel long waiter
+
+  EXPECT_EQ(1u, context.run_one_for(short_duration)); // timeout
+  EXPECT_TRUE(context.stopped());
+  const ceph::timespan elapsed = ceph::real_clock::now() - start;
+
+  EXPECT_LE(short_duration, elapsed); // waited at least 10ms
+  EXPECT_GT(long_duration, elapsed); // waited less than 10s
+  short_waiter.stop();
+}
+
+TEST(ReshardWait, stop_multiple)
+{
+  constexpr ceph::timespan short_duration = 10ms;
+  constexpr ceph::timespan long_duration = 10s;
+
+  RGWReshardWait long_waiter(long_duration);
+  RGWReshardWait short_waiter(short_duration);
+
+  // spawn 4 threads
+  std::vector<std::thread> threads;
+  {
+    auto sync_waiter([&long_waiter] {
+      EXPECT_EQ(-ECANCELED, long_waiter.wait(null_yield));
+    });
+    threads.emplace_back(sync_waiter);
+    threads.emplace_back(sync_waiter);
+    threads.emplace_back(sync_waiter);
+    threads.emplace_back(sync_waiter);
+  }
+  // spawn 4 coroutines
+  boost::asio::io_context context;
+  {
+    auto async_waiter = [&] (boost::asio::yield_context yield) {
+        EXPECT_EQ(-ECANCELED, long_waiter.wait(optional_yield{context, yield}));
+      };
+    boost::asio::spawn(context, async_waiter);
+    boost::asio::spawn(context, async_waiter);
+    boost::asio::spawn(context, async_waiter);
+    boost::asio::spawn(context, async_waiter);
+  }
+  EXPECT_EQ(4u, context.poll()); // spawn
+  EXPECT_FALSE(context.stopped());
+
+  const ceph::real_time start = ceph::real_clock::now();
+  EXPECT_EQ(0, short_waiter.wait(null_yield));
+
+  long_waiter.stop(); // cancel long waiter
+
+  EXPECT_EQ(4u, context.run_for(short_duration)); // timeout
+  EXPECT_TRUE(context.stopped());
+
+  for (auto& thread : threads) {
+    thread.join();
+  }
+  const ceph::timespan elapsed = ceph::real_clock::now() - start;
+
+  EXPECT_LE(short_duration, elapsed); // waited at least 10ms
+  EXPECT_GT(long_duration, elapsed); // waited less than 10s
+  short_waiter.stop();
+}