summaryrefslogtreecommitdiffhomepage
path: root/server/fsm_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/fsm_test.go')
-rw-r--r--server/fsm_test.go344
1 files changed, 0 insertions, 344 deletions
diff --git a/server/fsm_test.go b/server/fsm_test.go
deleted file mode 100644
index 73159556..00000000
--- a/server/fsm_test.go
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package server
-
-import (
- "errors"
- "net"
- "strconv"
- "sync"
- "testing"
- "time"
-
- "github.com/eapache/channels"
- "github.com/osrg/gobgp/config"
- "github.com/osrg/gobgp/packet/bgp"
- "github.com/osrg/gobgp/table"
- log "github.com/sirupsen/logrus"
- "github.com/stretchr/testify/assert"
-)
-
-type MockConnection struct {
- *testing.T
- net.Conn
- recvCh chan chan byte
- sendBuf [][]byte
- currentCh chan byte
- isClosed bool
- wait int
- mtx sync.Mutex
-}
-
-func NewMockConnection(t *testing.T) *MockConnection {
- m := &MockConnection{
- T: t,
- recvCh: make(chan chan byte, 128),
- sendBuf: make([][]byte, 0),
- isClosed: false,
- }
- return m
-}
-
-func (m *MockConnection) SetWriteDeadline(t time.Time) error {
- return nil
-}
-
-func (m *MockConnection) setData(data []byte) int {
- dataChan := make(chan byte, 4096)
- for _, b := range data {
- dataChan <- b
- }
- m.recvCh <- dataChan
- return len(dataChan)
-}
-
-func (m *MockConnection) Read(buf []byte) (int, error) {
- m.mtx.Lock()
- closed := m.isClosed
- m.mtx.Unlock()
- if closed {
- return 0, errors.New("already closed")
- }
-
- if m.currentCh == nil {
- m.currentCh = <-m.recvCh
- }
-
- length := 0
- rest := len(buf)
- for i := 0; i < rest; i++ {
- if len(m.currentCh) > 0 {
- val := <-m.currentCh
- buf[i] = val
- length++
- } else {
- m.currentCh = nil
- break
- }
- }
-
- m.Logf("%d bytes read from peer", length)
- return length, nil
-}
-
-func (m *MockConnection) Write(buf []byte) (int, error) {
- time.Sleep(time.Duration(m.wait) * time.Millisecond)
- m.sendBuf = append(m.sendBuf, buf)
- msg, _ := bgp.ParseBGPMessage(buf)
- m.Logf("%d bytes written by gobgp message type : %s",
- len(buf), showMessageType(msg.Header.Type))
- return len(buf), nil
-}
-
-func showMessageType(t uint8) string {
- switch t {
- case bgp.BGP_MSG_KEEPALIVE:
- return "BGP_MSG_KEEPALIVE"
- case bgp.BGP_MSG_NOTIFICATION:
- return "BGP_MSG_NOTIFICATION"
- case bgp.BGP_MSG_OPEN:
- return "BGP_MSG_OPEN"
- case bgp.BGP_MSG_UPDATE:
- return "BGP_MSG_UPDATE"
- case bgp.BGP_MSG_ROUTE_REFRESH:
- return "BGP_MSG_ROUTE_REFRESH"
- }
- return strconv.Itoa(int(t))
-}
-
-func (m *MockConnection) Close() error {
- m.mtx.Lock()
- defer m.mtx.Unlock()
- if !m.isClosed {
- close(m.recvCh)
- m.isClosed = true
- }
- return nil
-}
-
-func (m *MockConnection) LocalAddr() net.Addr {
- return &net.TCPAddr{
- IP: net.ParseIP("10.10.10.10"),
- Port: bgp.BGP_PORT}
-}
-
-func TestReadAll(t *testing.T) {
- assert := assert.New(t)
- m := NewMockConnection(t)
- msg := open()
- expected1, _ := msg.Header.Serialize()
- expected2, _ := msg.Body.Serialize()
-
- pushBytes := func() {
- m.Log("push 5 bytes")
- m.setData(expected1[0:5])
- m.Log("push rest")
- m.setData(expected1[5:])
- m.Log("push bytes at once")
- m.setData(expected2)
- }
-
- go pushBytes()
-
- var actual1 []byte
- actual1, _ = readAll(m, bgp.BGP_HEADER_LENGTH)
- m.Log(actual1)
- assert.Equal(expected1, actual1)
-
- var actual2 []byte
- actual2, _ = readAll(m, len(expected2))
- m.Log(actual2)
- assert.Equal(expected2, actual2)
-}
-
-func TestFSMHandlerOpensent_HoldTimerExpired(t *testing.T) {
- assert := assert.New(t)
- m := NewMockConnection(t)
-
- p, h := makePeerAndHandler()
-
- // push mock connection
- p.fsm.conn = m
- p.fsm.h = h
-
- // set keepalive ticker
- p.fsm.pConf.Timers.State.NegotiatedHoldTime = 3
-
- // set holdtime
- p.fsm.opensentHoldTime = 2
-
- state, _ := h.opensent()
-
- assert.Equal(bgp.BGP_FSM_IDLE, state)
- lastMsg := m.sendBuf[len(m.sendBuf)-1]
- sent, _ := bgp.ParseBGPMessage(lastMsg)
- assert.Equal(uint8(bgp.BGP_MSG_NOTIFICATION), sent.Header.Type)
- assert.Equal(uint8(bgp.BGP_ERROR_HOLD_TIMER_EXPIRED), sent.Body.(*bgp.BGPNotification).ErrorCode)
-
-}
-
-func TestFSMHandlerOpenconfirm_HoldTimerExpired(t *testing.T) {
- assert := assert.New(t)
- m := NewMockConnection(t)
-
- p, h := makePeerAndHandler()
-
- // push mock connection
- p.fsm.conn = m
- p.fsm.h = h
-
- // set up keepalive ticker
- p.fsm.pConf.Timers.Config.KeepaliveInterval = 1
-
- // set holdtime
- p.fsm.pConf.Timers.State.NegotiatedHoldTime = 2
- state, _ := h.openconfirm()
-
- assert.Equal(bgp.BGP_FSM_IDLE, state)
- lastMsg := m.sendBuf[len(m.sendBuf)-1]
- sent, _ := bgp.ParseBGPMessage(lastMsg)
- assert.Equal(uint8(bgp.BGP_MSG_NOTIFICATION), sent.Header.Type)
- assert.Equal(uint8(bgp.BGP_ERROR_HOLD_TIMER_EXPIRED), sent.Body.(*bgp.BGPNotification).ErrorCode)
-
-}
-
-func TestFSMHandlerEstablish_HoldTimerExpired(t *testing.T) {
- assert := assert.New(t)
- m := NewMockConnection(t)
-
- p, h := makePeerAndHandler()
-
- // push mock connection
- p.fsm.conn = m
- p.fsm.h = h
-
- // set keepalive ticker
- p.fsm.pConf.Timers.State.NegotiatedHoldTime = 3
-
- msg := keepalive()
- header, _ := msg.Header.Serialize()
- body, _ := msg.Body.Serialize()
-
- pushPackets := func() {
- // first keepalive from peer
- m.setData(header)
- m.setData(body)
- }
-
- // set holdtime
- p.fsm.pConf.Timers.Config.HoldTime = 2
- p.fsm.pConf.Timers.State.NegotiatedHoldTime = 2
-
- go pushPackets()
- state, _ := h.established()
- time.Sleep(time.Second * 1)
- assert.Equal(bgp.BGP_FSM_IDLE, state)
- m.mtx.Lock()
- lastMsg := m.sendBuf[len(m.sendBuf)-1]
- m.mtx.Unlock()
- sent, _ := bgp.ParseBGPMessage(lastMsg)
- assert.Equal(uint8(bgp.BGP_MSG_NOTIFICATION), sent.Header.Type)
- assert.Equal(uint8(bgp.BGP_ERROR_HOLD_TIMER_EXPIRED), sent.Body.(*bgp.BGPNotification).ErrorCode)
-}
-
-func TestFSMHandlerOpenconfirm_HoldtimeZero(t *testing.T) {
- log.SetLevel(log.DebugLevel)
- assert := assert.New(t)
- m := NewMockConnection(t)
-
- p, h := makePeerAndHandler()
-
- // push mock connection
- p.fsm.conn = m
- p.fsm.h = h
-
- // set up keepalive ticker
- p.fsm.pConf.Timers.Config.KeepaliveInterval = 1
- // set holdtime
- p.fsm.pConf.Timers.State.NegotiatedHoldTime = 0
- go h.openconfirm()
-
- time.Sleep(100 * time.Millisecond)
-
- assert.Equal(0, len(m.sendBuf))
-
-}
-
-func TestFSMHandlerEstablished_HoldtimeZero(t *testing.T) {
- log.SetLevel(log.DebugLevel)
- assert := assert.New(t)
- m := NewMockConnection(t)
-
- p, h := makePeerAndHandler()
-
- // push mock connection
- p.fsm.conn = m
- p.fsm.h = h
-
- // set holdtime
- p.fsm.pConf.Timers.State.NegotiatedHoldTime = 0
-
- go h.established()
-
- time.Sleep(100 * time.Millisecond)
-
- assert.Equal(0, len(m.sendBuf))
-}
-
-func TestCheckOwnASLoop(t *testing.T) {
- assert := assert.New(t)
- aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65100})}
- aspath := bgp.NewPathAttributeAsPath(aspathParam)
- assert.False(hasOwnASLoop(65100, 10, aspath))
- assert.True(hasOwnASLoop(65100, 0, aspath))
- assert.False(hasOwnASLoop(65200, 0, aspath))
-}
-
-func makePeerAndHandler() (*Peer, *FSMHandler) {
- p := &Peer{
- fsm: NewFSM(&config.Global{}, &config.Neighbor{}, table.NewRoutingPolicy()),
- outgoing: channels.NewInfiniteChannel(),
- }
-
- h := &FSMHandler{
- fsm: p.fsm,
- stateReasonCh: make(chan FsmStateReason, 2),
- incoming: channels.NewInfiniteChannel(),
- outgoing: p.outgoing,
- }
-
- return p, h
-
-}
-
-func open() *bgp.BGPMessage {
- p1 := bgp.NewOptionParameterCapability(
- []bgp.ParameterCapabilityInterface{bgp.NewCapRouteRefresh()})
- p2 := bgp.NewOptionParameterCapability(
- []bgp.ParameterCapabilityInterface{bgp.NewCapMultiProtocol(bgp.RF_IPv4_UC)})
- g := &bgp.CapGracefulRestartTuple{AFI: 4, SAFI: 2, Flags: 3}
- p3 := bgp.NewOptionParameterCapability(
- []bgp.ParameterCapabilityInterface{bgp.NewCapGracefulRestart(true, true, 100,
- []*bgp.CapGracefulRestartTuple{g})})
- p4 := bgp.NewOptionParameterCapability(
- []bgp.ParameterCapabilityInterface{bgp.NewCapFourOctetASNumber(100000)})
- return bgp.NewBGPOpenMessage(11033, 303, "100.4.10.3",
- []bgp.OptionParameterInterface{p1, p2, p3, p4})
-}
-
-func keepalive() *bgp.BGPMessage {
- return bgp.NewBGPKeepAliveMessage()
-}