2022-07-22 23:38:49 +00:00
|
|
|
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
|
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
proc runSuite(cache: bool) =
|
|
|
|
suite "SQLite Store " & (if cache: "(cache enabled)" else: "(cache disabled)"):
|
|
|
|
randomize()
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
var
|
|
|
|
store: SQLiteStore
|
2022-07-22 23:38:49 +00:00
|
|
|
|
|
|
|
let
|
2022-08-04 23:51:05 +00:00
|
|
|
repoDir = getAppDir() / "repo"
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
proc randomBlock(): bt.Block =
|
|
|
|
let
|
|
|
|
blockRes = bt.Block.new(($genOid()).toBytes)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
require(blockRes.isOk)
|
|
|
|
blockRes.get
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
var
|
|
|
|
newBlock: bt.Block
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
setup:
|
|
|
|
removeDir(repoDir)
|
|
|
|
require(not dirExists(repoDir))
|
2022-08-08 21:42:05 +00:00
|
|
|
createDir(repoDir)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
if cache:
|
|
|
|
store = SQLiteStore.new(repoDir)
|
|
|
|
else:
|
2022-08-19 00:56:36 +00:00
|
|
|
store = SQLiteStore.new(repoDir, cache = nil)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
newBlock = randomBlock()
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
teardown:
|
|
|
|
if not store.isNil: await store.close
|
|
|
|
store = nil
|
|
|
|
removeDir(repoDir)
|
|
|
|
require(not dirExists(repoDir))
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
test "putBlock":
|
|
|
|
let
|
|
|
|
blkKeyRes = blockKey(newBlock.cid)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert blkKeyRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
let
|
|
|
|
blkKey = blkKeyRes.get
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
var
|
|
|
|
# bypass enabled cache
|
|
|
|
containsRes = await store.datastore.contains(blkKey)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert containsRes.isOk
|
|
|
|
assert not containsRes.get
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
let
|
|
|
|
putRes = await store.putBlock(newBlock)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
check: putRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
# bypass enabled cache
|
|
|
|
containsRes = await store.datastore.contains(blkKey)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert containsRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
check: containsRes.get
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
test "getBlock":
|
|
|
|
var
|
|
|
|
r = rand(100)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
# put `r` number of random blocks before putting newBlock
|
|
|
|
if r > 0:
|
|
|
|
for _ in 0..r:
|
|
|
|
let
|
|
|
|
b = randomBlock()
|
|
|
|
kRes = blockKey(b.cid)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert kRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
let
|
|
|
|
# bypass enabled cache
|
|
|
|
pRes = await store.datastore.put(kRes.get, b.data)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert pRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
let
|
|
|
|
blkKeyRes = blockKey(newBlock.cid)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert blkKeyRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
var
|
|
|
|
# bypass enabled cache
|
|
|
|
putRes = await store.datastore.put(blkKeyRes.get, newBlock.data)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert putRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
r = rand(100)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
# put `r` number of random blocks after putting newBlock
|
|
|
|
if r > 0:
|
|
|
|
for _ in 0..r:
|
|
|
|
let
|
|
|
|
b = randomBlock()
|
|
|
|
kRes = blockKey(b.cid)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert kRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
let
|
|
|
|
# bypass enabled cache
|
|
|
|
pRes = await store.datastore.put(kRes.get, b.data)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert pRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
var
|
|
|
|
# get from database
|
|
|
|
getRes = await store.getBlock(newBlock.cid)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
check:
|
2022-08-19 00:56:36 +00:00
|
|
|
getRes.isOk
|
|
|
|
getRes.get == newBlock
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
# get from enabled cache
|
2022-07-22 23:38:49 +00:00
|
|
|
getRes = await store.getBlock(newBlock.cid)
|
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
check:
|
2022-08-19 00:56:36 +00:00
|
|
|
getRes.isOk
|
|
|
|
getRes.get == newBlock
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
test "fail getBlock":
|
|
|
|
let
|
2022-08-19 00:56:36 +00:00
|
|
|
blkRes = await store.getBlock(newBlock.cid)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-19 00:56:36 +00:00
|
|
|
check:
|
|
|
|
blkRes.isErr
|
|
|
|
blkRes.error of BlockNotFoundError
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
test "hasBlock":
|
|
|
|
let
|
|
|
|
putRes = await store.putBlock(newBlock)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert putRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
let
|
|
|
|
hasRes = await store.hasBlock(newBlock.cid)
|
|
|
|
|
|
|
|
check:
|
|
|
|
hasRes.isOk
|
|
|
|
hasRes.get
|
|
|
|
await newBlock.cid in store
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
test "fail hasBlock":
|
2022-07-22 23:38:49 +00:00
|
|
|
let
|
2022-08-04 23:51:05 +00:00
|
|
|
hasRes = await store.hasBlock(newBlock.cid)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
check:
|
|
|
|
hasRes.isOk
|
|
|
|
not hasRes.get
|
|
|
|
not (await newBlock.cid in store)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
test "listBlocks":
|
|
|
|
var
|
|
|
|
newBlocks: seq[bt.Block]
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
for _ in 0..99:
|
|
|
|
let
|
|
|
|
b = randomBlock()
|
|
|
|
pRes = await store.putBlock(b)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
assert pRes.isOk
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
newBlocks.add(b)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
var
|
|
|
|
called = 0
|
|
|
|
cids = toHashSet(newBlocks.mapIt(it.cid))
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
let
|
|
|
|
onBlock = proc(cid: Cid) {.async, gcsafe.} =
|
|
|
|
check: cid in cids
|
|
|
|
if cid in cids:
|
|
|
|
inc called
|
|
|
|
cids.excl(cid)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
listRes = await store.listBlocks(onBlock)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
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)
|
2022-07-22 23:38:49 +00:00
|
|
|
|
2022-08-04 23:51:05 +00:00
|
|
|
runSuite(cache = true)
|
|
|
|
runSuite(cache = false)
|