summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/bloom/test_bloom.c3
-rw-r--r--test/checkpoint/test_checkpoint.c3
-rw-r--r--test/csuite/Makefile.am6
-rw-r--r--test/csuite/wt2246_col_append/main.c2
-rw-r--r--test/csuite/wt2447_join_main_table/main.c189
-rw-r--r--test/csuite/wt2592_join_schema/main.c222
-rw-r--r--test/cursor_order/cursor_order.c3
-rw-r--r--test/fops/t.c3
-rw-r--r--test/format/bdb.c14
-rw-r--r--test/format/format.h8
-rw-r--r--test/format/ops.c6
-rw-r--r--test/format/t.c3
-rw-r--r--test/format/wts.c4
-rw-r--r--test/huge/huge.c6
-rw-r--r--test/manydbs/manydbs.c10
-rw-r--r--test/mciproject.yml115
-rw-r--r--test/readonly/readonly.c5
-rw-r--r--test/recovery/random-abort.c281
-rw-r--r--test/recovery/truncated-log.c3
-rw-r--r--test/salvage/salvage.c2
-rw-r--r--test/suite/run.py18
-rw-r--r--test/suite/suite_subprocess.py31
-rw-r--r--test/suite/test_config04.py55
-rw-r--r--test/suite/test_dump.py4
-rw-r--r--test/suite/test_jsondump02.py15
-rw-r--r--test/suite/test_util02.py29
-rw-r--r--test/suite/test_util07.py9
-rw-r--r--test/suite/test_util12.py5
-rw-r--r--test/suite/test_verify.py12
-rw-r--r--test/suite/wttest.py2
-rw-r--r--test/thread/t.c3
-rw-r--r--test/utility/test_util.h5
32 files changed, 839 insertions, 237 deletions
diff --git a/test/bloom/test_bloom.c b/test/bloom/test_bloom.c
index e9980cd53cb..9a7584f951f 100644
--- a/test/bloom/test_bloom.c
+++ b/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/test/checkpoint/test_checkpoint.c b/test/checkpoint/test_checkpoint.c
index 307cfd914bd..6293d36f916 100644
--- a/test/checkpoint/test_checkpoint.c
+++ b/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/test/csuite/Makefile.am b/test/csuite/Makefile.am
index 6058a05431b..f842bc1316f 100644
--- a/test/csuite/Makefile.am
+++ b/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/test/csuite/wt2246_col_append/main.c b/test/csuite/wt2246_col_append/main.c
index 3ac96677ed0..798970cbb6d 100644
--- a/test/csuite/wt2246_col_append/main.c
+++ b/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/test/csuite/wt2447_join_main_table/main.c b/test/csuite/wt2447_join_main_table/main.c
new file mode 100644
index 00000000000..a6f19cb0858
--- /dev/null
+++ b/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/test/csuite/wt2592_join_schema/main.c b/test/csuite/wt2592_join_schema/main.c
new file mode 100644
index 00000000000..4ffc9194646
--- /dev/null
+++ b/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/test/cursor_order/cursor_order.c b/test/cursor_order/cursor_order.c
index d8cfc0c1421..aa351e6fea8 100644
--- a/test/cursor_order/cursor_order.c
+++ b/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/test/fops/t.c b/test/fops/t.c
index 24994404c7c..bf0588d5a53 100644
--- a/test/fops/t.c
+++ b/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/test/format/bdb.c b/test/format/bdb.c
index 48229cfd5e7..e56281f2c3e 100644
--- a/test/format/bdb.c
+++ b/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/test/format/format.h b/test/format/format.h
index 8fd9b113311..ad5f408ac30 100644
--- a/test/format/format.h
+++ b/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/test/format/ops.c b/test/format/ops.c
index 7fd5563f486..c97d82809a1 100644
--- a/test/format/ops.c
+++ b/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/test/format/t.c b/test/format/t.c
index 085163befe2..2eb2b078804 100644
--- a/test/format/t.c
+++ b/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/test/format/wts.c b/test/format/wts.c
index 2ee01aa75b5..69195abc3d4 100644
--- a/test/format/wts.c
+++ b/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/test/huge/huge.c b/test/huge/huge.c
index 1e104a705f2..3aa61a9048e 100644
--- a/test/huge/huge.c
+++ b/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/test/manydbs/manydbs.c b/test/manydbs/manydbs.c
index d9639198c34..e485e73067f 100644
--- a/test/manydbs/manydbs.c
+++ b/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/test/mciproject.yml b/test/mciproject.yml
index 9abdf23ec3b..3df1ce5805e 100644
--- a/test/mciproject.yml
+++ b/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/test/readonly/readonly.c b/test/readonly/readonly.c
index 402b99d7d29..31edc0d2a24 100644
--- a/test/readonly/readonly.c
+++ b/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/test/recovery/random-abort.c b/test/recovery/random-abort.c
index 33597245966..85629eddec4 100644
--- a/test/recovery/random-abort.c
+++ b/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/test/recovery/truncated-log.c b/test/recovery/truncated-log.c
index 3b99ea2c932..a7509c27566 100644
--- a/test/recovery/truncated-log.c
+++ b/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/test/salvage/salvage.c b/test/salvage/salvage.c
index 497902e07b8..c3349188623 100644
--- a/test/salvage/salvage.c
+++ b/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/test/suite/run.py b/test/suite/run.py
index f7f0d1399ff..6e7421b8b96 100644
--- a/test/suite/run.py
+++ b/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/test/suite/suite_subprocess.py b/test/suite/suite_subprocess.py
index df89d82e4c9..c56c8d8e933 100644
--- a/test/suite/suite_subprocess.py
+++ b/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/test/suite/test_config04.py b/test/suite/test_config04.py
index 7186bc3a716..dffa7479f1b 100644
--- a/test/suite/test_config04.py
+++ b/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/test/suite/test_dump.py b/test/suite/test_dump.py
index d0163066639..85196174c1b 100644
--- a/test/suite/test_dump.py
+++ b/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/test/suite/test_jsondump02.py b/test/suite/test_jsondump02.py
index 251237f3faf..50931f0f5e6 100644
--- a/test/suite/test_jsondump02.py
+++ b/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/test/suite/test_util02.py b/test/suite/test_util02.py
index 51e03d8d105..475e856052a 100644
--- a/test/suite/test_util02.py
+++ b/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/test/suite/test_util07.py b/test/suite/test_util07.py
index 2bbb40422bd..602ddbba5ff 100644
--- a/test/suite/test_util07.py
+++ b/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/test/suite/test_util12.py b/test/suite/test_util12.py
index e8226a3146c..f407c2ce7d6 100644
--- a/test/suite/test_util12.py
+++ b/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/test/suite/test_verify.py b/test/suite/test_verify.py
index 5ce926027ef..28a66415b9d 100644
--- a/test/suite/test_verify.py
+++ b/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/test/suite/wttest.py b/test/suite/wttest.py
index f7a2a5c8890..9e430fcdba7 100644
--- a/test/suite/wttest.py
+++ b/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/test/thread/t.c b/test/thread/t.c
index 22334076ee1..5b53532e8a6 100644
--- a/test/thread/t.c
+++ b/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/test/utility/test_util.h b/test/utility/test_util.h
index 6417c5a326b..66ff8de2d19 100644
--- a/test/utility/test_util.h
+++ b/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);