1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.io.input;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22 import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.time.Duration;
28 import java.time.temporal.ChronoUnit;
29 import java.util.concurrent.atomic.AtomicBoolean;
30
31 import org.apache.commons.io.IOUtils;
32 import org.apache.commons.io.input.ThrottledInputStream.Builder;
33 import org.apache.commons.io.test.CustomIOException;
34 import org.junit.jupiter.api.Test;
35
36
37
38
39 class ThrottledInputStreamTest extends ProxyInputStreamTest<ThrottledInputStream> {
40
41 @Override
42 @SuppressWarnings({ "resource" })
43 protected ThrottledInputStream createFixture() throws IOException {
44 return ThrottledInputStream.builder().setInputStream(createOriginInputStream()).get();
45 }
46
47 @Test
48 void testAfterReadConsumer() throws Exception {
49 final AtomicBoolean boolRef = new AtomicBoolean();
50
51 try (InputStream bounded = ThrottledInputStream.builder()
52 .setCharSequence("Hi")
53 .setAfterRead(i -> boolRef.set(true))
54 .get()) {
55 IOUtils.consume(bounded);
56 }
57
58 assertTrue(boolRef.get());
59
60 final String message = "test exception message";
61
62 try (InputStream inputStream = ThrottledInputStream.builder()
63 .setCharSequence("Hi")
64 .setAfterRead(i -> {
65 throw new CustomIOException(message);
66 })
67 .get()) {
68 assertEquals(message, assertThrowsExactly(CustomIOException.class, () -> IOUtils.consume(inputStream)).getMessage());
69 }
70
71 }
72
73 @Test
74 void testBuilder() throws IOException {
75 final Builder builder = ThrottledInputStream.builder();
76 assertThrows(IllegalArgumentException.class, () -> builder.setMaxBytesPerSecond(-1));
77 assertThrows(IllegalArgumentException.class, () -> builder.setMaxBytesPerSecond(0));
78 assertThrows(IllegalArgumentException.class, () -> builder.setMaxBytes(1, Duration.ZERO.minusMillis(1)));
79 assertThrows(IllegalArgumentException.class, () -> builder.setMaxBytes(1, Duration.ZERO));
80 assertThrows(NullPointerException.class, () -> builder.setMaxBytes(1, (Duration) null));
81 assertThrows(NullPointerException.class, () -> builder.setMaxBytes(1, (ChronoUnit) null));
82
83
84 builder.setMaxBytesPerSecond(2);
85 assertEquals(2.0, builder.getMaxBytesPerSecond());
86
87 try (ThrottledInputStream inputStream = builder
88 .setInputStream(createOriginInputStream())
89 .get()) {
90 assertEquals(2.0, builder.getMaxBytesPerSecond());
91 assertEquals(2.0, inputStream.getMaxBytesPerSecond());
92 }
93 try (ThrottledInputStream inputStream = builder
94 .setInputStream(createOriginInputStream())
95 .setMaxBytes(2, ChronoUnit.SECONDS)
96 .get()) {
97 assertEquals(2.0, builder.getMaxBytesPerSecond());
98 assertEquals(2.0, inputStream.getMaxBytesPerSecond());
99 }
100
101 Duration maxBytesPer = Duration.ofSeconds(1);
102
103 try (ThrottledInputStream inputStream = builder
104 .setInputStream(createOriginInputStream())
105 .setMaxBytes(2, maxBytesPer)
106 .get()) {
107 assertEquals(2.0, builder.getMaxBytesPerSecond());
108 assertEquals(2.0, inputStream.getMaxBytesPerSecond());
109 }
110
111
112
113 maxBytesPer = maxBytesPer.dividedBy(2);
114
115 try (ThrottledInputStream inputStream = builder
116 .setInputStream(createOriginInputStream())
117 .setMaxBytes(1, maxBytesPer)
118 .get()) {
119 assertEquals(0.5, inputStream.getMaxBytesPerSecond());
120 }
121
122 try (ThrottledInputStream inputStream = builder
123 .setInputStream(createOriginInputStream())
124 .setMaxBytes(1, ChronoUnit.MILLIS)
125 .get()) {
126 assertEquals(0.001, inputStream.getMaxBytesPerSecond());
127 }
128
129
130 maxBytesPer = Duration.ofSeconds(20).plusMillis(11);
131
132 try (ThrottledInputStream inputStream = builder
133 .setInputStream(createOriginInputStream())
134 .setMaxBytes(1, maxBytesPer)
135 .get()) {
136 assertEquals(20.011, inputStream.getMaxBytesPerSecond());
137 }
138
139
140
141 try (ThrottledInputStream inputStream = builder
142 .setInputStream(createOriginInputStream())
143 .setMaxBytes(100_000, ChronoUnit.SECONDS)
144 .get()) {
145 assertEquals(100_000.0, inputStream.getMaxBytesPerSecond());
146 }
147
148 }
149
150 @Test
151 void testCalSleepTimeMs() {
152
153 assertEquals(0, ThrottledInputStream.toSleepMillis(0, 1_000, 10_000));
154
155 assertEquals(0, ThrottledInputStream.toSleepMillis(Long.MAX_VALUE, 1_000, 0));
156 assertEquals(0, ThrottledInputStream.toSleepMillis(Long.MAX_VALUE, 1_000, -1));
157
158 assertEquals(1500, ThrottledInputStream.toSleepMillis(5, 1_000, 2));
159 assertEquals(500, ThrottledInputStream.toSleepMillis(5, 2_000, 2));
160 assertEquals(6500, ThrottledInputStream.toSleepMillis(15, 1_000, 2));
161 assertEquals(4000, ThrottledInputStream.toSleepMillis(5, 1_000, 1));
162 assertEquals(9000, ThrottledInputStream.toSleepMillis(5, 1_000, 0.5));
163 assertEquals(99000, ThrottledInputStream.toSleepMillis(5, 1_000, 0.05));
164
165 assertEquals(0, ThrottledInputStream.toSleepMillis(1, 1_000, 2));
166 assertEquals(0, ThrottledInputStream.toSleepMillis(2, 2_000, 2));
167 assertEquals(0, ThrottledInputStream.toSleepMillis(1, 1_000, 2));
168 assertEquals(0, ThrottledInputStream.toSleepMillis(1, 1_000, 2.0));
169 assertEquals(0, ThrottledInputStream.toSleepMillis(1, 1_000, 1));
170 assertEquals(0, ThrottledInputStream.toSleepMillis(1, 1_000, 1.0));
171 }
172
173 @Test
174 void testCloseHandleIOException() throws IOException {
175 ProxyInputStreamTest.testCloseHandleIOException(ThrottledInputStream.builder());
176 }
177
178 @Override
179 protected void testEos(final ThrottledInputStream inputStream) {
180 assertEquals(3, inputStream.getByteCount());
181 }
182
183 @Test
184 void testGet() throws IOException {
185 try (ThrottledInputStream inputStream = createFixture()) {
186 inputStream.read();
187 assertEquals(Duration.ZERO, inputStream.getTotalSleepDuration());
188 }
189 }
190
191 }