From f0108f7dd1e39cbfc26a838ebe2108139c5cea91 Mon Sep 17 00:00:00 2001
From: Oliver Herms <oliver.herms@exaring.de>
Date: Sun, 24 Jun 2018 15:10:28 +0200
Subject: [PATCH] Adding tests

---
 protocols/bgp/server/fake_conn.go       | 52 ++++++++++++++
 protocols/bgp/server/fsm_established.go |  6 ++
 protocols/bgp/server/fsm_test.go        | 95 +++++++++++++++++++++++++
 routingtable/client_interface.go        |  1 +
 routingtable/locRIB/loc_rib.go          |  4 ++
 5 files changed, 158 insertions(+)
 create mode 100644 protocols/bgp/server/fake_conn.go
 create mode 100644 protocols/bgp/server/fsm_test.go

diff --git a/protocols/bgp/server/fake_conn.go b/protocols/bgp/server/fake_conn.go
new file mode 100644
index 00000000..4537da5a
--- /dev/null
+++ b/protocols/bgp/server/fake_conn.go
@@ -0,0 +1,52 @@
+package server
+
+import (
+	"net"
+	"time"
+)
+
+type fakeConn struct {
+}
+
+type fakeAddr struct {
+}
+
+func (f fakeAddr) Network() string {
+	return ""
+}
+
+func (f fakeAddr) String() string {
+	return "169.254.100.100:179"
+}
+
+func (f fakeConn) Read(b []byte) (n int, err error) {
+	return 0, nil
+}
+
+func (f fakeConn) Write(b []byte) (n int, err error) {
+	return len(b), nil
+}
+
+func (f fakeConn) Close() error {
+	return nil
+}
+
+func (f fakeConn) LocalAddr() net.Addr {
+	return fakeAddr{}
+}
+
+func (f fakeConn) RemoteAddr() net.Addr {
+	return fakeAddr{}
+}
+
+func (f fakeConn) SetDeadline(t time.Time) error {
+	return nil
+}
+
+func (f fakeConn) SetReadDeadline(t time.Time) error {
+	return nil
+}
+
+func (f fakeConn) SetWriteDeadline(t time.Time) error {
+	return nil
+}
diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go
index 80ff7fa7..8462b2c5 100644
--- a/protocols/bgp/server/fsm_established.go
+++ b/protocols/bgp/server/fsm_established.go
@@ -154,8 +154,10 @@ func (s *establishedState) keepaliveTimerExpired() (state, string) {
 }
 
 func (s *establishedState) msgReceived(data []byte) (state, string) {
+	fmt.Printf("Processing MSG\n")
 	msg, err := packet.Decode(bytes.NewBuffer(data))
 	if err != nil {
+		fmt.Printf("Decode failure: %v\n", err)
 		switch bgperr := err.(type) {
 		case packet.BGPError:
 			s.fsm.sendNotification(bgperr.ErrorCode, bgperr.ErrorSubCode)
@@ -165,6 +167,7 @@ func (s *establishedState) msgReceived(data []byte) (state, string) {
 		s.fsm.connectRetryCounter++
 		return newIdleState(s.fsm), "Failed to decode BGP message"
 	}
+	fmt.Printf("Msg type: %d\n", msg.Header.Type)
 	switch msg.Header.Type {
 	case packet.NotificationMsg:
 		return s.notification()
@@ -191,9 +194,12 @@ func (s *establishedState) update(msg *packet.BGPMessage) (state, string) {
 	}
 
 	u := msg.Body.(*packet.BGPUpdate)
+	fmt.Printf("Processing withdraws\n")
 	s.withdraws(u)
+	fmt.Printf("Processing advertisements\n")
 	s.updates(u)
 
+	fmt.Printf("update done\n")
 	return newEstablishedState(s.fsm), s.fsm.reason
 }
 
diff --git a/protocols/bgp/server/fsm_test.go b/protocols/bgp/server/fsm_test.go
new file mode 100644
index 00000000..eeab5a60
--- /dev/null
+++ b/protocols/bgp/server/fsm_test.go
@@ -0,0 +1,95 @@
+package server
+
+import (
+	"fmt"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/bio-routing/bio-rd/routingtable/filter"
+
+	"net"
+
+	"github.com/bio-routing/bio-rd/routingtable/locRIB"
+)
+
+func TestFSM(t *testing.T) {
+	fsmA := newFSM2(&peer{
+		addr:         net.ParseIP("169.254.100.100"),
+		rib:          locRIB.New(),
+		importFilter: filter.NewAcceptAllFilter(),
+		exportFilter: filter.NewAcceptAllFilter(),
+	})
+
+	fsmA.holdTimer = time.NewTimer(time.Second * 90)
+	fsmA.keepaliveTimer = time.NewTimer(time.Second * 30)
+	fsmA.connectRetryTimer = time.NewTimer(time.Second * 120)
+	fsmA.state = newEstablishedState(fsmA)
+
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func() {
+		fsmA.con = fakeConn{}
+		for {
+			nextState, reason := fsmA.state.run()
+			fsmA.state = nextState
+			stateName := stateName(nextState)
+			fmt.Printf("New state: %s\n", stateName)
+			switch stateName {
+			case "idle":
+				wg.Done()
+				return
+			case "cease":
+				t.Errorf("Unexpected cease state: %s", reason)
+				wg.Done()
+				return
+			case "established":
+				continue
+			default:
+				t.Errorf("Unexpected new state: %s", reason)
+				wg.Done()
+				return
+			}
+		}
+
+	}()
+
+	for i := uint8(0); i < 255; i++ {
+		fsmA.msgRecvCh <- []byte{
+			255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+			0, 53,
+			2,
+			0, 0,
+			0, 26,
+			64, // Attribute flags
+			1,  // Attribute Type code (ORIGIN)
+			1,  // Length
+			2,  // INCOMPLETE
+
+			64,     // Attribute flags
+			2,      // Attribute Type code (AS Path)
+			12,     // Length
+			2,      // Type = AS_SEQUENCE
+			2,      // Path Segement Length
+			59, 65, // AS15169
+			12, 248, // AS3320
+			1,      // Type = AS_SET
+			2,      // Path Segement Length
+			59, 65, // AS15169
+			12, 248, // AS3320
+
+			0,              // Attribute flags
+			3,              // Attribute Type code (Next Hop)
+			4,              // Length
+			10, 11, 12, 13, // Next Hop
+			24, 169, 254, i,
+		}
+	}
+
+	fmt.Printf("Route count in RIB: %d\n", fsmA.rib.RouteCount())
+
+	fmt.Printf("Stopping FSM\n")
+	fsmA.eventCh <- ManualStop
+	fmt.Printf("WAINTING\n")
+	wg.Wait()
+}
diff --git a/routingtable/client_interface.go b/routingtable/client_interface.go
index e7190c5b..536a7602 100644
--- a/routingtable/client_interface.go
+++ b/routingtable/client_interface.go
@@ -13,4 +13,5 @@ type RouteTableClient interface {
 	Register(RouteTableClient)
 	RegisterWithOptions(RouteTableClient, ClientOptions)
 	Unregister(RouteTableClient)
+	RouteCount() int64
 }
diff --git a/routingtable/locRIB/loc_rib.go b/routingtable/locRIB/loc_rib.go
index ff5750c3..90004e27 100644
--- a/routingtable/locRIB/loc_rib.go
+++ b/routingtable/locRIB/loc_rib.go
@@ -40,6 +40,10 @@ func (a *LocRIB) UpdateNewClient(client routingtable.RouteTableClient) error {
 	return nil
 }
 
+func (a *LocRIB) RouteCount() int64 {
+	return a.rt.
+}
+
 // AddPath replaces the path for prefix `pfx`. If the prefix doesn't exist it is added.
 func (a *LocRIB) AddPath(pfx net.Prefix, p *route.Path) error {
 	a.mu.Lock()
-- 
GitLab