summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/test
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2017-11-03 15:14:01 +1100
committerLuke Chen <luke.chen@mongodb.com>2017-11-03 15:37:51 +1100
commit48acb7cfa8503440e1b0ab2771371f4790245015 (patch)
treea8b8efbd78f6aa3b04f53bc1b226ec1e0cf4a422 /src/third_party/wiredtiger/test
parent73b4a7c888d90b8e875104b1a0f20627d29e0124 (diff)
downloadmongo-48acb7cfa8503440e1b0ab2771371f4790245015.tar.gz
Import wiredtiger: 0a2f8f6ad756189263d050b29f69bc57b45b9816 from branch mongodb-3.6
ref: a31e9d415a..0a2f8f6ad7 for: 3.6.0-rc3 WT-3223 Output progress messages during long checkpoint operations WT-3630 Intermittent failure loading libwiredtiger in Evergreen OSX job WT-3652 Skip lookaside reads for checkpoints without a timestamp WT-3666 Fix lost updates with lookaside eviction WT-3675 timestamp abort test failure WT-3677 test/format compaction doesn't handle timeout error return WT-3679 Python test suite: when 'wt' fails, display its output and error files WT-3680 metadata unroll should discard in-process checkpoints WT-3681 Don't truncate the last log file in recovery WT-3683 WT tests failing with cache full of clean pages WT-3699 support minimum cache sizes in format WT-3705 Full build Friday and lint WT-3707 timestamp_abort updating timestamp out of order and parent process not handling failure WT-3708 PRIu64 format incorrectly specified for size_t WT-3711 random_abort test needs signal handler change WT-3713 Make timestamp abort test output more concise WT-3714 Make timestamp_abort and random_abort ranges readable
Diffstat (limited to 'src/third_party/wiredtiger/test')
-rw-r--r--src/third_party/wiredtiger/test/csuite/random_abort/main.c32
-rw-r--r--src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c178
-rw-r--r--src/third_party/wiredtiger/test/format/compact.c7
-rw-r--r--src/third_party/wiredtiger/test/format/config.c42
-rw-r--r--src/third_party/wiredtiger/test/format/config.h18
-rw-r--r--src/third_party/wiredtiger/test/format/format.h1
-rw-r--r--src/third_party/wiredtiger/test/mciproject.yml16
-rw-r--r--src/third_party/wiredtiger/test/suite/suite_subprocess.py44
8 files changed, 245 insertions, 93 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 a171cfef13a..ad49f01dde5 100644
--- a/src/third_party/wiredtiger/test/csuite/random_abort/main.c
+++ b/src/third_party/wiredtiger/test/csuite/random_abort/main.c
@@ -56,6 +56,8 @@ static bool inmem;
#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
@@ -123,6 +125,8 @@ thread_run(void *arg)
/*
* 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));
@@ -185,7 +189,7 @@ fill_db(uint32_t nth)
printf("Create %" PRIu32 " writer threads\n", nth);
for (i = 0; i < nth; ++i) {
td[i].conn = conn;
- td[i].start = (UINT64_MAX / nth) * i;
+ td[i].start = WT_BILLION * (uint64_t)i;
td[i].id = i;
testutil_check(__wt_thread_create(
NULL, &thr[i], thread_run, &td[i]));
@@ -209,9 +213,24 @@ fill_db(uint32_t nth)
extern int __wt_optind;
extern char *__wt_optarg;
+static void
+handler(int sig)
+{
+ 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);
+}
+
int
main(int argc, char *argv[])
{
+ struct sigaction sa;
struct stat sb;
FILE *fp;
WT_CONNECTION *conn;
@@ -298,6 +317,9 @@ main(int argc, char *argv[])
* 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");
@@ -311,15 +333,15 @@ main(int argc, char *argv[])
* Sleep for the configured amount of time before killing
* the child. Start the timeout from the time we notice that
* the table has been created. That allows the test to run
- * correctly on really slow machines. Verify the process ID
- * still exists in case the child aborts for some reason we
- * don't stay in this loop forever.
+ * correctly on really slow machines.
*/
testutil_check(__wt_snprintf(
buf, sizeof(buf), "%s/%s", home, fs_main));
- while (stat(buf, &sb) != 0 && kill(pid, 0) == 0)
+ while (stat(buf, &sb) != 0)
sleep(1);
sleep(timeout);
+ sa.sa_handler = SIG_DFL;
+ testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
/*
* !!! It should be plenty long enough to make sure more than
diff --git a/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c b/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c
index f6dadd95495..ca5fa10c2db 100644
--- a/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c
+++ b/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c
@@ -56,6 +56,7 @@ static char home[1024]; /* Program working dir */
* Each worker thread creates its own records file that records the data it
* inserted and it records the timestamp that was used for that insertion.
*/
+#define INVALID_KEY UINT64_MAX
#define MAX_CKPT_INVL 5 /* Maximum interval between checkpoints */
#define MAX_TH 12
#define MAX_TIME 40
@@ -84,6 +85,22 @@ static uint64_t th_ts[MAX_TH];
"transaction_sync=(enabled,method=none)"
#define ENV_CONFIG_REC "log=(archive=false,recover=on)"
+typedef struct {
+ uint64_t absent_key; /* Last absent key */
+ uint64_t exist_key; /* First existing key after miss */
+ uint64_t first_key; /* First key in range */
+ uint64_t first_miss; /* First missing key */
+ uint64_t last_key; /* Last key in range */
+} REPORT;
+
+typedef struct {
+ WT_CONNECTION *conn;
+ uint64_t start;
+ uint32_t info;
+} THREAD_DATA;
+
+static void handler(int)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
static void usage(void)
WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn));
static void
@@ -94,12 +111,6 @@ usage(void)
exit(EXIT_FAILURE);
}
-typedef struct {
- WT_CONNECTION *conn;
- uint64_t start;
- uint32_t info;
-} WT_THREAD_DATA;
-
/*
* thread_ts_run --
* Runner function for a timestamp thread.
@@ -109,11 +120,11 @@ thread_ts_run(void *arg)
{
WT_CURSOR *cur_stable;
WT_SESSION *session;
- WT_THREAD_DATA *td;
+ THREAD_DATA *td;
uint64_t i, last_ts, oldest_ts;
char tscfg[64];
- td = (WT_THREAD_DATA *)arg;
+ td = (THREAD_DATA *)arg;
last_ts = 0;
testutil_check(td->conn->open_session(td->conn, NULL, NULL, &session));
@@ -177,7 +188,7 @@ thread_ckpt_run(void *arg)
FILE *fp;
WT_RAND_STATE rnd;
WT_SESSION *session;
- WT_THREAD_DATA *td;
+ THREAD_DATA *td;
uint64_t ts;
uint32_t sleep_time;
int i;
@@ -185,7 +196,7 @@ thread_ckpt_run(void *arg)
__wt_random_init(&rnd);
- td = (WT_THREAD_DATA *)arg;
+ td = (THREAD_DATA *)arg;
/*
* Keep a separate file with the records we wrote for checking.
*/
@@ -233,7 +244,7 @@ thread_run(void *arg)
WT_ITEM data;
WT_RAND_STATE rnd;
WT_SESSION *session;
- WT_THREAD_DATA *td;
+ THREAD_DATA *td;
uint64_t i, stable_ts;
char cbuf[MAX_VAL], lbuf[MAX_VAL], obuf[MAX_VAL];
char kname[64], tscfg[64];
@@ -244,7 +255,7 @@ thread_run(void *arg)
memset(obuf, 0, sizeof(obuf));
memset(kname, 0, sizeof(kname));
- td = (WT_THREAD_DATA *)arg;
+ td = (THREAD_DATA *)arg;
/*
* Set up the separate file for checking.
*/
@@ -310,7 +321,13 @@ thread_run(void *arg)
"commit_timestamp=%" PRIx64, stable_ts));
testutil_check(
session->commit_transaction(session, tscfg));
- th_ts[td->info] = stable_ts;
+ /*
+ * Update the thread's last-committed timestamp.
+ * Don't let the compiler re-order this statement,
+ * if we were to race with the timestamp thread, it
+ * might see our thread update before the commit.
+ */
+ WT_PUBLISH(th_ts[td->info], stable_ts);
} else
testutil_check(
session->commit_transaction(session, NULL));
@@ -343,13 +360,13 @@ run_workload(uint32_t nth)
{
WT_CONNECTION *conn;
WT_SESSION *session;
- WT_THREAD_DATA *td;
+ THREAD_DATA *td;
wt_thread_t *thr;
uint32_t ckpt_id, i, ts_id;
char envconf[512];
thr = dcalloc(nth+2, sizeof(*thr));
- td = dcalloc(nth+2, sizeof(WT_THREAD_DATA));
+ td = dcalloc(nth+2, sizeof(THREAD_DATA));
if (chdir(home) != 0)
testutil_die(errno, "Child chdir: %s", home);
if (inmem)
@@ -398,7 +415,7 @@ run_workload(uint32_t nth)
printf("Create %" PRIu32 " writer threads\n", nth);
for (i = 0; i < nth; ++i) {
td[i].conn = conn;
- td[i].start = (UINT64_MAX / nth) * i;
+ td[i].start = WT_BILLION * (uint64_t)i;
td[i].info = i;
testutil_check(__wt_thread_create(
NULL, &thr[i], thread_run, &td[i]));
@@ -434,18 +451,66 @@ timestamp_build(void)
extern int __wt_optind;
extern char *__wt_optarg;
+/*
+ * Initialize a report structure. Since zero is a valid key we
+ * cannot just clear it.
+ */
+static void
+initialize_rep(REPORT *r)
+{
+ r->first_key = r->first_miss = INVALID_KEY;
+ r->absent_key = r->exist_key = r->last_key = INVALID_KEY;
+}
+
+/*
+ * Print out information if we detect missing records in the
+ * middle of the data of a report structure.
+ */
+static void
+print_missing(REPORT *r, const char *fname, const char *msg)
+{
+ if (r->exist_key != INVALID_KEY)
+ printf("%s: %s error %" PRIu64
+ " absent records %" PRIu64 "-%" PRIu64
+ ". Then keys %" PRIu64 "-%" PRIu64 " exist."
+ " Key range %" PRIu64 "-%" PRIu64 "\n",
+ fname, msg,
+ r->exist_key - r->first_miss - 1,
+ r->first_miss, r->exist_key - 1,
+ r->exist_key, r->last_key,
+ r->first_key, r->last_key);
+}
+
+/*
+ * Signal handler to catch if the child died unexpectedly.
+ */
+static void
+handler(int sig)
+{
+ 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);
+}
+
int
main(int argc, char *argv[])
{
+ struct sigaction sa;
struct stat sb;
FILE *fp;
+ REPORT c_rep[MAX_TH], l_rep[MAX_TH], o_rep[MAX_TH];
WT_CONNECTION *conn;
WT_CURSOR *cur_coll, *cur_local, *cur_oplog, *cur_stable;
WT_RAND_STATE rnd;
WT_SESSION *session;
pid_t pid;
uint64_t absent_coll, absent_local, absent_oplog, count, key, last_key;
- uint64_t first_miss, middle_coll, middle_local, middle_oplog;
uint64_t stable_fp, stable_val, val[MAX_TH+1];
uint32_t i, nth, timeout;
int ch, status, ret;
@@ -524,6 +589,7 @@ main(int argc, char *argv[])
if (nth < MIN_TH)
nth = MIN_TH;
}
+
printf("Parent: compatibility: %s, "
"in-mem log sync: %s, timestamp in use: %s\n",
compat ? "true" : "false",
@@ -536,6 +602,9 @@ main(int argc, char *argv[])
* 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));
testutil_checksys((pid = fork()) < 0);
if (pid == 0) { /* child */
@@ -548,15 +617,15 @@ main(int argc, char *argv[])
* Sleep for the configured amount of time before killing
* the child. Start the timeout from the time we notice that
* the file has been created. That allows the test to run
- * correctly on really slow machines. Verify the process ID
- * still exists in case the child aborts for some reason we
- * don't stay in this loop forever.
+ * correctly on really slow machines.
*/
testutil_check(__wt_snprintf(
statname, sizeof(statname), "%s/%s", home, ckpt_file));
- while (stat(statname, &sb) != 0 && kill(pid, 0) == 0)
+ while (stat(statname, &sb) != 0)
sleep(1);
sleep(timeout);
+ sa.sa_handler = SIG_DFL;
+ testutil_checksys(sigaction(SIGCHLD, &sa, NULL));
/*
* !!! It should be plenty long enough to make sure more than
@@ -573,6 +642,12 @@ main(int argc, char *argv[])
*/
if (chdir(home) != 0)
testutil_die(errno, "parent chdir: %s", home);
+ /*
+ * The tables can get very large, so while we'd ideally like to
+ * copy the entire database, we only copy the log files for now.
+ * Otherwise it can take far too long to run the test, particularly
+ * in automated testing.
+ */
testutil_check(__wt_snprintf(buf, sizeof(buf),
"rm -rf ../%s.SAVE && mkdir ../%s.SAVE && "
"cp -p WiredTigerLog.* ../%s.SAVE",
@@ -619,7 +694,9 @@ main(int argc, char *argv[])
absent_coll = absent_local = absent_oplog = 0;
fatal = false;
for (i = 0; i < nth; ++i) {
- first_miss = middle_coll = middle_local = middle_oplog = 0;
+ initialize_rep(&c_rep[i]);
+ initialize_rep(&l_rep[i]);
+ initialize_rep(&o_rep[i]);
testutil_check(__wt_snprintf(
fname, sizeof(fname), RECORDS_FILE, i));
if ((fp = fopen(fname, "r")) == NULL)
@@ -632,9 +709,14 @@ main(int argc, char *argv[])
* 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) {
+ for (last_key = INVALID_KEY;; ++count, last_key = key) {
ret = fscanf(fp, "%" SCNu64 "%" SCNu64 "\n",
&stable_fp, &key);
+ if (last_key == INVALID_KEY) {
+ c_rep[i].first_key = key;
+ l_rep[i].first_key = key;
+ o_rep[i].first_key = key;
+ }
if (ret != EOF && ret != 2) {
/*
* If we find a partial line, consider it
@@ -651,7 +733,7 @@ main(int argc, char *argv[])
* 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) {
+ if (last_key != INVALID_KEY && key != last_key + 1) {
printf("%s: Ignore partial record %" PRIu64
" last valid key %" PRIu64 "\n",
fname, key, last_key);
@@ -682,18 +764,16 @@ main(int argc, char *argv[])
fname, key, stable_fp, val[i]);
absent_coll++;
}
- if (middle_coll == 0)
- first_miss = key;
- middle_coll = key;
- } else if (middle_coll != 0) {
+ if (c_rep[i].first_miss == INVALID_KEY)
+ c_rep[i].first_miss = key;
+ c_rep[i].absent_key = key;
+ } else if (c_rep[i].absent_key != INVALID_KEY &&
+ c_rep[i].exist_key == INVALID_KEY) {
/*
- * We should never find an existing key after
- * we have detected one missing.
+ * If we get here we found a record that exists
+ * after absent records, a hole in our data.
*/
- printf("%s: COLLECTION after absent records %"
- PRIu64 "-%" PRIu64 " key %" PRIu64
- " exists\n",
- fname, first_miss, middle_coll, key);
+ c_rep[i].exist_key = key;
fatal = true;
}
/*
@@ -706,15 +786,16 @@ main(int argc, char *argv[])
printf("%s: LOCAL no record with key %"
PRIu64 "\n", fname, key);
absent_local++;
- middle_local = key;
- } else if (middle_local != 0) {
+ if (l_rep[i].first_miss == INVALID_KEY)
+ l_rep[i].first_miss = key;
+ l_rep[i].absent_key = key;
+ } else if (l_rep[i].absent_key != INVALID_KEY &&
+ l_rep[i].exist_key == INVALID_KEY) {
/*
* We should never find an existing key after
* we have detected one missing.
*/
- printf("%s: LOCAL after absent record at %"
- PRIu64 " key %" PRIu64 " exists\n",
- fname, middle_local, key);
+ l_rep[i].exist_key = key;
fatal = true;
}
/*
@@ -727,23 +808,28 @@ main(int argc, char *argv[])
printf("%s: OPLOG no record with key %"
PRIu64 "\n", fname, key);
absent_oplog++;
- middle_oplog = key;
- } else if (middle_oplog != 0) {
+ if (o_rep[i].first_miss == INVALID_KEY)
+ o_rep[i].first_miss = key;
+ o_rep[i].absent_key = key;
+ } else if (o_rep[i].absent_key != INVALID_KEY &&
+ o_rep[i].exist_key == INVALID_KEY) {
/*
* We should never find an existing key after
* we have detected one missing.
*/
- printf("%s: OPLOG after absent record at %"
- PRIu64 " key %" PRIu64 " exists\n",
- fname, middle_oplog, key);
+ o_rep[i].exist_key = key;
fatal = true;
}
}
+ c_rep[i].last_key = last_key;
+ l_rep[i].last_key = last_key;
+ o_rep[i].last_key = last_key;
testutil_checksys(fclose(fp) != 0);
+ print_missing(&c_rep[i], fname, "COLLECTION");
+ print_missing(&l_rep[i], fname, "LOCAL");
+ print_missing(&o_rep[i], fname, "OPLOG");
}
testutil_check(conn->close(conn, NULL));
- if (fatal)
- return (EXIT_FAILURE);
if (!inmem && absent_coll) {
printf("COLLECTION: %" PRIu64
" record(s) absent from %" PRIu64 "\n",
diff --git a/src/third_party/wiredtiger/test/format/compact.c b/src/third_party/wiredtiger/test/format/compact.c
index c1a73bea64b..2df3839f67b 100644
--- a/src/third_party/wiredtiger/test/format/compact.c
+++ b/src/third_party/wiredtiger/test/format/compact.c
@@ -66,9 +66,14 @@ compact(void *arg)
/*
* Compact can return EBUSY if concurrent with alter or if there
* is eviction pressure, or we collide with checkpoints.
+ *
+ * Compact returns ETIMEDOUT if the compaction doesn't finish in
+ * in some number of seconds. We don't configure a timeout and
+ * occasionally exceed the default of 1200 seconds.
*/
ret = session->compact(session, g.uri, NULL);
- if (ret != 0 && ret != EBUSY && ret != WT_ROLLBACK)
+ if (ret != 0 &&
+ ret != EBUSY && ret != ETIMEDOUT && ret != WT_ROLLBACK)
testutil_die(ret, "session.compact");
}
diff --git a/src/third_party/wiredtiger/test/format/config.c b/src/third_party/wiredtiger/test/format/config.c
index 049a655cb79..769ed608e64 100644
--- a/src/third_party/wiredtiger/test/format/config.c
+++ b/src/third_party/wiredtiger/test/format/config.c
@@ -181,6 +181,10 @@ config_setup(void)
g.c_cache = g.c_threads;
}
+ /* Check if a minimum cache size has been specified. */
+ if (g.c_cache_minimum != 0 && g.c_cache < g.c_cache_minimum)
+ g.c_cache = g.c_cache_minimum;
+
/* Give Helium configuration a final review. */
if (DATASOURCE("helium"))
config_helium_reset();
@@ -190,6 +194,25 @@ config_setup(void)
config_in_memory_reset();
/*
+ * Key/value minimum/maximum are related, correct unless specified by
+ * the configuration.
+ */
+ if (!config_is_perm("key_min") && g.c_key_min > g.c_key_max)
+ g.c_key_min = g.c_key_max;
+ if (!config_is_perm("key_max") && g.c_key_max < g.c_key_min)
+ g.c_key_max = g.c_key_min;
+ if (g.c_key_min > g.c_key_max)
+ testutil_die(EINVAL, "key_min may not be larger than key_max");
+
+ if (!config_is_perm("value_min") && g.c_value_min > g.c_value_max)
+ g.c_value_min = g.c_value_max;
+ if (!config_is_perm("value_max") && g.c_value_max < g.c_value_min)
+ g.c_value_max = g.c_value_min;
+ if (g.c_value_min > g.c_value_max)
+ testutil_die(EINVAL,
+ "value_min may not be larger than value_max");
+
+ /*
* Run-length is configured by a number of operations and a timer.
*
* If the operation count and the timer are both configured, do nothing.
@@ -213,25 +236,6 @@ config_setup(void)
config_single("timer=360", 0);
}
- /*
- * Key/value minimum/maximum are related, correct unless specified by
- * the configuration.
- */
- if (!config_is_perm("key_min") && g.c_key_min > g.c_key_max)
- g.c_key_min = g.c_key_max;
- if (!config_is_perm("key_max") && g.c_key_max < g.c_key_min)
- g.c_key_max = g.c_key_min;
- if (g.c_key_min > g.c_key_max)
- testutil_die(EINVAL, "key_min may not be larger than key_max");
-
- if (!config_is_perm("value_min") && g.c_value_min > g.c_value_max)
- g.c_value_min = g.c_value_max;
- if (!config_is_perm("value_max") && g.c_value_max < g.c_value_min)
- g.c_value_max = g.c_value_min;
- if (g.c_value_min > g.c_value_max)
- testutil_die(EINVAL,
- "value_min may not be larger than value_max");
-
/* Reset the key count. */
g.key_cnt = 0;
}
diff --git a/src/third_party/wiredtiger/test/format/config.h b/src/third_party/wiredtiger/test/format/config.h
index 6fb4071074d..7ac65147462 100644
--- a/src/third_party/wiredtiger/test/format/config.h
+++ b/src/third_party/wiredtiger/test/format/config.h
@@ -101,6 +101,10 @@ static CONFIG c[] = {
"size of the cache in MB",
0x0, 1, 100, 100 * 1024, &g.c_cache, NULL },
+ { "cache_minimum",
+ "minimum size of the cache in MB",
+ C_IGNORE, 1, 0, 100 * 1024, &g.c_cache_minimum, NULL },
+
{ "checkpoints",
"type of checkpoints (on | off | wiredtiger)",
C_IGNORE|C_STRING, 0, 0, 0, NULL, &g.c_checkpoint},
@@ -115,7 +119,7 @@ static CONFIG c[] = {
{ "checksum",
"type of checksums (on | off | uncompressed)",
- C_IGNORE|C_STRING, 1, 3, 3, NULL, &g.c_checksum },
+ C_IGNORE|C_STRING, 0, 0, 0, NULL, &g.c_checksum },
{ "chunk_size",
"LSM chunk size in MB",
@@ -159,7 +163,7 @@ static CONFIG c[] = {
{ "file_type",
"type of store to create (fix | var | row)",
- C_IGNORE|C_STRING, 1, 3, 3, NULL, &g.c_file_type },
+ C_IGNORE|C_STRING, 0, 0, 0, NULL, &g.c_file_type },
{ "firstfit",
"if allocation is firstfit", /* 10% */
@@ -196,7 +200,7 @@ static CONFIG c[] = {
{ "isolation",
"isolation level "
"(random | read-uncommitted | read-committed | snapshot)",
- C_IGNORE|C_STRING, 1, 4, 4, NULL, &g.c_isolation },
+ C_IGNORE|C_STRING, 0, 0, 0, NULL, &g.c_isolation },
{ "key_gap",
"gap between instantiated keys on a Btree page",
@@ -272,7 +276,7 @@ static CONFIG c[] = {
{ "quiet",
"quiet run (same as -q)",
- C_IGNORE|C_BOOL, 0, 0, 0, &g.c_quiet, NULL },
+ C_IGNORE|C_BOOL, 0, 0, 1, &g.c_quiet, NULL },
{ "read_pct",
"percent operations that are reads",
@@ -296,7 +300,7 @@ static CONFIG c[] = {
{ "runs",
"the number of runs",
- C_IGNORE, 0, UINT_MAX, UINT_MAX, &g.c_runs, NULL },
+ C_IGNORE, 0, 0, UINT_MAX, &g.c_runs, NULL },
{ "salvage",
"salvage testing", /* 100% */
@@ -319,8 +323,8 @@ static CONFIG c[] = {
0x0, 1, 32, 128, &g.c_threads, NULL },
{ "timer",
- "maximum time to run in minutes (default 20 minutes)",
- C_IGNORE, 0, UINT_MAX, UINT_MAX, &g.c_timer, NULL },
+ "maximum time to run in minutes",
+ C_IGNORE, 0, 0, UINT_MAX, &g.c_timer, NULL },
{ "transaction_timestamps", /* 10% */
"enable transaction timestamp support",
diff --git a/src/third_party/wiredtiger/test/format/format.h b/src/third_party/wiredtiger/test/format/format.h
index 96e1a0fe335..af66e166f47 100644
--- a/src/third_party/wiredtiger/test/format/format.h
+++ b/src/third_party/wiredtiger/test/format/format.h
@@ -150,6 +150,7 @@ typedef struct {
uint32_t c_bloom_hash_count;
uint32_t c_bloom_oldest;
uint32_t c_cache;
+ uint32_t c_cache_minimum;
char *c_checkpoint;
uint32_t c_checkpoint_log_size;
uint32_t c_checkpoint_wait;
diff --git a/src/third_party/wiredtiger/test/mciproject.yml b/src/third_party/wiredtiger/test/mciproject.yml
index 4b67299d14c..16e103e5366 100644
--- a/src/third_party/wiredtiger/test/mciproject.yml
+++ b/src/third_party/wiredtiger/test/mciproject.yml
@@ -65,7 +65,7 @@ tasks:
./build_posix/reconf
${configure_env_vars|} ./configure --enable-diagnostic --enable-python --enable-zlib --enable-strict --enable-verbose
${make_command|make} ${smp_command|} 2>&1
- TESTUTIL_ENABLE_LONG_TESTS=1 ${make_command|make} VERBOSE=1 check 2>&1
+ ${test_env_vars|} TESTUTIL_ENABLE_LONG_TESTS=1 ${make_command|make} VERBOSE=1 check 2>&1
fi
- command: archive.targz_pack
params:
@@ -96,15 +96,9 @@ tasks:
set -o errexit
set -o verbose
- # On 10.12, change the binary location with install_name_tool since DYLD_LIBRARY_PATH
- # appears not to work for dynamic modules loaded by python. For wt, the libtool generated
- # script has the wrong path for running on test machines.
- if [ "$(uname -s)" == "Darwin" ]; then
- WT_VERSION=$(m4 build_posix/aclocal/version.m4)
- install_name_tool -change /usr/local/lib/libwiredtiger-$WT_VERSION.dylib $(pwd)/.libs/libwiredtiger-$WT_VERSION.dylib lang/python/_wiredtiger.so
- install_name_tool -change /usr/local/lib/libwiredtiger-$WT_VERSION.dylib $(pwd)/.libs/libwiredtiger-$WT_VERSION.dylib .libs/wt
- fi
-
+ # Avoid /usr/bin/python, at least on macOS: with System Integrity
+ # Protection enabled, it ignores DYLD_LIBRARY_PATH and hence
+ # doesn't find the WiredTiger library in the local tree.
${test_env_vars|} python ./test/suite/run.py -v 2 ${smp_command|} 2>&1
- name: compile-windows-alt
@@ -186,7 +180,7 @@ buildvariants:
smp_command: -j $(sysctl -n hw.logicalcpu)
configure_env_vars: PATH=/opt/local/bin:$PATH
make_command: PATH=/opt/local/bin:$PATH ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future make
- test_env_vars: DYLD_LIBRARY_PATH=`pwd`/.libs
+ test_env_vars: PATH=/opt/local/bin:$PATH DYLD_LIBRARY_PATH=`pwd`/.libs
tasks:
- name: compile
- name: unit-test
diff --git a/src/third_party/wiredtiger/test/suite/suite_subprocess.py b/src/third_party/wiredtiger/test/suite/suite_subprocess.py
index 626a6b5efd3..71aab9c5422 100644
--- a/src/third_party/wiredtiger/test/suite/suite_subprocess.py
+++ b/src/third_party/wiredtiger/test/suite/suite_subprocess.py
@@ -26,8 +26,9 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
-import os, subprocess
+import os, subprocess, sys
from run import wt_builddir
+from wttest import WiredTigerTestCase
# suite_subprocess.py
# Run a subprocess within the test suite
@@ -117,6 +118,28 @@ class suite_subprocess:
print 'ERROR: ' + filename + ' should not be empty (this command expected error output)'
self.assertNotEqual(filesize, 0, filename + ': expected to not be empty')
+ def verbose_env(self, envvar):
+ return envvar + '=' + str(os.environ.get(envvar)) + '\n'
+
+ def show_outputs(self, procargs, message, filenames):
+ out = 'ERROR: wt command ' + message + ': ' + str(procargs) + '\n' + \
+ self.verbose_env('PATH') + \
+ self.verbose_env('LD_LIBRARY_PATH') + \
+ self.verbose_env('DYLD_LIBRARY_PATH') + \
+ self.verbose_env('PYTHONPATH') + \
+ 'output files follow:'
+ WiredTigerTestCase.prout(out)
+ for filename in filenames:
+ maxbytes = 1024*100
+ with open(filename, 'r') as f:
+ contents = f.read(maxbytes)
+ if len(contents) > 0:
+ if len(contents) >= maxbytes:
+ contents += '...\n'
+ sepline = '*' * 50 + '\n'
+ out = sepline + filename + '\n' + sepline + contents
+ WiredTigerTestCase.prout(out)
+
# Run the wt utility.
def runWt(self, args, infilename=None,
outfilename=None, errfilename=None, closeconn=True,
@@ -131,10 +154,17 @@ class suite_subprocess:
wterrname = errfilename or "wt.err"
with open(wterrname, "w") as wterr:
with open(wtoutname, "w") as wtout:
- procargs = [os.path.join(wt_builddir, "wt")]
+ # Prefer running the actual 'wt' executable rather than the
+ # 'wt' script created by libtool. On OS/X with System Integrity
+ # Protection enabled, running a shell script strips
+ # environment variables needed to run 'wt'.
+ if sys.platform == "darwin":
+ wtexe = os.path.join(wt_builddir, ".libs", "wt")
+ else:
+ wtexe = os.path.join(wt_builddir, "wt")
+ procargs = [ wtexe ]
if self._gdbSubprocess:
- procargs = [os.path.join(wt_builddir, "libtool"),
- "--mode=execute", "gdb", "--args"] + procargs
+ procargs = [ "gdb", "--args" ] + procargs
procargs.extend(args)
if self._gdbSubprocess:
infilepart = ""
@@ -155,10 +185,16 @@ class suite_subprocess:
returncode = subprocess.call(
procargs, stdout=wtout, stderr=wterr)
if failure:
+ if returncode == 0:
+ self.show_outputs(procargs, "expected failure, got success",
+ [wtoutname, wterrname])
self.assertNotEqual(returncode, 0,
'expected failure: "' + \
str(procargs) + '": exited ' + str(returncode))
else:
+ if returncode != 0:
+ self.show_outputs(procargs, "expected success, got failure",
+ [wtoutname, wterrname])
self.assertEqual(returncode, 0,
'expected success: "' + \
str(procargs) + '": exited ' + str(returncode))