Skip to content

Commit 600f97e

Browse files
authored
chore(core/rawdb): ExampleInspectDatabase test (#119)
## Why this should be merged Add an example test for `InspectDatabase` with options. ## How this works See example code
1 parent 7429998 commit 600f97e

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed

core/rawdb/database.libevm_test.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
package rawdb_test
1818

1919
import (
20+
"bytes"
2021
"fmt"
2122

2223
"github.com/ava-labs/libevm/common"
2324
// To ensure that all methods are available to importing packages, this test
2425
// is defined in package `rawdb_test` instead of `rawdb`.
2526
"github.com/ava-labs/libevm/core/rawdb"
27+
"github.com/ava-labs/libevm/ethdb"
2628
)
2729

2830
// ExampleDatabaseStat demonstrates the method signatures of DatabaseStat, which
@@ -42,3 +44,145 @@ func ExampleDatabaseStat() {
4244
// Sum: 7.00 B
4345
// Count: 4
4446
}
47+
48+
func ExampleInspectDatabase() {
49+
db := &stubDatabase{
50+
iterator: &stubIterator{
51+
i: -1,
52+
kvs: []keyValue{
53+
// Bloom bits total = 5 + 1 = 6
54+
{key: []byte("iBxxx"), value: []byte("m")},
55+
// Optional stat record total = 5 + 7 = 12
56+
{key: []byte("mykey"), value: []byte("myvalue")},
57+
// metadata total = 13 + 7 = 20
58+
{key: []byte("mymetadatakey"), value: []byte("myvalue")},
59+
},
60+
},
61+
}
62+
63+
keyPrefix := []byte(nil)
64+
keyStart := []byte(nil)
65+
66+
var (
67+
myStat rawdb.DatabaseStat
68+
)
69+
options := []rawdb.InspectDatabaseOption{
70+
rawdb.WithDatabaseStatRecorder(func(key []byte, size common.StorageSize) bool {
71+
if bytes.Equal(key, []byte("mykey")) {
72+
myStat.Add(size)
73+
return true
74+
}
75+
return false
76+
}),
77+
rawdb.WithDatabaseMetadataKeys(func(key []byte) bool {
78+
return bytes.Equal(key, []byte("mymetadatakey"))
79+
}),
80+
rawdb.WithDatabaseStatsTransformer(func(s [][]string) [][]string {
81+
var modified [][]string
82+
// Remove lines
83+
for _, line := range s {
84+
database, category := line[0], line[1]
85+
switch {
86+
case database == "Ancient store (Chain)":
87+
case database == "Key-Value store" && category == "Difficulties":
88+
default:
89+
modified = append(modified, line)
90+
}
91+
}
92+
// Add lines for data collected with [rawdb.WithDatabaseStatRecorder]
93+
line := []string{"My database", "My category", myStat.Size(), myStat.Count()}
94+
modified = append(modified, line)
95+
return modified
96+
}),
97+
}
98+
99+
err := rawdb.InspectDatabase(db, keyPrefix, keyStart, options...)
100+
if err != nil {
101+
fmt.Println(err)
102+
}
103+
// Output:
104+
// +-----------------+-------------------------+---------+-------+
105+
// | DATABASE | CATEGORY | SIZE | ITEMS |
106+
// +-----------------+-------------------------+---------+-------+
107+
// | Key-Value store | Headers | 0.00 B | 0 |
108+
// | Key-Value store | Bodies | 0.00 B | 0 |
109+
// | Key-Value store | Receipt lists | 0.00 B | 0 |
110+
// | Key-Value store | Block number->hash | 0.00 B | 0 |
111+
// | Key-Value store | Block hash->number | 0.00 B | 0 |
112+
// | Key-Value store | Transaction index | 0.00 B | 0 |
113+
// | Key-Value store | Bloombit index | 6.00 B | 1 |
114+
// | Key-Value store | Contract codes | 0.00 B | 0 |
115+
// | Key-Value store | Hash trie nodes | 0.00 B | 0 |
116+
// | Key-Value store | Path trie state lookups | 0.00 B | 0 |
117+
// | Key-Value store | Path trie account nodes | 0.00 B | 0 |
118+
// | Key-Value store | Path trie storage nodes | 0.00 B | 0 |
119+
// | Key-Value store | Trie preimages | 0.00 B | 0 |
120+
// | Key-Value store | Account snapshot | 0.00 B | 0 |
121+
// | Key-Value store | Storage snapshot | 0.00 B | 0 |
122+
// | Key-Value store | Beacon sync headers | 0.00 B | 0 |
123+
// | Key-Value store | Clique snapshots | 0.00 B | 0 |
124+
// | Key-Value store | Singleton metadata | 20.00 B | 1 |
125+
// | Light client | CHT trie nodes | 0.00 B | 0 |
126+
// | Light client | Bloom trie nodes | 0.00 B | 0 |
127+
// | My database | My category | 12.00 B | 1 |
128+
// +-----------------+-------------------------+---------+-------+
129+
// | TOTAL | 38.00 B | |
130+
// +-----------------+-------------------------+---------+-------+
131+
}
132+
133+
type stubDatabase struct {
134+
ethdb.Database
135+
iterator ethdb.Iterator
136+
}
137+
138+
func (s *stubDatabase) NewIterator(keyPrefix, keyStart []byte) ethdb.Iterator {
139+
return s.iterator
140+
}
141+
142+
// AncientSize is used in [InspectDatabase] to determine the ancient sizes.
143+
func (s *stubDatabase) AncientSize(kind string) (uint64, error) {
144+
return 0, nil
145+
}
146+
147+
func (s *stubDatabase) Ancients() (uint64, error) {
148+
return 0, nil
149+
}
150+
151+
func (s *stubDatabase) Tail() (uint64, error) {
152+
return 0, nil
153+
}
154+
155+
func (s *stubDatabase) Get(key []byte) ([]byte, error) {
156+
return nil, nil
157+
}
158+
159+
func (s *stubDatabase) ReadAncients(fn func(ethdb.AncientReaderOp) error) (err error) {
160+
return nil
161+
}
162+
163+
type stubIterator struct {
164+
ethdb.Iterator
165+
i int
166+
kvs []keyValue
167+
}
168+
169+
type keyValue struct {
170+
key []byte
171+
value []byte
172+
}
173+
174+
func (s *stubIterator) Next() bool {
175+
s.i++
176+
available := s.i < len(s.kvs)
177+
return available
178+
}
179+
180+
func (s *stubIterator) Release() {}
181+
182+
func (s *stubIterator) Key() []byte {
183+
return s.kvs[s.i].key
184+
}
185+
186+
func (s *stubIterator) Value() []byte {
187+
return s.kvs[s.i].value
188+
}

0 commit comments

Comments
 (0)