Skip to content

Commit e4220c7

Browse files
authored
refactor: rawdb tests (#221)
## Why this should be merged The need for examples to be in `package rawdb_test` made it difficult to test other code that relied on non-exported `rawdb` identifiers. ## How this works 1. Move all testable examples from `database.libevm_test.go` to `examples.libevm_test.go` _without any change_. 2. Change `database.libevm_test.go` to be in `package rawdb` and extend the `WithSkipFreezers()` test. ## How this was tested No change at all to testable examples. The `WithSkipFreezers()` test now touches both the happy and (specific) error paths to demonstrate exact behaviour (under the old approach it could have just been that there was no error, even without the option).
1 parent f19cd58 commit e4220c7

File tree

2 files changed

+219
-185
lines changed

2 files changed

+219
-185
lines changed

core/rawdb/database.libevm_test.go

Lines changed: 21 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -14,200 +14,36 @@
1414
// along with the go-ethereum library. If not, see
1515
// <http://www.gnu.org/licenses/>.
1616

17-
package rawdb_test
17+
package rawdb
1818

1919
import (
20-
"bytes"
21-
"fmt"
22-
"sort"
2320
"testing"
2421

25-
"github.com/stretchr/testify/require"
26-
27-
"github.com/ava-labs/libevm/common"
28-
// To ensure that all methods are available to importing packages, this test
29-
// is defined in package `rawdb_test` instead of `rawdb`.
30-
"github.com/ava-labs/libevm/core/rawdb"
31-
"github.com/ava-labs/libevm/ethdb"
22+
"github.com/stretchr/testify/assert"
3223
)
3324

3425
func TestSkipFreezers(t *testing.T) {
35-
require := require.New(t)
36-
db := rawdb.NewMemoryDatabase()
37-
38-
var (
39-
keyPrefix []byte
40-
keyStart []byte
41-
)
42-
43-
require.NoError(rawdb.InspectDatabase(db, keyPrefix, keyStart, rawdb.WithSkipFreezers()))
44-
}
45-
46-
// ExampleDatabaseStat demonstrates the method signatures of DatabaseStat, which
47-
// exposes an otherwise unexported type that won't have its methods documented.
48-
func ExampleDatabaseStat() {
49-
var stat rawdb.DatabaseStat
50-
51-
stat.Add(common.StorageSize(1)) // only to demonstrate param type
52-
stat.Add(2)
53-
54-
fmt.Println("Sum:", stat.Size()) // sum of all values passed to Add()
55-
fmt.Println("Count:", stat.Count()) // number of calls to Add()
56-
57-
// Output:
58-
// Sum: 3.00 B
59-
// Count: 2
60-
}
61-
62-
func ExampleInspectDatabase() {
63-
db := &stubDatabase{
64-
iterator: &stubIterator{
65-
kvs: []keyValue{
66-
// Bloom bits total = 5 + 1 = 6
67-
{key: []byte("iBxxx"), value: []byte("m")},
68-
// Optional stat record total = 5 + 7 = 12
69-
{key: []byte("mykey"), value: []byte("myvalue")},
70-
// metadata total = (13 + 7) + (14 + 7) = 41
71-
{key: []byte("mymetadatakey"), value: []byte("myvalue")},
72-
{key: []byte("mymetadatakey2"), value: []byte("myvalue")},
73-
},
26+
db := NewMemoryDatabase()
27+
28+
tests := []struct {
29+
skipFreezers bool
30+
wantErr error
31+
}{
32+
{
33+
skipFreezers: false,
34+
wantErr: errNotSupported,
35+
},
36+
{
37+
skipFreezers: true,
38+
wantErr: nil,
7439
},
7540
}
7641

77-
keyPrefix := []byte(nil)
78-
keyStart := []byte(nil)
79-
80-
var (
81-
myStat rawdb.DatabaseStat
82-
)
83-
options := []rawdb.InspectDatabaseOption{
84-
rawdb.WithDatabaseStatRecorder(func(key []byte, size common.StorageSize) bool {
85-
if bytes.Equal(key, []byte("mykey")) {
86-
myStat.Add(size)
87-
return true
88-
}
89-
return false
90-
}),
91-
rawdb.WithDatabaseMetadataKeys(func(key []byte) bool {
92-
return bytes.Equal(key, []byte("mymetadatakey"))
93-
}),
94-
rawdb.WithDatabaseMetadataKeys(func(key []byte) bool {
95-
return bytes.Equal(key, []byte("mymetadatakey2"))
96-
}),
97-
rawdb.WithDatabaseStatsTransformer(func(rows [][]string) [][]string {
98-
sort.Slice(rows, func(i, j int) bool {
99-
ri, rj := rows[i], rows[j]
100-
if ri[0] != rj[0] {
101-
return ri[0] < rj[0]
102-
}
103-
return ri[1] < rj[1]
104-
})
105-
106-
return append(
107-
rows,
108-
[]string{"My database", "My category", myStat.Size(), myStat.Count()},
109-
)
110-
}),
111-
}
112-
113-
err := rawdb.InspectDatabase(db, keyPrefix, keyStart, options...)
114-
if err != nil {
115-
fmt.Println(err)
42+
for _, tt := range tests {
43+
var opts []InspectDatabaseOption
44+
if tt.skipFreezers {
45+
opts = append(opts, WithSkipFreezers())
46+
}
47+
assert.ErrorIsf(t, InspectDatabase(db, nil, nil, opts...), tt.wantErr, "InspectDatabase(%T, nil, nil, [WithSkipFreezers = %t])", db, tt.skipFreezers)
11648
}
117-
// Output:
118-
// +-----------------------+-------------------------+---------+-------+
119-
// | DATABASE | CATEGORY | SIZE | ITEMS |
120-
// +-----------------------+-------------------------+---------+-------+
121-
// | Ancient store (Chain) | Bodies | 0.00 B | 0 |
122-
// | Ancient store (Chain) | Diffs | 0.00 B | 0 |
123-
// | Ancient store (Chain) | Hashes | 0.00 B | 0 |
124-
// | Ancient store (Chain) | Headers | 0.00 B | 0 |
125-
// | Ancient store (Chain) | Receipts | 0.00 B | 0 |
126-
// | Key-Value store | Account snapshot | 0.00 B | 0 |
127-
// | Key-Value store | Beacon sync headers | 0.00 B | 0 |
128-
// | Key-Value store | Block hash->number | 0.00 B | 0 |
129-
// | Key-Value store | Block number->hash | 0.00 B | 0 |
130-
// | Key-Value store | Bloombit index | 6.00 B | 1 |
131-
// | Key-Value store | Bodies | 0.00 B | 0 |
132-
// | Key-Value store | Clique snapshots | 0.00 B | 0 |
133-
// | Key-Value store | Contract codes | 0.00 B | 0 |
134-
// | Key-Value store | Difficulties | 0.00 B | 0 |
135-
// | Key-Value store | Hash trie nodes | 0.00 B | 0 |
136-
// | Key-Value store | Headers | 0.00 B | 0 |
137-
// | Key-Value store | Path trie account nodes | 0.00 B | 0 |
138-
// | Key-Value store | Path trie state lookups | 0.00 B | 0 |
139-
// | Key-Value store | Path trie storage nodes | 0.00 B | 0 |
140-
// | Key-Value store | Receipt lists | 0.00 B | 0 |
141-
// | Key-Value store | Singleton metadata | 41.00 B | 2 |
142-
// | Key-Value store | Storage snapshot | 0.00 B | 0 |
143-
// | Key-Value store | Transaction index | 0.00 B | 0 |
144-
// | Key-Value store | Trie preimages | 0.00 B | 0 |
145-
// | Light client | Bloom trie nodes | 0.00 B | 0 |
146-
// | Light client | CHT trie nodes | 0.00 B | 0 |
147-
// | My database | My category | 12.00 B | 1 |
148-
// +-----------------------+-------------------------+---------+-------+
149-
// | TOTAL | 59.00 B | |
150-
// +-----------------------+-------------------------+---------+-------+
151-
}
152-
153-
type stubDatabase struct {
154-
ethdb.Database
155-
iterator ethdb.Iterator
156-
}
157-
158-
func (s *stubDatabase) NewIterator(keyPrefix, keyStart []byte) ethdb.Iterator {
159-
return s.iterator
160-
}
161-
162-
// AncientSize is used in [InspectDatabase] to determine the ancient sizes.
163-
func (s *stubDatabase) AncientSize(kind string) (uint64, error) {
164-
return 0, nil
165-
}
166-
167-
func (s *stubDatabase) Ancients() (uint64, error) {
168-
return 0, nil
169-
}
170-
171-
func (s *stubDatabase) Tail() (uint64, error) {
172-
return 0, nil
173-
}
174-
175-
func (s *stubDatabase) Get(key []byte) ([]byte, error) {
176-
return nil, nil
177-
}
178-
179-
func (s *stubDatabase) ReadAncients(fn func(ethdb.AncientReaderOp) error) error {
180-
return nil
181-
}
182-
183-
type stubIterator struct {
184-
ethdb.Iterator
185-
i int // see [stubIterator.pos]
186-
kvs []keyValue
187-
}
188-
189-
type keyValue struct {
190-
key []byte
191-
value []byte
192-
}
193-
194-
// pos returns the true iterator position, which is otherwise off by one because
195-
// Next() is called _before_ usage.
196-
func (s *stubIterator) pos() int {
197-
return s.i - 1
198-
}
199-
200-
func (s *stubIterator) Next() bool {
201-
s.i++
202-
return s.pos() < len(s.kvs)
203-
}
204-
205-
func (s *stubIterator) Release() {}
206-
207-
func (s *stubIterator) Key() []byte {
208-
return s.kvs[s.pos()].key
209-
}
210-
211-
func (s *stubIterator) Value() []byte {
212-
return s.kvs[s.pos()].value
21349
}

0 commit comments

Comments
 (0)