1 // Copyright (c) 2013 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.
5 #include "components/policy/core/common/cloud/rate_limiter.h"
8 #include "base/bind_helpers.h"
9 #include "base/test/simple_test_tick_clock.h"
10 #include "base/test/test_simple_task_runner.h"
11 #include "base/time/tick_clock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 class RateLimiterTest
: public testing::Test
{
19 : task_runner_(new base::TestSimpleTaskRunner()),
20 clock_(new base::SimpleTestTickClock()),
23 duration_(base::TimeDelta::FromHours(1)),
24 small_delta_(base::TimeDelta::FromMinutes(1)),
25 limiter_(max_requests_
,
27 base::Bind(&RateLimiterTest::Callback
, base::Unretained(this)),
29 scoped_ptr
<base::TickClock
>(clock_
).Pass()) {}
30 virtual ~RateLimiterTest() {}
37 scoped_refptr
<base::TestSimpleTaskRunner
> task_runner_
;
38 base::SimpleTestTickClock
* clock_
;
40 const size_t max_requests_
;
41 const base::TimeDelta duration_
;
42 const base::TimeDelta small_delta_
;
46 TEST_F(RateLimiterTest
, LimitRequests
) {
48 for (size_t i
= 0; i
< max_requests_
; ++i
) {
49 EXPECT_EQ(count
, callbacks_
);
50 limiter_
.PostRequest();
52 EXPECT_EQ(count
, callbacks_
);
53 EXPECT_TRUE(task_runner_
->GetPendingTasks().empty());
54 clock_
->Advance(small_delta_
);
57 for (size_t i
= 0; i
< 10; ++i
) {
58 limiter_
.PostRequest();
59 EXPECT_EQ(max_requests_
, callbacks_
);
60 clock_
->Advance(small_delta_
);
61 EXPECT_FALSE(task_runner_
->GetPendingTasks().empty());
64 // Now advance the clock beyond the duration. The callback is invoked once.
66 clock_
->Advance(duration_
);
67 task_runner_
->RunPendingTasks();
68 EXPECT_EQ(1u, callbacks_
);
69 EXPECT_TRUE(task_runner_
->GetPendingTasks().empty());
72 TEST_F(RateLimiterTest
, Steady
) {
73 const base::TimeDelta delta
= duration_
/ 2;
75 for (int i
= 0; i
< 100; ++i
) {
76 EXPECT_EQ(count
, callbacks_
);
77 limiter_
.PostRequest();
79 EXPECT_EQ(count
, callbacks_
);
80 EXPECT_TRUE(task_runner_
->GetPendingTasks().empty());
81 clock_
->Advance(delta
);
85 TEST_F(RateLimiterTest
, RetryAfterDelay
) {
87 base::TimeDelta total_delta
;
89 for (size_t i
= 0; i
< max_requests_
; ++i
) {
90 EXPECT_EQ(count
, callbacks_
);
91 limiter_
.PostRequest();
93 EXPECT_EQ(count
, callbacks_
);
94 EXPECT_TRUE(task_runner_
->GetPendingTasks().empty());
95 clock_
->Advance(small_delta_
);
96 total_delta
+= small_delta_
;
99 // Now post a request that will be delayed.
100 EXPECT_EQ(max_requests_
, callbacks_
);
101 limiter_
.PostRequest();
102 EXPECT_EQ(max_requests_
, callbacks_
);
103 EXPECT_FALSE(task_runner_
->GetPendingTasks().empty());
105 while (total_delta
< duration_
) {
106 task_runner_
->RunPendingTasks();
107 // The queue is still full, so another task is immediately posted.
108 EXPECT_FALSE(task_runner_
->GetPendingTasks().empty());
109 clock_
->Advance(small_delta_
);
110 total_delta
+= small_delta_
;
113 // Now advance time beyond the initial duration. It will immediately execute
115 EXPECT_EQ(max_requests_
, callbacks_
);
116 task_runner_
->RunPendingTasks();
117 EXPECT_TRUE(task_runner_
->GetPendingTasks().empty());
118 EXPECT_EQ(max_requests_
+ 1, callbacks_
);
121 } // namespace policy