nim-codex/tests/codex/stores/testrepostore.nim

187 lines
4.8 KiB
Nim
Raw Normal View History

import std/os
import std/options
import std/strutils
import pkg/questionable
import pkg/questionable/results
import pkg/chronos
import pkg/asynctest
import pkg/libp2p
import pkg/stew/byteutils
import pkg/stew/endians2
import pkg/datastore
import pkg/codex/stores/cachestore
import pkg/codex/chunker
import pkg/codex/stores
import pkg/codex/blocktype as bt
import ../helpers
import ./commonstoretests
suite "Test RepoStore Quota":
var
repoDs: Datastore
metaDs: Datastore
setup:
repoDs = SQLiteDatastore.new(Memory).tryGet()
metaDs = SQLiteDatastore.new(Memory).tryGet()
teardown:
(await repoDs.close()).tryGet
(await metaDs.close()).tryGet
test "Should update current used bytes on block put":
let
blk = bt.Block.new('a'.repeat(100).toBytes).tryGet()
repo = RepoStore.new(repoDs, metaDs, quotaMaxBytes = 100)
check repo.quotaUsedBytes == 0
(await repo.putBlock(blk)).tryGet
check:
repo.quotaUsedBytes == 100
uint64.fromBytesBE((await metaDs.get(QuotaUsedKey)).tryGet) == 100'u
test "Should update current used bytes on block delete":
let
blk = bt.Block.new('a'.repeat(100).toBytes).tryGet()
repo = RepoStore.new(repoDs, metaDs, quotaMaxBytes = 100)
check repo.quotaUsedBytes == 0
(await repo.putBlock(blk)).tryGet
check repo.quotaUsedBytes == 100
(await repo.delBlock(blk.cid)).tryGet
check:
repo.quotaUsedBytes == 0
uint64.fromBytesBE((await metaDs.get(QuotaUsedKey)).tryGet) == 0'u
2022-12-05 15:00:13 +00:00
test "Should not update current used bytes if block exist":
let
blk = bt.Block.new('a'.repeat(100).toBytes).tryGet()
repo = RepoStore.new(repoDs, metaDs, quotaMaxBytes = 200)
check repo.quotaUsedBytes == 0
(await repo.putBlock(blk)).tryGet
check repo.quotaUsedBytes == 100
# put again
(await repo.putBlock(blk)).tryGet
check repo.quotaUsedBytes == 100
check:
uint64.fromBytesBE((await metaDs.get(QuotaUsedKey)).tryGet) == 100'u
test "Should fail storing passed the quota":
let
blk = bt.Block.new('a'.repeat(200).toBytes).tryGet()
repo = RepoStore.new(repoDs, metaDs, quotaMaxBytes = 100)
check repo.totalUsed == 0
expect QuotaUsedError:
(await repo.putBlock(blk)).tryGet
test "Should reserve bytes":
let
blk = bt.Block.new('a'.repeat(100).toBytes).tryGet()
repo = RepoStore.new(repoDs, metaDs, quotaMaxBytes = 200)
check repo.totalUsed == 0
(await repo.putBlock(blk)).tryGet
check repo.totalUsed == 100
(await repo.reserve(100)).tryGet
check:
repo.totalUsed == 200
repo.quotaUsedBytes == 100
repo.quotaReservedBytes == 100
uint64.fromBytesBE((await metaDs.get(QuotaReservedKey)).tryGet) == 100'u
test "Should not reserve bytes over max quota":
let
blk = bt.Block.new('a'.repeat(100).toBytes).tryGet()
repo = RepoStore.new(repoDs, metaDs, quotaMaxBytes = 200)
check repo.totalUsed == 0
(await repo.putBlock(blk)).tryGet
check repo.totalUsed == 100
expect QuotaNotEnoughError:
(await repo.reserve(101)).tryGet
check:
repo.totalUsed == 100
repo.quotaUsedBytes == 100
repo.quotaReservedBytes == 0
expect DatastoreKeyNotFound:
discard (await metaDs.get(QuotaReservedKey)).tryGet
test "Should release bytes":
let
blk = bt.Block.new('a'.repeat(100).toBytes).tryGet()
repo = RepoStore.new(repoDs, metaDs, quotaMaxBytes = 200)
check repo.totalUsed == 0
(await repo.reserve(100)).tryGet
check repo.totalUsed == 100
(await repo.release(100)).tryGet
check:
repo.totalUsed == 0
repo.quotaUsedBytes == 0
repo.quotaReservedBytes == 0
uint64.fromBytesBE((await metaDs.get(QuotaReservedKey)).tryGet) == 0'u
test "Should not release bytes less than quota":
let
repo = RepoStore.new(repoDs, metaDs, quotaMaxBytes = 200)
check repo.totalUsed == 0
(await repo.reserve(100)).tryGet
check repo.totalUsed == 100
expect CatchableError:
(await repo.release(101)).tryGet
check:
repo.totalUsed == 100
repo.quotaUsedBytes == 0
repo.quotaReservedBytes == 100
uint64.fromBytesBE((await metaDs.get(QuotaReservedKey)).tryGet) == 100'u
commonBlockStoreTests(
"RepoStore Sql backend", proc: BlockStore =
BlockStore(
RepoStore.new(
SQLiteDatastore.new(Memory).tryGet(),
SQLiteDatastore.new(Memory).tryGet())))
const
path = currentSourcePath().parentDir / "test"
proc before() {.async.} =
createDir(path)
proc after() {.async.} =
removeDir(path)
let
depth = path.split(DirSep).len
commonBlockStoreTests(
"RepoStore FS backend", proc: BlockStore =
BlockStore(
RepoStore.new(
FSDatastore.new(path, depth).tryGet(),
SQLiteDatastore.new(Memory).tryGet())),
before = before,
after = after)