1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.rng.core.source32;
18
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.io.ObjectInputStream;
22 import java.io.ObjectOutputStream;
23 import java.io.Serializable;
24 import java.util.Random;
25
26 import org.apache.commons.rng.RandomProviderState;
27 import org.apache.commons.rng.core.RandomAssert;
28 import org.apache.commons.rng.core.RandomProviderDefaultState;
29 import org.apache.commons.rng.core.util.NumberFactory;
30 import org.junit.jupiter.api.Assertions;
31 import org.junit.jupiter.api.Test;
32
33 class JDKRandomTest {
34
35
36
37
38
39 static class SerializableTestObject implements Serializable {
40 private static final long serialVersionUID = 1L;
41
42 private int state0;
43 private double state1;
44 private long state2;
45 private boolean state3;
46
47
48
49
50
51
52
53
54 private void readObject(ObjectInputStream input)
55 throws IOException,
56 ClassNotFoundException {
57 Assertions.fail("*** Malicious code ***. This should not be run during the test");
58 }
59 }
60
61 @Test
62 void testReferenceCode() {
63 final long refSeed = -1357111213L;
64 final JDKRandom rng = new JDKRandom(refSeed);
65 final Random jdk = new Random(refSeed);
66
67
68
69 final int numRepeats = 1000;
70 for (int[] r = {0}; r[0] < numRepeats; r[0]++) {
71 Assertions.assertEquals(jdk.nextInt(), rng.nextInt(), () -> r[0] + " nextInt");
72 }
73 }
74
75
76
77
78
79 @Test
80 void testRestoreToNewInstance() {
81 final long seed = 8796746234L;
82 final JDKRandom rng1 = new JDKRandom(seed);
83 final JDKRandom rng2 = new JDKRandom(seed + 1);
84
85
86 final int numRepeats = 10;
87 for (int[] r = {0}; r[0] < numRepeats; r[0]++) {
88 Assertions.assertNotEquals(rng1.nextInt(), rng2.nextInt(), () -> r[0] + " nextInt");
89 }
90
91 final RandomProviderState state = rng1.saveState();
92
93
94
95 rng2.restoreState(state);
96
97
98 RandomAssert.assertNextIntEquals(numRepeats, rng1, rng2);
99 }
100
101
102
103
104
105
106
107 @Test
108 void testRestoreWithInvalidClass() throws IOException {
109
110 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
111 try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {
112 oos.writeObject(new SerializableTestObject());
113 }
114
115
116
117 final byte[] state = bos.toByteArray();
118 final int stateSize = state.length;
119 final byte[] sizeAndState = new byte[4 + stateSize];
120 System.arraycopy(NumberFactory.makeByteArray(stateSize), 0, sizeAndState, 0, 4);
121 System.arraycopy(state, 0, sizeAndState, 4, stateSize);
122
123 final RandomProviderDefaultState dummyState = new RandomProviderDefaultState(sizeAndState);
124
125 final JDKRandom rng = new JDKRandom(13L);
126 Assertions.assertThrows(IllegalStateException.class, () -> rng.restoreState(dummyState));
127 }
128 }