Esempio n. 1
0
class test_empty(wttest.WiredTigerTestCase):
    name = 'test_empty'

    scenarios = check_scenarios([('file-r', dict(type='file:', fmt='r')),
                                 ('file-S', dict(type='file:', fmt='S')),
                                 ('table-r', dict(type='table:', fmt='r')),
                                 ('table-S', dict(type='table:', fmt='S'))])

    # Creating an object and then closing it shouldn't write any blocks.
    def test_empty_create(self):
        uri = self.type + self.name
        self.session.create(uri, 'key_format=' + self.fmt)
        self.session.close()
        name = self.name
        if self.type == "table:":
            name = name + '.wt'
        self.assertEquals(os.stat(name).st_size, 4 * 1024)

    # Open a new sesssion, add a few rows to an object and then remove them,
    # then close the object.  We open/close the object so it's flushed from
    # the underlying cache each time.
    def empty(self):
        uri = self.type + self.name
        self.session = self.conn.open_session()
        self.session.create(uri, 'key_format=' + self.fmt)

        # Add a few records to the object and remove them.
        cursor = self.session.open_cursor(uri, None, None)
        for i in range(1, 5):
            cursor.set_key(key_populate(cursor, i))
            cursor.set_value("XXX")
            cursor.insert()
            cursor.remove()

        # Perform a checkpoint (we shouldn't write any underlying pages because
        # of a checkpoint, either).
        self.session.checkpoint("name=ckpt")

        # Open and close a checkpoint cursor.
        cursor = self.session.open_cursor(uri, None, "checkpoint=ckpt")
        cursor.close()

        self.session.close()

        # The file should not have grown.
        name = self.name
        if self.type == "table:":
            name = name + '.wt'
        self.assertEquals(os.stat(name).st_size, 4 * 1024)

    # Creating an object, inserting and removing records (that is, building an
    # empty, dirty tree), shouldn't write any blocks.  This doesn't work for
    # column-store objects, though, because deleting an object modifies the name
    # space, which requires a write.
    def test_empty(self):
        if self.fmt == 'r':
            return

        for i in range(1, 5):
            self.empty()
Esempio n. 2
0
class test_upgrade(wttest.WiredTigerTestCase):
    name = 'test_upgrade'

    scenarios = check_scenarios([
        ('file', dict(uri='file:')),
        ('table', dict(uri='table:'))
    ])

    # Populate an object, then upgrade it.
    def upgrade(self, populate, with_cursor):
        uri = self.uri + self.name
        populate(self, uri, 'key_format=S', 10)

        # Open cursors should cause failure.
        if with_cursor:
            cursor = self.session.open_cursor(uri, None, None)
            self.assertRaises(wiredtiger.WiredTigerError,
                lambda: self.session.drop(uri, None))
            cursor.close()

        self.session.upgrade(uri, None)
        self.session.drop(uri)

    # Test upgrade of an object.
    def test_upgrade(self):
        # Simple file or table object.
        self.upgrade(simple_populate, False)
        self.upgrade(simple_populate, True)

        # A complex, multi-file table object.
        if self.uri == "table:":
            self.upgrade(complex_populate, False)
            self.upgrade(complex_populate, True)
Esempio n. 3
0
class test_bulk_load_not_empty(wttest.WiredTigerTestCase):
    name = 'test_bulk'

    scenarios = check_scenarios([
        ('file', dict(type='file:')),
        ('table', dict(type='table:'))
    ])

    def test_bulk_load_not_empty(self):
        uri = self.type + self.name
        self.session.create(uri, 'key_format=S,value_format=S')
        cursor = self.session.open_cursor(uri, None)
        cursor.set_key(key_populate(cursor, 1))
        cursor.set_value(value_populate(cursor, 1))
        cursor.insert()
        # Close the insert cursor, else we'll get EBUSY.
        cursor.close()
        msg = '/bulk-load is only supported on newly created objects/'
        self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
            lambda: self.session.open_cursor(uri, None, "bulk"), msg)

    def test_bulk_load_busy(self):
        uri = self.type + self.name
        self.session.create(uri, 'key_format=S,value_format=S')
        cursor = self.session.open_cursor(uri, None)
        cursor.set_key(key_populate(cursor, 1))
        cursor.set_value(value_populate(cursor, 1))
        cursor.insert()
        # Don't close the insert cursor, we want EBUSY.
        self.assertRaises(wiredtiger.WiredTigerError,
            lambda: self.session.open_cursor(uri, None, "bulk"))
Esempio n. 4
0
class test_rename(wttest.WiredTigerTestCase):
    name1 = 'test_rename1'
    name2 = 'test_rename2'

    scenarios = check_scenarios([
        ('file', dict(uri='file:')),
        ('table', dict(uri='table:'))
    ])

    # Populate and object, and rename it a couple of times, confirming the
    # old name doesn't exist and the new name has the right contents.
    def rename(self, populate, check, with_cursor):
        uri1 = self.uri + self.name1
        uri2 = self.uri + self.name2
        populate(self, uri1, 'key_format=S', 10)

        # Open cursors should cause failure.
        if with_cursor:
            cursor = self.session.open_cursor(uri1, None, None)
            self.assertRaises(wiredtiger.WiredTigerError,
                lambda: self.session.rename(uri1, uri2, None))
            cursor.close()

        self.session.rename(uri1, uri2, None)
        confirm_does_not_exist(self, uri1)
        check(self, uri2, 10)

        self.session.rename(uri2, uri1, None)
        confirm_does_not_exist(self, uri2)
        check(self, uri1, 10)

        self.session.drop(uri1)

    # Test rename of an object.
    def test_rename(self):
        # Simple, one-file file or table object.
        self.rename(simple_populate, simple_populate_check, False)
        self.rename(simple_populate, simple_populate_check, True)

        # A complex, multi-file table object.
        if self.uri == "table:":
            self.rename(complex_populate, complex_populate_check, False)
            self.rename(complex_populate, complex_populate_check, True)

    def test_rename_dne(self):
        uri1 = self.uri + self.name1
        uri2 = self.uri + self.name2
        confirm_does_not_exist(self, uri1)
        self.assertRaises(wiredtiger.WiredTigerError,
            lambda: self.session.rename(uri1, uri2, None))

    def test_rename_bad_uri(self):
        uri1 = self.uri + self.name1
        if self.uri == "file:":
                uri2 = "table:" + self.name2
        else:
                uri2 = "file:" + self.name2
        self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
            lambda: self.session.rename(uri1, uri2, None),
            '/type must match URI/')
