// +build !network
-
-package p2p
+package pex
import (
"fmt"
"github.com/stretchr/testify/assert"
"github.com/tendermint/tmlibs/log"
-)
-
-func createTempFileName(prefix string) string {
- f, err := ioutil.TempFile("", prefix)
- if err != nil {
- panic(err)
- }
- fname := f.Name()
- err = f.Close()
- if err != nil {
- panic(err)
- }
- return fname
-}
-
-func TestAddrBookSaveLoad(t *testing.T) {
- fname := createTempFileName("addrbook_test")
-
- // 0 addresses
- book := NewAddrBook(fname, true)
- book.SetLogger(log.TestingLogger())
- book.saveToFile(fname)
-
- book = NewAddrBook(fname, true)
- book.SetLogger(log.TestingLogger())
- book.loadFromFile(fname)
- assert.Zero(t, book.Size())
-
- // 100 addresses
- randAddrs := randNetAddressPairs(t, 100)
-
- for _, addrSrc := range randAddrs {
- book.AddAddress(addrSrc.addr, addrSrc.src)
- }
-
- assert.Equal(t, 100, book.Size())
- book.saveToFile(fname)
-
- book = NewAddrBook(fname, true)
- book.SetLogger(log.TestingLogger())
- book.loadFromFile(fname)
-
- assert.Equal(t, 100, book.Size())
-}
+ "github.com/bytom/p2p"
+)
func TestAddrBookLookup(t *testing.T) {
fname := createTempFileName("addrbook_test")
-
randAddrs := randNetAddressPairs(t, 100)
book := NewAddrBook(fname, true)
fname := createTempFileName("addrbook_test")
randAddrs := randNetAddressPairs(t, 100)
-
book := NewAddrBook(fname, true)
book.SetLogger(log.TestingLogger())
for _, addrSrc := range randAddrs {
}
}
- // TODO: do more testing :)
-
selection := book.GetSelection()
t.Logf("selection: %v", selection)
book.SetLogger(log.TestingLogger())
randAddrs := randNetAddressPairs(t, 100)
-
differentSrc := randIPv4Address(t)
for _, addrSrc := range randAddrs {
book.AddAddress(addrSrc.addr, addrSrc.src)
assert.Equal(t, 100, book.Size())
}
+func TestAddrBookRemoveAddress(t *testing.T) {
+ fname := createTempFileName("addrbook_test")
+ book := NewAddrBook(fname, true)
+ book.SetLogger(log.TestingLogger())
+
+ addr := randIPv4Address(t)
+ book.AddAddress(addr, addr)
+ assert.Equal(t, 1, book.Size())
+
+ book.RemoveAddress(addr)
+ assert.Equal(t, 0, book.Size())
+
+ nonExistingAddr := randIPv4Address(t)
+ book.RemoveAddress(nonExistingAddr)
+ assert.Equal(t, 0, book.Size())
+}
+
type netAddressPair struct {
- addr *NetAddress
- src *NetAddress
+ addr *p2p.NetAddress
+ src *p2p.NetAddress
+}
+
+func createTempFileName(prefix string) string {
+ f, err := ioutil.TempFile("", prefix)
+ if err != nil {
+ panic(err)
+ }
+ fname := f.Name()
+ if err = f.Close(); err != nil {
+ panic(err)
+ }
+ return fname
}
func randNetAddressPairs(t *testing.T, n int) []netAddressPair {
return randAddrs
}
-func randIPv4Address(t *testing.T) *NetAddress {
+func randIPv4Address(t *testing.T) *p2p.NetAddress {
for {
ip := fmt.Sprintf("%v.%v.%v.%v",
rand.Intn(254)+1,
rand.Intn(255),
)
port := rand.Intn(65535-1) + 1
- addr, err := NewNetAddressString(fmt.Sprintf("%v:%v", ip, port))
+ addr, err := p2p.NewNetAddressString(fmt.Sprintf("%v:%v", ip, port))
assert.Nil(t, err, "error generating rand network address")
if addr.Routable() {
return addr
}
}
}
-
-func TestAddrBookRemoveAddress(t *testing.T) {
- fname := createTempFileName("addrbook_test")
- book := NewAddrBook(fname, true)
- book.SetLogger(log.TestingLogger())
-
- addr := randIPv4Address(t)
- book.AddAddress(addr, addr)
- assert.Equal(t, 1, book.Size())
-
- book.RemoveAddress(addr)
- assert.Equal(t, 0, book.Size())
-
- nonExistingAddr := randIPv4Address(t)
- book.RemoveAddress(nonExistingAddr)
- assert.Equal(t, 0, book.Size())
-}
--- /dev/null
+package pex
+
+import (
+ "os"
+ "testing"
+)
+
+func TestFileStorage(t *testing.T) {
+ file := createTempFileName("TestFileStorage")
+ defer os.Remove(file)
+
+ a := NewAddrBook(file, true)
+ for i := 1; i < 256; i++ {
+ if err := a.addAddress(randIPv4Address(t), randIPv4Address(t)); err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ i := 0
+ for _, ka := range a.addrLookup {
+ i++
+ if i%7 != 0 {
+ continue
+ }
+ if err := a.moveToOld(ka); err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ if err := a.SaveToFile(); err != nil {
+ t.Fatal(err)
+ }
+
+ // load address book b from file
+ b := NewAddrBook(file, true)
+ if err := b.loadFromFile(); err != nil {
+ t.Fatal(err)
+ }
+
+ for key, want := range a.addrLookup {
+ got, ok := b.addrLookup[key]
+ if !ok {
+ t.Errorf("can't find %s in loaded address book", key)
+ }
+ if !want.Addr.Equals(got.Addr) || !want.Src.Equals(got.Src) {
+ t.Errorf("addrLookup check want %v but get %v", want, got)
+ }
+ }
+
+ for i, aBucket := range a.bucketsNew {
+ bBucket := b.bucketsNew[i]
+ for j, want := range aBucket {
+ got := bBucket[j]
+ if !want.Addr.Equals(got.Addr) {
+ t.Errorf("new bucket check want %v but get %v", want, got)
+ }
+ }
+ }
+
+ for i, aBucket := range a.bucketsOld {
+ bBucket := b.bucketsOld[i]
+ for j, want := range aBucket {
+ got := bBucket[j]
+ if !want.Addr.Equals(got.Addr) {
+ t.Errorf("old bucket check want %v but get %v", want, got)
+ }
+ }
+ }
+}
log.WithField("err", err).Warn("dialSeeds: fail to add address")
}
}
- r.book.SaveToFile()
+
+ if err := r.book.SaveToFile(); err != nil {
+ log.WithField("err", err).Warn("dialSeeds: fail to save address book")
+ }
perm := rand.Perm(len(netAddrs))
for i := 0; i < len(perm); i += 2 {
+++ /dev/null
-// +build !network
-
-package p2p
-
-import (
- "io/ioutil"
- "math/rand"
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- wire "github.com/tendermint/go-wire"
- cmn "github.com/tendermint/tmlibs/common"
- "github.com/tendermint/tmlibs/log"
-)
-
-var (
- sw *Switch
-)
-
-func TestPEXReactorBasic(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- dir, err := ioutil.TempDir("", "pex_reactor")
- require.Nil(err)
- defer os.RemoveAll(dir)
- book := NewAddrBook(dir+"addrbook.json", true)
- book.SetLogger(log.TestingLogger())
-
- r := NewPEXReactor(book, sw)
- r.SetLogger(log.TestingLogger())
-
- assert.NotNil(r)
- assert.NotEmpty(r.GetChannels())
-}
-
-func TestPEXReactorAddRemovePeer(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- dir, err := ioutil.TempDir("", "pex_reactor")
- require.Nil(err)
- defer os.RemoveAll(dir)
- book := NewAddrBook(dir+"addrbook.json", true)
- book.SetLogger(log.TestingLogger())
-
- r := NewPEXReactor(book, sw)
- r.SetLogger(log.TestingLogger())
-
- size := book.Size()
- peer := createRandomPeer(false)
-
- r.AddPeer(peer)
- assert.Equal(size+1, book.Size())
-
- r.RemovePeer(peer, "peer not available")
- assert.Equal(size+1, book.Size())
-
- outboundPeer := createRandomPeer(true)
-
- r.AddPeer(outboundPeer)
- assert.Equal(size+1, book.Size(), "outbound peers should not be added to the address book")
-
- r.RemovePeer(outboundPeer, "peer not available")
- assert.Equal(size+1, book.Size())
-}
-
-func TestPEXReactorRunning(t *testing.T) {
- require := require.New(t)
-
- N := 3
- switches := make([]*Switch, N)
-
- dir, err := ioutil.TempDir("", "pex_reactor")
- require.Nil(err)
- defer os.RemoveAll(dir)
- book := NewAddrBook(dir+"addrbook.json", false)
- book.SetLogger(log.TestingLogger())
-
- // create switches
- for i := 0; i < N; i++ {
- switches[i] = makeSwitch(config, i, "127.0.0.1", "123.123.123", func(i int, sw *Switch) *Switch {
- sw.SetLogger(log.TestingLogger().With("switch", i))
-
- r := NewPEXReactor(book, sw)
- r.SetLogger(log.TestingLogger())
- r.SetEnsurePeersPeriod(250 * time.Millisecond)
- sw.AddReactor("pex", r)
- return sw
- })
- }
-
- // fill the address book and add listeners
- for _, s := range switches {
- addr, _ := NewNetAddressString(s.NodeInfo().ListenAddr)
- book.AddAddress(addr, addr)
- l, _ := NewDefaultListener("tcp", s.NodeInfo().ListenAddr, true, log.TestingLogger())
- s.AddListener(l)
- }
-
- // start switches
- for _, s := range switches {
- _, err := s.Start() // start switch and reactors
- require.Nil(err)
- }
-
- time.Sleep(1 * time.Second)
-
- // check peers are connected after some time
- for _, s := range switches {
- outbound, inbound, _ := s.NumPeers()
- if outbound+inbound == 0 {
- t.Errorf("%v expected to be connected to at least one peer", s.NodeInfo().ListenAddr)
- }
- }
-
- // stop them
- for _, s := range switches {
- s.Stop()
- }
-}
-
-func TestPEXReactorReceive(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- dir, err := ioutil.TempDir("", "pex_reactor")
- require.Nil(err)
- defer os.RemoveAll(dir)
- book := NewAddrBook(dir+"addrbook.json", true)
- book.SetLogger(log.TestingLogger())
-
- r := NewPEXReactor(book, sw)
- r.SetLogger(log.TestingLogger())
-
- peer := createRandomPeer(false)
-
- size := book.Size()
- netAddr, _ := NewNetAddressString(peer.ListenAddr)
- addrs := []*NetAddress{netAddr}
- msg := wire.BinaryBytes(struct{ PexMessage }{&pexAddrsMessage{Addrs: addrs}})
- r.Receive(PexChannel, peer, msg)
- assert.Equal(size+1, book.Size())
-
- msg = wire.BinaryBytes(struct{ PexMessage }{&pexRequestMessage{}})
- r.Receive(PexChannel, peer, msg)
-}
-
-func TestPEXReactorAbuseFromPeer(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- dir, err := ioutil.TempDir("", "pex_reactor")
- require.Nil(err)
- defer os.RemoveAll(dir)
- book := NewAddrBook(dir+"addrbook.json", true)
- book.SetLogger(log.TestingLogger())
-
- r := NewPEXReactor(book, sw)
- r.SetLogger(log.TestingLogger())
- r.SetMaxMsgCountByPeer(5)
-
- peer := createRandomPeer(false)
-
- msg := wire.BinaryBytes(struct{ PexMessage }{&pexRequestMessage{}})
- for i := 0; i < 10; i++ {
- r.Receive(PexChannel, peer, msg)
- }
-
- assert.True(r.ReachedMaxMsgCountForPeer(peer.ListenAddr))
-}
-
-func createRandomPeer(outbound bool) *Peer {
- addr := cmn.Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256)
- netAddr, _ := NewNetAddressString(addr)
- p := &Peer{
- Key: cmn.RandStr(12),
- NodeInfo: &NodeInfo{
- ListenAddr: addr,
- },
- outbound: outbound,
- mconn: &MConnection{RemoteAddress: netAddr},
- }
- p.SetLogger(log.TestingLogger().With("peer", addr))
- return p
-}
//PanicOnAddPeerErr add peer error
var PanicOnAddPeerErr = false
+func CreateRandomPeer(outbound bool) *Peer {
+ _, netAddr := CreateRoutableAddr()
+ p := &Peer{
+ peerConn: &peerConn{
+ outbound: outbound,
+ },
+ NodeInfo: &NodeInfo{
+ ListenAddr: netAddr.DialString(),
+ },
+ mconn: &MConnection{},
+ }
+ return p
+}
+
+func CreateRoutableAddr() (addr string, netAddr *NetAddress) {
+ for {
+ var err error
+ addr = cmn.Fmt("%X@%v.%v.%v.%v:46656", cmn.RandBytes(20), cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256)
+ netAddr, err = NewNetAddressString(addr)
+ if err != nil {
+ panic(err)
+ }
+ if netAddr.Routable() {
+ break
+ }
+ }
+ return
+}
+
// MakeConnectedSwitches switches connected via arbitrary net.Conn; useful for testing
// Returns n switches, connected according to the connect func.
// If connect==Connect2Switches, the switches will be fully connected.
func MakeConnectedSwitches(cfg *cfg.P2PConfig, n int, initSwitch func(int, *Switch) *Switch, connect func([]*Switch, int, int)) []*Switch {
switches := make([]*Switch, n)
for i := 0; i < n; i++ {
- switches[i] = makeSwitch(cfg, i, "testing", "123.123.123", initSwitch)
+ switches[i] = MakeSwitch(cfg, i, "testing", "123.123.123", initSwitch)
}
if err := startSwitches(switches); err != nil {
return nil
}
-func makeSwitch(cfg *cfg.P2PConfig, i int, network, version string, initSwitch func(int, *Switch) *Switch) *Switch {
+func MakeSwitch(cfg *cfg.P2PConfig, i int, network, version string, initSwitch func(int, *Switch) *Switch) *Switch {
privKey := crypto.GenPrivKeyEd25519()
// new switch, add reactors
// TODO: let the config be passed in?