187 lines
4.8 KiB
Nim
187 lines
4.8 KiB
Nim
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
|
|
|
|
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)
|