Esempio n. 5
0
class test_cursor09(wttest.WiredTigerTestCase):
    scenarios = check_scenarios([
        ('file-r', dict(type='file:', config='key_format=r', complex=0)),
        ('file-S', dict(type='file:', config='key_format=S', complex=0)),
        ('lsm-S', dict(type='lsm:', config='key_format=S', complex=0)),
        ('table-r', dict(type='table:', config='key_format=r', complex=0)),
        ('table-S', dict(type='table:', config='key_format=S', complex=0)),
        ('table-r-complex',
         dict(type='table:', config='key_format=r', complex=1)),
        ('table-S-complex',
         dict(type='table:', config='key_format=S', complex=1)),
        ('table-S-complex-lsm',
         dict(type='table:', config='key_format=S,type=lsm', complex=1)),
    ])

    # WT_CURSOR.insert doesn't leave the cursor positioned, verify any
    # subsequent cursor operation fails with a "key not set" message.
    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)
Esempio n. 6
0
class test_bulk_load_row_order(wttest.WiredTigerTestCase):
    name = 'test_bulk'

    scenarios = check_scenarios([('file', dict(type='file:')),
                                 ('table', dict(type='table:'))])

    def test_bulk_load_row_order_check(self):
        uri = self.type + self.name
        self.session.create(uri, 'key_format=S,value_format=S')
        cursor = self.session.open_cursor(uri, None, "bulk")
        cursor[key_populate(cursor, 10)] = value_populate(cursor, 10)

        cursor.set_key(key_populate(cursor, 1))
        cursor.set_value(value_populate(cursor, 1))
        msg = '/compares smaller than previously inserted key/'
        self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
                                     lambda: cursor.insert(), msg)

    def test_bulk_load_row_order_nocheck(self):
        uri = self.type + self.name
        self.session.create(uri, 'key_format=S,value_format=S')
        cursor = self.session.open_cursor(uri, None, "bulk,skip_sort_check")
        cursor[key_populate(cursor, 10)] = value_populate(cursor, 10)
        cursor[key_populate(cursor, 1)] = value_populate(cursor, 1)

        if not wiredtiger.diagnostic_build():
            self.skipTest('requires a diagnostic build')

        # Close explicitly, there's going to be a fallure.
        msg = '/are incorrectly sorted/'
        self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
                                     lambda: self.conn.close(), msg)
Esempio n. 7
0
class test_checkpoint_last(wttest.WiredTigerTestCase):
    scenarios = check_scenarios([('file', dict(uri='file:checkpoint',
                                               fmt='S')),
                                 ('table', dict(uri='table:checkpoint',
                                                fmt='S'))])

    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)
Esempio n. 8
0
class test_perf001(wttest.WiredTigerTestCase):
    table_name = 'test_perf001'

    scenarios = check_scenarios([
        #('file-file', dict(tabletype='file',indextype='file')),
        ('file-lsm', dict(tabletype='file',indextype='lsm')),
        #('lsm-file', dict(tabletype='lsm',indextype='file')),
        #('lsm-lsm', dict(tabletype='lsm',indextype='lsm')),
    ])

    def setUpConnectionOpen(self, dir):
        wtopen_args = 'create,cache_size=512M'
        conn = wiredtiger.wiredtiger_open(dir, wtopen_args)
        self.pr(`conn`)
        return conn

    def test_performance_of_indices(self):
        uri = 'table:' + self.table_name
        create_args = 'key_format=i,value_format=ii,columns=(a,c,d),type=' + self.tabletype
        self.session.create(uri, create_args)
        self.session.create('index:' + self.table_name + ':ia',
            'columns=(d,c),type=' + self.indextype)

        c = self.session.open_cursor('table:' + self.table_name, None, None)
        start_time = clock()
        for i in xrange(750000):
            # 100 operations should never take 5 seconds, sometimes they take
            # 2 seconds when a page is being force-evicted.
            if i % 100 == 0 and i != 0:
                end_time = clock()
                self.assertTrue(end_time - start_time < 5)
                start_time = end_time
            c[i] = (int(time()), random.randint(1,5))
        c.close()
Esempio n. 9
0
class test_cursor06(wttest.WiredTigerTestCase):
    name = 'reconfigure'
    scenarios = check_scenarios([
        ('file-r', dict(type='file:', keyfmt='r', complex=0)),
        ('file-S', dict(type='file:', keyfmt='S', complex=0)),
        ('lsm-S', dict(type='lsm:', keyfmt='S', complex=0)),
        ('table-r', dict(type='table:', keyfmt='r', complex=0)),
        ('table-S', dict(type='table:', keyfmt='S', complex=0)),
        ('table-r-complex', dict(type='table:', keyfmt='r', complex=1)),
        ('table-S-complex', dict(type='table:', keyfmt='S', complex=1)),
    ])

    def pop(self, uri):
        if self.complex == 1:
            complex_populate(self, uri, 'key_format=' + self.keyfmt, 100)
        else:
            simple_populate(self, uri, 'key_format=' + self.keyfmt, 100)

    def set_kv(self, cursor):
        cursor.set_key(key_populate(cursor, 10))
        if self.complex == 1:
            v = complex_value_populate(cursor, 10)
            cursor.set_value(v[0], v[1], v[2], v[3])
        else:
            cursor.set_value(value_populate(cursor, 10))

    def test_reconfigure_overwrite(self):
        uri = self.type + self.name
        for open_config in (None, "overwrite=0", "overwrite=1"):
            self.session.drop(uri, "force")
            self.pop(uri)
            cursor = self.session.open_cursor(uri, None, open_config)
            if open_config != "overwrite=0":
                self.set_kv(cursor)
                cursor.insert()
            for i in range(0, 10):
                cursor.reconfigure("overwrite=0")
                self.set_kv(cursor)
                self.assertRaises(wiredtiger.WiredTigerError,
                                  lambda: cursor.insert())
                cursor.reconfigure("overwrite=1")
                self.set_kv(cursor)
                cursor.insert()
            cursor.close()

    def test_reconfigure_readonly(self):
        uri = self.type + self.name
        for open_config in (None, "readonly=0", "readonly=1"):
            self.session.drop(uri, "force")
            self.pop(uri)
            cursor = self.session.open_cursor(uri, None, open_config)
            if open_config == "readonly=1":
                self.set_kv(cursor)
                self.assertRaises(wiredtiger.WiredTigerError,
                                  lambda: cursor.update())
            else:
                self.set_kv(cursor)
                cursor.update()
            cursor.close()
