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 testShouldThrowExceptionWhenSettingIncorrectPosition() {
166 try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) {
167 assertThrows(IllegalArgumentException.class, () -> c.position(Integer.MAX_VALUE + 1L));
168 }
169 }
170
171 @Test
172 void testShouldThrowExceptionWhenTruncatingToIncorrectSize() {
173 try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) {
174 assertThrows(IllegalArgumentException.class, () -> c.truncate(Integer.MAX_VALUE + 1L));
175 }
176 }
177
178 @Test
179 void testShouldTruncateContentsProperly() throws ClosedChannelException {
180 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
181 c.truncate(4);
182 final byte[] bytes = Arrays.copyOf(c.array(), (int) c.size());
183 assertEquals("Some", new String(bytes, StandardCharsets.UTF_8));
184 }
185 }
186
187
188
189 @Test
190 void testShouldWriteDataProperly() throws IOException {
191 try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) {
192 final ByteBuffer inData = ByteBuffer.wrap(testData);
193 final int writeCount = c.write(inData);
194 assertEquals(testData.length, writeCount);
195 assertEquals(testData.length, c.position());
196 assertArrayEquals(testData, Arrays.copyOf(c.array(), (int) c.position()));
197 }
198 }
199
200
201 @Test
202 void testShouldWriteDataProperlyAfterPositionSet() throws IOException {
203 try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData.clone())) {
204 final ByteBuffer inData = ByteBuffer.wrap(testData);
205 final ByteBuffer expectedData = ByteBuffer.allocate(testData.length + 5).put(testData, 0, 5).put(testData);
206 c.position(5L);
207 final int writeCount = c.write(inData);
208 assertEquals(testData.length, writeCount);
209 assertArrayEquals(expectedData.array(), Arrays.copyOf(c.array(), (int) c.size()));
210 assertEquals(testData.length + 5, c.position());
211 }
212 }
213
214
215
216
217
218 @Test
219 void testThrowsClosedChannelExceptionWhenPositionIsSetOnClosedChannel() throws Exception {
220 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
221 c.close();
222 assertThrows(ClosedChannelException.class, () -> c.position(0));
223 }
224 }
225
226
227
228
229
230 @Test
231 void testThrowsIllegalArgumentExceptionWhenTruncatingToANegativeSize() throws Exception {
232 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
233 assertThrows(IllegalArgumentException.class, () -> c.truncate(-1));
234 }
235 }
236
237
238
239
240 @Test
241 void testThrowsIOExceptionWhenPositionIsSetToANegativeValue() throws Exception {
242 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
243 assertThrows(IllegalArgumentException.class, () -> c.position(-1));
244 }
245 }
246
247
248
249
250 @Test
251 void testTruncateDoesntChangeSmallPosition() throws Exception {
252 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
253 c.position(1);
254 c.truncate(testData.length - 1);
255 assertEquals(testData.length - 1, c.size());
256 assertEquals(1, c.position());
257 }
258 }
259
260
261
262
263 @Test
264 void testTruncateMovesPositionWhenNewSizeIsBiggerThanSizeAndPositionIsEvenBigger() throws Exception {
265 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
266 c.position(2 * testData.length);
267 c.truncate(testData.length + 1);
268 assertEquals(testData.length, c.size());
269 assertEquals(testData.length + 1, c.position());
270 }
271 }
272
273
274
275
276
277 @Test
278 void testTruncateMovesPositionWhenNotResizingButPositionBiggerThanSize() throws Exception {
279 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
280 c.position(2 * testData.length);
281 c.truncate(testData.length);
282 assertEquals(testData.length, c.size());
283 assertEquals(testData.length, c.position());
284 }
285 }
286
287
288
289
290 @Test
291 void testTruncateMovesPositionWhenShrinkingBeyondPosition() throws Exception {
292 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
293 c.position(4);
294 c.truncate(3);
295 assertEquals(3, c.size());
296 assertEquals(3, c.position());
297 }
298 }
299
300
301
302
303 @Test
304 void testTruncateToBiggerSizeDoesntChangeAnything() throws Exception {
305 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
306 assertEquals(testData.length, c.size());
307 c.truncate(testData.length + 1);
308 assertEquals(testData.length, c.size());
309 final ByteBuffer readBuffer = ByteBuffer.allocate(testData.length);
310 assertEquals(testData.length, c.read(readBuffer));
311 assertArrayEquals(testData, Arrays.copyOf(readBuffer.array(), testData.length));
312 }
313 }
314
315
316
317
318 @Test
319 void testTruncateToCurrentSizeDoesntChangeAnything() throws Exception {
320 try (SeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) {
321 assertEquals(testData.length, c.size());
322 c.truncate(testData.length);
323 assertEquals(testData.length, c.size());
324 final ByteBuffer readBuffer = ByteBuffer.allocate(testData.length);
325 assertEquals(testData.length, c.read(readBuffer));
326 assertArrayEquals(testData, Arrays.copyOf(readBuffer.array(), testData.length));
327 }
328 }
329
330
331
332
333 @Test
334 public void throwsClosedChannelExceptionWhenPositionIsReadOnClosedChannel() throws Exception {
335 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
336 c.close();
337 assertThrows(ClosedChannelException.class, c::position);
338 }
339 }
340
341
342
343
344 @Test
345 public void throwsClosedChannelExceptionWhenSizeIsReadOnClosedChannel() throws Exception {
346 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
347 c.close();
348 assertThrows(ClosedChannelException.class, c::size);
349 }
350 }
351
352
353
354
355 @Test
356 public void throwsClosedChannelExceptionWhenTruncateIsCalledOnClosedChannel() throws Exception {
357 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
358 c.close();
359 assertThrows(ClosedChannelException.class, () -> c.truncate(0));
360 }
361 }
362
363
364
365
366
367
368 public void writingToAPositionAfterEndGrowsChannel() throws Exception {
369 try (SeekableByteChannel c = new ByteArraySeekableByteChannel()) {
370 c.position(2);
371 assertEquals(2, c.position());
372 final ByteBuffer inData = ByteBuffer.wrap(testData);
373 assertEquals(testData.length, c.write(inData));
374 assertEquals(testData.length + 2, c.size());
375 c.position(2);
376 final ByteBuffer readBuffer = ByteBuffer.allocate(testData.length);
377 c.read(readBuffer);
378 assertArrayEquals(testData, Arrays.copyOf(readBuffer.array(), testData.length));
379 }
380 }
381 }