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

     1  package decision
     2  
     3  import (
     4  	"math"
     5  	"math/rand"
     6  	"sort"
     7  	"strings"
     8  	"testing"
     9  
    10  	key "github.com/ipfs/go-ipfs/blocks/key"
    11  	"github.com/ipfs/go-ipfs/exchange/bitswap/wantlist"
    12  	"github.com/ipfs/go-ipfs/util/testutil"
    13  )
    14  
    15  func TestPushPop(t *testing.T) {
    16  	prq := newPRQ()
    17  	partner := testutil.RandPeerIDFatal(t)
    18  	alphabet := strings.Split("abcdefghijklmnopqrstuvwxyz", "")
    19  	vowels := strings.Split("aeiou", "")
    20  	consonants := func() []string {
    21  		var out []string
    22  		for _, letter := range alphabet {
    23  			skip := false
    24  			for _, vowel := range vowels {
    25  				if letter == vowel {
    26  					skip = true
    27  				}
    28  			}
    29  			if !skip {
    30  				out = append(out, letter)
    31  			}
    32  		}
    33  		return out
    34  	}()
    35  	sort.Strings(alphabet)
    36  	sort.Strings(vowels)
    37  	sort.Strings(consonants)
    38  
    39  	// add a bunch of blocks. cancel some. drain the queue. the queue should only have the kept entries
    40  
    41  	for _, index := range rand.Perm(len(alphabet)) { // add blocks for all letters
    42  		letter := alphabet[index]
    43  		t.Log(partner.String())
    44  		prq.Push(wantlist.Entry{Key: key.Key(letter), Priority: math.MaxInt32 - index}, partner)
    45  	}
    46  	for _, consonant := range consonants {
    47  		prq.Remove(key.Key(consonant), partner)
    48  	}
    49  
    50  	var out []string
    51  	for {
    52  		received := prq.Pop()
    53  		if received == nil {
    54  			break
    55  		}
    56  
    57  		out = append(out, string(received.Entry.Key))
    58  	}
    59  
    60  	// Entries popped should already be in correct order
    61  	for i, expected := range vowels {
    62  		if out[i] != expected {
    63  			t.Fatal("received", out[i], "expected", expected)
    64  		}
    65  	}
    66  }
    67  
    68  // This test checks that peers wont starve out other peers
    69  func TestPeerRepeats(t *testing.T) {
    70  	prq := newPRQ()
    71  	a := testutil.RandPeerIDFatal(t)
    72  	b := testutil.RandPeerIDFatal(t)
    73  	c := testutil.RandPeerIDFatal(t)
    74  	d := testutil.RandPeerIDFatal(t)
    75  
    76  	// Have each push some blocks
    77  
    78  	for i := 0; i < 5; i++ {
    79  		prq.Push(wantlist.Entry{Key: key.Key(i)}, a)
    80  		prq.Push(wantlist.Entry{Key: key.Key(i)}, b)
    81  		prq.Push(wantlist.Entry{Key: key.Key(i)}, c)
    82  		prq.Push(wantlist.Entry{Key: key.Key(i)}, d)
    83  	}
    84  
    85  	// now, pop off four entries, there should be one from each
    86  	var targets []string
    87  	var tasks []*peerRequestTask
    88  	for i := 0; i < 4; i++ {
    89  		t := prq.Pop()
    90  		targets = append(targets, t.Target.Pretty())
    91  		tasks = append(tasks, t)
    92  	}
    93  
    94  	expected := []string{a.Pretty(), b.Pretty(), c.Pretty(), d.Pretty()}
    95  	sort.Strings(expected)
    96  	sort.Strings(targets)
    97  
    98  	t.Log(targets)
    99  	t.Log(expected)
   100  	for i, s := range targets {
   101  		if expected[i] != s {
   102  			t.Fatal("unexpected peer", s, expected[i])
   103  		}
   104  	}
   105  
   106  	// Now, if one of the tasks gets finished, the next task off the queue should
   107  	// be for the same peer
   108  	for blockI := 0; blockI < 4; blockI++ {
   109  		for i := 0; i < 4; i++ {
   110  			// its okay to mark the same task done multiple times here (JUST FOR TESTING)
   111  			tasks[i].Done()
   112  
   113  			ntask := prq.Pop()
   114  			if ntask.Target != tasks[i].Target {
   115  				t.Fatal("Expected task from peer with lowest active count")
   116  			}
   117  		}
   118  	}
   119  }