Esempio n. 10
0
class test_intpack(wttest.WiredTigerTestCase):
    name = 'test_intpack'

    scenarios = check_scenarios([
        ('b', dict(formatcode='b', low=-128, high=127, nbits=8)),
        ('B', dict(formatcode='B', low=0, high=255, nbits=8)),
        ('8t', dict(formatcode='8t', low=0, high=255, nbits=8)),
        ('5t', dict(formatcode='5t', low=0, high=31, nbits=5)),
        ('h', dict(formatcode='h', low=-32768, high=32767, nbits=16)),
        ('H', dict(formatcode='H', low=0, high=65535, nbits=16)),
        ('i', dict(formatcode='i', low=-2147483648, high=2147483647,
                   nbits=32)),
        ('I', dict(formatcode='I', low=0, high=4294967295, nbits=32)),
        ('l', dict(formatcode='l', low=-2147483648, high=2147483647,
                   nbits=32)),
        ('L', dict(formatcode='L', low=0, high=4294967295, nbits=32)),
        ('q',
         dict(formatcode='q',
              low=-9223372036854775808,
              high=9223372036854775807,
              nbits=64)),
        ('Q', dict(formatcode='Q', low=0, high=18446744073709551615,
                   nbits=64)),
    ])
    scenarios = check_scenarios(number_scenarios(scenarios))

    def test_packing(self):
        pt = PackTester(self.formatcode, self.low, self.high,
                        self.assertEquals)
        self.assertEquals(2**self.nbits, self.high - self.low + 1)
        pt.initialize(self.session)
        pt.check_range(-66000, 66000)
        if self.nbits >= 32:
            e32 = 2**32
            pt.check_range(e32 - 1000, e32 + 1000)
            pt.check_range(-e32 - 1000, -e32 + 1000)
        if self.nbits >= 64:
            e64 = 2**64
            pt.check_range(e64 - 1000, e64 + 1000)
            pt.check_range(-e64 - 1000, -e64 + 1000)
            pt.truncate()
            i = 8
            while i < 1 << 60:
                pt.check_range(-i - 1, -i + 1)
                pt.check_range(i - 1, i + 1)
                i <<= 1
Esempio n. 11
0
class test_txn03(wttest.WiredTigerTestCase):
    tablename = 'test_txn03'
    uri1 = 'table:' + tablename + "_1"
    uri2 = 'table:' + tablename + "_2"
    key_str = "TEST_KEY1"
    data_str1 = "VAL"
    data_str2 = "TEST_VAL1"

    nentries = 1000
    scenarios = check_scenarios([
        ('var', dict(create_params="key_format=S,value_format=S")),
    ])

    def test_ops(self):
        self.session.create(self.uri1, self.create_params)
        self.session.create(self.uri2, self.create_params)
        # Set up the table with entries for 1 and 10
        # We use the overwrite config so insert can update as needed.
        c = self.session.open_cursor(self.uri1, None, 'overwrite')
        c[self.key_str] = self.data_str1
        c.close()
        c = self.session.open_cursor(self.uri2, None, 'overwrite')
        c[self.key_str] = self.data_str1
        c.close()

        # Update the first table - this update should be visible in the
        # new session.
        self.session.begin_transaction()
        c = self.session.open_cursor(self.uri1, None, 'overwrite')
        c[self.key_str] = self.data_str2
        self.session.commit_transaction()
        c.close()

        # Open another session and some transactional cursors.
        self.session2 = self.conn.open_session()
        self.session2.begin_transaction("isolation=snapshot")
        t1c = self.session2.open_cursor(self.uri1, None, 'overwrite')
        t2c = self.session2.open_cursor(self.uri2, None, 'overwrite')

        # Make an update in the first session.
        self.session.begin_transaction()
        c = self.session.open_cursor(self.uri2, None, 'overwrite')
        c[self.key_str] = self.data_str2
        self.session.commit_transaction()
        c.close()

        t1c.set_key(self.key_str)
        t1c.search()
        t2c.set_key(self.key_str)
        t2c.search()
        self.assertEqual(t1c.get_value(), self.data_str2)
        self.assertEqual(t2c.get_value(), self.data_str1)

        # Clean up
        t1c.close()
        t2c.close()
        self.session2.rollback_transaction()
Esempio n. 12
0
class test_checkpoint02(wttest.WiredTigerTestCase):
    scenarios = check_scenarios([('table-100',
                                  dict(uri='table:test',
                                       fmt='L',
                                       dsize=100,
                                       nops=50000,
                                       nthreads=10)),
                                 ('table-10',
                                  dict(uri='table:test',
                                       fmt='L',
                                       dsize=10,
                                       nops=50000,
                                       nthreads=30))])

    def test_checkpoint02(self):
        done = threading.Event()
        self.session.create(self.uri,
                            "key_format=" + self.fmt + ",value_format=S")
        ckpt = checkpoint_thread(self.conn, done)
        ckpt.start()

        uris = list()
        uris.append(self.uri)
        queue = Queue.Queue()
        my_data = 'a' * self.dsize
        for i in xrange(self.nops):
            if i % 191 == 0 and i != 0:
                queue.put_nowait(('b', i, my_data))
            queue.put_nowait(('i', i, my_data))

        opthreads = []
        for i in xrange(self.nthreads):
            t = op_thread(self.conn, uris, self.fmt, queue, done)
            opthreads.append(t)
            t.start()

        queue.join()
        done.set()
        for t in opthreads:
            t.join()
        ckpt.join()

        # Create a cursor - ensure all items have been put.
        cursor = self.session.open_cursor(self.uri, None, None)
        i = 0
        while True:
            nextret = cursor.next()
            if nextret != 0:
                break
            key = cursor.get_key()
            value = cursor.get_value()
            self.assertEqual(key, i)
            self.assertEqual(value, my_data)
            i += 1

        self.assertEqual(i, self.nops)
Esempio n. 13
0
class test_cursor_random_column(wttest.WiredTigerTestCase):
    scenarios = check_scenarios([('file', dict(uri='file:random')),
                                 ('table', dict(uri='table:random'))])

    def test_cursor_random_column(self):
        self.session.create(self.uri, 'key_format=r,value_format=S')
        msg = '/Operation not supported/'
        self.assertRaisesWithMessage(
            wiredtiger.WiredTigerError, lambda: self.session.open_cursor(
                self.uri, None, "next_random=true"), msg)
