vpp/extras/vpp_if_stats/vpp_if_stats_test.go
Koren Lev f3b7a5e47a vpp_if_stats: Fixing a bug in getting vpp interfaces indexes
Change-Id: I6290945a94b4f7878e9af94cc7daec455327482e
Signed-off-by: Koren Lev <korenlev@gmail.com>
2018-12-07 10:42:00 +00:00

193 lines
5.5 KiB
Go

package main
import (
"git.fd.io/govpp.git/adapter"
"git.fd.io/govpp.git/api"
"git.fd.io/govpp.git/examples/bin_api/interfaces"
"git.fd.io/govpp.git/examples/bin_api/vpe"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"math/rand"
"testing"
"time"
)
var (
vppDetails = vpe.ShowVersionReply{
Program: []byte("vpe"),
Version: []byte("18.10"),
}
testSwIfIndex = uint32(0)
testInterface = func() *vppInterface {
return &vppInterface{
SwInterfaceDetails: interfaces.SwInterfaceDetails{SwIfIndex: testSwIfIndex}, // TODO
Stats: interfaceStats{}, // TODO
}
}
testInterfaces = func() []*vppInterface {
return []*vppInterface{
testInterface(),
}
}
r = rand.New(rand.NewSource(time.Now().UnixNano()))
testCombinedStats = interfaceStats{
TxBytes: r.Uint64(),
TxPackets: r.Uint64(),
RxBytes: r.Uint64(),
RxPackets: r.Uint64(),
}
testCombinedStatsDump = []*adapter.StatEntry{
{
Name: "/if/tx",
Type: adapter.CombinedCounterVector,
Data: adapter.CombinedCounterStat{
[]adapter.CombinedCounter{
{
Bytes: adapter.Counter(testCombinedStats.TxBytes),
Packets: adapter.Counter(testCombinedStats.TxPackets),
},
},
},
},
{
Name: "/if/rx",
Type: adapter.CombinedCounterVector,
Data: adapter.CombinedCounterStat{
[]adapter.CombinedCounter{
{
Bytes: adapter.Counter(testCombinedStats.RxBytes),
Packets: adapter.Counter(testCombinedStats.RxPackets),
},
},
},
},
}
testSimpleStats = interfaceStats{
TxErrors: r.Uint64(),
RxErrors: r.Uint64(),
Drops: r.Uint64(),
Punts: r.Uint64(),
}
testSimpleStatsDump = []*adapter.StatEntry{
{
Name: "/if/tx-error",
Type: adapter.SimpleCounterVector,
Data: adapter.SimpleCounterStat{
[]adapter.Counter{adapter.Counter(testSimpleStats.TxErrors)},
},
},
{
Name: "/if/rx-error",
Type: adapter.SimpleCounterVector,
Data: adapter.SimpleCounterStat{
[]adapter.Counter{adapter.Counter(testSimpleStats.RxErrors)},
},
},
{
Name: "/if/drops",
Type: adapter.SimpleCounterVector,
Data: adapter.SimpleCounterStat{
[]adapter.Counter{adapter.Counter(testSimpleStats.Drops)},
},
},
{
Name: "/if/punt",
Type: adapter.SimpleCounterVector,
Data: adapter.SimpleCounterStat{
[]adapter.Counter{adapter.Counter(testSimpleStats.Punts)},
},
},
}
)
type showDetailsContext struct {
details vpe.ShowVersionReply
}
func (ctx *showDetailsContext) ReceiveReply(msg api.Message) (err error) {
*(msg.(*vpe.ShowVersionReply)) = vppDetails
return nil
}
type interfaceDumpContext struct {
interfaces []interfaces.SwInterfaceDetails
currentIndex int
}
func (ctx *interfaceDumpContext) ReceiveReply(msg api.Message) (lastReplyReceived bool, err error) {
stop := ctx.currentIndex >= len(ctx.interfaces)
if !stop {
*(msg.(*interfaces.SwInterfaceDetails)) = ctx.interfaces[ctx.currentIndex]
ctx.currentIndex++
}
return stop, nil
}
func TestVppIfStats_GetVppVersion(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockChannel := NewMockChannel(mockCtrl)
mockChannel.EXPECT().SendRequest(&vpe.ShowVersion{}).Return(&showDetailsContext{details: vppDetails})
v := vppConnector{api: mockChannel}
err := v.getVppVersion()
assert.NoError(t, err, "GetVppVersion should not return an error")
assert.Equal(t, vppDetails, v.VppDetails, "VPP details should be saved")
}
func TestVppIfStats_GetInterfaces(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
testContext := interfaceDumpContext{interfaces: []interfaces.SwInterfaceDetails{testInterface().SwInterfaceDetails}}
mockChannel := NewMockChannel(mockCtrl)
mockChannel.EXPECT().SendMultiRequest(&interfaces.SwInterfaceDump{}).Return(&testContext)
v := vppConnector{api: mockChannel}
err := v.getInterfaces()
assert.NoError(t, err, "GetInterfaces should not return an error")
assert.Len(t, v.Interfaces, len(testContext.interfaces), "All dumped interfaces should be saved")
if len(testContext.interfaces) > 0 {
assert.Equal(t, testContext.interfaces[0], v.Interfaces[testInterface().SwIfIndex].SwInterfaceDetails,
"All dumped interface info should be saved")
}
}
func TestVppIfStats_GetStatsForAllInterfacesNoStats(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockStatsAPI := NewMockStatsAPI(mockCtrl)
mockStatsAPI.EXPECT().DumpStats("/if").Return([]*adapter.StatEntry{}, nil)
v := vppConnector{stats: mockStatsAPI, Interfaces: testInterfaces()}
err := v.getStatsForAllInterfaces()
assert.NoError(t, err, "GetStatsForAllInterfaces should not return an error")
assert.Equal(t, interfaceStats{}, v.Interfaces[testSwIfIndex].Stats, "Stats should be empty")
}
func testStats(t *testing.T, statsDump *[]*adapter.StatEntry, expectedStats *interfaceStats) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockStatsAPI := NewMockStatsAPI(mockCtrl)
mockStatsAPI.EXPECT().DumpStats("/if").Return(*statsDump, nil)
v := vppConnector{stats: mockStatsAPI, Interfaces: testInterfaces()}
err := v.getStatsForAllInterfaces()
assert.NoError(t, err, "GetStatsForAllInterfaces should not return an error")
assert.Equal(t, *expectedStats, v.Interfaces[testSwIfIndex].Stats, "Collected and saved stats should match")
}
func TestVppIfStats_GetStatsForAllInterfacesCombinedStats(t *testing.T) {
testStats(t, &testCombinedStatsDump, &testCombinedStats)
}
func TestVppIfStats_GetStatsForAllInterfacesSimpleStats(t *testing.T) {
testStats(t, &testSimpleStatsDump, &testSimpleStats)
}