1 parent
b137f3b639
commit
13fc0bf720
3 files changed
+227
No files matched your search
@@ -55,6 +55,7 @@ $(WEAVETOOLS_EXPORT): tools/Dockerfile $(WEAVETOOLS_EXES)
|
||||
|
||||
# Add more directories in here as more tests are created
|
||||
tests:
|
||||
cd router; go test -tags netgo
|
||||
cd nameserver; go test -tags netgo
|
||||
|
||||
$(PUBLISH): publish_%:
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// No mocks are tested by this file.
|
||||
//
|
||||
// It supplies some mock implementations to other unit tests, and is
|
||||
// named "...test.go" so it is only compiled under `go test`.
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
wt "github.com/zettio/weave/testing"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Add to peers a connection from peers.ourself to p
|
||||
func (peers *Peers) AddTestConnection(p *Peer) {
|
||||
toPeer := NewPeer(p.Name, p.UID, 0)
|
||||
peers.FetchWithDefault(toPeer) // Has side-effect of incrementing refcount
|
||||
conn := newMockConnection(peers.ourself, toPeer)
|
||||
peers.ourself.addConnection(conn)
|
||||
peers.ourself.connectionEstablished(conn)
|
||||
}
|
||||
|
||||
// Add to (peers,p0) a connection from p1 to p2
|
||||
func (peers *Peers) AddTestRemoteConnection(p1, p2 *Peer) {
|
||||
fromName := p1.Name
|
||||
fromPeer := NewPeer(fromName, p1.UID, 0)
|
||||
fromPeer = peers.FetchWithDefault(fromPeer)
|
||||
toName := p2.Name
|
||||
toPeer := NewPeer(toName, p2.UID, 0)
|
||||
toPeer = peers.FetchWithDefault(toPeer)
|
||||
peers.ourself.addConnection(&RemoteConnection{fromPeer, toPeer, ""})
|
||||
}
|
||||
|
||||
func (peers *Peers) DeleteTestConnection(ourself *Peer, peer *Peer) {
|
||||
toName := peer.Name
|
||||
toPeer, _ := peers.Fetch(toName)
|
||||
toPeer.DecrementLocalRefCount()
|
||||
conn, _ := ourself.ConnectionTo(toName)
|
||||
ourself.deleteConnection(conn)
|
||||
}
|
||||
|
||||
// mockConnection used in testing is very similar to a
|
||||
// RemoteConnection, without the RemoteTCPAddr(). We are making it a
|
||||
// separate type in order to distinguish what is created by the test
|
||||
// from what is created by the real code.
|
||||
func newMockConnection(from, to *Peer) Connection {
|
||||
type mockConnection struct{ RemoteConnection }
|
||||
return &mockConnection{RemoteConnection{from, to, ""}}
|
||||
}
|
||||
|
||||
func checkEqualConns(t *testing.T, ourName PeerName, got, wanted map[PeerName]Connection) {
|
||||
checkConns := make(map[PeerName]bool)
|
||||
for _, conn := range wanted {
|
||||
checkConns[conn.Remote().Name] = true
|
||||
}
|
||||
for _, conn := range got {
|
||||
remoteName := conn.Remote().Name
|
||||
if _, found := checkConns[remoteName]; found {
|
||||
delete(checkConns, remoteName)
|
||||
} else {
|
||||
wt.Fatalf(t, "Unexpected connection from %s to %s", ourName, remoteName)
|
||||
}
|
||||
}
|
||||
if len(checkConns) > 0 {
|
||||
wt.Fatalf(t, "Expected connections not found: from %s to %v", ourName, checkConns)
|
||||
}
|
||||
}
|
||||
|
||||
// Get all the peers from a Peers in a slice
|
||||
func (peers *Peers) allPeers() []*Peer {
|
||||
res := make([]*Peer, 0)
|
||||
for _, peer := range peers.table {
|
||||
res = append(res, peer)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (peers *Peers) allPeersExcept(excludeName PeerName) []*Peer {
|
||||
res := peers.allPeers()
|
||||
for i, peer := range res {
|
||||
if peer.Name == excludeName {
|
||||
return append(res[:i], res[i+1:]...)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Check that the peers slice matches the wanted peers
|
||||
func checkPeerArray(t *testing.T, peers []*Peer, wantedPeers ...*Peer) {
|
||||
checkTopologyPeers(t, false, peers, wantedPeers...)
|
||||
}
|
||||
|
||||
// Check that the peers slice matches the wanted peers and optionally
|
||||
// all of their connections
|
||||
func checkTopologyPeers(t *testing.T, checkConns bool, peers []*Peer, wantedPeers ...*Peer) {
|
||||
check := make(map[PeerName]*Peer)
|
||||
for _, peer := range wantedPeers {
|
||||
check[peer.Name] = peer
|
||||
}
|
||||
for _, peer := range peers {
|
||||
name := peer.Name
|
||||
if wantedPeer, found := check[name]; found {
|
||||
if checkConns {
|
||||
checkEqualConns(t, name, peer.connections, wantedPeer.connections)
|
||||
}
|
||||
delete(check, name)
|
||||
} else {
|
||||
wt.Fatalf(t, "Unexpected peer: %s", name)
|
||||
}
|
||||
}
|
||||
if len(check) > 0 {
|
||||
wt.Fatalf(t, "Expected peers not found: %v", check)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
wt "github.com/zettio/weave/testing"
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TODO we should also test:
|
||||
//
|
||||
// - applying an incremental update, including the case where that
|
||||
// leads to an UnknownPeersError
|
||||
//
|
||||
// - the "improved update" calculation
|
||||
//
|
||||
// - non-gc of peers that are only referenced locally
|
||||
|
||||
func newNode(name PeerName) (*Peer, *Peers) {
|
||||
peer := NewPeer(name, 0, 0)
|
||||
peers := NewPeers(peer, func(*Peer) {})
|
||||
peers.FetchWithDefault(peer)
|
||||
return peer, peers
|
||||
}
|
||||
|
||||
// Check that ApplyUpdate copies the whole topology from peers
|
||||
func checkApplyUpdate(t *testing.T, peers *Peers) {
|
||||
dummyName, _ := PeerNameFromString("99:00:00:01:00:00")
|
||||
// We need a new node outside of the network, with a connection
|
||||
// into it.
|
||||
_, testBedPeers := newNode(dummyName)
|
||||
testBedPeers.AddTestConnection(peers.ourself)
|
||||
testBedPeers.ApplyUpdate(peers.EncodeAllPeers())
|
||||
|
||||
checkTopologyPeers(t, true, testBedPeers.allPeersExcept(dummyName), peers.allPeers()...)
|
||||
}
|
||||
|
||||
func TestPeersEncoding(t *testing.T) {
|
||||
const numNodes = 20
|
||||
const numIters = 1000
|
||||
var peer [numNodes]*Peer
|
||||
var ps [numNodes]*Peers
|
||||
for i := 0; i < numNodes; i++ {
|
||||
name, _ := PeerNameFromString(fmt.Sprintf("%02d:00:00:01:00:00", i))
|
||||
peer[i], ps[i] = newNode(name)
|
||||
}
|
||||
|
||||
conns := make([]struct{ from, to int }, 0)
|
||||
for i := 0; i < numIters; i++ {
|
||||
oper := rand.Intn(2)
|
||||
switch oper {
|
||||
case 0:
|
||||
from, to := rand.Intn(numNodes), rand.Intn(numNodes)
|
||||
if from != to {
|
||||
if _, found := peer[from].ConnectionTo(peer[to].Name); !found {
|
||||
ps[from].AddTestConnection(peer[to])
|
||||
conns = append(conns, struct{ from, to int }{from, to})
|
||||
checkApplyUpdate(t, ps[from])
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
if len(conns) > 0 {
|
||||
n := rand.Intn(len(conns))
|
||||
c := conns[n]
|
||||
ps[c.from].DeleteTestConnection(peer[c.from], peer[c.to])
|
||||
ps[c.from].GarbageCollect()
|
||||
checkApplyUpdate(t, ps[c.from])
|
||||
conns = append(conns[:n], conns[n+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPeersGarbageCollection(t *testing.T) {
|
||||
const (
|
||||
peer1NameString = "01:00:00:01:00:00"
|
||||
peer2NameString = "02:00:00:02:00:00"
|
||||
peer3NameString = "03:00:00:03:00:00"
|
||||
)
|
||||
var (
|
||||
peer1Name, _ = PeerNameFromString(peer1NameString)
|
||||
peer2Name, _ = PeerNameFromString(peer2NameString)
|
||||
peer3Name, _ = PeerNameFromString(peer3NameString)
|
||||
)
|
||||
|
||||
// Create some peers with some connections to each other
|
||||
p1, ps1 := newNode(peer1Name)
|
||||
p2, ps2 := newNode(peer2Name)
|
||||
p3, ps3 := newNode(peer3Name)
|
||||
ps1.AddTestConnection(p2)
|
||||
ps2.AddTestRemoteConnection(p1, p2)
|
||||
ps2.AddTestConnection(p1)
|
||||
ps2.AddTestConnection(p3)
|
||||
ps3.AddTestConnection(p1)
|
||||
ps1.AddTestConnection(p3)
|
||||
ps2.AddTestRemoteConnection(p1, p3)
|
||||
ps2.AddTestRemoteConnection(p3, p1)
|
||||
|
||||
// Every peer is referenced, so nothing should be dropped
|
||||
wt.AssertEmpty(t, ps1.GarbageCollect(), "peers removed")
|
||||
wt.AssertEmpty(t, ps2.GarbageCollect(), "peers removed")
|
||||
wt.AssertEmpty(t, ps3.GarbageCollect(), "peers removed")
|
||||
|
||||
// Drop the connection from 2 to 3, and 3 isn't garbage-collected
|
||||
// because 1 has a connection to 3
|
||||
ps2.DeleteTestConnection(p2, p3)
|
||||
wt.AssertEmpty(t, ps2.GarbageCollect(), "peers removed")
|
||||
|
||||
// Drop the connection from 1 to 3, and 3 will get removed by
|
||||
// garbage-collection
|
||||
ps1.DeleteTestConnection(p1, p3)
|
||||
checkPeerArray(t, ps1.GarbageCollect(), p3)
|
||||
}
|
||||
Reference in new issue
Block a user