Esempio n. 14
0
class test_txn13(wttest.WiredTigerTestCase, suite_subprocess):
    logmax = "100K"
    tablename = 'test_txn13'
    uri = 'table:' + tablename
    nops = 1024
    create_params = 'key_format=i,value_format=S'

    scenarios = check_scenarios([
        ('1gb', dict(expect_err=False, valuesize=1048576)),
        ('2gb', dict(expect_err=False, valuesize=2097152)),
        ('4gb', dict(expect_err=True, valuesize=4194304))
    ])

    # Overrides WiredTigerTestCase
    def setUpConnectionOpen(self, dir):
        self.home = dir
        conn_params = \
                'log=(archive=false,enabled,file_max=%s)' % self.logmax + \
                ',create,cache_size=8G,error_prefix="%s: ",' % self.shortid()
        # print "Creating conn at '%s' with config '%s'" % (dir, conn_params)
        try:
            conn = wiredtiger_open(dir, conn_params)
        except wiredtiger.WiredTigerError as e:
            print "Failed conn at '%s' with config '%s'" % (dir, conn_params)
        self.pr( ` conn `)
        return conn

    @wttest.longtest('txn tests with huge values')
    def test_large_values(self):
        # print "Creating %s with config '%s'" % (self.uri, self.create_params)
        # print "Running with %d" % (self.valuesize)
        self.session.create(self.uri, self.create_params)
        c = self.session.open_cursor(self.uri, None)

        # We want to test very large values.  Generate 'nops' records within
        # a single transaction.
        valuepfx = self.valuesize * 'X'

        gotException = False
        self.session.begin_transaction()
        for k in range(self.nops):
            value = valuepfx + str(k)
            c[k] = value

        if self.expect_err:
            # EFBIG is expected: File too large
            msg = '/exceeds the maximum/'
            self.assertRaisesWithMessage(
                wiredtiger.WiredTigerError,
                lambda: self.session.commit_transaction(), msg)
            gotException = True
        else:
            self.session.commit_transaction()

        self.assertTrue(gotException == self.expect_err)
Esempio n. 15
0
class test_create_excl(wttest.WiredTigerTestCase):
    scenarios = check_scenarios([('file', dict(type='file:')),
                                 ('table', dict(type='table:'))])

    # Create the object with "exclusive", then assert that creation with
    # "exclusive" fails.
    def test_create_excl(self):
        uri = self.type + 'create_excl'
        self.session.create(uri, "exclusive")
        self.assertRaises(wiredtiger.WiredTigerError,
                          lambda: self.session.create(uri, "exclusive"))
Esempio n. 16
0
class test_cursor_random_column(wttest.WiredTigerTestCase):
    scenarios = check_scenarios([
        ('file', dict(uri='file:random', fmt='r')),
        ('table', dict(uri='table:random', fmt='r')),
    ])

    def test_cursor_random_column(self):
        self.session.create(self.uri,
                            'key_format=' + self.fmt + ',value_format=S')
        cursor = self.session.open_cursor(self.uri, None, "next_random=true")
        self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.next())
        cursor.close()
Esempio n. 17
0
class test_cursor07(wttest.WiredTigerTestCase, suite_subprocess):
    logmax = "100K"
    tablename = 'test_cursor07'
    uri = 'table:' + tablename
    #  A large number of keys will force a log file change which will
    # test that scenario for log cursors.
    nkeys = 7000

    scenarios = check_scenarios([('regular', dict(reopen=False)),
                                 ('reopen', dict(reopen=True))])

    # Enable logging for this test.
    def conn_config(self, dir):
        return 'log=(archive=false,enabled,file_max=%s),' % self.logmax + \
            'transaction_sync="(method=dsync,enabled)"'

    def test_log_cursor(self):
        # print "Creating %s with config '%s'" % (self.uri, self.create_params)
        create_params = 'key_format=i,value_format=S'
        self.session.create(self.uri, create_params)
        c = self.session.open_cursor(self.uri, None)

        # A binary value.
        value = u'\u0001\u0002abcd\u0003\u0004'

        self.session.begin_transaction()
        for k in range(self.nkeys):
            c[k] = value
        self.session.commit_transaction()
        c.close()

        if self.reopen:
            self.reopen_conn()

        # Check for these values via a log cursor
        c = self.session.open_cursor("log:", None)
        count = 0
        while c.next() == 0:
            # lsn.file, lsn.offset, opcount
            keys = c.get_key()
            # txnid, rectype, optype, fileid, logrec_key, logrec_value
            values = c.get_value()
            try:
                if value in str(values[5]):  # logrec_value
                    count += 1
            except:
                pass
        c.close()
        self.assertEqual(count, self.nkeys)
Esempio n. 18
0
class test_backup02(wttest.WiredTigerTestCase):
    scenarios = check_scenarios([
        ('table', dict(uri='table:test',fmt='L',dsize=100,nops=200,nthreads=1,time=30)),
    ])

    def test_backup02(self):
        done = threading.Event()
        uris = list()
        uris.append(self.uri + str(1))
        uris.append(self.uri + str(2))
        uris.append(self.uri + str(3))
        for this_uri in uris:
            self.session.create(this_uri,
                "key_format=" + self.fmt + ",value_format=S")
        # TODO: Ideally we'd like a checkpoint thread, separate to the backup
        # thread. Need a way to stop checkpoints while doing backups.
#        ckpt = checkpoint_thread(self.conn, done)
#        ckpt.start()
        bkp = backup_thread(self.conn, 'backup.dir', done)
        bkp.start()

        queue = Queue.Queue()
        my_data = 'a' * self.dsize
        for i in xrange(self.nops):
            queue.put_nowait(('gi', i, my_data))

        opthreads = []
        for i in xrange(self.nthreads):
            t = op_thread(self.conn, uris, self.fmt, queue, done)
            opthreads.append(t)
            t.start()

        # Add 200 update entries into the queue every .1 seconds.
        more_time = self.time
        while more_time > 0:
            time.sleep(0.1)
            my_data = str(more_time) + 'a' * (self.dsize - len(str(more_time)))
            more_time = more_time - 0.1
            for i in xrange(self.nops):
                queue.put_nowait(('gu', i, my_data))

        queue.join()
        done.set()
#        # Wait for checkpoint thread to notice status change.
#        ckpt.join()
        for t in opthreads:
            t.join()
        bkp.join()
Esempio n. 19
0
class test_checkpoint_target(wttest.WiredTigerTestCase):
    scenarios = check_scenarios([
        ('file', dict(uri='file:checkpoint',fmt='S')),
        ('table', dict(uri='table:checkpoint',fmt='S'))
    ])

    def update(self, uri, value):
        cursor = self.session.open_cursor(uri, None, "overwrite")
        cursor.set_key(key_populate(cursor, 10))
        cursor.set_value(value)
        cursor.insert()
        cursor.close()

    def check(self, uri, value):
        cursor = self.session.open_cursor(uri, None, "checkpoint=checkpoint-1")
        self.assertEquals(cursor[key_populate(cursor, 10)], value)
        cursor.close()

    def test_checkpoint_target(self):
        # Create 3 objects, change one record to an easily recognizable string.
        uri = self.uri + '1'
        simple_populate(self, uri, 'key_format=' + self.fmt, 100)
        self.update(uri, 'ORIGINAL')
        uri = self.uri + '2'
        simple_populate(self, uri, 'key_format=' + self.fmt, 100)
        self.update(uri, 'ORIGINAL')
        uri = self.uri + '3'
        simple_populate(self, uri, 'key_format=' + self.fmt, 100)
        self.update(uri, 'ORIGINAL')

        # Checkpoint all three objects.
        self.session.checkpoint("name=checkpoint-1")

        # Update all 3 objects, then checkpoint two of the objects with the
        # same checkpoint name.
        self.update(self.uri + '1', 'UPDATE')
        self.update(self.uri + '2', 'UPDATE')
        self.update(self.uri + '3', 'UPDATE')
        target = 'target=("' + self.uri + '1"' + ',"' + self.uri + '2")'
        self.session.checkpoint("name=checkpoint-1," + target)

        # Confirm the checkpoint has the old value in objects that weren't
        # checkpointed, and the new value in objects that were checkpointed.
        self.check(self.uri + '1', 'UPDATE')
        self.check(self.uri + '2', 'UPDATE')
        self.check(self.uri + '3', 'ORIGINAL')
