]>
Commit | Line | Data |
---|---|---|
3749640d | 1 | /* Test program for random(), srandom(), initstate(), setstate() |
3749640d UD |
2 | Placed in the public domain. */ |
3 | ||
4 | /* This program primarily tests the correct functioning of srandom() | |
5 | and setstate(). The strategy is generate and store a set of random | |
6 | sequences, each with a specified starting seed. Then each sequence | |
7 | is regenerated twice and checked against the stored values. | |
8 | ||
9 | First they are regenerated one sequence at a time, using srandom() | |
10 | to set the initial state. A discrepency here would suggest that | |
11 | srandom() was failing to completely initialize the random number | |
12 | generator. | |
13 | ||
14 | Second the sequences are regenerated in an interleaved order. | |
15 | A state vector is created for each sequence using initstate(). | |
16 | setstate() is used to switch from sequence to sequence during | |
17 | the interleaved generation. A discrepency here would suggest | |
18 | a problem with either initstate() failing to initialize the | |
19 | random number generator properly, or the failure of setstate() | |
20 | to correctly save and restore state information. Also, each | |
21 | time setstate() is called, the returned value is checked for | |
22 | correctness (since we know what it should be). | |
23 | ||
24 | Note: We use default state vector for sequence 0 and our own | |
25 | state vectors for the remaining sequences. This is to give a check | |
26 | that the value returned by initstate() is valid and can indeed be | |
27 | used in the future. */ | |
28 | ||
29 | /* Strategy: | |
30 | 1. Use srandom() followed by calls on random to generate a set of | |
31 | sequences of values. | |
32 | 2. Regenerate and check the sequences. | |
33 | 3. Use initstate() to create new states. | |
34 | 4. Regenerate the sequences in an interleaved manner and check. | |
35 | */ | |
36 | ||
37 | #include <stdlib.h> | |
38 | #include <stdio.h> | |
39 | ||
40 | const int degree = 128; /* random number generator degree (should | |
41 | be one of 8, 16, 32, 64, 128, 256) */ | |
42 | const int nseq = 3; /* number of test sequences */ | |
43 | const int nrnd = 50; /* length of each test sequence */ | |
44 | const unsigned int seed[3] = { 0x12344321U, 0xEE11DD22U, 0xFEDCBA98 }; | |
45 | ||
bf4de8f3 | 46 | void fail (const char *msg, int s, int i) __attribute__ ((__noreturn__)); |
3749640d | 47 | |
29955b5d AS |
48 | static int |
49 | do_test (void) | |
3749640d UD |
50 | { |
51 | long int rnd[nseq][nrnd]; /* pseudorandom numbers */ | |
52 | char* state[nseq]; /* state for PRNG */ | |
53 | char* oldstate[nseq]; /* old PRNG state */ | |
54 | int s; /* sequence index */ | |
55 | int i; /* element index */ | |
56 | ||
57 | printf ("Begining random package test using %d sequences of length %d.\n", | |
58 | nseq, nrnd); | |
59 | ||
60 | /* 1. Generate and store the sequences. */ | |
61 | printf ("Generating random sequences.\n"); | |
62 | for (s = 0; s < nseq; ++s) | |
63 | { | |
64 | srandom ( seed[s] ); | |
65 | for (i = 0; i < nrnd; ++i) | |
66 | rnd[s][i] = random (); | |
67 | } | |
68 | ||
69 | /* 2. Regenerate and check. */ | |
70 | printf ("Regenerating and checking sequences.\n"); | |
71 | for (s = 0; s < nseq; ++s) | |
72 | { | |
73 | srandom (seed[s]); | |
74 | for (i = 0; i < nrnd; ++i) | |
75 | if (rnd[s][i] != random ()) | |
76 | fail ("first regenerate test", s, i); | |
77 | } | |
78 | ||
79 | /* 3. Create state vector, one for each sequence. | |
80 | First state is random's internal state; others are malloced. */ | |
81 | printf ("Creating and checking state vector for each sequence.\n"); | |
82 | srandom (seed[0]); /* reseed with first seed */ | |
83 | for (s = 1; s < nseq; ++s) | |
84 | { | |
85 | state[s] = (char*) malloc (degree); | |
86 | oldstate[s] = initstate (seed[s], state[s], degree); | |
87 | } | |
88 | state[0] = oldstate[1]; | |
89 | ||
90 | /* Check returned values. */ | |
91 | for (s = 1; s < nseq - 1; ++s) | |
92 | if (state[s] != oldstate[s + 1]) | |
93 | fail ("bad initstate() return value", s, i); | |
94 | ||
95 | /* 4. Regenerate sequences interleaved and check. */ | |
96 | printf ("Regenerating and checking sequences in interleaved order.\n"); | |
97 | for (i = 0; i < nrnd; ++i) | |
98 | { | |
99 | for (s = 0; s < nseq; ++s) | |
100 | { | |
101 | char *oldstate = (char *) setstate (state[s]); | |
102 | if (oldstate != state[(s + nseq - 1) % nseq]) | |
647eb037 | 103 | fail ("bad setstate() return value", s, i); |
3749640d UD |
104 | if (rnd[s][i] != random ()) |
105 | fail ("bad value generated in interleave test", s, i); | |
106 | } | |
107 | } | |
108 | printf ("All tests passed!\n"); | |
109 | return 0; | |
110 | } | |
111 | ||
112 | void | |
113 | fail (const char *msg, int s, int i) | |
114 | { | |
115 | printf ("\nTest FAILED: "); | |
116 | printf ("%s (seq %d, pos %d).\n", msg, s, i); | |
117 | exit (1); | |
118 | } | |
29955b5d AS |
119 | |
120 | #define TEST_FUNCTION do_test () | |
121 | #include "../test-skeleton.c" |