github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/routing/kbucket/table_test.go (about)

     1  package kbucket
     2  
     3  import (
     4  	"math/rand"
     5  	"testing"
     6  	"time"
     7  
     8  	tu "github.com/ipfs/go-ipfs/util/testutil"
     9  
    10  	peer "github.com/ipfs/go-ipfs/p2p/peer"
    11  )
    12  
    13  // Test basic features of the bucket struct
    14  func TestBucket(t *testing.T) {
    15  	b := newBucket()
    16  
    17  	peers := make([]peer.ID, 100)
    18  	for i := 0; i < 100; i++ {
    19  		peers[i] = tu.RandPeerIDFatal(t)
    20  		b.PushFront(peers[i])
    21  	}
    22  
    23  	local := tu.RandPeerIDFatal(t)
    24  	localID := ConvertPeerID(local)
    25  
    26  	i := rand.Intn(len(peers))
    27  	if !b.Has(peers[i]) {
    28  		t.Errorf("Failed to find peer: %v", peers[i])
    29  	}
    30  
    31  	spl := b.Split(0, ConvertPeerID(local))
    32  	llist := b.list
    33  	for e := llist.Front(); e != nil; e = e.Next() {
    34  		p := ConvertPeerID(e.Value.(peer.ID))
    35  		cpl := commonPrefixLen(p, localID)
    36  		if cpl > 0 {
    37  			t.Fatalf("Split failed. found id with cpl > 0 in 0 bucket")
    38  		}
    39  	}
    40  
    41  	rlist := spl.list
    42  	for e := rlist.Front(); e != nil; e = e.Next() {
    43  		p := ConvertPeerID(e.Value.(peer.ID))
    44  		cpl := commonPrefixLen(p, localID)
    45  		if cpl == 0 {
    46  			t.Fatalf("Split failed. found id with cpl == 0 in non 0 bucket")
    47  		}
    48  	}
    49  }
    50  
    51  // Right now, this just makes sure that it doesnt hang or crash
    52  func TestTableUpdate(t *testing.T) {
    53  	local := tu.RandPeerIDFatal(t)
    54  	m := peer.NewMetrics()
    55  	rt := NewRoutingTable(10, ConvertPeerID(local), time.Hour, m)
    56  
    57  	peers := make([]peer.ID, 100)
    58  	for i := 0; i < 100; i++ {
    59  		peers[i] = tu.RandPeerIDFatal(t)
    60  	}
    61  
    62  	// Testing Update
    63  	for i := 0; i < 10000; i++ {
    64  		rt.Update(peers[rand.Intn(len(peers))])
    65  	}
    66  
    67  	for i := 0; i < 100; i++ {
    68  		id := ConvertPeerID(tu.RandPeerIDFatal(t))
    69  		ret := rt.NearestPeers(id, 5)
    70  		if len(ret) == 0 {
    71  			t.Fatal("Failed to find node near ID.")
    72  		}
    73  	}
    74  }
    75  
    76  func TestTableFind(t *testing.T) {
    77  	local := tu.RandPeerIDFatal(t)
    78  	m := peer.NewMetrics()
    79  	rt := NewRoutingTable(10, ConvertPeerID(local), time.Hour, m)
    80  
    81  	peers := make([]peer.ID, 100)
    82  	for i := 0; i < 5; i++ {
    83  		peers[i] = tu.RandPeerIDFatal(t)
    84  		rt.Update(peers[i])
    85  	}
    86  
    87  	t.Logf("Searching for peer: '%s'", peers[2])
    88  	found := rt.NearestPeer(ConvertPeerID(peers[2]))
    89  	if !(found == peers[2]) {
    90  		t.Fatalf("Failed to lookup known node...")
    91  	}
    92  }
    93  
    94  func TestTableFindMultiple(t *testing.T) {
    95  	local := tu.RandPeerIDFatal(t)
    96  	m := peer.NewMetrics()
    97  	rt := NewRoutingTable(20, ConvertPeerID(local), time.Hour, m)
    98  
    99  	peers := make([]peer.ID, 100)
   100  	for i := 0; i < 18; i++ {
   101  		peers[i] = tu.RandPeerIDFatal(t)
   102  		rt.Update(peers[i])
   103  	}
   104  
   105  	t.Logf("Searching for peer: '%s'", peers[2])
   106  	found := rt.NearestPeers(ConvertPeerID(peers[2]), 15)
   107  	if len(found) != 15 {
   108  		t.Fatalf("Got back different number of peers than we expected.")
   109  	}
   110  }
   111  
   112  // Looks for race conditions in table operations. For a more 'certain'
   113  // test, increase the loop counter from 1000 to a much higher number
   114  // and set GOMAXPROCS above 1
   115  func TestTableMultithreaded(t *testing.T) {
   116  	local := peer.ID("localPeer")
   117  	m := peer.NewMetrics()
   118  	tab := NewRoutingTable(20, ConvertPeerID(local), time.Hour, m)
   119  	var peers []peer.ID
   120  	for i := 0; i < 500; i++ {
   121  		peers = append(peers, tu.RandPeerIDFatal(t))
   122  	}
   123  
   124  	done := make(chan struct{})
   125  	go func() {
   126  		for i := 0; i < 1000; i++ {
   127  			n := rand.Intn(len(peers))
   128  			tab.Update(peers[n])
   129  		}
   130  		done <- struct{}{}
   131  	}()
   132  
   133  	go func() {
   134  		for i := 0; i < 1000; i++ {
   135  			n := rand.Intn(len(peers))
   136  			tab.Update(peers[n])
   137  		}
   138  		done <- struct{}{}
   139  	}()
   140  
   141  	go func() {
   142  		for i := 0; i < 1000; i++ {
   143  			n := rand.Intn(len(peers))
   144  			tab.Find(peers[n])
   145  		}
   146  		done <- struct{}{}
   147  	}()
   148  	<-done
   149  	<-done
   150  	<-done
   151  }
   152  
   153  func BenchmarkUpdates(b *testing.B) {
   154  	b.StopTimer()
   155  	local := ConvertKey("localKey")
   156  	m := peer.NewMetrics()
   157  	tab := NewRoutingTable(20, local, time.Hour, m)
   158  
   159  	var peers []peer.ID
   160  	for i := 0; i < b.N; i++ {
   161  		peers = append(peers, tu.RandPeerIDFatal(b))
   162  	}
   163  
   164  	b.StartTimer()
   165  	for i := 0; i < b.N; i++ {
   166  		tab.Update(peers[i])
   167  	}
   168  }
   169  
   170  func BenchmarkFinds(b *testing.B) {
   171  	b.StopTimer()
   172  	local := ConvertKey("localKey")
   173  	m := peer.NewMetrics()
   174  	tab := NewRoutingTable(20, local, time.Hour, m)
   175  
   176  	var peers []peer.ID
   177  	for i := 0; i < b.N; i++ {
   178  		peers = append(peers, tu.RandPeerIDFatal(b))
   179  		tab.Update(peers[i])
   180  	}
   181  
   182  	b.StartTimer()
   183  	for i := 0; i < b.N; i++ {
   184  		tab.Find(peers[i])
   185  	}
   186  }