Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(370)

Side by Side Diff: webrtc/base/rate_limiter_unittest.cc

Issue 2877023002: Move webrtc/{base => rtc_base} (Closed)
Patch Set: update presubmit.py and DEPS include rules Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/rate_limiter.cc ('k') | webrtc/base/rate_statistics.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <algorithm>
12 #include <memory>
13
14 #include "webrtc/base/event.h"
15 #include "webrtc/base/platform_thread.h"
16 #include "webrtc/base/rate_limiter.h"
17 #include "webrtc/base/task_queue.h"
18 #include "webrtc/system_wrappers/include/clock.h"
19 #include "webrtc/test/gtest.h"
20
21 namespace webrtc {
22
23 class RateLimitTest : public ::testing::Test {
24 public:
25 RateLimitTest()
26 : clock_(0), rate_limiter(new RateLimiter(&clock_, kWindowSizeMs)) {}
27 ~RateLimitTest() override {}
28
29 void SetUp() override { rate_limiter->SetMaxRate(kMaxRateBps); }
30
31 protected:
32 static constexpr int64_t kWindowSizeMs = 1000;
33 static constexpr uint32_t kMaxRateBps = 100000;
34 // Bytes needed to completely saturate the rate limiter.
35 static constexpr size_t kRateFillingBytes =
36 (kMaxRateBps * kWindowSizeMs) / (8 * 1000);
37 SimulatedClock clock_;
38 std::unique_ptr<RateLimiter> rate_limiter;
39 };
40
41 TEST_F(RateLimitTest, IncreasingMaxRate) {
42 // Fill rate, extend window to full size.
43 EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
44 clock_.AdvanceTimeMilliseconds(kWindowSizeMs - 1);
45 EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
46
47 // All rate consumed.
48 EXPECT_FALSE(rate_limiter->TryUseRate(1));
49
50 // Double the available rate and fill that too.
51 rate_limiter->SetMaxRate(kMaxRateBps * 2);
52 EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes));
53
54 // All rate consumed again.
55 EXPECT_FALSE(rate_limiter->TryUseRate(1));
56 }
57
58 TEST_F(RateLimitTest, DecreasingMaxRate) {
59 // Fill rate, extend window to full size.
60 EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
61 clock_.AdvanceTimeMilliseconds(kWindowSizeMs - 1);
62 EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
63
64 // All rate consumed.
65 EXPECT_FALSE(rate_limiter->TryUseRate(1));
66
67 // Halve the available rate and move window so half of the data falls out.
68 rate_limiter->SetMaxRate(kMaxRateBps / 2);
69 clock_.AdvanceTimeMilliseconds(1);
70
71 // All rate still consumed.
72 EXPECT_FALSE(rate_limiter->TryUseRate(1));
73 }
74
75 TEST_F(RateLimitTest, ChangingWindowSize) {
76 // Fill rate, extend window to full size.
77 EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
78 clock_.AdvanceTimeMilliseconds(kWindowSizeMs - 1);
79 EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
80
81 // All rate consumed.
82 EXPECT_FALSE(rate_limiter->TryUseRate(1));
83
84 // Decrease window size so half of the data falls out.
85 rate_limiter->SetWindowSize(kWindowSizeMs / 2);
86 // Average rate should still be the same, so rate is still all consumed.
87 EXPECT_FALSE(rate_limiter->TryUseRate(1));
88
89 // Increase window size again. Now the rate is only half used (removed data
90 // points don't come back to life).
91 rate_limiter->SetWindowSize(kWindowSizeMs);
92 EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes / 2));
93
94 // All rate consumed again.
95 EXPECT_FALSE(rate_limiter->TryUseRate(1));
96 }
97
98 TEST_F(RateLimitTest, SingleUsageAlwaysOk) {
99 // Using more bytes than can fit in a window is OK for a single packet.
100 EXPECT_TRUE(rate_limiter->TryUseRate(kRateFillingBytes + 1));
101 }
102
103 TEST_F(RateLimitTest, WindowSizeLimits) {
104 EXPECT_TRUE(rate_limiter->SetWindowSize(1));
105 EXPECT_FALSE(rate_limiter->SetWindowSize(0));
106 EXPECT_TRUE(rate_limiter->SetWindowSize(kWindowSizeMs));
107 EXPECT_FALSE(rate_limiter->SetWindowSize(kWindowSizeMs + 1));
108 }
109
110 static const int64_t kMaxTimeoutMs = 30000;
111
112 class ThreadTask {
113 public:
114 explicit ThreadTask(RateLimiter* rate_limiter)
115 : rate_limiter_(rate_limiter),
116 start_signal_(false, false),
117 end_signal_(false, false) {}
118 virtual ~ThreadTask() {}
119
120 void Run() {
121 start_signal_.Wait(kMaxTimeoutMs);
122 DoRun();
123 end_signal_.Set();
124 }
125
126 virtual void DoRun() = 0;
127
128 RateLimiter* const rate_limiter_;
129 rtc::Event start_signal_;
130 rtc::Event end_signal_;
131 };
132
133 void RunTask(void* thread_task) {
134 reinterpret_cast<ThreadTask*>(thread_task)->Run();
135 }
136
137 TEST_F(RateLimitTest, MultiThreadedUsage) {
138 // Simple sanity test, with different threads calling the various methods.
139 // Runs a few simple tasks, each on its own thread, but coordinated with
140 // events so that they run in a serialized order. Intended to catch data
141 // races when run with tsan et al.
142
143 // Half window size, double rate -> same amount of bytes needed to fill rate.
144
145 class SetWindowSizeTask : public ThreadTask {
146 public:
147 explicit SetWindowSizeTask(RateLimiter* rate_limiter)
148 : ThreadTask(rate_limiter) {}
149 ~SetWindowSizeTask() override {}
150
151 void DoRun() override {
152 EXPECT_TRUE(rate_limiter_->SetWindowSize(kWindowSizeMs / 2));
153 }
154 } set_window_size_task(rate_limiter.get());
155 rtc::PlatformThread thread1(RunTask, &set_window_size_task, "Thread1");
156 thread1.Start();
157
158 class SetMaxRateTask : public ThreadTask {
159 public:
160 explicit SetMaxRateTask(RateLimiter* rate_limiter)
161 : ThreadTask(rate_limiter) {}
162 ~SetMaxRateTask() override {}
163
164 void DoRun() override { rate_limiter_->SetMaxRate(kMaxRateBps * 2); }
165 } set_max_rate_task(rate_limiter.get());
166 rtc::PlatformThread thread2(RunTask, &set_max_rate_task, "Thread2");
167 thread2.Start();
168
169 class UseRateTask : public ThreadTask {
170 public:
171 UseRateTask(RateLimiter* rate_limiter, SimulatedClock* clock)
172 : ThreadTask(rate_limiter), clock_(clock) {}
173 ~UseRateTask() override {}
174
175 void DoRun() override {
176 EXPECT_TRUE(rate_limiter_->TryUseRate(kRateFillingBytes / 2));
177 clock_->AdvanceTimeMilliseconds((kWindowSizeMs / 2) - 1);
178 EXPECT_TRUE(rate_limiter_->TryUseRate(kRateFillingBytes / 2));
179 }
180
181 SimulatedClock* const clock_;
182 } use_rate_task(rate_limiter.get(), &clock_);
183 rtc::PlatformThread thread3(RunTask, &use_rate_task, "Thread3");
184 thread3.Start();
185
186 set_window_size_task.start_signal_.Set();
187 EXPECT_TRUE(set_window_size_task.end_signal_.Wait(kMaxTimeoutMs));
188
189 set_max_rate_task.start_signal_.Set();
190 EXPECT_TRUE(set_max_rate_task.end_signal_.Wait(kMaxTimeoutMs));
191
192 use_rate_task.start_signal_.Set();
193 EXPECT_TRUE(use_rate_task.end_signal_.Wait(kMaxTimeoutMs));
194
195 // All rate consumed.
196 EXPECT_FALSE(rate_limiter->TryUseRate(1));
197
198 thread1.Stop();
199 thread2.Stop();
200 thread3.Stop();
201 }
202
203 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/base/rate_limiter.cc ('k') | webrtc/base/rate_statistics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698