summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/genall5.c28
-rw-r--r--test/genall5.h1
-rw-r--r--test/testvfdswmr.sh.in2
-rw-r--r--test/vfd_swmr_zoo_writer.c51
4 files changed, 75 insertions, 7 deletions
diff --git a/test/genall5.c b/test/genall5.c
index b9a66f8..dfc835e 100644
--- a/test/genall5.c
+++ b/test/genall5.c
@@ -2676,6 +2676,31 @@ create_or_validate_selection(hid_t fid, const char *full_path,
return true;
}
+/* Sleep for no more than `max_pause_msecs` milliseconds. */
+static void
+random_pause(unsigned int max_pause_msecs)
+{
+ struct timespec delay;
+ const uint64_t nsecs_per_sec = 1000 * 1000 * 1000;
+ uint64_t nsecs_per_msec, nsecs;
+
+ if (max_pause_msecs == 0)
+ return;
+
+ nsecs_per_msec = 1 + (uint64_t)random() % (1000 * 1000);
+ nsecs = max_pause_msecs * nsecs_per_msec;
+
+ delay.tv_sec = (time_t)(nsecs / nsecs_per_sec);
+ delay.tv_nsec = (long)(nsecs % nsecs_per_sec);
+ for (;;) {
+ if (nanosleep(&delay, &delay) == 0)
+ break;
+ if (errno == EINTR)
+ continue;
+ errx(EXIT_FAILURE, "%s: nanosleep", __func__);
+ }
+}
+
/* Create and validate objects or, if `only_validate` is true, only
* validate objects in file `fid` under group `base_path`. `config.proc_num`
* tells the processor number the test runs on. If `config.skip_varlen` is
@@ -2688,7 +2713,6 @@ static bool
tend_zoo(hid_t fid, const char *base_path, zoo_config_t config,
const phase_t *phase, size_t nphases)
{
- struct timespec delay = {.tv_sec = 0, .tv_nsec = 50 * 1000 * 1000};
char full_path[1024];
int i, nwritten;
size_t j;
@@ -2716,8 +2740,8 @@ tend_zoo(hid_t fid, const char *base_path, zoo_config_t config,
if (phase[j] == PHASE_CREATE || phase[j] == PHASE_DELETE)
zoo_create_hook(fid);
}
+ random_pause(config.max_pause_msecs);
}
- nanosleep(&delay, NULL);
out:
if (!ok)
warnx("%s: %s", __func__, failure_mssg);
diff --git a/test/genall5.h b/test/genall5.h
index 4e5fbba..1becbb2 100644
--- a/test/genall5.h
+++ b/test/genall5.h
@@ -20,6 +20,7 @@ typedef struct _zoo_config {
bool continue_on_failure;
bool skip_compact;
bool skip_varlen;
+ unsigned max_pause_msecs;
} zoo_config_t;
bool create_zoo(hid_t, const char *, zoo_config_t);
diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in
index 925f3e2..b372e1c 100644
--- a/test/testvfdswmr.sh.in
+++ b/test/testvfdswmr.sh.in
@@ -597,7 +597,7 @@ if [ ${do_zoo:-no} = yes ]; then
rm -f ./shared_tick_num
echo launch vfd_swmr_zoo_writer
STDIN_PATH="./fifo" catch_out_err_and_rc vfd_swmr_zoo_writer \
- ../vfd_swmr_zoo_writer -q &
+ ../vfd_swmr_zoo_writer -m 1000 -q &
pid_writer=$!
STDOUT_PATH="./fifo" catch_out_err_and_rc vfd_swmr_zoo_reader \
diff --git a/test/vfd_swmr_zoo_writer.c b/test/vfd_swmr_zoo_writer.c
index a0af7d8..76165d3 100644
--- a/test/vfd_swmr_zoo_writer.c
+++ b/test/vfd_swmr_zoo_writer.c
@@ -33,6 +33,10 @@
#include "genall5.h"
#include "vfd_swmr_common.h"
+#ifndef _arraycount
+#define _arraycount(_a) (sizeof(_a)/sizeof(_a[0]))
+#endif
+
typedef struct _shared_ticks {
uint64_t reader_tick;
} shared_ticks_t;
@@ -79,14 +83,15 @@ zoo_create_hook(hid_t fid)
static void
usage(const char *progname)
{
- fprintf(stderr, "usage: %s [-C] [-S] [-W] [-a] [-e] [-n] [-q] [-v]\n",
+ fprintf(stderr, "usage: %s [-C] [-S] [-W] [-a] [-e] [-m] [-q] [-v]\n",
progname);
fprintf(stderr, "\n -C: skip compact dataset tests\n");
fprintf(stderr, " -S: do not use VFD SWMR\n");
fprintf(stderr, " -W: do not wait for SIGINT or SIGUSR1\n");
fprintf(stderr, " -a: run all tests, including variable-length data\n");
fprintf(stderr, " -e: print error stacks\n");
- fprintf(stderr, " -n: number of test steps to perform\n");
+ fprintf(stderr, " -m ms: maximum `ms` milliseconds pause between\n");
+ fprintf(stderr, " each create/delete step\n");
fprintf(stderr, " -q: be quiet: few/no progress messages\n");
fprintf(stderr, " -v: be verbose: most progress messages\n");
exit(EXIT_FAILURE);
@@ -215,9 +220,16 @@ main(int argc, char **argv)
zoo_config_t config = {
.proc_num = 0
, .skip_compact = false
- , .skip_varlen = true};
+ , .skip_varlen = true
+ , .max_pause_msecs = 0
+ };
bool wait_for_signal;
int ch;
+ char vector[8];
+ unsigned seed = 1;
+ unsigned long tmpl;
+ char *end, *ostate;
+ const char *seedvar = "H5_ZOO_STEP_SEED";
bool use_vfd_swmr = true;
bool print_estack = false;
const char *progname = basename(argv[0]);
@@ -233,7 +245,10 @@ main(int argc, char **argv)
"unknown personality, expected vfd_swmr_zoo_{reader,writer}");
}
- while ((ch = getopt(argc, argv, "CSWaen:qv")) != -1) {
+ if (writer)
+ config.max_pause_msecs = 50;
+
+ while ((ch = getopt(argc, argv, "CSWaem:qv")) != -1) {
switch(ch) {
case 'C':
config.skip_compact = true;
@@ -250,6 +265,17 @@ main(int argc, char **argv)
case 'e':
print_estack = true;
break;
+ case 'm':
+ errno = 0;
+ tmpl = strtoul(optarg, &end, 0);
+ if (end == optarg || *end != '\0')
+ errx(EXIT_FAILURE, "couldn't parse `-m` argument `%s`", optarg);
+ else if (errno != 0)
+ err(EXIT_FAILURE, "couldn't parse `-m` argument `%s`", optarg);
+ else if (tmpl > UINT_MAX)
+ errx(EXIT_FAILURE, "`-m` argument `%lu` too large", tmpl);
+ config.max_pause_msecs = (unsigned)tmpl;
+ break;
case 'q':
verbosity = 1;
break;
@@ -309,6 +335,22 @@ main(int argc, char **argv)
dbgf(2, "Writing zoo...\n");
+ /* get seed from environment or else from time(3) */
+ switch (fetch_env_ulong(seedvar, UINT_MAX, &tmpl)) {
+ case -1:
+ errx(EXIT_FAILURE, "%s: fetch_env_ulong", __func__);
+ case 0:
+ seed = (unsigned int)time(NULL);
+ break;
+ default:
+ seed = (unsigned int)tmpl;
+ break;
+ }
+
+ dbgf(1, "To reproduce, set seed (%s) to %u.\n", seedvar, seed);
+
+ ostate = initstate(seed, vector, _arraycount(vector));
+
if (!create_zoo(fid, ".", config))
errx(EXIT_FAILURE, "create_zoo didn't pass self-check");
@@ -326,6 +368,7 @@ main(int argc, char **argv)
if (!delete_zoo(fid, ".", config))
errx(EXIT_FAILURE, "delete_zoo failed");
+ (void)setstate(ostate);
} else {
dbgf(2, "Reading zoo...\n");