Esempio n. 20
0
class test_duplicate_cursor(wttest.WiredTigerTestCase):
    name = 'test_dupc'
    nentries = 1000

    config = 'key_format='

    scenarios = check_scenarios([
        ('file-r', dict(uri='file:', fmt='r')),
        ('file-S', dict(uri='file:', fmt='S')),
        ('table-r', dict(uri='table:', fmt='r')),
        ('table-S', dict(uri='table:', fmt='S'))
    ])

    # Iterate through an object, duplicate the cursor and checking that it
    # matches the original and is set to the same record.
    def iterate(self, uri):
        cursor = self.session.open_cursor(uri, None, None)
        next = 0
        while True:
            nextret = cursor.next()
            if nextret != 0:
                break
            next += 1
            self.assertEqual(cursor.get_key(), key_populate(cursor, next))
            dupc = self.session.open_cursor(None, cursor, None)
            self.assertEqual(cursor.compare(dupc), 0)
            self.assertEqual(dupc.get_key(), key_populate(dupc, next))
            cursor.close()
            cursor = dupc
        self.assertEqual(next, self.nentries)
        self.assertEqual(nextret, wiredtiger.WT_NOTFOUND)
        cursor.close()

    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)
Esempio n. 21
0
class test_checkpoint_cursor_update(wttest.WiredTigerTestCase):
    scenarios = check_scenarios([
        ('file-r', dict(uri='file:checkpoint',fmt='r')),
        ('file-S', dict(uri='file:checkpoint',fmt='S')),
        ('table-r', dict(uri='table:checkpoint',fmt='r')),
        ('table-S', dict(uri='table:checkpoint',fmt='S'))
    ])

    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()
Esempio n. 22
0
class test_bug006(wttest.WiredTigerTestCase):
    name = 'test_bug006'
    scenarios = check_scenarios([
        ('file', dict(uri='file:')),
        ('table', dict(uri='table:')),
    ])

    def test_bug006(self):
        uri = self.uri + self.name
        self.session.create(uri, 'value_format=S,key_format=S')
        cursor = self.session.open_cursor(uri, None)
        for i in range(1, 1000):
            cursor.set_key(key_populate(cursor, i))
            cursor.set_value(value_populate(cursor, i))
            cursor.insert()

        # Table operations should fail, the cursor is open.
        self.assertRaises(
            wiredtiger.WiredTigerError, lambda: self.session.drop(uri, None))
        self.assertRaises(
            wiredtiger.WiredTigerError,
            lambda: self.session.rename(uri, self.uri + "new", None))
        self.assertRaises(
            wiredtiger.WiredTigerError, lambda: self.session.salvage(uri, None))
        self.assertRaises(
            wiredtiger.WiredTigerError,
            lambda: self.session.truncate(uri, None, None, None))
        self.assertRaises(
            wiredtiger.WiredTigerError, lambda: self.session.upgrade(uri, None))
        self.assertRaises(
            wiredtiger.WiredTigerError, lambda: self.session.verify(uri, None))

        cursor.close()

        # Table operations should succeed, the cursor is closed.
        self.session.rename(uri, self.uri + "new", None)
        self.session.rename(self.uri + "new", uri, None)
        self.session.salvage(uri, None)
        self.session.truncate(uri, None, None, None)
        self.session.upgrade(uri, None)
        self.session.verify(uri, None)

        self.session.drop(uri, None)
Esempio n. 23
0
class test_truncate_uri(wttest.WiredTigerTestCase):
    name = 'test_truncate'
    scenarios = check_scenarios([('file', dict(type='file:')),
                                 ('table', dict(type='table:'))])

    # Populate an object, truncate it by URI, and confirm it's empty.
    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)
Esempio n. 24
0
class test_truncate_arguments(wttest.WiredTigerTestCase):
    name = 'test_truncate'

    scenarios = check_scenarios([('file', dict(type='file:')),
                                 ('table', dict(type='table:'))])

    # Test truncation without URI or cursors specified, or with a URI and
    # either cursor specified, expect errors.
    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)

    # Test truncation of cursors where no key is set, expect errors.
    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()
Esempio n. 25
0
class test_rebalance(wttest.WiredTigerTestCase):
    name = 'test_rebalance'

    # Use small pages so we generate some internal layout
    # Setup LSM so multiple chunks are present
    config = 'key_format=S,allocation_size=512,internal_page_max=512' + \
             ',leaf_page_max=1k,lsm=(chunk_size=512k,merge_min=10)'

    scenarios = check_scenarios([('file', dict(uri='file:')),
                                 ('table', dict(uri='table:')),
                                 ('lsm', dict(uri='lsm:'))])

    # Populate an object, then rebalance it.
    def rebalance(self, populate, with_cursor):
        uri = self.uri + self.name
        populate(self, uri, self.config, 10000)

        # Force to disk, we don't rebalance in-memory objects.
        self.reopen_conn()

        # Open cursors should cause failure.
        if with_cursor:
            cursor = self.session.open_cursor(uri, None, None)
            self.assertRaises(wiredtiger.WiredTigerError,
                              lambda: self.session.drop(uri, None))
            cursor.close()

        self.session.rebalance(uri, None)
        self.session.drop(uri)

    # Test rebalance of an object.
    def test_rebalance(self):
        # Simple file or table object.
        self.rebalance(simple_populate, False)
        self.rebalance(simple_populate, True)

        # A complex, multi-file table object.
        if self.uri == "table:":
            self.rebalance(complex_populate, False)
            self.rebalance(complex_populate, True)
