Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fuzz test for NewIteratorWithStartAndPrefix #1992

Merged
merged 42 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2a19372
fix fuzz tests
Sep 8, 2023
97b41de
remove unneeded if statements
Sep 8, 2023
f6a52da
add fuzz test for NewIteratorWithStartAndPrefix
Sep 8, 2023
86328ec
Merge branch 'dev' into fuzz-iterator
Sep 11, 2023
bd88a14
Merge branch 'fuzz-iterator' into fuzz-iterator-2
Sep 11, 2023
c521f5f
Merge branch 'dev' into fuzz-iterator
Sep 12, 2023
e824d07
Merge branch 'fuzz-iterator' into fuzz-iterator-2
Sep 12, 2023
b86b4e6
remove unneeded close calls
Sep 12, 2023
5800937
Merge branch 'fuzz-iterator' of github.com:ava-labs/avalanchego into …
Sep 12, 2023
2fc7f3b
Merge branch 'fuzz-iterator' into fuzz-iterator-2
Sep 12, 2023
565b8ba
Merge branch 'fuzz-iterator-2' of github.com:ava-labs/avalanchego int…
Sep 12, 2023
8e3154a
remove unneeded close calls
Sep 12, 2023
c4462c2
tweak test
Sep 12, 2023
5a7746e
Merge branch 'fuzz-iterator' into fuzz-iterator-2
Sep 12, 2023
2e93b5d
tweak test
Sep 12, 2023
4268edd
fix test
Sep 12, 2023
a122098
Merge branch 'fuzz-iterator' into fuzz-iterator-2
Sep 12, 2023
3bbd476
fix test
Sep 12, 2023
45cfa80
Merge branch 'dev' into fuzz-iterator
Sep 15, 2023
d2d42fb
update test
Sep 15, 2023
ec733e9
Merge branch 'fuzz-iterator' into fuzz-iterator-2
Sep 15, 2023
8fdacd6
update test
Sep 15, 2023
a8c95ca
update tests
Sep 15, 2023
264980a
nits
Sep 15, 2023
0cb321f
use atomic clear helper
Sep 15, 2023
5ee8cd9
Merge branch 'fuzz-iterator' into fuzz-iterator-2
Sep 15, 2023
4ec1d53
appease linter
Sep 15, 2023
2c57062
Merge branch 'fuzz-iterator' into fuzz-iterator-2
Sep 15, 2023
4c803f8
appease linter
Sep 15, 2023
a0f6697
Merge branch 'dev' into fuzz-iterator
Sep 15, 2023
78caed3
Merge branch 'dev' into fuzz-iterator
Sep 15, 2023
4636244
Merge branch 'fuzz-iterator' into fuzz-iterator-2
Sep 15, 2023
7b2744e
Merge remote-tracking branch 'upstream/dev' into fuzz-iterator-2
Sep 18, 2023
182f57f
nit
Sep 18, 2023
4ddd4fa
Merge branch 'dev' into fuzz-iterator-2
Sep 18, 2023
2b92306
nit
Sep 19, 2023
dd31012
Merge branch 'fuzz-iterator-2' of github.com:ava-labs/avalanchego int…
Sep 19, 2023
b93b45a
nit
Sep 19, 2023
efbc4df
Merge branch 'dev' into fuzz-iterator-2
abi87 Sep 22, 2023
091ae2a
Merge branch 'dev' into fuzz-iterator-2
Sep 25, 2023
b24b49a
Merge branch 'dev' into fuzz-iterator-2
Nov 7, 2023
55fd672
add FuzzNewIteratorWithStartAndPrefix for pebble
Nov 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions database/corruptabledb/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,21 @@ func TestInterface(t *testing.T) {
}
}

