summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2022-09-30 11:31:37 +1000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-09-30 02:03:48 +0000
commitf3481a5054f0d85917627ee7816416567ec9a6f7 (patch)
treef07ec20def91f2add87e882f5093771558ca4504
parenta085ddf0bce45c881ae6061fb7b132854f0694e0 (diff)
downloadmongo-f3481a5054f0d85917627ee7816416567ec9a6f7.tar.gz
Import wiredtiger: 440964001da03f8081c6a134fe10e0be2318d081 from branch mongodb-master
ref: 7e38deff7b..440964001d for: 6.2.0-rc0 WT-9890 separate timestamp testing into its own hook. (#8306)
-rw-r--r--src/third_party/wiredtiger/import.data2
-rwxr-xr-xsrc/third_party/wiredtiger/test/evergreen.yml22
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/hook_tiered.py66
-rw-r--r--src/third_party/wiredtiger/test/suite/hook_timestamp.py163
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/suite_subprocess.py14
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_checkpoint01.py7
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_compact01.py7
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_cursor06.py2
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_cursor12.py2
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_cursor17.py2
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_flcs01.py2
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_flcs05.py2
-rw-r--r--src/third_party/wiredtiger/test/suite/test_inmem01.py12
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/test_stat01.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_stat05.py2
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/wtdataset.py2
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/wthooks.py76
-rwxr-xr-xsrc/third_party/wiredtiger/test/suite/wttimestamp.py14
18 files changed, 277 insertions, 121 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index 4d1d4ed28e9..e1212d37ce5 100644
--- a/src/third_party/wiredtiger/import.data
+++ b/src/third_party/wiredtiger/import.data
@@ -2,5 +2,5 @@
"vendor": "wiredtiger",
"github": "wiredtiger/wiredtiger.git",
"branch": "mongodb-master",
- "commit": "7e38deff7bff0f2cdad1b8760b123bcf0a476456"
+ "commit": "440964001da03f8081c6a134fe10e0be2318d081"
}
diff --git a/src/third_party/wiredtiger/test/evergreen.yml b/src/third_party/wiredtiger/test/evergreen.yml
index 453c187615b..e1c8d403311 100755
--- a/src/third_party/wiredtiger/test/evergreen.yml
+++ b/src/third_party/wiredtiger/test/evergreen.yml
@@ -1918,6 +1918,26 @@ tasks:
vars:
unit_test_args: --hook tiered
+ - name: unit-test-hook-tiered-timestamp
+ tags: ["python"]
+ depends_on:
+ - name: compile
+ commands:
+ - func: "fetch artifacts"
+ - func: "unit test"
+ vars:
+ unit_test_args: --hook tiered --hook timestamp
+
+ - name: unit-test-hook-timestamp
+ tags: ["python"]
+ depends_on:
+ - name: compile
+ commands:
+ - func: "fetch artifacts"
+ - func: "unit test"
+ vars:
+ unit_test_args: --hook timestamp
+
# Break out Python unit tests into multiple buckets/tasks. We have a fixed number of buckets,
# and we use the -b option of the test/suite/run.py script to split up the tests.
@@ -3975,6 +3995,8 @@ buildvariants:
- name: unit-test-zstd
- name: unit-test-random-seed
- name: unit-test-hook-tiered
+ - name: unit-test-hook-tiered-timestamp
+ - name: unit-test-hook-timestamp
- name: spinlock-gcc-test
- name: spinlock-pthread-adaptive-test
- name: compile-wtperf
diff --git a/src/third_party/wiredtiger/test/suite/hook_tiered.py b/src/third_party/wiredtiger/test/suite/hook_tiered.py
index 1d64644e549..9fcd6cfa303 100755
--- a/src/third_party/wiredtiger/test/suite/hook_tiered.py
+++ b/src/third_party/wiredtiger/test/suite/hook_tiered.py
@@ -55,7 +55,7 @@
#
from __future__ import print_function
-import os, sys, unittest, wthooks, wttimestamp
+import os, sys, unittest, wthooks
from wttest import WiredTigerTestCase
# These are the hook functions that are run when particular APIs are called.
@@ -163,13 +163,6 @@ def connection_close_replace(orig_connection_close, connection_self, config):
ret = orig_connection_close(connection_self, config)
return ret
-# Called to replace Connection.open_session
-def connection_open_session_replace(orig_connection_open_session, connection_self, config):
- ret_session = orig_connection_open_session(connection_self, config)
- ret_session._connection = connection_self
- ret_session._has_transaction = False
- return ret_session
-
# Called to replace Session.checkpoint.
# We add a call to flush_tier after the checkpoint to make sure we are exercising tiered
# functionality.
@@ -184,24 +177,6 @@ def session_checkpoint_replace(orig_session_checkpoint, session_self, config):
' Calling flush_tier() after checkpoint')
return session_self.flush_tier(None)
-# Called to replace Session.begin_transaction
-def session_begin_transaction_replace(orig_session_begin_transaction, session_self, config):
- ret = orig_session_begin_transaction(session_self, config)
- session_self._has_transaction = True
- return ret
-
-# Called to replace Session.commit_transaction
-def session_commit_transaction_replace(orig_session_commit_transaction, session_self, config):
- ret = orig_session_commit_transaction(session_self, config)
- session_self._has_transaction = False
- return ret
-
-# Called to replace Session.rollback_transaction
-def session_rollback_transaction_replace(orig_session_rollback_transaction, session_self, config):
- ret = orig_session_rollback_transaction(session_self, config)
- session_self._has_transaction = False
- return ret
-
# Called to replace Session.compact
def session_compact_replace(orig_session_compact, session_self, uri, config):
# Compact isn't implemented for tiered tables. Only call it if this can't be the uri
@@ -242,9 +217,7 @@ def session_open_cursor_replace(orig_session_open_cursor, session_self, uri, dup
if uri != None and uri.startswith("backup:"):
testcase = WiredTigerTestCase.currentTestCase()
testcase.skipTest("backup on tiered tables not yet implemented")
- ret_cursor = orig_session_open_cursor(session_self, uri, dupcursor, config)
- ret_cursor._session = session_self
- return ret_cursor
+ return orig_session_open_cursor(session_self, uri, dupcursor, config)
# Called to replace Session.rename
def session_rename_replace(orig_session_rename, session_self, uri, newuri, config):
@@ -289,14 +262,6 @@ class TieredHookCreator(wthooks.WiredTigerHookCreator):
# Override some platform APIs
self.platform_api = TieredPlatformAPI()
- # This hook plays with timestamps, indirectly by modifying the behavior of the *DataSet classes.
- # Here we declare our use of timestamp code, so that tests that have their own notion of
- # timestamps can be skipped when running with this hook.
- def uses(self, use_list):
- if "timestamp" in use_list:
- return True
- return False
-
# Is this test one we should skip?
def skip_test(self, test):
# Skip any test that contains one of these strings as a substring
@@ -333,7 +298,6 @@ class TieredHookCreator(wthooks.WiredTigerHookCreator):
# This group fail within Python for various, sometimes unknown, reasons.
"test_bug018.test_bug018",
"test_checkpoint.test_checkpoint",
- "test_checkpoint_target.test_checkpoint_target",
"test_checkpoint_snapshot02.test_checkpoint_snapshot_with_txnid_and_timestamp",
"test_compat05.test_compat05",
"test_config05.test_too_many_sessions",
@@ -401,22 +365,6 @@ class TieredHookCreator(wthooks.WiredTigerHookCreator):
self.Connection['close'] = (wthooks.HOOK_REPLACE, lambda s, config=None:
connection_close_replace(orig_connection_close, s, config))
- orig_connection_open_session = self.Connection['open_session']
- self.Connection['open_session'] = (wthooks.HOOK_REPLACE, lambda s, config=None:
- connection_open_session_replace(orig_connection_open_session, s, config))
-
- orig_session_begin_transaction = self.Session['begin_transaction']
- self.Session['begin_transaction'] = (wthooks.HOOK_REPLACE, lambda s, config=None:
- session_begin_transaction_replace(orig_session_begin_transaction, s, config))
-
- orig_session_commit_transaction = self.Session['commit_transaction']
- self.Session['commit_transaction'] = (wthooks.HOOK_REPLACE, lambda s, config=None:
- session_commit_transaction_replace(orig_session_commit_transaction, s, config))
-
- orig_session_rollback_transaction = self.Session['rollback_transaction']
- self.Session['rollback_transaction'] = (wthooks.HOOK_REPLACE, lambda s, config=None:
- session_rollback_transaction_replace(orig_session_rollback_transaction, s, config))
-
orig_session_compact = self.Session['compact']
self.Session['compact'] = (wthooks.HOOK_REPLACE, lambda s, uri, config=None:
session_compact_replace(orig_session_compact, s, uri, config))
@@ -445,12 +393,6 @@ class TieredHookCreator(wthooks.WiredTigerHookCreator):
# Override some platform APIs for this hook.
class TieredPlatformAPI(wthooks.WiredTigerHookPlatformAPI):
- def setUp(self):
- self._timestamp = wttimestamp.WiredTigerTimeStamp()
-
- def tearDown(self):
- pass
-
def tableExists(self, name):
for i in range(1, 9):
tablename = name + "-000000000{}.wtobj".format(i)
@@ -464,10 +406,6 @@ class TieredPlatformAPI(wthooks.WiredTigerHookPlatformAPI):
else:
return wthooks.DefaultPlatformAPI.initialFileName(uri)
- # By default, there is no timestamping by the data set classes.
- def getTimestamp(self):
- return self._timestamp
-
# Every hook file must have a top level initialize function,
# returning a list of WiredTigerHook objects.
diff --git a/src/third_party/wiredtiger/test/suite/hook_timestamp.py b/src/third_party/wiredtiger/test/suite/hook_timestamp.py
new file mode 100644
index 00000000000..7322b2fc19e
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/hook_timestamp.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-present 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_TAGS]
+# ignored_file
+# [END_TAGS]
+
+# hook_timestamp.py
+#
+# Insert the use of timestamps into data sets.
+#
+# These hooks have three functions. The primary one is setting up the platform API to return
+# a "timestamper". The dataset package uses this platform API, and so will run with timestamps
+# when this hook is enabled. The timestamper provides a timestamping cursor that "knows" to wrap
+# timestamped transactions around certain operations, like insert.
+#
+# Secondly, we set hooks on the transaction APIs so we know when a transaction has been started or
+# finished by the test application. If the application already a transaction in progress,
+# the timestamping cursor should not try to open a transaction, but can place a timestamp on the
+# current transaction.
+#
+# To run, for example, the cursor tests with these hooks enabled:
+# ../test/suite/run.py --hooks timestamp cursor
+#
+from __future__ import print_function
+
+import os, sys, unittest, wthooks, wttimestamp
+from wttest import WiredTigerTestCase
+
+# These are the hook functions that are run when particular APIs are called.
+
+# Called to replace Session.begin_transaction
+def session_begin_transaction_replace(orig_session_begin_transaction, session_self, config):
+ ret = orig_session_begin_transaction(session_self, config)
+ session_self._has_transaction = True
+ return ret
+
+# Called to replace Session.commit_transaction
+def session_commit_transaction_replace(orig_session_commit_transaction, session_self, config):
+ ret = orig_session_commit_transaction(session_self, config)
+ session_self._has_transaction = False
+ return ret
+
+# Called to replace Session.rollback_transaction
+def session_rollback_transaction_replace(orig_session_rollback_transaction, session_self, config):
+ ret = orig_session_rollback_transaction(session_self, config)
+ session_self._has_transaction = False
+ return ret
+
+def make_dataset_names():
+ import wtdataset
+ names = ['wtdataset']
+ #g = globals(sys.modules['wtdataset'])
+ g = sys.modules['wtdataset'].__dict__
+ for name in g:
+ if name.endswith('DataSet'):
+ names.append(name)
+ return names
+
+# Every hook file must have one or more classes descended from WiredTigerHook
+# This is where the hook functions are 'hooked' to API methods.
+class TimestampHookCreator(wthooks.WiredTigerHookCreator):
+ def __init__(self, arg=0):
+ # Caller can specify an optional command-line argument. We're not using it
+ # now, but this is where it would show up.
+
+ # Override some platform APIs
+ self.platform_api = TimestampPlatformAPI()
+
+ # This hook plays with timestamps, indirectly by modifying the behavior of the *DataSet classes.
+ # Here we declare our use of timestamp code, so that tests that have their own notion of
+ # timestamps can be skipped when running with this hook.
+ def uses(self, use_list):
+ if "timestamp" in use_list:
+ return True
+ return False
+
+ dataset_names = make_dataset_names()
+
+ # We skip tests that don't use datasets
+ def skip_test(self, test, known_skip):
+ import importlib
+ testname = str(test)
+ #print('CHECK: {}'.format(testname))
+ modname = testname.split('.')[0]
+ if modname in known_skip:
+ return known_skip[modname]
+ g = sys.modules[modname].__dict__
+ uses_dataset = False
+ for dsname in self.dataset_names:
+ if dsname in g:
+ uses_dataset = True
+ break
+ #print('CHECK: {}: {}'.format(test,uses_dataset))
+ skip = not uses_dataset
+ known_skip[modname] = skip
+ return skip
+
+ # Remove tests that won't work on timestamp cursors
+ def filter_tests(self, tests):
+ new_tests = unittest.TestSuite()
+ known_skip = dict()
+ new_tests.addTests([t for t in tests if not self.skip_test(t, known_skip)])
+ return new_tests
+
+ def get_platform_api(self):
+ return self.platform_api
+
+ def setup_hooks(self):
+ orig_session_begin_transaction = self.Session['begin_transaction']
+ self.Session['begin_transaction'] = (wthooks.HOOK_REPLACE, lambda s, config=None:
+ session_begin_transaction_replace(orig_session_begin_transaction, s, config))
+
+ orig_session_commit_transaction = self.Session['commit_transaction']
+ self.Session['commit_transaction'] = (wthooks.HOOK_REPLACE, lambda s, config=None:
+ session_commit_transaction_replace(orig_session_commit_transaction, s, config))
+
+ orig_session_rollback_transaction = self.Session['rollback_transaction']
+ self.Session['rollback_transaction'] = (wthooks.HOOK_REPLACE, lambda s, config=None:
+ session_rollback_transaction_replace(orig_session_rollback_transaction, s, config))
+
+# Override some platform APIs for this hook.
+class TimestampPlatformAPI(wthooks.WiredTigerHookPlatformAPI):
+ def setUp(self):
+ self._timestamp = wttimestamp.WiredTigerTimeStamp()
+
+ def tearDown(self):
+ pass
+
+ # Return a timestamping implementation, it will be used by the data set classes.
+ def getTimestamp(self):
+ return self._timestamp
+
+
+# Every hook file must have a top level initialize function,
+# returning a list of WiredTigerHook objects.
+def initialize(arg):
+ return [TimestampHookCreator(arg)]
diff --git a/src/third_party/wiredtiger/test/suite/suite_subprocess.py b/src/third_party/wiredtiger/test/suite/suite_subprocess.py
index 2aab7e4f186..507c647757f 100755
--- a/src/third_party/wiredtiger/test/suite/suite_subprocess.py
+++ b/src/third_party/wiredtiger/test/suite/suite_subprocess.py
@@ -30,6 +30,7 @@ from __future__ import print_function
import os, re, subprocess, sys
from run import wt_builddir
from wttest import WiredTigerTestCase
+import wttest
# suite_subprocess.py
# Run a subprocess within the test suite
@@ -224,15 +225,18 @@ class suite_subprocess:
return [ returncode, new_home_dir ]
# Run the wt utility.
+
+ # FIXME-WT-9808:
+ # The tiered hook silently interjects tiered configuration and extensions,
+ # these are not yet dealt with when running the external 'wt' process.
+ @wttest.skip_for_hook("tiered", "runWt cannot add needed extensions")
def runWt(self, args, infilename=None,
outfilename=None, errfilename=None, closeconn=True,
reopensession=True, failure=False):
- # FIXME-WT-9808:
- # The tiered hook silently interjects tiered configuration and extensions,
- # these are not yet dealt with when running the external 'wt' process.
- if 'tiered' in self.hook_names:
- self.skipTest("runWt is not yet supported with tiering")
+ # FIXME-WT-9809:
+ if 'timestamp' in self.hook_names and args[0] == 'load':
+ self.skipTest("the load utility cannot be run when timestamps are already set")
# Close the connection to guarantee everything is flushed, and that
# we can open it from another process.
diff --git a/src/third_party/wiredtiger/test/suite/test_checkpoint01.py b/src/third_party/wiredtiger/test/suite/test_checkpoint01.py
index e8c08cbd48e..6f3940f47cb 100755
--- a/src/third_party/wiredtiger/test/suite/test_checkpoint01.py
+++ b/src/third_party/wiredtiger/test/suite/test_checkpoint01.py
@@ -209,15 +209,18 @@ class test_checkpoint_target(wttest.WiredTigerTestCase):
])
def update(self, uri, ds, value):
- cursor = self.session.open_cursor(uri, None, "overwrite")
+ cursor = ds.open_cursor(uri, None, "overwrite")
cursor[ds.key(10)] = value
cursor.close()
def check(self, uri, ds, value):
- cursor = self.session.open_cursor(uri, None, "checkpoint=checkpoint-1")
+ cursor = ds.open_cursor(uri, None, "checkpoint=checkpoint-1")
self.assertEquals(cursor[ds.key(10)], value)
cursor.close()
+ # FIXME-WT-9902
+ @wttest.skip_for_hook("tiered", "strange interaction with tiered and named checkpoints using target")
+ @wttest.skip_for_hook("timestamp", "strange interaction with timestamps and named checkpoints using target")
def test_checkpoint_target(self):
# Create 3 objects, change one record to an easily recognizable string.
uri = self.uri + '1'
diff --git a/src/third_party/wiredtiger/test/suite/test_compact01.py b/src/third_party/wiredtiger/test/suite/test_compact01.py
index 9790816805c..4193a9e2dea 100755
--- a/src/third_party/wiredtiger/test/suite/test_compact01.py
+++ b/src/third_party/wiredtiger/test/suite/test_compact01.py
@@ -73,6 +73,7 @@ class test_compact(wttest.WiredTigerTestCase, suite_subprocess):
return statDict
# Test compaction.
+ @wttest.skip_for_hook("timestamp", "removing timestamped items will not free space")
def test_compact(self):
# Populate an object
uri = self.type + self.name
@@ -88,11 +89,11 @@ class test_compact(wttest.WiredTigerTestCase, suite_subprocess):
stat_cursor.close()
# Remove most of the object.
- c1 = self.session.open_cursor(uri, None)
+ c1 = ds.open_cursor(uri, None)
c1.set_key(ds.key(5))
- c2 = self.session.open_cursor(uri, None)
+ c2 = ds.open_cursor(uri, None)
c2.set_key(ds.key(self.nentries - 5))
- self.session.truncate(None, c1, c2, None)
+ ds.truncate(None, c1, c2, None)
c1.close()
c2.close()
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor06.py b/src/third_party/wiredtiger/test/suite/test_cursor06.py
index 88364288f83..03eafeed145 100755
--- a/src/third_party/wiredtiger/test/suite/test_cursor06.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor06.py
@@ -62,7 +62,7 @@ class test_cursor06(wttest.WiredTigerTestCase):
cursor.set_key(self.ds.key(10))
cursor.set_value(self.ds.value(10))
- @wttest.skip_for_hook("tiered", "crashes on final connection close") # FIXME-WT-9809
+ @wttest.skip_for_hook("timestamp", "crashes on final connection close") # FIXME-WT-9809
def test_reconfigure_overwrite(self):
uri = self.type + self.name
for open_config in (None, "overwrite=0", "overwrite=1"):
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor12.py b/src/third_party/wiredtiger/test/suite/test_cursor12.py
index 614bf5c713c..fb6187137e6 100755
--- a/src/third_party/wiredtiger/test/suite/test_cursor12.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor12.py
@@ -339,7 +339,7 @@ class test_cursor12(wttest.WiredTigerTestCase):
self.modify_confirm(ds, False)
# Check that we can perform a large number of modifications to a record.
- @wttest.skip_for_hook("tiered", "crashes on commit_transaction or connection close") # FIXME-WT-9809
+ @wttest.skip_for_hook("timestamp", "crashes on commit_transaction or connection close") # FIXME-WT-9809
def test_modify_many(self):
ds = SimpleDataSet(self,
self.uri, 20, key_format=self.keyfmt, value_format=self.valuefmt)
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor17.py b/src/third_party/wiredtiger/test/suite/test_cursor17.py
index 84cfc4d7c27..dbdddab1f6b 100755
--- a/src/third_party/wiredtiger/test/suite/test_cursor17.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor17.py
@@ -60,7 +60,7 @@ class test_cursor17(wttest.WiredTigerTestCase):
self.ds = self.dataset(self, self.type + self.tablename, rownum, key_format=self.keyformat)
self.ds.populate()
- @wttest.skip_for_hook("tiered", "fails assertion 99") # FIXME-WT-9809
+ @wttest.skip_for_hook("timestamp", "fails assertion 99") # FIXME-WT-9809
def test_globally_deleted_key(self):
self.populate(100)
diff --git a/src/third_party/wiredtiger/test/suite/test_flcs01.py b/src/third_party/wiredtiger/test/suite/test_flcs01.py
index fae21b7e02c..44b2bbf551c 100755
--- a/src/third_party/wiredtiger/test/suite/test_flcs01.py
+++ b/src/third_party/wiredtiger/test/suite/test_flcs01.py
@@ -105,7 +105,7 @@ class test_flcs01(wttest.WiredTigerTestCase):
self.check_prev(cursor, k, 0)
self.session.rollback_transaction()
- @wttest.skip_for_hook("tiered", "crashes in evict function, during cursor reset") # FIXME-WT-9809
+ @wttest.skip_for_hook("timestamp", "crashes in evict function, during cursor reset") # FIXME-WT-9809
def test_flcs(self):
uri = "table:test_flcs01"
nrows = 44
diff --git a/src/third_party/wiredtiger/test/suite/test_flcs05.py b/src/third_party/wiredtiger/test/suite/test_flcs05.py
index cff43208d7d..8bb60bab6f4 100755
--- a/src/third_party/wiredtiger/test/suite/test_flcs05.py
+++ b/src/third_party/wiredtiger/test/suite/test_flcs05.py
@@ -56,7 +56,7 @@ class test_flcs05(wttest.WiredTigerTestCase):
self.session.rollback_transaction()
evict_cursor.close()
- @wttest.skip_for_hook("tiered", "fails at begin_transaction") # FIXME-WT-9809
+ @wttest.skip_for_hook("timestamp", "fails at begin_transaction") # FIXME-WT-9809
def test_flcs(self):
uri = "table:test_flcs05"
nrows = 44
diff --git a/src/third_party/wiredtiger/test/suite/test_inmem01.py b/src/third_party/wiredtiger/test/suite/test_inmem01.py
index 14263a1648e..4764f526030 100644
--- a/src/third_party/wiredtiger/test/suite/test_inmem01.py
+++ b/src/third_party/wiredtiger/test/suite/test_inmem01.py
@@ -63,7 +63,7 @@ class test_inmem01(wttest.WiredTigerTestCase):
# Figure out the last key we successfully inserted, and check all
# previous inserts are still there.
- cursor = self.session.open_cursor(self.uri, None)
+ cursor = ds.open_cursor(self.uri, None)
cursor.prev()
last_key = int(cursor.get_key())
ds = SimpleDataSet(self, self.uri, last_key, key_format=self.keyfmt,
@@ -81,13 +81,15 @@ class test_inmem01(wttest.WiredTigerTestCase):
# Now that the database contains as much data as will fit into
# the configured cache, verify removes succeed.
- cursor = self.session.open_cursor(self.uri, None)
+ cursor = ds.open_cursor(self.uri, None)
for i in range(1, 100):
cursor.set_key(ds.key(i))
self.assertEqual(cursor.remove(), 0)
# Run queries after adding, removing and re-inserting data.
# Try out keeping a cursor open while adding new data.
+
+ @wttest.skip_for_hook("timestamp", "removing timestamped items will not free space")
def test_insert_over_delete_replace(self):
msg = '/WT_CACHE_FULL.*/'
ds = SimpleDataSet(self, self.uri, 10000000, key_format=self.keyfmt,
@@ -95,7 +97,7 @@ class test_inmem01(wttest.WiredTigerTestCase):
self.assertRaisesHavingMessage(wiredtiger.WiredTigerError,
ds.populate, msg)
- cursor = self.session.open_cursor(self.uri, None)
+ cursor = ds.open_cursor(self.uri, None)
cursor.prev()
last_key = int(cursor.get_key())
@@ -141,7 +143,7 @@ class test_inmem01(wttest.WiredTigerTestCase):
# Now that the database contains as much data as will fit into
# the configured cache, verify removes succeed.
- cursor = self.session.open_cursor(self.uri, None)
+ cursor = ds.open_cursor(self.uri, None)
for i in range(1, last_key // 4, 1):
cursor.set_key(ds.key(i))
self.assertEqual(cursor.remove(), 0)
@@ -176,7 +178,7 @@ class test_inmem01(wttest.WiredTigerTestCase):
ds = SimpleDataSet(self, self.uri, 0, key_format=self.keyfmt,
value_format=self.valuefmt, config=self.table_config)
ds.populate()
- cursor = self.session.open_cursor(self.uri, None)
+ cursor = ds.open_cursor(self.uri, None)
run = 0
start, last_key = -1000, 0
diff --git a/src/third_party/wiredtiger/test/suite/test_stat01.py b/src/third_party/wiredtiger/test/suite/test_stat01.py
index 6a4ad5423ad..5431a6f892d 100755
--- a/src/third_party/wiredtiger/test/suite/test_stat01.py
+++ b/src/third_party/wiredtiger/test/suite/test_stat01.py
@@ -142,6 +142,7 @@ class test_stat01(wttest.WiredTigerTestCase):
cursor.close()
# Test simple per-checkpoint statistics.
+ @wttest.skip_for_hook("timestamp", "__txn_visiable_all_id assertion hit") # FIXME-WT-9809
def test_checkpoint_stats(self):
ds = SimpleDataSet(self, self.uri, self.nentries,
config=self.config, key_format=self.keyfmt)
diff --git a/src/third_party/wiredtiger/test/suite/test_stat05.py b/src/third_party/wiredtiger/test/suite/test_stat05.py
index 6de398c0524..a93b309e585 100644
--- a/src/third_party/wiredtiger/test/suite/test_stat05.py
+++ b/src/third_party/wiredtiger/test/suite/test_stat05.py
@@ -92,7 +92,7 @@ class test_stat_cursor_config(wttest.WiredTigerTestCase):
self, self.uri, 100, key_format=key_format, value_format=value_format, config=self.cfg)
ds.populate()
self.openAndWalkStatCursor()
- cursor = self.session.open_cursor(self.uri, None)
+ cursor = ds.open_cursor(self.uri, None)
for i in range(100, 40000 + 1):
if i % 100 == 0:
self.openAndWalkStatCursor()
diff --git a/src/third_party/wiredtiger/test/suite/wtdataset.py b/src/third_party/wiredtiger/test/suite/wtdataset.py
index afda18043b6..c6c399625ec 100755
--- a/src/third_party/wiredtiger/test/suite/wtdataset.py
+++ b/src/third_party/wiredtiger/test/suite/wtdataset.py
@@ -58,7 +58,7 @@ class BaseDataSet(object):
if session == None:
session = self.testcase.session
c = session.open_cursor(uri, None, config)
- return wttimestamp.TimestampedCursor(c, self.timestamp, self.testcase)
+ return wttimestamp.TimestampedCursor(session, c, self.timestamp, self.testcase)
def truncate(self, uri, c1, c2, config, session=None):
if session == None:
diff --git a/src/third_party/wiredtiger/test/suite/wthooks.py b/src/third_party/wiredtiger/test/suite/wthooks.py
index 2ee0e26c499..5f52a1def1f 100755
--- a/src/third_party/wiredtiger/test/suite/wthooks.py
+++ b/src/third_party/wiredtiger/test/suite/wthooks.py
@@ -143,7 +143,7 @@ def hooked_function(self, orig_func, hook_info_name, *args):
class WiredTigerHookManager(object):
def __init__(self, hooknames = []):
self.hooks = []
- self.platform_api = None
+ self.platform_apis = []
names_seen = []
for name in hooknames:
# The hooks are indicated as "somename=arg" or simply "somename".
@@ -172,16 +172,8 @@ class WiredTigerHookManager(object):
for hook in self.hooks:
hook.setup_hooks()
api = hook.get_platform_api() # can return None
- if api:
- # We currently don't allow multiple platforms to create their own API,
- # but this could be relaxed. Imagine that hooks implement subsets of the
- # API. We could create an ordered list, and try each platform_api in turn.
- if self.platform_api:
- raise Exception('Running multiple hooks, each with their own platform API, ' +
- 'is not implemented')
- self.platform_api = api
- if self.platform_api == None:
- self.platform_api = DefaultPlatformAPI()
+ self.platform_apis.append(api)
+ self.platform_apis.append(DefaultPlatformAPI())
def add_hook(self, clazz, method_name, hook_type, hook_func):
if not hasattr(clazz, method_name):
@@ -244,7 +236,7 @@ class WiredTigerHookManager(object):
return self.hook_names
def get_platform_api(self):
- return self.platform_api
+ return MultiPlatformAPI(self.platform_apis)
# Returns a list of hook names that use something on the list
def hooks_using(self, use_list):
@@ -297,39 +289,28 @@ class WiredTigerHookCreator(ABC):
def uses(self, use_list):
return False
-class WiredTigerHookPlatformAPI(ABC):
- @abstractmethod
+class WiredTigerHookPlatformAPI(object):
def setUp(self):
"""Called at the beginning of a test case"""
pass
- @abstractmethod
def tearDown(self):
"""Called at the termination of a test case"""
pass
- @abstractmethod
def tableExists(self, name):
"""Return boolean if local files exist for the table with the given base name"""
- pass
+ raise NotImplementedError('tableExists method not implemented')
- @abstractmethod
def initialFileName(self, uri):
"""The first local backing file name created for this URI."""
- pass
+ raise NotImplementedError('initialFileName method not implemented')
- @abstractmethod
def getTimestamp(self):
"""The timestamp generator for this test case."""
- pass
+ raise NotImplementedError('getTimestamp method not implemented')
class DefaultPlatformAPI(WiredTigerHookPlatformAPI):
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
def tableExists(self, name):
tablename = name + ".wt"
return os.path.exists(tablename)
@@ -345,3 +326,44 @@ class DefaultPlatformAPI(WiredTigerHookPlatformAPI):
# By default, there is no automatic timestamping by test infrastructure classes.
def getTimestamp(self):
return None
+
+class MultiPlatformAPI(WiredTigerHookPlatformAPI):
+ def __init__(self, platform_apis):
+ self.apis = platform_apis
+
+ def setUp(self):
+ """Called at the beginning of a test case"""
+ for api in self.apis:
+ api.setUp()
+
+ def tearDown(self):
+ """Called at the termination of a test case"""
+ for api in self.apis:
+ api.tearDown()
+
+ def tableExists(self, name):
+ """Return boolean if local files exist for the table with the given base name"""
+ for api in self.apis:
+ try:
+ return api.tableExists(name)
+ except NotImplementedError:
+ pass
+ raise Exception('tableExists: no implementation') # should never happen
+
+ def initialFileName(self, uri):
+ """The first local backing file name created for this URI."""
+ for api in self.apis:
+ try:
+ return api.initialFileName(uri)
+ except NotImplementedError:
+ pass
+ raise Exception('initialFileName: no implementation') # should never happen
+
+ def getTimestamp(self):
+ """The timestamp generator for this test case."""
+ for api in self.apis:
+ try:
+ return api.getTimestamp()
+ except NotImplementedError:
+ pass
+ raise Exception('getTimestamp: no implementation') # should never happen
diff --git a/src/third_party/wiredtiger/test/suite/wttimestamp.py b/src/third_party/wiredtiger/test/suite/wttimestamp.py
index 26fff886d65..03edd2e7c7c 100755
--- a/src/third_party/wiredtiger/test/suite/wttimestamp.py
+++ b/src/third_party/wiredtiger/test/suite/wttimestamp.py
@@ -49,7 +49,8 @@ class WiredTigerTimeStamp(object):
@contextmanager
def session_timestamped_transaction(session, timestamper):
need_commit = False
- if timestamper != None and not getattr(session, "_has_transaction", False):
+ if timestamper != None and \
+ not (hasattr(session, "_has_transaction") and session._has_transaction):
session.begin_transaction()
need_commit = True
yield
@@ -66,10 +67,13 @@ def session_timestamped_transaction(session, timestamper):
# are passed to the implementation object (via __getattr__),
# except for the ones that we explicitly override here.
class TimestampedCursor(wiredtiger.Cursor):
- def __init__(self, cursor, timeStamper, testcase):
+ def __init__(self, session, cursor, timeStamper, testcase):
self._cursor = cursor
self._timeStamper = timeStamper
self._testcase = testcase
+ self._session = session
+ if not hasattr(session, "_has_transaction"):
+ session._has_transaction = False
def __getattr__(self, name):
return getattr(self._cursor, name)
@@ -77,11 +81,7 @@ class TimestampedCursor(wiredtiger.Cursor):
# A more convenient way to "wrap" an operation in a transaction
@contextmanager
def timestamped_transaction(self):
- # Prefer the _session object if available, it returns a Python
- # Session object that is 1-1 mapped to the WT_SESSION in the C API.
- session = getattr(self._cursor, "_session", self._cursor.session)
- timestamper = self._timeStamper
- with session_timestamped_transaction(session, timestamper):
+ with session_timestamped_transaction(self._session, self._timeStamper):
yield
# Overrides Cursor.insert