(root)/
glibc-2.38/
stdlib/
tst-random.c
       1  /* Test program for random(), srandom(), initstate(), setstate()
       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 discrepancy 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 discrepancy 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  
      46  void fail (const char *msg, int s, int i) __attribute__ ((__noreturn__));
      47  
      48  static int
      49  do_test (void)
      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 ("Beginning 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])
     103  	    fail ("bad setstate() return value", s, i);
     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  }
     119  
     120  #define TEST_FUNCTION do_test ()
     121  #include "../test-skeleton.c"