Esempio n. 26
0
class test_util03(wttest.WiredTigerTestCase, suite_subprocess):
    tablename = 'test_util03.a'
    nentries = 1000

    scenarios = check_scenarios([
        ('none', dict(key_format=None, value_format=None)),
        ('SS', dict(key_format='S', value_format='S')),
        ('rS', dict(key_format='r', value_format='S')),
        ('ri', dict(key_format='r', value_format='i')),
    ])

    def test_create_process(self):
        """
        Test create in a 'wt' process
        """

        args = ["create"]
        if self.key_format != None or self.value_format != None:
            args.append('-c')
            config = ''
            if self.key_format != None:
                config += 'key_format=' + self.key_format + ','
            if self.value_format != None:
                config += 'value_format=' + self.value_format
            args.append(config)
        args.append('table:' + self.tablename)
        self.runWt(args)

        cursor = self.session.open_cursor('table:' + self.tablename, None,
                                          None)
        if self.key_format != None:
            self.assertEqual(cursor.key_format, self.key_format)
        if self.value_format != None:
            self.assertEqual(cursor.value_format, self.value_format)
        for key, val in cursor:
            self.fail('table should be empty')
        cursor.close()
Esempio n. 27
0
class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess):
    dir='backup.dir'                    # Backup directory name
    logmax="100K"

    # This test is written to test incremental backups.  We want to add
    # enough data to generate more than one log file each time we add data.
    # First we populate and take a full backup.  Then we loop, checkpointing
    # running an incremental backup with a targeted cursor and then calling
    # truncate to archive the logs.
    #
    # At the same time, we take a full backup during each loop.
    # We run recovery and verify the full backup with the incremental
    # backup after each loop.  We compare two backups instead of the original
    # because running 'wt' causes all of our original handles to be closed
    # and that is not what we want here.
    #
    pfx = 'test_backup'
    scenarios = check_scenarios([
        ('table', dict(uri='table:test',dsize=100,nops=2000,nthreads=1,time=30)),
    ])

    # Create a large cache, otherwise this test runs quite slowly.
    def setUpConnectionOpen(self, dir):
        wtopen_args = \
            'create,cache_size=1G,log=(archive=false,enabled,file_max=%s)' % \
            self.logmax
        conn = wiredtiger.wiredtiger_open(dir, wtopen_args)
        self.pr(`conn`)
        return conn

    def populate(self, uri, dsize, rows):
        self.pr('populate: ' + uri + ' with ' + str(rows) + ' rows')
        cursor = self.session.open_cursor(uri, None)
        for i in range(1, rows + 1):
            cursor[key_populate(cursor, i)] = str(i) + ':' + 'a' * dsize
        cursor.close()

    def update(self, uri, dsize, upd, rows):
        self.pr('update: ' + uri + ' with ' + str(rows) + ' rows')
        cursor = self.session.open_cursor(uri, None)
        for i in range(1, rows + 1):
            cursor[key_populate(cursor, i)] = str(i) + ':' + upd * dsize
        cursor.close()

    # Compare the original and backed-up files using the wt dump command.
    def compare(self, uri, dir_full, dir_incr):
        # print "Compare: full URI: " + uri + " with incremental URI " 
        if dir_full == None:
            full_name='original'
        else:
            full_name='backup_full'
        incr_name='backup_incr'
        if os.path.exists(full_name):
            os.remove(full_name)
        if os.path.exists(incr_name):
            os.remove(incr_name)
        #
        # We have been copying the logs only, so we need to force 'wt' to
        # run recovery in order to apply all the logs and check the data.
        #
        if dir_full == None:
            self.runWt(['-R', 'dump', uri], outfilename=full_name)
        else:
            self.runWt(['-R', '-h', dir_full, 'dump', uri], outfilename=full_name)
        self.runWt(['-R', '-h', dir_incr, 'dump', uri], outfilename=incr_name)
        self.assertEqual(True,
            compare_files(self, full_name, incr_name))

    def take_full_backup(self, dir):
        # Open up the backup cursor, and copy the files.  Do a full backup.
        cursor = self.session.open_cursor('backup:', None, None)
        self.pr('Full backup to ' + dir + ': ')
        os.mkdir(dir)
        while True:
            ret = cursor.next()
            if ret != 0:
                break
            newfile = cursor.get_key()
            sz = os.path.getsize(newfile)
            self.pr('Copy from: ' + newfile + ' (' + str(sz) + ') to ' + dir)
            shutil.copy(newfile, dir)
        self.assertEqual(ret, wiredtiger.WT_NOTFOUND)
        cursor.close()

    # Take an incremental backup and then truncate/archive the logs.
    def take_incr_backup(self, dir):
            config = 'target=("log:")'
            cursor = self.session.open_cursor('backup:', None, config)
            while True:
                ret = cursor.next()
                if ret != 0:
                    break
                newfile = cursor.get_key()
                sz = os.path.getsize(newfile)
                self.pr('Copy from: ' + newfile + ' (' + str(sz) + ') to ' + dir)
                shutil.copy(newfile, dir)
            self.assertEqual(ret, wiredtiger.WT_NOTFOUND)
            self.session.truncate('log:', cursor, None, None)
            cursor.close()

    # Run background inserts while running checkpoints and incremental backups
    # repeatedly.
    def test_incremental_backup(self):
        import sys
        # Create the backup directory.
        self.session.create(self.uri, "key_format=S,value_format=S")

        self.populate(self.uri, self.dsize, self.nops)

        # We need to start the directory for the incremental backup with
        # a full backup.  The full backup function creates the directory.
        dir = self.dir
        self.take_full_backup(dir)
        self.session.checkpoint(None)

        #
        # Incremental backups perform a loop:
        #   Do more work
        #   Checkpoint
        #   Copy log files returned by log targeted backup cursor
        #   Truncate (archive) the log files
        #   Close the backup cursor
        updstr="bcdefghi"
        for increment in range(0, 5):
            full_dir = self.dir + str(increment)
            # Add more work to move the logs forward.
            self.update(self.uri, self.dsize, updstr[increment], self.nops)
            self.session.checkpoint(None)

            self.pr('Iteration: ' + str(increment))
            self.take_incr_backup(self.dir)

        # After running, take a full backup.  Compare the incremental
        # backup to the original database and the full backup database.
        self.take_full_backup(full_dir)
        self.compare(self.uri, full_dir, self.dir)
        self.compare(self.uri, None, self.dir)
