func TestTombstoneDeletion(t *testing.T) { oldNow := now defer func() { now = oldNow }() now = func() int64 { return 1234 } peername, err := router.PeerNameFromString("00:00:00:02:00:00") require.Nil(t, err) nameserver := New(peername, nil, "") err = nameserver.AddEntry("hostname", "containerid", peername, address.Address(0)) require.Nil(t, err) require.Equal(t, []address.Address{0}, nameserver.Lookup("hostname")) nameserver.deleteTombstones() require.Equal(t, []address.Address{0}, nameserver.Lookup("hostname")) err = nameserver.Delete("hostname", "containerid", "", address.Address(0)) require.Nil(t, err) require.Equal(t, []address.Address{}, nameserver.Lookup("hostname")) require.Equal(t, Entries{{ ContainerID: "containerid", Origin: peername, Addr: address.Address(0), Hostname: "hostname", Version: 1, Tombstone: 1234, }}, nameserver.entries) now = func() int64 { return 1234 + int64(tombstoneTimeout/time.Second) + 1 } nameserver.deleteTombstones() require.Equal(t, Entries{}, nameserver.entries) }
func ExpectMessage(alloc *Allocator, dst string, msgType byte, buf []byte) { m := alloc.gossip.(*mockGossipComms) dstPeerName, _ := router.PeerNameFromString(dst) m.Lock() m.messages = append(m.messages, mockMessage{dstPeerName, msgType, buf}) m.Unlock() }
// Lookup a PeerName by nickname or stringified PeerName. We can't // call into the router for this because we are interested in peers // that have gone away but are still in the ring, which is why we // maintain our own nicknames map. func (alloc *Allocator) lookupPeername(name string) (router.PeerName, error) { for peername, nickname := range alloc.nicknames { if nickname == name { return peername, nil } } return router.PeerNameFromString(name) }
func startServer(t *testing.T) (*DNSServer, *Nameserver, int, int) { peername, err := router.PeerNameFromString("00:00:00:02:00:00") require.Nil(t, err) nameserver := New(peername, nil, nil, "") dnsserver, err := NewDNSServer(nameserver, "weave.local.", "0.0.0.0:0", 30, 5*time.Second) require.Nil(t, err) udpPort := dnsserver.servers[0].PacketConn.LocalAddr().(*net.UDPAddr).Port tcpPort := dnsserver.servers[1].Listener.Addr().(*net.TCPAddr).Port go dnsserver.ActivateAndServe() return dnsserver, nameserver, udpPort, tcpPort }
func TestTruncation(t *testing.T) { //common.SetLogLevel("debug") peername, err := router.PeerNameFromString("00:00:00:02:00:00") require.Nil(t, err) nameserver := New(peername, nil, nil, "") dnsserver, err := NewDNSServer(nameserver, "weave.local.", "0.0.0.0:0", 30, 5*time.Second) require.Nil(t, err) udpPort := dnsserver.servers[0].PacketConn.LocalAddr().(*net.UDPAddr).Port tcpPort := dnsserver.servers[1].Listener.Addr().(*net.TCPAddr).Port go dnsserver.ActivateAndServe() defer dnsserver.Stop() // Add 100 mappings to nameserver addrs := []address.Address{} for i := address.Address(0); i < 100; i++ { addrs = append(addrs, i) nameserver.AddEntry("foo.weave.local.", "", peername, i) } doRequest := func(client *dns.Client, request *dns.Msg, port int) *dns.Msg { request.SetQuestion("foo.weave.local.", dns.TypeA) response, _, err := client.Exchange(request, fmt.Sprintf("127.0.0.1:%d", port)) require.Nil(t, err) return response } // do a udp query, ensure we get a truncated response { udpClient := dns.Client{Net: "udp", UDPSize: minUDPSize} response := doRequest(&udpClient, &dns.Msg{}, udpPort) require.Nil(t, err) require.True(t, response.MsgHdr.Truncated) require.True(t, len(response.Answer) < 100) } // do a udp query with big size, ensure we don't get a truncated response { udpClient := dns.Client{Net: "udp", UDPSize: 65535} request := &dns.Msg{} request.SetEdns0(65535, false) response := doRequest(&udpClient, request, udpPort) require.False(t, response.MsgHdr.Truncated) require.Equal(t, len(response.Answer), 100) } // do a tcp query, ensure we don't get a truncated response { tcpClient := dns.Client{Net: "tcp"} response := doRequest(&tcpClient, &dns.Msg{}, tcpPort) require.False(t, response.MsgHdr.Truncated) require.Equal(t, len(response.Answer), 100) } }
func startServer(t *testing.T, upstream *dns.ClientConfig) (*DNSServer, *Nameserver, int, int) { peername, err := router.PeerNameFromString("00:00:00:02:00:00") require.Nil(t, err) nameserver := New(peername, "", func(router.PeerName) bool { return true }) dnsserver, err := NewDNSServer(nameserver, "weave.local.", "0.0.0.0:0", "", 30, 5*time.Second) require.Nil(t, err) udpPort := dnsserver.servers[0].PacketConn.LocalAddr().(*net.UDPAddr).Port tcpPort := dnsserver.servers[1].Listener.Addr().(*net.TCPAddr).Port if upstream != nil { dnsserver.upstream = upstream } go dnsserver.ActivateAndServe() return dnsserver, nameserver, udpPort, tcpPort }
func makeNetwork(size int) ([]*Nameserver, *gossip.TestRouter) { gossipRouter := gossip.NewTestRouter(0.0) nameservers := make([]*Nameserver, size) for i := 0; i < size; i++ { name, _ := router.PeerNameFromString(fmt.Sprintf("%02d:00:00:02:00:00", i)) nameserver := New(name, nil, "") nameserver.SetGossip(gossipRouter.Connect(nameserver.ourName, nameserver)) nameserver.Start() nameservers[i] = nameserver } return nameservers, gossipRouter }
func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, address.Range) { peername, err := router.PeerNameFromString(name) if err != nil { panic(err) } _, cidr, err := address.ParseCIDR(cidrStr) if err != nil { panic(err) } alloc := NewAllocator(peername, router.PeerUID(rand.Int63()), "nick-"+name, cidr.Range(), quorum, func(router.PeerName) bool { return true }) return alloc, cidr.HostRange() }
func TestContainerAndPeerDeath(t *testing.T) { peername, err := router.PeerNameFromString("00:00:00:02:00:00") require.Nil(t, err) nameserver := New(peername, nil, "") err = nameserver.AddEntry("hostname", "containerid", peername, address.Address(0)) require.Nil(t, err) require.Equal(t, []address.Address{0}, nameserver.Lookup("hostname")) nameserver.ContainerDied("containerid") require.Equal(t, []address.Address{}, nameserver.Lookup("hostname")) err = nameserver.AddEntry("hostname", "containerid", peername, address.Address(0)) require.Nil(t, err) require.Equal(t, []address.Address{0}, nameserver.Lookup("hostname")) nameserver.PeerGone(&router.Peer{Name: peername}) require.Equal(t, []address.Address{}, nameserver.Lookup("hostname")) }
func TestFuzzRingHard(t *testing.T) { //common.InitDefaultLogging(true) var ( numPeers = 100 iterations = 3000 peers []router.PeerName rings []*Ring nextPeerID = 0 ) addPeer := func() { peer, _ := router.PeerNameFromString(fmt.Sprintf("%02d:%02d:00:00:00:00", nextPeerID/10, nextPeerID%10)) common.Debug.Printf("%s: Adding peer", peer) nextPeerID++ peers = append(peers, peer) rings = append(rings, New(start, end, peer)) } for i := 0; i < numPeers; i++ { addPeer() } rings[0].ClaimItAll() randomPeer := func(exclude int) (int, router.PeerName, *Ring) { var peerIndex int if exclude >= 0 { peerIndex = rand.Intn(len(peers) - 1) if peerIndex == exclude { peerIndex++ } } else { peerIndex = rand.Intn(len(peers)) } return peerIndex, peers[peerIndex], rings[peerIndex] } // Keep a map of index -> ranges, as these are a little expensive to // calculate for every ring on every iteration. var theRanges = make(map[int][]address.Range) theRanges[0] = rings[0].OwnedRanges() addOrRmPeer := func() { if len(peers) < numPeers { addPeer() return } peerIndex, peername, _ := randomPeer(-1) // Remove peer from our state peers = append(peers[:peerIndex], peers[peerIndex+1:]...) rings = append(rings[:peerIndex], rings[peerIndex+1:]...) theRanges = make(map[int][]address.Range) // Transfer the space for this peer on another peer, but not this one _, otherPeername, otherRing := randomPeer(peerIndex) // We need to be in a ~converged ring to rmpeer for _, ring := range rings { require.NoError(t, otherRing.Merge(*ring)) } common.Debug.Printf("%s: transferring from peer %s", otherPeername, peername) otherRing.Transfer(peername, peername) // And now tell everyone about the transfer - rmpeer is // not partition safe for i, ring := range rings { require.NoError(t, ring.Merge(*otherRing)) theRanges[i] = ring.OwnedRanges() } } doGrantOrGossip := func() { var ringsWithRanges = make([]int, 0, len(rings)) for index, ranges := range theRanges { if len(ranges) > 0 { ringsWithRanges = append(ringsWithRanges, index) } } if len(ringsWithRanges) > 0 { // Produce a random split in a random owned range, given to a random peer indexWithRanges := ringsWithRanges[rand.Intn(len(ringsWithRanges))] ownedRanges := theRanges[indexWithRanges] ring := rings[indexWithRanges] rangeToSplit := ownedRanges[rand.Intn(len(ownedRanges))] size := address.Subtract(rangeToSplit.End, rangeToSplit.Start) ipInRange := address.Add(rangeToSplit.Start, address.Offset(rand.Intn(int(size)))) _, peerToGiveTo, _ := randomPeer(-1) common.Debug.Printf("%s: Granting [%v, %v) to %s", ring.Peer, ipInRange, rangeToSplit.End, peerToGiveTo) ring.GrantRangeToHost(ipInRange, rangeToSplit.End, peerToGiveTo) // Now 'gossip' this to a random host (note, note could be same host as above) otherIndex, _, otherRing := randomPeer(-1) common.Debug.Printf("%s: 'Gossiping' to %s", ring.Peer, otherRing.Peer) require.NoError(t, otherRing.Merge(*ring)) theRanges[indexWithRanges] = ring.OwnedRanges() theRanges[otherIndex] = otherRing.OwnedRanges() return } // No rings think they own anything (as gossip might be behind) // We're going to pick a random host (which has entries) and gossip // it to a random host (which may or may not have entries). var ringsWithEntries = make([]*Ring, 0, len(rings)) for _, ring := range rings { if len(ring.Entries) > 0 { ringsWithEntries = append(ringsWithEntries, ring) } } ring1 := ringsWithEntries[rand.Intn(len(ringsWithEntries))] ring2index, _, ring2 := randomPeer(-1) common.Debug.Printf("%s: 'Gossiping' to %s", ring1.Peer, ring2.Peer) require.NoError(t, ring2.Merge(*ring1)) theRanges[ring2index] = ring2.OwnedRanges() } for i := 0; i < iterations; i++ { // about 1 in 10 times, rmpeer or add host n := rand.Intn(10) switch { case n < 1: addOrRmPeer() default: doGrantOrGossip() } } }
func TestFuzzRing(t *testing.T) { var ( numPeers = 25 iterations = 1000 ) peers := make([]router.PeerName, numPeers) for i := 0; i < numPeers; i++ { peer, _ := router.PeerNameFromString(fmt.Sprintf("%02d:00:00:00:02:00", i)) peers[i] = peer } // Make a valid, random ring makeGoodRandomRing := func() *Ring { addressSpace := end - start numTokens := rand.Intn(int(addressSpace)) tokenMap := make(map[address.Address]bool) for i := 0; i < numTokens; i++ { tokenMap[address.Address(rand.Intn(int(addressSpace)))] = true } var tokens []address.Address for token := range tokenMap { tokens = append(tokens, token) } sort.Sort(addressSlice(tokens)) peer := peers[rand.Intn(len(peers))] ring := New(start, end, peer) for _, token := range tokens { peer = peers[rand.Intn(len(peers))] ring.Entries = append(ring.Entries, &entry{Token: start + token, Peer: peer}) } ring.assertInvariants() return ring } for i := 0; i < iterations; i++ { // make 2 random rings ring1 := makeGoodRandomRing() ring2 := makeGoodRandomRing() // Merge them - this might fail, we don't care // We just want to make sure it doesn't panic ring1.Merge(*ring2) // Check whats left still passes assertions ring1.assertInvariants() ring2.assertInvariants() } // Make an invalid, random ring makeBadRandomRing := func() *Ring { addressSpace := end - start numTokens := rand.Intn(int(addressSpace)) tokens := make([]address.Address, numTokens) for i := 0; i < numTokens; i++ { tokens[i] = address.Address(rand.Intn(int(addressSpace))) } peer := peers[rand.Intn(len(peers))] ring := New(start, end, peer) for _, token := range tokens { peer = peers[rand.Intn(len(peers))] ring.Entries = append(ring.Entries, &entry{Token: start + token, Peer: peer}) } return ring } for i := 0; i < iterations; i++ { // make 2 random rings ring1 := makeGoodRandomRing() ring2 := makeBadRandomRing() // Merge them - this might fail, we don't care // We just want to make sure it doesn't panic ring1.Merge(*ring2) // Check whats left still passes assertions ring1.assertInvariants() } }
import ( "bytes" "fmt" "math/rand" "sort" "testing" "github.com/stretchr/testify/require" "github.com/weaveworks/weave/common" "github.com/weaveworks/weave/ipam/address" "github.com/weaveworks/weave/router" ) var ( peer1name, _ = router.PeerNameFromString("01:00:00:00:02:00") peer2name, _ = router.PeerNameFromString("02:00:00:00:02:00") peer3name, _ = router.PeerNameFromString("03:00:00:00:02:00") start, end = ParseIP("10.0.0.0"), ParseIP("10.0.0.255") dot10, dot245 = ParseIP("10.0.0.10"), ParseIP("10.0.0.245") dot250 = ParseIP("10.0.0.250") middle = ParseIP("10.0.0.128") ) func ParseIP(s string) address.Address { addr, _ := address.ParseIP(s) return addr } func TestInvariants(t *testing.T) {