websocket_throttler_unittest.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/network/websocket_throttler.h"
  5. #include <vector>
  6. #include "base/test/task_environment.h"
  7. #include "services/network/public/mojom/network_context.mojom-forward.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. #include "third_party/abseil-cpp/absl/types/optional.h"
  10. namespace network {
  11. namespace {
  12. class WebSocketThrottlerTest : public ::testing::Test {
  13. private:
  14. base::test::SingleThreadTaskEnvironment task_environment_;
  15. };
  16. TEST(WebSocketPerProcessThrottlerTest, InitialState) {
  17. WebSocketPerProcessThrottler throttler;
  18. EXPECT_FALSE(throttler.HasTooManyPendingConnections());
  19. EXPECT_EQ(0, throttler.num_pending_connections());
  20. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  21. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  22. EXPECT_EQ(0, throttler.num_current_failed_connections());
  23. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  24. EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
  25. }
  26. TEST(WebSocketPerProcessThrottlerTest, Pending) {
  27. WebSocketPerProcessThrottler throttler;
  28. auto tracker = throttler.IssuePendingConnectionTracker();
  29. EXPECT_FALSE(throttler.HasTooManyPendingConnections());
  30. EXPECT_EQ(1, throttler.num_pending_connections());
  31. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  32. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  33. EXPECT_EQ(0, throttler.num_current_failed_connections());
  34. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  35. EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
  36. }
  37. TEST(WebSocketPerProcessThrottlerTest, Complete) {
  38. WebSocketPerProcessThrottler throttler;
  39. {
  40. auto tracker = throttler.IssuePendingConnectionTracker();
  41. EXPECT_FALSE(throttler.HasTooManyPendingConnections());
  42. EXPECT_EQ(1, throttler.num_pending_connections());
  43. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  44. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  45. EXPECT_EQ(0, throttler.num_current_failed_connections());
  46. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  47. EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
  48. tracker.OnCompleteHandshake();
  49. EXPECT_FALSE(throttler.HasTooManyPendingConnections());
  50. EXPECT_EQ(0, throttler.num_pending_connections());
  51. EXPECT_EQ(1, throttler.num_current_succeeded_connections());
  52. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  53. EXPECT_EQ(0, throttler.num_current_failed_connections());
  54. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  55. EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
  56. // Destruct |tracker|.
  57. }
  58. EXPECT_FALSE(throttler.HasTooManyPendingConnections());
  59. EXPECT_EQ(0, throttler.num_pending_connections());
  60. EXPECT_EQ(1, throttler.num_current_succeeded_connections());
  61. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  62. EXPECT_EQ(0, throttler.num_current_failed_connections());
  63. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  64. EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
  65. }
  66. TEST(WebSocketPerProcessThrottlerTest, Failed) {
  67. WebSocketPerProcessThrottler throttler;
  68. {
  69. auto tracker = throttler.IssuePendingConnectionTracker();
  70. EXPECT_FALSE(throttler.HasTooManyPendingConnections());
  71. EXPECT_EQ(1, throttler.num_pending_connections());
  72. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  73. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  74. EXPECT_EQ(0, throttler.num_current_failed_connections());
  75. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  76. EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
  77. // Destruct |tracker|.
  78. }
  79. EXPECT_FALSE(throttler.HasTooManyPendingConnections());
  80. EXPECT_EQ(0, throttler.num_pending_connections());
  81. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  82. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  83. EXPECT_EQ(1, throttler.num_current_failed_connections());
  84. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  85. EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
  86. }
  87. TEST(WebSocketPerProcessThrottlerTest, TooManyPendingConnections) {
  88. constexpr int limit = 255;
  89. WebSocketPerProcessThrottler throttler;
  90. std::vector<WebSocketPerProcessThrottler::PendingConnection> trackers;
  91. for (int i = 0; i < limit - 1; ++i) {
  92. ASSERT_FALSE(throttler.HasTooManyPendingConnections());
  93. trackers.push_back(throttler.IssuePendingConnectionTracker());
  94. }
  95. ASSERT_FALSE(throttler.HasTooManyPendingConnections());
  96. trackers.push_back(throttler.IssuePendingConnectionTracker());
  97. EXPECT_TRUE(throttler.HasTooManyPendingConnections());
  98. }
  99. TEST(WebSocketPerProcessThrottlerTest, CompletedConnectionsDontCount) {
  100. constexpr int limit = 255;
  101. WebSocketPerProcessThrottler throttler;
  102. for (int i = 0; i < limit * 3; ++i) {
  103. ASSERT_FALSE(throttler.HasTooManyPendingConnections());
  104. auto tracker = throttler.IssuePendingConnectionTracker();
  105. tracker.OnCompleteHandshake();
  106. }
  107. EXPECT_FALSE(throttler.HasTooManyPendingConnections());
  108. }
  109. TEST(WebSocketPerProcessThrottlerTest, FailedConnectionsDontCount) {
  110. constexpr int limit = 255;
  111. WebSocketPerProcessThrottler throttler;
  112. for (int i = 0; i < limit * 3; ++i) {
  113. ASSERT_FALSE(throttler.HasTooManyPendingConnections());
  114. auto tracker = throttler.IssuePendingConnectionTracker();
  115. }
  116. EXPECT_FALSE(throttler.HasTooManyPendingConnections());
  117. }
  118. TEST(WebSocketPerProcessThrottlerTest, Roll) {
  119. WebSocketPerProcessThrottler throttler;
  120. for (int i = 0; i < 2; ++i)
  121. throttler.IssuePendingConnectionTracker().OnCompleteHandshake();
  122. for (int i = 0; i < 3; ++i)
  123. throttler.IssuePendingConnectionTracker();
  124. EXPECT_EQ(0, throttler.num_pending_connections());
  125. EXPECT_EQ(2, throttler.num_current_succeeded_connections());
  126. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  127. EXPECT_EQ(3, throttler.num_current_failed_connections());
  128. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  129. throttler.Roll();
  130. EXPECT_EQ(0, throttler.num_pending_connections());
  131. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  132. EXPECT_EQ(2, throttler.num_previous_succeeded_connections());
  133. EXPECT_EQ(0, throttler.num_current_failed_connections());
  134. EXPECT_EQ(3, throttler.num_previous_failed_connections());
  135. throttler.Roll();
  136. EXPECT_EQ(0, throttler.num_pending_connections());
  137. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  138. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  139. EXPECT_EQ(0, throttler.num_current_failed_connections());
  140. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  141. }
  142. TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_3Pending) {
  143. WebSocketPerProcessThrottler throttler;
  144. std::vector<WebSocketPerProcessThrottler::PendingConnection> trackers;
  145. for (int i = 0; i < 3; ++i)
  146. trackers.push_back(throttler.IssuePendingConnectionTracker());
  147. EXPECT_EQ(3, throttler.num_pending_connections());
  148. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  149. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  150. EXPECT_EQ(0, throttler.num_current_failed_connections());
  151. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  152. EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
  153. }
  154. TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_7Pending) {
  155. WebSocketPerProcessThrottler throttler;
  156. std::vector<WebSocketPerProcessThrottler::PendingConnection> trackers;
  157. for (int i = 0; i < 7; ++i)
  158. trackers.push_back(throttler.IssuePendingConnectionTracker());
  159. EXPECT_EQ(7, throttler.num_pending_connections());
  160. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  161. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  162. EXPECT_EQ(0, throttler.num_current_failed_connections());
  163. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  164. EXPECT_LT(base::TimeDelta(), throttler.CalculateDelay());
  165. }
  166. TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_16Pending) {
  167. WebSocketPerProcessThrottler throttler;
  168. std::vector<WebSocketPerProcessThrottler::PendingConnection> trackers;
  169. for (int i = 0; i < 16; ++i)
  170. trackers.push_back(throttler.IssuePendingConnectionTracker());
  171. EXPECT_EQ(16, throttler.num_pending_connections());
  172. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  173. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  174. EXPECT_EQ(0, throttler.num_current_failed_connections());
  175. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  176. EXPECT_LE(base::Milliseconds(1000), throttler.CalculateDelay());
  177. EXPECT_LE(throttler.CalculateDelay(), base::Milliseconds(5000));
  178. }
  179. TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_3Failure) {
  180. WebSocketPerProcessThrottler throttler;
  181. for (int i = 0; i < 3; ++i)
  182. throttler.IssuePendingConnectionTracker();
  183. EXPECT_EQ(0, throttler.num_pending_connections());
  184. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  185. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  186. EXPECT_EQ(3, throttler.num_current_failed_connections());
  187. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  188. EXPECT_EQ(base::TimeDelta(), throttler.CalculateDelay());
  189. }
  190. TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_7Failure) {
  191. WebSocketPerProcessThrottler throttler;
  192. for (int i = 0; i < 7; ++i)
  193. throttler.IssuePendingConnectionTracker();
  194. EXPECT_EQ(0, throttler.num_pending_connections());
  195. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  196. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  197. EXPECT_EQ(7, throttler.num_current_failed_connections());
  198. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  199. EXPECT_LT(base::TimeDelta(), throttler.CalculateDelay());
  200. }
  201. TEST(WebSocketPerProcessThrottlerTest, CalculateDelay_16Failure) {
  202. WebSocketPerProcessThrottler throttler;
  203. for (int i = 0; i < 16; ++i)
  204. throttler.IssuePendingConnectionTracker();
  205. EXPECT_EQ(0, throttler.num_pending_connections());
  206. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  207. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  208. EXPECT_EQ(16, throttler.num_current_failed_connections());
  209. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  210. EXPECT_LE(base::Milliseconds(1000), throttler.CalculateDelay());
  211. EXPECT_LE(throttler.CalculateDelay(), base::Milliseconds(5000));
  212. }
  213. TEST(WebSocketPerProcessThrottlerTest, MoveTracker) {
  214. WebSocketPerProcessThrottler throttler;
  215. absl::optional<WebSocketThrottler::PendingConnection> tracker_holder;
  216. {
  217. WebSocketThrottler::PendingConnection tracker =
  218. throttler.IssuePendingConnectionTracker();
  219. EXPECT_EQ(1, throttler.num_pending_connections());
  220. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  221. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  222. EXPECT_EQ(0, throttler.num_current_failed_connections());
  223. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  224. WebSocketThrottler::PendingConnection tracker2 = std::move(tracker);
  225. WebSocketThrottler::PendingConnection tracker3 = std::move(tracker2);
  226. EXPECT_EQ(1, throttler.num_pending_connections());
  227. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  228. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  229. EXPECT_EQ(0, throttler.num_current_failed_connections());
  230. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  231. tracker_holder.emplace(std::move(tracker3));
  232. EXPECT_EQ(1, throttler.num_pending_connections());
  233. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  234. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  235. EXPECT_EQ(0, throttler.num_current_failed_connections());
  236. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  237. }
  238. EXPECT_EQ(1, throttler.num_pending_connections());
  239. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  240. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  241. EXPECT_EQ(0, throttler.num_current_failed_connections());
  242. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  243. tracker_holder = absl::nullopt;
  244. EXPECT_EQ(0, throttler.num_pending_connections());
  245. EXPECT_EQ(0, throttler.num_current_succeeded_connections());
  246. EXPECT_EQ(0, throttler.num_previous_succeeded_connections());
  247. EXPECT_EQ(1, throttler.num_current_failed_connections());
  248. EXPECT_EQ(0, throttler.num_previous_failed_connections());
  249. }
  250. TEST_F(WebSocketThrottlerTest, InitialState) {
  251. WebSocketThrottler throttler;
  252. EXPECT_EQ(0u, throttler.GetSizeForTesting());
  253. }
  254. TEST_F(WebSocketThrottlerTest, TooManyPendingConnections) {
  255. constexpr int process1 = 1;
  256. constexpr int process2 = 2;
  257. constexpr int limit = 255;
  258. WebSocketThrottler throttler;
  259. std::vector<WebSocketThrottler::PendingConnection> trackers;
  260. for (int i = 0; i < limit - 1; ++i) {
  261. ASSERT_FALSE(throttler.HasTooManyPendingConnections(process1));
  262. ASSERT_FALSE(throttler.HasTooManyPendingConnections(process2));
  263. trackers.push_back(
  264. std::move(throttler.IssuePendingConnectionTracker(process1).value()));
  265. trackers.push_back(
  266. std::move(throttler.IssuePendingConnectionTracker(process2).value()));
  267. }
  268. EXPECT_EQ(2u, throttler.GetSizeForTesting());
  269. ASSERT_FALSE(throttler.HasTooManyPendingConnections(process1));
  270. ASSERT_FALSE(throttler.HasTooManyPendingConnections(process2));
  271. trackers.push_back(
  272. std::move(throttler.IssuePendingConnectionTracker(process1).value()));
  273. ASSERT_TRUE(throttler.HasTooManyPendingConnections(process1));
  274. ASSERT_FALSE(throttler.HasTooManyPendingConnections(process2));
  275. trackers.push_back(
  276. std::move(throttler.IssuePendingConnectionTracker(process2).value()));
  277. ASSERT_TRUE(throttler.HasTooManyPendingConnections(process1));
  278. ASSERT_TRUE(throttler.HasTooManyPendingConnections(process2));
  279. }
  280. TEST_F(WebSocketThrottlerTest, BrowserProcessNotThrottled) {
  281. WebSocketThrottler throttler;
  282. ASSERT_FALSE(
  283. throttler.HasTooManyPendingConnections(mojom::kBrowserProcessId));
  284. ASSERT_FALSE(throttler.IssuePendingConnectionTracker(mojom::kBrowserProcessId)
  285. .has_value());
  286. }
  287. } // namespace
  288. } // namespace network