func FuzzKeyValue(f *testing.F) {
func newDB() *Database {
baseDB := memdb.New()
db := New(baseDB)
database.FuzzKeyValue(f, db)
return New(baseDB)
}

func FuzzKeyValue(f *testing.F) {
database.FuzzKeyValue(f, newDB())
}

func FuzzNewIteratorWithPrefix(f *testing.F) {
baseDB := memdb.New()
db := New(baseDB)
database.FuzzNewIteratorWithPrefix(f, db)
database.FuzzNewIteratorWithPrefix(f, newDB())
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F) {
database.FuzzNewIteratorWithStartAndPrefix(f, newDB())
}

// TestCorruption tests to make sure corruptabledb wrapper works as expected.
Expand Down Expand Up @@ -70,9 +75,7 @@ func TestCorruption(t *testing.T) {
return err
},
}
baseDB := memdb.New()
// wrap this db
corruptableDB := New(baseDB)
corruptableDB := newDB()
_ = corruptableDB.handleError(errTest)
for name, testFn := range tests {
t.Run(name, func(tt *testing.T) {
Expand Down Expand Up @@ -176,9 +179,7 @@ func TestIterator(t *testing.T) {
ctrl := gomock.NewController(t)

// Make a database
baseDB := memdb.New()
corruptableDB := New(baseDB)

corruptableDB := newDB()
// Put a key-value pair in the database.
require.NoError(corruptableDB.Put([]byte{0}, []byte{1}))

Expand Down
24 changes: 13 additions & 11 deletions database/encdb/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,30 @@ func TestInterface(t *testing.T) {
}
}

func FuzzKeyValue(f *testing.F) {
func newDB(t testing.TB) database.Database {
unencryptedDB := memdb.New()
db, err := New([]byte(testPassword), unencryptedDB)
require.NoError(f, err)
database.FuzzKeyValue(f, db)
require.NoError(t, err)
return db
}

func FuzzKeyValue(f *testing.F) {
database.FuzzKeyValue(f, newDB(f))
}

func FuzzNewIteratorWithPrefix(f *testing.F) {
unencryptedDB := memdb.New()
db, err := New([]byte(testPassword), unencryptedDB)
require.NoError(f, err)
database.FuzzNewIteratorWithPrefix(f, db)
database.FuzzNewIteratorWithPrefix(f, newDB(f))
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F) {
database.FuzzNewIteratorWithStartAndPrefix(f, newDB(f))
}

func BenchmarkInterface(b *testing.B) {
for _, size := range database.BenchmarkSizes {
keys, values := database.SetupBenchmark(b, size[0], size[1], size[2])
for _, bench := range database.Benchmarks {
unencryptedDB := memdb.New()
db, err := New([]byte(testPassword), unencryptedDB)
require.NoError(b, err)
bench(b, db, "encdb", keys, values)
bench(b, newDB(b), "encdb", keys, values)
}
}
}
27 changes: 16 additions & 11 deletions database/leveldb/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,39 @@ func TestInterface(t *testing.T) {
}
}

func FuzzKeyValue(f *testing.F) {
folder := f.TempDir()
func newDB(t testing.TB) database.Database {
folder := t.TempDir()
db, err := New(folder, nil, logging.NoLog{}, "", prometheus.NewRegistry())
require.NoError(f, err)
require.NoError(t, err)
return db
}

func FuzzKeyValue(f *testing.F) {
db := newDB(f)
defer db.Close()

database.FuzzKeyValue(f, db)
}

func FuzzNewIteratorWithPrefix(f *testing.F) {
folder := f.TempDir()
db, err := New(folder, nil, logging.NoLog{}, "", prometheus.NewRegistry())
require.NoError(f, err)

db := newDB(f)
defer db.Close()

database.FuzzNewIteratorWithPrefix(f, db)
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F) {
db := newDB(f)
defer db.Close()

database.FuzzNewIteratorWithStartAndPrefix(f, db)
}

func BenchmarkInterface(b *testing.B) {
for _, size := range database.BenchmarkSizes {
keys, values := database.SetupBenchmark(b, size[0], size[1], size[2])
for _, bench := range database.Benchmarks {
folder := b.TempDir()

db, err := New(folder, nil, logging.NoLog{}, "", prometheus.NewRegistry())
require.NoError(b, err)
db := newDB(b)

bench(b, db, "leveldb", keys, values)

Expand Down
4 changes: 4 additions & 0 deletions database/memdb/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ func FuzzNewIteratorWithPrefix(f *testing.F) {
database.FuzzNewIteratorWithPrefix(f, New())
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F) {
database.FuzzNewIteratorWithStartAndPrefix(f, New())
}

func BenchmarkInterface(b *testing.B) {
for _, size := range database.BenchmarkSizes {
keys, values := database.SetupBenchmark(b, size[0], size[1], size[2])
Expand Down
24 changes: 13 additions & 11 deletions database/meterdb/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,30 @@ func TestInterface(t *testing.T) {
}
}

func FuzzKeyValue(f *testing.F) {
func newDB(t testing.TB) database.Database {
baseDB := memdb.New()
db, err := New("", prometheus.NewRegistry(), baseDB)
require.NoError(f, err)
database.FuzzKeyValue(f, db)
require.NoError(t, err)
return db
}

func FuzzKeyValue(f *testing.F) {
database.FuzzKeyValue(f, newDB(f))
}

func FuzzNewIteratorWithPrefix(f *testing.F) {
baseDB := memdb.New()
db, err := New("", prometheus.NewRegistry(), baseDB)
require.NoError(f, err)
database.FuzzNewIteratorWithPrefix(f, db)
database.FuzzNewIteratorWithPrefix(f, newDB(f))
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F) {
database.FuzzNewIteratorWithStartAndPrefix(f, newDB(f))
}

func BenchmarkInterface(b *testing.B) {
for _, size := range database.BenchmarkSizes {
keys, values := database.SetupBenchmark(b, size[0], size[1], size[2])
for _, bench := range database.Benchmarks {
baseDB := memdb.New()
db, err := New("", prometheus.NewRegistry(), baseDB)
require.NoError(b, err)
bench(b, db, "meterdb", keys, values)
bench(b, newDB(b), "meterdb", keys, values)
}
}
}
6 changes: 6 additions & 0 deletions database/pebble/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ func FuzzNewIteratorWithPrefix(f *testing.F) {
_ = db.Close()
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F) {
db := newDB(f)
database.FuzzNewIteratorWithStartAndPrefix(f, db)
_ = db.Close()
}

func BenchmarkInterface(b *testing.B) {
for _, size := range database.BenchmarkSizes {
keys, values := database.SetupBenchmark(b, size[0], size[1], size[2])
Expand Down
4 changes: 4 additions & 0 deletions database/prefixdb/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ func FuzzNewIteratorWithPrefix(f *testing.F) {
database.FuzzNewIteratorWithPrefix(f, New([]byte(""), memdb.New()))
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F) {
database.FuzzNewIteratorWithStartAndPrefix(f, New([]byte(""), memdb.New()))
}

func BenchmarkInterface(b *testing.B) {
for _, size := range database.BenchmarkSizes {
keys, values := database.SetupBenchmark(b, size[0], size[1], size[2])
Expand Down
7 changes: 7 additions & 0 deletions database/rpcdb/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ func FuzzNewIteratorWithPrefix(f *testing.F) {
db.closeFn()
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F) {
db := setupDB(f)
database.FuzzNewIteratorWithStartAndPrefix(f, db.client)

db.closeFn()
}

func BenchmarkInterface(b *testing.B) {
for _, size := range database.BenchmarkSizes {
keys, values := database.SetupBenchmark(b, size[0], size[1], size[2])
Expand Down
69 changes: 68 additions & 1 deletion database/test_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,74 @@ func FuzzNewIteratorWithPrefix(f *testing.F, db Database) {
require.Equal(expected[string(iter.Key())], val)
numIterElts++
}
require.Equal(len(expectedList), numIterElts)
require.Len(expectedList, numIterElts)

// Clear the database for the next fuzz iteration.
require.NoError(AtomicClear(db, db))
})
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F, db Database) {
const (
maxKeyLen = 32
maxValueLen = 32
)

f.Fuzz(func(
t *testing.T,
randSeed int64,
start []byte,
prefix []byte,
numKeyValues uint,
) {
require := require.New(t)
r := rand.New(rand.NewSource(randSeed)) // #nosec G404

expected := map[string][]byte{}

// Put a bunch of key-values
for i := 0; i < int(numKeyValues); i++ {
key := make([]byte, r.Intn(maxKeyLen))
_, _ = r.Read(key) // #nosec G404
danlaine marked this conversation as resolved.
Show resolved Hide resolved

value := make([]byte, r.Intn(maxValueLen))
_, _ = r.Read(value) // #nosec G404

if len(value) == 0 {
// Consistently treat zero length values as nil
// so that we can compare [expected] and [got] with
// require.Equal, which treats nil and empty byte
// as being unequal, whereas the database treats
// them as being equal.
danlaine marked this conversation as resolved.
Show resolved Hide resolved
value = nil
}

if bytes.HasPrefix(key, prefix) && bytes.Compare(key, start) >= 0 {
abi87 marked this conversation as resolved.
Show resolved Hide resolved
expected[string(key)] = value
}

require.NoError(db.Put(key, value))
}

expectedList := maps.Keys(expected)
slices.Sort(expectedList)

iter := db.NewIteratorWithStartAndPrefix(start, prefix)
defer iter.Release()

// Assert the iterator returns the expected key-values.
numIterElts := 0
for iter.Next() {
val := iter.Value()
if len(val) == 0 {
val = nil
}
keyStr := string(iter.Key())
require.Equal(expectedList[numIterElts], keyStr)
require.Equal(expected[keyStr], val)
numIterElts++
}
require.Len(expectedList, numIterElts)

// Clear the database for the next fuzz iteration.
require.NoError(AtomicClear(db, db))
Expand Down
4 changes: 4 additions & 0 deletions database/versiondb/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ func FuzzNewIteratorWithPrefix(f *testing.F) {
database.FuzzNewIteratorWithPrefix(f, New(memdb.New()))
}

func FuzzNewIteratorWithStartAndPrefix(f *testing.F) {
database.FuzzNewIteratorWithStartAndPrefix(f, New(memdb.New()))
}

func TestIterate(t *testing.T) {
require := require.New(t)

Expand Down
Loading