]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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" | |
9f95a23c | 16 | #include <spawn/spawn.hpp> |
11fdf7f2 TL |
17 | |
18 | #include <gtest/gtest.h> | |
19 | ||
20 | using namespace std::chrono_literals; | |
81eedcae | 21 | using Clock = RGWReshardWait::Clock; |
11fdf7f2 TL |
22 | |
23 | TEST(ReshardWait, wait_block) | |
24 | { | |
25 | constexpr ceph::timespan wait_duration = 10ms; | |
26 | RGWReshardWait waiter(wait_duration); | |
27 | ||
81eedcae | 28 | const auto start = Clock::now(); |
11fdf7f2 | 29 | EXPECT_EQ(0, waiter.wait(null_yield)); |
81eedcae | 30 | const ceph::timespan elapsed = Clock::now() - start; |
11fdf7f2 TL |
31 | |
32 | EXPECT_LE(wait_duration, elapsed); // waited at least 10ms | |
33 | waiter.stop(); | |
34 | } | |
35 | ||
36 | TEST(ReshardWait, stop_block) | |
37 | { | |
38 | constexpr ceph::timespan short_duration = 10ms; | |
39 | constexpr ceph::timespan long_duration = 10s; | |
40 | ||
41 | RGWReshardWait long_waiter(long_duration); | |
42 | RGWReshardWait short_waiter(short_duration); | |
43 | ||
81eedcae | 44 | const auto start = Clock::now(); |
11fdf7f2 TL |
45 | std::thread thread([&long_waiter] { |
46 | EXPECT_EQ(-ECANCELED, long_waiter.wait(null_yield)); | |
47 | }); | |
48 | ||
49 | EXPECT_EQ(0, short_waiter.wait(null_yield)); | |
50 | ||
51 | long_waiter.stop(); // cancel long waiter | |
52 | ||
53 | thread.join(); | |
81eedcae | 54 | const ceph::timespan elapsed = Clock::now() - start; |
11fdf7f2 TL |
55 | |
56 | EXPECT_LE(short_duration, elapsed); // waited at least 10ms | |
57 | EXPECT_GT(long_duration, elapsed); // waited less than 10s | |
58 | short_waiter.stop(); | |
59 | } | |
60 | ||
11fdf7f2 TL |
61 | TEST(ReshardWait, wait_yield) |
62 | { | |
9f95a23c | 63 | constexpr ceph::timespan wait_duration = 50ms; |
11fdf7f2 TL |
64 | RGWReshardWait waiter(wait_duration); |
65 | ||
66 | boost::asio::io_context context; | |
20effc67 | 67 | spawn::spawn(context, [&] (yield_context yield) { |
11fdf7f2 TL |
68 | EXPECT_EQ(0, waiter.wait(optional_yield{context, yield})); |
69 | }); | |
70 | ||
81eedcae | 71 | const auto start = Clock::now(); |
11fdf7f2 TL |
72 | EXPECT_EQ(1u, context.poll()); // spawn |
73 | EXPECT_FALSE(context.stopped()); | |
74 | ||
75 | EXPECT_EQ(1u, context.run_one()); // timeout | |
76 | EXPECT_TRUE(context.stopped()); | |
81eedcae | 77 | const ceph::timespan elapsed = Clock::now() - start; |
11fdf7f2 TL |
78 | |
79 | EXPECT_LE(wait_duration, elapsed); // waited at least 10ms | |
80 | waiter.stop(); | |
81 | } | |
82 | ||
83 | TEST(ReshardWait, stop_yield) | |
84 | { | |
9f95a23c | 85 | constexpr ceph::timespan short_duration = 50ms; |
11fdf7f2 TL |
86 | constexpr ceph::timespan long_duration = 10s; |
87 | ||
88 | RGWReshardWait long_waiter(long_duration); | |
89 | RGWReshardWait short_waiter(short_duration); | |
90 | ||
91 | boost::asio::io_context context; | |
9f95a23c | 92 | spawn::spawn(context, |
20effc67 | 93 | [&] (yield_context yield) { |
11fdf7f2 TL |
94 | EXPECT_EQ(-ECANCELED, long_waiter.wait(optional_yield{context, yield})); |
95 | }); | |
96 | ||
81eedcae | 97 | const auto start = Clock::now(); |
11fdf7f2 TL |
98 | EXPECT_EQ(1u, context.poll()); // spawn |
99 | EXPECT_FALSE(context.stopped()); | |
100 | ||
11fdf7f2 TL |
101 | EXPECT_EQ(0, short_waiter.wait(null_yield)); |
102 | ||
103 | long_waiter.stop(); // cancel long waiter | |
104 | ||
105 | EXPECT_EQ(1u, context.run_one_for(short_duration)); // timeout | |
106 | EXPECT_TRUE(context.stopped()); | |
81eedcae | 107 | const ceph::timespan elapsed = Clock::now() - start; |
11fdf7f2 TL |
108 | |
109 | EXPECT_LE(short_duration, elapsed); // waited at least 10ms | |
110 | EXPECT_GT(long_duration, elapsed); // waited less than 10s | |
111 | short_waiter.stop(); | |
112 | } | |
113 | ||
114 | TEST(ReshardWait, stop_multiple) | |
115 | { | |
9f95a23c | 116 | constexpr ceph::timespan short_duration = 50ms; |
11fdf7f2 TL |
117 | constexpr ceph::timespan long_duration = 10s; |
118 | ||
119 | RGWReshardWait long_waiter(long_duration); | |
120 | RGWReshardWait short_waiter(short_duration); | |
121 | ||
122 | // spawn 4 threads | |
123 | std::vector<std::thread> threads; | |
124 | { | |
125 | auto sync_waiter([&long_waiter] { | |
126 | EXPECT_EQ(-ECANCELED, long_waiter.wait(null_yield)); | |
127 | }); | |
128 | threads.emplace_back(sync_waiter); | |
129 | threads.emplace_back(sync_waiter); | |
130 | threads.emplace_back(sync_waiter); | |
131 | threads.emplace_back(sync_waiter); | |
132 | } | |
133 | // spawn 4 coroutines | |
134 | boost::asio::io_context context; | |
135 | { | |
20effc67 | 136 | auto async_waiter = [&] (yield_context yield) { |
11fdf7f2 TL |
137 | EXPECT_EQ(-ECANCELED, long_waiter.wait(optional_yield{context, yield})); |
138 | }; | |
9f95a23c TL |
139 | spawn::spawn(context, async_waiter); |
140 | spawn::spawn(context, async_waiter); | |
141 | spawn::spawn(context, async_waiter); | |
142 | spawn::spawn(context, async_waiter); | |
11fdf7f2 | 143 | } |
81eedcae TL |
144 | |
145 | const auto start = Clock::now(); | |
11fdf7f2 TL |
146 | EXPECT_EQ(4u, context.poll()); // spawn |
147 | EXPECT_FALSE(context.stopped()); | |
148 | ||
11fdf7f2 TL |
149 | EXPECT_EQ(0, short_waiter.wait(null_yield)); |
150 | ||
151 | long_waiter.stop(); // cancel long waiter | |
152 | ||
153 | EXPECT_EQ(4u, context.run_for(short_duration)); // timeout | |
154 | EXPECT_TRUE(context.stopped()); | |
155 | ||
156 | for (auto& thread : threads) { | |
157 | thread.join(); | |
158 | } | |
81eedcae | 159 | const ceph::timespan elapsed = Clock::now() - start; |
11fdf7f2 TL |
160 | |
161 | EXPECT_LE(short_duration, elapsed); // waited at least 10ms | |
162 | EXPECT_GT(long_duration, elapsed); // waited less than 10s | |
163 | short_waiter.stop(); | |
164 | } |