Esempio n. 28
0
class test_async01(wttest.WiredTigerTestCase, suite_subprocess):
    """
    Test basic operations
    """
    table_name1 = 'test_async01'
    nentries = 100
    async_ops = nentries / 2
    async_threads = 3
    current = {}

    scenarios = check_scenarios([
        ('file-col', dict(tablekind='col', uri='file')),
        ('file-fix', dict(tablekind='fix', uri='file')),
        ('file-row', dict(tablekind='row', uri='file')),
        ('lsm-row', dict(tablekind='row', uri='lsm')),
        ('table-col', dict(tablekind='col', uri='table')),
        ('table-fix', dict(tablekind='fix', uri='table')),
        ('table-row', dict(tablekind='row', uri='table')),
    ])

    # Overrides WiredTigerTestCase so that we can configure
    # async operations.
    def setUpConnectionOpen(self, dir):
        self.home = dir
        conn_params = \
                'create,error_prefix="%s: ",' % self.shortid() + \
                'async=(enabled=true,ops_max=%s,' % self.async_ops + \
                'threads=%s)' % self.async_threads
        sys.stdout.flush()
        conn = wiredtiger_open(dir, conn_params)
        self.pr( ` conn `)
        return conn

    def genkey(self, i):
        if self.tablekind == 'row':
            return 'key' + str(i)
        else:
            return long(i + 1)

    def genvalue(self, i):
        if self.tablekind == 'fix':
            return int(i & 0xff)
        else:
            return 'value' + str(i)

    # Create and populate the object.
    def create_session(self, tablearg):
        if self.tablekind == 'row':
            keyformat = 'key_format=S'
        else:
            keyformat = 'key_format=r'  # record format
        if self.tablekind == 'fix':
            valformat = 'value_format=8t'
        else:
            valformat = 'value_format=S'
        create_args = keyformat + ',' + valformat

        self.pr('creating session: ' + create_args)
        self.session.create(tablearg, create_args)

    def test_ops(self):
        tablearg = self.uri + ':' + self.table_name1
        ncompact = 0
        self.create_session(tablearg)

        # Populate our reference table first, so we don't need to
        # use locks to reference it.
        self.current = {}
        for i in range(0, self.nentries):
            k = self.genkey(i)
            v = self.genvalue(i)
            self.current[k] = v

        # Populate table with async inserts, callback checks
        # to ensure key/value is correct.
        callback = Callback(self.current)
        for i in range(0, self.nentries):
            self.pr('creating async op')
            op = self.conn.async_new_op(tablearg, None, callback)
            k = self.genkey(i)
            v = self.genvalue(i)
            op.set_key(k)
            op.set_value(v)
            op.insert()

        # Compact after insert.
        # Wait for all outstanding async ops to finish.
        op = self.conn.async_new_op(tablearg, 'timeout=0', callback)
        op.compact()
        ncompact += 1
        self.conn.async_flush()
        self.pr('flushed')

        # Now test async search and check key/value in the callback.
        for i in range(0, self.nentries):
            op = self.conn.async_new_op(tablearg, None, callback)
            k = self.genkey(i)
            op.set_key(k)
            op.search()

        # Wait for all outstanding async ops to finish.
        self.conn.async_flush()
        self.pr('flushed')

        # Reset the reference table for the update.
        for i in range(0, self.nentries):
            k = self.genkey(i)
            v = self.genvalue(i + 10)
            self.current[k] = v

        for i in range(0, self.nentries):
            self.pr('creating async op')
            op = self.conn.async_new_op(tablearg, None, callback)
            k = self.genkey(i)
            v = self.genvalue(i + 10)
            op.set_key(k)
            op.set_value(v)
            op.update()

        # Compact after update.
        # Wait for all outstanding async ops to finish.
        op = self.conn.async_new_op(tablearg, None, callback)
        op.compact()
        ncompact += 1
        self.conn.async_flush()
        self.pr('flushed')

        # Now test async search and check key/value in the callback.
        for i in range(0, self.nentries):
            op = self.conn.async_new_op(tablearg, None, callback)
            k = self.genkey(i)
            op.set_key(k)
            op.search()

        # Wait for all outstanding async ops to finish.
        self.conn.async_flush()
        self.pr('flushed')

        for i in range(0, self.nentries):
            self.pr('creating async op')
            op = self.conn.async_new_op(tablearg, None, callback)
            k = self.genkey(i)
            op.set_key(k)
            op.remove()

        # Wait for all outstanding async ops to finish.
        self.conn.async_flush()
        self.pr('flushed')

        # Make sure all callbacks went according to plan.
        self.assertTrue(callback.ncompact == ncompact)
        self.assertTrue(callback.ninsert == self.nentries)
        self.assertTrue(callback.nremove == self.nentries)
        self.assertTrue(callback.nsearch == self.nentries * 2)
        self.assertTrue(callback.nupdate == self.nentries)
        self.assertTrue(callback.nerror == 0)
Esempio n. 29
0
class test_cursor_pin(wttest.WiredTigerTestCase):
    uri = 'file:cursor_pin'
    nentries = 10000
    config = 'allocation_size=512,leaf_page_max=512,value_format=S,key_format='
    scenarios = check_scenarios([
        ('recno', dict(keyfmt='r')),
        ('string', dict(keyfmt='S')),
    ])

    # Create a multi-page file, confirm that a simple search to the local
    # page works, followed by a search to a different page.
    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))

    # Forward check.
    def forward(self, c, max, notfound):
        for i in range(1, max + 1):
            c.set_key(key_populate(c, i))
            if i in notfound:
                self.assertEqual(c.search(), wiredtiger.WT_NOTFOUND)
            else:
                self.assertEqual(c.search(), 0)
                self.assertEqual(c.get_value(), value_populate(c, i))

    # Backward check.
    def backward(self, c, max, notfound):
        for i in range(max, 0, -1):
            c.set_key(key_populate(c, i))
            if i in notfound:
                self.assertEqual(c.search(), wiredtiger.WT_NOTFOUND)
            else:
                self.assertEqual(c.search(), 0)
                self.assertEqual(c.get_value(), value_populate(c, i))

    # Create a multi-page file, search backward, forward to check page
    # boundaries.
    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, [])

    # Create a multi-page file with a big chunk of missing space in the
    # middle (to exercise column-store searches).
    def test_missing(self):
        simple_populate(self, self.uri, self.config + self.keyfmt,
                        self.nentries)
        c = self.session.open_cursor(self.uri, None)
        for i in range(self.nentries + 3000, self.nentries + 5001):
            c[key_populate(c, i)] = value_populate(c, i)
        self.reopen_conn()
        c = self.session.open_cursor(self.uri, None)
        self.forward(c, self.nentries + 5000,
                     list(range(self.nentries + 1, self.nentries + 3000)))
        self.backward(c, self.nentries + 5000,
                      list(range(self.nentries + 1, self.nentries + 3000)))

        # Insert into the empty space so we test searching inserted items.
        for i in range(self.nentries + 1000, self.nentries + 2001):
            c[key_populate(c, i)] = value_populate(c, i)
        self.forward(c, self.nentries + 5000,
            list(range(self.nentries + 1, self.nentries + 1000) +\
                 range(self.nentries + 2001, self.nentries + 3000)))
        self.backward(c, self.nentries + 5000,
            list(range(self.nentries + 1, self.nentries + 1000) +\
                 range(self.nentries + 2001, self.nentries + 3000)))
