1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /* Original author: bcampen@mozilla.com */
8
9 #include "simpletokenbucket.h"
10
11 #define GTEST_HAS_RTTI 0
12 #include "gtest/gtest.h"
13 #include "gtest_utils.h"
14
15 using mozilla::SimpleTokenBucket;
16
17 class TestSimpleTokenBucket : public SimpleTokenBucket {
18 public:
TestSimpleTokenBucket(size_t bucketSize,size_t tokensPerSecond)19 TestSimpleTokenBucket(size_t bucketSize, size_t tokensPerSecond)
20 : SimpleTokenBucket(bucketSize, tokensPerSecond) {}
21
fastForward(int32_t timeMilliSeconds)22 void fastForward(int32_t timeMilliSeconds) {
23 if (timeMilliSeconds >= 0) {
24 last_time_tokens_added_ -= PR_MillisecondsToInterval(timeMilliSeconds);
25 } else {
26 last_time_tokens_added_ += PR_MillisecondsToInterval(-timeMilliSeconds);
27 }
28 }
29 };
30
TEST(SimpleTokenBucketTest,TestConstruct)31 TEST(SimpleTokenBucketTest, TestConstruct)
32 { TestSimpleTokenBucket b(10, 1); }
33
TEST(SimpleTokenBucketTest,TestGet)34 TEST(SimpleTokenBucketTest, TestGet)
35 {
36 TestSimpleTokenBucket b(10, 1);
37 ASSERT_EQ(5U, b.getTokens(5));
38 }
39
TEST(SimpleTokenBucketTest,TestGetAll)40 TEST(SimpleTokenBucketTest, TestGetAll)
41 {
42 TestSimpleTokenBucket b(10, 1);
43 ASSERT_EQ(10U, b.getTokens(10));
44 }
45
TEST(SimpleTokenBucketTest,TestGetInsufficient)46 TEST(SimpleTokenBucketTest, TestGetInsufficient)
47 {
48 TestSimpleTokenBucket b(10, 1);
49 ASSERT_EQ(5U, b.getTokens(5));
50 ASSERT_EQ(5U, b.getTokens(6));
51 }
52
TEST(SimpleTokenBucketTest,TestGetBucketCount)53 TEST(SimpleTokenBucketTest, TestGetBucketCount)
54 {
55 TestSimpleTokenBucket b(10, 1);
56 ASSERT_EQ(10U, b.getTokens(UINT32_MAX));
57 ASSERT_EQ(5U, b.getTokens(5));
58 ASSERT_EQ(5U, b.getTokens(UINT32_MAX));
59 }
60
TEST(SimpleTokenBucketTest,TestTokenRefill)61 TEST(SimpleTokenBucketTest, TestTokenRefill)
62 {
63 TestSimpleTokenBucket b(10, 1);
64 ASSERT_EQ(5U, b.getTokens(5));
65 b.fastForward(1000);
66 ASSERT_EQ(6U, b.getTokens(6));
67 }
68
TEST(SimpleTokenBucketTest,TestNoTimeWasted)69 TEST(SimpleTokenBucketTest, TestNoTimeWasted)
70 {
71 // Makes sure that when the time elapsed is insufficient to add any
72 // tokens to the bucket, the internal timestamp that is used in this
73 // calculation is not updated (ie; two subsequent 0.5 second elapsed times
74 // counts as a full second)
75 TestSimpleTokenBucket b(10, 1);
76 ASSERT_EQ(5U, b.getTokens(5));
77 b.fastForward(500);
78 ASSERT_EQ(5U, b.getTokens(6));
79 b.fastForward(500);
80 ASSERT_EQ(6U, b.getTokens(6));
81 }
82
TEST(SimpleTokenBucketTest,TestNegativeTime)83 TEST(SimpleTokenBucketTest, TestNegativeTime)
84 {
85 TestSimpleTokenBucket b(10, 1);
86 b.fastForward(-1000);
87 // Make sure we don't end up with an invalid number of tokens, but otherwise
88 // permit anything.
89 ASSERT_GT(11U, b.getTokens(100));
90 }
91
TEST(SimpleTokenBucketTest,TestEmptyBucket)92 TEST(SimpleTokenBucketTest, TestEmptyBucket)
93 {
94 TestSimpleTokenBucket b(10, 1);
95 ASSERT_EQ(10U, b.getTokens(10));
96 ASSERT_EQ(0U, b.getTokens(10));
97 }
98
TEST(SimpleTokenBucketTest,TestEmptyThenFillBucket)99 TEST(SimpleTokenBucketTest, TestEmptyThenFillBucket)
100 {
101 TestSimpleTokenBucket b(10, 1);
102 ASSERT_EQ(10U, b.getTokens(10));
103 ASSERT_EQ(0U, b.getTokens(1));
104 b.fastForward(50000);
105 ASSERT_EQ(10U, b.getTokens(10));
106 }
107
TEST(SimpleTokenBucketTest,TestNoOverflow)108 TEST(SimpleTokenBucketTest, TestNoOverflow)
109 {
110 TestSimpleTokenBucket b(10, 1);
111 ASSERT_EQ(10U, b.getTokens(10));
112 ASSERT_EQ(0U, b.getTokens(1));
113 b.fastForward(50000);
114 ASSERT_EQ(10U, b.getTokens(11));
115 }
116