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

     1  package api
     2  
     3  // renterhost_test.go sets up larger integration tests between renters and
     4  // hosts, checking that the whole storage ecosystem is functioning cohesively.
     5  
     6  // TODO: There are a bunch of magic numbers in this file.
     7  
     8  import (
     9  	"bytes"
    10  	"io/ioutil"
    11  	"net/url"
    12  	"path/filepath"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/NebulousLabs/Sia/modules"
    17  	"github.com/NebulousLabs/Sia/types"
    18  )
    19  
    20  // TestIntegrationHostAndRent sets up an integration test where a host and
    21  // renter participate in all of the actions related to simple renting and
    22  // hosting.
    23  func TestIntegrationHostAndRent(t *testing.T) {
    24  	if testing.Short() {
    25  		t.SkipNow()
    26  	}
    27  	st, err := createServerTester("TestIntegrationHostAndRent")
    28  	if err != nil {
    29  		t.Fatal(err)
    30  	}
    31  	defer st.server.Close()
    32  
    33  	// announce the host and start accepting contracts
    34  	err = st.announceHost()
    35  	if err != nil {
    36  		t.Fatal(err)
    37  	}
    38  	err = st.acceptContracts()
    39  	if err != nil {
    40  		t.Fatal(err)
    41  	}
    42  	err = st.setHostStorage()
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  
    47  	// create contracts
    48  	allowanceValues := url.Values{}
    49  	allowanceValues.Set("funds", "10000000000000000000000000000") // 10k SC
    50  	allowanceValues.Set("period", "5")
    51  	err = st.stdPostAPI("/renter/allowance", allowanceValues)
    52  	if err != nil {
    53  		t.Fatal(err)
    54  	}
    55  
    56  	// create a file
    57  	path := filepath.Join(st.dir, "test.dat")
    58  	err = createRandFile(path, 1024)
    59  	if err != nil {
    60  		t.Fatal(err)
    61  	}
    62  
    63  	// upload to host
    64  	uploadValues := url.Values{}
    65  	uploadValues.Set("source", path)
    66  	err = st.stdPostAPI("/renter/upload/test", uploadValues)
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	// only one piece will be uploaded (10% at current redundancy)
    71  	var rf RenterFiles
    72  	for i := 0; i < 200 && (len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10); i++ {
    73  		st.getAPI("/renter/files", &rf)
    74  		time.Sleep(50 * time.Millisecond)
    75  	}
    76  	if len(rf.Files) != 1 || rf.Files[0].UploadProgress < 10 {
    77  		t.Fatal("the uploading is not succeeding for some reason:", rf.Files[0])
    78  	}
    79  
    80  	// On a second connection, upload another file.
    81  	path2 := filepath.Join(st.dir, "test2.dat")
    82  	test2Size := modules.SectorSize*2 + 1
    83  	err = createRandFile(path2, int(test2Size))
    84  	if err != nil {
    85  		t.Fatal(err)
    86  	}
    87  	uploadValues = url.Values{}
    88  	uploadValues.Set("source", path2)
    89  	err = st.stdPostAPI("/renter/upload/test2", uploadValues)
    90  	if err != nil {
    91  		t.Fatal(err)
    92  	}
    93  	// only one piece will be uploaded (10% at current redundancy)
    94  	for i := 0; i < 200 && (len(rf.Files) != 2 || rf.Files[0].UploadProgress < 10 || rf.Files[1].UploadProgress < 10); i++ {
    95  		st.getAPI("/renter/files", &rf)
    96  		time.Sleep(50 * time.Millisecond)
    97  	}
    98  	if len(rf.Files) != 2 || rf.Files[0].UploadProgress < 10 || rf.Files[1].UploadProgress < 10 {
    99  		t.Fatal("the uploading is not succeeding for some reason:", rf.Files[0])
   100  	}
   101  
   102  	// Try downloading the second file.
   103  	downpath := filepath.Join(st.dir, "testdown.dat")
   104  	err = st.stdGetAPI("/renter/download/test2?destination=" + downpath)
   105  	if err != nil {
   106  		t.Fatal(err)
   107  	}
   108  	// Check that the download has the right contents.
   109  	orig, err := ioutil.ReadFile(path2)
   110  	if err != nil {
   111  		t.Fatal(err)
   112  	}
   113  	download, err := ioutil.ReadFile(downpath)
   114  	if err != nil {
   115  		t.Fatal(err)
   116  	}
   117  	if bytes.Compare(orig, download) != 0 {
   118  		t.Fatal("data mismatch when downloading a file")
   119  	}
   120  
   121  	// Mine blocks until the host recognizes profit. The host will wait for 12
   122  	// blocks after the storage window has closed to report the profit, a total
   123  	// of 40 blocks should be mined.
   124  	for i := 0; i < 40; i++ {
   125  		st.miner.AddBlock()
   126  	}
   127  	// Check that the host is reporting a profit.
   128  	var hg HostGET
   129  	st.getAPI("/host", &hg)
   130  	if hg.FinancialMetrics.StorageRevenue.Cmp(types.ZeroCurrency) <= 0 {
   131  		t.Fatal("host is not reporting storage revenue")
   132  	}
   133  	if hg.FinancialMetrics.DownloadBandwidthRevenue.Cmp(types.ZeroCurrency) <= 0 {
   134  		t.Fatal("host is not reporting bandwidth revenue")
   135  	}
   136  }