Example #1
0
def test_size_limit_option(db):
    value = b'a' * 1024

    setValue(db, b't1', value)
    assert(value == db[b't1'])

    try:
        db.options.set_transaction_size_limit(1000)
        setValue(db, b't2', value)
        assert(False)  # not reached
    except fdb.FDBError as e:
        assert(e.code == 2101)  # Transaction exceeds byte limit (2101)

    # Per transaction option overrides database option
    db.options.set_transaction_size_limit(1000000)
    try:
        setValueWithLimit(db, b't3', value, 1000)
        assert(False)  # not reached
    except fdb.FDBError as e:
        assert(e.code == 2101)  # Transaction exceeds byte limit (2101)

    # DB default survives on_error reset
    db.options.set_transaction_size_limit(1000)
    tr = db.create_transaction()
    try:
        tr[b't4'] = b'bar'
        tr.on_error(fdb.FDBError(1007)).wait()
        setValue(tr, b't4', value)
        tr.commit().wait()
        assert(False)  # not reached
    except fdb.FDBError as e:
        assert(e.code == 2101)  # Transaction exceeds byte limit (2101)
Example #2
0
 def txn2(tr):
     tr.options.set_timeout(100)
     tr.on_error(fdb.FDBError(1007)).wait()  # should not throw
     time.sleep(1)
     try:
         tr.commit().wait()  # should throw
     except fdb.FDBError as e:
         if e.code != 1031:
             raise
Example #3
0
 def txn1(tr):
     tr.options.set_retry_limit(0)
     tr.options.set_timeout(100)
     try:
         tr.on_error(fdb.FDBError(1007)).wait()  # should throw
         raise TestError("Retry limit was ignored.")
     except fdb.FDBError as e:
         if e.code != 1007:
             raise
     time.sleep(1)
     tr.commit().wait()  # should not throw
Example #4
0
 def txn8(tr):
     tr[b'foo'] = b'bar'
     time.sleep(1)
     tr.on_error(fdb.FDBError(1007)).wait()  # should not throw
     tr[b'foo'] = b'bar'
     tr.options.set_timeout(100)
     try:
         tr.commit().wait()  # should throw
         raise TestError("Timeout didn't fire.")
     except fdb.FDBError as e:
         if e.code != 1031:
             raise
Example #5
0
 def txn3(tr):
     tr.cancel()
     try:
         tr.on_error(fdb.FDBError(1007)).wait()  # should throw
         raise TestError('on_error() did not notice cancellation.')
     except fdb.FDBError as e:
         if e.code != 1025:
             raise
     try:
         tr.commit().wait()  # should throw
         raise TestError('Cancellation did not survive on_error().')
     except fdb.FDBError as e:
         if e.code != 1025:
             raise
Example #6
0
 def txn11(tr):
     for i in range(2):
         tr.options.set_timeout(1500)
         tr.set_read_version(0x7ffffffffffffff0)
         x = tr[b'foo']
         try:
             tr.commit().wait()
             tr.reset()
         except fdb.FDBError as e:
             if i == 0:
                 if e.code != 1009:  # future_version
                     raise fdb.FDBError(1007)  # Something weird happened; raise a retryable error so we run this transaction again
                 else:
                     tr.on_error(e).wait()
             elif i == 1 and e.code != 1031:
                 raise
Example #7
0
 def wait_empty(tr, prefix):
     res = tr.get_range_startswith(prefix, 1).to_list()
     if len(res) == 1:
         raise fdb.FDBError(1020)
Example #8
0
def test_predicates():
    assert fdb.predicates.is_retryable(fdb.FDBError(1020))
    assert not fdb.predicates.is_retryable(fdb.FDBError(10))
Example #9
0
 def txn2(tr):
     tr.options.set_timeout(100)
     tr.on_error(fdb.FDBError(1007)).wait()  # should not throw
     time.sleep(1)
     tr.commit().wait()  # should not throw
Example #10
0
def test_retry_limits(db):
    err = fdb.FDBError(1007)

    # (1) Basic retry limits
    @retry_with_timeout(default_timeout)
    def txn1(tr):
        tr.options.set_retry_limit(1)
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        tr.options.set_retry_limit(1)
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(1) Retry limit was ignored.')
        except fdb.FDBError as e:
            if e.code != 1007:
                raise
        tr[b'foo'] = b'bar'
        tr.options.set_retry_limit(1)
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(1) Retry limit was ignored.')
        except fdb.FDBError as e:
            if e.code != 1007:
                raise

    txn1(db)

    # (2) Number of retries accumulates even when limit is being hit
    @retry_with_timeout(default_timeout)
    def txn2(tr):
        tr.options.set_retry_limit(0)
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(2) Retry limit was ignored.')
        except fdb.FDBError as e:
            if e.code != 1007:
                raise
        tr.options.set_retry_limit(1)
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(2) Retry limit was ignored.')
        except fdb.FDBError as e:
            if e.code != 1007:
                raise

    txn2(db)

    # (3) Retry limits don't survive resets
    @retry_with_timeout(default_timeout)
    def txn3(tr):
        tr.options.set_retry_limit(1)
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr.options.set_retry_limit(1)
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(3) Retry limit was ignored.')
        except fdb.FDBError as e:
            if e.code != 1007:
                raise
        tr.reset()
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw

    txn3(db)

    # (4) Number of retries does not survive resets
    @retry_with_timeout(default_timeout)
    def txn4(tr):
        tr.options.set_retry_limit(0)
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(4) Retry limit was ignored.')
        except fdb.FDBError as e:
            if e.code != 1007:
                raise
        tr.reset()
        tr.options.set_retry_limit(1)
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw

    txn4(db)

    # (5) Retries accumulate when limits are turned off, and are respected retroactively
    @retry_with_timeout(default_timeout)
    def txn5(tr):
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr.options.set_retry_limit(1)
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(5) Retry limit was ignored.')
        except fdb.FDBError as e:
            if e.code != 1007:
                raise
        tr[b'foo'] = b'bar'
        tr.options.set_retry_limit(-1)
        tr.on_error(err).wait()  # should not throw
        tr.options.set_retry_limit(4)
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(5) Retry limit was ignored.')
        except fdb.FDBError as e:
            if e.code != 1007:
                raise

    txn5(db)

    # (6) Retry limits don't survive on_error()
    @retry_with_timeout(default_timeout)
    def txn6(tr):
        tr.options.set_retry_limit(1)
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        tr.options.set_retry_limit(1)
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(6) Retry limit was ignored.')
        except fdb.FDBError as e:
            if e.code != 1007:
                raise
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw

    txn6(db)
