aboutsummaryrefslogtreecommitdiffstats
path: root/api/api_test.go
diff options
context:
space:
mode:
authorVladimir Lavor <vlavor@cisco.com>2018-07-03 10:39:21 +0200
committerVladimir Lavor <vlavor@cisco.com>2018-07-06 13:18:01 +0200
commitf1bef4a3c66f4408afdeb64cda62ccd8562d0fc6 (patch)
tree5767c18051f97362a00b1a4dfe90ec9480247032 /api/api_test.go
parent5276b9439d0f902e125a5113bfa4f1b6622aea18 (diff)
make api.Channel as interface
Change-Id: I052d241ab09043b1195beebeee99df4d8536621f Signed-off-by: Vladimir Lavor <vlavor@cisco.com>
Diffstat (limited to 'api/api_test.go')
-rw-r--r--api/api_test.go588
1 files changed, 0 insertions, 588 deletions
diff --git a/api/api_test.go b/api/api_test.go
deleted file mode 100644
index 7cbd9f0..0000000
--- a/api/api_test.go
+++ /dev/null
@@ -1,588 +0,0 @@
-// Copyright (c) 2017 Cisco and/or its affiliates.
-//
-// 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 api_test
-
-import (
- "testing"
- "time"
-
- "git.fd.io/govpp.git/adapter/mock"
- "git.fd.io/govpp.git/api"
- "git.fd.io/govpp.git/core"
- "git.fd.io/govpp.git/core/bin_api/vpe"
- "git.fd.io/govpp.git/examples/bin_api/interfaces"
- "git.fd.io/govpp.git/examples/bin_api/memif"
- "git.fd.io/govpp.git/examples/bin_api/tap"
-
- . "github.com/onsi/gomega"
-)
-
-type testCtx struct {
- mockVpp *mock.VppAdapter
- conn *core.Connection
- ch *api.Channel
-}
-
-func setupTest(t *testing.T) *testCtx {
- RegisterTestingT(t)
-
- ctx := &testCtx{
- mockVpp: &mock.VppAdapter{},
- }
-
- var err error
- ctx.conn, err = core.Connect(ctx.mockVpp)
- Expect(err).ShouldNot(HaveOccurred())
-
- ctx.ch, err = ctx.conn.NewAPIChannel()
- Expect(err).ShouldNot(HaveOccurred())
-
- return ctx
-}
-
-func (ctx *testCtx) teardownTest() {
- ctx.ch.Close()
- ctx.conn.Disconnect()
-}
-
-func TestRequestReplyTapConnect(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.mockVpp.MockReply(&tap.TapConnectReply{
- Retval: 10,
- SwIfIndex: 1,
- })
- request := &tap.TapConnect{
- TapName: []byte("test-tap-name"),
- UseRandomMac: 1,
- }
- reply := &tap.TapConnectReply{}
-
- err := ctx.ch.SendRequest(request).ReceiveReply(reply)
- Expect(err).ShouldNot(HaveOccurred())
- Expect(reply.Retval).To(BeEquivalentTo(10), "Incorrect retval value for TapConnectReply")
- Expect(reply.SwIfIndex).To(BeEquivalentTo(1), "Incorrect SwIfIndex value for TapConnectReply")
-}
-
-func TestRequestReplyTapModify(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.mockVpp.MockReply(&tap.TapModifyReply{
- Retval: 15,
- SwIfIndex: 2,
- })
- request := &tap.TapModify{
- TapName: []byte("test-tap-modify"),
- UseRandomMac: 1,
- CustomDevInstance: 1,
- }
- reply := &tap.TapModifyReply{}
-
- err := ctx.ch.SendRequest(request).ReceiveReply(reply)
- Expect(err).ShouldNot(HaveOccurred())
- Expect(reply.Retval).To(BeEquivalentTo(15), "Incorrect retval value for TapModifyReply")
- Expect(reply.SwIfIndex).To(BeEquivalentTo(2), "Incorrect SwIfIndex value for TapModifyReply")
-}
-
-func TestRequestReplyTapDelete(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.mockVpp.MockReply(&tap.TapDeleteReply{
- Retval: 20,
- })
- request := &tap.TapDelete{
- SwIfIndex: 3,
- }
- reply := &tap.TapDeleteReply{}
-
- err := ctx.ch.SendRequest(request).ReceiveReply(reply)
- Expect(err).ShouldNot(HaveOccurred())
- Expect(reply.Retval).To(BeEquivalentTo(20), "Incorrect retval value for TapDeleteReply")
-}
-
-func TestRequestReplySwInterfaceTapDump(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- byteName := []byte("dev-name-test")
- ctx.mockVpp.MockReply(&tap.SwInterfaceTapDetails{
- SwIfIndex: 25,
- DevName: byteName,
- })
- request := &tap.SwInterfaceTapDump{}
- reply := &tap.SwInterfaceTapDetails{}
-
- err := ctx.ch.SendRequest(request).ReceiveReply(reply)
- Expect(err).ShouldNot(HaveOccurred())
- Expect(reply.SwIfIndex).To(BeEquivalentTo(25), "Incorrect SwIfIndex value for SwInterfaceTapDetails")
- Expect(reply.DevName).ToNot(BeNil(), "Incorrect DevName value for SwInterfaceTapDetails")
-}
-
-func TestRequestReplyMemifCreate(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.mockVpp.MockReply(&memif.MemifCreateReply{
- Retval: 22,
- SwIfIndex: 4,
- })
- request := &memif.MemifCreate{
- Role: 10,
- ID: 12,
- RingSize: 8000,
- BufferSize: 50,
- }
- reply := &memif.MemifCreateReply{}
-
- err := ctx.ch.SendRequest(request).ReceiveReply(reply)
- Expect(err).ShouldNot(HaveOccurred())
- Expect(reply.Retval).To(BeEquivalentTo(22), "Incorrect Retval value for MemifCreate")
- Expect(reply.SwIfIndex).To(BeEquivalentTo(4), "Incorrect SwIfIndex value for MemifCreate")
-}
-
-func TestRequestReplyMemifDelete(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.mockVpp.MockReply(&memif.MemifDeleteReply{
- Retval: 24,
- })
- request := &memif.MemifDelete{
- SwIfIndex: 15,
- }
- reply := &memif.MemifDeleteReply{}
-
- err := ctx.ch.SendRequest(request).ReceiveReply(reply)
- Expect(err).ShouldNot(HaveOccurred())
- Expect(reply.Retval).To(BeEquivalentTo(24), "Incorrect Retval value for MemifDelete")
-}
-
-func TestRequestReplyMemifDetails(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.mockVpp.MockReply(&memif.MemifDetails{
- SwIfIndex: 25,
- IfName: []byte("memif-name"),
- Role: 0,
- })
- request := &memif.MemifDump{}
- reply := &memif.MemifDetails{}
-
- err := ctx.ch.SendRequest(request).ReceiveReply(reply)
- Expect(err).ShouldNot(HaveOccurred())
- Expect(reply.SwIfIndex).To(BeEquivalentTo(25), "Incorrect SwIfIndex value for MemifDetails")
- Expect(reply.IfName).ToNot(BeEmpty(), "MemifDetails IfName is empty byte array")
- Expect(reply.Role).To(BeEquivalentTo(0), "Incorrect Role value for MemifDetails")
-}
-
-func TestMultiRequestReplySwInterfaceTapDump(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- // mock reply
- msgs := []api.Message{}
- for i := 1; i <= 10; i++ {
- msgs = append(msgs, &tap.SwInterfaceTapDetails{
- SwIfIndex: uint32(i),
- DevName: []byte("dev-name-test"),
- })
- }
- ctx.mockVpp.MockReply(msgs...)
- ctx.mockVpp.MockReply(&vpe.ControlPingReply{})
-
- reqCtx := ctx.ch.SendMultiRequest(&tap.SwInterfaceTapDump{})
- cnt := 0
- for {
- msg := &tap.SwInterfaceTapDetails{}
- stop, err := reqCtx.ReceiveReply(msg)
- if stop {
- break // break out of the loop
- }
- Expect(err).ShouldNot(HaveOccurred())
- cnt++
- }
- Expect(cnt).To(BeEquivalentTo(10))
-}
-
-func TestMultiRequestReplySwInterfaceMemifDump(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- // mock reply
- msgs := []api.Message{}
- for i := 1; i <= 10; i++ {
- msgs = append(msgs, &memif.MemifDetails{
- SwIfIndex: uint32(i),
- })
- }
- ctx.mockVpp.MockReply(msgs...)
- ctx.mockVpp.MockReply(&vpe.ControlPingReply{})
-
- reqCtx := ctx.ch.SendMultiRequest(&memif.MemifDump{})
- cnt := 0
- for {
- msg := &memif.MemifDetails{}
- stop, err := reqCtx.ReceiveReply(msg)
- if stop {
- break // break out of the loop
- }
- Expect(err).ShouldNot(HaveOccurred())
- cnt++
- }
- Expect(cnt).To(BeEquivalentTo(10))
-}
-
-func TestNotifications(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- // subscribe for notification
- notifChan := make(chan api.Message, 1)
- subs, err := ctx.ch.SubscribeNotification(notifChan, interfaces.NewSwInterfaceSetFlags)
- Expect(err).ShouldNot(HaveOccurred())
-
- // mock the notification and force its delivery
- ctx.mockVpp.MockReply(&interfaces.SwInterfaceSetFlags{
- SwIfIndex: 3,
- AdminUpDown: 1,
- })
- ctx.mockVpp.SendMsg(0, []byte(""))
-
- // receive the notification
- var notif *interfaces.SwInterfaceSetFlags
- Eventually(func() *interfaces.SwInterfaceSetFlags {
- select {
- case n := <-notifChan:
- notif = n.(*interfaces.SwInterfaceSetFlags)
- return notif
- default:
- return nil
- }
- }).ShouldNot(BeNil())
-
- // verify the received notifications
- Expect(notif.SwIfIndex).To(BeEquivalentTo(3), "Incorrect SwIfIndex value for SwInterfaceSetFlags")
- Expect(notif.AdminUpDown).To(BeEquivalentTo(1), "Incorrect AdminUpDown value for SwInterfaceSetFlags")
-
- ctx.ch.UnsubscribeNotification(subs)
-}
-
-func TestNotificationEvent(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- // subscribe for notification
- notifChan := make(chan api.Message, 1)
- subs, err := ctx.ch.SubscribeNotification(notifChan, interfaces.NewSwInterfaceEvent)
- Expect(err).ShouldNot(HaveOccurred())
-
- // mock the notification and force its delivery
- ctx.mockVpp.MockReply(&interfaces.SwInterfaceEvent{
- SwIfIndex: 2,
- LinkUpDown: 1,
- })
- ctx.mockVpp.SendMsg(0, []byte(""))
-
- // receive the notification
- var notif *interfaces.SwInterfaceEvent
- Eventually(func() *interfaces.SwInterfaceEvent {
- select {
- case n := <-notifChan:
- notif = n.(*interfaces.SwInterfaceEvent)
- return notif
- default:
- return nil
- }
- }).ShouldNot(BeNil())
-
- // verify the received notifications
- Expect(notif.SwIfIndex).To(BeEquivalentTo(2), "Incorrect SwIfIndex value for SwInterfaceSetFlags")
- Expect(notif.LinkUpDown).To(BeEquivalentTo(1), "Incorrect LinkUpDown value for SwInterfaceSetFlags")
-
- ctx.ch.UnsubscribeNotification(subs)
-}
-
-func TestCheckMessageCompatibility(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- err := ctx.ch.CheckMessageCompatibility(&interfaces.SwInterfaceSetFlags{})
- Expect(err).ShouldNot(HaveOccurred())
-}
-func TestSetReplyTimeout(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.ch.SetReplyTimeout(time.Millisecond)
-
- // first one request should work
- ctx.mockVpp.MockReply(&vpe.ControlPingReply{})
- err := ctx.ch.SendRequest(&vpe.ControlPing{}).ReceiveReply(&vpe.ControlPingReply{})
- Expect(err).ShouldNot(HaveOccurred())
-
- // no other reply ready - expect timeout
- err = ctx.ch.SendRequest(&vpe.ControlPing{}).ReceiveReply(&vpe.ControlPingReply{})
- Expect(err).Should(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("timeout"))
-}
-
-func TestSetReplyTimeoutMultiRequest(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.ch.SetReplyTimeout(time.Millisecond)
-
- msgs := []api.Message{}
- for i := 1; i <= 3; i++ {
- msgs = append(msgs, &interfaces.SwInterfaceDetails{
- SwIfIndex: uint32(i),
- InterfaceName: []byte("if-name-test"),
- })
- }
- ctx.mockVpp.MockReply(msgs...)
- ctx.mockVpp.MockReply(&vpe.ControlPingReply{})
-
- cnt := 0
- sendMultiRequest := func() error {
- reqCtx := ctx.ch.SendMultiRequest(&interfaces.SwInterfaceDump{})
- for {
- msg := &interfaces.SwInterfaceDetails{}
- stop, err := reqCtx.ReceiveReply(msg)
- if stop {
- break // break out of the loop
- }
- if err != nil {
- return err
- }
- cnt++
- }
- return nil
- }
-
- // first one request should work
- err := sendMultiRequest()
- Expect(err).ShouldNot(HaveOccurred())
-
- // no other reply ready - expect timeout
- err = sendMultiRequest()
- Expect(err).Should(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("timeout"))
-
- Expect(cnt).To(BeEquivalentTo(3))
-}
-
-func TestReceiveReplyNegative(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- // invalid context 1
- reqCtx1 := &api.RequestCtx{}
- err := reqCtx1.ReceiveReply(&vpe.ControlPingReply{})
- Expect(err).Should(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("invalid request context"))
-
- // invalid context 2
- reqCtx2 := &api.MultiRequestCtx{}
- _, err = reqCtx2.ReceiveReply(&vpe.ControlPingReply{})
- Expect(err).Should(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("invalid request context"))
-
- // NU
- reqCtx3 := &api.RequestCtx{}
- err = reqCtx3.ReceiveReply(nil)
- Expect(err).Should(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("invalid request context"))
-}
-
-func TestMultiRequestDouble(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- // mock reply
- msgs := []mock.MsgWithContext{}
- for i := 1; i <= 3; i++ {
- msgs = append(msgs, mock.MsgWithContext{
- Msg: &interfaces.SwInterfaceDetails{
- SwIfIndex: uint32(i),
- InterfaceName: []byte("if-name-test"),
- },
- Multipart: true,
- SeqNum: 1,
- })
- }
- msgs = append(msgs, mock.MsgWithContext{Msg: &vpe.ControlPingReply{}, Multipart: true, SeqNum: 1})
-
- for i := 1; i <= 3; i++ {
- msgs = append(msgs,
- mock.MsgWithContext{
- Msg: &interfaces.SwInterfaceDetails{
- SwIfIndex: uint32(i),
- InterfaceName: []byte("if-name-test"),
- },
- Multipart: true,
- SeqNum: 2,
- })
- }
- msgs = append(msgs, mock.MsgWithContext{Msg: &vpe.ControlPingReply{}, Multipart: true, SeqNum: 2})
-
- ctx.mockVpp.MockReplyWithContext(msgs...)
-
- cnt := 0
- var sendMultiRequest = func() error {
- reqCtx := ctx.ch.SendMultiRequest(&interfaces.SwInterfaceDump{})
- for {
- msg := &interfaces.SwInterfaceDetails{}
- stop, err := reqCtx.ReceiveReply(msg)
- if stop {
- break // break out of the loop
- }
- if err != nil {
- return err
- }
- cnt++
- }
- return nil
- }
-
- err := sendMultiRequest()
- Expect(err).ShouldNot(HaveOccurred())
-
- err = sendMultiRequest()
- Expect(err).ShouldNot(HaveOccurred())
-
- Expect(cnt).To(BeEquivalentTo(6))
-}
-
-func TestReceiveReplyAfterTimeout(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.ch.SetReplyTimeout(time.Millisecond)
-
- // first one request should work
- ctx.mockVpp.MockReplyWithContext(mock.MsgWithContext{Msg: &vpe.ControlPingReply{}, SeqNum: 1})
- err := ctx.ch.SendRequest(&vpe.ControlPing{}).ReceiveReply(&vpe.ControlPingReply{})
- Expect(err).ShouldNot(HaveOccurred())
-
- err = ctx.ch.SendRequest(&vpe.ControlPing{}).ReceiveReply(&vpe.ControlPingReply{})
- Expect(err).Should(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("timeout"))
-
- ctx.mockVpp.MockReplyWithContext(
- // simulating late reply
- mock.MsgWithContext{Msg: &vpe.ControlPingReply{}, SeqNum: 2},
- // normal reply for next request
- mock.MsgWithContext{Msg: &tap.TapConnectReply{}, SeqNum: 3})
-
- req := &tap.TapConnect{
- TapName: []byte("test-tap-name"),
- UseRandomMac: 1,
- }
- reply := &tap.TapConnectReply{}
-
- // should succeed
- err = ctx.ch.SendRequest(req).ReceiveReply(reply)
- Expect(err).ShouldNot(HaveOccurred())
-}
-
-func TestReceiveReplyAfterTimeoutMultiRequest(t *testing.T) {
- /*
- TODO: fix mock adapter
- This test will fail because mock adapter will stop sending replies
- when it encounters control_ping_reply from multi request,
- thus never sending reply for next request
- */
- t.Skip()
-
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- ctx.ch.SetReplyTimeout(time.Millisecond * 100)
-
- // first one request should work
- ctx.mockVpp.MockReplyWithContext(mock.MsgWithContext{Msg: &vpe.ControlPingReply{}, SeqNum: 1})
- err := ctx.ch.SendRequest(&vpe.ControlPing{}).ReceiveReply(&vpe.ControlPingReply{})
- Expect(err).ShouldNot(HaveOccurred())
-
- cnt := 0
- var sendMultiRequest = func() error {
- reqCtx := ctx.ch.SendMultiRequest(&interfaces.SwInterfaceDump{})
- for {
- msg := &interfaces.SwInterfaceDetails{}
- stop, err := reqCtx.ReceiveReply(msg)
- if stop {
- break // break out of the loop
- }
- if err != nil {
- return err
- }
- cnt++
- }
- return nil
- }
-
- err = sendMultiRequest()
- Expect(err).Should(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("timeout"))
- Expect(cnt).To(BeEquivalentTo(0))
-
- // simulating late replies
- msgs := []mock.MsgWithContext{}
- for i := 1; i <= 3; i++ {
- msgs = append(msgs, mock.MsgWithContext{
- Msg: &interfaces.SwInterfaceDetails{
- SwIfIndex: uint32(i),
- InterfaceName: []byte("if-name-test"),
- },
- Multipart: true,
- SeqNum: 2,
- })
- }
- msgs = append(msgs, mock.MsgWithContext{Msg: &vpe.ControlPingReply{}, Multipart: true, SeqNum: 2})
- ctx.mockVpp.MockReplyWithContext(msgs...)
-
- // normal reply for next request
- ctx.mockVpp.MockReplyWithContext(mock.MsgWithContext{Msg: &tap.TapConnectReply{}, SeqNum: 3})
-
- req := &tap.TapConnect{
- TapName: []byte("test-tap-name"),
- UseRandomMac: 1,
- }
- reply := &tap.TapConnectReply{}
-
- // should succeed
- err = ctx.ch.SendRequest(req).ReceiveReply(reply)
- Expect(err).ShouldNot(HaveOccurred())
-}
-
-func TestInvalidMessageID(t *testing.T) {
- ctx := setupTest(t)
- defer ctx.teardownTest()
-
- // first one request should work
- ctx.mockVpp.MockReply(&vpe.ShowVersionReply{})
- err := ctx.ch.SendRequest(&vpe.ShowVersion{}).ReceiveReply(&vpe.ShowVersionReply{})
- Expect(err).ShouldNot(HaveOccurred())
-
- // second should fail with error invalid message ID
- ctx.mockVpp.MockReply(&vpe.ShowVersionReply{})
- err = ctx.ch.SendRequest(&vpe.ControlPing{}).ReceiveReply(&vpe.ControlPingReply{})
- Expect(err).Should(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("invalid message ID"))
-}