Esempio n. 30
0
class test_schema02(wttest.WiredTigerTestCase):
    """
    Test basic operations
    """
    nentries = 1000

    scenarios = check_scenarios([
        ('normal', { 'idx_config' : '' }),
        ('lsm', { 'idx_config' : ',type=lsm' }),
    ])

    def expect_failure_colgroup(self, name, configstr, match):
        self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
            lambda:self.session.create("colgroup:" + name, configstr), match)

    def test_colgroup_after_failure(self):
        # bogus formats
        self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
            lambda:self.session.create("table:main",
                                       "key_format=Z,value_format=S"),
            "/Invalid type 'Z' found in format 'Z'/")
        self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
            lambda:self.session.create("table:main",
                                       "key_format=S,value_format=Z"),
            "/Invalid type 'Z' found in format 'Z'/")

        # These should succeed
        self.session.create("table:main", "key_format=iS,value_format=SiSi,"
                            "columns=(ikey,Skey,S1,i2,S3,i4),colgroups=(c1,c2)")
        self.session.create("colgroup:main:c1", "columns=(S1,i2)")

    def test_colgroup_failures(self):
        # too many columns
        self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
            lambda:self.session.create("table:main", "key_format=S,"
                                       "value_format=,columns=(a,b)"),
            "/Number of columns in '\(a,b\)' does not match "
            "key format 'S' plus value format ''/")
        # Note: too few columns is allowed

        # expect this to work
        self.session.create("table:main", "key_format=iS,value_format=SiSi,"
                            "columns=(ikey,Skey,S1,i2,S3,i4),"
                            "colgroups=(c1,c2)")

        # bad table name
        self.expect_failure_colgroup("nomatch:c", "columns=(S1,i2)",
                                     "/Can't create 'colgroup:nomatch:c'"
                                     " for non-existent table 'nomatch'/")
        # colgroup not declared in initial create
        self.expect_failure_colgroup("main:nomatch", "columns=(S1,i2)",
                                     "/Column group 'nomatch' not found"
                                     " in table 'main'/")
        # bad column
        self.expect_failure_colgroup("main:c1", "columns=(S1,i2,bad)",
                                     "/Column 'bad' not found/")

        # TODO: no columns allowed, or not?
        #self.session.create("colgroup:main:c0", "columns=()")

        # key in a column group
        self.expect_failure_colgroup("main:c1", "columns=(ikey,S1,i2)",
                                     "/A column group cannot store key column"
                                     " 'ikey' in its value/")

        # expect this to work
        self.session.create("colgroup:main:c1", "columns=(S1,i2)")

        # colgroup not declared in initial create
        self.expect_failure_colgroup("main:c3", "columns=(S3,i4)",
                                     "/Column group 'c3' not found in"
                                     " table 'main'/")

        # this is the last column group, but there are missing columns
        self.expect_failure_colgroup("main:c2", "columns=(S1,i4)",
                                     "/Column 'S3' in 'table:main' does not"
                                     " appear in a column group/")

        # TODO: is repartitioning column groups allowed?
        # this does not raise an error
        # self.expect_failure_colgroup("main:c2", "columns=(S1,S3,i4)"

        # expect this to work
        self.session.create("colgroup:main:c2", "columns=(S3,i4)")

        # expect these to work - each table name is a separate namespace
        self.session.create("table:main2", "key_format=iS,value_format=SiSi,"
                            "columns=(ikey,Skey,S1,i2,S3,i4),colgroups=(c1,c2)")
        self.session.create("colgroup:main2:c1", "columns=(S1,i2)")
        self.session.create("colgroup:main2:c2", "columns=(S3,i4)")

    def test_index(self):
        self.session.create("table:main", "key_format=iS,value_format=SiSi,"
                            "columns=(ikey,Skey,S1,i2,S3,i4),colgroups=(c1,c2)")

        # should be able to create colgroups before indices
        self.session.create("colgroup:main:c2", "columns=(S3,i4)")

        # should be able to create indices on all key combinations
        self.session.create(
            "index:main:ikey", "columns=(ikey)" + self.idx_config)
        self.session.create(
            "index:main:Skey", "columns=(Skey)" + self.idx_config)
        self.session.create(
            "index:main:ikeySkey", "columns=(ikey,Skey)" + self.idx_config)
        self.session.create(
            "index:main:Skeyikey", "columns=(Skey,ikey)" + self.idx_config)

        # should be able to create indices on all value combinations
        self.session.create(
            "index:main:S1", "columns=(S1)" + self.idx_config)
        self.session.create(
            "index:main:i2", "columns=(i2)" + self.idx_config)
        self.session.create(
            "index:main:i2S1", "columns=(i2,S1)" + self.idx_config)
        self.session.create(
            "index:main:S1i4", "columns=(S1,i4)" + self.idx_config)

        # somewhat nonsensical to repeat columns within an index, but allowed
        self.session.create(
            "index:main:i4S3i4S1", "columns=(i4,S3,i4,S1)" + self.idx_config)

        # should be able to create colgroups after indices
        self.session.create("colgroup:main:c1", "columns=(S1,i2)")

        self.populate()

        # should be able to create indices after populating
        self.session.create(
            "index:main:i2S1i4", "columns=(i2,S1,i4)" + self.idx_config)

        self.check_entries()

    def populate(self):
        cursor = self.session.open_cursor('table:main', None, None)
        for i in range(0, self.nentries):
            cursor.set_key(i, 'key' + str(i))
            square = i * i
            cube = square * i
            cursor.set_value('val' + str(square), square, 'val' + str(cube), cube)
            cursor.insert()
        cursor.close()
        
    def check_entries(self):
        cursor = self.session.open_cursor('table:main', None, None)
        # spot check via search
        n = self.nentries
        for i in (n / 5, 0, n - 1, n - 2, 1):
            cursor.set_key(i, 'key' + str(i))
            square = i * i
            cube = square * i
            cursor.search()
            (s1, i2, s3, i4) = cursor.get_values()
            self.assertEqual(s1, 'val' + str(square))
            self.assertEqual(i2, square)
            self.assertEqual(s3, 'val' + str(cube))
            self.assertEqual(i4, cube)

        i = 0
        # then check all via cursor
        cursor.reset()
        for ikey, skey, s1, i2, s3, i4 in cursor:
            square = i * i
            cube = square * i
            self.assertEqual(ikey, i)
            self.assertEqual(skey, 'key' + str(i))
            self.assertEqual(s1, 'val' + str(square))
            self.assertEqual(i2, square)
            self.assertEqual(s3, 'val' + str(cube))
            self.assertEqual(i4, cube)
            i += 1
        cursor.close()
        self.assertEqual(i, n)
        
    def test_colgroups(self):
        self.session.create("table:main", "key_format=iS,value_format=SiSi,"
                            "columns=(ikey,Skey,S1,i2,S3,i4),colgroups=(c1,c2)")
        self.session.create("colgroup:main:c1", "columns=(S1,i2)")
        self.session.create("colgroup:main:c2", "columns=(S3,i4)")
        self.populate()
        self.check_entries()