diff --git a/Makefile b/Makefile index bbd535b..560ee12 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ test-all: test-clean test-with-reset: db-reset test-all test-clean: - GOGC=off go clean -testcache + GOGC=off go clean -testcache && rm -rf test_db tmp_db bench: @cd _benchmarks && go test -timeout=25m -bench=. diff --git a/backup_test.go b/backup_test.go index 22da412..fd7bc5c 100644 --- a/backup_test.go +++ b/backup_test.go @@ -97,6 +97,9 @@ func TestBond_BackupRestore(t *testing.T) { // make sure both db has same keys and values. itr := db.Iter(&IterOptions{}) itr2 := db2.Iter(&IterOptions{}) + defer itr.Close() + defer itr2.Close() + for _, _ = itr.First(), itr2.First(); itr.Valid(); _, _ = itr.Next(), itr2.Next() { require.Equal(t, itr.Key(), itr2.Key()) require.Equal(t, itr.Value(), itr2.Value()) diff --git a/bond.go b/bond.go index 76575b0..24c75de 100644 --- a/bond.go +++ b/bond.go @@ -389,6 +389,7 @@ func (db *_db) Dump(_ context.Context, path string, tables []TableID, withIndex defer snapshot.Close() grp := new(errgroup.Group) + // write all the table data to the sst file. for _, tableID := range tables { tablePath := filepath.Join(path, fmt.Sprintf("table_%d", tableID)) @@ -413,6 +414,7 @@ func (db *_db) Dump(_ context.Context, path string, tables []TableID, withIndex if !withIndex { continue } + // write all the index data to sst file. indexes := db.getIndexIDS(tableID) for _, index := range indexes { @@ -518,12 +520,14 @@ func (db *_db) getIndexIDS(tableID TableID) []IndexID { } prefix[1] = indexID + 1 } + itr.Close() return indexIDS } // write all the key/value of iterator to the SST file. func iteratorToSST(itr Iterator, path string) error { defer itr.Close() + // sst reader currentFileID := 1 file, err := vfs.Default.Create(filepath.Join(path, fmt.Sprintf("%d.sst", currentFileID)), vfs.WriteCategoryUnspecified) @@ -538,6 +542,7 @@ func iteratorToSST(itr Iterator, path string) error { for itr.First(); itr.Valid(); itr.Next() { if err := writer.Set(itr.Key(), itr.Value()); err != nil { + writer.Close() return err } diff --git a/bond_test.go b/bond_test.go index c6db74f..47c3d2a 100644 --- a/bond_test.go +++ b/bond_test.go @@ -22,7 +22,10 @@ func setupDB(name string, serializer ...Serializer[any]) DB { options.Serializer = serializer[0] } - db, _ := Open(name, options) + db, err := Open(name, options) + if err != nil { + panic(err) + } return db } @@ -31,8 +34,17 @@ func tearDownDatabase(db DB) { } func tearDownDB(name string, db DB) { - _ = db.Close() - _ = os.RemoveAll(name) + // NOTE: we intentionally panic on Close here, as it will catch any + // leaking iterators which would otherwise be difficult to debug, + // and are relevant to ensure we close. + err := db.Close() + if err != nil { + panic(err) + } + err = os.RemoveAll(name) + if err != nil { + panic(err) + } } func TestBond_Open(t *testing.T) { diff --git a/index_test.go b/index_test.go index 2aeb365..b094668 100644 --- a/index_test.go +++ b/index_test.go @@ -1268,6 +1268,7 @@ func TestBond_Table_Index_Insert(t *testing.T) { copy(buff, it.Key()) keys = append(keys, buff) } + it.Close() require.Equal(t, 8, len(keys)) assert.True(t, strings.Contains(string(keys[3]), "0xtestAccount1")) @@ -1287,6 +1288,7 @@ func TestBond_Table_Index_Insert(t *testing.T) { for it.First(); it.Valid(); it.Next() { fmt.Printf("0x%x(%s): %s\n", it.Key(), it.Key(), it.Value()) } + it.Close() } func TestBond_Table_Index_Insert_Ordered(t *testing.T) { @@ -1395,6 +1397,7 @@ func TestBond_Table_Index_Insert_Ordered(t *testing.T) { copy(buff, it.Key()) keys = append(keys, buff) } + it.Close() require.Equal(t, 8, len(keys)) assert.True(t, strings.Contains(string(keys[3]), "0xtestAccount1") && bytes.Contains(keys[3], []byte{0xF0})) @@ -1414,6 +1417,7 @@ func TestBond_Table_Index_Insert_Ordered(t *testing.T) { for it.First(); it.Valid(); it.Next() { fmt.Printf("0x%x(%s): %s\n", it.Key(), it.Key(), it.Value()) } + it.Close() } func TestBond_Table_Index_Update(t *testing.T) { @@ -1532,6 +1536,7 @@ func TestBond_Table_Index_Update(t *testing.T) { copy(buff, it.Key()) keys = append(keys, buff) } + it.Close() require.Equal(t, 8, len(keys)) assert.True(t, strings.Contains(string(keys[3]), "0xtestAccount3")) @@ -1551,6 +1556,7 @@ func TestBond_Table_Index_Update(t *testing.T) { for it.First(); it.Valid(); it.Next() { fmt.Printf("0x%x(%s): %s\n", it.Key(), it.Key(), it.Value()) } + it.Close() } func TestBond_Table_Index_Update_Ordered(t *testing.T) { @@ -1673,6 +1679,7 @@ func TestBond_Table_Index_Update_Ordered(t *testing.T) { copy(buff, it.Key()) keys = append(keys, buff) } + it.Close() require.Equal(t, 8, len(keys)) assert.True(t, strings.Contains(string(keys[3]), "0xtestAccount3") && bytes.Contains(keys[3], []byte{0xF0})) @@ -1692,6 +1699,7 @@ func TestBond_Table_Index_Update_Ordered(t *testing.T) { for it.First(); it.Valid(); it.Next() { fmt.Printf("0x%x(%s): %s\n", it.Key(), it.Key(), it.Value()) } + it.Close() } func TestBond_Table_Index_Delete(t *testing.T) { @@ -1800,6 +1808,7 @@ func TestBond_Table_Index_Delete(t *testing.T) { }) require.NoError(t, err) assert.False(t, it.First()) + it.Close() it, err = db.Backend().NewIter(&pebble.IterOptions{ LowerBound: []byte{byte(TokenBalanceTableID)}, @@ -1812,6 +1821,7 @@ func TestBond_Table_Index_Delete(t *testing.T) { for it.First(); it.Valid(); it.Next() { fmt.Printf("0x%x(%s): %s\n", it.Key(), it.Key(), it.Value()) } + it.Close() } func TestBond_Table_Reindex(t *testing.T) { diff --git a/table_test.go b/table_test.go index 8df031e..7d3a401 100644 --- a/table_test.go +++ b/table_test.go @@ -460,6 +460,7 @@ func TestBondTable_Insert(t *testing.T) { UpperBound: []byte{byte(TokenBalanceTableID + 1)}, }) require.NoError(t, err) + defer it.Close() for it.First(); it.Valid(); it.Next() { rawData := it.Value() @@ -539,6 +540,7 @@ func TestBondTable_Insert_When_Exist(t *testing.T) { UpperBound: []byte{byte(TokenBalanceTableID + 1)}, }) require.NoError(t, err) + defer it.Close() for it.First(); it.Valid(); it.Next() { rawData := it.Value() @@ -780,8 +782,13 @@ func TestBondTable_Upsert(t *testing.T) { var tokenBalanceAccountFromDB TokenBalance err = db.Serializer().Deserialize(rawData, &tokenBalanceAccountFromDB) + if err != nil { + // panic(err) + break + } tokenBalances = append(tokenBalances, &tokenBalanceAccountFromDB) } + require.NoError(t, err) _ = it.Close() @@ -872,8 +879,12 @@ func TestBondTable_Upsert_Context_Canceled(t *testing.T) { var tokenBalanceAccountFromDB TokenBalance err = db.Serializer().Deserialize(rawData, &tokenBalanceAccountFromDB) + if err != nil { + break + } tokenBalances = append(tokenBalances, &tokenBalanceAccountFromDB) } + require.NoError(t, err) _ = it.Close() @@ -978,8 +989,12 @@ func TestBondTable_Upsert_OnConflict(t *testing.T) { var tokenBalanceAccountFromDB TokenBalance err = db.Serializer().Deserialize(rawData, &tokenBalanceAccountFromDB) + if err != nil { + break + } tokenBalances = append(tokenBalances, &tokenBalanceAccountFromDB) } + require.NoError(t, err) _ = it.Close() @@ -1128,7 +1143,7 @@ func TestBondTable_Update_No_Such_Entry(t *testing.T) { UpperBound: []byte{byte(TokenBalanceTableID + 1)}, }) require.NoError(t, err) - + defer it.Close() assert.False(t, it.First()) } @@ -1168,6 +1183,7 @@ func TestBondTable_Delete(t *testing.T) { UpperBound: []byte{byte(TokenBalanceTableID + 1)}, }) require.NoError(t, err) + defer it.Close() assert.False(t, it.First()) } @@ -1475,4 +1491,5 @@ func TestBond_Batch(t *testing.T) { require.NoError(t, err) assert.Equal(t, tokenBalance, &tokenBalanceAccountFromDB) } + it.Close() }