tests: Make robust against variations in PRNG use

Tests need repeatable pseudorandom numbers to yield repeatable
results.  We seed the pseudorandom number generator with a fixed value
(emp_server -R) to make it produce the same sequence of numbers every
time.  But whenever code exercised by a test is changed to consume
fewer or more of them, all subsequent users get different numbers
regardless.  The ensuing test result changes are extremely tedious to
review.

To address this problem, reseed the PRNG with the count of commands
right before executing a command when running_test_suite is on.  This
way, the effect of perturbing the PRN sequence lasts only until the
next command.

Note that the next command could be another player's.  Doesn't matter.

Adding or removing commands now upsets the PRN sequence even for
commands that don't consume PRNs.  The next commit will take care of
that.

Perturbs test results across the board.  Hopefully, that'll happen
much less frequently now.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2014-01-13 20:24:37 +01:00
parent 6c0a1fcb1e
commit 73f1ac8a2c
5 changed files with 2928 additions and 2921 deletions

View file

@ -29,11 +29,12 @@
* Known contributors to this file:
* Dave Pare, 1994
* Steve McClure, 1998
* Markus Armbruster, 2007-2012
* Markus Armbruster, 2007-2014
*/
#include <config.h>
#include "chance.h"
#include "com.h"
#include "empio.h"
#include "file.h"
@ -46,6 +47,12 @@
#include "prototypes.h"
#include "server.h"
/*
* Last command's PRNG seed.
* Only used when running_test_suite.
*/
int test_suite_prng_seed;
/*
* Execute command named by player->argp[0].
* BUF is the raw UTF-8 command line. It should have been passed to
@ -71,6 +78,7 @@ dispatch(char *buf, char *redir)
return -1;
}
command = &player_coms[cmd];
np = getnatp(player->cnum);
if (np->nat_btu < command->c_cost && command->c_cost > 0) {
if (player->god || opt_BLITZ)
@ -88,6 +96,15 @@ dispatch(char *buf, char *redir)
? PLAYER_SLEEP_ON_INPUT : PLAYER_SLEEP_FREELY;
player->command = command;
empth_rwlock_rdlock(update_lock);
/*
* When running the test suite, reseed PRNG for each command with
* a counter, to keep results stable even when the number of PRNs
* consumed changes.
*/
if (running_test_suite)
seed_prng(++test_suite_prng_seed);
if (redir) {
prredir(redir);
uprnf(buf);
@ -109,6 +126,7 @@ dispatch(char *buf, char *redir)
CANT_REACH();
break;
}
empth_rwlock_unlock(update_lock);
player->command = NULL;
if (player->may_sleep != PLAYER_SLEEP_NEVER || !io_eof(player->iop))