decred.org/dcrwallet/v3@v3.1.0/wallet/walletdb/db_test.go (about)

     1  // Copyright (c) 2014 The btcsuite developers
     2  // Copyright (c) 2015 The Decred developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package walletdb_test
     7  
     8  import (
     9  	"context"
    10  	"os"
    11  	"testing"
    12  
    13  	"decred.org/dcrwallet/v3/errors"
    14  	_ "decred.org/dcrwallet/v3/wallet/internal/bdb"
    15  	"decred.org/dcrwallet/v3/wallet/walletdb"
    16  )
    17  
    18  // dbType is the database type name for this driver.
    19  const dbType = "bdb"
    20  
    21  // TestAddDuplicateDriver ensures that adding a duplicate driver does not
    22  // overwrite an existing one.
    23  func TestAddDuplicateDriver(t *testing.T) {
    24  	supportedDrivers := walletdb.SupportedDrivers()
    25  	if len(supportedDrivers) == 0 {
    26  		t.Errorf("no backends to test")
    27  		return
    28  	}
    29  	dbType := supportedDrivers[0]
    30  
    31  	// bogusCreateDB is a function which acts as a bogus create and open
    32  	// driver function and intentionally returns a failure that can be
    33  	// detected if the interface allows a duplicate driver to overwrite an
    34  	// existing one.
    35  	bogusCreateDB := func(args ...interface{}) (walletdb.DB, error) {
    36  		return nil, errors.Errorf("duplicate driver allowed for database "+
    37  			"type [%v]", dbType)
    38  	}
    39  
    40  	// Create a driver that tries to replace an existing one.  Set its
    41  	// create and open functions to a function that causes a test failure if
    42  	// they are invoked.
    43  	driver := walletdb.Driver{
    44  		DbType: dbType,
    45  		Create: bogusCreateDB,
    46  		Open:   bogusCreateDB,
    47  	}
    48  	err := walletdb.RegisterDriver(driver)
    49  	if !errors.Is(err, errors.Exist) {
    50  		t.Errorf("unexpected duplicate driver registration error: %v", err)
    51  	}
    52  
    53  	dbPath := "dupdrivertest.db"
    54  	db, err := walletdb.Create(dbType, dbPath)
    55  	if err != nil {
    56  		t.Errorf("failed to create database: %v", err)
    57  		return
    58  	}
    59  	db.Close()
    60  	_ = os.Remove(dbPath)
    61  }
    62  
    63  // TestCreateOpenFail ensures that errors which occur while opening or closing
    64  // a database are handled properly.
    65  func TestCreateOpenFail(t *testing.T) {
    66  	// bogusCreateDB is a function which acts as a bogus create and open
    67  	// driver function that intentionally returns a failure which can be
    68  	// detected.
    69  	dbType := "createopenfail"
    70  	openError := errors.Errorf("failed to create or open database for "+
    71  		"database type [%v]", dbType)
    72  	bogusCreateDB := func(args ...interface{}) (walletdb.DB, error) {
    73  		return nil, openError
    74  	}
    75  
    76  	// Create and add driver that intentionally fails when created or opened
    77  	// to ensure errors on database open and create are handled properly.
    78  	driver := walletdb.Driver{
    79  		DbType: dbType,
    80  		Create: bogusCreateDB,
    81  		Open:   bogusCreateDB,
    82  	}
    83  	err := walletdb.RegisterDriver(driver)
    84  	if err != nil {
    85  		t.Errorf("failed to register driver: %v", err)
    86  		return
    87  	}
    88  
    89  	// Ensure creating a database with the new type fails with the expected
    90  	// error.
    91  	_, err = walletdb.Create(dbType)
    92  	if !errors.Is(err, openError) {
    93  		t.Errorf("expected error not received - got: %v, want %v", err,
    94  			openError)
    95  		return
    96  	}
    97  
    98  	// Ensure opening a database with the new type fails with the expected
    99  	// error.
   100  	_, err = walletdb.Open(dbType)
   101  	if !errors.Is(err, openError) {
   102  		t.Errorf("expected error not received - got: %v, want %v", err,
   103  			openError)
   104  		return
   105  	}
   106  }
   107  
   108  // TestCreateOpenUnsupported ensures that attempting to create or open an
   109  // unsupported database type is handled properly.
   110  func TestCreateOpenUnsupported(t *testing.T) {
   111  	// Ensure creating a database with an unsupported type fails with the
   112  	// expected error.
   113  	dbType := "unsupported"
   114  	_, err := walletdb.Create(dbType)
   115  	if !errors.Is(err, errors.Invalid) {
   116  		t.Errorf("walletdb.Create: %v", err)
   117  	}
   118  
   119  	// Ensure opening a database with the an unsupported type fails with the
   120  	// expected error.
   121  	_, err = walletdb.Open(dbType)
   122  	if !errors.Is(err, errors.Invalid) {
   123  		t.Errorf("walletdb.Create: %v", err)
   124  	}
   125  }
   126  
   127  // TestInterface performs all interfaces tests for this database driver.
   128  func TestInterface(t *testing.T) {
   129  	// Create a new database to run tests against.
   130  	dbPath := "interfacetest.db"
   131  	db, err := walletdb.Create(dbType, dbPath)
   132  	if err != nil {
   133  		t.Errorf("Failed to create test database (%s) %v", dbType, err)
   134  		return
   135  	}
   136  	defer os.Remove(dbPath)
   137  	defer db.Close()
   138  
   139  	// Run all of the interface tests against the database.
   140  	ctx := context.Background()
   141  	testInterface(ctx, t, db)
   142  }