1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.archivers.zip;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.eq;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.times;
28 import static org.mockito.Mockito.verify;
29 import static org.mockito.Mockito.when;
30
31 import java.io.IOException;
32 import java.nio.ByteBuffer;
33 import java.nio.channels.FileChannel;
34 import java.nio.charset.StandardCharsets;
35 import java.nio.file.Path;
36
37 import org.apache.commons.compress.AbstractTempDirTest;
38 import org.junit.jupiter.api.Test;
39
40
41
42
43 class FileRandomAccessOutputStreamTest extends AbstractTempDirTest {
44
45 @Test
46 void testChannelReturn() throws IOException {
47 final Path file = newTempPath("testChannel");
48 try (FileRandomAccessOutputStream stream = new FileRandomAccessOutputStream(file)) {
49 assertNotNull(stream.channel());
50 }
51 }
52
53 @Test
54 void testClose() throws IOException {
55 final Path file = newTempPath("testChannel");
56 try (FileRandomAccessOutputStream stream = new FileRandomAccessOutputStream(file)) {
57 assertNotNull(stream.channel());
58 stream.close();
59 stream.close();
60 }
61 }
62
63 @Test
64 void testWrite() throws IOException {
65 final FileChannel channel = mock(FileChannel.class);
66 final FileRandomAccessOutputStream stream = new FileRandomAccessOutputStream(channel);
67 when(channel.write((ByteBuffer) any())).thenAnswer(answer -> {
68 ((ByteBuffer) answer.getArgument(0)).position(5);
69 return 5;
70 }).thenAnswer(answer -> {
71 ((ByteBuffer) answer.getArgument(0)).position(6);
72 return 6;
73 });
74 stream.write("hello".getBytes(StandardCharsets.UTF_8));
75 stream.write("world\n".getBytes(StandardCharsets.UTF_8));
76 verify(channel, times(2)).write((ByteBuffer) any());
77 assertEquals(11, stream.position());
78 }
79
80 @Test
81 void testWriteFullyAt_whenFullAtOnce_thenSucceed() throws IOException {
82 final FileChannel channel = mock(FileChannel.class);
83 final FileRandomAccessOutputStream stream = new FileRandomAccessOutputStream(channel);
84 when(channel.write((ByteBuffer) any(), eq(20L))).thenAnswer(answer -> {
85 ((ByteBuffer) answer.getArgument(0)).position(5);
86 return 5;
87 });
88 when(channel.write((ByteBuffer) any(), eq(30L))).thenAnswer(answer -> {
89 ((ByteBuffer) answer.getArgument(0)).position(6);
90 return 6;
91 });
92 stream.writeAll("hello".getBytes(StandardCharsets.UTF_8), 20);
93 stream.writeAll("world\n".getBytes(StandardCharsets.UTF_8), 30);
94
95 verify(channel, times(1)).write((ByteBuffer) any(), eq(20L));
96 verify(channel, times(1)).write((ByteBuffer) any(), eq(30L));
97
98 assertEquals(11, stream.position());
99 }
100
101 @Test
102 void testWriteFullyAt_whenFullButPartial_thenSucceed() throws IOException {
103 final FileChannel channel = mock(FileChannel.class);
104 final FileRandomAccessOutputStream stream = new FileRandomAccessOutputStream(channel);
105 when(channel.write((ByteBuffer) any(), eq(20L))).thenAnswer(answer -> {
106 ((ByteBuffer) answer.getArgument(0)).position(3);
107 return 3;
108 });
109 when(channel.write((ByteBuffer) any(), eq(23L))).thenAnswer(answer -> {
110 ((ByteBuffer) answer.getArgument(0)).position(5);
111 return 2;
112 });
113 when(channel.write((ByteBuffer) any(), eq(30L))).thenAnswer(answer -> {
114 ((ByteBuffer) answer.getArgument(0)).position(6);
115 return 6;
116 });
117 stream.writeAll("hello".getBytes(StandardCharsets.UTF_8), 20);
118 stream.writeAll("world\n".getBytes(StandardCharsets.UTF_8), 30);
119
120 verify(channel, times(1)).write((ByteBuffer) any(), eq(20L));
121 verify(channel, times(1)).write((ByteBuffer) any(), eq(23L));
122 verify(channel, times(1)).write((ByteBuffer) any(), eq(30L));
123
124 assertEquals(11, stream.position());
125 }
126
127 @Test
128 void testWriteFullyAt_whenPartial_thenFail() throws IOException {
129 final FileChannel channel = mock(FileChannel.class);
130 final FileRandomAccessOutputStream stream = new FileRandomAccessOutputStream(channel);
131 when(channel.write((ByteBuffer) any(), eq(20L))).thenAnswer(answer -> 0).thenAnswer(answer -> {
132 ((ByteBuffer) answer.getArgument(0)).position(3);
133 return 3;
134 });
135 when(channel.write((ByteBuffer) any(), eq(23L))).thenAnswer(answer -> -1);
136 assertThrows(IOException.class, () -> stream.writeAll("hello".getBytes(StandardCharsets.UTF_8), 20));
137
138 verify(channel, times(2)).write((ByteBuffer) any(), eq(20L));
139 verify(channel, times(1)).write((ByteBuffer) any(), eq(23L));
140 verify(channel, times(0)).write((ByteBuffer) any(), eq(25L));
141
142 assertEquals(0, stream.position());
143 }
144 }