diff options
Diffstat (limited to 'src/third_party/wiredtiger/test')
32 files changed, 839 insertions, 237 deletions
diff --git a/src/third_party/wiredtiger/test/bloom/test_bloom.c b/src/third_party/wiredtiger/test/bloom/test_bloom.c index e9980cd53cb..9a7584f951f 100644 --- a/src/third_party/wiredtiger/test/bloom/test_bloom.c +++ b/src/third_party/wiredtiger/test/bloom/test_bloom.c @@ -50,7 +50,8 @@ void cleanup(void); void populate_entries(void); void run(void); void setup(void); -void usage(void); +void usage(void) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); extern char *__wt_optarg; extern int __wt_optind; diff --git a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c index 307cfd914bd..6293d36f916 100644 --- a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c +++ b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c @@ -32,7 +32,8 @@ GLOBAL g; static int handle_error(WT_EVENT_HANDLER *, WT_SESSION *, int, const char *); static int handle_message(WT_EVENT_HANDLER *, WT_SESSION *, const char *); -static void onint(int); +static void onint(int) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static int cleanup(void); static int usage(void); static int wt_connect(const char *); diff --git a/src/third_party/wiredtiger/test/csuite/Makefile.am b/src/third_party/wiredtiger/test/csuite/Makefile.am index 6058a05431b..f842bc1316f 100644 --- a/src/third_party/wiredtiger/test/csuite/Makefile.am +++ b/src/third_party/wiredtiger/test/csuite/Makefile.am @@ -13,6 +13,12 @@ noinst_PROGRAMS += test_wt2246_col_append test_wt2535_insert_race_SOURCES = wt2535_insert_race/main.c noinst_PROGRAMS += test_wt2535_insert_race +test_wt2447_join_main_table_SOURCES = wt2447_join_main_table/main.c +noinst_PROGRAMS += test_wt2447_join_main_table + +test_wt2592_join_schema_SOURCES = wt2592_join_schema/main.c +noinst_PROGRAMS += test_wt2592_join_schema + # Run this during a "make check" smoke test. TESTS = $(noinst_PROGRAMS) LOG_COMPILER = $(TEST_WRAPPER) 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 3ac96677ed0..798970cbb6d 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 @@ -45,7 +45,7 @@ void (*custom_die)(void) = NULL; /* Needs to be global for signal handling. */ -TEST_OPTS *opts, _opts; +static TEST_OPTS *opts, _opts; static void page_init(uint64_t n) 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 new file mode 100644 index 00000000000..a6f19cb0858 --- /dev/null +++ b/src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c @@ -0,0 +1,189 @@ +/*- + * 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" + +/* + * JIRA ticket reference: WT-2447 + * + * Test case description: This test case is adapted from the submitted test + * program in the JIRA ticket. We create a database of 10,000 entries, with + * every key i having pair of values (i, i). Create indices on both values, + * and establish a join: table.v1 >= 5000 AND table.v2 < 5001. There's a + * Bloom filter on v2. We expect that although we iterate from 5000 to + * 10000, we'll only have accesses to the main table for key 5000, as + * 5001-10000 will generally not be in the Bloom filter. For key 5000, + * we technically have two accesses to the main table - one occurs when we + * see key 5000 is in the Bloom filter, and we need to do a full test, we + * make an access to the projection table:tablename(v2), that's just to get + * the value of v2, which we'll check by comparison to the cursor at 5001. + * That counts as a main table access, and when we see it is satisfied and + * return the complete set of values, we'll access the main table with the + * full projection (that's the second main table access). + * + * Failure mode: Before fixes of WT-2447, we saw lots of accesses to the main + * table. + */ + +void (*custom_die)(void) = NULL; + +#define N_RECORDS 10000 + +static void +get_stat_total(WT_SESSION *session, WT_CURSOR *jcursor, const char *descmatch, + uint64_t *pval) +{ + WT_CURSOR *statcursor; + uint64_t val; + int ret; + bool match; + char *desc, *valstr; + + match = false; + *pval = 0; + testutil_check(session->open_cursor(session, "statistics:join", jcursor, + NULL, &statcursor)); + + while ((ret = statcursor->next(statcursor)) == 0) { + testutil_assert(statcursor->get_value( + statcursor, &desc, &valstr, &val) == 0); + + printf("statistics: %s: %s: %" PRIu64 "\n", desc, valstr, val); + + if (strstr(desc, descmatch) != NULL) { + *pval += val; + match = true; + } + } + testutil_assert(ret == WT_NOTFOUND); + testutil_check(statcursor->close(statcursor)); + testutil_assert(match); +} + +int +main(int argc, char *argv[]) +{ + TEST_OPTS *opts, _opts; + WT_CURSOR *cursor1, *cursor2, *jcursor; + WT_ITEM d; + WT_SESSION *session; + uint64_t maincount; + int half, i, j; + const char *tablename; + char bloom_cfg[128], index1uri[256], index2uri[256], joinuri[256]; + + opts = &_opts; + memset(opts, 0, sizeof(*opts)); + testutil_check(testutil_parse_opts(argc, argv, opts)); + testutil_make_work_dir(opts->home); + + tablename = strchr(opts->uri, ':'); + testutil_assert(tablename != NULL); + tablename++; + snprintf(index1uri, sizeof(index1uri), "index:%s:index1", tablename); + snprintf(index2uri, sizeof(index2uri), "index:%s:index2", tablename); + snprintf(joinuri, sizeof(joinuri), "join:%s", opts->uri); + + testutil_check(wiredtiger_open(opts->home, NULL, + "statistics=(all),create", &opts->conn)); + testutil_check( + opts->conn->open_session(opts->conn, NULL, NULL, &session)); + + testutil_check(session->create(session, opts->uri, + "key_format=i,value_format=iiu,columns=(k,v1,v2,d)")); + testutil_check(session->create(session, index1uri, "columns=(v1)")); + testutil_check(session->create(session, index2uri, "columns=(v2)")); + + testutil_check(session->open_cursor(session, opts->uri, NULL, NULL, + &cursor1)); + + d.size = 4100; + d.data = dmalloc(d.size); + memset((char *)d.data, 7, d.size); + + for (i = 0; i < N_RECORDS; ++i) + { + cursor1->set_key(cursor1, i); + cursor1->set_value(cursor1, i, i, &d); + testutil_check(cursor1->insert(cursor1)); + } + + free((void*)d.data); + + testutil_check(opts->conn->close(opts->conn, NULL)); + testutil_check(wiredtiger_open(opts->home, NULL, + "statistics=(all),create,cache_size=1GB", &opts->conn)); + testutil_check(opts->conn->open_session(opts->conn, NULL, NULL, + &session)); + + testutil_check(session->open_cursor(session, index1uri, NULL, NULL, + &cursor1)); + testutil_check(session->open_cursor(session, index2uri, NULL, NULL, + &cursor2)); + + half = N_RECORDS / 2; + cursor1->set_key(cursor1, half); + testutil_check(cursor1->search(cursor1)); + + cursor2->set_key(cursor2, half + 1); + testutil_check(cursor2->search(cursor2)); + + sprintf(bloom_cfg, "compare=lt,strategy=bloom,count=%d", half); + + testutil_check(session->open_cursor(session, joinuri, NULL, NULL, + &jcursor)); + testutil_check(session->join(session, jcursor, cursor1, "compare=ge")); + testutil_check(session->join(session, jcursor, cursor2, bloom_cfg)); + + /* Expect one value returned */ + testutil_assert(jcursor->next(jcursor) == 0); + i = 0; + testutil_assert(jcursor->get_key(jcursor, &i) == 0); + testutil_assert(i == (int)half); + i = j = 0; + memset(&d, 0, sizeof(d)); + testutil_assert(jcursor->get_value(jcursor, &i, &j, &d) == 0); + testutil_assert(i == (int)half); + testutil_assert(j == (int)half); + testutil_assert(d.size == 4100); + for (i = 0; i < 4100; i++) + testutil_assert(((char *)d.data)[i] == 7); + + testutil_assert(jcursor->next(jcursor) == WT_NOTFOUND); + + /* + * Make sure there have been 2 accesses to the main table, + * explained in the discussion above. + */ + get_stat_total(session, jcursor, "accesses to the main table", + &maincount); + testutil_assert(maincount == 2); + + testutil_cleanup(opts); + + return (0); +} 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 new file mode 100644 index 00000000000..4ffc9194646 --- /dev/null +++ b/src/third_party/wiredtiger/test/csuite/wt2592_join_schema/main.c @@ -0,0 +1,222 @@ +/*- + * 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" + +/* + * JIRA ticket reference: WT-2592 + * Test case description: This is an adaptation of the join parts of + * ex_schema.c, but written as a test. Though we have join tests in the + * Python test suite, the Python API uses raw mode for cursors, so errors + * that are specific to non-raw mode are undetected in Python. + * Failure mode: The failure seen in WT-2592 was that no items were returned + * by a join. + */ +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <wiredtiger.h> + +/* The C struct for the data we are storing in a WiredTiger table. */ +typedef struct { + char country[5]; + uint16_t year; + uint64_t population; +} POP_RECORD; + +static POP_RECORD pop_data[] = { + { "AU", 1900, 4000000 }, + { "AU", 1950, 8267337 }, + { "AU", 2000, 19053186 }, + { "CAN", 1900, 5500000 }, + { "CAN", 1950, 14011422 }, + { "CAN", 2000, 31099561 }, + { "UK", 1900, 369000000 }, + { "UK", 1950, 50127000 }, + { "UK", 2000, 59522468 }, + { "USA", 1900, 76212168 }, + { "USA", 1950, 150697361 }, + { "USA", 2000, 301279593 }, + { "", 0, 0 } +}; + +void (*custom_die)(void) = NULL; + +int +main(int argc, char *argv[]) +{ + POP_RECORD *p; + TEST_OPTS *opts, _opts; + WT_CURSOR *country_cursor, *country_cursor2, *cursor, *join_cursor, + *subjoin_cursor, *year_cursor; + WT_SESSION *session; + const char *country, *tablename; + char countryuri[256], joinuri[256], yearuri[256]; + uint64_t recno, population; + uint16_t year; + int count, ret; + + opts = &_opts; + memset(opts, 0, sizeof(*opts)); + testutil_check(testutil_parse_opts(argc, argv, opts)); + testutil_make_work_dir(opts->home); + + tablename = strchr(opts->uri, ':'); + testutil_assert(tablename != NULL); + tablename++; + snprintf(countryuri, sizeof(countryuri), "index:%s:country", tablename); + snprintf(yearuri, sizeof(yearuri), "index:%s:year", tablename); + snprintf(joinuri, sizeof(joinuri), "join:%s", opts->uri); + + 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(session->create(session, opts->uri, + "key_format=r," + "value_format=5sHQ," + "columns=(id,country,year,population)")); + + /* Create an index with a simple key. */ + testutil_check(session->create(session, + countryuri, "columns=(country)")); + + /* Create an immutable index. */ + testutil_check(session->create(session, + yearuri, "columns=(year),immutable")); + + /* Insert the records into the table. */ + testutil_check(session->open_cursor( + session, opts->uri, NULL, "append", &cursor)); + count = 1; + for (p = pop_data; p->year != 0; p++) { + cursor->set_key(cursor, count); + cursor->set_value(cursor, p->country, p->year, p->population); + testutil_check(cursor->insert(cursor)); + count++; + } + testutil_check(cursor->close(cursor)); + + /* Open cursors needed by the join. */ + testutil_check(session->open_cursor(session, + joinuri, NULL, NULL, &join_cursor)); + testutil_check(session->open_cursor(session, + countryuri, NULL, NULL, &country_cursor)); + testutil_check(session->open_cursor(session, + yearuri, NULL, NULL, &year_cursor)); + + /* select values WHERE country == "AU" AND year > 1900 */ + country_cursor->set_key(country_cursor, "AU\0\0\0"); + testutil_check(country_cursor->search(country_cursor)); + testutil_check(session->join(session, join_cursor, country_cursor, + "compare=eq,count=10")); + year_cursor->set_key(year_cursor, (uint16_t)1900); + testutil_check(year_cursor->search(year_cursor)); + testutil_check(session->join(session, join_cursor, year_cursor, + "compare=gt,count=10,strategy=bloom")); + + count = 0; + /* List the values that are joined */ + while ((ret = join_cursor->next(join_cursor)) == 0) { + testutil_check(join_cursor->get_key(join_cursor, &recno)); + testutil_check(join_cursor->get_value(join_cursor, &country, + &year, &population)); + printf("ID %" PRIu64, recno); + printf( + ": country %s, year %" PRIu16 ", population %" PRIu64 "\n", + country, year, population); + count++; + } + testutil_assert(ret == WT_NOTFOUND); + testutil_assert(count == 2); + + testutil_check(join_cursor->close(join_cursor)); + testutil_check(year_cursor->close(year_cursor)); + testutil_check(country_cursor->close(country_cursor)); + + /* Open cursors needed by the join. */ + testutil_check(session->open_cursor(session, + joinuri, NULL, NULL, &join_cursor)); + testutil_check(session->open_cursor(session, + joinuri, NULL, NULL, &subjoin_cursor)); + testutil_check(session->open_cursor(session, + countryuri, NULL, NULL, &country_cursor)); + testutil_check(session->open_cursor(session, + countryuri, NULL, NULL, &country_cursor2)); + testutil_check(session->open_cursor(session, + yearuri, NULL, NULL, &year_cursor)); + + /* + * select values WHERE (country == "AU" OR country == "UK") + * AND year > 1900 + * + * First, set up the join representing the country clause. + */ + country_cursor->set_key(country_cursor, "AU\0\0\0"); + testutil_check(country_cursor->search(country_cursor)); + testutil_check(session->join(session, subjoin_cursor, country_cursor, + "operation=or,compare=eq,count=10")); + country_cursor2->set_key(country_cursor2, "UK\0\0\0"); + testutil_check(country_cursor2->search(country_cursor2)); + testutil_check(session->join(session, subjoin_cursor, country_cursor2, + "operation=or,compare=eq,count=10")); + + /* Join that to the top join, and add the year clause */ + testutil_check(session->join(session, join_cursor, subjoin_cursor, + NULL)); + year_cursor->set_key(year_cursor, (uint16_t)1900); + testutil_check(year_cursor->search(year_cursor)); + testutil_check(session->join(session, join_cursor, year_cursor, + "compare=gt,count=10,strategy=bloom")); + + count = 0; + /* List the values that are joined */ + while ((ret = join_cursor->next(join_cursor)) == 0) { + testutil_check(join_cursor->get_key(join_cursor, &recno)); + testutil_check(join_cursor->get_value(join_cursor, &country, + &year, &population)); + printf("ID %" PRIu64, recno); + printf( + ": country %s, year %" PRIu16 ", population %" PRIu64 "\n", + country, year, population); + count++; + } + testutil_assert(ret == WT_NOTFOUND); + testutil_assert(count == 4); + + testutil_check(join_cursor->close(join_cursor)); + testutil_check(subjoin_cursor->close(subjoin_cursor)); + testutil_check(country_cursor->close(country_cursor)); + testutil_check(country_cursor2->close(country_cursor2)); + testutil_check(year_cursor->close(year_cursor)); + testutil_check(session->close(session, NULL)); + + testutil_cleanup(opts); + return (EXIT_SUCCESS); +} 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 d8cfc0c1421..aa351e6fea8 100644 --- a/src/third_party/wiredtiger/test/cursor_order/cursor_order.c +++ b/src/third_party/wiredtiger/test/cursor_order/cursor_order.c @@ -34,7 +34,8 @@ static FILE *logfp; /* Log file */ static int handle_error(WT_EVENT_HANDLER *, WT_SESSION *, int, const char *); static int handle_message(WT_EVENT_HANDLER *, WT_SESSION *, const char *); -static void onint(int); +static void onint(int) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void shutdown(void); static int usage(void); static void wt_connect(SHARED_CONFIG *, char *); diff --git a/src/third_party/wiredtiger/test/fops/t.c b/src/third_party/wiredtiger/test/fops/t.c index 24994404c7c..bf0588d5a53 100644 --- a/src/third_party/wiredtiger/test/fops/t.c +++ b/src/third_party/wiredtiger/test/fops/t.c @@ -41,7 +41,8 @@ static char home[512]; static int handle_error(WT_EVENT_HANDLER *, WT_SESSION *, int, const char *); static int handle_message(WT_EVENT_HANDLER *, WT_SESSION *, const char *); -static void onint(int); +static void onint(int) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void shutdown(void); static int usage(void); static void wt_startup(char *); diff --git a/src/third_party/wiredtiger/test/format/bdb.c b/src/third_party/wiredtiger/test/format/bdb.c index 48229cfd5e7..e56281f2c3e 100644 --- a/src/third_party/wiredtiger/test/format/bdb.c +++ b/src/third_party/wiredtiger/test/format/bdb.c @@ -106,9 +106,9 @@ bdb_insert( DBC *dbc; key.data = (void *)key_data; - key.size = (uint32_t)key_size; + key.size = (u_int32_t)key_size; value.data = (void *)value_data; - value.size = (uint32_t)value_size; + value.size = (u_int32_t)value_size; dbc = g.dbc; @@ -147,7 +147,7 @@ bdb_read(uint64_t keyno, void *valuep, size_t *valuesizep, int *notfoundp) key_gen(&keyitem, keyno); key.data = (void *)keyitem.data; - key.size = keyitem.size; + key.size = (u_int32_t)keyitem.size; *notfoundp = 0; if ((ret = dbc->get(dbc, &key, &value, DB_SET)) != 0) { @@ -169,9 +169,9 @@ bdb_update(const void *arg_key, size_t arg_key_size, int ret; key.data = (void *)arg_key; - key.size = (uint32_t)arg_key_size; + key.size = (u_int32_t)arg_key_size; value.data = (void *)arg_value; - value.size = (uint32_t)arg_value_size; + value.size = (u_int32_t)arg_value_size; if ((ret = dbc->put(dbc, &key, &value, DB_KEYFIRST)) != 0) testutil_die(ret, "dbc.put: DB_KEYFIRST: {%.*s}{%.*s}", @@ -188,10 +188,10 @@ bdb_remove(uint64_t keyno, int *notfoundp) key_gen(&keyitem, keyno); key.data = (void *)keyitem.data; - key.size = keyitem.size; + key.size = (u_int32_t)keyitem.size; bdb_read(keyno, &value.data, &size, notfoundp); - value.size = (uint32_t)size; + value.size = (u_int32_t)size; if (*notfoundp) return; diff --git a/src/third_party/wiredtiger/test/format/format.h b/src/third_party/wiredtiger/test/format/format.h index 8fd9b113311..ad5f408ac30 100644 --- a/src/third_party/wiredtiger/test/format/format.h +++ b/src/third_party/wiredtiger/test/format/format.h @@ -33,12 +33,6 @@ #include <db.h> #endif -#if defined(__GNUC__) -#define WT_GCC_ATTRIBUTE(x) __attribute__(x) -#else -#define WT_GCC_ATTRIBUTE(x) -#endif - #define EXTPATH "../../ext/" /* Extensions path */ #define LZ4_PATH \ @@ -266,7 +260,7 @@ typedef struct { #define TINFO_COMPLETE 2 /* Finished */ #define TINFO_JOINED 3 /* Resolved */ volatile int state; /* state */ -} TINFO WT_GCC_ATTRIBUTE((aligned(WT_CACHE_LINE_ALIGNMENT))); +} TINFO WT_COMPILER_TYPE_ALIGN(WT_CACHE_LINE_ALIGNMENT); #ifdef HAVE_BERKELEY_DB void bdb_close(void); diff --git a/src/third_party/wiredtiger/test/format/ops.c b/src/third_party/wiredtiger/test/format/ops.c index 7fd5563f486..c97d82809a1 100644 --- a/src/third_party/wiredtiger/test/format/ops.c +++ b/src/third_party/wiredtiger/test/format/ops.c @@ -1465,7 +1465,7 @@ print_item(const char *tag, WT_ITEM *item) static const char hex[] = "0123456789abcdef"; const uint8_t *data; size_t size; - int ch; + u_char ch; data = item->data; size = item->size; @@ -1476,8 +1476,8 @@ print_item(const char *tag, WT_ITEM *item) else for (; size > 0; --size, ++data) { ch = data[0]; - if (isprint(ch)) - fprintf(stderr, "%c", ch); + if (__wt_isprint(ch)) + fprintf(stderr, "%c", (int)ch); else fprintf(stderr, "%x%x", hex[(data[0] & 0xf0) >> 4], diff --git a/src/third_party/wiredtiger/test/format/t.c b/src/third_party/wiredtiger/test/format/t.c index 085163befe2..2eb2b078804 100644 --- a/src/third_party/wiredtiger/test/format/t.c +++ b/src/third_party/wiredtiger/test/format/t.c @@ -32,7 +32,8 @@ GLOBAL g; static void format_die(void); static void startup(void); -static void usage(void); +static void usage(void) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); extern int __wt_optind; extern char *__wt_optarg; diff --git a/src/third_party/wiredtiger/test/format/wts.c b/src/third_party/wiredtiger/test/format/wts.c index 2ee01aa75b5..69195abc3d4 100644 --- a/src/third_party/wiredtiger/test/format/wts.c +++ b/src/third_party/wiredtiger/test/format/wts.c @@ -87,10 +87,10 @@ handle_message(WT_EVENT_HANDLER *handler, /* Write and flush the message so we're up-to-date on error. */ if (g.logfp == NULL) { - out = printf("%p:%s\n", session, message); + out = printf("%p:%s\n", (void *)session, message); (void)fflush(stdout); } else { - out = fprintf(g.logfp, "%p:%s\n", session, message); + out = fprintf(g.logfp, "%p:%s\n", (void *)session, message); (void)fflush(g.logfp); } return (out < 0 ? EIO : 0); diff --git a/src/third_party/wiredtiger/test/huge/huge.c b/src/third_party/wiredtiger/test/huge/huge.c index 1e104a705f2..3aa61a9048e 100644 --- a/src/third_party/wiredtiger/test/huge/huge.c +++ b/src/third_party/wiredtiger/test/huge/huge.c @@ -65,13 +65,13 @@ static size_t lengths[] = { 0 }; +static void usage(void) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void usage(void) { fprintf(stderr, "usage: %s [-s]\n", progname); - fprintf(stderr, "%s", - "\t-s small run, only test up to 1GB\n"); - + fprintf(stderr, "%s", "\t-s small run, only test up to 1GB\n"); exit(EXIT_FAILURE); } diff --git a/src/third_party/wiredtiger/test/manydbs/manydbs.c b/src/third_party/wiredtiger/test/manydbs/manydbs.c index d9639198c34..e485e73067f 100644 --- a/src/third_party/wiredtiger/test/manydbs/manydbs.c +++ b/src/third_party/wiredtiger/test/manydbs/manydbs.c @@ -55,6 +55,8 @@ static const char * const uri = "table:main"; #define MAX_KV 100 #define MAX_VAL 128 +static void usage(void) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void usage(void) { @@ -68,10 +70,10 @@ extern char *__wt_optarg; void (*custom_die)(void) = NULL; -WT_CONNECTION **connections = NULL; -WT_CURSOR **cursors = NULL; -WT_RAND_STATE rnd; -WT_SESSION **sessions = NULL; +static WT_CONNECTION **connections = NULL; +static WT_CURSOR **cursors = NULL; +static WT_RAND_STATE rnd; +static WT_SESSION **sessions = NULL; static int get_stat(WT_SESSION *stat_session, int stat_field, uint64_t *valuep) diff --git a/src/third_party/wiredtiger/test/mciproject.yml b/src/third_party/wiredtiger/test/mciproject.yml index 9abdf23ec3b..3df1ce5805e 100644 --- a/src/third_party/wiredtiger/test/mciproject.yml +++ b/src/third_party/wiredtiger/test/mciproject.yml @@ -8,6 +8,14 @@ functions: command: git.get_project params: directory: wiredtiger + "fetch artifacts" : &fetch_artifacts + - command: s3.get + params: + aws_key: ${aws_key} + aws_secret: ${aws_secret} + remote_file: wiredtiger/${build_variant}/${revision}/artifacts/${build_id}.tgz + bucket: build_external + extract_to: wiredtiger pre: - command: shell.exec @@ -21,7 +29,9 @@ post: rm -rf "wiredtiger" tasks: - - name: compile-posix +## Base compile task on posix flavours + - name: compile + depends_on: [] commands: - func: "fetch source" - command: git.apply_patch @@ -33,36 +43,49 @@ tasks: script: | set -o errexit set -o verbose - - ./build_posix/reconf - ${configure_env_vars|} ./configure --enable-diagnostic --enable-python --enable-zlib - ${make_command|make} ${smp_command|} - ${make_command|make} check - - ${test_env_vars|} python ./test/suite/run.py -v 2 - - name: compile-windows - commands: - - func: "fetch source" - - command: git.apply_patch + if [ "Windows_NT" = "$OS" ]; then + scons.bat --enable-python=c:\\swigwin-3.0.2\\swig.exe --enable-diagnostic --enable-verbose ${smp_command|} + else + ./build_posix/reconf + ${configure_env_vars|} ./configure --enable-diagnostic --enable-python --enable-zlib --enable-strict --enable-verbose + ${make_command|make} ${smp_command|} 2>&1 + ${make_command|make} check 2>&1 + fi + - command: archive.targz_pack params: - directory: wiredtiger + target: "wiredtiger.tgz" + source_dir: "wiredtiger" + include: + - "./**" + - command: s3.put + params: + aws_secret: ${aws_secret} + aws_key: ${aws_key} + local_file: wiredtiger.tgz + bucket: build_external + permissions: public-read + content_type: application/tar + display_name: Artifacts + remote_file: wiredtiger/${build_variant}/${revision}/artifacts/${build_id}.tgz + + - name: unit-test + depends_on: + - name: compile + commands: + - func: "fetch artifacts" - command: shell.exec params: working_dir: "wiredtiger" script: | set -o errexit set -o verbose - - scons.bat --enable-python=c:\\swigwin-3.0.2\\swig.exe ${smp_command|} - - ${test_env_vars|} python ./test/suite/run.py -v 2 + ${test_env_vars|} python ./test/suite/run.py -v 2 ${smp_command|} 2>&1 - name: compile-windows-alt + depends_on: + - name: compile commands: - - func: "fetch source" - - command: git.apply_patch - params: - directory: wiredtiger + - func: "fetch artifacts" - command: shell.exec params: working_dir: "wiredtiger" @@ -72,22 +95,22 @@ tasks: scons.bat ${smp_command|} "CFLAGS=/Gv /wd4090 /wd4996 /we4047 /we4024 /TC /we4100" wiredtiger.dll libwiredtiger.lib - - name: fops-windows + - name: fops + depends_on: + - name: compile commands: - - func: "fetch source" - - command: git.apply_patch - params: - directory: wiredtiger + - func: "fetch artifacts" - command: shell.exec params: working_dir: "wiredtiger" script: | set -o errexit set -o verbose - - scons.bat --enable-python=c:\\swigwin-3.0.2\\swig.exe ${smp_command|} - - cmd.exe /c t_fops.exe + if [ "Windows_NT" = "$OS" ]; then + cmd.exe /c t_fops.exe + else + ./test/fops/t + fi buildvariants: - name: ubuntu1404 @@ -95,11 +118,14 @@ buildvariants: run_on: - ubuntu1404-test expansions: - test_env_vars: LD_LIBRARY_PATH=.libs - smp_command: -j$(grep -c ^processor /proc/cpuinfo) + # It's ugly, but we need the absolute path here, not the relative + test_env_vars: LD_LIBRARY_PATH=`pwd`/.libs + smp_command: -j $(grep -c ^processor /proc/cpuinfo) configure_env_vars: CC=/opt/mongodbtoolchain/bin/gcc CXX=/opt/mongodbtoolchain/bin/g++ tasks: - - name: compile-posix + - name: compile + - name: unit-test + - name: fops - name: solaris display_name: Solaris @@ -107,31 +133,34 @@ buildvariants: - solaris expansions: make_command: PATH=/opt/mongodbtoolchain/bin:$PATH gmake - test_env_vars: LD_LIBRARY_PATH=.libs - smp_command: -j$(kstat cpu | sort -u | grep -c "^module") + test_env_vars: LD_LIBRARY_PATH=`pwd`/.libs + smp_command: -j $(kstat cpu | sort -u | grep -c "^module") configure_env_vars: PATH=/opt/mongodbtoolchain/bin:$PATH CFLAGS="-m64" tasks: - - name: compile-posix + - name: compile + - name: unit-test + - name: fops - name: windows-64 display_name: Windows 64-bit run_on: - windows-64-vs2013-test - expansions: - smp_command: -j$(grep -c ^processor /proc/cpuinfo) tasks: - - name: compile-windows + - name: compile - name: compile-windows-alt - - name: fops-windows + - name: unit-test + - name: fops - name: osx-1010 display_name: OS X 10.10 run_on: - osx-1010 expansions: - smp_command: -j$(sysctl -n hw.logicalcpu) + 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=.libs + test_env_vars: DYLD_LIBRARY_PATH=`pwd`/.libs tasks: - - name: compile-posix + - name: compile + - name: unit-test + - name: fops diff --git a/src/third_party/wiredtiger/test/readonly/readonly.c b/src/third_party/wiredtiger/test/readonly/readonly.c index 402b99d7d29..31edc0d2a24 100644 --- a/src/third_party/wiredtiger/test/readonly/readonly.c +++ b/src/third_party/wiredtiger/test/readonly/readonly.c @@ -57,6 +57,8 @@ static const char * const uri = "table:main"; #define OP_READ 0 #define OP_WRITE 1 +static void usage(void) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void usage(void) { @@ -119,6 +121,9 @@ run_child(const char *homedir, int op, int expect) * Child process opens both databases readonly. */ static void +open_dbs(int, const char *, const char *, + const char *, const char *) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); +static void open_dbs(int op, const char *dir, const char *dir_wr, const char *dir_rd, const char *dir_rd2) { diff --git a/src/third_party/wiredtiger/test/recovery/random-abort.c b/src/third_party/wiredtiger/test/recovery/random-abort.c index 33597245966..85629eddec4 100644 --- a/src/third_party/wiredtiger/test/recovery/random-abort.c +++ b/src/third_party/wiredtiger/test/recovery/random-abort.c @@ -35,7 +35,11 @@ static char home[512]; /* Program working dir */ static const char *progname; /* Program name */ static const char * const uri = "table:main"; -#define RECORDS_FILE "records" +#define MAX_TH 12 +#define MIN_TH 5 +#define MAX_TIME 40 +#define MIN_TIME 10 +#define RECORDS_FILE "records-%" PRIu32 #define ENV_CONFIG \ "create,log=(file_max=10M,archive=false,enabled)," \ @@ -43,74 +47,67 @@ static const char * const uri = "table:main"; #define ENV_CONFIG_REC "log=(recover=on)" #define MAX_VAL 4096 +static void usage(void) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void usage(void) { - fprintf(stderr, "usage: %s [-h dir]\n", progname); + fprintf(stderr, "usage: %s [-h dir] [-T threads]\n", progname); exit(EXIT_FAILURE); } -/* - * Child process creates the database and table, and then writes data into - * the table until it is killed by the parent. - */ -static void -fill_db(void) +typedef struct { + WT_CONNECTION *conn; + uint64_t start; + uint32_t id; +} WT_THREAD_DATA; + +static void * +thread_run(void *arg) { FILE *fp; - WT_CONNECTION *conn; WT_CURSOR *cursor; WT_ITEM data; WT_RAND_STATE rnd; WT_SESSION *session; + WT_THREAD_DATA *td; uint64_t i; int ret; - uint8_t buf[MAX_VAL]; + char buf[MAX_VAL], kname[64]; __wt_random_init(&rnd); memset(buf, 0, sizeof(buf)); - /* - * Initialize the first 25% to random values. Leave a bunch of data - * space at the end to emphasize zero data. - */ - for (i = 0; i < MAX_VAL/4; i++) - buf[i] = (uint8_t)__wt_random(&rnd); + memset(kname, 0, sizeof(kname)); + td = (WT_THREAD_DATA *)arg; /* - * Run in the home directory so that the records file is in there too. + * The value is the name of the record file with our id appended. */ - if (chdir(home) != 0) - testutil_die(errno, "chdir: %s", home); - if ((ret = wiredtiger_open(NULL, NULL, ENV_CONFIG, &conn)) != 0) - testutil_die(ret, "wiredtiger_open"); - if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) - testutil_die(ret, "WT_CONNECTION:open_session"); - if ((ret = session->create(session, - uri, "key_format=Q,value_format=u")) != 0) - testutil_die(ret, "WT_SESSION.create: %s", uri); - if ((ret = - session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0) - testutil_die(ret, "WT_SESSION.open_cursor: %s", uri); - + snprintf(buf, sizeof(buf), RECORDS_FILE, td->id); /* * Keep a separate file with the records we wrote for checking. */ - (void)unlink(RECORDS_FILE); - if ((fp = fopen(RECORDS_FILE, "w")) == NULL) + (void)unlink(buf); + if ((fp = fopen(buf, "w")) == NULL) testutil_die(errno, "fopen"); /* * Set to no buffering. */ - __wt_stream_set_no_buffer(fp); - + __wt_stream_set_line_buffer(fp); + if ((ret = td->conn->open_session(td->conn, NULL, NULL, &session)) != 0) + testutil_die(ret, "WT_CONNECTION:open_session"); + if ((ret = + session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0) + testutil_die(ret, "WT_SESSION.open_cursor: %s", uri); + data.data = buf; + data.size = sizeof(buf); /* - * Write data into the table until we are killed by the parent. - * The data in the buffer is already set to random content. + * Write our portion of the key space until we're killed. */ - data.data = buf; - for (i = 0;; ++i) { + for (i = td->start; ; ++i) { + snprintf(kname, sizeof(kname), "%" PRIu64, i); data.size = __wt_random(&rnd) % MAX_VAL; - cursor->set_key(cursor, i); + cursor->set_key(cursor, kname); cursor->set_value(cursor, &data); if ((ret = cursor->insert(cursor)) != 0) testutil_die(ret, "WT_CURSOR.insert"); @@ -119,9 +116,63 @@ fill_db(void) */ if (fprintf(fp, "%" PRIu64 "\n", i) == -1) testutil_die(errno, "fprintf"); - if (i % 5000) - __wt_yield(); } + /* NOTREACHED */ +} + +/* + * Child process creates the database and table, and then creates worker + * threads to add data until it is killed by the parent. + */ +static void fill_db(uint32_t) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); +static void +fill_db(uint32_t nth) +{ + pthread_t *thr; + WT_CONNECTION *conn; + WT_SESSION *session; + WT_THREAD_DATA *td; + uint32_t i; + int ret; + + thr = dcalloc(nth, sizeof(pthread_t)); + td = dcalloc(nth, sizeof(WT_THREAD_DATA)); + if (chdir(home) != 0) + testutil_die(errno, "Child chdir: %s", home); + if ((ret = wiredtiger_open(NULL, NULL, ENV_CONFIG, &conn)) != 0) + testutil_die(ret, "wiredtiger_open"); + if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) + testutil_die(ret, "WT_CONNECTION:open_session"); + if ((ret = session->create(session, + uri, "key_format=S,value_format=u")) != 0) + testutil_die(ret, "WT_SESSION.create: %s", uri); + if ((ret = session->close(session, NULL)) != 0) + testutil_die(ret, "WT_SESSION:close"); + + 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].id = i; + if ((ret = pthread_create( + &thr[i], NULL, thread_run, &td[i])) != 0) + testutil_die(ret, "pthread_create"); + } + printf("Spawned %" PRIu32 " writer threads\n", nth); + fflush(stdout); + /* + * The threads never exit, so the child will just wait here until + * it is killed. + */ + for (i = 0; i < nth; ++i) + testutil_assert(pthread_join(thr[i], NULL) == 0); + /* + * NOTREACHED + */ + free(thr); + free(td); + exit(EXIT_SUCCESS); } extern int __wt_optind; @@ -138,26 +189,40 @@ main(int argc, char *argv[]) WT_SESSION *session; WT_RAND_STATE rnd; uint64_t key; - uint32_t absent, count, timeout; + uint32_t absent, count, i, nth, timeout; int ch, status, ret; pid_t pid; + bool rand_th, rand_time, verify_only; const char *working_dir; + char fname[64], kname[64]; if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL) progname = argv[0]; else ++progname; + nth = MIN_TH; + rand_th = rand_time = true; + timeout = MIN_TIME; + verify_only = false; working_dir = "WT_TEST.random-abort"; - timeout = 10; - while ((ch = __wt_getopt(progname, argc, argv, "h:t:")) != EOF) + + while ((ch = __wt_getopt(progname, argc, argv, "h:T:t:v")) != EOF) switch (ch) { case 'h': working_dir = __wt_optarg; break; + case 'T': + rand_th = false; + nth = (uint32_t)atoi(__wt_optarg); + break; case 't': + rand_time = false; timeout = (uint32_t)atoi(__wt_optarg); break; + case 'v': + verify_only = true; + break; default: usage(); } @@ -167,43 +232,68 @@ main(int argc, char *argv[]) usage(); testutil_work_dir_from_path(home, 512, working_dir); - testutil_make_work_dir(home); - /* - * Fork a child to insert as many items. We will then randomly - * kill the child, run recovery and make sure all items we wrote - * exist after recovery runs. + * If the user wants to verify they need to tell us how many threads + * there were so we can find the old record files. */ - if ((pid = fork()) < 0) - testutil_die(errno, "fork"); - - if (pid == 0) { /* child */ - fill_db(); - return (EXIT_SUCCESS); + if (verify_only && rand_th) { + fprintf(stderr, + "Verify option requires specifying number of threads\n"); + exit (EXIT_FAILURE); } + if (!verify_only) { + testutil_make_work_dir(home); - /* parent */ - __wt_random_init(&rnd); - /* Sleep for the configured amount of time before killing the child. */ - printf("Parent: sleep %" PRIu32 " seconds, then kill child\n", timeout); - sleep(timeout); + testutil_assert(__wt_random_init_seed(NULL, &rnd) == 0); + if (rand_time) { + timeout = __wt_random(&rnd) % MAX_TIME; + if (timeout < MIN_TIME) + timeout = MIN_TIME; + } + if (rand_th) { + nth = __wt_random(&rnd) % MAX_TH; + if (nth < MIN_TH) + nth = MIN_TH; + } + printf("Parent: Create %" PRIu32 + " threads; sleep %" PRIu32 " seconds\n", nth, timeout); + /* + * Fork a child to insert as many items. We will then randomly + * kill the child, run recovery and make sure all items we wrote + * exist after recovery runs. + */ + if ((pid = fork()) < 0) + testutil_die(errno, "fork"); - /* - * !!! It should be plenty long enough to make sure more than one - * log file exists. If wanted, that check would be added here. - */ - printf("Kill child\n"); - if (kill(pid, SIGKILL) != 0) - testutil_die(errno, "kill"); - if (waitpid(pid, &status, 0) == -1) - testutil_die(errno, "waitpid"); + if (pid == 0) { /* child */ + fill_db(nth); + return (EXIT_SUCCESS); + } + /* parent */ + /* + * Sleep for the configured amount of time before killing + * the child. + */ + sleep(timeout); + + /* + * !!! It should be plenty long enough to make sure more than + * one log file exists. If wanted, that check would be added + * here. + */ + printf("Kill child\n"); + if (kill(pid, SIGKILL) != 0) + testutil_die(errno, "kill"); + if (waitpid(pid, &status, 0) == -1) + testutil_die(errno, "waitpid"); + } /* * !!! If we wanted to take a copy of the directory before recovery, * this is the place to do it. */ if (chdir(home) != 0) - testutil_die(errno, "chdir: %s", home); + testutil_die(errno, "parent chdir: %s", home); printf("Open database, run recovery and verify content\n"); if ((ret = wiredtiger_open(NULL, NULL, ENV_CONFIG_REC, &conn)) != 0) testutil_die(ret, "wiredtiger_open"); @@ -213,30 +303,39 @@ main(int argc, char *argv[]) session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0) testutil_die(ret, "WT_SESSION.open_cursor: %s", uri); - if ((fp = fopen(RECORDS_FILE, "r")) == NULL) - testutil_die(errno, "fopen"); + absent = count = 0; + for (i = 0; i < nth; ++i) { + snprintf(fname, sizeof(fname), RECORDS_FILE, i); + if ((fp = fopen(fname, "r")) == NULL) { + fprintf(stderr, + "Failed to open %s. i %" PRIu32 "\n", fname, i); + testutil_die(errno, "fopen"); + } - /* - * For every key in the saved file, verify that the key exists - * in the table after recovery. Since we did write-no-sync, we - * expect every key to have been recovered. - */ - for (absent = count = 0;; ++count) { - ret = fscanf(fp, "%" SCNu64 "\n", &key); - if (ret != EOF && ret != 1) - testutil_die(errno, "fscanf"); - if (ret == EOF) - break; - cursor->set_key(cursor, key); - if ((ret = cursor->search(cursor)) != 0) { - if (ret != WT_NOTFOUND) - testutil_die(ret, "search"); - printf("no record with key %" PRIu64 "\n", key); - ++absent; + /* + * For every key in the saved file, verify that the key exists + * in the table after recovery. Since we did write-no-sync, we + * expect every key to have been recovered. + */ + for (;; ++count) { + ret = fscanf(fp, "%" SCNu64 "\n", &key); + if (ret != EOF && ret != 1) + testutil_die(errno, "fscanf"); + if (ret == EOF) + break; + snprintf(kname, sizeof(kname), "%" PRIu64, key); + cursor->set_key(cursor, kname); + if ((ret = cursor->search(cursor)) != 0) { + if (ret != WT_NOTFOUND) + testutil_die(ret, "search"); + printf("%s: no record with key %" PRIu64 "\n", + fname, key); + ++absent; + } } + if (fclose(fp) != 0) + testutil_die(errno, "fclose"); } - if (fclose(fp) != 0) - testutil_die(errno, "fclose"); if ((ret = conn->close(conn, NULL)) != 0) testutil_die(ret, "WT_CONNECTION:close"); if (absent) { diff --git a/src/third_party/wiredtiger/test/recovery/truncated-log.c b/src/third_party/wiredtiger/test/recovery/truncated-log.c index 3b99ea2c932..a7509c27566 100644 --- a/src/third_party/wiredtiger/test/recovery/truncated-log.c +++ b/src/third_party/wiredtiger/test/recovery/truncated-log.c @@ -50,6 +50,8 @@ static const char * const uri = "table:main"; #define K_SIZE 16 #define V_SIZE 256 +static void usage(void) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void usage(void) { @@ -61,6 +63,7 @@ usage(void) * Child process creates the database and table, and then writes data into * the table until it is killed by the parent. */ +static void fill_db(void)WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void fill_db(void) { diff --git a/src/third_party/wiredtiger/test/salvage/salvage.c b/src/third_party/wiredtiger/test/salvage/salvage.c index 497902e07b8..c3349188623 100644 --- a/src/third_party/wiredtiger/test/salvage/salvage.c +++ b/src/third_party/wiredtiger/test/salvage/salvage.c @@ -701,7 +701,7 @@ print_res(int key, int value, int cnt) switch (page_type) { /* Print value */ case WT_PAGE_COL_FIX: ch = value & 0x7f; - if (isprint(ch)) { + if (__wt_isprint((u_char)ch)) { if (ch == '\\') fputc('\\', res_fp); fputc(ch, res_fp); diff --git a/src/third_party/wiredtiger/test/suite/run.py b/src/third_party/wiredtiger/test/suite/run.py index f7f0d1399ff..6e7421b8b96 100644 --- a/src/third_party/wiredtiger/test/suite/run.py +++ b/src/third_party/wiredtiger/test/suite/run.py @@ -51,7 +51,7 @@ elif os.path.isfile(os.path.join(wt_disttop, 'wt.exe')): wt_builddir = wt_disttop else: print 'Unable to find useable WiredTiger build' - sys.exit(False) + sys.exit(1) # Cannot import wiredtiger and supporting utils until we set up paths # We want our local tree in front of any installed versions of WiredTiger. @@ -241,7 +241,7 @@ if __name__ == '__main__': if option == '-dir' or option == 'D': if dirarg != None or len(args) == 0: usage() - sys.exit(False) + sys.exit(2) dirarg = args.pop(0) continue if option == '-debug' or option == 'd': @@ -252,14 +252,14 @@ if __name__ == '__main__': continue if option == '-help' or option == 'h': usage() - sys.exit(True) + sys.exit(0) if option == '-long' or option == 'l': longtest = True continue if option == '-parallel' or option == 'j': if parallel != 0 or len(args) == 0: usage() - sys.exit(False) + sys.exit(2) parallel = int(args.pop(0)) continue if option == '-preserve' or option == 'p': @@ -271,7 +271,7 @@ if __name__ == '__main__': if option == '-verbose' or option == 'v': if len(args) == 0: usage() - sys.exit(False) + sys.exit(2) verbose = int(args.pop(0)) if verbose > 3: verbose = 3 @@ -281,19 +281,19 @@ if __name__ == '__main__': if option == '-config' or option == 'c': if configfile != None or len(args) == 0: usage() - sys.exit(False) + sys.exit(2) configfile = args.pop(0) continue if option == '-configcreate' or option == 'C': if configfile != None or len(args) == 0: usage() - sys.exit(False) + sys.exit(2) configfile = args.pop(0) configwrite = True continue print 'unknown arg: ' + arg usage() - sys.exit(False) + sys.exit(2) testargs.append(arg) # All global variables should be set before any test classes are loaded. @@ -318,4 +318,4 @@ if __name__ == '__main__': pdb.set_trace() result = wttest.runsuite(tests, parallel) - sys.exit(not result.wasSuccessful()) + sys.exit(0 if result.wasSuccessful() else 1) diff --git a/src/third_party/wiredtiger/test/suite/suite_subprocess.py b/src/third_party/wiredtiger/test/suite/suite_subprocess.py index df89d82e4c9..c56c8d8e933 100644 --- a/src/third_party/wiredtiger/test/suite/suite_subprocess.py +++ b/src/third_party/wiredtiger/test/suite/suite_subprocess.py @@ -117,13 +117,12 @@ 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 runWt(self, args, infilename=None, outfilename=None, errfilename=None, reopensession=True): - """ - Run the 'wt' process - """ + # Run the wt utility. + def runWt(self, args, infilename=None, + outfilename=None, errfilename=None, reopensession=True, failure=False): - # we close the connection to guarantee everything is - # flushed, and that we can open it from another process + # Close the connection to guarantee everything is flushed, and that + # we can open it from another process. self.close_conn() wtoutname = outfilename or "wt.out" @@ -141,14 +140,26 @@ class suite_subprocess: infilepart = "<" + infilename + " " print str(procargs) print "*********************************************" - print "**** Run 'wt' via: run " + " ".join(procargs[3:]) + infilepart + ">" + wtoutname + " 2>" + wterrname + print "**** Run 'wt' via: run " + \ + " ".join(procargs[3:]) + infilepart + \ + ">" + wtoutname + " 2>" + wterrname print "*********************************************" - subprocess.call(procargs) + returncode = subprocess.call(procargs) elif infilename: with open(infilename, "r") as wtin: - subprocess.call(procargs, stdin=wtin, stdout=wtout, stderr=wterr) + returncode = subprocess.call( + procargs, stdin=wtin, stdout=wtout, stderr=wterr) else: - subprocess.call(procargs, stdout=wtout, stderr=wterr) + returncode = subprocess.call( + procargs, stdout=wtout, stderr=wterr) + if failure: + self.assertNotEqual(returncode, 0, + 'expected failure: "' + \ + str(procargs) + '": exited ' + str(returncode)) + else: + self.assertEqual(returncode, 0, + 'expected success: "' + \ + str(procargs) + '": exited ' + str(returncode)) if errfilename == None: self.check_empty_file(wterrname) if outfilename == None: diff --git a/src/third_party/wiredtiger/test/suite/test_config04.py b/src/third_party/wiredtiger/test/suite/test_config04.py index 7186bc3a716..dffa7479f1b 100644 --- a/src/third_party/wiredtiger/test/suite/test_config04.py +++ b/src/third_party/wiredtiger/test/suite/test_config04.py @@ -26,7 +26,7 @@ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. -import os +import os, shutil import wiredtiger, wttest from wiredtiger import stat @@ -34,6 +34,7 @@ from wiredtiger import stat # Individually test config options class test_config04(wttest.WiredTigerTestCase): table_name1 = 'test_config04' + log1 = 'WiredTigerLog.0000000001' nentries = 100 K = 1024 @@ -86,6 +87,10 @@ class test_config04(wttest.WiredTigerTestCase): self.assertEqual(cursor[stat.conn.cache_bytes_max][2], size) cursor.close() + def common_log_test(self, path, dirname): + self.common_test('log=(archive=false,enabled,' + path + ')') + self.assertTrue(os.path.exists(dirname + os.sep + self.log1)) + def test_bad_config(self): msg = '/unknown configuration key/' self.assertRaisesWithMessage(wiredtiger.WiredTigerError, @@ -168,24 +173,46 @@ class test_config04(wttest.WiredTigerTestCase): self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.wiredtiger_open('.', '(create='), msg) - def test_session_max(self): - # Note: There isn't any direct way to know that this was set, - # but we'll have a separate functionality test to test for - # this indirectly. - self.common_test('session_max=99') - - def test_multiprocess(self): - self.common_test('multiprocess') - # TODO: how do we verify that it was set? - def test_error_prefix(self): self.common_test('error_prefix="MyOwnPrefix"') # TODO: how do we verify that it was set? def test_logging(self): - self.common_test('log=(enabled=true)') - # TODO: how do we verify that it was set? For this we could look - # for the existence of the log file in the home dir. + # Test variations on the log configuration. The log test takes + # a configuration string as the first arg and the directory pathname + # to confirm the existence of the log file. For now we're testing + # the log pathname only. + # + # Test the default in the home directory. + self.common_log_test('', '.') + self.conn.close() + + # Test a subdir of the home directory. + logdirname = 'logdir' + logdir = '.' + os.sep + logdirname + os.mkdir(logdir) + confstr = 'path=' + logdirname + self.common_log_test(confstr, logdir) + self.conn.close() + + # Test an absolute path directory. + if os.name == 'posix': + logdir = '/tmp/logdir' + os.mkdir(logdir) + confstr = 'path=' + logdir + self.common_log_test(confstr, logdir) + self.conn.close() + shutil.rmtree(logdir, ignore_errors=True) + + def test_multiprocess(self): + self.common_test('multiprocess') + # TODO: how do we verify that it was set? + + def test_session_max(self): + # Note: There isn't any direct way to know that this was set, + # but we'll have a separate functionality test to test for + # this indirectly. + self.common_test('session_max=99') def test_transactional(self): # Note: this will have functional tests in the future. diff --git a/src/third_party/wiredtiger/test/suite/test_dump.py b/src/third_party/wiredtiger/test/suite/test_dump.py index d0163066639..85196174c1b 100644 --- a/src/third_party/wiredtiger/test/suite/test_dump.py +++ b/src/third_party/wiredtiger/test/suite/test_dump.py @@ -143,8 +143,8 @@ class test_dump(wttest.WiredTigerTestCase, suite_subprocess): self.populate_check(self, uri, self.nentries) # Re-load the object again, but confirm -n (no overwrite) fails. - self.runWt(['-h', self.dir, - 'load', '-n', '-f', 'dump.out'], errfilename='errfile.out') + self.runWt(['-h', self.dir, 'load', '-n', '-f', 'dump.out'], + errfilename='errfile.out', failure=True) self.check_non_empty_file('errfile.out') # If there are indices, dump one of them and check the output. diff --git a/src/third_party/wiredtiger/test/suite/test_jsondump02.py b/src/third_party/wiredtiger/test/suite/test_jsondump02.py index 251237f3faf..50931f0f5e6 100644 --- a/src/third_party/wiredtiger/test/suite/test_jsondump02.py +++ b/src/third_party/wiredtiger/test/suite/test_jsondump02.py @@ -208,12 +208,16 @@ class test_jsondump02(wttest.WiredTigerTestCase, suite_subprocess): # this one should work self.load_json(self.table_uri2, - (('"key0" : "KEY002"', '"value0" : 345,\n"value1" : "str2"'),)) + (('"key0" : "KEY002"', '"value0" : 34,\n"value1" : "str2"'),)) # extraneous/missing space is okay self.load_json(self.table_uri2, ((' "key0"\n:\t"KEY003" ', - '"value0":456,"value1"\n\n\r\n:\t\n"str3"'),)) + '"value0":45,"value1"\n\n\r\n:\t\n"str3"'),)) + + table2_json = ( + ('"key0" : "KEY002"', '"value0" : 34,\n"value1" : "str2"'), + ('"key0" : "KEY003"', '"value0" : 45,\n"value1" : "str3"')) table3_json = ( ('"key0" : 1', '"value0" : "\\u0001\\u0002\\u0003"'), @@ -284,12 +288,11 @@ class test_jsondump02(wttest.WiredTigerTestCase, suite_subprocess): self.runWt(['load', '-jf', 'jsondump4.out']) self.session.drop(self.table_uri4) - # Note: only the first table is loaded. self.runWt(['load', '-jf', 'jsondump-all.out']) self.check_json(self.table_uri1, table1_json) - #self.check_json(self.table_uri2, table2_json) - #self.check_json(self.table_uri3, table3_json) - #self.check_json(self.table_uri4, table4_json) + self.check_json(self.table_uri2, table2_json) + self.check_json(self.table_uri3, table3_json) + self.check_json(self.table_uri4, table4_json) # Generate two byte keys that cover some range of byte values. # For simplicity, the keys are monotonically increasing. diff --git a/src/third_party/wiredtiger/test/suite/test_util02.py b/src/third_party/wiredtiger/test/suite/test_util02.py index 51e03d8d105..475e856052a 100644 --- a/src/third_party/wiredtiger/test/suite/test_util02.py +++ b/src/third_party/wiredtiger/test/suite/test_util02.py @@ -173,7 +173,7 @@ class test_load_commandline(wttest.WiredTigerTestCase, suite_subprocess): complex_populate(self, self.uri, "key_format=S,value_format=S", 20) self.runWt(["dump", self.uri], outfilename="dump.out") loadargs = ["load", "-f", "dump.out"] + args - self.runWt(loadargs, errfilename=errfile) + self.runWt(loadargs, errfilename=errfile, failure=fail) if fail: self.check_non_empty_file(errfile) else: @@ -181,23 +181,24 @@ class test_load_commandline(wttest.WiredTigerTestCase, suite_subprocess): # Empty arguments should suceed. def test_load_commandline_1(self): - self.load_commandline([], 0) + self.load_commandline([], False) # Arguments are in pairs. def test_load_commandline_2(self): - self.load_commandline(["table"], 1) - self.load_commandline([self.uri, "block_allocation=first", self.uri], 1) + self.load_commandline(["table"], True) + self.load_commandline( + [self.uri, "block_allocation=first", self.uri], True) # You can use short-hand URIs for a single object, but cannot match multiple # objects. def test_load_commandline_3(self): - self.load_commandline(["table", "block_allocation=first"], 0) - self.load_commandline(["colgroup", "block_allocation=first"], 1) + self.load_commandline(["table", "block_allocation=first"], False) + self.load_commandline(["colgroup", "block_allocation=first"], True) # You can't reference non-existent objects. def test_load_commandline_4(self): - self.load_commandline([self.uri, "block_allocation=first"], 0) - self.load_commandline(["table:bar", "block_allocation=first"], 1) + self.load_commandline([self.uri, "block_allocation=first"], False) + self.load_commandline(["table:bar", "block_allocation=first"], True) # You can specify multipleconfiguration arguments for the same object. def test_load_commandline_5(self): @@ -205,19 +206,19 @@ class test_load_commandline(wttest.WiredTigerTestCase, suite_subprocess): self.uri, "block_allocation=first", self.uri, "block_allocation=best", self.uri, "block_allocation=first", - self.uri, "block_allocation=best"], 0) + self.uri, "block_allocation=best"], False) # You can't modify a format. def test_load_commandline_6(self): - self.load_commandline(["table", "key_format=d"], 1) - self.load_commandline(["table", "value_format=d"], 1) + self.load_commandline(["table", "key_format=d"], True) + self.load_commandline(["table", "value_format=d"], True) # You can set the source or version, but it gets stripped; confirm the # attempt succeeds, so we know they configuration values are stripped. def test_load_commandline_7(self): - self.load_commandline(["table", "filename=bar"], 0) - self.load_commandline(["table", "source=bar"], 0) - self.load_commandline(["table", "version=(100,200)"], 0) + self.load_commandline(["table", "filename=bar"], False) + self.load_commandline(["table", "source=bar"], False) + self.load_commandline(["table", "version=(100,200)"], False) if __name__ == '__main__': diff --git a/src/third_party/wiredtiger/test/suite/test_util07.py b/src/third_party/wiredtiger/test/suite/test_util07.py index 2bbb40422bd..602ddbba5ff 100644 --- a/src/third_party/wiredtiger/test/suite/test_util07.py +++ b/src/third_party/wiredtiger/test/suite/test_util07.py @@ -71,7 +71,8 @@ class test_util07(wttest.WiredTigerTestCase, suite_subprocess): self.session.create('table:' + self.tablename, self.session_params) outfile = "readout.txt" errfile = "readerr.txt" - self.runWt(["read", 'table:' + self.tablename, 'NoMatch'], outfilename=outfile, errfilename=errfile) + self.runWt(["read", 'table:' + self.tablename, 'NoMatch'], + outfilename=outfile, errfilename=errfile, failure=True) self.check_empty_file(outfile) self.check_file_contains(errfile, 'NoMatch: not found\n') @@ -83,10 +84,12 @@ class test_util07(wttest.WiredTigerTestCase, suite_subprocess): self.populate(self.tablename) outfile = "readout.txt" errfile = "readerr.txt" - self.runWt(["read", 'table:' + self.tablename, 'KEY49'], outfilename=outfile, errfilename=errfile) + self.runWt(["read", 'table:' + self.tablename, 'KEY49'], + outfilename=outfile, errfilename=errfile) self.check_file_content(outfile, 'VAL49\n') self.check_empty_file(errfile) - self.runWt(["read", 'table:' + self.tablename, 'key49'], outfilename=outfile, errfilename=errfile) + self.runWt(["read", 'table:' + self.tablename, 'key49'], + outfilename=outfile, errfilename=errfile, failure=True) self.check_empty_file(outfile) self.check_file_contains(errfile, 'key49: not found\n') diff --git a/src/third_party/wiredtiger/test/suite/test_util12.py b/src/third_party/wiredtiger/test/suite/test_util12.py index e8226a3146c..f407c2ce7d6 100644 --- a/src/third_party/wiredtiger/test/suite/test_util12.py +++ b/src/third_party/wiredtiger/test/suite/test_util12.py @@ -57,7 +57,8 @@ class test_util12(wttest.WiredTigerTestCase, suite_subprocess): self.session.create('table:' + self.tablename, self.session_params) errfile = 'writeerr.txt' - self.runWt(['write', 'table:' + self.tablename], errfilename=errfile) + self.runWt(['write', 'table:' + self.tablename], + errfilename=errfile, failure=True) self.check_file_contains(errfile, 'usage:') def test_write_overwrite(self): @@ -82,7 +83,7 @@ class test_util12(wttest.WiredTigerTestCase, suite_subprocess): self.session.create('table:' + self.tablename, self.session_params) errfile = 'writeerr.txt' self.runWt(['write', 'table:' + self.tablename, - 'def', '456', 'abc'], errfilename=errfile) + 'def', '456', 'abc'], errfilename=errfile, failure=True) self.check_file_contains(errfile, 'usage:') diff --git a/src/third_party/wiredtiger/test/suite/test_verify.py b/src/third_party/wiredtiger/test/suite/test_verify.py index 5ce926027ef..28a66415b9d 100644 --- a/src/third_party/wiredtiger/test/suite/test_verify.py +++ b/src/third_party/wiredtiger/test/suite/test_verify.py @@ -151,7 +151,8 @@ class test_verify(wttest.WiredTigerTestCase, suite_subprocess): with self.open_and_position(self.tablename, 75) as f: for i in range(0, 4096): f.write(struct.pack('B', 0)) - self.runWt(["verify", "table:" + self.tablename], errfilename="verifyerr.out") + self.runWt(["verify", "table:" + self.tablename], + errfilename="verifyerr.out", failure=True) self.check_non_empty_file("verifyerr.out") def test_verify_process_25pct_junk(self): @@ -165,7 +166,8 @@ class test_verify(wttest.WiredTigerTestCase, suite_subprocess): with self.open_and_position(self.tablename, 25) as f: for i in range(0, 100): f.write('\x01\xff\x80') - self.runWt(["verify", "table:" + self.tablename], errfilename="verifyerr.out") + self.runWt(["verify", "table:" + self.tablename], + errfilename="verifyerr.out", failure=True) self.check_non_empty_file("verifyerr.out") def test_verify_process_truncated(self): @@ -178,7 +180,8 @@ class test_verify(wttest.WiredTigerTestCase, suite_subprocess): self.populate(self.tablename) with self.open_and_position(self.tablename, 75) as f: f.truncate(0) - self.runWt(["verify", "table:" + self.tablename], errfilename="verifyerr.out") + self.runWt(["verify", "table:" + self.tablename], + errfilename="verifyerr.out", failure=True) self.check_non_empty_file("verifyerr.out") def test_verify_process_zero_length(self): @@ -190,7 +193,8 @@ class test_verify(wttest.WiredTigerTestCase, suite_subprocess): self.populate(self.tablename) with self.open_and_position(self.tablename, 0) as f: f.truncate(0) - self.runWt(["verify", "table:" + self.tablename], errfilename="verifyerr.out") + self.runWt(["verify", "table:" + self.tablename], + errfilename="verifyerr.out", failure=True) self.check_non_empty_file("verifyerr.out") diff --git a/src/third_party/wiredtiger/test/suite/wttest.py b/src/third_party/wiredtiger/test/suite/wttest.py index f7a2a5c8890..9e430fcdba7 100644 --- a/src/third_party/wiredtiger/test/suite/wttest.py +++ b/src/third_party/wiredtiger/test/suite/wttest.py @@ -551,4 +551,4 @@ def runsuite(suite, parallel): def run(name='__main__'): result = runsuite(unittest.TestLoader().loadTestsFromName(name), False) - sys.exit(not result.wasSuccessful()) + sys.exit(0 if result.wasSuccessful() else 1) diff --git a/src/third_party/wiredtiger/test/thread/t.c b/src/third_party/wiredtiger/test/thread/t.c index 22334076ee1..5b53532e8a6 100644 --- a/src/third_party/wiredtiger/test/thread/t.c +++ b/src/third_party/wiredtiger/test/thread/t.c @@ -42,7 +42,8 @@ static FILE *logfp; /* Log file */ static int handle_error(WT_EVENT_HANDLER *, WT_SESSION *, int, const char *); static int handle_message(WT_EVENT_HANDLER *, WT_SESSION *, const char *); -static void onint(int); +static void onint(int) + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void shutdown(void); static int usage(void); static void wt_connect(char *); diff --git a/src/third_party/wiredtiger/test/utility/test_util.h b/src/third_party/wiredtiger/test/utility/test_util.h index 6417c5a326b..66ff8de2d19 100644 --- a/src/third_party/wiredtiger/test/utility/test_util.h +++ b/src/third_party/wiredtiger/test/utility/test_util.h @@ -109,10 +109,7 @@ typedef struct { extern void (*custom_die)(void); void testutil_die(int, const char *, ...) -#if defined(__GNUC__) -__attribute__((__noreturn__)) -#endif -; + WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); void *dcalloc(size_t, size_t); void *dmalloc(size_t); |