1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.commons.io.channels;
21
22 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
23 import static org.junit.jupiter.api.Assertions.assertEquals;
24 import static org.junit.jupiter.api.Assertions.assertFalse;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26
27 import java.io.IOException;
28 import java.nio.ByteBuffer;
29 import java.nio.channels.ClosedChannelException;
30 import java.nio.channels.SeekableByteChannel;
31 import java.nio.charset.StandardCharsets;
32 import java.util.Arrays;
33
34 import org.junit.jupiter.api.AfterEach;
35 import org.junit.jupiter.api.Test;
36 import org.junit.jupiter.params.ParameterizedTest;
37 import org.junit.jupiter.params.provider.ValueSource;
38
39
40
41
42 class ByteArraySeekableByteChannelCompressTest {
43
44 private static final byte[] testData = "Some data".getBytes(StandardCharsets.UTF_8);
45
46 @AfterEach
47 void afterEach() {
48
49 assertArrayEquals("Some data".getBytes(StandardCharsets.UTF_8), testData);
50 }
51
52
53
54
55 @Test
56 void testCloseIsIdempotent() throws Exception {
57 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
58 c.close();
59 assertFalse(c.isOpen());
60 c.close();
61 assertFalse(c.isOpen());
62 }
63 }
64
65
66
67
68
69 @ParameterizedTest
70 @ValueSource(ints = { 0, 1, 2, 3, 4, 5, 6 })
71 void testReadingFromAPositionAfterEndReturnsEOF(final int size) throws Exception {
72 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(new byte[size])) {
73 final int position = 2;
74 c.position(position);
75 assertEquals(position, c.position());
76 final int readSize = 5;
77 final ByteBuffer readBuffer = ByteBuffer.allocate(readSize);
78 assertEquals(position >= size ? -1 : size - position, c.read(readBuffer));
79 }
80 }
81
82 @Test
83 void testShouldReadContentsProperly() throws IOException {
84 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
85 final ByteBuffer readBuffer = ByteBuffer.allocate(testData.length);
86 final int readCount = c.read(readBuffer);
87 assertEquals(testData.length, readCount);
88 assertArrayEquals(testData, readBuffer.array());
89 assertEquals(testData.length, c.position());
90 }
91 }
92
93 @Test
94 void testShouldReadContentsWhenBiggerBufferSupplied() throws IOException {
95 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
96 final ByteBuffer readBuffer = ByteBuffer.allocate(testData.length + 1);
97 final int readCount = c.read(readBuffer);
98 assertEquals(testData.length, readCount);
99 assertArrayEquals(testData, Arrays.copyOf(readBuffer.array(), testData.length));
100 assertEquals(testData.length, c.position());
101 }
102 }
103
104 @Test
105 void testShouldReadDataFromSetPosition() throws IOException {
106 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
107 final ByteBuffer readBuffer = ByteBuffer.allocate(4);
108 c.position(5L);
109 final int readCount = c.read(readBuffer);
110 assertEquals(4L, readCount);
111 assertEquals("data", new String(readBuffer.array(), StandardCharsets.UTF_8));
112 assertEquals(testData.length, c.position());
113 }
114 }
115
116 @Test
117 void testShouldSetProperPosition() throws IOException {
118 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
119 final long posAtFour = c.position(4L).position();
120 final long posAtTheEnd = c.position(testData.length).position();
121 final long posPastTheEnd = c.position(testData.length + 1L).position();
122 assertEquals(4L, posAtFour);
123 assertEquals(c.size(), posAtTheEnd);
124 assertEquals(testData.length + 1L, posPastTheEnd);
125 }
126 }
127
128 @Test
129 void testShouldSetProperPositionOnTruncate() throws IOException {
130 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
131 c.position(testData.length);
132 c.truncate(4L);
133 assertEquals(4L, c.position());
134 assertEquals(4L, c.size());
135 }
136 }
137
138 @Test
139 void testShouldSignalEOFWhenPositionAtTheEnd() throws IOException {
140 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
141 final ByteBuffer readBuffer = ByteBuffer.allocate(testData.length);
142 c.position(testData.length + 1);
143 final int readCount = c.read(readBuffer);
144 assertEquals(0L, readBuffer.position());
145 assertEquals(-1, readCount);
146 assertEquals(-1, c.read(readBuffer));
147 }
148 }
149
150 @Test
151 void testShouldThrowExceptionOnReadingClosedChannel() {
152 final ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel();
153 c.close();
154 assertThrows(ClosedChannelException.class, () -> c.read(ByteBuffer.allocate(1)));
155 }
156
157 @Test
158 void testShouldThrowExceptionOnWritingToClosedChannel() {
159 final ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel();
160 c.close();
161 assertThrows(ClosedChannelException.class, () -> c.write(ByteBuffer.allocate(1)));
162 }
163
164 @Test
165 void testShouldTruncateContentsProperly() throws ClosedChannelException {
166 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
167 c.truncate(4);
168 final byte[] bytes = Arrays.copyOf(c.array(), (int) c.size());
169 assertEquals("Some", new String(bytes, StandardCharsets.UTF_8));
170 }
171 }
172
173
174
175 @Test
176 void testShouldWriteDataProperly() throws IOException {
177 try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) {
178 final ByteBuffer inData = ByteBuffer.wrap(testData);
179 final int writeCount = c.write(inData);
180 assertEquals(testData.length, writeCount);
181 assertEquals(testData.length, c.position());
182 assertArrayEquals(testData, Arrays.copyOf(c.array(), (int) c.position()));
183 }
184 }
185
186
187 @Test
188 void testShouldWriteDataProperlyAfterPositionSet() throws IOException {
189 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData.clone())) {
190 final ByteBuffer inData = ByteBuffer.wrap(testData);
191 final ByteBuffer expectedData = ByteBuffer.allocate(testData.length + 5).put(testData, 0, 5).put(testData);
192 c.position(5L);
193 final int writeCount = c.write(inData);
194 assertEquals(testData.length, writeCount);
195 assertArrayEquals(expectedData.array(), Arrays.copyOf(c.array(), (int) c.size()));
196 assertEquals(testData.length + 5, c.position());
197 }
198 }
199
200
201
202
203
204 @Test
205 void testThrowsClosedChannelExceptionWhenPositionIsSetOnClosedChannel() throws Exception {
206 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
207 c.close();
208 assertThrows(ClosedChannelException.class, () -> c.position(0));
209 }
210 }
211
212
213
214
215
216 @Test
217 void testThrowsIllegalArgumentExceptionWhenTruncatingToANegativeSize() throws Exception {
218 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
219 assertThrows(IllegalArgumentException.class, () -> c.truncate(-1));
220 }
221 }
222
223
224
225
226 @Test
227 void testThrowsIOExceptionWhenPositionIsSetToANegativeValue() throws Exception {
228 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
229 assertThrows(IllegalArgumentException.class, () -> c.position(-1));
230 }
231 }
232
233 @Test
234 void testThrowWhenSettingIncorrectPosition() throws IOException {
235 try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) {
236 final ByteBuffer buffer = ByteBuffer.allocate(1);
237
238 c.write(buffer);
239 assertEquals(1, c.position());
240
241 c.position(c.size() + 1);
242 assertEquals(c.size() + 1, c.position());
243 assertEquals(-1, c.read(buffer));
244
245 c.position(Integer.MAX_VALUE + 1L);
246 assertEquals(Integer.MAX_VALUE + 1L, c.position());
247 assertEquals(-1, c.read(buffer));
248 assertThrows(IOException.class, () -> c.write(buffer));
249
250 assertThrows(IllegalArgumentException.class, () -> c.position(-1));
251 assertThrows(IllegalArgumentException.class, () -> c.position(Integer.MIN_VALUE));
252 assertThrows(IllegalArgumentException.class, () -> c.position(Long.MIN_VALUE));
253 }
254 }
255
256 @Test
257 void testThrowWhenTruncatingToIncorrectSize() throws IOException {
258 try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) {
259 final ByteBuffer buffer = ByteBuffer.allocate(1);
260 c.truncate(c.size() + 1);
261 assertEquals(-1, c.read(buffer));
262 c.truncate(Integer.MAX_VALUE + 1L);
263 assertEquals(-1, c.read(buffer));
264 assertThrows(IllegalArgumentException.class, () -> c.truncate(-1));
265 assertThrows(IllegalArgumentException.class, () -> c.truncate(Integer.MIN_VALUE));
266 assertThrows(IllegalArgumentException.class, () -> c.truncate(Long.MIN_VALUE));
267 }
268 }
269
270
271
272
273 @Test
274 void testTruncateDoesntChangeSmallPosition() throws Exception {
275 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
276 c.position(1);
277 c.truncate(testData.length - 1);
278 assertEquals(testData.length - 1, c.size());
279 assertEquals(1, c.position());
280 }
281 }
282
283
284
285
286 @Test
287 void testTruncateMovesPositionWhenNewSizeIsBiggerThanSizeAndPositionIsEvenBigger() throws Exception {
288 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
289 c.position(2 * testData.length);
290 c.truncate(testData.length + 1);
291 assertEquals(testData.length, c.size());
292 assertEquals(testData.length + 1, c.position());
293 }
294 }
295
296
297
298
299
300 @Test
301 void testTruncateMovesPositionWhenNotResizingButPositionBiggerThanSize() throws Exception {
302 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
303 c.position(2 * testData.length);
304 c.truncate(testData.length);
305 assertEquals(testData.length, c.size());
306 assertEquals(testData.length, c.position());
307 }
308 }
309
310
311
312
313 @Test
314 void testTruncateMovesPositionWhenShrinkingBeyondPosition() throws Exception {
315 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
316 c.position(4);
317 c.truncate(3);
318 assertEquals(3, c.size());
319 assertEquals(3, c.position());
320 }
321 }
322
323
324
325
326 @Test
327 void testTruncateToBiggerSizeDoesntChangeAnything() throws Exception {
328 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
329 assertEquals(testData.length, c.size());
330 c.truncate(testData.length + 1);
331 assertEquals(testData.length, c.size());
332 final ByteBuffer readBuffer = ByteBuffer.allocate(testData.length);
333 assertEquals(testData.length, c.read(readBuffer));
334 assertArrayEquals(testData, Arrays.copyOf(readBuffer.array(), testData.length));
335 }
336 }
337
338
339
340
341 @Test
342 void testTruncateToCurrentSizeDoesntChangeAnything() throws Exception {
343 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
344 assertEquals(testData.length, c.size());
345 c.truncate(testData.length);
346 assertEquals(testData.length, c.size());
347 final ByteBuffer readBuffer = ByteBuffer.allocate(testData.length);
348 assertEquals(testData.length, c.read(readBuffer));
349 assertArrayEquals(testData, Arrays.copyOf(readBuffer.array(), testData.length));
350 }
351 }
352
353
354
355
356 @Test
357 public void throwsClosedChannelExceptionWhenPositionIsReadOnClosedChannel() throws Exception {
358 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
359 c.close();
360 assertThrows(ClosedChannelException.class, c::position);
361 }
362 }
363
364
365
366
367 @Test
368 public void throwsClosedChannelExceptionWhenSizeIsReadOnClosedChannel() throws Exception {
369 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
370 c.close();
371 assertThrows(ClosedChannelException.class, c::size);
372 }
373 }
374
375
376
377
378 @Test
379 public void throwsClosedChannelExceptionWhenTruncateIsCalledOnClosedChannel() throws Exception {
380 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
381 c.close();
382 assertThrows(ClosedChannelException.class, () -> c.truncate(0));
383 }
384 }
385
386
387
388
389
390
391 public void writingToAPositionAfterEndGrowsChannel() throws Exception {
392 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
393 c.position(2);
394 assertEquals(2, c.position());
395 final ByteBuffer inData = ByteBuffer.wrap(testData);
396 assertEquals(testData.length, c.write(inData));
397 assertEquals(testData.length + 2, c.size());
398 c.position(2);
399 final ByteBuffer readBuffer = ByteBuffer.allocate(testData.length);
400 c.read(readBuffer);
401 assertArrayEquals(testData, Arrays.copyOf(readBuffer.array(), testData.length));
402 }
403 }
404 }