mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
202 lines
4.2 KiB
Go
202 lines
4.2 KiB
Go
package blockstore
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"gx/ipfs/QmYsEQydGrsxNZfAiskvQ76N2xE9hDQtSAkRSynwMiUK3c/go-block-format"
|
|
|
|
ds "gx/ipfs/QmdHG8MAuARdGHxx4rPQASLcvhz24fzjSQq7AJRAQEorq5/go-datastore"
|
|
syncds "gx/ipfs/QmdHG8MAuARdGHxx4rPQASLcvhz24fzjSQq7AJRAQEorq5/go-datastore/sync"
|
|
cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid"
|
|
)
|
|
|
|
var exampleBlock = blocks.NewBlock([]byte("foo"))
|
|
|
|
func testArcCached(ctx context.Context, bs Blockstore) (*arccache, error) {
|
|
if ctx == nil {
|
|
ctx = context.TODO()
|
|
}
|
|
opts := DefaultCacheOpts()
|
|
opts.HasBloomFilterSize = 0
|
|
opts.HasBloomFilterHashes = 0
|
|
bbs, err := CachedBlockstore(ctx, bs, opts)
|
|
if err == nil {
|
|
return bbs.(*arccache), nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
func createStores(t *testing.T) (*arccache, Blockstore, *callbackDatastore) {
|
|
cd := &callbackDatastore{f: func() {}, ds: ds.NewMapDatastore()}
|
|
bs := NewBlockstore(syncds.MutexWrap(cd))
|
|
arc, err := testArcCached(context.TODO(), bs)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return arc, bs, cd
|
|
}
|
|
|
|
func trap(message string, cd *callbackDatastore, t *testing.T) {
|
|
cd.SetFunc(func() {
|
|
t.Fatal(message)
|
|
})
|
|
}
|
|
func untrap(cd *callbackDatastore) {
|
|
cd.SetFunc(func() {})
|
|
}
|
|
|
|
func TestRemoveCacheEntryOnDelete(t *testing.T) {
|
|
arc, _, cd := createStores(t)
|
|
|
|
arc.Put(exampleBlock)
|
|
|
|
cd.Lock()
|
|
writeHitTheDatastore := false
|
|
cd.Unlock()
|
|
|
|
cd.SetFunc(func() {
|
|
writeHitTheDatastore = true
|
|
})
|
|
|
|
arc.DeleteBlock(exampleBlock.Cid())
|
|
arc.Put(exampleBlock)
|
|
if !writeHitTheDatastore {
|
|
t.Fail()
|
|
}
|
|
}
|
|
|
|
func TestElideDuplicateWrite(t *testing.T) {
|
|
arc, _, cd := createStores(t)
|
|
|
|
arc.Put(exampleBlock)
|
|
trap("write hit datastore", cd, t)
|
|
arc.Put(exampleBlock)
|
|
}
|
|
|
|
func TestHasRequestTriggersCache(t *testing.T) {
|
|
arc, _, cd := createStores(t)
|
|
|
|
arc.Has(exampleBlock.Cid())
|
|
trap("has hit datastore", cd, t)
|
|
if has, err := arc.Has(exampleBlock.Cid()); has || err != nil {
|
|
t.Fatal("has was true but there is no such block")
|
|
}
|
|
|
|
untrap(cd)
|
|
err := arc.Put(exampleBlock)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
trap("has hit datastore", cd, t)
|
|
|
|
if has, err := arc.Has(exampleBlock.Cid()); !has || err != nil {
|
|
t.Fatal("has returned invalid result")
|
|
}
|
|
}
|
|
|
|
func TestGetFillsCache(t *testing.T) {
|
|
arc, _, cd := createStores(t)
|
|
|
|
if bl, err := arc.Get(exampleBlock.Cid()); bl != nil || err == nil {
|
|
t.Fatal("block was found or there was no error")
|
|
}
|
|
|
|
trap("has hit datastore", cd, t)
|
|
|
|
if has, err := arc.Has(exampleBlock.Cid()); has || err != nil {
|
|
t.Fatal("has was true but there is no such block")
|
|
}
|
|
|
|
untrap(cd)
|
|
|
|
if err := arc.Put(exampleBlock); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
trap("has hit datastore", cd, t)
|
|
|
|
if has, err := arc.Has(exampleBlock.Cid()); !has || err != nil {
|
|
t.Fatal("has returned invalid result")
|
|
}
|
|
}
|
|
|
|
func TestGetAndDeleteFalseShortCircuit(t *testing.T) {
|
|
arc, _, cd := createStores(t)
|
|
|
|
arc.Has(exampleBlock.Cid())
|
|
|
|
trap("get hit datastore", cd, t)
|
|
|
|
if bl, err := arc.Get(exampleBlock.Cid()); bl != nil || err != ErrNotFound {
|
|
t.Fatal("get returned invalid result")
|
|
}
|
|
|
|
if arc.DeleteBlock(exampleBlock.Cid()) != ErrNotFound {
|
|
t.Fatal("expected ErrNotFound error")
|
|
}
|
|
}
|
|
|
|
func TestArcCreationFailure(t *testing.T) {
|
|
if arc, err := newARCCachedBS(context.TODO(), nil, -1); arc != nil || err == nil {
|
|
t.Fatal("expected error and no cache")
|
|
}
|
|
}
|
|
|
|
func TestInvalidKey(t *testing.T) {
|
|
arc, _, _ := createStores(t)
|
|
|
|
bl, err := arc.Get(nil)
|
|
|
|
if bl != nil {
|
|
t.Fatal("blocks should be nil")
|
|
}
|
|
if err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
}
|
|
|
|
func TestHasAfterSucessfulGetIsCached(t *testing.T) {
|
|
arc, bs, cd := createStores(t)
|
|
|
|
bs.Put(exampleBlock)
|
|
|
|
arc.Get(exampleBlock.Cid())
|
|
|
|
trap("has hit datastore", cd, t)
|
|
arc.Has(exampleBlock.Cid())
|
|
}
|
|
|
|
func TestDifferentKeyObjectsWork(t *testing.T) {
|
|
arc, bs, cd := createStores(t)
|
|
|
|
bs.Put(exampleBlock)
|
|
|
|
arc.Get(exampleBlock.Cid())
|
|
|
|
trap("has hit datastore", cd, t)
|
|
cidstr := exampleBlock.Cid().String()
|
|
|
|
ncid, err := cid.Decode(cidstr)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
arc.Has(ncid)
|
|
}
|
|
|
|
func TestPutManyCaches(t *testing.T) {
|
|
arc, _, cd := createStores(t)
|
|
arc.PutMany([]blocks.Block{exampleBlock})
|
|
|
|
trap("has hit datastore", cd, t)
|
|
arc.Has(exampleBlock.Cid())
|
|
untrap(cd)
|
|
arc.DeleteBlock(exampleBlock.Cid())
|
|
|
|
arc.Put(exampleBlock)
|
|
trap("PunMany has hit datastore", cd, t)
|
|
arc.PutMany([]blocks.Block{exampleBlock})
|
|
}
|