Example #11
0
def test_db_timeouts(db):
    err = fdb.FDBError(1007)
    db.options.set_transaction_timeout(500)

    # (1) Basic timeout
    @retry_with_timeout(default_timeout)
    def txn1(tr):
        time.sleep(1)
        try:
            tr.commit().wait()  # should throw
            raise TestError("(1) Timeout didn't fire.")
        except fdb.FDBError as e:
            if e.code != 1031:
                raise

    txn1(db)

    # (2) Timeout after on_error
    @retry_with_timeout(default_timeout)
    def txn2(tr):
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        time.sleep(1)
        tr[b'foo']
        try:
            tr.commit().wait()  # should throw
            raise TestError("(2) Timeout didn't fire.")
        except fdb.FDBError as e:
            if e.code != 1031:
                raise

    txn2(db)

    # (3) Longer timeout than database timeout
    @retry_with_timeout(default_timeout)
    def txn3(tr):
        tr.options.set_timeout(1000)
        time.sleep(0.75)
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo']
        time.sleep(0.75)
        try:
            tr.commit().wait()  # should throw
            raise TestError("(3) Timeout didn't fire.")
        except fdb.FDBError as e:
            if e.code != 1031:
                raise

    txn3(db)

    # (4) Shorter timeout than database timeout
    @retry_with_timeout(default_timeout)
    def txn4(tr):
        tr.options.set_timeout(100)
        tr[b'foo'] = b'bar'
        time.sleep(0.2)
        try:
            tr.commit().wait()  # should throw
            raise TestError("(4) Timeout didn't fire.")
        except fdb.FDBError as e:
            if e.code != 1031:
                raise

    txn4(db)

    # (5) Reset resets timeout to database timeout
    @retry_with_timeout(default_timeout)
    def txn5(tr):
        tr.options.set_timeout(100)
        tr[b'foo'] = b'bar'
        time.sleep(0.2)
        try:
            tr.commit().wait()  # should throw
            raise TestError("(5) Timeout didn't fire.")
        except fdb.FDBError as e:
            if e.code != 1031:
                raise
        tr.reset()
        tr[b'foo'] = b'bar'
        time.sleep(0.2)
        tr.on_error(err).wait()  #should not throw
        tr[b'foo'] = b'bar'
        time.sleep(0.8)
        try:
            tr.commit().wait()  # should throw
            raise TestError("(5) Timeout didn't fire.")
        except fdb.FDBError as e:
            if e.code != 1031:
                raise

    txn5(db)

    db.options.set_transaction_timeout(0)  # reset to default (no timeout)
Example #12
0
def test_db_retry_limits(db):
    err = fdb.FDBError(1007)
    db.options.set_transaction_retry_limit(1)

    # (1) Basic retry limit
    @retry_with_timeout(default_timeout)
    def txn1(tr):
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(1) Retry limit from database was ignored.')
        except fdb.FDBError as e:
            if e.code != err.code:
                raise
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(1) Transaction not cancelled after error.')
        except fdb.FDBError as e:
            if e.code != 1025:
                raise

    txn1(db)

    # (2) More retries in transaction than database
    @retry_with_timeout(default_timeout)
    def txn2(tr):
        tr.options.set_retry_limit(2)
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(2) Retry limit from transaction was ignored.')
        except fdb.FDBError as e:
            if e.code != err.code:
                raise
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(2) Transaction not cancelled after error.')
        except fdb.FDBError as e:
            if e.code != 1025:
                raise

    txn2(db)

    # (3) More retries in database than transaction
    db.options.set_transaction_retry_limit(2)

    @retry_with_timeout(default_timeout)
    def txn3(tr):
        tr.options.set_retry_limit(1)
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(3) Retry limit from transaction was ignored.')
        except fdb.FDBError as e:
            if e.code != err.code:
                raise
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(3) Transaction not cancelled after error.')
        except fdb.FDBError as e:
            if e.code != 1025:
                raise

    txn3(db)

    # (4) Reset resets to database default
    @retry_with_timeout(default_timeout)
    def txn4(tr):
        tr.options.set_retry_limit(1)
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(4) Retry limit from transaction was ignored.')
        except fdb.FDBError as e:
            if e.code != err.code:
                raise
        tr.reset()
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        tr.on_error(err).wait()  # should not throw
        tr[b'foo'] = b'bar'
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(4) Retry limit from database was ignored.')
        except fdb.FDBError as e:
            if e.code != err.code:
                raise
        try:
            tr.on_error(err).wait()  # should throw
            raise TestError('(4) Transaction not cancelled after error.')
        except fdb.FDBError as e:
            if e.code != 1025:
                raise

    txn4(db)

    db.options.set_transaction_retry_limit(
        -1)  # reset to default (infinite retries)