github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/modules/wallet/wallet_test.go (about)

     1  package wallet
     2  
     3  import (
     4  	"crypto/rand"
     5  	"path/filepath"
     6  	"testing"
     7  
     8  	"github.com/NebulousLabs/Sia/build"
     9  	"github.com/NebulousLabs/Sia/crypto"
    10  	"github.com/NebulousLabs/Sia/modules"
    11  	"github.com/NebulousLabs/Sia/modules/consensus"
    12  	"github.com/NebulousLabs/Sia/modules/gateway"
    13  	"github.com/NebulousLabs/Sia/modules/miner"
    14  	"github.com/NebulousLabs/Sia/modules/transactionpool"
    15  	"github.com/NebulousLabs/Sia/types"
    16  )
    17  
    18  // A Wallet tester contains a ConsensusTester and has a bunch of helpful
    19  // functions for facilitating wallet integration testing.
    20  type walletTester struct {
    21  	cs      modules.ConsensusSet
    22  	gateway modules.Gateway
    23  	tpool   modules.TransactionPool
    24  	miner   modules.TestMiner
    25  	wallet  *Wallet
    26  
    27  	walletMasterKey crypto.TwofishKey
    28  
    29  	persistDir string
    30  }
    31  
    32  // createWalletTester takes a testing.T and creates a WalletTester.
    33  func createWalletTester(name string) (*walletTester, error) {
    34  	// Create the modules
    35  	testdir := build.TempDir(modules.WalletDir, name)
    36  	g, err := gateway.New("localhost:0", filepath.Join(testdir, modules.GatewayDir))
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir))
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir))
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  	w, err := New(cs, tp, filepath.Join(testdir, modules.WalletDir))
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	var masterKey crypto.TwofishKey
    53  	_, err = rand.Read(masterKey[:])
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	_, err = w.Encrypt(masterKey)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	err = w.Unlock(masterKey)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.WalletDir))
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	// Assemble all componenets into a wallet tester.
    71  	wt := &walletTester{
    72  		cs:      cs,
    73  		gateway: g,
    74  		tpool:   tp,
    75  		miner:   m,
    76  		wallet:  w,
    77  
    78  		walletMasterKey: masterKey,
    79  
    80  		persistDir: testdir,
    81  	}
    82  
    83  	// Mine blocks until there is money in the wallet.
    84  	for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ {
    85  		b, _ := wt.miner.FindBlock()
    86  		err := wt.cs.AcceptBlock(b)
    87  		if err != nil {
    88  			return nil, err
    89  		}
    90  	}
    91  	return wt, nil
    92  }
    93  
    94  // createBlankWalletTester creates a wallet tester that has not mined any
    95  // blocks or encrypted the wallet.
    96  func createBlankWalletTester(name string) (*walletTester, error) {
    97  	// Create the modules
    98  	testdir := build.TempDir(modules.WalletDir, name)
    99  	g, err := gateway.New("localhost:0", filepath.Join(testdir, modules.GatewayDir))
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  	cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir))
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  	tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir))
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  	w, err := New(cs, tp, filepath.Join(testdir, modules.WalletDir))
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  	m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.WalletDir))
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  
   120  	// Assemble all componenets into a wallet tester.
   121  	wt := &walletTester{
   122  		gateway: g,
   123  		cs:      cs,
   124  		tpool:   tp,
   125  		miner:   m,
   126  		wallet:  w,
   127  
   128  		persistDir: testdir,
   129  	}
   130  	return wt, nil
   131  }
   132  
   133  // closeWt closes all of the modules in the wallet tester.
   134  func (wt *walletTester) closeWt() {
   135  	err := wt.gateway.Close()
   136  	if err != nil {
   137  		panic(err)
   138  	}
   139  }
   140  
   141  // TestNilInputs tries starting the wallet using nil inputs.
   142  func TestNilInputs(t *testing.T) {
   143  	testdir := build.TempDir(modules.WalletDir, "TestNilInputs")
   144  	g, err := gateway.New("localhost:0", filepath.Join(testdir, modules.GatewayDir))
   145  	if err != nil {
   146  		t.Fatal(err)
   147  	}
   148  	cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir))
   149  	if err != nil {
   150  		t.Fatal(err)
   151  	}
   152  	tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir))
   153  	if err != nil {
   154  		t.Fatal(err)
   155  	}
   156  
   157  	wdir := filepath.Join(testdir, modules.WalletDir)
   158  	_, err = New(cs, nil, wdir)
   159  	if err != errNilTpool {
   160  		t.Error(err)
   161  	}
   162  	_, err = New(nil, tp, wdir)
   163  	if err != errNilConsensusSet {
   164  		t.Error(err)
   165  	}
   166  	_, err = New(nil, nil, wdir)
   167  	if err != errNilConsensusSet {
   168  		t.Error(err)
   169  	}
   170  }
   171  
   172  // TestAllAddresses checks that AllAddresses returns all of the wallet's
   173  // addresses in sorted order.
   174  func TestAllAddresses(t *testing.T) {
   175  	wt, err := createBlankWalletTester("TestAllAddresses")
   176  	if err != nil {
   177  		t.Fatal(err)
   178  	}
   179  	defer wt.closeWt()
   180  
   181  	wt.wallet.keys[types.UnlockHash{1}] = spendableKey{}
   182  	wt.wallet.keys[types.UnlockHash{5}] = spendableKey{}
   183  	wt.wallet.keys[types.UnlockHash{0}] = spendableKey{}
   184  	wt.wallet.keys[types.UnlockHash{2}] = spendableKey{}
   185  	wt.wallet.keys[types.UnlockHash{4}] = spendableKey{}
   186  	wt.wallet.keys[types.UnlockHash{3}] = spendableKey{}
   187  	addrs := wt.wallet.AllAddresses()
   188  	for i := range addrs {
   189  		if addrs[i][0] != byte(i) {
   190  			t.Error("address sorting failed:", i, addrs[i][0])
   191  		}
   192  	}
   193  }