forked from github/server
facility to inject a non-random random generator
This should be handy for writing tests that make use of randomization.
This commit is contained in:
parent
1a9e3db423
commit
703edb676c
4 changed files with 78 additions and 2 deletions
|
@ -23,6 +23,7 @@
|
|||
#include <util/language.h>
|
||||
#include <util/message.h>
|
||||
#include <util/log.h>
|
||||
#include <util/rand.h>
|
||||
|
||||
#include <CuTest.h>
|
||||
|
||||
|
@ -103,6 +104,8 @@ void test_cleanup(void)
|
|||
errno = 0;
|
||||
log_error("errno: %d", error);
|
||||
}
|
||||
|
||||
random_source_reset();
|
||||
}
|
||||
|
||||
terrain_type *
|
||||
|
|
|
@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "rng.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
@ -65,3 +66,66 @@ bool chance(double x)
|
|||
return true;
|
||||
return rng_double() < x;
|
||||
}
|
||||
|
||||
extern double genrand_real2(void);
|
||||
|
||||
|
||||
typedef struct random_source {
|
||||
double (*double_source) (void);
|
||||
} random_source;
|
||||
|
||||
random_source *r_source = 0;
|
||||
|
||||
double rng_injectable_double(void) {
|
||||
if (r_source)
|
||||
return r_source->double_source();
|
||||
return genrand_real2();
|
||||
}
|
||||
|
||||
static double constant_value;
|
||||
|
||||
static double constant_source (void) {
|
||||
return constant_value;
|
||||
}
|
||||
|
||||
struct random_source constant_provider = {
|
||||
constant_source
|
||||
};
|
||||
|
||||
void random_source_inject_constant(double value) {
|
||||
constant_value = value;
|
||||
r_source = &constant_provider;
|
||||
}
|
||||
|
||||
static int i = 0;
|
||||
static double *values;
|
||||
static int value_size = 0;
|
||||
|
||||
static double array_source (void) {
|
||||
assert(i<value_size);
|
||||
return values[i++];
|
||||
}
|
||||
|
||||
struct random_source array_provider = {
|
||||
array_source
|
||||
};
|
||||
|
||||
void random_source_inject_array(double inject[], int size) {
|
||||
assert(size > 0);
|
||||
value_size = size;
|
||||
if (values)
|
||||
free(values);
|
||||
values = malloc(sizeof(double) * size);
|
||||
for (i=0; i < size; ++i) {
|
||||
values[i] = inject[i];
|
||||
}
|
||||
i = 0;
|
||||
r_source = &array_provider;
|
||||
}
|
||||
|
||||
void random_source_reset(void) {
|
||||
if (values)
|
||||
free(values);
|
||||
values = NULL;
|
||||
r_source = NULL;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,15 @@ extern "C" {
|
|||
extern int ntimespprob(int n, double p, double mod);
|
||||
extern bool chance(double x);
|
||||
|
||||
/* a random source that generates numbers in [0, 1).
|
||||
By calling the random_source_inject... functions you can set a special random source,
|
||||
which is handy for testing */
|
||||
double rng_injectable_double(void);
|
||||
|
||||
void random_source_inject_constant(double value);
|
||||
void random_source_inject_array(double inject[], int size);
|
||||
void random_source_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
extern unsigned long genrand_int32(void);
|
||||
|
||||
/* generates a random number on [0,1)-real-interval */
|
||||
extern double genrand_real2(void);
|
||||
extern double rng_injectable_double(void);
|
||||
|
||||
/* generates a random number on [0,0x7fffffff]-interval */
|
||||
long genrand_int31(void);
|
||||
|
@ -31,7 +31,7 @@ extern "C" {
|
|||
# define rng_init(seed) init_genrand(seed)
|
||||
# define rng_int (int)genrand_int31
|
||||
# define rng_uint (unsigned int)genrand_int32
|
||||
# define rng_double genrand_real2
|
||||
# define rng_double rng_injectable_double
|
||||
# define RNG_RAND_MAX 0x7fffffff
|
||||
#else
|
||||
# include <stdlib.h>
|
||||
|
|
Loading…
Reference in a new issue