]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rgw/test_rgw_reshard_wait.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / rgw / test_rgw_reshard_wait.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2018 Red Hat, Inc.
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #include "rgw/rgw_reshard.h"
16
17 #include <gtest/gtest.h>
18
19 using namespace std::chrono_literals;
20
21 TEST(ReshardWait, wait_block)
22 {
23 constexpr ceph::timespan wait_duration = 10ms;
24 RGWReshardWait waiter(wait_duration);
25
26 const ceph::real_time start = ceph::real_clock::now();
27 EXPECT_EQ(0, waiter.wait(null_yield));
28 const ceph::timespan elapsed = ceph::real_clock::now() - start;
29
30 EXPECT_LE(wait_duration, elapsed); // waited at least 10ms
31 waiter.stop();
32 }
33
34 TEST(ReshardWait, stop_block)
35 {
36 constexpr ceph::timespan short_duration = 10ms;
37 constexpr ceph::timespan long_duration = 10s;
38
39 RGWReshardWait long_waiter(long_duration);
40 RGWReshardWait short_waiter(short_duration);
41
42 const ceph::real_time start = ceph::real_clock::now();
43 std::thread thread([&long_waiter] {
44 EXPECT_EQ(-ECANCELED, long_waiter.wait(null_yield));
45 });
46
47 EXPECT_EQ(0, short_waiter.wait(null_yield));
48
49 long_waiter.stop(); // cancel long waiter
50
51 thread.join();
52 const ceph::timespan elapsed = ceph::real_clock::now() - start;
53
54 EXPECT_LE(short_duration, elapsed); // waited at least 10ms
55 EXPECT_GT(long_duration, elapsed); // waited less than 10s
56 short_waiter.stop();
57 }
58
59 #ifdef HAVE_BOOST_CONTEXT
60 TEST(ReshardWait, wait_yield)
61 {
62 constexpr ceph::timespan wait_duration = 10ms;
63 RGWReshardWait waiter(wait_duration);
64
65 boost::asio::io_context context;
66 boost::asio::spawn(context, [&] (boost::asio::yield_context yield) {
67 EXPECT_EQ(0, waiter.wait(optional_yield{context, yield}));
68 });
69
70 const ceph::real_time start = ceph::real_clock::now();
71 EXPECT_EQ(1u, context.poll()); // spawn
72 EXPECT_FALSE(context.stopped());
73
74 EXPECT_EQ(1u, context.run_one()); // timeout
75 EXPECT_TRUE(context.stopped());
76 const ceph::timespan elapsed = ceph::real_clock::now() - start;
77
78 EXPECT_LE(wait_duration, elapsed); // waited at least 10ms
79 waiter.stop();
80 }
81
82 TEST(ReshardWait, stop_yield)
83 {
84 constexpr ceph::timespan short_duration = 10ms;
85 constexpr ceph::timespan long_duration = 10s;
86
87 RGWReshardWait long_waiter(long_duration);
88 RGWReshardWait short_waiter(short_duration);
89
90 boost::asio::io_context context;
91 boost::asio::spawn(context,
92 [&] (boost::asio::yield_context yield) {
93 EXPECT_EQ(-ECANCELED, long_waiter.wait(optional_yield{context, yield}));
94 });
95
96 EXPECT_EQ(1u, context.poll()); // spawn
97 EXPECT_FALSE(context.stopped());
98
99 const ceph::real_time start = ceph::real_clock::now();
100 EXPECT_EQ(0, short_waiter.wait(null_yield));
101
102 long_waiter.stop(); // cancel long waiter
103
104 EXPECT_EQ(1u, context.run_one_for(short_duration)); // timeout
105 EXPECT_TRUE(context.stopped());
106 const ceph::timespan elapsed = ceph::real_clock::now() - start;
107
108 EXPECT_LE(short_duration, elapsed); // waited at least 10ms
109 EXPECT_GT(long_duration, elapsed); // waited less than 10s
110 short_waiter.stop();
111 }
112
113 TEST(ReshardWait, stop_multiple)
114 {
115 constexpr ceph::timespan short_duration = 10ms;
116 constexpr ceph::timespan long_duration = 10s;
117
118 RGWReshardWait long_waiter(long_duration);
119 RGWReshardWait short_waiter(short_duration);
120
121 // spawn 4 threads
122 std::vector<std::thread> threads;
123 {
124 auto sync_waiter([&long_waiter] {
125 EXPECT_EQ(-ECANCELED, long_waiter.wait(null_yield));
126 });
127 threads.emplace_back(sync_waiter);
128 threads.emplace_back(sync_waiter);
129 threads.emplace_back(sync_waiter);
130 threads.emplace_back(sync_waiter);
131 }
132 // spawn 4 coroutines
133 boost::asio::io_context context;
134 {
135 auto async_waiter = [&] (boost::asio::yield_context yield) {
136 EXPECT_EQ(-ECANCELED, long_waiter.wait(optional_yield{context, yield}));
137 };
138 boost::asio::spawn(context, async_waiter);
139 boost::asio::spawn(context, async_waiter);
140 boost::asio::spawn(context, async_waiter);
141 boost::asio::spawn(context, async_waiter);
142 }
143 EXPECT_EQ(4u, context.poll()); // spawn
144 EXPECT_FALSE(context.stopped());
145
146 const ceph::real_time start = ceph::real_clock::now();
147 EXPECT_EQ(0, short_waiter.wait(null_yield));
148
149 long_waiter.stop(); // cancel long waiter
150
151 EXPECT_EQ(4u, context.run_for(short_duration)); // timeout
152 EXPECT_TRUE(context.stopped());
153
154 for (auto& thread : threads) {
155 thread.join();
156 }
157 const ceph::timespan elapsed = ceph::real_clock::now() - start;
158
159 EXPECT_LE(short_duration, elapsed); // waited at least 10ms
160 EXPECT_GT(long_duration, elapsed); // waited less than 10s
161 short_waiter.stop();
162 }
163 #endif // HAVE_BOOST_CONTEXT