1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.rng.core;
18
19 import org.junit.jupiter.api.Test;
20 import org.junit.jupiter.params.ParameterizedTest;
21 import org.junit.jupiter.params.provider.ValueSource;
22
23 import java.util.Arrays;
24 import java.util.SplittableRandom;
25
26 import org.apache.commons.rng.core.source64.SplitMix64;
27 import org.junit.jupiter.api.Assertions;
28 import org.junit.jupiter.api.Assumptions;
29
30
31
32
33
34
35
36
37
38 class BaseProviderTest {
39 @Test
40 void testStateSizeTooSmall() {
41 final DummyGenerator dummy = new DummyGenerator();
42 final int size = dummy.getStateSize();
43 Assumptions.assumeTrue(size > 0);
44 final RandomProviderDefaultState state = new RandomProviderDefaultState(new byte[size - 1]);
45 Assertions.assertThrows(IllegalStateException.class, () -> dummy.restoreState(state));
46 }
47
48 @Test
49 void testStateSizeTooLarge() {
50 final DummyGenerator dummy = new DummyGenerator();
51 final int size = dummy.getStateSize();
52 final RandomProviderDefaultState state = new RandomProviderDefaultState(new byte[size + 1]);
53 Assertions.assertThrows(IllegalStateException.class, () -> dummy.restoreState(state));
54 }
55
56 @Test
57 void testFillStateInt() {
58 final int[] state = new int[10];
59 final int[] seed = {1, 2, 3};
60
61 for (int i = 0; i < state.length; i++) {
62 Assertions.assertEquals(0, state[i]);
63 }
64
65 new DummyGenerator().fillState(state, seed);
66 for (int i = 0; i < seed.length; i++) {
67 Assertions.assertEquals(seed[i], state[i]);
68 }
69 for (int i = seed.length; i < state.length; i++) {
70 Assertions.assertNotEquals(0, state[i]);
71 }
72 }
73
74 @Test
75 void testFillStateLong() {
76 final long[] state = new long[10];
77 final long[] seed = {1, 2, 3};
78
79 for (int i = 0; i < state.length; i++) {
80 Assertions.assertEquals(0, state[i]);
81 }
82
83 new DummyGenerator().fillState(state, seed);
84 for (int i = 0; i < seed.length; i++) {
85 Assertions.assertEquals(seed[i], state[i]);
86 }
87 for (int i = seed.length; i < state.length; i++) {
88 Assertions.assertNotEquals(0, state[i]);
89 }
90 }
91
92
93
94
95
96 @Test
97 void testCheckIndex() {
98 final BaseProvider rng = new BaseProvider() {
99 @Override
100 public void nextBytes(byte[] bytes) { }
101 @Override
102 public void nextBytes(byte[] bytes, int start, int len) { }
103 @Override
104 public int nextInt() {
105 return 0;
106 }
107 @Override
108 public long nextLong() {
109 return 0;
110 }
111 @Override
112 public boolean nextBoolean() {
113 return false;
114 }
115 @Override
116 public float nextFloat() {
117 return 0;
118 }
119 @Override
120 public double nextDouble() {
121 return 0;
122 }
123 };
124
125
126 rng.checkIndex(-10, 5, 0);
127 rng.checkIndex(-10, 5, -10);
128 rng.checkIndex(-10, 5, 5);
129 rng.checkIndex(Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
130 rng.checkIndex(Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
131 Assertions.assertThrows(IndexOutOfBoundsException.class, () -> rng.checkIndex(-10, 5, -11));
132 Assertions.assertThrows(IndexOutOfBoundsException.class, () -> rng.checkIndex(-10, 5, 6));
133 Assertions.assertThrows(IndexOutOfBoundsException.class, () -> rng.checkIndex(-10, 5, Integer.MIN_VALUE));
134 Assertions.assertThrows(IndexOutOfBoundsException.class, () -> rng.checkIndex(-10, 5, Integer.MAX_VALUE));
135 }
136
137
138
139
140 @ParameterizedTest
141 @ValueSource(ints = {0, 1, 2, 4, 5, 6, 7, 8, 9})
142 void testExpandSeedLong(int length) {
143
144
145 final SplittableRandom rng = new SplittableRandom();
146 for (final long[] seed : new long[][] {
147 {},
148 rng.longs(1).toArray(),
149 rng.longs(2).toArray(),
150 rng.longs(3).toArray(),
151 rng.longs(4).toArray(),
152 rng.longs(5).toArray(),
153 rng.longs(6).toArray(),
154 rng.longs(7).toArray(),
155 rng.longs(8).toArray(),
156 rng.longs(9).toArray(),
157 }) {
158 Assertions.assertArrayEquals(expandSeed(length, seed),
159 BaseProvider.extendSeed(seed, length));
160 }
161 }
162
163
164
165
166
167
168
169
170
171 private static long[] expandSeed(int length, long... seed) {
172 if (seed.length < length) {
173 final long[] s = Arrays.copyOf(seed, length);
174 final SplitMix64 rng = new SplitMix64(s[0]);
175 for (int i = seed.length; i < length; i++) {
176 s[i] = rng.nextLong();
177 }
178 return s;
179 }
180 return seed;
181 }
182
183
184
185
186
187
188
189
190 @ParameterizedTest
191 @ValueSource(ints = {0, 1, 2, 4, 5, 6, 7, 8, 9})
192 void testExpandSeedInt(int length) {
193
194
195 final int seedA = 0x012de1ba;
196 final int[] valuesA = {
197 0x2f66c8b6, 0x256c0269, 0x054ef409, 0x402425ba, 0x78ebf590, 0x76bea1db,
198 0x8bf5dcbe, 0x104ecdd4, 0x43cfc87e, 0xa33c7643, 0x4d210f56, 0xfa12093d,
199 };
200
201 final int[] values0 = {
202 0x92ca2f0e, 0x3cd6e3f3, 0x1b147dcc, 0x4c081dbf, 0x487981ab, 0xdb408c9d,
203 0x78bc1b8f, 0xd83072e5, 0x65cbdd54, 0x1f4b8cef, 0x91783bb0, 0x0231739b,
204 };
205
206
207
208 final int[] data = new SplittableRandom().ints(10).toArray();
209 data[0] = seedA;
210
211 for (int i = 0; i <= 9; i++) {
212 final int seedLength = i;
213
214 final int[] seed = Arrays.copyOf(data, seedLength);
215
216
217 final int[] expected = Arrays.copyOf(seed, Math.max(seedLength, length));
218 if (expected.length == 0) {
219
220 Assertions.assertArrayEquals(new int[0],
221 BaseProvider.extendSeed(seed, length));
222 continue;
223 }
224
225
226 final int[] source = expected[0] == 0 ? values0 : valuesA;
227 System.arraycopy(source, 0, expected, seedLength, expected.length - seedLength);
228 Assertions.assertArrayEquals(expected,
229 BaseProvider.extendSeed(seed, length),
230 () -> String.format("%d -> %d", seedLength, length));
231 }
232 }
233
234
235
236
237
238
239
240
241 static class DummyGenerator extends org.apache.commons.rng.core.source32.IntProvider {
242
243 @Override
244 public int next() {
245 return 4;
246 }
247
248
249
250
251
252
253 int getStateSize() {
254 return getStateInternal().length;
255 }
256
257
258
259
260 @Override
261 public void fillState(int[] state, int[] seed) {
262 super.fillState(state, seed);
263 }
264
265
266 @Override
267 public void fillState(long[] state, long[] seed) {
268 super.fillState(state, seed);
269 }
270 }
271 }