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:
|
Queue:
|
||||||
Queues are lists of songs that the user has requested to play. They
|
Queues are lists of songs that the user has requested to play. They
|
||||||
are the main interface for all music played by Ocarina.
|
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
|
filter
|
||||||
idle
|
idle
|
||||||
tags
|
tags
|
||||||
|
random
|
||||||
queue
|
queue
|
||||||
|
|
|
@ -16,6 +16,7 @@ tests = [
|
||||||
("filter.cpp", True, [], []),
|
("filter.cpp", True, [], []),
|
||||||
("idle.cpp", False, [ "idle.cpp" ], []),
|
("idle.cpp", False, [ "idle.cpp" ], []),
|
||||||
("tags.cpp", True, [], [ "taglib" ]),
|
("tags.cpp", True, [], [ "taglib" ]),
|
||||||
|
("random.cpp", False, [ "random.cpp" ], []),
|
||||||
("queue.cpp", True, [ "callback.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