random: Use a different RNG for testing
This RNG is more predictable, which makes it great for testing. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
7aa5f22777
commit
6dc8bf7329
20
DESIGN
20
DESIGN
|
@ -828,6 +828,26 @@ Track Tag:
|
|||
|
||||
|
||||
|
||||
Random:
|
||||
The random number generator is used by the Queue to pick a song as
|
||||
randomly as possible. I use two different RNG implementations,
|
||||
depending on if Ocarina is compiled with CONFIG_TEST or not.
|
||||
|
||||
When CONFIG_TEST is enabled, the RNG is a simple counter. Every time
|
||||
_pick_random() is called, the counter is incremented and returned.
|
||||
When compiled without CONFIG_TEST we will return values using the
|
||||
rand() function from stdlib.h.
|
||||
|
||||
- API:
|
||||
void random_seed(unsigned int n);
|
||||
Seed the random number generator based on n.
|
||||
|
||||
void random(unsigned int min, unsigned int max);
|
||||
Return a random number between min and max, inclusive.
|
||||
If min >= max: return min.
|
||||
|
||||
|
||||
|
||||
Queue:
|
||||
Queues are lists of songs that the user has requested to play. They
|
||||
are the main interface for all music played by Ocarina.
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2014 (c) Anna Schumaker
|
||||
*/
|
||||
|
||||
#ifndef OCARINA_RANDOM_H
|
||||
#define OCARINA_RANDOM_H
|
||||
|
||||
#ifndef CONFIG_TEST
|
||||
|
||||
#include <stdlib.h>
|
||||
static inline void _seed_random(unsigned int n) { srand(time(NULL) + n); }
|
||||
static inline unsigned int _pick_random() { return rand(); }
|
||||
|
||||
#else /* CONFIG_TEST */
|
||||
|
||||
void _seed_random(unsigned int);
|
||||
unsigned int _pick_random();
|
||||
|
||||
#endif /* CONFIG_TEST */
|
||||
|
||||
|
||||
|
||||
static inline void random_seed(unsigned int n)
|
||||
{
|
||||
_seed_random(n);
|
||||
}
|
||||
|
||||
static inline unsigned int random(unsigned int min, unsigned int max)
|
||||
{
|
||||
if (min >= max)
|
||||
return min;
|
||||
return min + (_pick_random() % (max - min));
|
||||
}
|
||||
|
||||
|
||||
#endif /* OCARINA_RANDOM_H */
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright 2014 (c) Anna Schumaker
|
||||
*/
|
||||
#ifdef CONFIG_TEST
|
||||
|
||||
#include <random.h>
|
||||
|
||||
static unsigned int _random_value = 0;
|
||||
|
||||
|
||||
void _seed_random(unsigned int n)
|
||||
{
|
||||
_random_value = n;
|
||||
}
|
||||
|
||||
unsigned int _pick_random()
|
||||
{
|
||||
return ++_random_value;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TEST */
|
|
@ -5,4 +5,5 @@ index
|
|||
filter
|
||||
idle
|
||||
tags
|
||||
random
|
||||
queue
|
||||
|
|
|
@ -16,6 +16,7 @@ tests = [
|
|||
("filter.cpp", True, [], []),
|
||||
("idle.cpp", False, [ "idle.cpp" ], []),
|
||||
("tags.cpp", True, [], [ "taglib" ]),
|
||||
("random.cpp", False, [ "random.cpp" ], []),
|
||||
("queue.cpp", True, [ "callback.cpp" ], []),
|
||||
|
||||
]
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2014 (c) Anna Schumaker.
|
||||
*/
|
||||
|
||||
#include <random.h>
|
||||
#include "test.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
static void do_test_rng(unsigned int seed)
|
||||
{
|
||||
random_seed(seed);
|
||||
|
||||
for (unsigned int i = 0; i <= 10; i++) {
|
||||
if (i <= seed)
|
||||
test_equal(random(seed, i), seed);
|
||||
else
|
||||
test_equal(random(seed, i), seed + (i % (i - seed)));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_rng(unsigned int seed)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << " (seed = " << seed << ")";
|
||||
std::string seed_str = ss.str();
|
||||
|
||||
run_test("Random Number Generator Test" + seed_str, do_test_rng, seed);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
for (unsigned int i = 0; i < 10; i++)
|
||||
test_rng(i);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue