Skip to content

Commit 6207229

Browse files
test: add comprehensive tests for block cache benchmarks
1 parent adc1f33 commit 6207229

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
package stagedstreamsync
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"testing"
7+
"time"
8+
9+
syncproto "github.com/harmony-one/harmony/p2p/stream/protocols/sync"
10+
sttypes "github.com/harmony-one/harmony/p2p/stream/types"
11+
)
12+
13+
// BenchmarkProtocolProvider implements ProtocolProvider for benchmarking
14+
type BenchmarkProtocolProvider struct {
15+
cache map[sttypes.StreamID]uint64
16+
}
17+
18+
func NewBenchmarkProtocolProvider() *BenchmarkProtocolProvider {
19+
cache := make(map[sttypes.StreamID]uint64)
20+
// Pre-populate with some data
21+
for i := 0; i < 1000; i++ {
22+
streamID := sttypes.StreamID(fmt.Sprintf("stream-%d", i))
23+
cache[streamID] = uint64(10000 + i)
24+
}
25+
return &BenchmarkProtocolProvider{cache: cache}
26+
}
27+
28+
func (b *BenchmarkProtocolProvider) GetCurrentBlockNumber(ctx context.Context, opts ...syncproto.Option) (uint64, sttypes.StreamID, error) {
29+
// Simulate network latency
30+
time.Sleep(1 * time.Millisecond)
31+
32+
// Return a random stream ID and block number for benchmarking
33+
for streamID, blockNumber := range b.cache {
34+
return blockNumber, streamID, nil
35+
}
36+
return 0, "", fmt.Errorf("no streams available")
37+
}
38+
39+
func BenchmarkGetBlockNumber_CacheHit(b *testing.B) {
40+
provider := NewBenchmarkProtocolProvider()
41+
cache := NewBlockNumberCache(provider, nil)
42+
defer cache.Stop()
43+
44+
// Pre-populate cache
45+
streamID := sttypes.StreamID("benchmark-stream")
46+
targetBlock := uint64(5000)
47+
48+
cache.mu.Lock()
49+
cache.cache[streamID] = &BlockInfo{
50+
BlockNumber: 10000,
51+
Timestamp: time.Now(),
52+
LastUsed: time.Now(),
53+
AccessCount: 1,
54+
IsValid: true,
55+
}
56+
cache.mu.Unlock()
57+
58+
b.ResetTimer()
59+
b.RunParallel(func(pb *testing.PB) {
60+
for pb.Next() {
61+
_, err := cache.GetBlockNumber(context.Background(), streamID, targetBlock)
62+
if err != nil {
63+
b.Fatal(err)
64+
}
65+
}
66+
})
67+
}
68+
69+
func BenchmarkGetBlockNumber_CacheMiss(b *testing.B) {
70+
provider := NewBenchmarkProtocolProvider()
71+
cache := NewBlockNumberCache(provider, nil)
72+
defer cache.Stop()
73+
74+
streamID := sttypes.StreamID("benchmark-stream")
75+
targetBlock := uint64(5000)
76+
77+
b.ResetTimer()
78+
b.RunParallel(func(pb *testing.PB) {
79+
for pb.Next() {
80+
_, err := cache.GetBlockNumber(context.Background(), streamID, targetBlock)
81+
if err != nil {
82+
b.Fatal(err)
83+
}
84+
}
85+
})
86+
}
87+
88+
func BenchmarkGetBlockNumber_Mixed(b *testing.B) {
89+
provider := NewBenchmarkProtocolProvider()
90+
cache := NewBlockNumberCache(provider, nil)
91+
defer cache.Stop()
92+
93+
// Pre-populate cache with some entries
94+
for i := 0; i < 100; i++ {
95+
streamID := sttypes.StreamID(fmt.Sprintf("stream-%d", i))
96+
cache.mu.Lock()
97+
cache.cache[streamID] = &BlockInfo{
98+
BlockNumber: uint64(10000 + i),
99+
Timestamp: time.Now(),
100+
LastUsed: time.Now(),
101+
AccessCount: 1,
102+
IsValid: true,
103+
}
104+
cache.mu.Unlock()
105+
}
106+
107+
b.ResetTimer()
108+
b.RunParallel(func(pb *testing.PB) {
109+
i := 0
110+
for pb.Next() {
111+
streamID := sttypes.StreamID(fmt.Sprintf("stream-%d", i%150)) // Some hits, some misses
112+
targetBlock := uint64(5000 + i%1000)
113+
114+
_, err := cache.GetBlockNumber(context.Background(), streamID, targetBlock)
115+
if err != nil {
116+
b.Fatal(err)
117+
}
118+
i++
119+
}
120+
})
121+
}
122+
123+
func BenchmarkEvictOldestEntries(b *testing.B) {
124+
provider := NewBenchmarkProtocolProvider()
125+
config := &CacheConfig{
126+
MaxSize: 100,
127+
MaxAge: 1 * time.Hour,
128+
MinBlockThreshold: 100,
129+
CleanupInterval: 1 * time.Minute,
130+
}
131+
cache := NewBlockNumberCache(provider, config)
132+
defer cache.Stop()
133+
134+
// Pre-populate cache to trigger eviction
135+
for i := 0; i < 150; i++ {
136+
streamID := sttypes.StreamID(fmt.Sprintf("stream-%d", i))
137+
cache.mu.Lock()
138+
cache.cache[streamID] = &BlockInfo{
139+
BlockNumber: uint64(10000 + i),
140+
Timestamp: time.Now().Add(-time.Duration(i) * time.Minute),
141+
LastUsed: time.Now(),
142+
AccessCount: 1,
143+
IsValid: true,
144+
}
145+
cache.mu.Unlock()
146+
}
147+
148+
b.ResetTimer()
149+
for i := 0; i < b.N; i++ {
150+
cache.evictOldestEntries()
151+
}
152+
}
153+
154+
func BenchmarkCleanupExpiredEntries(b *testing.B) {
155+
provider := NewBenchmarkProtocolProvider()
156+
config := &CacheConfig{
157+
MaxSize: 1000,
158+
MaxAge: 1 * time.Hour,
159+
MinBlockThreshold: 100,
160+
CleanupInterval: 1 * time.Minute,
161+
}
162+
cache := NewBlockNumberCache(provider, config)
163+
defer cache.Stop()
164+
165+
// Pre-populate cache with mixed ages
166+
now := time.Now()
167+
for i := 0; i < 1000; i++ {
168+
streamID := sttypes.StreamID(fmt.Sprintf("stream-%d", i))
169+
age := time.Duration(i%3) * 2 * time.Hour // 0, 2, or 4 hours
170+
cache.mu.Lock()
171+
cache.cache[streamID] = &BlockInfo{
172+
BlockNumber: uint64(10000 + i),
173+
Timestamp: now.Add(-age),
174+
LastUsed: now,
175+
AccessCount: 1,
176+
IsValid: true,
177+
}
178+
cache.mu.Unlock()
179+
}
180+
181+
b.ResetTimer()
182+
for i := 0; i < b.N; i++ {
183+
cache.cleanupExpiredEntries()
184+
}
185+
}

0 commit comments

Comments
 (0)