github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/api/miner_test.go (about)

     1  package api
     2  
     3  import (
     4  	"io/ioutil"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/NebulousLabs/Sia/crypto"
     9  	"github.com/NebulousLabs/Sia/types"
    10  )
    11  
    12  // TestIntegrationMinerGET checks the GET call to the /miner endpoint.
    13  func TestIntegrationMinerGET(t *testing.T) {
    14  	if testing.Short() {
    15  		t.SkipNow()
    16  	}
    17  	st, err := createServerTester("TestIntegrationMinerGET")
    18  	if err != nil {
    19  		t.Fatal(err)
    20  	}
    21  	defer st.server.Close()
    22  
    23  	// Get the api returned fields of the miner.
    24  	var mg MinerGET
    25  	err = st.getAPI("/miner", &mg)
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  
    30  	// Verify the correctness of the results.
    31  	blocksMined, staleBlocksMined := st.server.miner.BlocksMined()
    32  	if mg.BlocksMined != blocksMined {
    33  		t.Error("blocks mined did not succeed")
    34  	}
    35  	if mg.StaleBlocksMined != staleBlocksMined {
    36  		t.Error("stale blocks mined is incorrect")
    37  	}
    38  	if mg.CPUHashrate != st.server.miner.CPUHashrate() {
    39  		t.Error("mismatched cpu hashrate")
    40  	}
    41  	if mg.CPUMining != st.server.miner.CPUMining() {
    42  		t.Error("mismatched cpu miner status")
    43  	}
    44  }
    45  
    46  // TestIntegrationMinerStartStop checks that the miner start and miner stop api endpoints
    47  // toggle the cpu miner.
    48  func TestIntegrationMinerStartStop(t *testing.T) {
    49  	if testing.Short() {
    50  		t.SkipNow()
    51  	}
    52  	st, err := createServerTester("TestIntegrationMinerStartStop")
    53  	if err != nil {
    54  		t.Fatal(err)
    55  	}
    56  	defer st.server.Close()
    57  
    58  	// Start the cpu miner, give time for the first hashrate readings to
    59  	// appear.
    60  	err = st.stdGetAPI("/miner/start")
    61  	if err != nil {
    62  		t.Fatal(err)
    63  	}
    64  	time.Sleep(100 * time.Millisecond)
    65  	if !st.server.miner.CPUMining() {
    66  		t.Error("cpu miner is reporting that it is not on")
    67  	}
    68  
    69  	// Check the numbers through the status api call.
    70  	var mg MinerGET
    71  	err = st.getAPI("/miner", &mg)
    72  	if err != nil {
    73  		t.Fatal(err)
    74  	}
    75  	if !mg.CPUMining {
    76  		t.Error("cpu is not reporting through the api that it is mining.")
    77  	}
    78  
    79  	// Stop the cpu miner and wait for the stop call to go through.
    80  	err = st.stdGetAPI("/miner/stop")
    81  	if err != nil {
    82  		t.Fatal(err)
    83  	}
    84  	time.Sleep(100 * time.Millisecond)
    85  	if st.server.miner.CPUMining() {
    86  		t.Error("cpu miner is reporting that it is not on")
    87  	}
    88  
    89  	// Check the numbers through the status api call.
    90  	err = st.getAPI("/miner", &mg)
    91  	if err != nil {
    92  		t.Fatal(err)
    93  	}
    94  	if mg.CPUMining {
    95  		t.Error("cpu is not reporting through the api that it is mining.")
    96  	}
    97  }
    98  
    99  // TestIntegrationMinerHeader checks that the header GET and POST calls are
   100  // useful tools for mining blocks.
   101  func TestIntegrationMinerHeader(t *testing.T) {
   102  	if testing.Short() {
   103  		t.SkipNow()
   104  	}
   105  	st, err := createServerTester("TestIntegrationMinerHeader")
   106  	if err != nil {
   107  		t.Fatal(err)
   108  	}
   109  	defer st.server.Close()
   110  	startingHeight := st.cs.Height()
   111  
   112  	// Get a header that can be used for mining.
   113  	resp, err := HttpGET("http://" + st.server.listener.Addr().String() + "/miner/header")
   114  	if err != nil {
   115  		t.Fatal(err)
   116  	}
   117  	defer resp.Body.Close()
   118  	targetAndHeader, err := ioutil.ReadAll(resp.Body)
   119  	if err != nil {
   120  		t.Fatal(err)
   121  	}
   122  
   123  	// Twiddle the header bits until a block has been found.
   124  	//
   125  	// Note: this test treats the target as hardcoded, if the testing target is
   126  	// changed, this test will also need to be changed.
   127  	if types.RootTarget[0] != 128 {
   128  		t.Fatal("test will fail because the testing constants have been unexpectedly changed")
   129  	}
   130  	var header [80]byte
   131  	copy(header[:], targetAndHeader[32:])
   132  	headerHash := crypto.HashObject(header)
   133  	for headerHash[0] >= types.RootTarget[0] {
   134  		header[35]++
   135  		headerHash = crypto.HashObject(header)
   136  	}
   137  
   138  	// Submit the solved header through the api and check that the height of
   139  	// the blockchain increases.
   140  	resp, err = HttpPOST("http://"+st.server.listener.Addr().String()+"/miner/header", string(header[:]))
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  	defer resp.Body.Close()
   145  	time.Sleep(500 * time.Millisecond)
   146  	if st.cs.Height() != startingHeight+1 {
   147  		t.Errorf("block height did not increase after trying to mine a block through the api, started at %v and ended at %v", startingHeight, st.cs.Height())
   148  	}
   149  }