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

     1  package explorer
     2  
     3  import (
     4  	"path/filepath"
     5  	"testing"
     6  
     7  	"github.com/NebulousLabs/Sia/build"
     8  	"github.com/NebulousLabs/Sia/crypto"
     9  	"github.com/NebulousLabs/Sia/modules"
    10  	"github.com/NebulousLabs/Sia/modules/consensus"
    11  	"github.com/NebulousLabs/Sia/modules/gateway"
    12  	"github.com/NebulousLabs/Sia/modules/miner"
    13  	"github.com/NebulousLabs/Sia/modules/transactionpool"
    14  	"github.com/NebulousLabs/Sia/modules/wallet"
    15  	"github.com/NebulousLabs/Sia/persist"
    16  	"github.com/NebulousLabs/Sia/types"
    17  )
    18  
    19  // Explorer tester struct is the helper object for explorer
    20  // testing. It holds the helper modules for its testing
    21  type explorerTester struct {
    22  	cs        modules.ConsensusSet
    23  	gateway   modules.Gateway
    24  	miner     modules.TestMiner
    25  	tpool     modules.TransactionPool
    26  	wallet    modules.Wallet
    27  	walletKey crypto.TwofishKey
    28  
    29  	explorer *Explorer
    30  	testdir  string
    31  }
    32  
    33  // createExplorerTester creates a tester object for the explorer module.
    34  func createExplorerTester(name string) (*explorerTester, error) {
    35  	// Create and assemble the dependencies.
    36  	testdir := build.TempDir(modules.ExplorerDir, name)
    37  	g, err := gateway.New("localhost:0", filepath.Join(testdir, modules.GatewayDir))
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir))
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir))
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir))
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	key, err := crypto.GenerateTwofishKey()
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	_, err = w.Encrypt(key)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	err = w.Unlock(key)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.RenterDir))
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  	e, err := New(cs, filepath.Join(testdir, modules.ExplorerDir))
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	et := &explorerTester{
    74  		cs:        cs,
    75  		gateway:   g,
    76  		miner:     m,
    77  		tpool:     tp,
    78  		wallet:    w,
    79  		walletKey: key,
    80  
    81  		explorer: e,
    82  		testdir:  testdir,
    83  	}
    84  
    85  	// Mine until the wallet has money.
    86  	for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ {
    87  		b, _ := et.miner.FindBlock()
    88  		err = et.cs.AcceptBlock(b)
    89  		if err != nil {
    90  			return nil, err
    91  		}
    92  	}
    93  	return et, nil
    94  }
    95  
    96  // reorgToBlank creates a bunch of empty blocks on top of the genesis block
    97  // that reorgs the explorer to a state of all blank blocks.
    98  func (et *explorerTester) reorgToBlank() error {
    99  	// Get a unique directory name to house the persistence of the miner
   100  	// dependencies.
   101  	dir := et.testdir + " - " + persist.RandomSuffix()
   102  
   103  	// Create a miner and all dependencies to create an alternate chain.
   104  	g, err := gateway.New("localhost:0", filepath.Join(dir, modules.GatewayDir))
   105  	if err != nil {
   106  		return err
   107  	}
   108  	cs, err := consensus.New(g, filepath.Join(dir, modules.ConsensusDir))
   109  	if err != nil {
   110  		return err
   111  	}
   112  	tp, err := transactionpool.New(cs, g, filepath.Join(dir, modules.TransactionPoolDir))
   113  	if err != nil {
   114  		return err
   115  	}
   116  	w, err := wallet.New(cs, tp, filepath.Join(dir, modules.WalletDir))
   117  	if err != nil {
   118  		return err
   119  	}
   120  	key, err := crypto.GenerateTwofishKey()
   121  	if err != nil {
   122  		return err
   123  	}
   124  	_, err = w.Encrypt(key)
   125  	if err != nil {
   126  		return err
   127  	}
   128  	err = w.Unlock(key)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	m, err := miner.New(cs, tp, w, filepath.Join(dir, modules.RenterDir))
   133  	if err != nil {
   134  		return err
   135  	}
   136  
   137  	// Mine blocks until the height is higher than the existing consensus,
   138  	// submitting each block to the explorerTester.
   139  	currentHeight := cs.Height()
   140  	for i := types.BlockHeight(0); i <= currentHeight+1; i++ {
   141  		block, err := m.AddBlock()
   142  		if err != nil {
   143  			return err
   144  		}
   145  		et.cs.AcceptBlock(block) // error is not checked, will not always be nil
   146  	}
   147  	return nil
   148  }
   149  
   150  // TestNilExplorerDependencies tries to initialize an explorer with nil
   151  // dependencies, checks that the correct error is returned.
   152  func TestNilExplorerDependencies(t *testing.T) {
   153  	_, err := New(nil, "expdir")
   154  	if err != errNilCS {
   155  		t.Fatal("Expecting errNilCS")
   156  	}
   157  }
   158  
   159  // TestExplorerGenesisHeight checks that when the explorer is initialized and given the
   160  // genesis block, the result has the correct height.
   161  func TestExplorerGenesisHeight(t *testing.T) {
   162  	// Create the dependencies.
   163  	testdir := build.TempDir(modules.HostDir, "TestExplorerGenesisHeight")
   164  	g, err := gateway.New("localhost:0", filepath.Join(testdir, modules.GatewayDir))
   165  	if err != nil {
   166  		t.Fatal(err)
   167  	}
   168  	cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir))
   169  	if err != nil {
   170  		t.Fatal(err)
   171  	}
   172  
   173  	// Create the explorer - from the subscription only the genesis block will
   174  	// be received.
   175  	e, err := New(cs, testdir)
   176  	if err != nil {
   177  		t.Fatal(err)
   178  	}
   179  	block, height, exists := e.Block(types.GenesisID)
   180  	if !exists {
   181  		t.Error("explorer missing genesis block after initialization")
   182  	}
   183  	if block.ID() != types.GenesisID {
   184  		t.Error("explorer returned wrong genesis block")
   185  	}
   186  	if height != 0 {
   187  		t.Errorf("genesis block hash wrong height: expected 0, got %v", height)
   188  	}
   189  }