github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/exchange/bitswap/bitswap_test.go (about)

     1  package bitswap
     2  
     3  import (
     4  	"bytes"
     5  	"sync"
     6  	"testing"
     7  	"time"
     8  
     9  	detectrace "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-detect-race"
    10  	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
    11  	travis "github.com/ipfs/go-ipfs/util/testutil/ci/travis"
    12  
    13  	blocks "github.com/ipfs/go-ipfs/blocks"
    14  	blocksutil "github.com/ipfs/go-ipfs/blocks/blocksutil"
    15  	key "github.com/ipfs/go-ipfs/blocks/key"
    16  	tn "github.com/ipfs/go-ipfs/exchange/bitswap/testnet"
    17  	p2ptestutil "github.com/ipfs/go-ipfs/p2p/test/util"
    18  	mockrouting "github.com/ipfs/go-ipfs/routing/mock"
    19  	delay "github.com/ipfs/go-ipfs/thirdparty/delay"
    20  )
    21  
    22  // FIXME the tests are really sensitive to the network delay. fix them to work
    23  // well under varying conditions
    24  const kNetworkDelay = 0 * time.Millisecond
    25  
    26  func TestClose(t *testing.T) {
    27  	vnet := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay))
    28  	sesgen := NewTestSessionGenerator(vnet)
    29  	defer sesgen.Close()
    30  	bgen := blocksutil.NewBlockGenerator()
    31  
    32  	block := bgen.Next()
    33  	bitswap := sesgen.Next()
    34  
    35  	bitswap.Exchange.Close()
    36  	bitswap.Exchange.GetBlock(context.Background(), block.Key())
    37  }
    38  
    39  func TestProviderForKeyButNetworkCannotFind(t *testing.T) { // TODO revisit this
    40  
    41  	rs := mockrouting.NewServer()
    42  	net := tn.VirtualNetwork(rs, delay.Fixed(kNetworkDelay))
    43  	g := NewTestSessionGenerator(net)
    44  	defer g.Close()
    45  
    46  	block := blocks.NewBlock([]byte("block"))
    47  	pinfo := p2ptestutil.RandTestBogusIdentityOrFatal(t)
    48  	rs.Client(pinfo).Provide(context.Background(), block.Key()) // but not on network
    49  
    50  	solo := g.Next()
    51  	defer solo.Exchange.Close()
    52  
    53  	ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
    54  	defer cancel()
    55  	_, err := solo.Exchange.GetBlock(ctx, block.Key())
    56  
    57  	if err != context.DeadlineExceeded {
    58  		t.Fatal("Expected DeadlineExceeded error")
    59  	}
    60  }
    61  
    62  func TestGetBlockFromPeerAfterPeerAnnounces(t *testing.T) {
    63  
    64  	net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay))
    65  	block := blocks.NewBlock([]byte("block"))
    66  	g := NewTestSessionGenerator(net)
    67  	defer g.Close()
    68  
    69  	peers := g.Instances(2)
    70  	hasBlock := peers[0]
    71  	defer hasBlock.Exchange.Close()
    72  
    73  	if err := hasBlock.Exchange.HasBlock(context.Background(), block); err != nil {
    74  		t.Fatal(err)
    75  	}
    76  
    77  	wantsBlock := peers[1]
    78  	defer wantsBlock.Exchange.Close()
    79  
    80  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    81  	defer cancel()
    82  	received, err := wantsBlock.Exchange.GetBlock(ctx, block.Key())
    83  	if err != nil {
    84  		t.Log(err)
    85  		t.Fatal("Expected to succeed")
    86  	}
    87  
    88  	if !bytes.Equal(block.Data, received.Data) {
    89  		t.Fatal("Data doesn't match")
    90  	}
    91  }
    92  
    93  func TestLargeSwarm(t *testing.T) {
    94  	if testing.Short() {
    95  		t.SkipNow()
    96  	}
    97  	numInstances := 100
    98  	numBlocks := 2
    99  	if detectrace.WithRace() {
   100  		// when running with the race detector, 500 instances launches
   101  		// well over 8k goroutines. This hits a race detector limit.
   102  		numInstances = 100
   103  	} else if travis.IsRunning() {
   104  		numInstances = 200
   105  	} else {
   106  		t.Parallel()
   107  	}
   108  	PerformDistributionTest(t, numInstances, numBlocks)
   109  }
   110  
   111  func TestLargeFile(t *testing.T) {
   112  	if testing.Short() {
   113  		t.SkipNow()
   114  	}
   115  
   116  	if !travis.IsRunning() {
   117  		t.Parallel()
   118  	}
   119  
   120  	numInstances := 10
   121  	numBlocks := 100
   122  	PerformDistributionTest(t, numInstances, numBlocks)
   123  }
   124  
   125  func TestLargeFileNoRebroadcast(t *testing.T) {
   126  	rbd := rebroadcastDelay.Get()
   127  	rebroadcastDelay.Set(time.Hour * 24 * 365 * 10) // ten years should be long enough
   128  	if testing.Short() {
   129  		t.SkipNow()
   130  	}
   131  	numInstances := 10
   132  	numBlocks := 100
   133  	PerformDistributionTest(t, numInstances, numBlocks)
   134  	rebroadcastDelay.Set(rbd)
   135  }
   136  
   137  func TestLargeFileTwoPeers(t *testing.T) {
   138  	if testing.Short() {
   139  		t.SkipNow()
   140  	}
   141  	numInstances := 2
   142  	numBlocks := 100
   143  	PerformDistributionTest(t, numInstances, numBlocks)
   144  }
   145  
   146  func PerformDistributionTest(t *testing.T, numInstances, numBlocks int) {
   147  	ctx := context.Background()
   148  	if testing.Short() {
   149  		t.SkipNow()
   150  	}
   151  	net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay))
   152  	sg := NewTestSessionGenerator(net)
   153  	defer sg.Close()
   154  	bg := blocksutil.NewBlockGenerator()
   155  
   156  	instances := sg.Instances(numInstances)
   157  	blocks := bg.Blocks(numBlocks)
   158  
   159  	t.Log("Give the blocks to the first instance")
   160  
   161  	var blkeys []key.Key
   162  	first := instances[0]
   163  	for _, b := range blocks {
   164  		blkeys = append(blkeys, b.Key())
   165  		first.Exchange.HasBlock(ctx, b)
   166  	}
   167  
   168  	t.Log("Distribute!")
   169  
   170  	wg := sync.WaitGroup{}
   171  	for _, inst := range instances[1:] {
   172  		wg.Add(1)
   173  		go func(inst Instance) {
   174  			defer wg.Done()
   175  			outch, err := inst.Exchange.GetBlocks(ctx, blkeys)
   176  			if err != nil {
   177  				t.Fatal(err)
   178  			}
   179  			for _ = range outch {
   180  			}
   181  		}(inst)
   182  	}
   183  	wg.Wait()
   184  
   185  	t.Log("Verify!")
   186  
   187  	for _, inst := range instances {
   188  		for _, b := range blocks {
   189  			if _, err := inst.Blockstore().Get(b.Key()); err != nil {
   190  				t.Fatal(err)
   191  			}
   192  		}
   193  	}
   194  }
   195  
   196  func getOrFail(bitswap Instance, b *blocks.Block, t *testing.T, wg *sync.WaitGroup) {
   197  	if _, err := bitswap.Blockstore().Get(b.Key()); err != nil {
   198  		_, err := bitswap.Exchange.GetBlock(context.Background(), b.Key())
   199  		if err != nil {
   200  			t.Fatal(err)
   201  		}
   202  	}
   203  	wg.Done()
   204  }
   205  
   206  // TODO simplify this test. get to the _essence_!
   207  func TestSendToWantingPeer(t *testing.T) {
   208  	if testing.Short() {
   209  		t.SkipNow()
   210  	}
   211  
   212  	net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay))
   213  	sg := NewTestSessionGenerator(net)
   214  	defer sg.Close()
   215  	bg := blocksutil.NewBlockGenerator()
   216  
   217  	prev := rebroadcastDelay.Set(time.Second / 2)
   218  	defer func() { rebroadcastDelay.Set(prev) }()
   219  
   220  	peers := sg.Instances(2)
   221  	peerA := peers[0]
   222  	peerB := peers[1]
   223  
   224  	t.Logf("Session %v\n", peerA.Peer)
   225  	t.Logf("Session %v\n", peerB.Peer)
   226  
   227  	timeout := time.Second
   228  	waitTime := time.Second * 5
   229  
   230  	alpha := bg.Next()
   231  	// peerA requests and waits for block alpha
   232  	ctx, cancel := context.WithTimeout(context.Background(), waitTime)
   233  	defer cancel()
   234  	alphaPromise, err := peerA.Exchange.GetBlocks(ctx, []key.Key{alpha.Key()})
   235  	if err != nil {
   236  		t.Fatal(err)
   237  	}
   238  
   239  	// peerB announces to the network that he has block alpha
   240  	ctx, cancel = context.WithTimeout(context.Background(), timeout)
   241  	defer cancel()
   242  	err = peerB.Exchange.HasBlock(ctx, alpha)
   243  	if err != nil {
   244  		t.Fatal(err)
   245  	}
   246  
   247  	// At some point, peerA should get alpha (or timeout)
   248  	blkrecvd, ok := <-alphaPromise
   249  	if !ok {
   250  		t.Fatal("context timed out and broke promise channel!")
   251  	}
   252  
   253  	if blkrecvd.Key() != alpha.Key() {
   254  		t.Fatal("Wrong block!")
   255  	}
   256  
   257  }
   258  
   259  func TestBasicBitswap(t *testing.T) {
   260  	net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay))
   261  	sg := NewTestSessionGenerator(net)
   262  	defer sg.Close()
   263  	bg := blocksutil.NewBlockGenerator()
   264  
   265  	t.Log("Test a one node trying to get one block from another")
   266  
   267  	instances := sg.Instances(2)
   268  	blocks := bg.Blocks(1)
   269  	err := instances[0].Exchange.HasBlock(context.Background(), blocks[0])
   270  	if err != nil {
   271  		t.Fatal(err)
   272  	}
   273  
   274  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
   275  	defer cancel()
   276  	blk, err := instances[1].Exchange.GetBlock(ctx, blocks[0].Key())
   277  	if err != nil {
   278  		t.Fatal(err)
   279  	}
   280  
   281  	t.Log(blk)
   282  	for _, inst := range instances {
   283  		err := inst.Exchange.Close()
   284  		if err != nil {
   285  			t.Fatal(err)
   286  		}
   287  	}
   288  }