From 0609d0ce2ef563d7a4cde77d46396fe5c92c6df1 Mon Sep 17 00:00:00 2001 From: Alex Gorrod Date: Mon, 24 Oct 2016 15:26:37 +1100 Subject: Import wiredtiger: ef9a7983ea47cea78400a4472a3d4e46735385c5 from branch mongodb-3.4 ref: 6a31c2118c..ef9a7983ea for: 3.4.0-rc2 WT-1592 Add ability to dump detailed cache information via statistics WT-2403 Enhance random cursor implementation for LSM trees WT-2880 Add support for Zstandard compression WT-2904 Fix a bug where the reported checkpoint size could be many times data size WT-2949 Add an option to wtperf to not close connection on shutdown WT-2954 Inserting multi-megabyte values can cause large in-memory pages WT-2955 Add statistics tracking the amount of time threads spend waiting for high level locks WT-2956 utility tests -h option is always overridden by the default setup WT-2959 Ensure WT_SESSION_IMPL is never used before it's initialized WT-2963 Race setting max_entries during eviction WT-2965 test_wt2323_join_visibility can hang on OSX WT-2974 lint WT-2976 Add a statistic tracking how long application threads spend doing I/O WT-2977 Csuite LSM Random test can occasionally fail WT-2985 Race during checkpoint can cause a core dump WT-2987 Fix a bug where opening a cursor on an incomplete table drops core WT-2988 Fix a bug where __wt_epoch potentially returns garbage values. --- src/third_party/wiredtiger/test/bloom/test_bloom.c | 2 - .../wiredtiger/test/checkpoint/test_checkpoint.c | 2 - src/third_party/wiredtiger/test/csuite/Makefile.am | 3 + .../test/csuite/wt1965_col_efficiency/main.c | 2 - .../test/csuite/wt2246_col_append/main.c | 2 - .../test/csuite/wt2323_join_visibility/main.c | 2 - .../test/csuite/wt2403_lsm_workload/main.c | 241 +++++++++++++++++++++ .../test/csuite/wt2447_join_main_table/main.c | 2 - .../test/csuite/wt2535_insert_race/main.c | 2 - .../test/csuite/wt2592_join_schema/main.c | 8 - .../wiredtiger/test/csuite/wt2695_checksum/main.c | 2 - .../wiredtiger/test/csuite/wt2719_reconfig/main.c | 4 +- .../test/csuite/wt2834_join_bloom_fix/main.c | 11 +- .../wiredtiger/test/csuite/wt2853_perf/main.c | 2 - .../wiredtiger/test/cursor_order/cursor_order.c | 2 - src/third_party/wiredtiger/test/fops/t.c | 2 - src/third_party/wiredtiger/test/format/config.c | 34 ++- src/third_party/wiredtiger/test/format/config.h | 2 +- src/third_party/wiredtiger/test/format/format.h | 3 + src/third_party/wiredtiger/test/format/t.c | 4 +- src/third_party/wiredtiger/test/format/wts.c | 5 +- src/third_party/wiredtiger/test/huge/huge.c | 2 - src/third_party/wiredtiger/test/manydbs/manydbs.c | 2 - .../wiredtiger/test/packing/intpack-test.c | 2 - .../wiredtiger/test/packing/intpack-test2.c | 2 - .../wiredtiger/test/packing/intpack-test3.c | 2 - .../wiredtiger/test/packing/packing-test.c | 2 - .../wiredtiger/test/readonly/readonly.c | 2 - .../wiredtiger/test/recovery/random-abort.c | 2 - .../wiredtiger/test/recovery/truncated-log.c | 2 - src/third_party/wiredtiger/test/salvage/salvage.c | 2 - .../wiredtiger/test/suite/test_bug017.py | 46 ++++ .../wiredtiger/test/suite/test_cursor_random02.py | 25 ++- .../wiredtiger/test/suite/test_encrypt01.py | 1 + .../wiredtiger/test/suite/test_stat02.py | 70 +++++- src/third_party/wiredtiger/test/thread/t.c | 2 - src/third_party/wiredtiger/test/utility/misc.c | 4 +- .../wiredtiger/test/utility/parse_opts.c | 18 +- .../wiredtiger/test/utility/test_util.h | 12 +- 39 files changed, 440 insertions(+), 95 deletions(-) create mode 100644 src/third_party/wiredtiger/test/csuite/wt2403_lsm_workload/main.c create mode 100644 src/third_party/wiredtiger/test/suite/test_bug017.py (limited to 'src/third_party/wiredtiger/test') diff --git a/src/third_party/wiredtiger/test/bloom/test_bloom.c b/src/third_party/wiredtiger/test/bloom/test_bloom.c index 7a298f000aa..67249ff887e 100644 --- a/src/third_party/wiredtiger/test/bloom/test_bloom.c +++ b/src/third_party/wiredtiger/test/bloom/test_bloom.c @@ -56,8 +56,6 @@ void usage(void) extern char *__wt_optarg; extern int __wt_optind; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c index 6b2f0d4466c..4998019ad8e 100644 --- a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c +++ b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c @@ -42,8 +42,6 @@ static int wt_shutdown(void); extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/csuite/Makefile.am b/src/third_party/wiredtiger/test/csuite/Makefile.am index 15db2fbcf46..8f1714237b9 100644 --- a/src/third_party/wiredtiger/test/csuite/Makefile.am +++ b/src/third_party/wiredtiger/test/csuite/Makefile.am @@ -7,6 +7,9 @@ AM_LDFLAGS = -static test_wt1965_col_efficiency_SOURCES = wt1965_col_efficiency/main.c noinst_PROGRAMS = test_wt1965_col_efficiency +test_wt2403_lsm_workload_SOURCES = wt2403_lsm_workload/main.c +noinst_PROGRAMS += test_wt2403_lsm_workload + test_wt2246_col_append_SOURCES = wt2246_col_append/main.c noinst_PROGRAMS += test_wt2246_col_append diff --git a/src/third_party/wiredtiger/test/csuite/wt1965_col_efficiency/main.c b/src/third_party/wiredtiger/test/csuite/wt1965_col_efficiency/main.c index 0dc367c0611..a7235d81b31 100644 --- a/src/third_party/wiredtiger/test/csuite/wt1965_col_efficiency/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt1965_col_efficiency/main.c @@ -35,8 +35,6 @@ * it is demonstrating an inefficiency rather than a correctness bug. */ -void (*custom_die)(void) = NULL; - /* If changing field count also need to change set_value and get_value calls */ #define NR_FIELDS 8 #define NR_OBJECTS 100 diff --git a/src/third_party/wiredtiger/test/csuite/wt2246_col_append/main.c b/src/third_party/wiredtiger/test/csuite/wt2246_col_append/main.c index 1da8732abb4..4b352b26051 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2246_col_append/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2246_col_append/main.c @@ -42,8 +42,6 @@ #define MILLION 1000000 -void (*custom_die)(void) = NULL; - /* Needs to be global for signal handling. */ static TEST_OPTS *opts, _opts; diff --git a/src/third_party/wiredtiger/test/csuite/wt2323_join_visibility/main.c b/src/third_party/wiredtiger/test/csuite/wt2323_join_visibility/main.c index 5987b77fd7d..239a3f300d0 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2323_join_visibility/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2323_join_visibility/main.c @@ -52,8 +52,6 @@ * of inserts set low as a default. */ -void (*custom_die)(void) = NULL; - #define N_RECORDS 10000 #define N_INSERT 500000 #define N_INSERT_THREAD 2 diff --git a/src/third_party/wiredtiger/test/csuite/wt2403_lsm_workload/main.c b/src/third_party/wiredtiger/test/csuite/wt2403_lsm_workload/main.c new file mode 100644 index 00000000000..0c287484b9e --- /dev/null +++ b/src/third_party/wiredtiger/test/csuite/wt2403_lsm_workload/main.c @@ -0,0 +1,241 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "test_util.h" + +static const char name[] = "lsm:test"; +#define NUM_DOCS 100000 +#define NUM_QUERIES (NUM_DOCS/100) + +static void +rand_str(uint64_t i, char *str) +{ + uint64_t x, y; + + y = strlen(str); + for (x = y; x > y - 8; x--) { + str[x - 1] = (char)(i % 10) + 48; + i = i / 10; + } +} + +static void +check_str(uint64_t i, char *str, bool mod) +{ + char str2[] = "0000000000000000"; + + rand_str(i, str2); + if (mod) + str2[0] = 'A'; + testutil_checkfmt(strcmp(str, str2), + "strcmp failed, got %s, expected %s", str, str2); +} + +static void +query_docs(WT_CURSOR *cursor, bool mod) +{ + WT_ITEM key, value; + int i; + + for (i = 0; i < NUM_QUERIES; i++) { + testutil_check(cursor->next(cursor)); + testutil_check(cursor->get_key(cursor, &key)); + testutil_check(cursor->get_value(cursor, &value)); + check_str((uint64_t)key.data, (char *)value.data, mod); + } + printf("%d documents read\n", NUM_QUERIES); +} + +static void * +compact_thread(void *args) +{ + WT_SESSION *session; + + session = (WT_SESSION *)args; + testutil_check(session->compact(session, name, NULL)); + return (NULL); +} + +int +main(int argc, char *argv[]) +{ + TEST_OPTS *opts, _opts; + WT_CURSOR *rcursor, *wcursor; + WT_ITEM key, value; + WT_SESSION *session, *session2; + pthread_t thread; + uint64_t i; + + char str[] = "0000000000000000"; + + /* + * Create a clean test directory for this run of the test program if the + * environment variable isn't already set (as is done by make check). + */ + opts = &_opts; + memset(opts, 0, sizeof(*opts)); + testutil_check(testutil_parse_opts(argc, argv, opts)); + testutil_make_work_dir(opts->home); + testutil_check(wiredtiger_open(opts->home, + NULL, "create,cache_size=200M", &opts->conn)); + + testutil_check( + opts->conn->open_session(opts->conn, NULL, NULL, &session)); + testutil_check( + opts->conn->open_session(opts->conn, NULL, NULL, &session2)); + + testutil_check(session->create(session, name, + "key_format=Q,value_format=S")); + + /* Populate the table with some data. */ + testutil_check(session->open_cursor( + session, name, NULL, "overwrite", &wcursor)); + for (i = 0; i < NUM_DOCS; i++) { + wcursor->set_key(wcursor, i); + rand_str(i, str); + wcursor->set_value(wcursor, str); + testutil_check(wcursor->insert(wcursor)); + } + testutil_check(wcursor->close(wcursor)); + printf("%d documents inserted\n", NUM_DOCS); + + /* Perform some random reads */ + testutil_check(session->open_cursor( + session, name, NULL, "next_random=true", &rcursor)); + query_docs(rcursor, false); + testutil_check(rcursor->close(rcursor)); + + /* Setup Transaction to pin the current values */ + testutil_check( + session2->begin_transaction(session2, "isolation=snapshot")); + testutil_check(session2->open_cursor( + session2, name, NULL, "next_random=true", &rcursor)); + + /* Perform updates in a txn to confirm that we see only the original. */ + testutil_check(session->open_cursor( + session, name, NULL, "overwrite", &wcursor)); + for (i = 0; i < NUM_DOCS; i++) { + rand_str(i, str); + str[0] = 'A'; + wcursor->set_key(wcursor, i); + wcursor->set_value(wcursor, str); + testutil_check(wcursor->update(wcursor)); + } + testutil_check(wcursor->close(wcursor)); + printf("%d documents set to update\n", NUM_DOCS); + + /* Random reads, which should see the original values */ + query_docs(rcursor, false); + testutil_check(rcursor->close(rcursor)); + + /* Finish the txn */ + testutil_check(session2->rollback_transaction(session2, NULL)); + + /* Random reads, which should see the updated values */ + testutil_check(session2->open_cursor( + session2, name, NULL, "next_random=true", &rcursor)); + query_docs(rcursor, true); + testutil_check(rcursor->close(rcursor)); + + /* Setup a pre-delete txn */ + testutil_check( + session2->begin_transaction(session2, "isolation=snapshot")); + testutil_check(session2->open_cursor( + session2, name, NULL, "next_random=true", &rcursor)); + + /* Delete all but one document */ + testutil_check(session->open_cursor( + session, name, NULL, "overwrite", &wcursor)); + for (i = 0; i < NUM_DOCS - 1; i++) { + wcursor->set_key(wcursor, i); + testutil_check(wcursor->remove(wcursor)); + } + testutil_check(wcursor->close(wcursor)); + printf("%d documents deleted\n", NUM_DOCS - 1); + + /* Random reads, which should not see the deletes */ + query_docs(rcursor, true); + testutil_check(rcursor->close(rcursor)); + + /* Rollback the txn so we can see the deletes */ + testutil_check(session2->rollback_transaction(session2, NULL)); + + /* Find the one remaining document 3 times */ + testutil_check(session2->open_cursor( + session2, name, NULL, "next_random=true", &rcursor)); + for (i = 0; i < 3; i++) { + testutil_check(rcursor->next(rcursor)); + testutil_check(rcursor->get_key(rcursor, &key)); + testutil_check(rcursor->get_value(rcursor, &value)); + /* There should only be one value available to us */ + testutil_assertfmt((uint64_t)key.data == NUM_DOCS - 1, + "expected %d and got %" PRIu64, + NUM_DOCS - 1, (uint64_t)key.data); + check_str((uint64_t)key.data, (char *)value.data, true); + } + printf("Found the deleted doc 3 times\n"); + testutil_check(rcursor->close(rcursor)); + + /* Repopulate the table for compact. */ + testutil_check(session->open_cursor( + session, name, NULL, "overwrite", &wcursor)); + for (i = 0; i < NUM_DOCS - 1; i++) { + wcursor->set_key(wcursor, i); + rand_str(i, str); + str[0] = 'A'; + wcursor->set_value(wcursor, str); + testutil_check(wcursor->insert(wcursor)); + } + testutil_check(wcursor->close(wcursor)); + + /* Run random cursor queries while compact is running */ + testutil_check(session2->open_cursor( + session2, name, NULL, "next_random=true", &rcursor)); + testutil_check(pthread_create(&thread, NULL, compact_thread, session)); + query_docs(rcursor, true); + testutil_check(rcursor->close(rcursor)); + testutil_check(pthread_join(thread, NULL)); + + /* Delete everything. Check for infinite loops */ + testutil_check(session->open_cursor( + session, name, NULL, "overwrite", &wcursor)); + for (i = 0; i < NUM_DOCS; i++) { + wcursor->set_key(wcursor, i); + testutil_check(wcursor->remove(wcursor)); + } + testutil_check(wcursor->close(wcursor)); + + testutil_check(session2->open_cursor( + session2, name, NULL, "next_random=true", &rcursor)); + for (i = 0; i < 3; i++) + testutil_assert(rcursor->next(rcursor) == WT_NOTFOUND); + printf("Successfully got WT_NOTFOUND\n"); + + testutil_cleanup(opts); + return (EXIT_SUCCESS); +} diff --git a/src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c b/src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c index bbae61e7ed5..1368e7c8c09 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c @@ -49,8 +49,6 @@ * table. */ -void (*custom_die)(void) = NULL; - #define N_RECORDS 10000 static void diff --git a/src/third_party/wiredtiger/test/csuite/wt2535_insert_race/main.c b/src/third_party/wiredtiger/test/csuite/wt2535_insert_race/main.c index ee567df8749..ae18760a829 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2535_insert_race/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2535_insert_race/main.c @@ -36,8 +36,6 @@ * Failure mode: Check that the data is correct at the end of the run. */ -void (*custom_die)(void) = NULL; - void *thread_insert_race(void *); int diff --git a/src/third_party/wiredtiger/test/csuite/wt2592_join_schema/main.c b/src/third_party/wiredtiger/test/csuite/wt2592_join_schema/main.c index 4ffc9194646..0ec1c765d99 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2592_join_schema/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2592_join_schema/main.c @@ -36,12 +36,6 @@ * Failure mode: The failure seen in WT-2592 was that no items were returned * by a join. */ -#include -#include -#include -#include - -#include /* The C struct for the data we are storing in a WiredTiger table. */ typedef struct { @@ -66,8 +60,6 @@ static POP_RECORD pop_data[] = { { "", 0, 0 } }; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/csuite/wt2695_checksum/main.c b/src/third_party/wiredtiger/test/csuite/wt2695_checksum/main.c index 50f118bf828..db4fed5dc53 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2695_checksum/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2695_checksum/main.c @@ -32,8 +32,6 @@ * Test case description: Smoke-test the CRC. */ -void (*custom_die)(void) = NULL; - static inline void check(uint32_t hw, uint32_t sw, size_t len, const char *msg) { diff --git a/src/third_party/wiredtiger/test/csuite/wt2719_reconfig/main.c b/src/third_party/wiredtiger/test/csuite/wt2719_reconfig/main.c index 64a47ea49a6..0942cfc73b2 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2719_reconfig/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2719_reconfig/main.c @@ -34,9 +34,7 @@ * Test case description: Fuzz testing for WiredTiger reconfiguration. */ -void (*custom_die)(void) = NULL; - -static const char *list[] = { +static const char * const list[] = { ",async=(enabled=0)", ",async=(enabled=1)", ",async=(ops_max=2048)", diff --git a/src/third_party/wiredtiger/test/csuite/wt2834_join_bloom_fix/main.c b/src/third_party/wiredtiger/test/csuite/wt2834_join_bloom_fix/main.c index 1d6abcfb179..7c80496f1b6 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2834_join_bloom_fix/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2834_join_bloom_fix/main.c @@ -39,8 +39,6 @@ * * Failure mode: We get results back from our join. */ -void (*custom_die)(void) = NULL; - #define N_RECORDS 100000 #define N_INSERT 1000000 @@ -103,8 +101,8 @@ main(int argc, char *argv[]) &maincur)); maincur->set_key(maincur, N_RECORDS); maincur->set_value(maincur, 54321, 0, "", 0, N_RECORDS); - maincur->insert(maincur); - maincur->close(maincur); + testutil_check(maincur->insert(maincur)); + testutil_check(maincur->close(maincur)); testutil_check(session->close(session, NULL)); populate(opts); @@ -153,6 +151,7 @@ main(int argc, char *argv[]) key, key2, post, balance, flag); count++; } + testutil_assert(ret == WT_NOTFOUND); testutil_assert(count == 0); testutil_cleanup(opts); @@ -197,6 +196,6 @@ populate(TEST_OPTS *opts) testutil_check(maincur->insert(maincur)); testutil_check(session->commit_transaction(session, NULL)); } - maincur->close(maincur); - session->close(session, NULL); + testutil_check(maincur->close(maincur)); + testutil_check(session->close(session, NULL)); } diff --git a/src/third_party/wiredtiger/test/csuite/wt2853_perf/main.c b/src/third_party/wiredtiger/test/csuite/wt2853_perf/main.c index 27591fdf214..6cec9634cd1 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2853_perf/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2853_perf/main.c @@ -42,8 +42,6 @@ * continues until the test ends (~30 seconds). */ -void (*custom_die)(void) = NULL; - static void *thread_insert(void *); static void *thread_get(void *); diff --git a/src/third_party/wiredtiger/test/cursor_order/cursor_order.c b/src/third_party/wiredtiger/test/cursor_order/cursor_order.c index aa351e6fea8..85b8c68e545 100644 --- a/src/third_party/wiredtiger/test/cursor_order/cursor_order.c +++ b/src/third_party/wiredtiger/test/cursor_order/cursor_order.c @@ -44,8 +44,6 @@ static void wt_shutdown(SHARED_CONFIG *); extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/fops/t.c b/src/third_party/wiredtiger/test/fops/t.c index bf0588d5a53..7b4a7cf8fca 100644 --- a/src/third_party/wiredtiger/test/fops/t.c +++ b/src/third_party/wiredtiger/test/fops/t.c @@ -51,8 +51,6 @@ static void wt_shutdown(void); extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/format/config.c b/src/third_party/wiredtiger/test/format/config.c index 542adf33da2..839ff5058de 100644 --- a/src/third_party/wiredtiger/test/format/config.c +++ b/src/third_party/wiredtiger/test/format/config.c @@ -187,8 +187,17 @@ config_setup(void) /* Give in-memory configuration a final review. */ config_in_memory_check(); - /* Make the default maximum-run length 20 minutes. */ - if (!config_is_perm("timer")) + /* + * Run-length configured by a number of operations and a timer. If the + * operation count and the timer are both set by a configuration, there + * isn't anything to do. If only the operation count was configured, + * set a default maximum-run of 20 minutes. If only the timer is set, + * clear the operations count (which was set randomly). + */ + if (config_is_perm("timer")) { + if (!config_is_perm("ops")) + config_single("ops=0", 0); + } else config_single("timer=20", 0); /* @@ -270,28 +279,33 @@ config_compression(const char *conf_name) */ switch (mmrand(NULL, 1, 20)) { #ifdef HAVE_BUILTIN_EXTENSION_LZ4 - case 1: case 2: case 3: case 4: /* 20% lz4 */ + case 1: case 2: /* 10% lz4 */ cstr = "lz4"; break; - case 5: /* 5% lz4-no-raw */ + case 3: /* 5% lz4-no-raw */ cstr = "lz4-noraw"; break; #endif #ifdef HAVE_BUILTIN_EXTENSION_SNAPPY - case 6: case 7: case 8: case 9: /* 30% snappy */ - case 10: case 11: + case 4: case 5: case 6: case 7: /* 30% snappy */ + case 8: case 9: cstr = "snappy"; break; #endif #ifdef HAVE_BUILTIN_EXTENSION_ZLIB - case 12: case 13: case 14: case 15: /* 20% zlib */ + case 10: case 11: case 12: case 13: /* 20% zlib */ cstr = "zlib"; break; - case 16: /* 5% zlib-no-raw */ + case 14: /* 5% zlib-no-raw */ cstr = "zlib-noraw"; break; #endif - case 17: case 18: case 19: case 20: /* 20% no compression */ +#ifdef HAVE_BUILTIN_EXTENSION_ZSTD + case 15: case 16 case 17: /* 15% zstd */ + cstr = "zstd"; + break; +#endif + case 18: case 19: case 20: /* 15% no compression */ default: break; } @@ -748,6 +762,8 @@ config_map_compression(const char *s, u_int *vp) *vp = COMPRESS_ZLIB; else if (strcmp(s, "zlib-noraw") == 0) *vp = COMPRESS_ZLIB_NO_RAW; + else if (strcmp(s, "zstd") == 0) + *vp = COMPRESS_ZSTD; else testutil_die(EINVAL, "illegal compression configuration: %s", s); diff --git a/src/third_party/wiredtiger/test/format/config.h b/src/third_party/wiredtiger/test/format/config.h index 725bc7c5d97..9bfba3cd0df 100644 --- a/src/third_party/wiredtiger/test/format/config.h +++ b/src/third_party/wiredtiger/test/format/config.h @@ -58,7 +58,7 @@ typedef struct { } CONFIG; #define COMPRESSION_LIST \ - "(none | lz4 | lz4-noraw | snappy | zlib | zlib-noraw)" + "(none | lz4 | lz4-noraw | snappy | zlib | zlib-noraw | zstd)" static CONFIG c[] = { { "abort", diff --git a/src/third_party/wiredtiger/test/format/format.h b/src/third_party/wiredtiger/test/format/format.h index 363dcf9eea8..820bc020c9b 100644 --- a/src/third_party/wiredtiger/test/format/format.h +++ b/src/third_party/wiredtiger/test/format/format.h @@ -48,6 +48,8 @@ EXTPATH "compressors/snappy/.libs/libwiredtiger_snappy.so" #define ZLIB_PATH \ EXTPATH "compressors/zlib/.libs/libwiredtiger_zlib.so" +#define ZSTD_PATH \ + EXTPATH "compressors/zstd/.libs/libwiredtiger_zstd.so" #define REVERSE_PATH \ EXTPATH "collators/reverse/.libs/libwiredtiger_reverse_collator.so" @@ -219,6 +221,7 @@ typedef struct { #define COMPRESS_SNAPPY 5 #define COMPRESS_ZLIB 6 #define COMPRESS_ZLIB_NO_RAW 7 +#define COMPRESS_ZSTD 8 u_int c_compression_flag; /* Compression flag value */ u_int c_logging_compression_flag; /* Log compression flag value */ diff --git a/src/third_party/wiredtiger/test/format/t.c b/src/third_party/wiredtiger/test/format/t.c index 41bdea11e73..7701595776c 100644 --- a/src/third_party/wiredtiger/test/format/t.c +++ b/src/third_party/wiredtiger/test/format/t.c @@ -38,8 +38,6 @@ static void usage(void) extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = format_die; /* Local death handler. */ - int main(int argc, char *argv[]) { @@ -47,6 +45,8 @@ main(int argc, char *argv[]) int ch, onerun, reps; const char *config, *home; + custom_die = format_die; /* Local death handler. */ + config = NULL; #ifdef _WIN32 diff --git a/src/third_party/wiredtiger/test/format/wts.c b/src/third_party/wiredtiger/test/format/wts.c index 1600786855a..23fdbce156c 100644 --- a/src/third_party/wiredtiger/test/format/wts.c +++ b/src/third_party/wiredtiger/test/format/wts.c @@ -50,6 +50,8 @@ compressor(uint32_t compress_flag) return ("zlib"); case COMPRESS_ZLIB_NO_RAW: return ("zlib-noraw"); + case COMPRESS_ZSTD: + return ("zstd"); default: break; } @@ -210,13 +212,14 @@ wts_open(const char *home, bool set_api, WT_CONNECTION **connp) /* Extensions. */ p += snprintf(p, REMAIN(p, end), ",extensions=[" - "\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"],", + "\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"],", g.c_reverse ? REVERSE_PATH : "", access(LZ4_PATH, R_OK) == 0 ? LZ4_PATH : "", access(LZO_PATH, R_OK) == 0 ? LZO_PATH : "", access(ROTN_PATH, R_OK) == 0 ? ROTN_PATH : "", access(SNAPPY_PATH, R_OK) == 0 ? SNAPPY_PATH : "", access(ZLIB_PATH, R_OK) == 0 ? ZLIB_PATH : "", + access(ZSTD_PATH, R_OK) == 0 ? ZSTD_PATH : "", DATASOURCE("kvsbdb") ? KVS_BDB_PATH : ""); /* diff --git a/src/third_party/wiredtiger/test/huge/huge.c b/src/third_party/wiredtiger/test/huge/huge.c index 3aa61a9048e..17e2db353d5 100644 --- a/src/third_party/wiredtiger/test/huge/huge.c +++ b/src/third_party/wiredtiger/test/huge/huge.c @@ -159,8 +159,6 @@ run(CONFIG *cp, int bigkey, size_t bytes) extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/manydbs/manydbs.c b/src/third_party/wiredtiger/test/manydbs/manydbs.c index c5c9a9a7ccd..7e986d47af3 100644 --- a/src/third_party/wiredtiger/test/manydbs/manydbs.c +++ b/src/third_party/wiredtiger/test/manydbs/manydbs.c @@ -68,8 +68,6 @@ usage(void) extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - static WT_CONNECTION **connections = NULL; static WT_CURSOR **cursors = NULL; static WT_RAND_STATE rnd; diff --git a/src/third_party/wiredtiger/test/packing/intpack-test.c b/src/third_party/wiredtiger/test/packing/intpack-test.c index 76851b38e35..c84823b741b 100644 --- a/src/third_party/wiredtiger/test/packing/intpack-test.c +++ b/src/third_party/wiredtiger/test/packing/intpack-test.c @@ -28,8 +28,6 @@ #include "test_util.h" -void (*custom_die)(void) = NULL; - int main(void) { diff --git a/src/third_party/wiredtiger/test/packing/intpack-test2.c b/src/third_party/wiredtiger/test/packing/intpack-test2.c index a7d31329069..4e612808a35 100644 --- a/src/third_party/wiredtiger/test/packing/intpack-test2.c +++ b/src/third_party/wiredtiger/test/packing/intpack-test2.c @@ -28,8 +28,6 @@ #include "test_util.h" -void (*custom_die)(void) = NULL; - int main(void) { diff --git a/src/third_party/wiredtiger/test/packing/intpack-test3.c b/src/third_party/wiredtiger/test/packing/intpack-test3.c index aac0178578f..763b0255ecf 100644 --- a/src/third_party/wiredtiger/test/packing/intpack-test3.c +++ b/src/third_party/wiredtiger/test/packing/intpack-test3.c @@ -28,8 +28,6 @@ #include "test_util.h" -void (*custom_die)(void) = NULL; - void test_value(int64_t); void test_spread(int64_t, int64_t, int64_t); diff --git a/src/third_party/wiredtiger/test/packing/packing-test.c b/src/third_party/wiredtiger/test/packing/packing-test.c index f251c17eb67..919b0622806 100644 --- a/src/third_party/wiredtiger/test/packing/packing-test.c +++ b/src/third_party/wiredtiger/test/packing/packing-test.c @@ -28,8 +28,6 @@ #include "test_util.h" -void (*custom_die)(void) = NULL; - static void check(const char *fmt, ...) { diff --git a/src/third_party/wiredtiger/test/readonly/readonly.c b/src/third_party/wiredtiger/test/readonly/readonly.c index 7a131912c31..a4b79f5859f 100644 --- a/src/third_party/wiredtiger/test/readonly/readonly.c +++ b/src/third_party/wiredtiger/test/readonly/readonly.c @@ -158,8 +158,6 @@ open_dbs(int op, const char *dir, extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/recovery/random-abort.c b/src/third_party/wiredtiger/test/recovery/random-abort.c index 22a163bedff..03e67e2f723 100644 --- a/src/third_party/wiredtiger/test/recovery/random-abort.c +++ b/src/third_party/wiredtiger/test/recovery/random-abort.c @@ -179,8 +179,6 @@ fill_db(uint32_t nth) extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/recovery/truncated-log.c b/src/third_party/wiredtiger/test/recovery/truncated-log.c index c0effa85e95..c265263d44c 100644 --- a/src/third_party/wiredtiger/test/recovery/truncated-log.c +++ b/src/third_party/wiredtiger/test/recovery/truncated-log.c @@ -258,8 +258,6 @@ fill_db(void) extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/salvage/salvage.c b/src/third_party/wiredtiger/test/salvage/salvage.c index bad0167ca8e..b8553bbd72d 100644 --- a/src/third_party/wiredtiger/test/salvage/salvage.c +++ b/src/third_party/wiredtiger/test/salvage/salvage.c @@ -64,8 +64,6 @@ static int verbose; /* -v flag */ extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/suite/test_bug017.py b/src/third_party/wiredtiger/test/suite/test_bug017.py new file mode 100644 index 00000000000..03e7b2ba714 --- /dev/null +++ b/src/third_party/wiredtiger/test/suite/test_bug017.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# +# Public Domain 2014-2016 MongoDB, Inc. +# Public Domain 2008-2014 WiredTiger, Inc. +# +# This is free and unencumbered software released into the public domain. +# +# Anyone is free to copy, modify, publish, use, compile, sell, or +# distribute this software, either in source code form or as a compiled +# binary, for any purpose, commercial or non-commercial, and by any +# means. +# +# In jurisdictions that recognize copyright laws, the author or authors +# of this software dedicate any and all copyright interest in the +# software to the public domain. We make this dedication for the benefit +# of the public at large and to the detriment of our heirs and +# successors. We intend this dedication to be an overt act of +# relinquishment in perpetuity of all present and future rights to this +# software under copyright law. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import wiredtiger, wttest + +# test_bug017.py +# WT-2987: opening a cursor on an incomplete table drops core +class test_bug017(wttest.WiredTigerTestCase): + + def test_bug017_run(self): + self.session.create("table:bug17", + 'key_format=r,value_format=5sHQ,' + + 'columns=(id,country,year,population),colgroups=(main,population)') + + msg = '/column groups/' + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: self.session.open_cursor("table:bug17(country)", None), + msg) + +if __name__ == '__main__': + wttest.run() diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_random02.py b/src/third_party/wiredtiger/test/suite/test_cursor_random02.py index 93aa97f2282..195480d703b 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor_random02.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor_random02.py @@ -34,7 +34,10 @@ from wtscenario import make_scenarios # test_cursor_random02.py # Cursor next_random operations class test_cursor_random02(wttest.WiredTigerTestCase): - type = 'table:random' + types = [ + ('lsm', dict(type='lsm:random')), + ('table', dict(type='table:random')) + ] config = [ ('not-sample', dict(config='next_random=true')) ] @@ -46,26 +49,35 @@ class test_cursor_random02(wttest.WiredTigerTestCase): ('10000', dict(records=10000)), ('50000', dict(records=50000)), ] - scenarios = make_scenarios(config, records) + scenarios = make_scenarios(config, records, types) # Check that next_random works in the presence of a larger set of values, # where the values are in an insert list. def test_cursor_random_reasonable_distribution(self): uri = self.type num_entries = self.records + config = 'key_format=S' + if uri == 'table:random': + config = 'leaf_page_max=100MB,' + config # Set the leaf-page-max value, otherwise the page might split. - simple_populate(self, uri, - 'leaf_page_max=100MB,key_format=S', num_entries) + simple_populate(self, uri, config, num_entries) # Setup an array to track which keys are seen visitedKeys = [0] * (num_entries + 1) + # Setup a counter to see when we find a sequential key + sequentialKeys = 0 cursor = self.session.open_cursor(uri, None, 'next_random=true') + lastKey = None for i in range(0, num_entries): self.assertEqual(cursor.next(), 0) current = cursor.get_key() current = int(current) visitedKeys[current] = visitedKeys[current] + 1 + if lastKey != None: + if current == (lastKey + 1): + sequentialKeys += 1 + lastKey = current differentKeys = sum(x > 0 for x in visitedKeys) @@ -76,7 +88,10 @@ class test_cursor_random02(wttest.WiredTigerTestCase): str(num_entries) + ', ' + \ str((int)((differentKeys * 100) / num_entries)) + '%') ''' - + # Can't test for non-sequential data when there is 1 item in the table + if num_entries > 1: + self.assertGreater(num_entries - 1, sequentialKeys, + 'cursor is returning sequential data') self.assertGreater(differentKeys, num_entries / 4, 'next_random random distribution not adequate') diff --git a/src/third_party/wiredtiger/test/suite/test_encrypt01.py b/src/third_party/wiredtiger/test/suite/test_encrypt01.py index d314cbeadfd..746c9d13e96 100644 --- a/src/third_party/wiredtiger/test/suite/test_encrypt01.py +++ b/src/third_party/wiredtiger/test/suite/test_encrypt01.py @@ -57,6 +57,7 @@ class test_encrypt01(wttest.WiredTigerTestCase): ('lz4', dict(log_compress='lz4', block_compress='lz4')), ('snappy', dict(log_compress='snappy', block_compress='snappy')), ('zlib', dict(log_compress='zlib', block_compress='zlib')), + ('zstd', dict(log_compress='zstd', block_compress='zstd')), ('none-snappy', dict(log_compress=None, block_compress='snappy')), ('snappy-lz4', dict(log_compress='snappy', block_compress='lz4')), ] diff --git a/src/third_party/wiredtiger/test/suite/test_stat02.py b/src/third_party/wiredtiger/test/suite/test_stat02.py index 3d2a83d1c3c..047d2c74499 100644 --- a/src/third_party/wiredtiger/test/suite/test_stat02.py +++ b/src/third_party/wiredtiger/test/suite/test_stat02.py @@ -165,7 +165,7 @@ class test_stat_cursor_conn_error(wttest.WiredTigerTestCase): args = ['none', 'all', 'fast'] for i in list(itertools.permutations(args, 2)): config = 'create,statistics=(' + i[0] + ',' + i[1] + ')' - msg = '/only one statistics configuration value/' + msg = '/Only one of/' self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.wiredtiger_open('.', config), msg) @@ -188,10 +188,76 @@ class test_stat_cursor_dsrc_error(wttest.WiredTigerTestCase): args = ['all', 'fast'] for i in list(itertools.permutations(args, 2)): config = 'statistics=(' + i[0] + ',' + i[1] + ')' - msg = '/only one statistics configuration value/' + msg = '/Only one of/' self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.open_cursor( 'statistics:' + self.uri, None, config), msg) +# Test data-source cache walk statistics +class test_stat_cursor_dsrc_cache_walk(wttest.WiredTigerTestCase): + uri = 'file:test_stat_cursor_dsrc_cache_walk' + + conn_config = 'statistics=(none)' + + def test_stat_cursor_dsrc_cache_walk(self): + simple_populate(self, self.uri, 'key_format=S', 100) + # Ensure that it's an error to get cache_walk stats if none is set + msg = '/doesn\'t match the database statistics/' + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: self.session.open_cursor( + 'statistics:' + self.uri, None, None), msg) + + # Test configurations that are valid but should not collect + # cache walk information. Do these first since the cache walk + # statistics are mostly marked as not cleared - so once they are + # populated the values will always be returned + self.conn.reconfigure('statistics=(cache_walk,fast,clear)') + c = self.session.open_cursor( + 'statistics:' + self.uri, None, 'statistics=(fast)') + self.assertEqual(c[stat.dsrc.cache_state_root_size][2], 0) + c.close() + + self.conn.reconfigure('statistics=(all,clear)') + c = self.session.open_cursor( + 'statistics:' + self.uri, None, 'statistics=(fast)') + self.assertEqual(c[stat.dsrc.cache_state_root_size][2], 0) + c.close() + + self.conn.reconfigure('statistics=(cache_walk,fast,clear)') + c = self.session.open_cursor('statistics:' + self.uri, None, None) + self.assertGreater(c[stat.dsrc.cache_state_root_size][2], 0) + # Verify that cache_walk didn't imply tree_walk + self.assertEqual(c[stat.dsrc.btree_entries][2], 0) + c.close() + + self.conn.reconfigure('statistics=(cache_walk,tree_walk,fast,clear)') + c = self.session.open_cursor('statistics:' + self.uri, None, None) + self.assertGreater(c[stat.dsrc.cache_state_root_size][2], 0) + # Verify that cache_walk didn't exclude tree_walk + self.assertGreater(c[stat.dsrc.btree_entries][2], 0) + c.close() + + self.conn.reconfigure('statistics=(all,clear)') + c = self.session.open_cursor( + 'statistics:' + self.uri, None, 'statistics=(all)') + self.assertGreater(c[stat.dsrc.cache_state_root_size][2], 0) + self.assertGreater(c[stat.dsrc.btree_entries][2], 0) + c.close() + + # Verify that cache and tree walk can operate independantly + self.conn.reconfigure('statistics=(all,clear)') + c = self.session.open_cursor( + 'statistics:' + self.uri, None, 'statistics=(cache_walk,fast)') + self.assertGreater(c[stat.dsrc.cache_state_root_size][2], 0) + self.assertEqual(c[stat.dsrc.btree_entries][2], 0) + c.close() + + self.conn.reconfigure('statistics=(all,clear)') + c = self.session.open_cursor( + 'statistics:' + self.uri, None, 'statistics=(tree_walk,fast)') + # Don't check the cache walk stats for empty - they won't be cleared + self.assertGreater(c[stat.dsrc.btree_entries][2], 0) + c.close() + if __name__ == '__main__': wttest.run() diff --git a/src/third_party/wiredtiger/test/thread/t.c b/src/third_party/wiredtiger/test/thread/t.c index 5b53532e8a6..baadbf2adb9 100644 --- a/src/third_party/wiredtiger/test/thread/t.c +++ b/src/third_party/wiredtiger/test/thread/t.c @@ -52,8 +52,6 @@ static void wt_shutdown(void); extern int __wt_optind; extern char *__wt_optarg; -void (*custom_die)(void) = NULL; - int main(int argc, char *argv[]) { diff --git a/src/third_party/wiredtiger/test/utility/misc.c b/src/third_party/wiredtiger/test/utility/misc.c index 096bc752726..1491c9a6938 100644 --- a/src/third_party/wiredtiger/test/utility/misc.c +++ b/src/third_party/wiredtiger/test/utility/misc.c @@ -27,6 +27,8 @@ */ #include "test_util.h" +void (*custom_die)(void) = NULL; + /* * die -- * Report an error and quit. @@ -142,8 +144,6 @@ testutil_cleanup(TEST_OPTS *opts) if (!opts->preserve) testutil_clean_work_dir(opts->home); - free(opts->conn_config); - free(opts->table_config); free(opts->uri); free(opts->home); } diff --git a/src/third_party/wiredtiger/test/utility/parse_opts.c b/src/third_party/wiredtiger/test/utility/parse_opts.c index 08aeafa9617..74a1c021d5d 100644 --- a/src/third_party/wiredtiger/test/utility/parse_opts.c +++ b/src/third_party/wiredtiger/test/utility/parse_opts.c @@ -27,10 +27,6 @@ */ #include "test_util.h" -extern int __wt_opterr; /* if error message should be printed */ -extern int __wt_optind; /* index into parent argv vector */ -extern int __wt_optopt; /* character checked for validity */ -extern int __wt_optreset; /* reset getopt */ extern char *__wt_optarg; /* argument associated with option */ /* @@ -59,7 +55,7 @@ testutil_parse_opts(int argc, char * const *argv, TEST_OPTS *opts) opts->n_append_threads = (uint64_t)atoll(__wt_optarg); break; case 'h': /* Home directory */ - opts->home = __wt_optarg; + opts->home = dstrdup(__wt_optarg); break; case 'n': /* Number of records */ opts->nrecords = (uint64_t)atoll(__wt_optarg); @@ -116,12 +112,14 @@ testutil_parse_opts(int argc, char * const *argv, TEST_OPTS *opts) } /* - * Setup the home directory. It needs to be unique for every test - * or the auto make parallel tester gets upset. + * Setup the home directory if not explicitly specified. It needs to be + * unique for every test or the auto make parallel tester gets upset. */ - len = strlen("WT_TEST.") + strlen(opts->progname) + 10; - opts->home = dmalloc(len); - snprintf(opts->home, len, "WT_TEST.%s", opts->progname); + if (opts->home == NULL) { + len = strlen("WT_TEST.") + strlen(opts->progname) + 10; + opts->home = dmalloc(len); + snprintf(opts->home, len, "WT_TEST.%s", opts->progname); + } /* Setup the default URI string */ len = strlen("table:") + strlen(opts->progname) + 10; diff --git a/src/third_party/wiredtiger/test/utility/test_util.h b/src/third_party/wiredtiger/test/utility/test_util.h index 1047d1ca8a0..f6a9cd68e02 100644 --- a/src/third_party/wiredtiger/test/utility/test_util.h +++ b/src/third_party/wiredtiger/test/utility/test_util.h @@ -68,10 +68,8 @@ typedef struct { * resources. */ WT_CONNECTION *conn; - char *conn_config; WT_SESSION *session; bool running; - char *table_config; char *uri; volatile uint64_t next_threadid; uint64_t max_inserted_id; @@ -86,6 +84,16 @@ typedef struct { testutil_die(0, "%s/%d: %s", __func__, __LINE__, #a); \ } while (0) +/* + * testutil_assertfmt -- + * Complain and quit if something isn't true. + */ +#define testutil_assertfmt(a, fmt, ...) do { \ + if (!(a)) \ + testutil_die(0, "%s/%d: %s: " fmt, \ + __func__, __LINE__, #a, __VA_ARGS__); \ +} while (0) + /* * testutil_check -- * Complain and quit if a function call fails. -- cgit v1.2.1