diff options
author | Luke Chen <luke.chen@mongodb.com> | 2017-11-03 15:14:01 +1100 |
---|---|---|
committer | Luke Chen <luke.chen@mongodb.com> | 2017-11-03 15:37:51 +1100 |
commit | 48acb7cfa8503440e1b0ab2771371f4790245015 (patch) | |
tree | a8b8efbd78f6aa3b04f53bc1b226ec1e0cf4a422 /src/third_party/wiredtiger/test | |
parent | 73b4a7c888d90b8e875104b1a0f20627d29e0124 (diff) | |
download | mongo-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')
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)) |