summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/test
diff options
context:
space:
mode:
authorAlex Gorrod <alexander.gorrod@mongodb.com>2017-10-10 16:29:49 +1100
committerAlex Gorrod <alexander.gorrod@mongodb.com>2017-10-10 16:37:55 +1100
commit39998ac6928c4e7f3acd2f7ee2fc5fb4df056c18 (patch)
treec075233cd32c6ec0205af77db475836c0fba60e9 /src/third_party/wiredtiger/test
parentdd094ce1bc1fb424ccc6dd71939e5c7a30159e2e (diff)
downloadmongo-39998ac6928c4e7f3acd2f7ee2fc5fb4df056c18.tar.gz
Import wiredtiger: 0cd3d5bbd8a5c8779f1129c6754b4463403e788f from branch mongodb-3.6
ref: 6f561957cb..0cd3d5bbd8 for: 3.5.14 WT-3200 LSM bug: Failed lookup in bloom filter. WT-3435 Lookaside eviction should be able to save unstable updates WT-3453 Enhance lookaside table test coverage in Python suite WT-3559 Detect when a checkpoint races with metadata changes WT-3579 Enhance support for running wtperf workloads with workgen WT-3582 Cache stuck full of internal pages WT-3593 Add an API to enforce consistent use of timestamps (#3667) WT-3599 reconciliation calculates block matching checksums too frequently. WT-3600 timestamp API lets you set timestamps with invalid characters WT-3612 Improve documentation of durability with backup cursors WT-3613 test/format cache full with LSM WT-3618 WT remove solaris from evergreen builds WT-3620 POSIX thread attribute structures must be destroyed WT-3621 Add test for full backups with concurrent table creation WT-3622 Allow upper case hexadecimal timestamps WT-3627 test_txn14.test_txn14.test_log_flush timeout WT-3631 Convert timestamps to integers in Python tests before comparing WT-3636 Account for page image sizes in cache consistently WT-3638 format failure, update list without complete visible record WT-3639 Test/format tried to drop named checkpoints during a hot backup WT-3641 Track maximum timestamp used in each btree WT-3642 Avoid lookaside reads for dead trees
Diffstat (limited to 'src/third_party/wiredtiger/test')
-rw-r--r--src/third_party/wiredtiger/test/fops/file.c64
-rw-r--r--src/third_party/wiredtiger/test/fops/t.c13
-rw-r--r--src/third_party/wiredtiger/test/fops/thread.h1
-rw-r--r--src/third_party/wiredtiger/test/format/format.h1
-rw-r--r--src/third_party/wiredtiger/test/format/ops.c139
-rw-r--r--src/third_party/wiredtiger/test/format/t.c2
-rw-r--r--src/third_party/wiredtiger/test/format/util.c80
-rw-r--r--src/third_party/wiredtiger/test/mciproject.yml14
-rw-r--r--src/third_party/wiredtiger/test/suite/test_assert01.py114
-rw-r--r--src/third_party/wiredtiger/test/suite/test_assert02.py141
-rw-r--r--src/third_party/wiredtiger/test/suite/test_assert03.py86
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup07.py117
-rw-r--r--src/third_party/wiredtiger/test/suite/test_las.py88
-rw-r--r--src/third_party/wiredtiger/test/suite/test_timestamp01.py30
-rw-r--r--src/third_party/wiredtiger/test/suite/test_timestamp02.py12
-rw-r--r--src/third_party/wiredtiger/test/suite/test_timestamp03.py8
-rw-r--r--src/third_party/wiredtiger/test/suite/test_timestamp04.py7
-rw-r--r--src/third_party/wiredtiger/test/suite/test_timestamp05.py6
-rw-r--r--src/third_party/wiredtiger/test/suite/test_timestamp07.py41
-rw-r--r--src/third_party/wiredtiger/test/suite/test_timestamp09.py6
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn14.py9
-rw-r--r--src/third_party/wiredtiger/test/suite/wttest.py6
22 files changed, 800 insertions, 185 deletions
diff --git a/src/third_party/wiredtiger/test/fops/file.c b/src/third_party/wiredtiger/test/fops/file.c
index 60320ae3a38..118845ab805 100644
--- a/src/third_party/wiredtiger/test/fops/file.c
+++ b/src/third_party/wiredtiger/test/fops/file.c
@@ -39,6 +39,8 @@ obj_bulk(void)
testutil_check(conn->open_session(conn, NULL, NULL, &session));
+ if (use_txn)
+ testutil_check(session->begin_transaction(session, NULL));
if ((ret = session->create(session, uri, config)) != 0)
if (ret != EEXIST && ret != EBUSY)
testutil_die(ret, "session.create");
@@ -51,6 +53,21 @@ obj_bulk(void)
} else if (ret != ENOENT && ret != EBUSY && ret != EINVAL)
testutil_die(ret, "session.open_cursor bulk");
}
+
+ if (use_txn) {
+ /*
+ * As the operations are being performed concurrently,
+ * return value can be ENOENT, EBUSY or EINVAL will set
+ * error to transaction opened by session. In these
+ * cases the transaction has to be aborted.
+ */
+ if (ret != ENOENT && ret != EBUSY && ret != EINVAL)
+ ret = session->commit_transaction(session, NULL);
+ else
+ ret = session->rollback_transaction(session, NULL);
+ if (ret == EINVAL)
+ testutil_die(ret, "session.commit bulk");
+ }
testutil_check(session->close(session, NULL));
}
@@ -70,6 +87,8 @@ obj_bulk_unique(int force)
new_uri, sizeof(new_uri), "%s.%u", uri, ++uid));
testutil_check(pthread_rwlock_unlock(&single));
+ if (use_txn)
+ testutil_check(session->begin_transaction(session, NULL));
testutil_check(session->create(session, new_uri, config));
__wt_yield();
@@ -89,6 +108,10 @@ obj_bulk_unique(int force)
if (ret != EBUSY)
testutil_die(ret, "session.drop: %s", new_uri);
+ if (use_txn &&
+ (ret = session->commit_transaction(session, NULL)) != 0 &&
+ ret != EINVAL)
+ testutil_die(ret, "session.commit bulk unique");
testutil_check(session->close(session, NULL));
}
@@ -101,12 +124,19 @@ obj_cursor(void)
testutil_check(conn->open_session(conn, NULL, NULL, &session));
+ if (use_txn)
+ testutil_check(session->begin_transaction(session, NULL));
if ((ret =
session->open_cursor(session, uri, NULL, NULL, &cursor)) != 0) {
if (ret != ENOENT && ret != EBUSY)
testutil_die(ret, "session.open_cursor");
} else
testutil_check(cursor->close(cursor));
+
+ if (use_txn &&
+ (ret = session->commit_transaction(session, NULL)) != 0 &&
+ ret != EINVAL)
+ testutil_die(ret, "session.commit cursor");
testutil_check(session->close(session, NULL));
}
@@ -118,10 +148,16 @@ obj_create(void)
testutil_check(conn->open_session(conn, NULL, NULL, &session));
+ if (use_txn)
+ testutil_check(session->begin_transaction(session, NULL));
if ((ret = session->create(session, uri, config)) != 0)
if (ret != EEXIST && ret != EBUSY)
testutil_die(ret, "session.create");
+ if (use_txn &&
+ (ret = session->commit_transaction(session, NULL)) != 0 &&
+ ret != EINVAL)
+ testutil_die(ret, "session.commit create");
testutil_check(session->close(session, NULL));
}
@@ -140,13 +176,25 @@ obj_create_unique(int force)
new_uri, sizeof(new_uri), "%s.%u", uri, ++uid));
testutil_check(pthread_rwlock_unlock(&single));
+ if (use_txn)
+ testutil_check(session->begin_transaction(session, NULL));
testutil_check(session->create(session, new_uri, config));
+ if (use_txn &&
+ (ret = session->commit_transaction(session, NULL)) != 0 &&
+ ret != EINVAL)
+ testutil_die(ret, "session.commit create unique");
__wt_yield();
+ if (use_txn)
+ testutil_check(session->begin_transaction(session, NULL));
while ((ret = session->drop(
session, new_uri, force ? "force" : NULL)) != 0)
if (ret != EBUSY)
testutil_die(ret, "session.drop: %s", new_uri);
+ if (use_txn &&
+ (ret = session->commit_transaction(session, NULL)) != 0 &&
+ ret != EINVAL)
+ testutil_die(ret, "session.commit create unique");
testutil_check(session->close(session, NULL));
}
@@ -159,10 +207,26 @@ obj_drop(int force)
testutil_check(conn->open_session(conn, NULL, NULL, &session));
+ if (use_txn)
+ testutil_check(session->begin_transaction(session, NULL));
if ((ret = session->drop(session, uri, force ? "force" : NULL)) != 0)
if (ret != ENOENT && ret != EBUSY)
testutil_die(ret, "session.drop");
+ if (use_txn) {
+ /*
+ * As the operations are being performed concurrently,
+ * return value can be ENOENT or EBUSY will set
+ * error to transaction opened by session. In these
+ * cases the transaction has to be aborted.
+ */
+ if (ret != ENOENT && ret != EBUSY)
+ ret = session->commit_transaction(session, NULL);
+ else
+ ret = session->rollback_transaction(session, NULL);
+ if (ret == EINVAL)
+ testutil_die(ret, "session.commit drop");
+ }
testutil_check(session->close(session, NULL));
}
diff --git a/src/third_party/wiredtiger/test/fops/t.c b/src/third_party/wiredtiger/test/fops/t.c
index b6b80ba5db8..fcbbdcabd73 100644
--- a/src/third_party/wiredtiger/test/fops/t.c
+++ b/src/third_party/wiredtiger/test/fops/t.c
@@ -28,6 +28,7 @@
#include "thread.h"
+bool use_txn; /* Operations with user txn */
WT_CONNECTION *conn; /* WiredTiger connection */
pthread_rwlock_t single; /* Single thread */
u_int nops; /* Operations */
@@ -77,8 +78,9 @@ main(int argc, char *argv[])
nops = 1000;
nthreads = 10;
runs = 1;
+ use_txn = false;
config_open = working_dir = NULL;
- while ((ch = __wt_getopt(progname, argc, argv, "C:h:l:n:r:t:")) != EOF)
+ while ((ch = __wt_getopt(progname, argc, argv, "C:h:l:n:r:t:x")) != EOF)
switch (ch) {
case 'C': /* wiredtiger_open config */
config_open = __wt_optarg;
@@ -102,6 +104,9 @@ main(int argc, char *argv[])
case 't':
nthreads = (u_int)atoi(__wt_optarg);
break;
+ case 'x':
+ use_txn = true;
+ break;
default:
return (usage());
}
@@ -245,7 +250,8 @@ usage(void)
{
fprintf(stderr,
"usage: %s "
- "[-C wiredtiger-config] [-l log] [-n ops] [-r runs] [-t threads]\n",
+ "[-C wiredtiger-config] [-l log] [-n ops] [-r runs] [-t threads] "
+ "[-x] \n",
progname);
fprintf(stderr, "%s",
"\t-C specify wiredtiger_open configuration arguments\n"
@@ -253,6 +259,7 @@ usage(void)
"\t-l specify a log file\n"
"\t-n set number of operations each thread does\n"
"\t-r set number of runs\n"
- "\t-t set number of threads\n");
+ "\t-t set number of threads\n"
+ "\t-x operations within user transaction \n");
return (EXIT_FAILURE);
}
diff --git a/src/third_party/wiredtiger/test/fops/thread.h b/src/third_party/wiredtiger/test/fops/thread.h
index f6b6bdffd63..0df36025be0 100644
--- a/src/third_party/wiredtiger/test/fops/thread.h
+++ b/src/third_party/wiredtiger/test/fops/thread.h
@@ -30,6 +30,7 @@
#include <signal.h>
+extern bool use_txn; /* Operations with user txn */
extern WT_CONNECTION *conn; /* WiredTiger connection */
extern u_int nops; /* Operations per thread */
diff --git a/src/third_party/wiredtiger/test/format/format.h b/src/third_party/wiredtiger/test/format/format.h
index 81b7fa27f79..f35e71f58aa 100644
--- a/src/third_party/wiredtiger/test/format/format.h
+++ b/src/third_party/wiredtiger/test/format/format.h
@@ -287,6 +287,7 @@ void bdb_update(const void *, size_t, const void *, size_t);
WT_THREAD_RET alter(void *);
WT_THREAD_RET backup(void *);
+WT_THREAD_RET checkpoint(void *);
WT_THREAD_RET compact(void *);
void config_clear(void);
void config_error(void);
diff --git a/src/third_party/wiredtiger/test/format/ops.c b/src/third_party/wiredtiger/test/format/ops.c
index f4770465628..4fed18d12b4 100644
--- a/src/third_party/wiredtiger/test/format/ops.c
+++ b/src/third_party/wiredtiger/test/format/ops.c
@@ -76,7 +76,8 @@ wts_ops(int lastrun)
TINFO **tinfo_list, *tinfo, total;
WT_CONNECTION *conn;
WT_SESSION *session;
- wt_thread_t alter_tid, backup_tid, compact_tid, lrt_tid, timestamp_tid;
+ wt_thread_t alter_tid, backup_tid, checkpoint_tid, compact_tid, lrt_tid;
+ wt_thread_t timestamp_tid;
int64_t fourths, quit_fourths, thread_ops;
uint32_t i;
bool running;
@@ -86,6 +87,7 @@ wts_ops(int lastrun)
session = NULL; /* -Wconditional-uninitialized */
memset(&alter_tid, 0, sizeof(alter_tid));
memset(&backup_tid, 0, sizeof(backup_tid));
+ memset(&checkpoint_tid, 0, sizeof(checkpoint_tid));
memset(&compact_tid, 0, sizeof(compact_tid));
memset(&lrt_tid, 0, sizeof(lrt_tid));
memset(&timestamp_tid, 0, sizeof(timestamp_tid));
@@ -173,6 +175,9 @@ wts_ops(int lastrun)
if (g.c_backups)
testutil_check(
__wt_thread_create(NULL, &backup_tid, backup, NULL));
+ if (g.c_checkpoints)
+ testutil_check(__wt_thread_create(
+ NULL, &checkpoint_tid, checkpoint, NULL));
if (g.c_compact)
testutil_check(
__wt_thread_create(NULL, &compact_tid, compact, NULL));
@@ -247,6 +252,8 @@ wts_ops(int lastrun)
testutil_check(__wt_thread_join(NULL, alter_tid));
if (g.c_backups)
testutil_check(__wt_thread_join(NULL, backup_tid));
+ if (g.c_checkpoints)
+ testutil_check(__wt_thread_join(NULL, checkpoint_tid));
if (g.c_compact)
testutil_check(__wt_thread_join(NULL, compact_tid));
if (!SINGLETHREADED && g.c_long_running_txn)
@@ -514,12 +521,11 @@ ops(void *arg)
WT_DECL_RET;
WT_ITEM *key, _key, *value, _value;
WT_SESSION *session;
- uint64_t ckpt_op, keyno, reset_op, session_op;
+ uint64_t keyno, reset_op, session_op;
uint32_t rnd;
u_int i, iso_config;
int dir;
- char *ckpt_config, ckpt_name[64];
- bool ckpt_available, intxn, positioned, readonly;
+ bool intxn, positioned, readonly;
tinfo = arg;
@@ -542,58 +548,61 @@ ops(void *arg)
session = NULL;
session_op = 0;
- /* Set the first operation where we'll perform checkpoint operations. */
- ckpt_op = g.c_checkpoints ? mmrand(&tinfo->rnd, 100, 10000) : 0;
- ckpt_available = false;
-
/* Set the first operation where we'll reset the session. */
reset_op = mmrand(&tinfo->rnd, 100, 10000);
for (intxn = false; !tinfo->quit; ++tinfo->ops) {
- /*
- * We can't checkpoint or swap sessions/cursors while in a
- * transaction, resolve any running transaction.
- */
- if (intxn &&
- (tinfo->ops == ckpt_op || tinfo->ops == session_op)) {
- commit_transaction(tinfo, session);
- intxn = false;
- }
-
- /* Open up a new session and cursors. */
- if (tinfo->ops == session_op ||
+ /* Periodically open up a new session and cursors. */
+ if (tinfo->ops > session_op ||
session == NULL || cursor == NULL) {
+ /*
+ * We can't swap sessions/cursors if in a transaction,
+ * resolve any running transaction.
+ */
+ if (intxn) {
+ commit_transaction(tinfo, session);
+ intxn = false;
+ }
+
if (session != NULL)
testutil_check(session->close(session, NULL));
-
testutil_check(
conn->open_session(conn, NULL, NULL, &session));
+ /* Pick the next session/cursor close/open. */
+ session_op += mmrand(&tinfo->rnd, 100, 5000);
+
/*
* 10% of the time, perform some read-only operations
* from a checkpoint.
*
- * Skip that if we are single-threaded and doing checks
- * against a Berkeley DB database, because that won't
- * work because the Berkeley DB database records won't
- * match the checkpoint. Also skip if we are using
- * LSM, because it doesn't support reads from
- * checkpoints.
+ * Skip if single-threaded and doing checks against a
+ * Berkeley DB database, that won't work because the
+ * Berkeley DB database won't match the checkpoint.
+ *
+ * Skip if we are using data-sources or LSM, they don't
+ * support reading from checkpoints.
*/
- if (!SINGLETHREADED && !DATASOURCE("lsm") &&
- ckpt_available && mmrand(&tinfo->rnd, 1, 10) == 1) {
+ if (!SINGLETHREADED && !DATASOURCE("helium") &&
+ !DATASOURCE("kvsbdb") && !DATASOURCE("lsm") &&
+ mmrand(&tinfo->rnd, 1, 10) == 1) {
/*
* open_cursor can return EBUSY if concurrent
* with a metadata operation, retry.
*/
while ((ret = session->open_cursor(session,
- g.uri, NULL, ckpt_name, &cursor)) == EBUSY)
+ g.uri, NULL,
+ "checkpoint=WiredTigerCheckpoint",
+ &cursor)) == EBUSY)
__wt_yield();
+ /*
+ * If the checkpoint hasn't been created yet,
+ * ignore the error.
+ */
+ if (ret == ENOENT)
+ continue;
testutil_check(ret);
- /* Pick the next session/cursor close/open. */
- session_op += 250;
-
/* Checkpoints are read-only. */
readonly = true;
} else {
@@ -608,75 +617,11 @@ ops(void *arg)
__wt_yield();
testutil_check(ret);
- /* Pick the next session/cursor close/open. */
- session_op += mmrand(&tinfo->rnd, 100, 5000);
-
/* Updates supported. */
readonly = false;
}
}
- /* Checkpoint the database. */
- if (tinfo->ops == ckpt_op && g.c_checkpoints) {
- /*
- * Checkpoints are single-threaded inside WiredTiger,
- * skip our checkpoint if another thread is already
- * doing one.
- */
- ret = pthread_rwlock_trywrlock(&g.checkpoint_lock);
- if (ret == EBUSY)
- goto skip_checkpoint;
- testutil_check(ret);
-
- /*
- * LSM and data-sources don't support named checkpoints
- * and we can't drop a named checkpoint while there's a
- * backup in progress, otherwise name the checkpoint 5%
- * of the time.
- */
- if (mmrand(&tinfo->rnd, 1, 20) != 1 ||
- DATASOURCE("helium") ||
- DATASOURCE("kvsbdb") || DATASOURCE("lsm") ||
- pthread_rwlock_trywrlock(&g.backup_lock) == EBUSY)
- ckpt_config = NULL;
- else {
- testutil_check(__wt_snprintf(
- ckpt_name, sizeof(ckpt_name),
- "name=thread-%d", tinfo->id));
- ckpt_config = ckpt_name;
- }
-
- ret = session->checkpoint(session, ckpt_config);
- /*
- * We may be trying to create a named checkpoint while
- * we hold a cursor open to the previous checkpoint.
- * Tolerate EBUSY.
- */
- if (ret != 0 && ret != EBUSY)
- testutil_die(ret, "%s",
- ckpt_config == NULL ? "" : ckpt_config);
- ret = 0;
-
- if (ckpt_config != NULL)
- testutil_check(
- pthread_rwlock_unlock(&g.backup_lock));
- testutil_check(
- pthread_rwlock_unlock(&g.checkpoint_lock));
-
- /* Rephrase the checkpoint name for cursor open. */
- if (ckpt_config == NULL)
- strcpy(ckpt_name,
- "checkpoint=WiredTigerCheckpoint");
- else
- testutil_check(__wt_snprintf(
- ckpt_name, sizeof(ckpt_name),
- "checkpoint=thread-%d", tinfo->id));
- ckpt_available = true;
-
-skip_checkpoint: /* Pick the next checkpoint operation. */
- ckpt_op += mmrand(&tinfo->rnd, 5000, 20000);
- }
-
/*
* Reset the session every now and then, just to make sure that
* operation gets tested. Note the test is not for equality, we
diff --git a/src/third_party/wiredtiger/test/format/t.c b/src/third_party/wiredtiger/test/format/t.c
index dc288ba4bc2..02ed0a2da60 100644
--- a/src/third_party/wiredtiger/test/format/t.c
+++ b/src/third_party/wiredtiger/test/format/t.c
@@ -169,7 +169,6 @@ main(int argc, char *argv[])
*/
testutil_check(pthread_rwlock_init(&g.append_lock, NULL));
testutil_check(pthread_rwlock_init(&g.backup_lock, NULL));
- testutil_check(pthread_rwlock_init(&g.checkpoint_lock, NULL));
testutil_check(pthread_rwlock_init(&g.death_lock, NULL));
printf("%s: process %" PRIdMAX "\n", progname, (intmax_t)getpid());
@@ -267,7 +266,6 @@ main(int argc, char *argv[])
testutil_check(pthread_rwlock_destroy(&g.append_lock));
testutil_check(pthread_rwlock_destroy(&g.backup_lock));
- testutil_check(pthread_rwlock_destroy(&g.checkpoint_lock));
testutil_check(pthread_rwlock_destroy(&g.death_lock));
config_clear();
diff --git a/src/third_party/wiredtiger/test/format/util.c b/src/third_party/wiredtiger/test/format/util.c
index 98af8e766f1..9ea44a29801 100644
--- a/src/third_party/wiredtiger/test/format/util.c
+++ b/src/third_party/wiredtiger/test/format/util.c
@@ -501,6 +501,86 @@ fclose_and_clear(FILE **fpp)
}
/*
+ * checkpoint --
+ * Periodically take a checkpoint
+ */
+WT_THREAD_RET
+checkpoint(void *arg)
+{
+ WT_CONNECTION *conn;
+ WT_DECL_RET;
+ WT_SESSION *session;
+ u_int secs;
+ const char *ckpt_config;
+ char config_buf[64];
+ bool backup_locked;
+
+ (void)arg;
+ conn = g.wts_conn;
+ testutil_check(conn->open_session(conn, NULL, NULL, &session));
+
+ for (secs = mmrand(NULL, 1, 10); !g.workers_finished;) {
+ if (secs > 0) {
+ __wt_sleep(1, 0);
+ --secs;
+ continue;
+ }
+
+ /*
+ * LSM and data-sources don't support named checkpoints. Also,
+ * don't attempt named checkpoints during a hot backup. It's
+ * OK to create named checkpoints during a hot backup, but we
+ * can't delete them, so repeating an already existing named
+ * checkpoint will fail when we can't drop the previous one.
+ */
+ ckpt_config = NULL;
+ backup_locked = false;
+ if (!DATASOURCE("helium") && !DATASOURCE("kvsbdb") &&
+ !DATASOURCE("lsm"))
+ switch (mmrand(NULL, 1, 20)) {
+ case 1:
+ /*
+ * 5% create a named snapshot. Rotate between a
+ * few names to test multiple named snapshots in
+ * the system.
+ */
+ ret = pthread_rwlock_trywrlock(&g.backup_lock);
+ if (ret == 0) {
+ backup_locked = true;
+ testutil_check(__wt_snprintf(
+ config_buf, sizeof(config_buf),
+ "name=mine.%" PRIu32,
+ mmrand(NULL, 1, 4)));
+ ckpt_config = config_buf;
+ } else if (ret != EBUSY)
+ testutil_check(ret);
+ break;
+ case 2:
+ /*
+ * 5% drop all named snapshots.
+ */
+ ret = pthread_rwlock_trywrlock(&g.backup_lock);
+ if (ret == 0) {
+ backup_locked = true;
+ ckpt_config = "drop=(all)";
+ } else if (ret != EBUSY)
+ testutil_check(ret);
+ break;
+ }
+
+ testutil_check(session->checkpoint(session, ckpt_config));
+
+ if (backup_locked)
+ testutil_check(pthread_rwlock_unlock(&g.backup_lock));
+
+ secs = mmrand(NULL, 5, 40);
+ }
+
+ testutil_check(session->close(session, NULL));
+ return (WT_THREAD_RET_VALUE);
+}
+
+/*
* timestamp --
* Periodically update the oldest timestamp.
*/
diff --git a/src/third_party/wiredtiger/test/mciproject.yml b/src/third_party/wiredtiger/test/mciproject.yml
index 72022fe46ec..4b67299d14c 100644
--- a/src/third_party/wiredtiger/test/mciproject.yml
+++ b/src/third_party/wiredtiger/test/mciproject.yml
@@ -167,20 +167,6 @@ buildvariants:
- name: unit-test
- name: fops
-- name: solaris
- display_name: Solaris
- run_on:
- - solaris
- expansions:
- make_command: PATH=/opt/mongodbtoolchain/bin:$PATH gmake
- 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
- - name: unit-test
- - name: fops
-
- name: windows-64
display_name: Windows 64-bit
run_on:
diff --git a/src/third_party/wiredtiger/test/suite/test_assert01.py b/src/third_party/wiredtiger/test/suite/test_assert01.py
new file mode 100644
index 00000000000..3a4f8e4127a
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_assert01.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2017 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.
+#
+# test_assert01.py
+# Timestamps: assert commit settings
+#
+
+from suite_subprocess import suite_subprocess
+import wiredtiger, wttest
+
+def timestamp_str(t):
+ return '%x' % t
+
+class test_assert01(wttest.WiredTigerTestCase, suite_subprocess):
+ base = 'assert01'
+ base_uri = 'file:' + base
+ uri_always = base_uri + '.always.wt'
+ uri_def = base_uri + '.def.wt'
+ uri_never = base_uri + '.never.wt'
+ uri_none = base_uri + '.none.wt'
+ cfg = 'key_format=S,value_format=S,'
+ cfg_always = 'assert=(commit_timestamp=always)'
+ cfg_def = ''
+ cfg_never = 'assert=(commit_timestamp=never)'
+ cfg_none = 'assert=(commit_timestamp=none)'
+
+ count = 1
+ #
+ # Commit a k/v pair making sure that it detects an error if needed, when
+ # used with and without a commit timestamp.
+ #
+ def insert_check(self, uri, use_ts):
+ c = self.session.open_cursor(uri)
+ key = 'key' + str(self.count)
+ val = 'value' + str(self.count)
+
+ # Commit with a timestamp
+ self.session.begin_transaction()
+ self.session.timestamp_transaction(
+ 'commit_timestamp=' + timestamp_str(self.count))
+ c[key] = val
+ # All settings other than never should commit successfully
+ if (use_ts != 'never'):
+ self.session.commit_transaction()
+ else:
+ msg = "/timestamp set on this transaction/"
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda:self.assertEquals(self.session.commit_transaction(),
+ 0), msg)
+ c.close()
+ self.count += 1
+
+ # Commit without a timestamp
+ key = 'key' + str(self.count)
+ val = 'value' + str(self.count)
+ c = self.session.open_cursor(uri)
+ self.session.begin_transaction()
+ c[key] = val
+ # All settings other than always should commit successfully
+ if (use_ts != 'always'):
+ self.session.commit_transaction()
+ else:
+ msg = "/none set on this transaction/"
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda:self.assertEquals(self.session.commit_transaction(),
+ 0), msg)
+ self.count += 1
+ c.close()
+
+ def test_commit_timestamp(self):
+ #if not wiredtiger.timestamp_build() or not wiredtiger.diagnostic_build():
+ # self.skipTest('requires a timestamp and diagnostic build')
+ if not wiredtiger.timestamp_build():
+ self.skipTest('requires a timestamp build')
+
+ # Create a data item at a timestamp
+ self.session.create(self.uri_always, self.cfg + self.cfg_always)
+ self.session.create(self.uri_def, self.cfg + self.cfg_def)
+ self.session.create(self.uri_never, self.cfg + self.cfg_never)
+ self.session.create(self.uri_none, self.cfg + self.cfg_none)
+
+ # Check inserting into each table
+ self.insert_check(self.uri_always, 'always')
+ self.insert_check(self.uri_def, 'none')
+ self.insert_check(self.uri_never, 'never')
+ self.insert_check(self.uri_none, 'none')
+
+if __name__ == '__main__':
+ wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_assert02.py b/src/third_party/wiredtiger/test/suite/test_assert02.py
new file mode 100644
index 00000000000..d264273c3a0
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_assert02.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2017 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.
+#
+# test_assert02.py
+# Timestamps: assert read timestamp settings
+#
+
+from suite_subprocess import suite_subprocess
+import wiredtiger, wttest
+
+def timestamp_str(t):
+ return '%x' % t
+
+class test_assert02(wttest.WiredTigerTestCase, suite_subprocess):
+ def test_read_timestamp(self):
+ #if not wiredtiger.timestamp_build() or not wiredtiger.diagnostic_build():
+ # self.skipTest('requires a timestamp and diagnostic build')
+ if not wiredtiger.timestamp_build():
+ self.skipTest('requires a timestamp build')
+
+ base = 'assert02.'
+ base_uri = 'file:' + base
+ uri_always = base_uri + '.always.wt'
+ uri_def = base_uri + '.def.wt'
+ uri_never = base_uri + '.never.wt'
+ uri_none = base_uri + '.none.wt'
+
+ cfg = 'key_format=S,value_format=S'
+ cfg_always = cfg + ',assert=(read_timestamp=always)'
+ cfg_def = cfg
+ cfg_never = cfg + ',assert=(read_timestamp=never)'
+ cfg_none = cfg + ',assert=(read_timestamp=none)'
+
+ # Create a data item at a timestamp
+ self.session.create(uri_always, cfg_always)
+ self.session.create(uri_def, cfg_def)
+ self.session.create(uri_never, cfg_never)
+ self.session.create(uri_none, cfg_none)
+
+ # Insert a data item at timestamp 1. This should work for all.
+ c_always = self.session.open_cursor(uri_always)
+ c_def = self.session.open_cursor(uri_def)
+ c_never = self.session.open_cursor(uri_never)
+ c_none = self.session.open_cursor(uri_none)
+ self.session.begin_transaction()
+ self.session.timestamp_transaction(
+ 'commit_timestamp=' + timestamp_str(1))
+ c_always['key1'] = 'value1'
+ c_def['key1'] = 'value1'
+ c_never['key1'] = 'value1'
+ c_none['key1'] = 'value1'
+ self.session.commit_transaction()
+ c_always.close()
+ c_def.close()
+ c_never.close()
+ c_none.close()
+
+ # Now that we have a timestamped data, try reading with and without
+ # the timestamp.
+ c_always = self.session.open_cursor(uri_always)
+ c_def = self.session.open_cursor(uri_def)
+ c_never = self.session.open_cursor(uri_never)
+ c_none = self.session.open_cursor(uri_none)
+
+ c_always.set_key('key1')
+ c_def.set_key('key1')
+ c_never.set_key('key1')
+ c_none.set_key('key1')
+
+ self.session.begin_transaction('read_timestamp=' + timestamp_str(1))
+ c_always.search()
+ c_def.search()
+ c_none.search()
+ self.assertEqual(c_always.get_value(), 'value1')
+ self.assertEqual(c_def.get_value(), 'value1')
+ self.assertEqual(c_none.get_value(), 'value1')
+
+ msg = "/timestamp set on this transaction/"
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda:self.assertEquals(c_never.search(), 0), msg)
+ self.session.commit_transaction()
+ c_always.close()
+ c_def.close()
+ c_never.close()
+ c_none.close()
+
+ # Read in a transaction without a timestamp.
+ c_always = self.session.open_cursor(uri_always)
+ c_def = self.session.open_cursor(uri_def)
+ c_never = self.session.open_cursor(uri_never)
+ c_none = self.session.open_cursor(uri_none)
+
+ c_always.set_key('key1')
+ c_def.set_key('key1')
+ c_never.set_key('key1')
+ c_none.set_key('key1')
+
+ self.session.begin_transaction()
+ c_never.search()
+ c_def.search()
+ c_none.search()
+ self.assertEqual(c_never.get_value(), 'value1')
+ self.assertEqual(c_def.get_value(), 'value1')
+ self.assertEqual(c_none.get_value(), 'value1')
+
+ msg = "/none set on this transaction/"
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda:self.assertEquals(c_always.search(), 0), msg)
+ self.session.commit_transaction()
+ c_always.close()
+ c_def.close()
+ c_never.close()
+ c_none.close()
+
+if __name__ == '__main__':
+ wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_assert03.py b/src/third_party/wiredtiger/test/suite/test_assert03.py
new file mode 100644
index 00000000000..36d4936a82e
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_assert03.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2017 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.
+#
+# test_assert03.py
+# Test changing assert setting via alter.
+#
+
+from suite_subprocess import suite_subprocess
+import wiredtiger, wttest
+
+class test_assert03(wttest.WiredTigerTestCase, suite_subprocess):
+ conn_config = 'log=(enabled)'
+ base_uri = 'file:assert03.wt'
+ cfg = 'key_format=S,value_format=S'
+ always = 'assert=(commit_timestamp=always)'
+ never = 'assert=(commit_timestamp=never)'
+ none = 'assert=(commit_timestamp=none)'
+
+ def test_assert03(self):
+
+ #if not wiredtiger.timestamp_build() or not wiredtiger.diagnostic_build():
+ # self.skipTest('requires a timestamp and diagnostic build')
+ if not wiredtiger.timestamp_build():
+ self.skipTest('requires a timestamp build')
+
+ # Create a data item at the default setting
+ self.session.create(self.base_uri, self.cfg)
+ c = self.session.open_cursor(self.base_uri)
+ self.session.begin_transaction()
+ c['key0'] = 'value0'
+ self.session.commit_transaction()
+ c.close()
+
+ # Now rotate through the alter settings and verify the data.
+ # The always setting should fail.
+ self.session.alter(self.base_uri, self.always)
+ c = self.session.open_cursor(self.base_uri)
+ self.session.begin_transaction()
+ c['key1'] = 'value1'
+ msg = "/none set on this transaction/"
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda:self.assertEquals(self.session.commit_transaction(), 0), msg)
+ c.close()
+
+ # The never and none settings should succeed.
+ self.session.alter(self.base_uri, self.never)
+ c = self.session.open_cursor(self.base_uri)
+ self.session.begin_transaction()
+ c['key2'] = 'value2'
+ self.session.commit_transaction()
+ c.close()
+
+ self.session.alter(self.base_uri, self.none)
+ c = self.session.open_cursor(self.base_uri)
+ self.session.begin_transaction()
+ c['key3'] = 'value3'
+ self.session.commit_transaction()
+ c.close()
+
+if __name__ == '__main__':
+ wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_backup07.py b/src/third_party/wiredtiger/test/suite/test_backup07.py
new file mode 100644
index 00000000000..8332815b0ca
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_backup07.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2017 MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+import wiredtiger, wttest
+import os, shutil
+from helper import compare_files
+from suite_subprocess import suite_subprocess
+from wtdataset import simple_key
+from wtscenario import make_scenarios
+
+# test_backup07.py
+# Test cursor backup with target URIs, logging and create during backup
+
+class test_backup07(wttest.WiredTigerTestCase, suite_subprocess):
+ dir='backup.dir' # Backup directory name
+ logmax="100K"
+ newuri="table:newtable"
+
+ pfx = 'test_backup'
+ scenarios = make_scenarios([
+ ('table', dict(uri='table:test',dsize=100,nops=100,nthreads=1)),
+ ])
+
+ # Create a large cache, otherwise this test runs quite slowly.
+ def conn_config(self):
+ return 'cache_size=1G,log=(archive=false,enabled,file_max=%s)' % \
+ self.logmax
+
+ # Run background inserts while running checkpoints and incremental backups
+ # repeatedly.
+ def test_backup07(self):
+ log2 = "WiredTigerLog.0000000002"
+
+ self.session.create(self.uri, "key_format=S,value_format=S")
+
+ # Insert small amounts of data at a time stopping just after we
+ # cross into log file 2. That way we can add more operations into
+ # log file 2 during the full backup.
+ loop = 0
+ c = self.session.open_cursor(self.uri)
+ while not os.path.exists(log2):
+ for i in range(0, self.nops):
+ num = i + (loop * self.nops)
+ key = 'key' + str(num)
+ val = 'value' + str(num)
+ c[key] = val
+ loop += 1
+
+ # Test a potential bug in full backups and creates.
+ # We allow creates during backup because the file doesn't exist
+ # when the backup metadata is created on cursor open and the newly
+ # created file is not in the cursor list. However, if using logging
+ # and the create and inserts/updates appear in a log file copied,
+ # then currently there will be an error opening the backup directory.
+
+ # Open up the backup cursor, create and add data to a new table
+ # and then copy the files.
+ os.mkdir(self.dir)
+ bkup_c = self.session.open_cursor('backup:', None, None)
+
+ # Now create and populate the new table. Make sure the log records
+ # are on disk and will be copied to the backup.
+ self.session.create(self.newuri, "key_format=S,value_format=S")
+ c = self.session.open_cursor(self.newuri)
+ for i in range(0, self.nops):
+ key = 'key' + str(i)
+ val = 'value' + str(i)
+ c[key] = val
+ c.close()
+ self.session.log_flush('sync=on')
+
+ # Now copy the files returned by the backup cursor. This will
+ # include the log file that has updates for the newly created table.
+ while True:
+ ret = bkup_c.next()
+ if ret != 0:
+ break
+ newfile = bkup_c.get_key()
+ sz = os.path.getsize(newfile)
+ self.pr('Copy from: ' + newfile + ' (' + str(sz) + ') to ' + self.dir)
+ shutil.copy(newfile, self.dir)
+ self.assertEqual(ret, wiredtiger.WT_NOTFOUND)
+ bkup_c.close()
+
+ # After the full backup, open and recover the backup database.
+ # Make sure we properly recover even though the log file will have
+ # records for the newly created table file id.
+ backup_conn = self.wiredtiger_open(self.dir)
+ backup_conn.close()
+
+if __name__ == '__main__':
+ wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_las.py b/src/third_party/wiredtiger/test/suite/test_las.py
index d0bd1d108fa..52a0b2d7300 100644
--- a/src/third_party/wiredtiger/test/suite/test_las.py
+++ b/src/third_party/wiredtiger/test/suite/test_las.py
@@ -26,16 +26,53 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
+from helper import copy_wiredtiger_home
import wiredtiger, wttest
from wtdataset import SimpleDataSet
+def timestamp_str(t):
+ return '%x' % t
+
# test_las.py
-# Smoke tests to ensure lookaside tables are working.
+# Smoke tests to ensure lookaside tables are working.
class test_las(wttest.WiredTigerTestCase):
# Force a small cache.
def conn_config(self):
return 'cache_size=1GB'
+ def large_updates(self, session, uri, value, ds, nrows, timestamp=False):
+ # Insert a large number of records, we'll hang if the lookaside table
+ # isn't doing its thing.
+ cursor = session.open_cursor(uri)
+ for i in range(1, 1000000):
+ if timestamp == True:
+ session.begin_transaction()
+ cursor.set_key(ds.key(nrows + i))
+ cursor.set_value(value)
+ self.assertEquals(cursor.update(), 0)
+ if timestamp == True:
+ session.commit_transaction('commit_timestamp=' + timestamp_str(i + 1))
+ cursor.close()
+
+ def durable_check(self, check_value, uri, ds, nrows):
+ # Checkpoint and backup so as to simulate recovery
+ self.session.checkpoint()
+ newdir = "BACKUP"
+ copy_wiredtiger_home('.', newdir, True)
+
+ conn = self.setUpConnectionOpen(newdir)
+ session = self.setUpSessionOpen(conn)
+ cursor = session.open_cursor(uri, None)
+ # Skip the initial rows, which were not updated
+ for i in range(0, nrows+1):
+ self.assertEquals(cursor.next(), 0)
+ #print "Check value : " + str(check_value)
+ #print "value : " + str(cursor.get_value())
+ self.assertTrue(check_value == cursor.get_value())
+ cursor.close()
+ session.close()
+ conn.close()
+
@wttest.longtest('lookaside table smoke test')
def test_las(self):
# Create a small table.
@@ -43,18 +80,49 @@ class test_las(wttest.WiredTigerTestCase):
nrows = 100
ds = SimpleDataSet(self, uri, nrows, key_format="S")
ds.populate()
+ bigvalue = "aaaaa" * 100
- # Take a snapshot.
+ # Initially load huge data
+ cursor = self.session.open_cursor(uri)
+ for i in range(1, 1000000):
+ cursor.set_key(ds.key(nrows + i))
+ cursor.set_value(bigvalue)
+ self.assertEquals(cursor.insert(), 0)
+ cursor.close()
+ self.session.checkpoint()
+
+ # Scenario: 1
+ # Check to see LAS working with old snapshot
+ bigvalue1 = "bbbbb" * 100
self.session.snapshot("name=xxx")
+ # Update the values in different session after snapshot
+ self.large_updates(self.session, uri, bigvalue1, ds, nrows)
+ # Check to see the value after recovery
+ self.durable_check(bigvalue1, uri, ds, nrows)
+ self.session.snapshot("drop=(all)")
- # Insert a large number of records, we'll hang if the lookaside table
- # isn't doing its thing.
- c = self.session.open_cursor(uri)
- bigvalue = "abcde" * 100
- for i in range(1, 1000000):
- c.set_key(ds.key(nrows + i))
- c.set_value(bigvalue)
- self.assertEquals(c.insert(), 0)
+ # Scenario: 2
+ # Check to see LAS working with old reader
+ bigvalue2 = "ccccc" * 100
+ session2 = self.conn.open_session()
+ session2.begin_transaction('isolation=snapshot')
+ self.large_updates(self.session, uri, bigvalue2, ds, nrows)
+ # Check to see the value after recovery
+ self.durable_check(bigvalue2, uri, ds, nrows)
+ session2.rollback_transaction()
+ session2.close()
+
+ # Scenario: 3
+ # Check to see LAS working with old timestamp
+ bigvalue3 = "ddddd" * 100
+ self.conn.set_timestamp('stable_timestamp=' + timestamp_str(1))
+ self.large_updates(self.session, uri, bigvalue3, ds, nrows, timestamp=True)
+ # Check to see data can be see only till the stable_timestamp
+ self.durable_check(bigvalue2, uri, ds, nrows)
+
+ self.conn.set_timestamp('stable_timestamp=' + timestamp_str(i + 1))
+ # Check to see latest data can be seen
+ self.durable_check(bigvalue3, uri, ds, nrows)
if __name__ == '__main__':
wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp01.py b/src/third_party/wiredtiger/test/suite/test_timestamp01.py
index c7a5df66ae0..09a264e2afd 100644
--- a/src/third_party/wiredtiger/test/suite/test_timestamp01.py
+++ b/src/third_party/wiredtiger/test/suite/test_timestamp01.py
@@ -61,12 +61,40 @@ class test_timestamp01(wttest.WiredTigerTestCase, suite_subprocess):
'commit_timestamp=' + timestamp_str(1 << 5000)),
'/too long/')
- # One is okay, as is 2**64 - 1
+ # Anything other than lower case hexadecimal characters is not permitted
+ self.session.begin_transaction()
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.session.commit_transaction(
+ 'commit_timestamp=' + timestamp_str(-1)),
+ '/Failed to parse commit timestamp/')
+
+ self.session.begin_transaction()
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.session.commit_transaction(
+ 'commit_timestamp=' + 'a/78f'),
+ '/Failed to parse commit timestamp/')
+
+ self.session.begin_transaction()
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.session.commit_transaction(
+ 'commit_timestamp=' + 'a`78f'),
+ '/Failed to parse commit timestamp/')
+
+ self.session.begin_transaction()
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.session.commit_transaction(
+ 'commit_timestamp=' + 'a{78f'),
+ '/Failed to parse commit timestamp/')
+
+ # One is okay, as is upper case hex and 2**64 - 1
self.session.begin_transaction()
self.session.commit_transaction(
'commit_timestamp=' + timestamp_str(1))
self.session.begin_transaction()
self.session.commit_transaction(
+ 'commit_timestamp=0A78F')
+ self.session.begin_transaction()
+ self.session.commit_transaction(
'commit_timestamp=' + timestamp_str(1 << 64 - 1))
if __name__ == '__main__':
diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp02.py b/src/third_party/wiredtiger/test/suite/test_timestamp02.py
index 31bea22ec66..f928dbc184f 100644
--- a/src/third_party/wiredtiger/test/suite/test_timestamp02.py
+++ b/src/third_party/wiredtiger/test/suite/test_timestamp02.py
@@ -38,12 +38,6 @@ from wtscenario import make_scenarios
def timestamp_str(t):
return '%x' % t
-def timestamp_ret_str(t):
- s = timestamp_str(t)
- if len(s) % 2 == 1:
- s = '0' + s
- return s
-
class test_timestamp02(wttest.WiredTigerTestCase, suite_subprocess):
tablename = 'test_timestamp02'
uri = 'table:' + tablename
@@ -98,7 +92,7 @@ class test_timestamp02(wttest.WiredTigerTestCase, suite_subprocess):
dict((k, 1) for k in orig_keys[:i+1]))
# Everything up to and including timestamp 100 has been committed.
- self.assertEqual(self.conn.query_timestamp(), timestamp_ret_str(100))
+ self.assertTimestampsEqual(self.conn.query_timestamp(), timestamp_str(100))
# Bump the oldest timestamp, we're not going back...
self.conn.set_timestamp('oldest_timestamp=' + timestamp_str(100))
@@ -111,11 +105,11 @@ class test_timestamp02(wttest.WiredTigerTestCase, suite_subprocess):
self.session.commit_transaction('commit_timestamp=' + timestamp_str(k + 100))
# Everything up to and including timestamp 200 has been committed.
- self.assertEqual(self.conn.query_timestamp(), timestamp_ret_str(200))
+ self.assertTimestampsEqual(self.conn.query_timestamp(), timestamp_str(200))
# Test that we can manually move the commit timestamp back
self.conn.set_timestamp('commit_timestamp=' + timestamp_str(150))
- self.assertEqual(self.conn.query_timestamp(), timestamp_ret_str(150))
+ self.assertTimestampsEqual(self.conn.query_timestamp(), timestamp_str(150))
self.conn.set_timestamp('commit_timestamp=' + timestamp_str(200))
# Now the stable timestamp before we read.
diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp03.py b/src/third_party/wiredtiger/test/suite/test_timestamp03.py
index 9caf597e6ed..1a2511ea6ee 100644
--- a/src/third_party/wiredtiger/test/suite/test_timestamp03.py
+++ b/src/third_party/wiredtiger/test/suite/test_timestamp03.py
@@ -39,12 +39,6 @@ from wtscenario import make_scenarios
def timestamp_str(t):
return '%x' % t
-def timestamp_ret_str(t):
- s = timestamp_str(t)
- if len(s) % 2 == 1:
- s = '0' + s
- return s
-
class test_timestamp03(wttest.WiredTigerTestCase, suite_subprocess):
table_ts_log = 'ts03_ts_logged'
table_ts_nolog = 'ts03_ts_nologged'
@@ -226,7 +220,7 @@ class test_timestamp03(wttest.WiredTigerTestCase, suite_subprocess):
self.table_nots_nolog, dict((k, self.value) for k in orig_keys))
# Bump the oldest_timestamp, we're not going back...
- self.assertEqual(self.conn.query_timestamp(), timestamp_ret_str(100))
+ self.assertTimestampsEqual(self.conn.query_timestamp(), timestamp_str(100))
old_ts = timestamp_str(100)
self.conn.set_timestamp('oldest_timestamp=' + old_ts)
self.conn.set_timestamp('stable_timestamp=' + old_ts)
diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp04.py b/src/third_party/wiredtiger/test/suite/test_timestamp04.py
index a52675daf8b..f7052448208 100644
--- a/src/third_party/wiredtiger/test/suite/test_timestamp04.py
+++ b/src/third_party/wiredtiger/test/suite/test_timestamp04.py
@@ -37,12 +37,6 @@ from wtscenario import make_scenarios
def timestamp_str(t):
return '%x' % t
-def timestamp_ret_str(t):
- s = timestamp_str(t)
- if len(s) % 2 == 1:
- s = '0' + s
- return s
-
class test_timestamp04(wttest.WiredTigerTestCase, suite_subprocess):
table_ts_log = 'table:ts04_ts_logged'
table_ts_nolog = 'table:ts04_ts_nologged'
@@ -61,6 +55,7 @@ class test_timestamp04(wttest.WiredTigerTestCase, suite_subprocess):
('col_var', dict(empty=0, cacheSize='cache_size=20MB', extra_config=',key_format=r')),
('lsm', dict(empty=0, cacheSize='cache_size=31MB', extra_config=',type=lsm')),
('row', dict(empty=0, cacheSize='cache_size=20MB', extra_config='',)),
+ ('row-smallcache', dict(empty=0, cacheSize='cache_size=2MB', extra_config='',)),
]
scenarios = make_scenarios(conncfg, types)
diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp05.py b/src/third_party/wiredtiger/test/suite/test_timestamp05.py
index d7131cb2004..f145184146c 100644
--- a/src/third_party/wiredtiger/test/suite/test_timestamp05.py
+++ b/src/third_party/wiredtiger/test/suite/test_timestamp05.py
@@ -39,12 +39,6 @@ from wtscenario import make_scenarios
def timestamp_str(t):
return '%x' % t
-def timestamp_ret_str(t):
- s = timestamp_str(t)
- if len(s) % 2 == 1:
- s = '0' + s
- return s
-
class test_timestamp05(wttest.WiredTigerTestCase, suite_subprocess):
uri = 'table:ts05'
diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp07.py b/src/third_party/wiredtiger/test/suite/test_timestamp07.py
index 12b36bdc2f8..09547dba3a7 100644
--- a/src/third_party/wiredtiger/test/suite/test_timestamp07.py
+++ b/src/third_party/wiredtiger/test/suite/test_timestamp07.py
@@ -56,8 +56,8 @@ class test_timestamp07(wttest.WiredTigerTestCase, suite_subprocess):
nkeys = [
('100keys', dict(nkeys=100)),
-# ('500keys', dict(nkeys=500)),
-# ('1000keys', dict(nkeys=1000)),
+ ('500keys', dict(nkeys=500)),
+ ('1000keys', dict(nkeys=1000)),
]
scenarios = make_scenarios(types, conncfg, nkeys)
@@ -68,19 +68,20 @@ class test_timestamp07(wttest.WiredTigerTestCase, suite_subprocess):
value3 = u'\u0001\u0002cdef\u0007\u0004'
# Check that a cursor (optionally started in a new transaction), sees the
- # expected values.
- def check(self, session, txn_config, expected):
+ # expected value for a key
+ def check(self, session, txn_config, k, expected):
if txn_config:
session.begin_transaction(txn_config)
c = session.open_cursor(self.uri + self.tablename, None)
- actual = dict((k, v) for k, v in c if v != 0)
- self.assertTrue(actual == expected)
- # Search for the expected items as well as iterating
- for k, v in expected.iteritems():
- self.assertEqual(c[k], v, "for key " + str(k))
+ if not expected:
+ c.set_key(k)
+ self.assertEqual(c.search(), wiredtiger.WT_NOTFOUND)
+ else:
+ self.assertEqual(c[k], expected)
c.close()
if txn_config:
session.commit_transaction()
+
#
# Take a backup of the database and verify that the value we want to
# check exists in the tables the expected number of times.
@@ -168,12 +169,14 @@ class test_timestamp07(wttest.WiredTigerTestCase, suite_subprocess):
# Now check that we see the expected state when reading at each
# timestamp.
- for i, t in enumerate(orig_keys):
- self.check(self.session, 'read_timestamp=' + timestamp_str(t),
- dict((k, self.value) for k in orig_keys[:i+1]))
+ for k in orig_keys:
+ self.check(self.session, 'read_timestamp=' + timestamp_str(k),
+ k, self.value)
+ self.check(self.session, 'read_timestamp=' + timestamp_str(k),
+ k + 1, None)
# Bump the oldest timestamp, we're not going back...
- self.assertEqual(self.conn.query_timestamp(), timestamp_str(self.nkeys))
+ self.assertTimestampsEqual(self.conn.query_timestamp(), timestamp_str(self.nkeys))
self.oldts = timestamp_str(self.nkeys)
self.conn.set_timestamp('oldest_timestamp=' + self.oldts)
self.conn.set_timestamp('stable_timestamp=' + self.oldts)
@@ -201,12 +204,8 @@ class test_timestamp07(wttest.WiredTigerTestCase, suite_subprocess):
# Take a checkpoint using the given configuration. Then verify
# whether value2 appears in a copy of that data or not.
- valcnt2 = valcnt3 = self.nkeys
- valcnt = 0
- # If logging is disabled then value2 should not appear in logged table.
- if self.using_log == False:
- valcnt3 = 0
- self.ckpt_backup(self.value2, valcnt, valcnt2, valcnt3)
+ self.ckpt_backup(self.value2, 0, self.nkeys, self.nkeys if self.using_log else 0)
+
# Update the stable timestamp to the latest, but not the oldest
# timestamp and make sure we can see the data. Once the stable
# timestamp is moved we should see all keys with value2.
@@ -245,9 +244,7 @@ class test_timestamp07(wttest.WiredTigerTestCase, suite_subprocess):
# of that data or not. Both tables that are logged should see
# all the data regardless of timestamps. The table that is not
# logged should not see any of it.
- valcnt = 0
- valcnt2 = valcnt3 = self.nkeys
- self.backup_check(self.value3, valcnt, valcnt2, valcnt3)
+ self.backup_check(self.value3, 0, self.nkeys, self.nkeys)
if __name__ == '__main__':
wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp09.py b/src/third_party/wiredtiger/test/suite/test_timestamp09.py
index 41a6909cbef..b79521329e7 100644
--- a/src/third_party/wiredtiger/test/suite/test_timestamp09.py
+++ b/src/third_party/wiredtiger/test/suite/test_timestamp09.py
@@ -114,8 +114,7 @@ class test_timestamp09(wttest.WiredTigerTestCase, suite_subprocess):
# Oldest timestamp is 3 at the moment, trying to set it to an earlier
# timestamp is a no-op.
self.conn.set_timestamp('oldest_timestamp=' + timestamp_str(1))
- self.assertEqual(int(self.conn.query_timestamp('get=oldest')),
- int(timestamp_str(3)))
+ self.assertTimestampsEqual(self.conn.query_timestamp('get=oldest'), timestamp_str(3))
self.conn.set_timestamp('oldest_timestamp=' + timestamp_str(3) +
',stable_timestamp=' + timestamp_str(3))
@@ -123,8 +122,7 @@ class test_timestamp09(wttest.WiredTigerTestCase, suite_subprocess):
# Stable timestamp is 5 at the moment, trying to set it to an earlier
# timestamp is a no-op.
self.conn.set_timestamp('stable_timestamp=' + timestamp_str(4))
- self.assertEqual(int(self.conn.query_timestamp('get=stable')),
- int(timestamp_str(5)))
+ self.assertTimestampsEqual(self.conn.query_timestamp('get=stable'), timestamp_str(5))
self.conn.set_timestamp('oldest_timestamp=' + timestamp_str(5))
self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
diff --git a/src/third_party/wiredtiger/test/suite/test_txn14.py b/src/third_party/wiredtiger/test/suite/test_txn14.py
index 7579bbc8e54..2245f49ae85 100644
--- a/src/third_party/wiredtiger/test/suite/test_txn14.py
+++ b/src/third_party/wiredtiger/test/suite/test_txn14.py
@@ -93,10 +93,11 @@ class test_txn14(wttest.WiredTigerTestCase, suite_subprocess):
c.close()
self.session.log_flush(cfgarg)
if self.sync == 'background':
- # If doing a background flush, wait a few seconds. I have
- # seen an individual log file's fsync take more than a second
- # on some systems. So give it time to flush perhaps a few files.
- self.session.transaction_sync('timeout_ms=4000')
+ # If doing a background flush, wait 10 seconds. I have seen an
+ # individual log file's fsync take more than a second on some
+ # systems, and we've seen timeouts at lower levels on systems
+ # with slow I/O. So give it time to flush perhaps a few files.
+ self.session.transaction_sync('timeout_ms=10000')
self.simulate_crash_restart(".", "RESTART")
c = self.session.open_cursor(self.t1, None, None)
i = 0
diff --git a/src/third_party/wiredtiger/test/suite/wttest.py b/src/third_party/wiredtiger/test/suite/wttest.py
index 1c95eb355ae..c654370718c 100644
--- a/src/third_party/wiredtiger/test/suite/wttest.py
+++ b/src/third_party/wiredtiger/test/suite/wttest.py
@@ -490,6 +490,12 @@ class WiredTigerTestCase(unittest.TestCase):
with self.expectedStderr(message):
self.assertRaises(exceptionType, expr)
+ def assertTimestampsEqual(self, ts1, ts2):
+ """
+ TestCase.assertEqual() for timestamps
+ """
+ self.assertEqual(int(ts1, 16), int(ts2, 16))
+
def exceptionToStderr(self, expr):
"""
Used by assertRaisesHavingMessage to convert an expression