Skip to content

Commit 44ef280

Browse files
committed
test: 81% coverage on blockstore
Coverage report available at: https://ipfs.io/ipfs/QmTuMtwGCfHrbYyZdQ1RaGNwS2MGsmAkjA8AaB69N7Ya1g/coverage.html#file0 Part of #3053 License: MIT Signed-off-by: Jakub Sztandera <[email protected]>
1 parent 16f8570 commit 44ef280

File tree

4 files changed

+191
-16
lines changed

4 files changed

+191
-16
lines changed

blocks/blockstore/arc_cache_test.go

Lines changed: 125 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ package blockstore
22

33
import (
44
"github.com/ipfs/go-ipfs/blocks"
5+
"github.com/ipfs/go-ipfs/blocks/key"
56
"testing"
67

78
ds "gx/ipfs/QmTxLSvdhwg68WJimdS6icLPhZi28aTp6b7uihC2Yb47Xk/go-datastore"
89
syncds "gx/ipfs/QmTxLSvdhwg68WJimdS6icLPhZi28aTp6b7uihC2Yb47Xk/go-datastore/sync"
910
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
1011
)
1112

13+
var exampleBlock = blocks.NewBlock([]byte("foo"))
14+
1215
func testArcCached(bs GCBlockstore, ctx context.Context) (*arccache, error) {
1316
if ctx == nil {
1417
ctx = context.TODO()
@@ -24,15 +27,29 @@ func testArcCached(bs GCBlockstore, ctx context.Context) (*arccache, error) {
2427
}
2528
}
2629

27-
func TestRemoveCacheEntryOnDelete(t *testing.T) {
28-
b := blocks.NewBlock([]byte("foo"))
30+
func createStores(t *testing.T) (*arccache, *blockstore, *callbackDatastore) {
2931
cd := &callbackDatastore{f: func() {}, ds: ds.NewMapDatastore()}
3032
bs := NewBlockstore(syncds.MutexWrap(cd))
31-
cachedbs, err := testArcCached(bs, nil)
33+
arc, err := testArcCached(bs, nil)
3234
if err != nil {
3335
t.Fatal(err)
3436
}
35-
cachedbs.Put(b)
37+
return arc, bs, cd
38+
}
39+
40+
func trap(message string, cd *callbackDatastore, t *testing.T) {
41+
cd.SetFunc(func() {
42+
t.Fatal(message)
43+
})
44+
}
45+
func untrap(cd *callbackDatastore) {
46+
cd.SetFunc(func() {})
47+
}
48+
49+
func TestRemoveCacheEntryOnDelete(t *testing.T) {
50+
arc, _, cd := createStores(t)
51+
52+
arc.Put(exampleBlock)
3653

3754
cd.Lock()
3855
writeHitTheDatastore := false
@@ -42,26 +59,119 @@ func TestRemoveCacheEntryOnDelete(t *testing.T) {
4259
writeHitTheDatastore = true
4360
})
4461

45-
cachedbs.DeleteBlock(b.Key())
46-
cachedbs.Put(b)
62+
arc.DeleteBlock(exampleBlock.Key())
63+
arc.Put(exampleBlock)
4764
if !writeHitTheDatastore {
4865
t.Fail()
4966
}
5067
}
5168

5269
func TestElideDuplicateWrite(t *testing.T) {
53-
cd := &callbackDatastore{f: func() {}, ds: ds.NewMapDatastore()}
54-
bs := NewBlockstore(syncds.MutexWrap(cd))
55-
cachedbs, err := testArcCached(bs, nil)
70+
arc, _, cd := createStores(t)
71+
72+
arc.Put(exampleBlock)
73+
trap("write hit datastore", cd, t)
74+
arc.Put(exampleBlock)
75+
}
76+
77+
func TestHasRequestTriggersCache(t *testing.T) {
78+
arc, _, cd := createStores(t)
79+
80+
arc.Has(exampleBlock.Key())
81+
trap("has hit datastore", cd, t)
82+
if has, err := arc.Has(exampleBlock.Key()); has || err != nil {
83+
t.Fatal("has was true but there is no such block")
84+
}
85+
86+
untrap(cd)
87+
err := arc.Put(exampleBlock)
5688
if err != nil {
5789
t.Fatal(err)
5890
}
5991

60-
b1 := blocks.NewBlock([]byte("foo"))
92+
trap("has hit datastore", cd, t)
6193

62-
cachedbs.Put(b1)
63-
cd.SetFunc(func() {
64-
t.Fatal("write hit the datastore")
65-
})
66-
cachedbs.Put(b1)
94+
if has, err := arc.Has(exampleBlock.Key()); !has || err != nil {
95+
t.Fatal("has returned invalid result")
96+
}
97+
}
98+
99+
func TestGetFillsCache(t *testing.T) {
100+
arc, _, cd := createStores(t)
101+
102+
if bl, err := arc.Get(exampleBlock.Key()); bl != nil || err == nil {
103+
t.Fatal("block was found or there was no error")
104+
}
105+
106+
trap("has hit datastore", cd, t)
107+
108+
if has, err := arc.Has(exampleBlock.Key()); has || err != nil {
109+
t.Fatal("has was true but there is no such block")
110+
}
111+
112+
untrap(cd)
113+
114+
if err := arc.Put(exampleBlock); err != nil {
115+
t.Fatal(err)
116+
}
117+
118+
trap("has hit datastore", cd, t)
119+
120+
if has, err := arc.Has(exampleBlock.Key()); !has || err != nil {
121+
t.Fatal("has returned invalid result")
122+
}
123+
}
124+
125+
func TestGetAndDeleteFalseShortCirciot(t *testing.T) {
126+
arc, _, cd := createStores(t)
127+
128+
arc.Has(exampleBlock.Key())
129+
130+
trap("get hit datastore", cd, t)
131+
132+
if bl, err := arc.Get(exampleBlock.Key()); bl != nil || err != ErrNotFound {
133+
t.Fatal("get returned invalid result")
134+
}
135+
136+
if arc.DeleteBlock(exampleBlock.Key()) != ErrNotFound {
137+
t.Fatal("expected ErrNotFound error")
138+
}
139+
}
140+
141+
func TestArcCreationFailure(t *testing.T) {
142+
if arc, err := arcCached(nil, -1); arc != nil || err == nil {
143+
t.Fatal("expected error and no cache")
144+
}
145+
}
146+
147+
func TestInvalidKey(t *testing.T) {
148+
arc, _, _ := createStores(t)
149+
150+
bl, err := arc.Get(key.Key(""))
151+
152+
if bl != nil {
153+
t.Fatal("blocks should be nil")
154+
}
155+
if err == nil {
156+
t.Fatal("expected error")
157+
}
158+
}
159+
160+
func TestHasAfterSucessfulGetIsCached(t *testing.T) {
161+
arc, bs, cd := createStores(t)
162+
163+
bs.Put(exampleBlock)
164+
165+
arc.Get(exampleBlock.Key())
166+
167+
trap("has hit datastore", cd, t)
168+
arc.Has(exampleBlock.Key())
169+
}
170+
171+
func TestPutManyCaches(t *testing.T) {
172+
arc, _, cd := createStores(t)
173+
arc.PutMany([]blocks.Block{exampleBlock})
174+
175+
trap("has hit datastore", cd, t)
176+
arc.Has(exampleBlock.Key())
67177
}

blocks/blockstore/blockstore_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,21 @@ func TestRuntimeHashing(t *testing.T) {
5757
bs := NewBlockstore(ds_sync.MutexWrap(ds.NewMapDatastore()))
5858
bl := blocks.NewBlock([]byte("some data"))
5959
blBad, err := blocks.NewBlockWithHash([]byte("some other data"), bl.Key().ToMultihash())
60+
bl2 := blocks.NewBlock([]byte("some other data"))
6061
if err != nil {
6162
t.Fatal("Debug is enabled")
6263
}
63-
6464
bs.Put(blBad)
65+
bs.Put(bl2)
6566
bs.RuntimeHashing(true)
6667

6768
if _, err := bs.Get(bl.Key()); err != ErrHashMismatch {
6869
t.Fatalf("Expected '%v' got '%v'\n", ErrHashMismatch, err)
6970
}
71+
72+
if b, err := bs.Get(bl2.Key()); err != nil || b.String() != bl2.String() {
73+
t.Fatal("got wrong blocks")
74+
}
7075
}
7176

7277
func newBlockStoreWithKeys(t *testing.T, d ds.Datastore, N int) (Blockstore, []key.Key) {

blocks/blockstore/bloom_cache_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,31 @@ func TestHasIsBloomCached(t *testing.T) {
6666
if float64(cacheFails)/float64(1000) > float64(0.05) {
6767
t.Fatal("Bloom filter has cache miss rate of more than 5%")
6868
}
69+
70+
cacheFails = 0
71+
block := blocks.NewBlock([]byte("newBlock"))
72+
73+
cachedbs.PutMany([]blocks.Block{block})
74+
if cacheFails != 2 {
75+
t.Fatalf("expected two datastore hits: %d", cacheFails)
76+
}
77+
cachedbs.Put(block)
78+
if cacheFails != 3 {
79+
t.Fatalf("expected datastore hit: %d", cacheFails)
80+
}
81+
82+
if has, err := cachedbs.Has(block.Key()); !has || err != nil {
83+
t.Fatal("has gave wrong response")
84+
}
85+
86+
bl, err := cachedbs.Get(block.Key())
87+
if bl.String() != block.String() {
88+
t.Fatal("block data doesn't match")
89+
}
90+
91+
if err != nil {
92+
t.Fatal("there should't be an error")
93+
}
6994
}
7095

7196
type callbackDatastore struct {

blocks/blockstore/caching_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package blockstore
2+
3+
import "testing"
4+
5+
func TestCachingOptsLessThanZero(t *testing.T) {
6+
opts := DefaultCacheOpts()
7+
opts.HasARCCacheSize = -1
8+
9+
if _, err := CachedBlockstore(nil, nil, opts); err == nil {
10+
t.Fatal()
11+
}
12+
13+
opts = DefaultCacheOpts()
14+
opts.HasBloomFilterSize = -1
15+
16+
if _, err := CachedBlockstore(nil, nil, opts); err == nil {
17+
t.Fatal()
18+
}
19+
20+
opts = DefaultCacheOpts()
21+
opts.HasBloomFilterHashes = -1
22+
23+
if _, err := CachedBlockstore(nil, nil, opts); err == nil {
24+
t.Fatal()
25+
}
26+
}
27+
28+
func TestBloomHashesAtZero(t *testing.T) {
29+
opts := DefaultCacheOpts()
30+
opts.HasBloomFilterHashes = 0
31+
32+
if _, err := CachedBlockstore(nil, nil, opts); err == nil {
33+
t.Fatal()
34+
}
35+
}

0 commit comments

Comments
 (0)