21
21
* questions.
22
22
*/
23
23
24
- import static java .lang .String .format ;
25
-
26
24
import java .io .ByteArrayInputStream ;
27
25
import java .io .ByteArrayOutputStream ;
28
26
import java .io .IOException ;
39
37
import java .util .function .Consumer ;
40
38
import java .util .function .Supplier ;
41
39
40
+ import org .testng .annotations .DataProvider ;
41
+ import org .testng .annotations .Test ;
42
+
42
43
import jdk .test .lib .RandomFactory ;
43
44
45
+ import static java .lang .String .format ;
46
+
47
+ import static org .testng .Assert .assertEquals ;
48
+ import static org .testng .Assert .assertThrows ;
49
+ import static org .testng .Assert .assertTrue ;
50
+
44
51
/*
45
52
* @test
46
53
* @library /test/lib
47
54
* @build jdk.test.lib.RandomFactory
48
- * @run main TransferTo
55
+ * @run testng TransferTo
49
56
* @bug 8265891
50
57
* @summary tests whether sun.nio.ChannelInputStream.transferTo conforms to the
51
58
* InputStream.transferTo contract defined in the javadoc
@@ -59,59 +66,81 @@ public class TransferTo {
59
66
60
67
private static final Random RND = RandomFactory .getRandom ();
61
68
62
- public static void main (String [] args ) throws Exception {
63
- test (fileChannelInput (), fileChannelOutput ());
64
- test (readableByteChannelInput (), defaultOutput ());
65
- }
66
-
67
- private static void test (InputStreamProvider inputStreamProvider , OutputStreamProvider outputStreamProvider )
68
- throws Exception {
69
- testNullPointerException (inputStreamProvider );
70
- testStreamContents (inputStreamProvider , outputStreamProvider );
69
+ /*
70
+ * Provides test scenarios, i. e. combinations of input and output streams to be tested.
71
+ */
72
+ @ DataProvider
73
+ public static Object [][] streamCombinations () throws Exception {
74
+ return new Object [][] {
75
+ // tests FileChannel.transferTo(FileChannel) optimized case
76
+ { fileChannelInput (), fileChannelOutput () },
77
+
78
+ // tests InputStream.transferTo(OutputStream) default case
79
+ { readableByteChannelInput (), defaultOutput () }
80
+ };
71
81
}
72
82
73
- private static void testNullPointerException (InputStreamProvider inputStreamProvider ) throws Exception {
74
- try (InputStream in = inputStreamProvider .input ()) {
75
- assertThrowsNPE (() -> in .transferTo (null ), "out" );
76
- }
83
+ /*
84
+ * Testing API compliance: Input stream must throw NullPointerException when parameter "out" is null.
85
+ */
86
+ @ Test (dataProvider = "streamCombinations" )
87
+ public void testNullPointerException (InputStreamProvider inputStreamProvider ,
88
+ OutputStreamProvider outputStreamProvider ) throws Exception {
89
+ // tests empty input stream
90
+ assertThrows (NullPointerException .class , () -> inputStreamProvider .input ().transferTo (null ));
77
91
78
- try (InputStream in = inputStreamProvider .input ((byte ) 1 )) {
79
- assertThrowsNPE (() -> in .transferTo (null ), "out" );
80
- }
92
+ // tests single-byte input stream
93
+ assertThrows (NullPointerException .class , () -> inputStreamProvider .input ((byte ) 1 ).transferTo (null ));
81
94
82
- try (InputStream in = inputStreamProvider .input ((byte ) 1 , (byte ) 2 )) {
83
- assertThrowsNPE (() -> in .transferTo (null ), "out" );
84
- }
95
+ // tests dual-byte input stream
96
+ assertThrows (NullPointerException .class , () -> inputStreamProvider .input ((byte ) 1 , (byte ) 2 ).transferTo (null ));
85
97
}
86
98
87
- private static void testStreamContents (InputStreamProvider inputStreamProvider ,
99
+ /*
100
+ * Testing API compliance: Complete content of input stream must be transferred to output stream.
101
+ */
102
+ @ Test (dataProvider = "streamCombinations" )
103
+ public void testStreamContents (InputStreamProvider inputStreamProvider ,
88
104
OutputStreamProvider outputStreamProvider ) throws Exception {
105
+ // tests empty input stream
89
106
checkTransferredContents (inputStreamProvider , outputStreamProvider , new byte [0 ]);
107
+
108
+ // tests input stream with a length between 1k and 4k
90
109
checkTransferredContents (inputStreamProvider , outputStreamProvider , createRandomBytes (1024 , 4096 ));
91
110
92
- // to span through several batches
111
+ // tests input stream with several data chunks, as 16k is more than a single chunk can hold
93
112
checkTransferredContents (inputStreamProvider , outputStreamProvider , createRandomBytes (16384 , 16384 ));
94
113
95
- // randomly chosen starting positions within source and target
114
+ // tests randomly chosen starting positions within source and target stream
96
115
for (int i = 0 ; i < ITERATIONS ; i ++) {
97
116
byte [] inBytes = createRandomBytes (MIN_SIZE , MAX_SIZE_INCR );
98
117
int posIn = RND .nextInt (inBytes .length );
99
118
int posOut = RND .nextInt (MIN_SIZE );
100
119
checkTransferredContents (inputStreamProvider , outputStreamProvider , inBytes , posIn , posOut );
101
120
}
102
121
103
- // beyond source EOF
122
+ // tests reading beyond source EOF (must not transfer any bytes)
104
123
checkTransferredContents (inputStreamProvider , outputStreamProvider , createRandomBytes (4096 , 0 ), 4096 , 0 );
105
124
106
- // beyond target EOF
125
+ // tests writing beyond target EOF (must extend output stream)
107
126
checkTransferredContents (inputStreamProvider , outputStreamProvider , createRandomBytes (4096 , 0 ), 0 , 4096 );
108
127
}
109
128
129
+ /*
130
+ * Asserts that the transferred content is correct, i. e. compares the actually transferred bytes
131
+ * to the expected assumption. The position of the input and output stream before the transfer is
132
+ * the start of stream (BOF).
133
+ */
110
134
private static void checkTransferredContents (InputStreamProvider inputStreamProvider ,
111
135
OutputStreamProvider outputStreamProvider , byte [] inBytes ) throws Exception {
112
136
checkTransferredContents (inputStreamProvider , outputStreamProvider , inBytes , 0 , 0 );
113
137
}
114
138
139
+ /*
140
+ * Asserts that the transferred content is correct, i. e. compares the actually transferred bytes
141
+ * to the expected assumption. The position of the input and output stream before the transfer is
142
+ * provided by the caller.
143
+ */
115
144
private static void checkTransferredContents (InputStreamProvider inputStreamProvider ,
116
145
OutputStreamProvider outputStreamProvider , byte [] inBytes , int posIn , int posOut ) throws Exception {
117
146
AtomicReference <Supplier <byte []>> recorder = new AtomicReference <>();
@@ -124,17 +153,17 @@ private static void checkTransferredContents(InputStreamProvider inputStreamProv
124
153
long reported = in .transferTo (out );
125
154
int count = inBytes .length - posIn ;
126
155
127
- if (reported != count )
128
- throw new AssertionError (
129
- format ("reported %d bytes but should report %d" , reported , count ));
156
+ assertEquals (reported , count , format ("reported %d bytes but should report %d" , reported , count ));
130
157
131
158
byte [] outBytes = recorder .get ().get ();
132
- if (!Arrays .equals (inBytes , posIn , posIn + count , outBytes , posOut , posOut + count ))
133
- throw new AssertionError (
134
- format ("inBytes.length=%d, outBytes.length=%d" , count , outBytes .length ));
159
+ assertTrue (Arrays .equals (inBytes , posIn , posIn + count , outBytes , posOut , posOut + count ),
160
+ format ("inBytes.length=%d, outBytes.length=%d" , count , outBytes .length ));
135
161
}
136
162
}
137
163
164
+ /*
165
+ * Creates an array of random size (between min and min + maxRandomAdditive) filled with random bytes
166
+ */
138
167
private static byte [] createRandomBytes (int min , int maxRandomAdditive ) {
139
168
byte [] bytes = new byte [min + (maxRandomAdditive == 0 ? 0 : RND .nextInt (maxRandomAdditive ))];
140
169
RND .nextBytes (bytes );
@@ -149,6 +178,9 @@ private interface OutputStreamProvider {
149
178
OutputStream output (Consumer <Supplier <byte []>> spy ) throws Exception ;
150
179
}
151
180
181
+ /*
182
+ * Creates a provider for an output stream which does not wrap a channel
183
+ */
152
184
private static OutputStreamProvider defaultOutput () {
153
185
return new OutputStreamProvider () {
154
186
@ Override
@@ -160,6 +192,9 @@ public OutputStream output(Consumer<Supplier<byte[]>> spy) {
160
192
};
161
193
}
162
194
195
+ /*
196
+ * Creates a provider for an input stream which wraps a file channel
197
+ */
163
198
private static InputStreamProvider fileChannelInput () {
164
199
return new InputStreamProvider () {
165
200
@ Override
@@ -172,6 +207,9 @@ public InputStream input(byte... bytes) throws Exception {
172
207
};
173
208
}
174
209
210
+ /*
211
+ * Creates a provider for an input stream which wraps a readable byte channel but is not a file channel
212
+ */
175
213
private static InputStreamProvider readableByteChannelInput () {
176
214
return new InputStreamProvider () {
177
215
@ Override
@@ -181,6 +219,9 @@ public InputStream input(byte... bytes) throws Exception {
181
219
};
182
220
}
183
221
222
+ /*
223
+ * Creates a provider for an output stream which wraps a file channel
224
+ */
184
225
private static OutputStreamProvider fileChannelOutput () {
185
226
return new OutputStreamProvider () {
186
227
public OutputStream output (Consumer <Supplier <byte []>> spy ) throws Exception {
@@ -198,31 +239,4 @@ public OutputStream output(Consumer<Supplier<byte[]>> spy) throws Exception {
198
239
};
199
240
}
200
241
201
- public interface Thrower {
202
- public void run () throws Throwable ;
203
- }
204
-
205
- public static void assertThrowsNPE (Thrower thrower , String message ) {
206
- assertThrows (thrower , NullPointerException .class , message );
207
- }
208
-
209
- public static <T extends Throwable > void assertThrows (Thrower thrower , Class <T > throwable , String message ) {
210
- Throwable thrown ;
211
- try {
212
- thrower .run ();
213
- thrown = null ;
214
- } catch (Throwable caught ) {
215
- thrown = caught ;
216
- }
217
-
218
- if (!throwable .isInstance (thrown )) {
219
- String caught = thrown == null ? "nothing" : thrown .getClass ().getCanonicalName ();
220
- throw new AssertionError (format ("Expected to catch %s, but caught %s" , throwable , caught ), thrown );
221
- }
222
-
223
- if (thrown != null && !message .equals (thrown .getMessage ())) {
224
- throw new AssertionError (
225
- format ("Expected exception message to be '%s', but it's '%s'" , message , thrown .getMessage ()));
226
- }
227
- }
228
242
}
0 commit comments