5a4c7a9ce4
- goimports properly formats imports Type: test Change-Id: I78c162dd552fd3ee3d59955d7ea215af30601425 Signed-off-by: Adrian Villin <avillin@cisco.com>
194 lines
5.5 KiB
Go
194 lines
5.5 KiB
Go
package main
|
|
|
|
import (
|
|
"math/rand"
|
|
"testing"
|
|
"time"
|
|
|
|
"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"
|
|
)
|
|
|
|
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)
|
|
}
|