summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/test/csuite/random_abort/main.c
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2019-08-21 05:23:37 +0000
committerevergreen <evergreen@mongodb.com>2019-08-21 05:23:37 +0000
commitac41c65f6355f83aac70136324c98561ac79daa1 (patch)
treea7c3f7ef090b59c6a06838a02c96bd1d49e1c729 /src/third_party/wiredtiger/test/csuite/random_abort/main.c
parentf54709196711c63a429b71f47c584661286d675f (diff)
downloadmongo-ac41c65f6355f83aac70136324c98561ac79daa1.tar.gz
Import wiredtiger: 7dfd9391862bc9a6d84868c4dc51689c45a3aacf from branch mongodb-4.4
ref: c809757d8b..7dfd939186 for: 4.3.1 WT-4658 Apply Clang Format WT-4810 Adding WT_ERR_ASSERT and WT_RET_ASSERT macros WT-5046 Prepared transactions aren't properly cleared from global table with WT_CONN_LOG_DEBUG_MODE enabled
Diffstat (limited to 'src/third_party/wiredtiger/test/csuite/random_abort/main.c')
-rw-r--r--src/third_party/wiredtiger/test/csuite/random_abort/main.c703
1 files changed, 336 insertions, 367 deletions
diff --git a/src/third_party/wiredtiger/test/csuite/random_abort/main.c b/src/third_party/wiredtiger/test/csuite/random_abort/main.c
index 98402f0d233..8bc365d75c1 100644
--- a/src/third_party/wiredtiger/test/csuite/random_abort/main.c
+++ b/src/third_party/wiredtiger/test/csuite/random_abort/main.c
@@ -31,182 +31,171 @@
#include <sys/wait.h>
#include <signal.h>
-static char home[1024]; /* Program working dir */
+static char home[1024]; /* Program working dir */
/*
* These two names for the URI and file system must be maintained in tandem.
*/
-static const char * const uri = "table:main";
+static const char *const uri = "table:main";
static bool compat;
static bool inmem;
-#define MAX_TH 12
-#define MIN_TH 5
-#define MAX_TIME 40
-#define MIN_TIME 10
-#define RECORDS_FILE "records-%" PRIu32
+#define MAX_TH 12
+#define MIN_TH 5
+#define MAX_TIME 40
+#define MIN_TIME 10
+#define RECORDS_FILE "records-%" PRIu32
-#define ENV_CONFIG_COMPAT ",compatibility=(release=\"2.9\")"
-#define ENV_CONFIG_DEF \
- "create,log=(file_max=10M,enabled)"
-#define ENV_CONFIG_TXNSYNC \
- "create,log=(file_max=10M,enabled)," \
+#define ENV_CONFIG_COMPAT ",compatibility=(release=\"2.9\")"
+#define ENV_CONFIG_DEF "create,log=(file_max=10M,enabled)"
+#define ENV_CONFIG_TXNSYNC \
+ "create,log=(file_max=10M,enabled)," \
"transaction_sync=(enabled,method=none)"
-#define ENV_CONFIG_REC "log=(recover=on)"
-#define MAX_VAL 4096
+#define ENV_CONFIG_REC "log=(recover=on)"
+#define MAX_VAL 4096
-static void handler(int)
- WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
-static void usage(void)
- WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
+static void handler(int) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
+static void usage(void) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
static void
usage(void)
{
- fprintf(stderr, "usage: %s [-h dir] [-T threads]\n", progname);
- exit(EXIT_FAILURE);
+ fprintf(stderr, "usage: %s [-h dir] [-T threads]\n", progname);
+ exit(EXIT_FAILURE);
}
typedef struct {
- WT_CONNECTION *conn;
- uint64_t start;
- uint32_t id;
+ WT_CONNECTION *conn;
+ uint64_t start;
+ uint32_t id;
} WT_THREAD_DATA;
static WT_THREAD_RET
thread_run(void *arg)
{
- FILE *fp;
- WT_CURSOR *cursor;
- WT_ITEM data;
- WT_RAND_STATE rnd;
- WT_SESSION *session;
- WT_THREAD_DATA *td;
- size_t lsize;
- uint64_t i;
- char buf[MAX_VAL], kname[64], lgbuf[8];
- char large[128*1024];
+ FILE *fp;
+ WT_CURSOR *cursor;
+ WT_ITEM data;
+ WT_RAND_STATE rnd;
+ WT_SESSION *session;
+ WT_THREAD_DATA *td;
+ size_t lsize;
+ uint64_t i;
+ char buf[MAX_VAL], kname[64], lgbuf[8];
+ char large[128 * 1024];
- __wt_random_init(&rnd);
- memset(buf, 0, sizeof(buf));
- memset(kname, 0, sizeof(kname));
- lsize = sizeof(large);
- memset(large, 0, lsize);
+ __wt_random_init(&rnd);
+ memset(buf, 0, sizeof(buf));
+ memset(kname, 0, sizeof(kname));
+ lsize = sizeof(large);
+ memset(large, 0, lsize);
- td = (WT_THREAD_DATA *)arg;
- /*
- * The value is the name of the record file with our id appended.
- */
- testutil_check(__wt_snprintf(buf, sizeof(buf), RECORDS_FILE, td->id));
- /*
- * Set up a large value putting our id in it. Write it in there a
- * bunch of times, but the rest of the buffer can just be zero.
- */
- testutil_check(__wt_snprintf(
- lgbuf, sizeof(lgbuf), "th-%" PRIu32, td->id));
- for (i = 0; i < 128; i += strlen(lgbuf))
- testutil_check(__wt_snprintf(
- &large[i], lsize - i, "%s", lgbuf));
- /*
- * Keep a separate file with the records we wrote for checking.
- */
- (void)unlink(buf);
- if ((fp = fopen(buf, "w")) == NULL)
- testutil_die(errno, "fopen");
- /*
- * Set to line buffering. But that is advisory only. We've seen
- * cases where the result files end up with partial lines.
- */
- __wt_stream_set_line_buffer(fp);
- testutil_check(td->conn->open_session(td->conn, NULL, NULL, &session));
- testutil_check(session->open_cursor(session, uri, NULL, NULL, &cursor));
- data.data = buf;
- data.size = sizeof(buf);
- /*
- * Write our portion of the key space until we're killed.
- */
- printf("Thread %" PRIu32 " starts at %" PRIu64 "\n",
- td->id, td->start);
- for (i = td->start; ; ++i) {
- testutil_check(__wt_snprintf(
- kname, sizeof(kname), "%" PRIu64, i));
- cursor->set_key(cursor, kname);
- /*
- * Every 30th record write a very large record that exceeds the
- * log buffer size. This forces us to use the unbuffered path.
- */
- if (i % 30 == 0) {
- data.size = 128 * 1024;
- data.data = large;
- } else {
- data.size = __wt_random(&rnd) % MAX_VAL;
- data.data = buf;
- }
- cursor->set_value(cursor, &data);
- testutil_check(cursor->insert(cursor));
- /*
- * Save the key separately for checking later.
- */
- if (fprintf(fp, "%" PRIu64 "\n", i) == -1)
- testutil_die(errno, "fprintf");
- }
- /* NOTREACHED */
+ td = (WT_THREAD_DATA *)arg;
+ /*
+ * The value is the name of the record file with our id appended.
+ */
+ testutil_check(__wt_snprintf(buf, sizeof(buf), RECORDS_FILE, td->id));
+ /*
+ * Set up a large value putting our id in it. Write it in there a bunch of times, but the rest
+ * of the buffer can just be zero.
+ */
+ testutil_check(__wt_snprintf(lgbuf, sizeof(lgbuf), "th-%" PRIu32, td->id));
+ for (i = 0; i < 128; i += strlen(lgbuf))
+ testutil_check(__wt_snprintf(&large[i], lsize - i, "%s", lgbuf));
+ /*
+ * Keep a separate file with the records we wrote for checking.
+ */
+ (void)unlink(buf);
+ if ((fp = fopen(buf, "w")) == NULL)
+ testutil_die(errno, "fopen");
+ /*
+ * Set to line buffering. But that is advisory only. We've seen cases where the result files end
+ * up with partial lines.
+ */
+ __wt_stream_set_line_buffer(fp);
+ testutil_check(td->conn->open_session(td->conn, NULL, NULL, &session));
+ testutil_check(session->open_cursor(session, uri, NULL, NULL, &cursor));
+ data.data = buf;
+ data.size = sizeof(buf);
+ /*
+ * Write our portion of the key space until we're killed.
+ */
+ printf("Thread %" PRIu32 " starts at %" PRIu64 "\n", td->id, td->start);
+ for (i = td->start;; ++i) {
+ testutil_check(__wt_snprintf(kname, sizeof(kname), "%" PRIu64, i));
+ cursor->set_key(cursor, kname);
+ /*
+ * Every 30th record write a very large record that exceeds the log buffer size. This forces
+ * us to use the unbuffered path.
+ */
+ if (i % 30 == 0) {
+ data.size = 128 * 1024;
+ data.data = large;
+ } else {
+ data.size = __wt_random(&rnd) % MAX_VAL;
+ data.data = buf;
+ }
+ cursor->set_value(cursor, &data);
+ testutil_check(cursor->insert(cursor));
+ /*
+ * Save the key separately for checking later.
+ */
+ if (fprintf(fp, "%" PRIu64 "\n", i) == -1)
+ testutil_die(errno, "fprintf");
+ }
+ /* NOTREACHED */
}
/*
- * Child process creates the database and table, and then creates worker
- * threads to add data until it is killed by the parent.
+ * Child process creates the database and table, and then creates worker threads to add data until
+ * it is killed by the parent.
*/
-static void fill_db(uint32_t)
- WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
+static void fill_db(uint32_t) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
static void
fill_db(uint32_t nth)
{
- WT_CONNECTION *conn;
- WT_SESSION *session;
- WT_THREAD_DATA *td;
- wt_thread_t *thr;
- uint32_t i;
- char envconf[512];
+ WT_CONNECTION *conn;
+ WT_SESSION *session;
+ WT_THREAD_DATA *td;
+ wt_thread_t *thr;
+ uint32_t i;
+ char envconf[512];
- thr = dcalloc(nth, sizeof(*thr));
- td = dcalloc(nth, sizeof(WT_THREAD_DATA));
- if (chdir(home) != 0)
- testutil_die(errno, "Child chdir: %s", home);
- if (inmem)
- strcpy(envconf, ENV_CONFIG_DEF);
- else
- strcpy(envconf, ENV_CONFIG_TXNSYNC);
- if (compat)
- strcat(envconf, ENV_CONFIG_COMPAT);
+ thr = dcalloc(nth, sizeof(*thr));
+ td = dcalloc(nth, sizeof(WT_THREAD_DATA));
+ if (chdir(home) != 0)
+ testutil_die(errno, "Child chdir: %s", home);
+ if (inmem)
+ strcpy(envconf, ENV_CONFIG_DEF);
+ else
+ strcpy(envconf, ENV_CONFIG_TXNSYNC);
+ if (compat)
+ strcat(envconf, ENV_CONFIG_COMPAT);
- testutil_check(wiredtiger_open(NULL, NULL, envconf, &conn));
- testutil_check(conn->open_session(conn, NULL, NULL, &session));
- testutil_check(session->create(
- session, uri, "key_format=S,value_format=u"));
- testutil_check(session->close(session, NULL));
+ testutil_check(wiredtiger_open(NULL, NULL, envconf, &conn));
+ testutil_check(conn->open_session(conn, NULL, NULL, &session));
+ testutil_check(session->create(session, uri, "key_format=S,value_format=u"));
+ testutil_check(session->close(session, NULL));
- printf("Create %" PRIu32 " writer threads\n", nth);
- for (i = 0; i < nth; ++i) {
- td[i].conn = conn;
- td[i].start = WT_BILLION * (uint64_t)i;
- td[i].id = i;
- testutil_check(__wt_thread_create(
- NULL, &thr[i], thread_run, &td[i]));
- }
- printf("Spawned %" PRIu32 " writer threads\n", nth);
- fflush(stdout);
- /*
- * The threads never exit, so the child will just wait here until
- * it is killed.
- */
- for (i = 0; i < nth; ++i)
- testutil_check(__wt_thread_join(NULL, &thr[i]));
- /*
- * NOTREACHED
- */
- free(thr);
- free(td);
- exit(EXIT_SUCCESS);
+ printf("Create %" PRIu32 " writer threads\n", nth);
+ for (i = 0; i < nth; ++i) {
+ td[i].conn = conn;
+ td[i].start = WT_BILLION * (uint64_t)i;
+ td[i].id = i;
+ testutil_check(__wt_thread_create(NULL, &thr[i], thread_run, &td[i]));
+ }
+ printf("Spawned %" PRIu32 " writer threads\n", nth);
+ fflush(stdout);
+ /*
+ * The threads never exit, so the child will just wait here until it is killed.
+ */
+ for (i = 0; i < nth; ++i)
+ testutil_check(__wt_thread_join(NULL, &thr[i]));
+ /*
+ * NOTREACHED
+ */
+ free(thr);
+ free(td);
+ exit(EXIT_SUCCESS);
}
extern int __wt_optind;
@@ -215,246 +204,226 @@ extern char *__wt_optarg;
static void
handler(int sig)
{
- pid_t pid;
+ pid_t pid;
- WT_UNUSED(sig);
- pid = wait(NULL);
- /*
- * The core file will indicate why the child exited. Choose EINVAL here.
- */
- testutil_die(EINVAL,
- "Child process %" PRIu64 " abnormally exited", (uint64_t)pid);
+ WT_UNUSED(sig);
+ pid = wait(NULL);
+ /*
+ * The core file will indicate why the child exited. Choose EINVAL here.
+ */
+ testutil_die(EINVAL, "Child process %" PRIu64 " abnormally exited", (uint64_t)pid);
}
int
main(int argc, char *argv[])
{
- struct sigaction sa;
- struct stat sb;
- FILE *fp;
- WT_CONNECTION *conn;
- WT_CURSOR *cursor;
- WT_RAND_STATE rnd;
- WT_SESSION *session;
- pid_t pid;
- uint64_t absent, count, key, last_key, middle;
- uint32_t i, nth, timeout;
- int ch, status, ret;
- char buf[1024], fname[64], kname[64];
- const char *working_dir;
- bool fatal, rand_th, rand_time, verify_only;
+ struct sigaction sa;
+ struct stat sb;
+ FILE *fp;
+ WT_CONNECTION *conn;
+ WT_CURSOR *cursor;
+ WT_RAND_STATE rnd;
+ WT_SESSION *session;
+ pid_t pid;
+ uint64_t absent, count, key, last_key, middle;
+ uint32_t i, nth, timeout;
+ int ch, status, ret;
+ char buf[1024], fname[64], kname[64];
+ const char *working_dir;
+ bool fatal, rand_th, rand_time, verify_only;
- (void)testutil_set_progname(argv);
+ (void)testutil_set_progname(argv);
- compat = inmem = false;
- nth = MIN_TH;
- rand_th = rand_time = true;
- timeout = MIN_TIME;
- verify_only = false;
- working_dir = "WT_TEST.random-abort";
+ compat = inmem = false;
+ nth = MIN_TH;
+ rand_th = rand_time = true;
+ timeout = MIN_TIME;
+ verify_only = false;
+ working_dir = "WT_TEST.random-abort";
- while ((ch = __wt_getopt(progname, argc, argv, "Ch:mT:t:v")) != EOF)
- switch (ch) {
- case 'C':
- compat = true;
- break;
- case 'h':
- working_dir = __wt_optarg;
- break;
- case 'm':
- inmem = true;
- break;
- case 'T':
- rand_th = false;
- nth = (uint32_t)atoi(__wt_optarg);
- break;
- case 't':
- rand_time = false;
- timeout = (uint32_t)atoi(__wt_optarg);
- break;
- case 'v':
- verify_only = true;
- break;
- default:
- usage();
- }
- argc -= __wt_optind;
- if (argc != 0)
- usage();
+ while ((ch = __wt_getopt(progname, argc, argv, "Ch:mT:t:v")) != EOF)
+ switch (ch) {
+ case 'C':
+ compat = true;
+ break;
+ case 'h':
+ working_dir = __wt_optarg;
+ break;
+ case 'm':
+ inmem = true;
+ break;
+ case 'T':
+ rand_th = false;
+ nth = (uint32_t)atoi(__wt_optarg);
+ break;
+ case 't':
+ rand_time = false;
+ timeout = (uint32_t)atoi(__wt_optarg);
+ break;
+ case 'v':
+ verify_only = true;
+ break;
+ default:
+ usage();
+ }
+ argc -= __wt_optind;
+ if (argc != 0)
+ usage();
- testutil_work_dir_from_path(home, sizeof(home), working_dir);
- /*
- * If the user wants to verify they need to tell us how many threads
- * there were so we can find the old record files.
- */
- if (verify_only && rand_th) {
- fprintf(stderr,
- "Verify option requires specifying number of threads\n");
- exit (EXIT_FAILURE);
- }
- if (!verify_only) {
- testutil_make_work_dir(home);
+ testutil_work_dir_from_path(home, sizeof(home), working_dir);
+ /*
+ * If the user wants to verify they need to tell us how many threads there were so we can find
+ * the old record files.
+ */
+ if (verify_only && rand_th) {
+ fprintf(stderr, "Verify option requires specifying number of threads\n");
+ exit(EXIT_FAILURE);
+ }
+ if (!verify_only) {
+ testutil_make_work_dir(home);
- __wt_random_init_seed(NULL, &rnd);
- if (rand_time) {
- timeout = __wt_random(&rnd) % MAX_TIME;
- if (timeout < MIN_TIME)
- timeout = MIN_TIME;
- }
- if (rand_th) {
- nth = __wt_random(&rnd) % MAX_TH;
- if (nth < MIN_TH)
- nth = MIN_TH;
- }
- printf("Parent: Compatibility %s in-mem log %s\n",
- compat ? "true" : "false", inmem ? "true" : "false");
- printf("Parent: Create %" PRIu32
- " threads; sleep %" PRIu32 " seconds\n", nth, timeout);
- printf("CONFIG: %s%s%s -h %s -T %" PRIu32 " -t %" PRIu32 "\n",
- progname,
- compat ? " -C" : "",
- inmem ? " -m" : "",
- working_dir, nth, timeout);
- /*
- * Fork a child to insert as many items. We will then randomly
- * kill the child, run recovery and make sure all items we wrote
- * exist after recovery runs.
- */
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = handler;
- testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
- if ((pid = fork()) < 0)
- testutil_die(errno, "fork");
+ __wt_random_init_seed(NULL, &rnd);
+ if (rand_time) {
+ timeout = __wt_random(&rnd) % MAX_TIME;
+ if (timeout < MIN_TIME)
+ timeout = MIN_TIME;
+ }
+ if (rand_th) {
+ nth = __wt_random(&rnd) % MAX_TH;
+ if (nth < MIN_TH)
+ nth = MIN_TH;
+ }
+ printf("Parent: Compatibility %s in-mem log %s\n", compat ? "true" : "false",
+ inmem ? "true" : "false");
+ printf("Parent: Create %" PRIu32 " threads; sleep %" PRIu32 " seconds\n", nth, timeout);
+ printf("CONFIG: %s%s%s -h %s -T %" PRIu32 " -t %" PRIu32 "\n", progname,
+ compat ? " -C" : "", inmem ? " -m" : "", working_dir, nth, timeout);
+ /*
+ * Fork a child to insert as many items. We will then randomly kill the child, run recovery
+ * and make sure all items we wrote exist after recovery runs.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = handler;
+ testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
+ if ((pid = fork()) < 0)
+ testutil_die(errno, "fork");
- if (pid == 0) { /* child */
- fill_db(nth);
- return (EXIT_SUCCESS);
- }
+ if (pid == 0) { /* child */
+ fill_db(nth);
+ return (EXIT_SUCCESS);
+ }
- /* parent */
- /*
- * Sleep for the configured amount of time before killing
- * the child. Start the timeout from the time we notice that
- * the child workers have created their record files. That
- * allows the test to run correctly on really slow machines.
- */
- i = 0;
- while (i < nth) {
- /*
- * Wait for each record file to exist.
- */
- testutil_check(__wt_snprintf(
- fname, sizeof(fname), RECORDS_FILE, i));
- testutil_check(__wt_snprintf(
- buf, sizeof(buf),"%s/%s", home, fname));
- while (stat(buf, &sb) != 0)
- testutil_sleep_wait(1, pid);
- ++i;
- }
- sleep(timeout);
- sa.sa_handler = SIG_DFL;
- testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
+ /* parent */
+ /*
+ * Sleep for the configured amount of time before killing the child. Start the timeout from
+ * the time we notice that the child workers have created their record files. That allows
+ * the test to run correctly on really slow machines.
+ */
+ i = 0;
+ while (i < nth) {
+ /*
+ * Wait for each record file to exist.
+ */
+ testutil_check(__wt_snprintf(fname, sizeof(fname), RECORDS_FILE, i));
+ testutil_check(__wt_snprintf(buf, sizeof(buf), "%s/%s", home, fname));
+ while (stat(buf, &sb) != 0)
+ testutil_sleep_wait(1, pid);
+ ++i;
+ }
+ sleep(timeout);
+ sa.sa_handler = SIG_DFL;
+ testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
- /*
- * !!! It should be plenty long enough to make sure more than
- * one log file exists. If wanted, that check would be added
- * here.
- */
- printf("Kill child\n");
- if (kill(pid, SIGKILL) != 0)
- testutil_die(errno, "kill");
- if (waitpid(pid, &status, 0) == -1)
- testutil_die(errno, "waitpid");
- }
- /*
- * !!! If we wanted to take a copy of the directory before recovery,
- * this is the place to do it.
- */
- if (chdir(home) != 0)
- testutil_die(errno, "parent chdir: %s", home);
+ /*
+ * !!! It should be plenty long enough to make sure more than
+ * one log file exists. If wanted, that check would be added
+ * here.
+ */
+ printf("Kill child\n");
+ if (kill(pid, SIGKILL) != 0)
+ testutil_die(errno, "kill");
+ if (waitpid(pid, &status, 0) == -1)
+ testutil_die(errno, "waitpid");
+ }
+ /*
+ * !!! If we wanted to take a copy of the directory before recovery,
+ * this is the place to do it.
+ */
+ if (chdir(home) != 0)
+ testutil_die(errno, "parent chdir: %s", home);
- testutil_check(__wt_snprintf(buf, sizeof(buf),
- "rm -rf ../%s.SAVE; mkdir ../%s.SAVE; "
- "cp -p WiredTigerLog.* ../%s.SAVE;",
- home, home, home));
- if ((status = system(buf)) < 0)
- testutil_die(status, "system: %s", buf);
+ testutil_check(__wt_snprintf(buf, sizeof(buf),
+ "rm -rf ../%s.SAVE; mkdir ../%s.SAVE; "
+ "cp -p WiredTigerLog.* ../%s.SAVE;",
+ home, home, home));
+ if ((status = system(buf)) < 0)
+ testutil_die(status, "system: %s", buf);
- printf("Open database, run recovery and verify content\n");
- testutil_check(wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn));
- testutil_check(conn->open_session(conn, NULL, NULL, &session));
- testutil_check(session->open_cursor(session, uri, NULL, NULL, &cursor));
+ printf("Open database, run recovery and verify content\n");
+ testutil_check(wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn));
+ testutil_check(conn->open_session(conn, NULL, NULL, &session));
+ testutil_check(session->open_cursor(session, uri, NULL, NULL, &cursor));
- absent = count = 0;
- fatal = false;
- for (i = 0; i < nth; ++i) {
- middle = 0;
- testutil_check(__wt_snprintf(
- fname, sizeof(fname), RECORDS_FILE, i));
- if ((fp = fopen(fname, "r")) == NULL)
- testutil_die(errno, "fopen: %s", fname);
+ absent = count = 0;
+ fatal = false;
+ for (i = 0; i < nth; ++i) {
+ middle = 0;
+ testutil_check(__wt_snprintf(fname, sizeof(fname), RECORDS_FILE, i));
+ if ((fp = fopen(fname, "r")) == NULL)
+ testutil_die(errno, "fopen: %s", fname);
- /*
- * For every key in the saved file, verify that the key exists
- * in the table after recovery. If we're doing in-memory
- * log buffering we never expect a record missing in the middle,
- * but records may be missing at the end. If we did
- * write-no-sync, we expect every key to have been recovered.
- */
- for (last_key = UINT64_MAX;; ++count, last_key = key) {
- ret = fscanf(fp, "%" SCNu64 "\n", &key);
- /*
- * Consider anything other than clear success in
- * getting the key to be EOF. We've seen file system
- * issues where the file ends with zeroes on a 4K
- * boundary and does not return EOF but a ret of zero.
- */
- if (ret != 1)
- break;
- /*
- * If we're unlucky, the last line may be a partially
- * written key at the end that can result in a false
- * negative error for a missing record. Detect it.
- */
- if (last_key != UINT64_MAX && key != last_key + 1) {
- printf("%s: Ignore partial record %" PRIu64
- " last valid key %" PRIu64 "\n",
- fname, key, last_key);
- break;
- }
- testutil_check(__wt_snprintf(
- kname, sizeof(kname), "%" PRIu64, key));
- cursor->set_key(cursor, kname);
- if ((ret = cursor->search(cursor)) != 0) {
- if (ret != WT_NOTFOUND)
- testutil_die(ret, "search");
- if (!inmem)
- printf("%s: no record with key %"
- PRIu64 "\n", fname, key);
- absent++;
- middle = key;
- } else if (middle != 0) {
- /*
- * We should never find an existing key after
- * we have detected one missing.
- */
- printf("%s: after absent record at %" PRIu64
- " key %" PRIu64 " exists\n",
- fname, middle, key);
- fatal = true;
- }
- }
- if (fclose(fp) != 0)
- testutil_die(errno, "fclose");
- }
- testutil_check(conn->close(conn, NULL));
- if (fatal)
- return (EXIT_FAILURE);
- if (!inmem && absent) {
- printf("%" PRIu64 " record(s) absent from %" PRIu64 "\n",
- absent, count);
- return (EXIT_FAILURE);
- }
- printf("%" PRIu64 " records verified\n", count);
- return (EXIT_SUCCESS);
+ /*
+ * For every key in the saved file, verify that the key exists in the table after recovery.
+ * If we're doing in-memory log buffering we never expect a record missing in the middle,
+ * but records may be missing at the end. If we did write-no-sync, we expect every key to
+ * have been recovered.
+ */
+ for (last_key = UINT64_MAX;; ++count, last_key = key) {
+ ret = fscanf(fp, "%" SCNu64 "\n", &key);
+ /*
+ * Consider anything other than clear success in getting the key to be EOF. We've seen
+ * file system issues where the file ends with zeroes on a 4K boundary and does not
+ * return EOF but a ret of zero.
+ */
+ if (ret != 1)
+ break;
+ /*
+ * If we're unlucky, the last line may be a partially written key at the end that can
+ * result in a false negative error for a missing record. Detect it.
+ */
+ if (last_key != UINT64_MAX && key != last_key + 1) {
+ printf("%s: Ignore partial record %" PRIu64 " last valid key %" PRIu64 "\n", fname,
+ key, last_key);
+ break;
+ }
+ testutil_check(__wt_snprintf(kname, sizeof(kname), "%" PRIu64, key));
+ cursor->set_key(cursor, kname);
+ if ((ret = cursor->search(cursor)) != 0) {
+ if (ret != WT_NOTFOUND)
+ testutil_die(ret, "search");
+ if (!inmem)
+ printf("%s: no record with key %" PRIu64 "\n", fname, key);
+ absent++;
+ middle = key;
+ } else if (middle != 0) {
+ /*
+ * We should never find an existing key after we have detected one missing.
+ */
+ printf("%s: after absent record at %" PRIu64 " key %" PRIu64 " exists\n", fname,
+ middle, key);
+ fatal = true;
+ }
+ }
+ if (fclose(fp) != 0)
+ testutil_die(errno, "fclose");
+ }
+ testutil_check(conn->close(conn, NULL));
+ if (fatal)
+ return (EXIT_FAILURE);
+ if (!inmem && absent) {
+ printf("%" PRIu64 " record(s) absent from %" PRIu64 "\n", absent, count);
+ return (EXIT_FAILURE);
+ }
+ printf("%" PRIu64 " records verified\n", count);
+ return (EXIT_SUCCESS);
}