diff options
Diffstat (limited to 'src/third_party/wiredtiger/test/suite')
13 files changed, 285 insertions, 82 deletions
diff --git a/src/third_party/wiredtiger/test/suite/test_bug022.py b/src/third_party/wiredtiger/test/suite/test_bug022.py index 31fb2387662..8e7b355133e 100644 --- a/src/third_party/wiredtiger/test/suite/test_bug022.py +++ b/src/third_party/wiredtiger/test/suite/test_bug022.py @@ -30,27 +30,37 @@ # Testing that we don't allow modifies on top of tombstone updates. import wiredtiger, wttest +from wtscenario import make_scenarios class test_bug022(wttest.WiredTigerTestCase): uri = 'file:test_bug022' conn_config = 'cache_size=50MB' session_config = 'isolation=snapshot' + key_format_values = [ + ('string-row', dict(key_format='S', usestrings=True)), + ('column', dict(key_format='r', usestrings=False)), + ] + scenarios = make_scenarios(key_format_values) + + def get_key(self, i): + return str(i) if self.usestrings else i + def test_apply_modifies_on_onpage_tombstone(self): - self.session.create(self.uri, 'key_format=S,value_format=S') + self.session.create(self.uri, 'key_format={},value_format=S'.format(self.key_format)) self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(1)) cursor = self.session.open_cursor(self.uri) value = 'a' * 500 for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value + cursor[self.get_key(i)] = value self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(2)) # Apply tombstones for every key. for i in range(1, 10000): self.session.begin_transaction() - cursor.set_key(str(i)) + cursor.set_key(self.get_key(i)) cursor.remove() self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(3)) @@ -59,11 +69,11 @@ class test_bug022(wttest.WiredTigerTestCase): # Now try to apply a modify on top of the tombstone at timestamp 3. for i in range(1, 10000): self.session.begin_transaction() - cursor.set_key(str(i)) + cursor.set_key(self.get_key(i)) self.assertEqual(cursor.modify([wiredtiger.Modify('B', 0, 100)]), wiredtiger.WT_NOTFOUND) self.session.rollback_transaction() # Check that the tombstone is visible. for i in range(1, 10000): - cursor.set_key(str(i)) + cursor.set_key(self.get_key(i)) self.assertEqual(cursor.search(), wiredtiger.WT_NOTFOUND) diff --git a/src/third_party/wiredtiger/test/suite/test_durable_ts03.py b/src/third_party/wiredtiger/test/suite/test_durable_ts03.py index deea2f3dfc5..ea3fe771169 100755 --- a/src/third_party/wiredtiger/test/suite/test_durable_ts03.py +++ b/src/third_party/wiredtiger/test/suite/test_durable_ts03.py @@ -28,6 +28,7 @@ from helper import copy_wiredtiger_home import wiredtiger, wttest +from wtscenario import make_scenarios # test_durable_ts03.py # Check that the checkpoint honors the durable timestamp of updates. @@ -35,11 +36,17 @@ class test_durable_ts03(wttest.WiredTigerTestCase): conn_config = 'cache_size=10MB' session_config = 'isolation=snapshot' + key_format_values = [ + ('integer-row', dict(key_format='i')), + ('column', dict(key_format='r')), + ] + scenarios = make_scenarios(key_format_values) + def test_durable_ts03(self): # Create a table. uri = 'table:test_durable_ts03' nrows = 3000 - self.session.create(uri, 'key_format=i,value_format=u') + self.session.create(uri, 'key_format={},value_format=u'.format(self.key_format)) valueA = b"aaaaa" * 100 valueB = b"bbbbb" * 100 valueC = b"ccccc" * 100 @@ -51,7 +58,7 @@ class test_durable_ts03(wttest.WiredTigerTestCase): # Load the data into the table. session = self.conn.open_session(self.session_config) cursor = session.open_cursor(uri, None) - for i in range(0, nrows): + for i in range(1, nrows + 1): session.begin_transaction() cursor[i] = valueA session.commit_transaction('commit_timestamp=' + self.timestamp_str(50)) @@ -65,7 +72,7 @@ class test_durable_ts03(wttest.WiredTigerTestCase): # Update all the values within transaction. Commit the transaction with # a durable timestamp newer than the stable timestamp. cursor = session.open_cursor(uri, None) - for i in range(0, nrows): + for i in range(1, nrows + 1): session.begin_transaction() cursor[i] = valueB session.prepare_transaction('prepare_timestamp=' + self.timestamp_str(150)) @@ -105,7 +112,7 @@ class test_durable_ts03(wttest.WiredTigerTestCase): self.assertEqual(value, valueA) self.assertEquals(cursor.reset(), 0) - for i in range(0, nrows): + for i in range(1, nrows + 1): session.begin_transaction() cursor[i] = valueC session.prepare_transaction('prepare_timestamp=' + self.timestamp_str(220)) diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp10.py b/src/third_party/wiredtiger/test/suite/test_timestamp10.py index 4af2004c162..be6dafc5c38 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp10.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp10.py @@ -45,6 +45,10 @@ class test_timestamp10(wttest.WiredTigerTestCase, suite_subprocess): nentries = 10 table_cnt = 3 + key_format_values = [ + ('integer-row', dict(key_format='i')), + ('column', dict(key_format='r')), + ] types = [ ('all', dict(use_stable='false', run_wt=0)), ('all+wt', dict(use_stable='false', run_wt=1)), @@ -56,7 +60,7 @@ class test_timestamp10(wttest.WiredTigerTestCase, suite_subprocess): ('stable+wt', dict(use_stable='true', run_wt=1)), ('stable+wt2', dict(use_stable='true', run_wt=2)), ] - scenarios = make_scenarios(types) + scenarios = make_scenarios(key_format_values, types) def data_and_checkpoint(self): # @@ -64,10 +68,11 @@ class test_timestamp10(wttest.WiredTigerTestCase, suite_subprocess): # Add data to each of them separately and checkpoint so that each one # has a different stable timestamp. # - self.session.create(self.oplog_uri, 'key_format=i,value_format=i') - self.session.create(self.coll1_uri, 'key_format=i,value_format=i,log=(enabled=false)') - self.session.create(self.coll2_uri, 'key_format=i,value_format=i,log=(enabled=false)') - self.session.create(self.coll3_uri, 'key_format=i,value_format=i,log=(enabled=false)') + basecfg = 'key_format={},value_format=i'.format(self.key_format) + self.session.create(self.oplog_uri, basecfg) + self.session.create(self.coll1_uri, basecfg + ',log=(enabled=false)') + self.session.create(self.coll2_uri, basecfg + ',log=(enabled=false)') + self.session.create(self.coll3_uri, basecfg + ',log=(enabled=false)') c_op = self.session.open_cursor(self.oplog_uri) c = [] c.append(self.session.open_cursor(self.coll1_uri)) diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp11.py b/src/third_party/wiredtiger/test/suite/test_timestamp11.py index c4b4210df43..d5998bdc212 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp11.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp11.py @@ -32,14 +32,24 @@ from suite_subprocess import suite_subprocess import wiredtiger, wttest +from wtscenario import make_scenarios class test_timestamp11(wttest.WiredTigerTestCase, suite_subprocess): session_config = 'isolation=snapshot' + key_format_values = [ + ('string-row', dict(key_format='S', usestrings=True)), + ('column', dict(key_format='r', usestrings=False)), + ] + scenarios = make_scenarios(key_format_values) + def test_timestamp_range(self): base = 'timestamp11' uri = 'file:' + base - self.session.create(uri, 'key_format=S,value_format=S') + self.session.create(uri, 'key_format={},value_format=S'.format(self.key_format)) + + key = 'key' if self.usestrings else 1 + key2 = 'key2' if self.usestrings else 2 # Test that mixed timestamp usage where some transactions use timestamps # and others don't behave in the expected way. @@ -49,8 +59,8 @@ class test_timestamp11(wttest.WiredTigerTestCase, suite_subprocess): self.session.begin_transaction() self.session.timestamp_transaction( 'commit_timestamp=' + self.timestamp_str(2)) - c['key'] = 'value2' - c['key2'] = 'value2' + c[key] = 'value2' + c[key2] = 'value2' self.session.commit_transaction() c.close() @@ -62,13 +72,13 @@ class test_timestamp11(wttest.WiredTigerTestCase, suite_subprocess): self.session.begin_transaction() self.session.timestamp_transaction( 'commit_timestamp=' + self.timestamp_str(5)) - c['key'] = 'value5' + c[key] = 'value5' self.session.commit_transaction() c.close() c = self.session.open_cursor(uri) self.session.begin_transaction() - c['key2'] = 'valueNOTS' + c[key2] = 'valueNOTS' self.session.commit_transaction() c.close() @@ -85,15 +95,15 @@ class test_timestamp11(wttest.WiredTigerTestCase, suite_subprocess): c = self.session.open_cursor(uri) self.session.begin_transaction() - self.assertEquals(c['key'], 'value2') - self.assertEquals(c['key2'], 'valueNOTS') + self.assertEquals(c[key], 'value2') + self.assertEquals(c[key2], 'valueNOTS') self.session.commit_transaction() c.close() c = self.session.open_cursor(uri) self.session.begin_transaction('read_timestamp=' + stable_ts) - self.assertEquals(c['key'], 'value2') - self.assertEquals(c['key2'], 'valueNOTS') + self.assertEquals(c[key], 'value2') + self.assertEquals(c[key2], 'valueNOTS') self.session.commit_transaction() c.close() @@ -104,13 +114,13 @@ class test_timestamp11(wttest.WiredTigerTestCase, suite_subprocess): self.session.begin_transaction() self.session.timestamp_transaction( 'commit_timestamp=' + self.timestamp_str(5)) - c['key2'] = 'value5' + c[key2] = 'value5' self.session.commit_transaction() c.close() c = self.session.open_cursor(uri) self.session.begin_transaction() - c['key'] = 'valueNOTS' + c[key] = 'valueNOTS' self.session.commit_transaction() c.close() @@ -119,8 +129,8 @@ class test_timestamp11(wttest.WiredTigerTestCase, suite_subprocess): # Without a timestamp. We should see the latest value for each. c = self.session.open_cursor(uri) self.session.begin_transaction() - self.assertEquals(c['key'], 'valueNOTS') - self.assertEquals(c['key2'], 'value5') + self.assertEquals(c[key], 'valueNOTS') + self.assertEquals(c[key2], 'value5') self.session.commit_transaction() c.close() @@ -128,8 +138,8 @@ class test_timestamp11(wttest.WiredTigerTestCase, suite_subprocess): # value at timestamp 2. c = self.session.open_cursor(uri) self.session.begin_transaction('read_timestamp=' + stable_ts) - self.assertEquals(c['key'], 'valueNOTS') - self.assertEquals(c['key2'], 'valueNOTS') + self.assertEquals(c[key], 'valueNOTS') + self.assertEquals(c[key2], 'valueNOTS') self.session.commit_transaction() c.close() @@ -138,8 +148,8 @@ class test_timestamp11(wttest.WiredTigerTestCase, suite_subprocess): # we inserted at timestamp 5 after the non-timestamped insert. c = self.session.open_cursor(uri) self.session.begin_transaction('read_timestamp=' + self.timestamp_str(5)) - self.assertEquals(c['key'], 'valueNOTS') - self.assertEquals(c['key2'], 'value5') + self.assertEquals(c[key], 'valueNOTS') + self.assertEquals(c[key2], 'value5') self.session.commit_transaction() c.close() diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp12.py b/src/third_party/wiredtiger/test/suite/test_timestamp12.py index e54ed923474..5ccab50ce05 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp12.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp12.py @@ -38,12 +38,16 @@ class test_timestamp12(wttest.WiredTigerTestCase): session_config = 'isolation=snapshot' coll_uri = 'table:collection12' oplog_uri = 'table:oplog12' + key_format_values = [ + ('integer-row', dict(key_format='i')), + ('column', dict(key_format='r')), + ] closecfg = [ ('dfl', dict(close_cfg='', all_expected=False)), ('use_stable', dict(close_cfg='use_timestamp=true', all_expected=False)), ('all_dirty', dict(close_cfg='use_timestamp=false', all_expected=True)), - ] - scenarios = make_scenarios(closecfg) + ] + scenarios = make_scenarios(key_format_values, closecfg) def verify_expected(self, op_exp, coll_exp): c_op = self.session.open_cursor(self.oplog_uri) @@ -67,8 +71,9 @@ class test_timestamp12(wttest.WiredTigerTestCase): # Add data to each of them separately and checkpoint so that each one # has a different stable timestamp. # - self.session.create(self.oplog_uri, 'key_format=i,value_format=i') - self.session.create(self.coll_uri, 'key_format=i,value_format=i,log=(enabled=false)') + basecfg = 'key_format={},value_format=i'.format(self.key_format) + self.session.create(self.oplog_uri, basecfg) + self.session.create(self.coll_uri, basecfg + ',log=(enabled=false)') c_op = self.session.open_cursor(self.oplog_uri) c_coll = self.session.open_cursor(self.coll_uri) diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp14.py b/src/third_party/wiredtiger/test/suite/test_timestamp14.py index 8d6e753bf4d..3b4c4bf40ae 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp14.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp14.py @@ -40,6 +40,12 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): uri = 'table:' + tablename session_config = 'isolation=snapshot' + key_format_values = [ + ('integer-row', dict(key_format='i')), + ('column', dict(key_format='r')), + ] + scenarios = make_scenarios(key_format_values) + def test_all_durable_old(self): # This test was originally for testing the all_committed timestamp. # In the absence of prepared transactions, all_durable is identical to @@ -47,8 +53,8 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): all_durable_uri = self.uri + '_all_durable' session1 = self.setUpSessionOpen(self.conn) session2 = self.setUpSessionOpen(self.conn) - session1.create(all_durable_uri, 'key_format=i,value_format=i') - session2.create(all_durable_uri, 'key_format=i,value_format=i') + session1.create(all_durable_uri, 'key_format={},value_format=i'.format(self.key_format)) + session2.create(all_durable_uri, 'key_format={},value_format=i'.format(self.key_format)) # Scenario 0: No commit timestamp has ever been specified therefore # There is no all_durable timestamp and we will get an error @@ -132,8 +138,8 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): oldest_reader_uri = self.uri + '_oldest_reader_pinned' session1 = self.setUpSessionOpen(self.conn) session2 = self.setUpSessionOpen(self.conn) - session1.create(oldest_reader_uri, 'key_format=i,value_format=i') - session2.create(oldest_reader_uri, 'key_format=i,value_format=i') + session1.create(oldest_reader_uri, 'key_format={},value_format=i'.format(self.key_format)) + session2.create(oldest_reader_uri, 'key_format={},value_format=i'.format(self.key_format)) # Nothing is reading so there is no oldest reader. self.assertRaisesException(wiredtiger.WiredTigerError, @@ -190,7 +196,7 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): def test_pinned_oldest(self): pinned_oldest_uri = self.uri + 'pinned_oldest' session1 = self.setUpSessionOpen(self.conn) - session1.create(pinned_oldest_uri, 'key_format=i,value_format=i') + session1.create(pinned_oldest_uri, 'key_format={},value_format=i'.format(self.key_format)) # Confirm no oldest timestamp exists. self.assertRaisesException(wiredtiger.WiredTigerError, lambda: self.conn.query_timestamp('get=oldest')) @@ -241,7 +247,7 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): def test_all_durable(self): all_durable_uri = self.uri + '_all_durable' session1 = self.setUpSessionOpen(self.conn) - session1.create(all_durable_uri, 'key_format=i,value_format=i') + session1.create(all_durable_uri, 'key_format={},value_format=i'.format(self.key_format)) # Since this is a non-prepared transaction, we'll be using the commit # timestamp when calculating all_durable since it's implied that they're @@ -329,8 +335,8 @@ class test_timestamp14(wttest.WiredTigerTestCase, suite_subprocess): all_uri = self.uri + 'pinned_oldest' session1 = self.setUpSessionOpen(self.conn) session2 = self.setUpSessionOpen(self.conn) - session1.create(all_uri, 'key_format=i,value_format=i') - session2.create(all_uri, 'key_format=i,value_format=i') + session1.create(all_uri, 'key_format={},value_format=i'.format(self.key_format)) + session2.create(all_uri, 'key_format={},value_format=i'.format(self.key_format)) cur1 = session1.open_cursor(all_uri) cur2 = session2.open_cursor(all_uri) # Set up oldest timestamp. diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp16.py b/src/third_party/wiredtiger/test/suite/test_timestamp16.py index f74557ad2c6..2485a14be12 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp16.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp16.py @@ -34,7 +34,6 @@ import random from suite_subprocess import suite_subprocess import wiredtiger, wttest -from wtscenario import make_scenarios class test_timestamp16(wttest.WiredTigerTestCase, suite_subprocess): tablename = 'test_timestamp16' diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp17.py b/src/third_party/wiredtiger/test/suite/test_timestamp17.py index 3c2453b0aa2..fe4ec606d23 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp17.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp17.py @@ -43,8 +43,14 @@ class test_timestamp17(wttest.WiredTigerTestCase, suite_subprocess): uri = 'table:' + tablename session_config = 'isolation=snapshot' + key_format_values = [ + ('integer-row', dict(key_format='i')), + ('column', dict(key_format='r')), + ] + scenarios = make_scenarios(key_format_values) + def test_inconsistent_timestamping(self): - self.session.create(self.uri, 'key_format=i,value_format=i') + self.session.create(self.uri, 'key_format={},value_format=i'.format(self.key_format)) self.session.begin_transaction() cur1 = self.session.open_cursor(self.uri) cur1[1] = 1 diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp18.py b/src/third_party/wiredtiger/test/suite/test_timestamp18.py index c7f20dbd9a4..b41fc5ccb34 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp18.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp18.py @@ -41,15 +41,23 @@ from wtscenario import make_scenarios class test_timestamp18(wttest.WiredTigerTestCase): conn_config = 'cache_size=50MB' session_config = 'isolation=snapshot' + + key_format_values = [ + ('string-row', dict(key_format='S', usestrings=True)), + ('column', dict(key_format='r', usestrings=False)), + ] non_ts_writes = [ ('insert', dict(delete=False)), ('delete', dict(delete=True)), ] - scenarios = make_scenarios(non_ts_writes) + scenarios = make_scenarios(key_format_values, non_ts_writes) + + def get_key(self, i): + return str(i) if self.usestrings else i def test_ts_writes_with_non_ts_write(self): uri = 'table:test_timestamp18' - self.session.create(uri, 'key_format=S,value_format=S') + self.session.create(uri, 'key_format={},value_format=S'.format(self.key_format)) self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(1)) cursor = self.session.open_cursor(uri) @@ -61,17 +69,17 @@ class test_timestamp18(wttest.WiredTigerTestCase): # A series of timestamped writes on each key. for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value1 + cursor[self.get_key(i)] = value1 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(2)) for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value2 + cursor[self.get_key(i)] = value2 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(3)) for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value3 + cursor[self.get_key(i)] = value3 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(4)) # Add a non-timestamped delete. @@ -80,10 +88,10 @@ class test_timestamp18(wttest.WiredTigerTestCase): for i in range(1, 10000): if i % 2 == 0: if self.delete: - cursor.set_key(str(i)) + cursor.set_key(self.get_key(i)) cursor.remove() else: - cursor[str(i)] = value4 + cursor[self.get_key(i)] = value4 self.session.checkpoint() @@ -94,16 +102,16 @@ class test_timestamp18(wttest.WiredTigerTestCase): # invisible. if i % 2 == 0: if self.delete: - cursor.set_key(str(i)) + cursor.set_key(self.get_key(i)) self.assertEqual(cursor.search(), wiredtiger.WT_NOTFOUND) else: - self.assertEqual(cursor[str(i)], value4) + self.assertEqual(cursor[self.get_key(i)], value4) # Otherwise, expect one of the timestamped writes. else: if ts == 2: - self.assertEqual(cursor[str(i)], value1) + self.assertEqual(cursor[self.get_key(i)], value1) elif ts == 3: - self.assertEqual(cursor[str(i)], value2) + self.assertEqual(cursor[self.get_key(i)], value2) else: - self.assertEqual(cursor[str(i)], value3) + self.assertEqual(cursor[self.get_key(i)], value3) self.session.rollback_transaction() diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp19.py b/src/third_party/wiredtiger/test/suite/test_timestamp19.py index 9f5b71df843..e271c8f1145 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp19.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp19.py @@ -30,15 +30,22 @@ # Use the oldest timestamp in the metadata as the oldest timestamp on restart. import wiredtiger, wttest from wtdataset import SimpleDataSet +from wtscenario import make_scenarios class test_timestamp19(wttest.WiredTigerTestCase): conn_config = 'cache_size=50MB,log=(enabled)' session_config = 'isolation=snapshot' + key_format_values = [ + ('integer-row', dict(key_format='i')), + ('column', dict(key_format='r')), + ] + scenarios = make_scenarios(key_format_values) + def updates(self, uri, value, ds, nrows, commit_ts): session = self.session cursor = session.open_cursor(uri) - for i in range(0, nrows): + for i in range(1, nrows + 1): session.begin_transaction() cursor[ds.key(i)] = value session.commit_transaction('commit_timestamp=' + self.timestamp_str(commit_ts)) @@ -46,11 +53,11 @@ class test_timestamp19(wttest.WiredTigerTestCase): def test_timestamp(self): uri = "table:test_timestamp19" - create_params = 'value_format=S,key_format=i' + create_params = 'key_format={},value_format=S'.format(self.key_format) self.session.create(uri, create_params) ds = SimpleDataSet( - self, uri, 0, key_format="i", value_format="S", config='log=(enabled=false)') + self, uri, 0, key_format=self.key_format, value_format="S", config='log=(enabled=false)') ds.populate() nrows = 1000 diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp20.py b/src/third_party/wiredtiger/test/suite/test_timestamp20.py index c4edcbfe592..7bfeb670004 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp20.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp20.py @@ -27,6 +27,7 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest +from wtscenario import make_scenarios # test_timestamp20.py # Exercise fixing up of out-of-order updates in the history store. @@ -34,9 +35,18 @@ class test_timestamp20(wttest.WiredTigerTestCase): conn_config = 'cache_size=50MB' session_config = 'isolation=snapshot' + key_format_values = [ + ('string-row', dict(key_format='S', usestrings=True)), + ('column', dict(key_format='r', usestrings=False)), + ] + scenarios = make_scenarios(key_format_values) + + def get_key(self, i): + return str(i) if self.usestrings else i + def test_timestamp20_standard(self): uri = 'table:test_timestamp20' - self.session.create(uri, 'key_format=S,value_format=S') + self.session.create(uri, 'key_format={},value_format=S'.format(self.key_format)) self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(1)) cursor = self.session.open_cursor(uri) @@ -48,17 +58,17 @@ class test_timestamp20(wttest.WiredTigerTestCase): for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value1 + cursor[self.get_key(i)] = value1 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(10)) for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value2 + cursor[self.get_key(i)] = value2 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(20)) for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value3 + cursor[self.get_key(i)] = value3 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(30)) old_reader_session = self.conn.open_session() @@ -69,19 +79,19 @@ class test_timestamp20(wttest.WiredTigerTestCase): # correction to the existing contents. for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value4 + cursor[self.get_key(i)] = value4 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(25)) self.session.begin_transaction() - cursor[str(i)] = value5 + cursor[self.get_key(i)] = value5 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(40)) self.session.begin_transaction('read_timestamp=' + self.timestamp_str(30)) for i in range(1, 10000): - self.assertEqual(cursor[str(i)], value4) + self.assertEqual(cursor[self.get_key(i)], value4) self.session.rollback_transaction() for i in range(1, 10000): - self.assertEqual(old_reader_cursor[str(i)], value2) + self.assertEqual(old_reader_cursor[self.get_key(i)], value2) old_reader_session.rollback_transaction() # In this test we're using modifies since they are more sensitive to corruptions. @@ -90,7 +100,7 @@ class test_timestamp20(wttest.WiredTigerTestCase): # the conversion to a Python string. def test_timestamp20_modify(self): uri = 'table:test_timestamp20' - self.session.create(uri, 'key_format=S,value_format=S') + self.session.create(uri, 'key_format={},value_format=S'.format(self.key_format)) self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(1)) cursor = self.session.open_cursor(uri) @@ -101,19 +111,19 @@ class test_timestamp20(wttest.WiredTigerTestCase): # Apply the base value. for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value1 + cursor[self.get_key(i)] = value1 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(10)) # Now apply a series of modifies. for i in range(1, 10000): self.session.begin_transaction() - cursor.set_key(str(i)) + cursor.set_key(self.get_key(i)) self.assertEqual(cursor.modify([wiredtiger.Modify('B', 100, 1)]), 0) self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(20)) for i in range(1, 10000): self.session.begin_transaction() - cursor.set_key(str(i)) + cursor.set_key(self.get_key(i)) self.assertEqual(cursor.modify([wiredtiger.Modify('C', 200, 1)]), 0) self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(30)) @@ -129,7 +139,7 @@ class test_timestamp20(wttest.WiredTigerTestCase): # This will be the end of the chain of modifies. for i in range(1, 10000): self.session.begin_transaction() - cursor.set_key(str(i)) + cursor.set_key(self.get_key(i)) self.assertEqual(cursor.modify([wiredtiger.Modify('D', 300, 1)]), 0) self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(40)) @@ -137,17 +147,17 @@ class test_timestamp20(wttest.WiredTigerTestCase): # correction to the existing contents. for i in range(1, 10000): self.session.begin_transaction() - cursor[str(i)] = value2 + cursor[self.get_key(i)] = value2 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(25)) self.session.begin_transaction() - cursor[str(i)] = value3 + cursor[self.get_key(i)] = value3 self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(50)) # Open up a new transaction and read at 30. # We shouldn't be able to see past 5 due to txnid visibility. self.session.begin_transaction('read_timestamp=' + self.timestamp_str(30)) for i in range(1, 10000): - self.assertEqual(cursor[str(i)], value2) + self.assertEqual(cursor[self.get_key(i)], value2) self.session.rollback_transaction() # Put together expected value. @@ -157,5 +167,5 @@ class test_timestamp20(wttest.WiredTigerTestCase): # On the other hand, this older transaction SHOULD be able to read past the 5. for i in range(1, 10000): - self.assertEqual(old_reader_cursor[str(i)], expected) + self.assertEqual(old_reader_cursor[self.get_key(i)], expected) old_reader_session.rollback_transaction() diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp22.py b/src/third_party/wiredtiger/test/suite/test_timestamp22.py index e02dbf99e09..b26b844dd32 100755 --- a/src/third_party/wiredtiger/test/suite/test_timestamp22.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp22.py @@ -31,6 +31,7 @@ import wiredtiger, wttest, re, suite_random from wtdataset import SimpleDataSet from contextlib import contextmanager +from wtscenario import make_scenarios class test_timestamp22(wttest.WiredTigerTestCase): conn_config = 'cache_size=50MB' @@ -46,6 +47,12 @@ class test_timestamp22(wttest.WiredTigerTestCase): SUCCESS = 'success' FAILURE = 'failure' + key_format_values = [ + ('integer-row', dict(key_format='i')), + ('column', dict(key_format='r')), + ] + scenarios = make_scenarios(key_format_values) + # Control execution of an operation, looking for exceptions and error messages. # Usage: # with self.expect(self.FAILURE, 'some operation'): @@ -240,7 +247,7 @@ class test_timestamp22(wttest.WiredTigerTestCase): msg = 'inserts with commit config(' + commit_config + ')' try: - for i in range(0, self.nrows): + for i in range(1, self.nrows + 1): needs_rollback = False if self.do_illegal(): # Illegal outside of transaction @@ -380,14 +387,14 @@ class test_timestamp22(wttest.WiredTigerTestCase): else: iterations = 1000 - create_params = 'value_format=S,key_format=i' + create_params = 'key_format={},value_format=S'.format(self.key_format) self.session.create(self.uri, create_params) self.set_global_timestamps(1, 1, -1, -1) # Create tables with no entries ds = SimpleDataSet( - self, self.uri, 0, key_format="i", value_format="S", config='log=(enabled=false)') + self, self.uri, 0, key_format=self.key_format, value_format="S", config='log=(enabled=false)') # We do a bunch of iterations, doing transactions, prepare, and global timestamp calls # with timestamps that are sometimes valid, sometimes not. We use the iteration number @@ -430,7 +437,7 @@ class test_timestamp22(wttest.WiredTigerTestCase): # Make sure the resulting rows are what we expect. cursor = self.session.open_cursor(self.uri) - expect_key = 0 + expect_key = 1 expect_value = self.commit_value for k,v in cursor: self.assertEquals(k, expect_key) @@ -440,7 +447,7 @@ class test_timestamp22(wttest.WiredTigerTestCase): # Although it's theoretically possible to never successfully update a single row, # with a large number of iterations that should never happen. I'd rather catch # a test code error where we mistakenly don't update any rows. - self.assertGreater(expect_key, 0) + self.assertGreater(expect_key, 1) cursor.close() if __name__ == '__main__': diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp23.py b/src/third_party/wiredtiger/test/suite/test_timestamp23.py new file mode 100644 index 00000000000..60d97cf78fb --- /dev/null +++ b/src/third_party/wiredtiger/test/suite/test_timestamp23.py @@ -0,0 +1,123 @@ +#!/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. + +import wiredtiger, wttest +from wtdataset import SimpleDataSet +from wtscenario import make_scenarios + +# test_timestamp23.py +# +# delete keys repeatedly at successive timestamps +class test_timestamp23(wttest.WiredTigerTestCase): + conn_config = '' + session_config = 'isolation=snapshot' + + key_format_values = [ + ('column', dict(key_format='r')), + ('integer_row', dict(key_format='i')), + ] + + scenarios = make_scenarios(key_format_values) + + def test_timestamp(self): + + # Create a file that contains active history (content newer than the oldest timestamp). + table_uri = 'table:timestamp23' + ds = SimpleDataSet( + self, table_uri, 0, key_format=self.key_format, value_format='S', config='log=(enabled=false)') + ds.populate() + self.session.checkpoint() + + key = 5 + value_1 = 'a' * 500 + value_2 = 'b' * 500 + value_3 = 'c' * 500 + + # Pin oldest and stable to timestamp 1. + self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(1) + + ',stable_timestamp=' + self.timestamp_str(1)) + + cursor = self.session.open_cursor(ds.uri) + + # Write two values at timestamp 10. We'll muck with the first value + # and use the second to reference the page for eviction. + self.session.begin_transaction('read_timestamp=10') + cursor[key] = value_1 + cursor[key+1] = value_2 + self.session.commit_transaction('commit_timestamp=11') + + # Delete the first value at timestamp 20. + self.session.begin_transaction('read_timestamp=20') + cursor.set_key(key) + cursor.remove() + self.session.commit_transaction('commit_timestamp=21') + + # Put it back at timestamp 30. + self.session.begin_transaction('read_timestamp=30') + cursor[key] = value_3 + self.session.commit_transaction('commit_timestamp=31') + + # Delete it again at timestamp 40. + self.session.begin_transaction('read_timestamp=40') + cursor.set_key(key) + cursor.remove() + self.session.commit_transaction('commit_timestamp=41') + + # Evict the page using the second key. + evict_cursor = self.session.open_cursor(ds.uri, None, "debug=(release_evict)") + self.session.begin_transaction() + v = evict_cursor[key+1] + self.assertEqual(v, value_2) + self.assertEqual(evict_cursor.reset(), 0) + self.session.rollback_transaction() + + # Create a separate session and a cursor to read the original value at timestamp 12. + session2 = self.conn.open_session() + cursor2 = session2.open_cursor(ds.uri) + session2.begin_transaction('read_timestamp=12') + v = cursor2[key] + self.assertEqual(v, value_1) + + self.session.breakpoint() + + # Now delete the original value. This _should_ cause WT_ROLLBACK, but with a column + # store bug seen and fixed in August 2021, it succeeds, and the resulting invalid + # tombstone will cause reconciliation to assert. (To see this behavior, comment out the + # self.fail call and let the transaction commit.) + try: + cursor2.remove() + self.fail("Conflicting remove did not fail") + session2.commit_transaction('commit_timestamp=50') + except wiredtiger.WiredTigerError as e: + self.assertTrue(wiredtiger.wiredtiger_strerror(wiredtiger.WT_ROLLBACK) in str(e)) + + cursor.close() + cursor2.close() + +if __name__ == '__main__': + wttest.run() |