diff --git a/common_test.go b/common_test.go new file mode 100644 index 00000000..340718a7 --- /dev/null +++ b/common_test.go @@ -0,0 +1,74 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "fmt" + "github.com/conformal/btcchain" + "github.com/conformal/btcdb" + _ "github.com/conformal/btcdb/ldb" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "os" + "path/filepath" +) + +// testDbRoot is the root directory used to create all test databases. +const testDbRoot = "testdbs" + +// filesExists returns whether or not the named file or directory exists. +func fileExists(name string) bool { + if _, err := os.Stat(name); err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} + +// chainSetup is used to create a new db and chain instance with the genesis +// block already inserted. In addition to the new chain instnce, it returns +// a teardown function the caller should invoke when done testing to clean up. +func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { + // Create the root directory for test databases. + if !fileExists(testDbRoot) { + if err := os.MkdirAll(testDbRoot, 0700); err != nil { + err := fmt.Errorf("unable to create test db root: %v", err) + return nil, nil, err + } + } + + // Create a new database to store the accepted blocks into. + dbPath := filepath.Join(testDbRoot, dbName) + _ = os.RemoveAll(dbPath) + db, err := btcdb.CreateDB("leveldb", dbPath) + if err != nil { + return nil, nil, fmt.Errorf("error creating db: %v", err) + } + + // Setup a teardown function for cleaning up. This function is returned + // to the caller to be invoked when it is done testing. + teardown := func() { + dbVersionPath := filepath.Join(testDbRoot, dbName+".ver") + db.Sync() + db.Close() + os.RemoveAll(dbPath) + os.Remove(dbVersionPath) + os.RemoveAll(testDbRoot) + } + + // Insert the main network genesis block. This is part of the initial + // database setup. + genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock) + _, err = db.InsertBlock(genesisBlock) + if err != nil { + teardown() + err := fmt.Errorf("failed to insert genesis block: %v", err) + return nil, nil, err + } + + chain := btcchain.New(db, btcwire.MainNet, nil) + return chain, teardown, nil +} diff --git a/reorganization_test.go b/reorganization_test.go index 69f22b0f..dbb902bb 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -8,8 +8,6 @@ import ( "compress/bzip2" "encoding/binary" "github.com/conformal/btcchain" - "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/sqlite3" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "io" @@ -26,7 +24,7 @@ import ( func TestReorganization(t *testing.T) { // Intentionally load the side chain blocks out of order to ensure // orphans are handled properly along with chain reorganization. - testFiles := [...]string{ + testFiles := []string{ "blk_0_to_4.dat.bz2", "blk_4A.dat.bz2", "blk_5A.dat.bz2", @@ -46,36 +44,26 @@ func TestReorganization(t *testing.T) { t.Logf("Number of blocks: %v\n", len(blocks)) - dbname := "chaintest" - _ = os.Remove(dbname) - db, err := btcdb.CreateDB("sqlite", dbname) + // Create a new database and chain instance to run tests against. + chain, teardownFunc, err := chainSetup("reorg") if err != nil { - t.Errorf("Error creating db: %v\n", err) - } - // Clean up - defer os.Remove(dbname) - defer db.Close() - - // Insert the main network genesis block. - genesis := btcutil.NewBlock(&btcwire.GenesisBlock) - if _, err := db.InsertBlock(genesis); err != nil { - t.Errorf("Failed to insert genesis block: %v", err) + t.Errorf("Failed to setup chain instance: %v", err) + return } + defer teardownFunc() // Since we're not dealing with the real block chain, disable // checkpoints and set the coinbase maturity to 1. - blockChain := btcchain.New(db, btcwire.MainNet, nil) - blockChain.DisableCheckpoints(true) + chain.DisableCheckpoints(true) btcchain.TstSetCoinbaseMaturity(1) for i := 1; i < len(blocks); i++ { - err = blockChain.ProcessBlock(blocks[i]) + err = chain.ProcessBlock(blocks[i]) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return } } - db.Sync() return } diff --git a/validate_test.go b/validate_test.go index 1b2998cd..5cde8f1a 100644 --- a/validate_test.go +++ b/validate_test.go @@ -6,30 +6,22 @@ package btcchain_test import ( "github.com/conformal/btcchain" - "github.com/conformal/btcdb" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math" - "os" "reflect" "testing" "time" ) func TestCheckBlockSanity(t *testing.T) { - // Create a new test database. - dbName := "cbsanitytest.db" - _ = os.Remove(dbName) - db, err := btcdb.CreateDB("sqlite", dbName) + // Create a new database and chain instance to run tests against. + chain, teardownFunc, err := chainSetup("cbsanity") if err != nil { - t.Errorf("Error creating db: %v\n", err) + t.Errorf("Failed to setup chain instance: %v", err) + return } - defer os.Remove(dbName) - defer db.Close() - - // Create a new BlockChain instance using the underlying database for - // the main bitcoin network and ignore notifications. - chain := btcchain.New(db, btcwire.MainNet, nil) + defer teardownFunc() block := btcutil.NewBlock(&Block100000) err = chain.TstCheckBlockSanity(block)