FixedIntervalRefillStrategyTest.java
3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package com.zhaoonline.coupen.concurrent.tokenbucket;
import com.google.common.base.Ticker;
import org.junit.Test;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
public class FixedIntervalRefillStrategyTest {
private static final long N = 5; // 5 tokens
private static final long P = 10; // every 10
private static final TimeUnit U = TimeUnit.SECONDS; // seconds
private final MockTicker ticker = new MockTicker();
private final FixedIntervalRefillStrategy strategy = new FixedIntervalRefillStrategy(ticker, N, P, U);
@Test
public void testFirstRefill() {
assertEquals(N, strategy.refill());
}
@Test
public void testNoRefillUntilPeriodUp() {
strategy.refill();
// Another refill shouldn't come for P time units.
for (int i = 0; i < P - 1; i++) {
ticker.advance(1, U);
assertEquals(0, strategy.refill());
}
}
@Test
public void testRefillEveryPeriod() {
strategy.refill();
ticker.advance(P, U);
assertEquals(N, strategy.refill());
ticker.advance(P, U);
assertEquals(N, strategy.refill());
ticker.advance(P, U);
assertEquals(N, strategy.refill());
}
@Test
public void testRefillEveryOtherPeriod() {
strategy.refill();
// Move time forward two periods, since we're skipping a period next time we should add double the tokens.
ticker.advance(2 * P, U);
assertEquals(2 * N, strategy.refill());
ticker.advance(2 * P, U);
assertEquals(2 * N, strategy.refill());
}
@Test
public void testRefillOnNonEvenPeriods() {
// The strategy is configured to refill tokens every P time units. So we should only get refills at 0, P, 2P, 3P,
// etc. Any other time should return 0 tokens.
// t = 0
assertEquals(N, strategy.refill());
// t = P+1
ticker.advance(P + 1, U);
assertEquals(N, strategy.refill());
// t = 2P+1
ticker.advance(P, U);
assertEquals(N, strategy.refill());
// t = 3P
ticker.advance(P - 1, U);
assertEquals(N, strategy.refill());
// t = 4P-1
ticker.advance(P - 1, U);
assertEquals(0, strategy.refill());
// t = 4P
ticker.advance(1, U);
assertEquals(N, strategy.refill());
}
@Test
public void testDurationUntilFirstRefill() {
// A refill has never happened, so one is supposed to happen immediately.
assertEquals(0, strategy.getDurationUntilNextRefill(TimeUnit.SECONDS));
}
@Test
public void testDurationAfterFirstRefill() {
strategy.refill();
for (int i = 0; i < P - 1; i++) {
assertEquals(P - i, strategy.getDurationUntilNextRefill(TimeUnit.SECONDS));
ticker.advance(1, U);
}
}
@Test
public void testDurationAtSecondRefillTime() {
strategy.refill();
ticker.advance(P, U);
assertEquals(0, strategy.getDurationUntilNextRefill(TimeUnit.SECONDS));
}
@Test
public void testDurationInProperUnits() {
strategy.refill();
assertEquals(10000, strategy.getDurationUntilNextRefill(TimeUnit.MILLISECONDS));
}
private static final class MockTicker extends Ticker {
private long now = 0;
@Override
public long read() {
return now;
}
public void advance(long delta, TimeUnit unit) {
now += unit.toNanos(delta);
}
}
}