1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.rng.examples.stress;
18
19 import org.apache.commons.rng.UniformRandomProvider;
20 import org.apache.commons.rng.core.source32.IntProvider;
21 import org.apache.commons.rng.core.source32.RandomIntSource;
22 import org.apache.commons.rng.core.source64.RandomLongSource;
23 import org.apache.commons.rng.simple.RandomSource;
24 import org.junit.Assert;
25 import org.junit.Test;
26
27 import java.io.ByteArrayOutputStream;
28 import java.io.DataOutputStream;
29 import java.io.IOException;
30 import java.io.OutputStream;
31 import java.nio.ByteOrder;
32 import java.util.function.BiConsumer;
33 import java.util.function.UnaryOperator;
34
35
36
37
38 public class RngDataOutputTest {
39
40
41
42 interface RngDataOutputFactory {
43
44
45
46
47
48
49
50
51 RngDataOutput create(OutputStream out, int size, ByteOrder byteOrder);
52 }
53
54 @Test
55 public void testIntBigEndian() throws IOException {
56 assertRngOutput(RandomSource.PCG_MCG_XSH_RS_32,
57 UnaryOperator.identity(),
58 RngDataOutputTest::writeInt,
59 RngDataOutput::ofInt, ByteOrder.BIG_ENDIAN);
60 }
61
62 @Test
63 public void testIntLittleEndian() throws IOException {
64 assertRngOutput(RandomSource.PCG_MCG_XSH_RS_32,
65 RNGUtils::createReverseBytesProvider,
66 RngDataOutputTest::writeInt,
67 RngDataOutput::ofInt, ByteOrder.LITTLE_ENDIAN);
68 }
69
70 @Test
71 public void testLongBigEndian() throws IOException {
72 assertRngOutput(RandomSource.SPLIT_MIX_64,
73 UnaryOperator.identity(),
74 RngDataOutputTest::writeLong,
75 RngDataOutput::ofLong, ByteOrder.BIG_ENDIAN);
76 }
77
78 @Test
79 public void testLongLittleEndian() throws IOException {
80 assertRngOutput(RandomSource.SPLIT_MIX_64,
81 RNGUtils::createReverseBytesProvider,
82 RngDataOutputTest::writeLong,
83 RngDataOutput::ofLong, ByteOrder.LITTLE_ENDIAN);
84 }
85
86 @Test
87 public void testLongAsIntBigEndian() throws IOException {
88 assertRngOutput(RandomSource.SPLIT_MIX_64,
89
90
91 rng -> new IntProvider() {
92 @Override
93 public int next() {
94 return rng.nextInt();
95 }
96 },
97 RngDataOutputTest::writeInt,
98 RngDataOutput::ofLongAsInt, ByteOrder.BIG_ENDIAN);
99 }
100
101 @Test
102 public void testLongAsIntLittleEndian() throws IOException {
103 assertRngOutput(RandomSource.SPLIT_MIX_64,
104
105
106 rng -> new IntProvider() {
107 @Override
108 public int next() {
109 return Integer.reverseBytes(rng.nextInt());
110 }
111 },
112 RngDataOutputTest::writeInt,
113 RngDataOutput::ofLongAsInt, ByteOrder.LITTLE_ENDIAN);
114 }
115
116 private static void writeInt(DataOutputStream sink, UniformRandomProvider rng) {
117 try {
118 sink.writeInt(rng.nextInt());
119 } catch (IOException e) {
120 Assert.fail();
121 }
122 }
123
124 private static void writeLong(DataOutputStream sink, UniformRandomProvider rng) {
125 try {
126 sink.writeLong(rng.nextLong());
127 } catch (IOException e) {
128 Assert.fail();
129 }
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 private static void assertRngOutput(RandomSource source,
149 UnaryOperator<UniformRandomProvider> rngConverter,
150 BiConsumer<DataOutputStream, UniformRandomProvider> pipe,
151 RngDataOutputFactory factory,
152 ByteOrder byteOrder) throws IOException {
153 final long seed = RandomSource.createLong();
154 UniformRandomProvider rng1 = RandomSource.create(source, seed);
155 UniformRandomProvider rng2 = RandomSource.create(source, seed);
156 final int size = 37;
157 for (int repeats = 1; repeats <= 2; repeats++) {
158 byte[] expected = createBytes(rng1, size, repeats, rngConverter, pipe);
159 byte[] actual = writeRngOutput(rng2, size, repeats, byteOrder, factory);
160 Assert.assertArrayEquals(expected, actual);
161 }
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175 private static byte[] createBytes(UniformRandomProvider rng, int size, int repeats,
176 UnaryOperator<UniformRandomProvider> rngConverter,
177 BiConsumer<DataOutputStream, UniformRandomProvider> pipe) throws IOException {
178 UniformRandomProvider rng2 = rngConverter.apply(rng);
179
180 if (rng instanceof RandomLongSource && rng2 instanceof RandomIntSource) {
181 size *= 2;
182 }
183 ByteArrayOutputStream out = new ByteArrayOutputStream();
184 try (DataOutputStream sink = new DataOutputStream(out)) {
185 for (int j = 0; j < repeats; j++) {
186 for (int i = 0; i < size; i++) {
187 pipe.accept(sink, rng2);
188 }
189 }
190 }
191 return out.toByteArray();
192 }
193
194
195
196
197
198
199
200
201
202
203
204
205 private static byte[] writeRngOutput(UniformRandomProvider rng, int size, int repeats,
206 ByteOrder byteOrder, RngDataOutputFactory factory) throws IOException {
207 ByteArrayOutputStream out = new ByteArrayOutputStream();
208 try (RngDataOutput sink = factory.create(out, size, byteOrder)) {
209 for (int j = 0; j < repeats; j++) {
210 sink.write(rng);
211 }
212 }
213 return out.toByteArray();
214 }
215 }