def test_illegal_extractor(self): ds = ComplexDataSet(self, 'table:A', 10) ds.populate() msg = '/unknown extractor/' self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.create('index:A:xyzzy', 'key_format=S,columns=(column2),extractor="xyzzy"'), msg)
def test_open_index_and_drop(self): # We should also be able to detect cached cursors # for indices session = self.session uri = 'table:test_cursor13_drops' ds = ComplexDataSet(self, uri, 100) ds.create() indexname = ds.index_name(0) c = session.open_cursor(indexname) # The index is really open, so we cannot drop the main table. self.assertRaises(wiredtiger.WiredTigerError, lambda: session.drop(uri)) c.close() session.drop(uri) confirm_does_not_exist(self, uri) # Same test for indices, but with cursor held by another session. # TODO: try with session that DOES have cache_cursors and another # that does not. session2 = self.conn.open_session(None) ds = ComplexDataSet(self, uri, 100) ds.create() indexname = ds.index_name(0) c = session2.open_cursor(indexname) self.assertRaises(wiredtiger.WiredTigerError, lambda: session.drop(uri)) c.close() session.drop(uri) confirm_does_not_exist(self, uri) session2.close()
def test_truncate_complex(self): # We only care about tables. if self.type == 'file:': return uri = self.type + self.name # list: truncation patterns # # begin and end: -1 means pass None for the cursor arg to truncate. An # integer N, with 1 <= N < self.nentries, truncates from/to a cursor # positioned at that row. list = [ (-1, self.nentries), # begin to end, begin = None (1, -1), # begin to end, end = None (1, self.nentries), # begin to end (-1, self.nentries - self.skip), # begin to middle, begin = None (1, self.nentries - self.skip), # begin to middle (self.skip, -1), # middle to end, end = None (self.skip, self.nentries), # middle to end (self.skip, # middle to different middle self.nentries - self.skip), (1, 1), # begin to begin (self.nentries, self.nentries), # end to end (self.skip, self.skip) # middle to same middle ] # Build the layout we're going to test for begin,end in list: ''' print '===== run:', uri print 'key:', self.keyfmt, 'begin:', begin, 'end:', end ''' # Create the object. ds = ComplexDataSet(self, uri, self.nentries, config=self.config, key_format=self.keyfmt) ds.populate() # Build a dictionary of what the object should look like for # later comparison cursor = self.session.open_cursor(uri, None) expected = {} for i in range(1, self.nentries + 1): expected[ds.key(i)] = ds.comparable_value(i) cursor.close() # Optionally close and re-open the object to get a disk image # instead of a big insert list. if self.reopen: self.reopen_conn() self.truncateRangeAndCheck(ds, uri, begin, end, expected) self.session.drop(uri, None)
def test_truncate_cursor_order(self): uri = self.type + self.name # A simple, one-file file or table object. ds = SimpleDataSet(self, uri, 100, key_format=self.keyfmt) ds.populate() c1 = self.session.open_cursor(uri, None) c1.set_key(ds.key(1000)) c2 = self.session.open_cursor(uri, None) c2.set_key(ds.key(2000)) self.session.truncate(None, c1, c2, None) self.assertEqual(c1.close(), 0) self.assertEqual(c2.close(), 0) self.session.drop(uri) if self.type == "table:": ds = ComplexDataSet(self, uri, 100, key_format=self.keyfmt) ds.populate() c1 = self.session.open_cursor(uri, None) c1.set_key(ds.key(1000)) c2 = self.session.open_cursor(uri, None) c2.set_key(ds.key(2000)) self.session.truncate(None, c1, c2, None) self.assertEqual(c1.close(), 0) self.assertEqual(c2.close(), 0) self.session.drop(uri)
def get_dataset(self, rows): args = 'key_format=S' if self.complex_dataset: return ComplexDataSet(self, self.uri, rows, config=args) else: return SimpleDataSet(self, self.uri, rows, config=args)
def test_bug025(self): ds = ComplexDataSet(self, self.uri, self.nrows, key_format="S", value_format='S') ds.populate() iname = ds.index_name(0) iname_suffix = iname[iname.rindex(':') + 1:] filename = 'test_bug025_' + iname_suffix + '.wti' self.close_conn() pos = os.path.getsize(filename) - 1024 os.remove(filename) # We get an error message, but the open succeeds. with self.expectedStderrPattern('.*No such file or directory'): self.open_conn() newkey = ds.key(self.nrows) newval = ds.value(self.nrows) cursor = self.session.open_cursor(self.uri) # We get an error message, and the insert fails. # The cursor remains open. with self.expectedStderrPattern('.*No such file or directory'): try: cursor[newkey] = newval except Exception as e: self.pr('Exception in first access: ' + str(e)) # We get an error message, and the insert fails. # Before the associated fix was made, the insert crashed. with self.expectedStderrPattern('.*No such file or directory'): try: cursor[newkey] = newval # point of crash except Exception as e: self.pr('Exception in second access: ' + str(e)) cursor.close()
def load_commandline(self, args, fail): errfile = "errfile" ComplexDataSet(self, self.uri, 20).populate() self.runWt(["dump", self.uri], outfilename="dump.out") loadargs = ["load", "-f", "dump.out"] + args self.runWt(loadargs, errfilename=errfile, failure=fail) if fail: self.check_non_empty_file(errfile) else: self.check_empty_file(errfile)
def test_truncate_complex(self): # We only care about tables. if self.type == 'file:': return uri = self.type + self.name # list: truncation patterns # # begin and end: -1 means pass None for the cursor arg to truncate. An # integer N, with 1 <= N < self.nentries, truncates from/to a cursor # positioned at that row. list = [ (-1, self.nentries), # begin to end, begin = None (1, -1), # begin to end, end = None (1, self.nentries), # begin to end (-1, self.nentries - self.skip), # begin to middle, begin = None (1, self.nentries - self.skip), # begin to middle (self.skip, -1), # middle to end, end = None (self.skip, self.nentries), # middle to end ( self.skip, # middle to different middle self.nentries - self.skip), (1, 1), # begin to begin (self.nentries, self.nentries), # end to end (self.skip, self.skip) # middle to same middle ] # Build the layout we're going to test for begin, end in list: ''' print '===== run:', uri print 'key:', self.keyfmt, 'begin:', begin, 'end:', end ''' # Create the object. ds = ComplexDataSet(self, uri, self.nentries, config=self.config, key_format=self.keyfmt) ds.populate() # Build a dictionary of what the object should look like for # later comparison cursor = self.session.open_cursor(uri, None) expected = {} for i in range(1, self.nentries + 1): expected[ds.key(i)] = ds.comparable_value(i) cursor.close() # Optionally close and re-open the object to get a disk image # instead of a big insert list. if self.reopen: self.reopen_conn() self.truncateRangeAndCheck(ds, uri, begin, end, expected) self.session.drop(uri, None)
def test_stat_cursor_conn_clear(self): uri = 'table:' + self.pfx ComplexDataSet(self, uri, 100).populate() # cursor_insert should clear # cache_bytes_dirty should not clear cursor = self.session.open_cursor('statistics:', None, 'statistics=(all,clear)') self.assertGreater(cursor[stat.conn.cache_bytes_dirty][2], 0) self.assertGreater(cursor[stat.conn.cursor_insert][2], 0) cursor = self.session.open_cursor('statistics:', None, 'statistics=(all,clear)') self.assertGreater(cursor[stat.conn.cache_bytes_dirty][2], 0) self.assertEqual(cursor[stat.conn.cursor_insert][2], 0)
def test_truncate_uri(self): uri = self.type + self.name # A simple, one-file file or table object. SimpleDataSet(self, uri, 100).populate() self.session.truncate(uri, None, None, None) confirm_empty(self, uri) self.session.drop(uri, None) if self.type == "table:": ComplexDataSet(self, uri, 100).populate() self.session.truncate(uri, None, None, None) confirm_empty(self, uri) self.session.drop(uri, None)
def test_duplicate_cursor(self): uri = self.uri + self.name # A simple, one-file file or table object. ds = SimpleDataSet(self, uri, self.nentries, key_format=self.fmt) ds.populate() self.iterate(uri, ds) self.session.drop(uri, None) # A complex, multi-file table object. if self.uri == "table:": ds = ComplexDataSet(self, uri, self.nentries, key_format=self.fmt) ds.populate() self.iterate(uri, ds) self.session.drop(uri, None)
def test_duplicate_cursor(self): uri = self.uri + self.name # A simple, one-file file or table object. ds = SimpleDataSet(self, uri, self.nentries, \ key_format=self.keyfmt, value_format=self.valfmt) ds.populate() self.iterate(uri, ds) self.dropUntilSuccess(self.session, uri) # A complex, multi-file table object. if self.uri == "table:" and self.valfmt != '8t': ds = ComplexDataSet(self, uri, self.nentries, \ key_format=self.keyfmt, value_format=self.valfmt) ds.populate() self.iterate(uri, ds) self.dropUntilSuccess(self.session, uri)
def test_bug025(self): ds = ComplexDataSet(self, self.uri, self.nrows, key_format="S", value_format='S') ds.populate() iname = ds.index_name(0) iname_suffix = iname[iname.rindex(':') + 1:] filename = 'test_bug025_' + iname_suffix + '.wti' self.close_conn() pos = os.path.getsize(filename) - 1024 os.remove(filename) # We will get error output, but not always in the same API calls from run to run, # in particular the open connection doesn't always report the missing file, as # index files are usually lazily loaded. As long as the missing file is reported # at least once in the following code, it's good. with self.expectedStderrPattern('.*No such file or directory.*'): self.open_conn() newkey = ds.key(self.nrows) newval = ds.value(self.nrows) cursor = self.session.open_cursor(self.uri) # The insert fails, and the cursor remains open. try: cursor[newkey] = newval except Exception as e: self.pr('Exception in first access: ' + str(e)) # The insert fails again. Before the associated fix was made, the insert crashed. try: cursor[newkey] = newval # point of crash except Exception as e: self.pr('Exception in second access: ' + str(e)) cursor.close()
def test_upgrade_table_complex_data(self): # Run wt upgrade on a complex dataset and test for successful completion. uri = 'table:' + self.name ComplexDataSet(self, uri, self.num_rows).populate() self.runWt(['upgrade', uri])