def cursor_random_multiple_page_records(self, reopen): uri = self.type if uri.startswith('file:'): simple_populate(self, uri, 'allocation_size=512,leaf_page_max=512,key_format=S', 10000) else: complex_populate(self, uri, 'allocation_size=512,leaf_page_max=512,key_format=S', 10000) # Optionally close the connection so everything is forced to disk, # insert lists are an entirely different path in the code. if reopen: self.reopen_conn() cursor = self.session.open_cursor(uri, None, self.config) last = '' match = 0 for i in range(1,10): self.assertEqual(cursor.next(), 0) current = cursor.get_key() if current == last: match += 1 last = current self.assertLess(match, 5, 'next_random did not return random records, too many matches found')
def test_cursor_comparison(self): uri = self.type + 'compare' # Build the object. if self.type == 'file:': simple_populate(self, uri, 'key_format=' + self.keyfmt, 100) else: complex_populate(self, uri, 'key_format=' + self.keyfmt, 100) c1 = self.session.open_cursor(uri, None) c2 = self.session.open_cursor(uri, None) # Confirm the method fails unless the keys are set. msg = '/requires key be set/' self.assertRaisesWithMessage( wiredtiger.WiredTigerError, lambda: c1.compare(c2), msg) self.assertRaisesWithMessage( wiredtiger.WiredTigerError, lambda: c2.compare(c1), msg) # Test cursors in all three orders. c1.set_key(key_populate(c1, 10)) self.assertEquals(c1.search(), 0) c2.set_key(key_populate(c2, 20)) self.assertEquals(c2.search(), 0) self.assertGreater(c2.compare(c1), 0) self.assertLess(c1.compare(c2), 0) c2.set_key(key_populate(c2, 10)) self.assertEquals(c1.compare(c2), 0)
def test_named_snapshots(self): # Populate a table end = start = 0 simple_populate(self, self.uri, 'key_format=i', 0) # Now run a workload: # every iteration: # create a new named snapshot, N # append 20 rows and delete the first 10 # verify that every snapshot N contains the expected number of rows # if there are more than 10 snapshots active, drop the first half snapshots = [] c = self.session.open_cursor(self.uri) for n in xrange(self.nrows / self.nrows_per_snap): if len(snapshots) > self.nsnapshots: middle = len(snapshots) / 2 dropcfg = ",drop=(to=%d)" % snapshots[middle][0] snapshots = snapshots[middle + 1:] else: dropcfg = "" self.session.snapshot("name=%d%s" % (n, dropcfg)) snapshots.append((n, end - start)) for i in xrange(2 * self.nrows_per_snap): c[end + i] = "some value" end += 2 * self.nrows_per_snap for i in xrange(self.nrows_per_snap): del c[start + i] start += self.nrows_per_snap for snapshot, expected in snapshots: self.check_named_snapshot(c, snapshot, expected)
def test_cursor_random_multiple_page_records(self): uri = self.type + 'random' if self.type == 'file:': simple_populate(self, uri, 'allocation_size=512,leaf_page_max=512,key_format=' +\ self.fmt, 10000) else: complex_populate(self, uri, 'allocation_size=512,leaf_page_max=512,key_format=' +\ self.fmt, 10000) # Close the connection so everything is forced to disk (otherwise the # values are on an insert list and the underlying engine doesn't make # random selections, it selects the middle of the list. self.reopen_conn() cursor = self.session.open_cursor(uri, None, "next_random=true") last = '' match = 0 for i in range(1,10): cursor.next() current = cursor.get_key() if current == last: match += 1 last = current self.assertLess(match, 5, 'next_random did not return random records, too many matches found')
def test_checkpoint_last(self): # Create an object, change one record to an easily recognizable string, # then checkpoint it and open a cursor, confirming we see the correct # value. Repeat this action, we want to be sure the engine gets the # latest checkpoint information each time. uri = self.uri simple_populate(self, uri, 'key_format=' + self.fmt, 100) for value in ('FIRST', 'SECOND', 'THIRD', 'FOURTH', 'FIFTH'): # Update the object. cursor = self.session.open_cursor(uri, None, "overwrite") cursor.set_key(key_populate(cursor, 10)) cursor.set_value(value) cursor.insert() cursor.close() # Checkpoint the object. self.session.checkpoint() # Verify the "last" checkpoint sees the correct value. cursor = self.session.open_cursor( uri, None, "checkpoint=WiredTigerCheckpoint") cursor.set_key(key_populate(cursor, 10)) cursor.search() self.assertEquals(cursor.get_value(), value)
def test_cursor_random_reasonable_distribution(self): uri = self.type num_entries = self.records # Set the leaf-page-max value, otherwise the page might split. simple_populate(self, uri, 'leaf_page_max=100MB,key_format=S', num_entries) # Setup an array to track which keys are seen visitedKeys = [0] * (num_entries + 1) cursor = self.session.open_cursor(uri, None, 'next_random=true') for i in range(0, num_entries): self.assertEqual(cursor.next(), 0) current = cursor.get_key() current = int(current) visitedKeys[current] = visitedKeys[current] + 1 differentKeys = sum(x > 0 for x in visitedKeys) #print visitedKeys #print differentKeys ''' self.tty('differentKeys: ' + str(differentKeys) + ' of ' + \ str(num_entries) + ', ' + \ str((int)((differentKeys * 100) / num_entries)) + '%') ''' self.assertGreater(differentKeys, num_entries / 4, 'next_random random distribution not adequate')
def test_checkpoint_inuse(self): simple_populate(self, self.uri, 'key_format=' + self.fmt, 100) self.session.checkpoint("name=checkpoint-1") self.session.checkpoint("name=checkpoint-2") self.session.checkpoint("name=checkpoint-3") cursor = self.session.open_cursor( self.uri, None, "checkpoint=checkpoint-2") # Check creating an identically named checkpoint fails. */ # Check dropping the specific checkpoint fails. # Check dropping all checkpoints fails. msg = '/checkpoints cannot be dropped/' self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.checkpoint("name=checkpoint-2"), msg) self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.checkpoint("drop=(checkpoint-2)"), msg) self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.checkpoint("drop=(from=all)"), msg) # Check dropping other checkpoints succeeds (which also tests that you # can create new checkpoints while other checkpoints are in-use). self.session.checkpoint("drop=(checkpoint-1,checkpoint-3)") # Close the cursor and repeat the failing commands, they should now # succeed. cursor.close() self.session.checkpoint("name=checkpoint-2") self.session.checkpoint("drop=(checkpoint-2)") self.session.checkpoint("drop=(from=all)")
def test_search_eot(self): # Populate the tree and reopen the connection, forcing it to disk # and moving the records to an on-page format. simple_populate(self, self.uri, self.fmt, 100) self.reopen_conn() # Open a cursor. cursor = self.session.open_cursor(self.uri, None) # Search for a record at the end of the table, which should succeed. cursor.set_key(key_populate(cursor, 100)) self.assertEqual(cursor.search(), 0) self.assertEqual(cursor.get_key(), key_populate(cursor, 100)) self.assertEqual(cursor.get_value(), value_populate(cursor, 100)) # Search-near for a record at the end of the table, which should # succeed, returning the last record. cursor.set_key(key_populate(cursor, 100)) self.assertEqual(cursor.search_near(), 0) self.assertEqual(cursor.get_key(), key_populate(cursor, 100)) self.assertEqual(cursor.get_value(), value_populate(cursor, 100)) # Search for a record past the end of the table, which should fail. cursor.set_key(key_populate(cursor, 200)) self.assertEqual(cursor.search(), wiredtiger.WT_NOTFOUND) # Search-near for a record past the end of the table, which should # succeed, returning the last record. cursor.set_key(key_populate(cursor, 200)) self.assertEqual(cursor.search_near(), -1) self.assertEqual(cursor.get_key(), key_populate(cursor, 100)) self.assertEqual(cursor.get_value(), value_populate(cursor, 100))
def test_named_snapshots(self): # Populate a table end = start = 0 simple_populate(self, self.uri, 'key_format=i', 0) snapshots = [] c = self.session.open_cursor(self.uri) for i in xrange(self.nrows_per_itr): c[i] = "some value" # Start a new transaction in a different session new_session = self.conn.open_session() new_session.begin_transaction("isolation=snapshot") new_c = new_session.open_cursor(self.uri) count = 0 for row in new_c: count += 1 new_session.snapshot("name=0") self.check_named_snapshot(0, self.nrows_per_itr) # Insert some more content using the original session. for i in xrange(self.nrows_per_itr): c[2 * self.nrows_per_itr + i] = "some value" self.check_named_snapshot(0, self.nrows_per_itr) new_session.close() # Update the named snapshot self.session.snapshot("name=0") self.check_named_snapshot(0, 2 * self.nrows_per_itr)
def test_basic(self): simple_populate(self, self.uri, self.config + self.keyfmt, self.nentries) self.reopen_conn() c = self.session.open_cursor(self.uri, None) self.forward(c, self.nentries, []) self.backward(c, self.nentries, [])
def test_overwrite_update(self): uri = self.type + self.name simple_populate(self, uri, 'key_format=' + self.keyfmt, 100) # Update of an existing record with overwrite off succeeds. cursor = self.session.open_cursor(uri, None, "overwrite=false") cursor.set_key(key_populate(cursor, 5)) cursor.set_value('XXXXXXXXXX') self.assertEquals(cursor.update(), 0) # Update of an existing record with overwrite on succeeds. cursor = self.session.open_cursor(uri, None) cursor.set_key(key_populate(cursor, 6)) cursor.set_value('XXXXXXXXXX') self.assertEquals(cursor.update(), 0) # Update of a non-existent record with overwrite off fails. cursor = self.session.open_cursor(uri, None, "overwrite=false") cursor.set_key(key_populate(cursor, 200)) cursor.set_value('XXXXXXXXXX') self.assertEquals(cursor.update(), wiredtiger.WT_NOTFOUND) # Update of a non-existent record with overwrite on succeeds. cursor = self.session.open_cursor(uri, None) cursor.set_key(key_populate(cursor, 201)) cursor.set_value('XXXXXXXXXX') self.assertEquals(cursor.update(), 0)
def test_search_invisible_two(self): uri = 'file:test_bug008' # This is a btree layer test. # Populate the tree and reopen the connection, forcing it to disk # and moving the records to an on-page format. simple_populate(self, uri, self.fmt, 100) self.reopen_conn() # Add some additional visible records. cursor = self.session.open_cursor(uri, None) for i in range(100, 120): cursor.set_key(key_populate(cursor, i)) cursor.set_value(value_populate(cursor, i)) cursor.insert() cursor.close() # Begin a transaction, and add some additional records. self.session.begin_transaction() cursor = self.session.open_cursor(uri, None) for i in range(120, 140): cursor.set_key(key_populate(cursor, i)) cursor.set_value(value_populate(cursor, i)) cursor.insert() # Open a separate session and cursor. s = self.conn.open_session() cursor = s.open_cursor(uri, None) # Search for an invisible record. cursor.set_key(key_populate(cursor, 130)) if self.empty: # Invisible updates to fixed-length column-store objects are # invisible to the reader, but the fact that they exist past # the end of the initial records causes the instantiation of # empty records: confirm successful return of an empty row. cursor.search() self.assertEqual(cursor.get_key(), 130) self.assertEqual(cursor.get_value(), 0) else: # Otherwise, we should not find any matching records. self.assertEqual(cursor.search(), wiredtiger.WT_NOTFOUND) # Search-near for an invisible record, which should succeed, returning # the last visible record. cursor.set_key(key_populate(cursor, 130)) cursor.search_near() if self.empty: # Invisible updates to fixed-length column-store objects are # invisible to the reader, but the fact that they exist past # the end of the initial records causes the instantiation of # empty records: confirm successful return of an empty row. cursor.search() self.assertEqual(cursor.get_key(), 130) self.assertEqual(cursor.get_value(), 0) else: # Otherwise, we should find the closest record for which we can see # the value. self.assertEqual(cursor.get_key(), key_populate(cursor, 119)) self.assertEqual(cursor.get_value(), value_populate(cursor, 119))
def test_stat_cursor_dsrc_cache_walk(self): simple_populate(self, self.uri, 'key_format=S', 100) # Ensure that it's an error to get cache_walk stats if none is set msg = '/doesn\'t match the database statistics/' self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.open_cursor( 'statistics:' + self.uri, None, None), msg) # Test configurations that are valid but should not collect # cache walk information. Do these first since the cache walk # statistics are mostly marked as not cleared - so once they are # populated the values will always be returned self.conn.reconfigure('statistics=(cache_walk,fast,clear)') c = self.session.open_cursor( 'statistics:' + self.uri, None, 'statistics=(fast)') self.assertEqual(c[stat.dsrc.cache_state_root_size][2], 0) c.close() self.conn.reconfigure('statistics=(all,clear)') c = self.session.open_cursor( 'statistics:' + self.uri, None, 'statistics=(fast)') self.assertEqual(c[stat.dsrc.cache_state_root_size][2], 0) c.close() self.conn.reconfigure('statistics=(cache_walk,fast,clear)') c = self.session.open_cursor('statistics:' + self.uri, None, None) self.assertGreater(c[stat.dsrc.cache_state_root_size][2], 0) # Verify that cache_walk didn't imply tree_walk self.assertEqual(c[stat.dsrc.btree_entries][2], 0) c.close() self.conn.reconfigure('statistics=(cache_walk,tree_walk,fast,clear)') c = self.session.open_cursor('statistics:' + self.uri, None, None) self.assertGreater(c[stat.dsrc.cache_state_root_size][2], 0) # Verify that cache_walk didn't exclude tree_walk self.assertGreater(c[stat.dsrc.btree_entries][2], 0) c.close() self.conn.reconfigure('statistics=(all,clear)') c = self.session.open_cursor( 'statistics:' + self.uri, None, 'statistics=(all)') self.assertGreater(c[stat.dsrc.cache_state_root_size][2], 0) self.assertGreater(c[stat.dsrc.btree_entries][2], 0) c.close() # Verify that cache and tree walk can operate independantly self.conn.reconfigure('statistics=(all,clear)') c = self.session.open_cursor( 'statistics:' + self.uri, None, 'statistics=(cache_walk,fast)') self.assertGreater(c[stat.dsrc.cache_state_root_size][2], 0) self.assertEqual(c[stat.dsrc.btree_entries][2], 0) c.close() self.conn.reconfigure('statistics=(all,clear)') c = self.session.open_cursor( 'statistics:' + self.uri, None, 'statistics=(tree_walk,fast)') # Don't check the cache walk stats for empty - they won't be cleared self.assertGreater(c[stat.dsrc.btree_entries][2], 0) c.close()
def test_checkpoint_dne(self): simple_populate(self, self.uri, 'key_format=' + self.fmt, 100) self.assertRaises(wiredtiger.WiredTigerError, lambda: self.session.open_cursor( self.uri, None, "checkpoint=checkpoint-1")) self.assertRaises(wiredtiger.WiredTigerError, lambda: self.session.open_cursor( self.uri, None, "checkpoint=WiredTigerCheckpoint"))
def test_checkpoint_dne(self): simple_populate(self, self.uri, 'key_format=' + self.fmt, 100) self.assertRaises( wiredtiger.WiredTigerError, lambda: self.session.open_cursor( self.uri, None, "checkpoint=checkpoint-1")) self.assertRaises( wiredtiger.WiredTigerError, lambda: self.session.open_cursor( self.uri, None, "checkpoint=WiredTigerCheckpoint"))
def test_checkpoint_stats(self): for name in ('first', 'second', 'third'): config = self.config + ',key_format=' + self.keyfmt helper.simple_populate(self, self.uri, config, self.nentries) self.session.checkpoint('name=' + name) cursor = self.session.open_cursor('statistics:' + self.uri, None, 'checkpoint=' + name) self.assertEqual(cursor[stat.dsrc.btree_entries][2], self.nentries) cursor.close()
def test_ops(self): # Populate a table simple_populate(self, self.source_uri, 'key_format=S', self.nrows) # Run forced checkpoints self.run_checkpoints() self.archive = 'false' # Close and reopen the connection self.reopen_conn()
def test_long_running(self): # Populate a table simple_populate(self, self.source_uri, 'key_format=S', self.nrows) # Now scan the table and copy the rows into a new table c_src = self.session.create(self.uri, "key_format=S") c_src = self.session.open_cursor(self.source_uri) c = self.session.open_cursor(self.uri) for k, v in c_src: c[k] = v
def test_checkpoint_cursor_update(self): simple_populate(self, self.uri, 'key_format=' + self.fmt, 100) self.session.checkpoint("name=ckpt") cursor = self.session.open_cursor(self.uri, None, "checkpoint=ckpt") cursor.set_key(key_populate(cursor, 10)) cursor.set_value("XXX") self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.insert()) self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.remove()) self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.update()) cursor.close()
def test_checkpoint_stats(self): for name in ('first', 'second', 'third'): config = self.config + ',key_format=' + self.keyfmt helper.simple_populate(self, self.uri, config, self.nentries) self.session.checkpoint('name=' + name) cursor = self.session.open_cursor( 'statistics:' + self.uri, None, 'checkpoint=' + name) self.assertEqual( cursor[stat.dsrc.btree_entries][2], self.nentries) cursor.close()
def test_search_invisible_two(self): uri = 'file:test_bug008' # This is a btree layer test. # Populate the tree and reopen the connection, forcing it to disk # and moving the records to an on-page format. simple_populate(self, uri, self.fmt, 100) self.reopen_conn() # Add some additional visible records. cursor = self.session.open_cursor(uri, None) for i in range(100, 120): cursor[key_populate(cursor, i)] = value_populate(cursor, i) cursor.close() # Begin a transaction, and add some additional records. self.session.begin_transaction() cursor = self.session.open_cursor(uri, None) for i in range(120, 140): cursor[key_populate(cursor, i)] = value_populate(cursor, i) # Open a separate session and cursor. s = self.conn.open_session() cursor = s.open_cursor(uri, None) # Search for an invisible record. cursor.set_key(key_populate(cursor, 130)) if self.empty: # Invisible updates to fixed-length column-store objects are # invisible to the reader, but the fact that they exist past # the end of the initial records causes the instantiation of # empty records: confirm successful return of an empty row. cursor.search() self.assertEqual(cursor.get_key(), 130) self.assertEqual(cursor.get_value(), 0) else: # Otherwise, we should not find any matching records. self.assertEqual(cursor.search(), wiredtiger.WT_NOTFOUND) # Search-near for an invisible record, which should succeed, returning # the last visible record. cursor.set_key(key_populate(cursor, 130)) cursor.search_near() if self.empty: # Invisible updates to fixed-length column-store objects are # invisible to the reader, but the fact that they exist past # the end of the initial records causes the instantiation of # empty records: confirm successful return of an empty row. cursor.search() self.assertEqual(cursor.get_key(), 130) self.assertEqual(cursor.get_value(), 0) else: # Otherwise, we should find the closest record for which we can see # the value. self.assertEqual(cursor.get_key(), key_populate(cursor, 119)) self.assertEqual(cursor.get_value(), value_populate(cursor, 119))
def test_truncate_bad_args(self): uri = self.type + self.name simple_populate(self, uri, 'key_format=S', 100) msg = '/either a URI or start/stop cursors/' self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.truncate(None, None, None, None), msg) cursor = self.session.open_cursor(uri, None) self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.truncate(uri, cursor, None, None), msg) self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.truncate(uri, None, cursor, None), msg)
def test_cursor_random_multiple_insert_records(self): uri = self.type if uri.startswith("file:"): simple_populate(self, uri, "allocation_size=512,leaf_page_max=512,key_format=S", 100) else: complex_populate(self, uri, "allocation_size=512,leaf_page_max=512,key_format=S", 100) # In a insert list, next_random always selects the middle key/value # pair, all we can do is confirm cursor.next works. cursor = self.session.open_cursor(uri, None, self.config) self.assertEqual(cursor.next(), 0)
def test_overwrite_reconfig(self): simple_populate(self, self.uri, 'key_format=' + self.fmt, 100) cursor = self.session.open_cursor(self.uri, None) cursor.set_key(key_populate(cursor, 10)) cursor.set_value('XXXXXXXXXX') self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.insert()) cursor.set_key(key_populate(cursor, 10)) dupc = self.session.open_cursor(None, cursor, "overwrite"); dupc.set_value('XXXXXXXXXX') dupc.insert()
def test_duplicate_cursor(self): uri = self.uri + self.name # A simple, one-file file or table object. simple_populate(self, uri, self.config + self.fmt, self.nentries) self.iterate(uri) self.session.drop(uri, None) # A complex, multi-file table object. if self.uri == "table:": complex_populate(self, uri, self.config + self.fmt, self.nentries) self.iterate(uri) self.session.drop(uri, None)
def test_truncate_cursor_order(self): uri = self.type + self.name simple_populate(self, uri, 'key_format=' + self.keyfmt, 100) c1 = self.session.open_cursor(uri, None) c2 = self.session.open_cursor(uri, None) c1.set_key(key_populate(c1, 20)) c2.set_key(key_populate(c2, 10)) msg = '/the start cursor position is after the stop cursor position/' self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.truncate(None, c1, c2, None), msg) c2.set_key(key_populate(c2, 20)) self.session.truncate(None, c1, c2, None)
def test_cursor_random_multiple_insert_records(self): uri = self.type if uri.startswith('file:'): simple_populate(self, uri, 'allocation_size=512,leaf_page_max=512,key_format=S', 100) else: complex_populate(self, uri, 'allocation_size=512,leaf_page_max=512,key_format=S', 100) # In a insert list, next_random always selects the middle key/value # pair, all we can do is confirm cursor.next works. cursor = self.session.open_cursor(uri, None, self.config) self.assertEqual(cursor.next(), 0)
def test_truncate_uri(self): uri = self.type + self.name # A simple, one-file file or table object. simple_populate(self, uri, 'key_format=S', 100) self.session.truncate(uri, None, None, None) confirm_empty(self, uri) self.session.drop(uri, None) if self.type == "table:": complex_populate(self, uri, 'key_format=S', 100) self.session.truncate(uri, None, None, None) confirm_empty(self, uri) self.session.drop(uri, None)
def test_smoke(self): simple_populate(self, self.uri, self.config + self.keyfmt, self.nentries) self.reopen_conn() c = self.session.open_cursor(self.uri, None) c.set_key(key_populate(c, 100)) self.assertEqual(c.search(), 0) self.assertEqual(c.get_value(), value_populate(c, 100)) c.set_key(key_populate(c, 101)) self.assertEqual(c.search(), 0) self.assertEqual(c.get_value(), value_populate(c, 101)) c.set_key(key_populate(c, 9999)) self.assertEqual(c.search(), 0) self.assertEqual(c.get_value(), value_populate(c, 9999))
def test_checkpoint_stats(self): nentries = 0 last_size = 0 for name in ('first', 'second', 'third'): helper.simple_populate(self, self.uri, self.config, nentries) nentries += self.nentries self.session.checkpoint('name=' + name) cursor = self.session.open_cursor( 'statistics:' + self.uri, None, 'checkpoint=' + name) size = cursor[stat.dsrc.btree_overflow][1] self.assertTrue(size >= last_size) last_size = size cursor.close() self.session.truncate(self.uri, None, None)
def test_cursor09(self): uri = self.type + "cursor09" if self.complex: complex_populate(self, uri, self.config, 100) else: simple_populate(self, uri, self.config, 100) cursor = self.session.open_cursor(uri, None, None) cursor[key_populate(cursor, 10)] = ( tuple(complex_value_populate(cursor, 10)) if self.complex else value_populate(cursor, 10) ) msg = "/requires key be set/" self.assertRaisesWithMessage(wiredtiger.WiredTigerError, cursor.search, msg)
def test_checkpoint_stats(self): nentries = 0 last_size = 0 for name in ('first', 'second', 'third'): helper.simple_populate(self, self.uri, self.config, nentries) nentries += self.nentries self.session.checkpoint('name=' + name) cursor = self.session.open_cursor('statistics:' + self.uri, None, 'checkpoint=' + name) size = cursor[stat.dsrc.btree_overflow][1] self.assertTrue(size >= last_size) last_size = size cursor.close() self.session.truncate(self.uri, None, None)
def test_checkpoint_multiple_open(self): simple_populate(self, self.uri, 'key_format=' + self.fmt, 100) self.session.checkpoint("name=checkpoint-1") c1 = self.session.open_cursor(self.uri, None, "checkpoint=checkpoint-1") c2 = self.session.open_cursor(self.uri, None, "checkpoint=checkpoint-1") c3 = self.session.open_cursor(self.uri, None, "checkpoint=checkpoint-1") c4 = self.session.open_cursor(self.uri, None, None) c4.close, c3.close, c2.close, c1.close self.session.checkpoint("name=checkpoint-2") c1 = self.session.open_cursor(self.uri, None, "checkpoint=checkpoint-1") c2 = self.session.open_cursor(self.uri, None, "checkpoint=checkpoint-2") c3 = self.session.open_cursor(self.uri, None, "checkpoint=checkpoint-2") c4 = self.session.open_cursor(self.uri, None, None) c4.close, c3.close, c2.close, c1.close
def test_truncate_cursor_notset(self): uri = self.type + self.name msg = '/requires key be set/' simple_populate(self, uri, 'key_format=S', 100) c1 = self.session.open_cursor(uri, None) c2 = self.session.open_cursor(uri, None) c2.set_key(key_populate(c2, 10)) self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.truncate(None, c1, c2, None), msg) self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.truncate(None, c2, c1, None), msg) c1.close() c2.close()
def test_cursor_random_multiple_insert_records(self): uri = self.type + 'random' if self.type == 'file:': simple_populate(self, uri, 'allocation_size=512,leaf_page_max=512,key_format=' +\ self.fmt, 100) else: complex_populate(self, uri, 'allocation_size=512,leaf_page_max=512,key_format=' +\ self.fmt, 100) # In a insert list, next_random always selects the middle key/value # pair, all we can do is confirm cursor.next works. cursor = self.session.open_cursor(uri, None, "next_random=true") self.assertEqual(cursor.next(), 0)
def test_checkpoint_last_name(self): simple_populate(self, "file:checkpoint", 'key_format=S', 100) msg = '/the checkpoint name.*is reserved/' for conf in ( 'name=WiredTigerCheckpoint', 'name=WiredTigerCheckpoint.', 'name=WiredTigerCheckpointX', 'drop=(from=WiredTigerCheckpoint)', 'drop=(from=WiredTigerCheckpoint.)', 'drop=(from=WiredTigerCheckpointX)', 'drop=(to=WiredTigerCheckpoint)', 'drop=(to=WiredTigerCheckpoint.)', 'drop=(to=WiredTigerCheckpointX)'): self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.checkpoint(conf), msg)
def test_cursor09(self): uri = self.type + 'cursor09' if self.complex: complex_populate(self, uri, self.config, 100) else: simple_populate(self, uri, self.config, 100) cursor = self.session.open_cursor(uri, None, None) cursor[key_populate(cursor, 10)] = \ tuple(complex_value_populate(cursor, 10)) if self.complex \ else value_populate(cursor, 10) msg = '/requires key be set/' self.assertRaisesWithMessage(wiredtiger.WiredTigerError, cursor.search, msg)
def test_insert_over_delete_replace(self): table_config = self.get_table_config() msg = '/WT_CACHE_FULL.*/' self.assertRaisesHavingMessage(wiredtiger.WiredTigerError, lambda:simple_populate(self, "table:" + self.name, table_config, 10000000), msg) cursor = self.session.open_cursor('table:' + self.name, None) cursor.prev() last_key = int(cursor.get_key()) # Now that the database contains as much data as will fit into # the configured cache, verify removes succeed. cursor = self.session.open_cursor('table:' + self.name, None) for i in range(1, last_key / 4, 1): cursor.set_key(key_populate(cursor, i)) cursor.remove() cursor.reset() # Spin inserting to give eviction a chance to reclaim space inserted = False for i in range(1, 1000): try: cursor[key_populate(cursor, 1)] = value_populate(cursor, 1) except wiredtiger.WiredTigerError: cursor.reset() sleep(1) continue inserted = True break self.assertTrue(inserted)
def test_basic_conn_stats(self): # Build an object and force some writes. config = self.config + ',key_format=' + self.keyfmt simple_populate(self, self.uri, config, 1000) self.session.checkpoint(None) # See that we can get a specific stat value by its key and verify its # entry is self-consistent. allstat_cursor = self.session.open_cursor('statistics:', None, None) self.check_stats(allstat_cursor, 10, 'block-manager: blocks written') values = allstat_cursor[stat.conn.block_write] self.assertEqual(values[0], 'block-manager: blocks written') val = self.statstr_to_int(values[1]) self.assertEqual(val, values[2]) allstat_cursor.close()
def test_lsm_drop_active(self): uri = 'lsm:' + self.name simple_populate(self, uri, self.config, 10000) # Force to disk self.reopen_conn() # An open cursors should cause failure. cursor = self.session.open_cursor(uri, None, None) self.assertRaises(wiredtiger.WiredTigerError, lambda: self.session.drop(uri, None)) cursor.close() # Add enough records that a merge should be running simple_populate(self, uri, self.config, 50000) # The drop should succeed even when LSM work units are active self.session.drop(uri)
def test_reconfig_lsm_manager(self): # We create and populate a tiny LSM so that we can start off with # the LSM threads running and change the numbers of threads. # Take all the defaults. uri = "lsm:test_reconfig" nrecs = 10 simple_populate(self, uri, 'key_format=S', nrecs) # Sleep to make sure all threads are started. time.sleep(2) # Now that an LSM tree exists, reconfigure LSM manager threads. # We start with the default, which is 4. Configure more threads. self.conn.reconfigure("lsm_manager=(worker_thread_max=10)") # Generate some work nrecs = 20 simple_populate(self, uri, 'key_format=S', nrecs) # Now reconfigure fewer threads. self.conn.reconfigure("lsm_manager=(worker_thread_max=3)")
def test_lsm(self): args = 'key_format=S' args += ',lsm=(' # Start the LSM configuration options. # add names to args, e.g. args += ',session_max=30' for var in self.config_vars: value = getattr(self, 's_' + var) if value != None: if var == 'verbose': value = '[' + str(value) + ']' if value == True: value = 'true' if value == False: value = 'false' args += ',' + var + '=' + str(value) args += ')' # Close the LSM configuration option group self.verbose( 3, 'Test LSM with config: ' + args + ' count: ' + str(self.nrecs)) simple_populate(self, self.uri, args, self.nrecs)
def test_checkpoint_illegal_name(self): simple_populate(self, "file:checkpoint", 'key_format=S', 100) msg = '/the checkpoint name.*is reserved/' for conf in ('name=WiredTigerCheckpoint', 'name=WiredTigerCheckpoint.', 'name=WiredTigerCheckpointX', 'drop=(from=WiredTigerCheckpoint)', 'drop=(from=WiredTigerCheckpoint.)', 'drop=(from=WiredTigerCheckpointX)', 'drop=(to=WiredTigerCheckpoint)', 'drop=(to=WiredTigerCheckpoint.)', 'drop=(to=WiredTigerCheckpointX)'): self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.checkpoint(conf), msg) msg = '/WiredTiger objects should not include grouping/' for conf in ('name=check{point', 'name=check\\point'): self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.checkpoint(conf), msg)
def address_deleted(self): # Create the object, force it to disk, and verify the object. simple_populate(self, self.uri, self.config, self.nentries) self.reopen_conn() self.session.verify(self.uri) # Create a new session and start a transaction to force the upcoming # checkpoint operation to write address-deleted cells to disk. tmp_session = self.conn.open_session(None) tmp_session.begin_transaction("isolation=snapshot") # Truncate a big range of rows; the leaf pages aren't in memory, so # leaf page references will be deleted without being read. start = self.session.open_cursor(self.uri, None) start.set_key(key_populate(start, 10)) end = self.session.open_cursor(self.uri, None) end.set_key(key_populate(end, self.nentries - 10)) self.session.truncate(None, start, end, None) self.assertEqual(start.close(), 0) self.assertEqual(end.close(), 0) # Checkpoint, forcing address-deleted cells to be written. self.session.checkpoint() # Crash/reopen the connection and verify the object. self.reopen_conn() self.session.verify(self.uri) # Open a cursor and update a record (to dirty the tree, else we won't # mark pages with address-deleted cells dirty), then walk the tree so # we get a good look at all the internal pages and the address-deleted # cells. cursor = self.session.open_cursor(self.uri, None) cursor.set_key(key_populate(cursor, 5)) cursor.set_value("changed value") self.assertEqual(cursor.update(), 0) cursor.reset() for key, val in cursor: continue self.assertEqual(cursor.close(), 0) # Checkpoint, freeing the pages. self.session.checkpoint()
def create_snapshots(self): # Populate a table end = start = 0 simple_populate(self, self.uri, 'key_format=i', 0) # Create a set of snapshots # Each snapshot has a bunch of new data # Each snapshot removes a (smaller) bunch of old data snapshots = [] c = self.session.open_cursor(self.uri) for n in xrange(self.nsnapshots): self.session.snapshot("name=%d" % (n)) snapshots.append((n, end - start, 0)) for i in xrange(2 * self.nrows_per_snap): c[end + i] = "some value" end += 2 * self.nrows_per_snap for i in xrange(self.nrows_per_snap): del c[start + i] start += self.nrows_per_snap return snapshots
def test_cursor_random_reasonable_distribution(self): uri = self.type num_entries = self.records config = 'key_format=S' if uri == 'table:random': config = 'leaf_page_max=100MB,' + config # Set the leaf-page-max value, otherwise the page might split. simple_populate(self, uri, config, num_entries) # Setup an array to track which keys are seen visitedKeys = [0] * (num_entries + 1) # Setup a counter to see when we find a sequential key sequentialKeys = 0 cursor = self.session.open_cursor(uri, None, 'next_random=true') lastKey = None for i in range(0, num_entries): self.assertEqual(cursor.next(), 0) current = cursor.get_key() current = int(current) visitedKeys[current] = visitedKeys[current] + 1 if lastKey != None: if current == (lastKey + 1): sequentialKeys += 1 lastKey = current differentKeys = sum(x > 0 for x in visitedKeys) #print visitedKeys #print differentKeys ''' self.tty('differentKeys: ' + str(differentKeys) + ' of ' + \ str(num_entries) + ', ' + \ str((int)((differentKeys * 100) / num_entries)) + '%') ''' # Can't test for non-sequential data when there is 1 item in the table if num_entries > 1: self.assertGreater(num_entries - 1, sequentialKeys, 'cursor is returning sequential data') self.assertGreater(differentKeys, num_entries / 4, 'next_random random distribution not adequate')
def test_checkpoint_last(self): # Create an object, change one record to an easily recognizable string, # then checkpoint it and open a cursor, confirming we see the correct # value. Repeat this action, we want to be sure the engine gets the # latest checkpoint information each time. uri = self.uri simple_populate(self, uri, 'key_format=' + self.fmt, 100) for value in ('FIRST', 'SECOND', 'THIRD', 'FOURTH', 'FIFTH'): # Update the object. cursor = self.session.open_cursor(uri, None, "overwrite") cursor[key_populate(cursor, 10)] = value cursor.close() # Checkpoint the object. self.session.checkpoint() # Verify the "last" checkpoint sees the correct value. cursor = self.session.open_cursor( uri, None, "checkpoint=WiredTigerCheckpoint") self.assertEquals(cursor[key_populate(cursor, 10)], value)
def test_insert_over_capacity(self): table_config = self.get_table_config() msg = '/WT_CACHE_FULL.*/' self.assertRaisesHavingMessage(wiredtiger.WiredTigerError, lambda:simple_populate(self, "table:" + self.name, table_config, 10000000), msg) # Figure out the last key we inserted. cursor = self.session.open_cursor('table:' + self.name, None) cursor.prev() last_key = int(cursor.get_key()) simple_populate_check(self, 'table:' + self.name, last_key)
def test_insert_over_delete(self): config = self.fmt + self.table_config msg = '/WT_CACHE_FULL.*/' self.assertRaisesHavingMessage(wiredtiger.WiredTigerError, lambda:simple_populate(self, self.uri, config, 10000000), msg) # 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) for i in range(1, 100): cursor.set_key(key_populate(cursor, i)) cursor.remove()