2022-03-02 16:30:42 +00:00
|
|
|
import std/strutils
|
2022-07-28 00:39:17 +00:00
|
|
|
import std/options
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
import pkg/chronos
|
|
|
|
import pkg/asynctest
|
|
|
|
import pkg/libp2p
|
|
|
|
import pkg/stew/byteutils
|
|
|
|
import pkg/questionable/results
|
2022-05-19 19:56:03 +00:00
|
|
|
import pkg/codex/stores/cachestore
|
|
|
|
import pkg/codex/chunker
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
import ../helpers
|
|
|
|
|
2022-07-22 23:38:49 +00:00
|
|
|
suite "Cache Store":
|
2022-03-02 16:30:42 +00:00
|
|
|
var
|
|
|
|
newBlock, newBlock1, newBlock2, newBlock3: Block
|
|
|
|
store: CacheStore
|
|
|
|
|
|
|
|
setup:
|
2022-03-18 19:50:53 +00:00
|
|
|
newBlock = Block.new("New Kids on the Block".toBytes()).tryGet()
|
|
|
|
newBlock1 = Block.new("1".repeat(100).toBytes()).tryGet()
|
|
|
|
newBlock2 = Block.new("2".repeat(100).toBytes()).tryGet()
|
|
|
|
newBlock3 = Block.new("3".repeat(100).toBytes()).tryGet()
|
2022-03-02 16:30:42 +00:00
|
|
|
store = CacheStore.new()
|
|
|
|
|
|
|
|
test "constructor":
|
|
|
|
# cache size cannot be smaller than chunk size
|
|
|
|
expect ValueError:
|
|
|
|
discard CacheStore.new(cacheSize = 1, chunkSize = 2)
|
|
|
|
|
|
|
|
store = CacheStore.new(cacheSize = 100, chunkSize = 1)
|
|
|
|
check store.currentSize == 0
|
|
|
|
store = CacheStore.new(@[newBlock1, newBlock2, newBlock3])
|
|
|
|
check store.currentSize == 300
|
|
|
|
|
|
|
|
# initial cache blocks total more than cache size, currentSize should
|
|
|
|
# never exceed max cache size
|
|
|
|
store = CacheStore.new(
|
|
|
|
blocks = @[newBlock1, newBlock2, newBlock3],
|
|
|
|
cacheSize = 200,
|
|
|
|
chunkSize = 1)
|
|
|
|
check store.currentSize == 200
|
|
|
|
|
|
|
|
# cache size cannot be less than chunks size
|
|
|
|
expect ValueError:
|
|
|
|
discard CacheStore.new(
|
|
|
|
cacheSize = 99,
|
|
|
|
chunkSize = 100)
|
|
|
|
|
|
|
|
test "putBlock":
|
|
|
|
|
2022-07-28 00:39:17 +00:00
|
|
|
(await store.putBlock(newBlock1)).tryGet()
|
|
|
|
check (await store.hasBlock(newBlock1.cid)).tryGet()
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
# block size bigger than entire cache
|
|
|
|
store = CacheStore.new(cacheSize = 99, chunkSize = 98)
|
2022-07-28 00:39:17 +00:00
|
|
|
(await store.putBlock(newBlock1)).tryGet()
|
|
|
|
check not (await store.hasBlock(newBlock1.cid)).tryGet()
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
# block being added causes removal of LRU block
|
|
|
|
store = CacheStore.new(
|
|
|
|
@[newBlock1, newBlock2, newBlock3],
|
|
|
|
cacheSize = 200,
|
|
|
|
chunkSize = 1)
|
|
|
|
check:
|
2022-07-28 00:39:17 +00:00
|
|
|
not (await store.hasBlock(newBlock1.cid)).tryGet()
|
|
|
|
(await store.hasBlock(newBlock2.cid)).tryGet()
|
|
|
|
(await store.hasBlock(newBlock2.cid)).tryGet()
|
2022-03-02 16:30:42 +00:00
|
|
|
store.currentSize == newBlock2.data.len + newBlock3.data.len # 200
|
|
|
|
|
|
|
|
test "getBlock":
|
|
|
|
store = CacheStore.new(@[newBlock])
|
|
|
|
|
|
|
|
let blk = await store.getBlock(newBlock.cid)
|
2022-07-28 00:39:17 +00:00
|
|
|
check blk.tryGet().get() == newBlock
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
test "fail getBlock":
|
|
|
|
let blk = await store.getBlock(newBlock.cid)
|
2022-07-28 00:39:17 +00:00
|
|
|
check blk.tryGet().isNone()
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
test "hasBlock":
|
|
|
|
let store = CacheStore.new(@[newBlock])
|
2022-07-28 00:39:17 +00:00
|
|
|
check:
|
|
|
|
(await store.hasBlock(newBlock.cid)).tryGet()
|
|
|
|
await newBlock.cid in store
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
test "fail hasBlock":
|
2022-07-28 00:39:17 +00:00
|
|
|
check:
|
|
|
|
not (await store.hasBlock(newBlock.cid)).tryGet()
|
|
|
|
not (await newBlock.cid in store)
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
test "delBlock":
|
|
|
|
# empty cache
|
2022-06-28 16:10:05 +00:00
|
|
|
(await store.delBlock(newBlock1.cid)).tryGet()
|
2022-07-28 00:39:17 +00:00
|
|
|
check not (await store.hasBlock(newBlock1.cid)).tryGet()
|
|
|
|
|
|
|
|
(await store.putBlock(newBlock1)).tryGet()
|
|
|
|
check (await store.hasBlock(newBlock1.cid)).tryGet()
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
# successfully deleted
|
2022-06-28 16:10:05 +00:00
|
|
|
(await store.delBlock(newBlock1.cid)).tryGet()
|
2022-07-28 00:39:17 +00:00
|
|
|
check not (await store.hasBlock(newBlock1.cid)).tryGet()
|
2022-03-02 16:30:42 +00:00
|
|
|
|
|
|
|
# deletes item should decrement size
|
|
|
|
store = CacheStore.new(@[newBlock1, newBlock2, newBlock3])
|
|
|
|
check:
|
|
|
|
store.currentSize == 300
|
2022-07-28 00:39:17 +00:00
|
|
|
|
2022-06-28 16:10:05 +00:00
|
|
|
(await store.delBlock(newBlock2.cid)).tryGet()
|
2022-07-28 00:39:17 +00:00
|
|
|
|
2022-06-28 16:10:05 +00:00
|
|
|
check:
|
2022-03-02 16:30:42 +00:00
|
|
|
store.currentSize == 200
|
2022-07-28 00:39:17 +00:00
|
|
|
not (await store.hasBlock(newBlock2.cid)).tryGet()
|
2022-05-12 20:02:30 +00:00
|
|
|
|
|
|
|
test "listBlocks":
|
2022-07-28 00:39:17 +00:00
|
|
|
(await store.putBlock(newBlock1)).tryGet()
|
2022-05-12 20:02:30 +00:00
|
|
|
|
|
|
|
var listed = false
|
2022-07-28 00:39:17 +00:00
|
|
|
(await store.listBlocks(
|
2022-05-12 20:02:30 +00:00
|
|
|
proc(cid: Cid) {.gcsafe, async.} =
|
2022-07-28 00:39:17 +00:00
|
|
|
check (await store.hasBlock(cid)).tryGet()
|
2022-05-12 20:02:30 +00:00
|
|
|
listed = true
|
2022-07-28 00:39:17 +00:00
|
|
|
)).tryGet()
|
2022-05-12 20:02:30 +00:00
|
|
|
|
|
|
|
check listed
|