These are needed to support vxlan encapsulation. In a vxlan packet, the only place we can straightforwardly hold the source and destination peers identifiers used by the weave router is in the 24-bit VNI (vxlan network identifier) field. This gives us 12 bits to indicate a peer. The resulting limit of 4096 peers on a weave network does not seem like a problem in the near future. But it does mean that decentralized allocation makes collisions fairly likely even in weave networks of sizes that are common today. Fortunately, the problem is much more tractable than IPAM because we can detect when collisions occur and take action to resolve them. TODO: We already notify the InterHost when a short id -> peer mapping changes, but we also need to flush any entries in the router MAC cache that might be affected.
114 lines
3.4 KiB
Go
114 lines
3.4 KiB
Go
// 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/weaveworks/weave/testing"
|
|
"testing"
|
|
)
|
|
|
|
// Add to peers a connection from peers.ourself to p
|
|
func (peers *Peers) AddTestConnection(p *Peer) {
|
|
summary := p.PeerSummary
|
|
summary.Version = 0
|
|
toPeer := NewPeerFromSummary(summary)
|
|
peers.FetchWithDefault(toPeer) // Has side-effect of incrementing refcount
|
|
conn := newMockConnection(peers.ourself.Peer, toPeer)
|
|
peers.ourself.addConnection(conn)
|
|
peers.ourself.connectionEstablished(conn)
|
|
}
|
|
|
|
// Add to peers a connection from p1 to p2
|
|
func (peers *Peers) AddTestRemoteConnection(p1, p2 *Peer) {
|
|
fromPeer := NewPeerFromSummary(p1.PeerSummary)
|
|
fromPeer = peers.FetchWithDefault(fromPeer)
|
|
toPeer := NewPeerFromSummary(p2.PeerSummary)
|
|
toPeer = peers.FetchWithDefault(toPeer)
|
|
peers.ourself.addConnection(&RemoteConnection{fromPeer, toPeer, "", false, false})
|
|
}
|
|
|
|
func (peers *Peers) DeleteTestConnection(p *Peer) {
|
|
toName := p.Name
|
|
toPeer, _ := peers.Fetch(toName)
|
|
peers.Dereference(toPeer)
|
|
conn, _ := peers.ourself.ConnectionTo(toName)
|
|
peers.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, "", false, false}}
|
|
}
|
|
|
|
func checkEqualConns(t *testing.T, ourName PeerName, got, wanted map[PeerName]Connection) {
|
|
checkConns := make(PeerNameSet)
|
|
for _, conn := range wanted {
|
|
checkConns[conn.Remote().Name] = void
|
|
}
|
|
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 {
|
|
var res []*Peer
|
|
for _, peer := range peers.byName {
|
|
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)
|
|
}
|
|
}
|