226 lines
3.9 KiB
Nim
226 lines
3.9 KiB
Nim
|
import std/oids
|
||
|
import std/options
|
||
|
import std/os
|
||
|
import std/random
|
||
|
import std/sequtils
|
||
|
import std/sets
|
||
|
|
||
|
import pkg/asynctest
|
||
|
import pkg/chronos
|
||
|
import pkg/stew/byteutils
|
||
|
|
||
|
import pkg/codex/chunker
|
||
|
import pkg/codex/blocktype as bt
|
||
|
import pkg/codex/stores
|
||
|
|
||
|
import ../helpers
|
||
|
|
||
|
suite "SQLite Store":
|
||
|
randomize()
|
||
|
|
||
|
var
|
||
|
store: SQLiteStore
|
||
|
|
||
|
let
|
||
|
repoDir = getAppDir() / "repo"
|
||
|
|
||
|
proc randomBlock(): bt.Block =
|
||
|
let
|
||
|
blockRes = bt.Block.new(($genOid()).toBytes)
|
||
|
|
||
|
require(blockRes.isOk)
|
||
|
blockRes.get
|
||
|
|
||
|
var
|
||
|
newBlock: bt.Block
|
||
|
|
||
|
setup:
|
||
|
removeDir(repoDir)
|
||
|
require(not dirExists(repoDir))
|
||
|
store = SQLiteStore.new(repoDir)
|
||
|
newBlock = randomBlock()
|
||
|
|
||
|
teardown:
|
||
|
if not store.isNil: await store.close
|
||
|
store = nil
|
||
|
removeDir(repoDir)
|
||
|
require(not dirExists(repoDir))
|
||
|
|
||
|
test "putBlock":
|
||
|
let
|
||
|
blkKeyRes = blockKey(newBlock.cid)
|
||
|
|
||
|
assert blkKeyRes.isOk
|
||
|
|
||
|
let
|
||
|
blkKey = blkKeyRes.get
|
||
|
|
||
|
var
|
||
|
# bypass cache
|
||
|
containsRes = await store.datastore.contains(blkKey)
|
||
|
|
||
|
assert containsRes.isOk
|
||
|
assert not containsRes.get
|
||
|
|
||
|
let
|
||
|
putRes = await store.putBlock(newBlock)
|
||
|
|
||
|
check: putRes.isOk
|
||
|
|
||
|
# bypass cache
|
||
|
containsRes = await store.datastore.contains(blkKey)
|
||
|
|
||
|
assert containsRes.isOk
|
||
|
|
||
|
check: containsRes.get
|
||
|
|
||
|
test "getBlock":
|
||
|
var
|
||
|
r = rand(100)
|
||
|
|
||
|
# put `r` number of random blocks before putting newBlock
|
||
|
if r > 0:
|
||
|
for _ in 0..r:
|
||
|
let
|
||
|
b = randomBlock()
|
||
|
kRes = blockKey(b.cid)
|
||
|
|
||
|
assert kRes.isOk
|
||
|
|
||
|
let
|
||
|
# bypass cache
|
||
|
pRes = await store.datastore.put(kRes.get, b.data)
|
||
|
|
||
|
assert pRes.isOk
|
||
|
|
||
|
let
|
||
|
blkKeyRes = blockKey(newBlock.cid)
|
||
|
|
||
|
assert blkKeyRes.isOk
|
||
|
|
||
|
var
|
||
|
# bypass cache
|
||
|
putRes = await store.datastore.put(blkKeyRes.get, newBlock.data)
|
||
|
|
||
|
assert putRes.isOk
|
||
|
|
||
|
r = rand(100)
|
||
|
|
||
|
# put `r` number of random blocks after putting newBlock
|
||
|
if r > 0:
|
||
|
for _ in 0..r:
|
||
|
let
|
||
|
b = randomBlock()
|
||
|
kRes = blockKey(b.cid)
|
||
|
|
||
|
assert kRes.isOk
|
||
|
|
||
|
let
|
||
|
# bypass cache
|
||
|
pRes = await store.datastore.put(kRes.get, b.data)
|
||
|
|
||
|
assert pRes.isOk
|
||
|
|
||
|
var
|
||
|
# get from database
|
||
|
getRes = await store.getBlock(newBlock.cid)
|
||
|
|
||
|
check: getRes.isOk
|
||
|
|
||
|
var
|
||
|
blkOpt = getRes.get
|
||
|
|
||
|
check:
|
||
|
blkOpt.isSome
|
||
|
blkOpt.get == newBlock
|
||
|
|
||
|
# get from cache
|
||
|
getRes = await store.getBlock(newBlock.cid)
|
||
|
|
||
|
check: getRes.isOk
|
||
|
|
||
|
blkOpt = getRes.get
|
||
|
|
||
|
check:
|
||
|
blkOpt.isSome
|
||
|
blkOpt.get == newBlock
|
||
|
|
||
|
test "fail getBlock":
|
||
|
let
|
||
|
getRes = await store.getBlock(newBlock.cid)
|
||
|
|
||
|
assert getRes.isOk
|
||
|
|
||
|
let
|
||
|
blkOpt = getRes.get
|
||
|
|
||
|
check: blkOpt.isNone
|
||
|
|
||
|
|
||
|
test "hasBlock":
|
||
|
let
|
||
|
putRes = await store.putBlock(newBlock)
|
||
|
|
||
|
assert putRes.isOk
|
||
|
|
||
|
let
|
||
|
hasRes = await store.hasBlock(newBlock.cid)
|
||
|
|
||
|
check:
|
||
|
hasRes.isOk
|
||
|
hasRes.get
|
||
|
await newBlock.cid in store
|
||
|
|
||
|
test "fail hasBlock":
|
||
|
let
|
||
|
hasRes = await store.hasBlock(newBlock.cid)
|
||
|
|
||
|
check:
|
||
|
hasRes.isOk
|
||
|
not hasRes.get
|
||
|
not (await newBlock.cid in store)
|
||
|
|
||
|
test "listBlocks":
|
||
|
var
|
||
|
newBlocks: seq[bt.Block]
|
||
|
|
||
|
for _ in 0..99:
|
||
|
let
|
||
|
b = randomBlock()
|
||
|
pRes = await store.putBlock(b)
|
||
|
|
||
|
assert pRes.isOk
|
||
|
|
||
|
newBlocks.add(b)
|
||
|
|
||
|
var
|
||
|
called = 0
|
||
|
cids = toHashSet(newBlocks.mapIt(it.cid))
|
||
|
|
||
|
let
|
||
|
onBlock = proc(cid: Cid) {.async, gcsafe.} =
|
||
|
check: cid in cids
|
||
|
if cid in cids:
|
||
|
inc called
|
||
|
cids.excl(cid)
|
||
|
|
||
|
listRes = await store.listBlocks(onBlock)
|
||
|
|
||
|
check:
|
||
|
listRes.isOk
|
||
|
called == newBlocks.len
|
||
|
|
||
|
test "delBlock":
|
||
|
let
|
||
|
putRes = await store.putBlock(newBlock)
|
||
|
|
||
|
assert putRes.isOk
|
||
|
assert (await newBlock.cid in store)
|
||
|
|
||
|
let
|
||
|
delRes = await store.delBlock(newBlock.cid)
|
||
|
|
||
|
check:
|
||
|
delRes.isOk
|
||
|
not (await newBlock.cid in store)
|