nim-rocksdb/tests/test_optimistictxdb.nim

292 lines
7.7 KiB
Nim

# Nim-RocksDB
# Copyright 2024 Status Research & Development GmbH
# Licensed under either of
#
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# * GPL license, version 2.0, ([LICENSE-GPLv2](LICENSE-GPLv2) or https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
#
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.used.}
import std/os, tempfile, unittest2, ../rocksdb/optimistictxdb, ./test_helper
suite "OptimisticTxDbRef Tests":
const
CF_DEFAULT = "default"
CF_OTHER = "other"
let
key1 = @[byte(1)]
val1 = @[byte(1)]
key2 = @[byte(2)]
val2 = @[byte(2)]
key3 = @[byte(3)]
val3 = @[byte(3)]
setup:
let
dbPath = mkdtemp() / "data"
db = initOptimisticTxDb(dbPath, columnFamilyNames = @[CF_OTHER])
defaultCfHandle = db.getColFamilyHandle(CF_DEFAULT).get()
otherCfHandle = db.getColFamilyHandle(CF_OTHER).get()
teardown:
db.close()
removeDir($dbPath)
# test multiple transactions
test "Test rollback using default column family":
var tx = db.beginTransaction()
defer:
tx.close()
check not tx.isClosed()
check:
tx.put(key1, val1).isOk()
tx.put(key2, val2).isOk()
tx.put(key3, val3).isOk()
tx.delete(key2).isOk()
not tx.isClosed()
check:
tx.get(key1).get() == val1
tx.get(key2).error() == ""
tx.get(key3).get() == val3
let res = tx.rollback()
check:
res.isOk()
tx.get(key1).error() == ""
tx.get(key2).error() == ""
tx.get(key3).error() == ""
test "Test commit using default column family":
var tx = db.beginTransaction()
defer:
tx.close()
check not tx.isClosed()
check:
tx.put(key1, val1).isOk()
tx.put(key2, val2).isOk()
tx.put(key3, val3).isOk()
tx.delete(key2).isOk()
not tx.isClosed()
check:
tx.get(key1).get() == val1
tx.get(key2).error() == ""
tx.get(key3).get() == val3
let res = tx.commit()
check:
res.isOk()
tx.get(key1).get() == val1
tx.get(key2).error() == ""
tx.get(key3).get() == val3
test "Test setting column family in beginTransaction":
var tx = db.beginTransaction(cfHandle = otherCfHandle)
defer:
tx.close()
check not tx.isClosed()
check:
tx.put(key1, val1).isOk()
tx.put(key2, val2).isOk()
tx.put(key3, val3).isOk()
tx.delete(key2).isOk()
not tx.isClosed()
check:
tx.get(key1, defaultCfHandle).error() == ""
tx.get(key2, defaultCfHandle).error() == ""
tx.get(key3, defaultCfHandle).error() == ""
tx.get(key1, otherCfHandle).get() == val1
tx.get(key2, otherCfHandle).error() == ""
tx.get(key3, otherCfHandle).get() == val3
test "Test rollback and commit with multiple transactions":
var tx1 = db.beginTransaction(cfHandle = defaultCfHandle)
defer:
tx1.close()
check not tx1.isClosed()
var tx2 = db.beginTransaction(cfHandle = otherCfHandle)
defer:
tx2.close()
check not tx2.isClosed()
check:
tx1.put(key1, val1).isOk()
tx1.put(key2, val2).isOk()
tx1.put(key3, val3).isOk()
tx1.delete(key2).isOk()
not tx1.isClosed()
tx2.put(key1, val1).isOk()
tx2.put(key2, val2).isOk()
tx2.put(key3, val3).isOk()
tx2.delete(key2).isOk()
not tx2.isClosed()
check:
tx1.get(key1, defaultCfHandle).get() == val1
tx1.get(key2, defaultCfHandle).error() == ""
tx1.get(key3, defaultCfHandle).get() == val3
tx1.get(key1, otherCfHandle).error() == ""
tx1.get(key2, otherCfHandle).error() == ""
tx1.get(key3, otherCfHandle).error() == ""
tx2.get(key1, defaultCfHandle).error() == ""
tx2.get(key2, defaultCfHandle).error() == ""
tx2.get(key3, defaultCfHandle).error() == ""
tx2.get(key1, otherCfHandle).get() == val1
tx2.get(key2, otherCfHandle).error() == ""
tx2.get(key3, otherCfHandle).get() == val3
block:
let res = tx1.rollback()
check:
res.isOk()
tx1.get(key1, defaultCfHandle).error() == ""
tx1.get(key2, defaultCfHandle).error() == ""
tx1.get(key3, defaultCfHandle).error() == ""
tx1.get(key1, otherCfHandle).error() == ""
tx1.get(key2, otherCfHandle).error() == ""
tx1.get(key3, otherCfHandle).error() == ""
block:
let res = tx2.commit()
check:
res.isOk()
tx2.get(key1, defaultCfHandle).error() == ""
tx2.get(key2, defaultCfHandle).error() == ""
tx2.get(key3, defaultCfHandle).error() == ""
tx2.get(key1, otherCfHandle).get() == val1
tx2.get(key2, otherCfHandle).error() == ""
tx2.get(key3, otherCfHandle).get() == val3
test "Test close":
var tx = db.beginTransaction()
check not tx.isClosed()
tx.close()
check tx.isClosed()
tx.close()
check tx.isClosed()
check not db.isClosed()
db.close()
check db.isClosed()
db.close()
check db.isClosed()
test "Test close multiple tx":
var tx1 = db.beginTransaction()
var tx2 = db.beginTransaction()
check not db.isClosed()
check not tx1.isClosed()
tx1.close()
check tx1.isClosed()
tx1.close()
check tx1.isClosed()
check not db.isClosed()
check not tx2.isClosed()
tx2.close()
check tx2.isClosed()
tx2.close()
check tx2.isClosed()
test "Test auto close enabled":
let
dbPath = mkdtemp() / "autoclose-enabled"
dbOpts = defaultDbOptions(autoClose = true)
columnFamilies =
@[
initColFamilyDescriptor(CF_DEFAULT, defaultColFamilyOptions(autoClose = true))
]
db = openOptimisticTxDb(dbPath, dbOpts, columnFamilies).get()
check:
dbOpts.isClosed() == false
columnFamilies[0].isClosed() == false
db.isClosed() == false
db.close()
check:
dbOpts.isClosed() == true
columnFamilies[0].isClosed() == true
db.isClosed() == true
test "Test auto close enabled":
let
dbPath = mkdtemp() / "autoclose-disabled"
dbOpts = defaultDbOptions(autoClose = false)
columnFamilies =
@[
initColFamilyDescriptor(
CF_DEFAULT, defaultColFamilyOptions(autoClose = false)
)
]
db = openOptimisticTxDb(dbPath, dbOpts, columnFamilies).get()
check:
dbOpts.isClosed() == false
columnFamilies[0].isClosed() == false
db.isClosed() == false
db.close()
check:
dbOpts.isClosed() == false
columnFamilies[0].isClosed() == false
db.isClosed() == true
test "Test auto close tx enabled":
let
readOpts = defaultReadOptions(autoClose = true)
writeOpts = defaultWriteOptions(autoClose = true)
otxOpts = defaultOptimisticTxOptions(autoClose = true)
tx = db.beginTransaction(readOpts, writeOpts, otxOpts)
check:
readOpts.isClosed() == false
writeOpts.isClosed() == false
otxOpts.isClosed() == false
tx.isClosed() == false
tx.close()
check:
readOpts.isClosed() == true
writeOpts.isClosed() == true
otxOpts.isClosed() == true
tx.isClosed() == true
test "Test auto close tx disabled":
let
readOpts = defaultReadOptions(autoClose = false)
writeOpts = defaultWriteOptions(autoClose = false)
otxOpts = defaultOptimisticTxOptions(autoClose = false)
tx = db.beginTransaction(readOpts, writeOpts, otxOpts)
check:
readOpts.isClosed() == false
writeOpts.isClosed() == false
otxOpts.isClosed() == false
tx.isClosed() == false
tx.close()
check:
readOpts.isClosed() == false
writeOpts.isClosed() == false
otxOpts.isClosed() == false
tx.isClosed() == true