-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathParallelBlockInputStreamTest.java
More file actions
111 lines (100 loc) · 4.7 KB
/
Copy pathParallelBlockInputStreamTest.java
File metadata and controls
111 lines (100 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package crosby.binary;
import crosby.binary.file.BlockInputStream;
import crosby.binary.file.ParallelBlockInputStream;
import org.junit.Assert;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Verifies that ParallelBlockInputStream still delivers blocks to the adaptor
* one at a time, in file order, producing output identical to the sequential
* BlockInputStream reader (see ReadFileTest).
*/
public class ParallelBlockInputStreamTest {
@Test
public void testParallel() throws Exception {
try (InputStream input = ReadFileTest.class.getResourceAsStream("/sample.pbf");
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
ParallelBlockInputStream blockInput = new ParallelBlockInputStream(
input, new ReadFileTest.TestBinaryParser(printWriter), 4)) {
blockInput.process();
Assert.assertEquals(ReadFileTest.EXPECTED, stringWriter.toString());
}
}
/**
* sample.pbf only has 4 blocks, so the default pipelineDepth (2 *
* numThreads) never fills up mid-stream: every block ends up delivered
* from the final drain loop after EOF, never from the backpressure
* branch inside the read loop. Force a small pipelineDepth so that
* branch -- and the resulting handleBlock/skipBlock interleaving -- is
* actually exercised.
*/
@Test
public void testParallelWithBackpressure() throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(2);
try (InputStream input = ReadFileTest.class.getResourceAsStream("/sample.pbf");
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
ParallelBlockInputStream blockInput = new ParallelBlockInputStream(
input, new ReadFileTest.TestBinaryParser(printWriter), executor, 2)) {
blockInput.process();
Assert.assertEquals(ReadFileTest.EXPECTED, stringWriter.toString());
} finally {
executor.shutdownNow();
executor.awaitTermination(5, TimeUnit.SECONDS);
}
}
/**
* A block body truncated mid-stream must be treated as a clean end of
* input -- same as BlockInputStream -- rather than aborting process()
* before complete() is called and dropping whatever was already
* in flight. Compares against BlockInputStream on the exact same bytes
* to pin the expected behavior instead of hard-coding it.
*/
@Test
public void testTruncatedInputMatchesSequentialReader() throws Exception {
byte[] full = readAll(ReadFileTest.class.getResourceAsStream("/sample.pbf"));
byte[] truncated = new byte[full.length / 2];
System.arraycopy(full, 0, truncated, 0, truncated.length);
String sequential = runSequential(truncated);
String parallel = runParallel(truncated);
Assert.assertTrue("sequential reader should still complete", sequential.endsWith("Complete!" + System.lineSeparator()));
Assert.assertEquals(sequential, parallel);
}
private static String runSequential(byte[] bytes) throws IOException {
try (InputStream input = new ByteArrayInputStream(bytes);
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter)) {
new BlockInputStream(input, new ReadFileTest.TestBinaryParser(printWriter)).process();
return stringWriter.toString();
}
}
private static String runParallel(byte[] bytes) throws IOException {
try (InputStream input = new ByteArrayInputStream(bytes);
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
ParallelBlockInputStream blockInput = new ParallelBlockInputStream(
input, new ReadFileTest.TestBinaryParser(printWriter), 2)) {
blockInput.process();
return stringWriter.toString();
}
}
private static byte[] readAll(InputStream in) throws IOException {
try (InputStream input = in; ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] buf = new byte[4096];
int n;
while ((n = input.read(buf)) >= 0) {
out.write(buf, 0, n);
}
return out.toByteArray();
}
}
}