2aca924514
The specific parameters required by a backend is better left up to the backend itself. For example memdb has no need for a database path, while ldb does. This commit modifies the OpenDB and CreateDB functions to take a arbitrary arguments which are passed along to the driver. The driver is expected to verify the correct type and number of arguments and error accordingly. The existing backends have been updated accordingly.
105 lines
3.1 KiB
Go
105 lines
3.1 KiB
Go
// Copyright (c) 2013-2014 Conformal Systems LLC.
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package memdb_test
|
|
|
|
import (
|
|
"github.com/conformal/btcdb"
|
|
"github.com/conformal/btcdb/memdb"
|
|
"github.com/conformal/btcutil"
|
|
"github.com/conformal/btcwire"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
// TestClosed ensure calling the interface functions on a closed database
|
|
// returns appropriate errors for the interface functions that return errors
|
|
// and does not panic or otherwise misbehave for functions which do not return
|
|
// errors.
|
|
func TestClosed(t *testing.T) {
|
|
db, err := btcdb.CreateDB("memdb")
|
|
if err != nil {
|
|
t.Errorf("Failed to open test database %v", err)
|
|
return
|
|
}
|
|
_, err = db.InsertBlock(btcutil.NewBlock(&btcwire.GenesisBlock))
|
|
if err != nil {
|
|
t.Errorf("InsertBlock: %v", err)
|
|
}
|
|
db.Close()
|
|
|
|
genesisHash := &btcwire.GenesisHash
|
|
if err := db.DropAfterBlockBySha(genesisHash); err != memdb.ErrDbClosed {
|
|
t.Errorf("DropAfterBlockBySha: unexpected error %v", err)
|
|
}
|
|
|
|
if exists := db.ExistsSha(genesisHash); exists != false {
|
|
t.Errorf("ExistsSha: genesis hash exists after close")
|
|
}
|
|
|
|
if _, err := db.FetchBlockBySha(genesisHash); err != memdb.ErrDbClosed {
|
|
t.Errorf("FetchBlockBySha: unexpected error %v", err)
|
|
}
|
|
|
|
if _, err := db.FetchBlockShaByHeight(0); err != memdb.ErrDbClosed {
|
|
t.Errorf("FetchBlockShaByHeight: unexpected error %v", err)
|
|
}
|
|
|
|
if _, err := db.FetchHeightRange(0, 1); err != memdb.ErrDbClosed {
|
|
t.Errorf("FetchHeightRange: unexpected error %v", err)
|
|
}
|
|
|
|
genesisMerkleRoot := &btcwire.GenesisMerkleRoot
|
|
if exists := db.ExistsTxSha(genesisMerkleRoot); exists != false {
|
|
t.Errorf("ExistsTxSha: hash %v exists when it shouldn't",
|
|
genesisMerkleRoot)
|
|
}
|
|
|
|
if _, err := db.FetchTxBySha(genesisHash); err != memdb.ErrDbClosed {
|
|
t.Errorf("FetchTxBySha: unexpected error %v", err)
|
|
}
|
|
|
|
requestHashes := []*btcwire.ShaHash{genesisHash}
|
|
reply := db.FetchTxByShaList(requestHashes)
|
|
if len(reply) != len(requestHashes) {
|
|
t.Errorf("FetchUnSpentTxByShaList unexpected number of replies "+
|
|
"got: %d, want: %d", len(reply), len(requestHashes))
|
|
}
|
|
for i, txLR := range reply {
|
|
wantReply := &btcdb.TxListReply{
|
|
Sha: requestHashes[i],
|
|
Err: memdb.ErrDbClosed,
|
|
}
|
|
if !reflect.DeepEqual(wantReply, txLR) {
|
|
t.Errorf("FetchTxByShaList unexpected reply\ngot: %v\n"+
|
|
"want: %v", txLR, wantReply)
|
|
}
|
|
}
|
|
|
|
reply = db.FetchUnSpentTxByShaList(requestHashes)
|
|
if len(reply) != len(requestHashes) {
|
|
t.Errorf("FetchUnSpentTxByShaList unexpected number of replies "+
|
|
"got: %d, want: %d", len(reply), len(requestHashes))
|
|
}
|
|
for i, txLR := range reply {
|
|
wantReply := &btcdb.TxListReply{
|
|
Sha: requestHashes[i],
|
|
Err: memdb.ErrDbClosed,
|
|
}
|
|
if !reflect.DeepEqual(wantReply, txLR) {
|
|
t.Errorf("FetchUnSpentTxByShaList unexpected reply\n"+
|
|
"got: %v\nwant: %v", txLR, wantReply)
|
|
}
|
|
}
|
|
|
|
if _, _, err := db.NewestSha(); err != memdb.ErrDbClosed {
|
|
t.Errorf("NewestSha: unexpected error %v", err)
|
|
}
|
|
|
|
// The following calls don't return errors from the interface to be able
|
|
// to detect a closed database, so just call them to ensure there are no
|
|
// panics.
|
|
db.Sync()
|
|
db.RollbackClose()
|
|
}
|