X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=core%2Fconnection_test.go;h=453bbce6020dbaf82932ba9eee65696c8724c66b;hb=c7ae74a95d1bd6fefcbb061f5f045c60c11e32fc;hp=b7c3aa0dfb4148a74d95cfbdaad63b6dfa0f2dbd;hpb=da815585c3f75c4ac073b0766dd668abf83844d8;p=govpp.git diff --git a/core/connection_test.go b/core/connection_test.go index b7c3aa0..453bbce 100644 --- a/core/connection_test.go +++ b/core/connection_test.go @@ -15,17 +15,17 @@ package core_test import ( + "git.fd.io/govpp.git/examples/binapi/interface_types" "testing" + . "github.com/onsi/gomega" + "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/stats" - "git.fd.io/govpp.git/codec" - . "github.com/onsi/gomega" + "git.fd.io/govpp.git/core" + "git.fd.io/govpp.git/examples/binapi/interfaces" + "git.fd.io/govpp.git/examples/binapi/vpe" ) type testCtx struct { @@ -37,8 +37,9 @@ type testCtx struct { func setupTest(t *testing.T, bufferedChan bool) *testCtx { RegisterTestingT(t) - ctx := &testCtx{} - ctx.mockVpp = &mock.VppAdapter{} + ctx := &testCtx{ + mockVpp: mock.NewVppAdapter(), + } var err error ctx.conn, err = core.Connect(ctx.mockVpp) @@ -59,100 +60,6 @@ func (ctx *testCtx) teardownTest() { ctx.conn.Disconnect() } -func TestSimpleRequest(t *testing.T) { - ctx := setupTest(t, false) - defer ctx.teardownTest() - - ctx.mockVpp.MockReply(&vpe.ControlPingReply{Retval: -5}) - - req := &vpe.ControlPing{} - reply := &vpe.ControlPingReply{} - - // send the request and receive a reply - ctx.ch.GetRequestChannel() <- &api.VppRequest{Message: req} - vppReply := <-ctx.ch.GetReplyChannel() - - Expect(vppReply).ShouldNot(BeNil()) - Expect(vppReply.Error).ShouldNot(HaveOccurred()) - - // decode the message - err := ctx.ch.GetMessageDecoder().DecodeMsg(vppReply.Data, reply) - Expect(err).ShouldNot(HaveOccurred()) - - Expect(reply.Retval).To(BeEquivalentTo(-5)) -} - -func TestMultiRequest(t *testing.T) { - ctx := setupTest(t, false) - defer ctx.teardownTest() - - msgs := []api.Message{} - for m := 0; m < 10; m++ { - msgs = append(msgs, &interfaces.SwInterfaceDetails{}) - } - ctx.mockVpp.MockReply(msgs...) - ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) - - // send multipart request - ctx.ch.GetRequestChannel() <- &api.VppRequest{Message: &interfaces.SwInterfaceDump{}, Multipart: true} - - cnt := 0 - for { - // receive a reply - vppReply := <-ctx.ch.GetReplyChannel() - if vppReply.LastReplyReceived { - break // break out of the loop - } - Expect(vppReply.Error).ShouldNot(HaveOccurred()) - - // decode the message - reply := &interfaces.SwInterfaceDetails{} - err := ctx.ch.GetMessageDecoder().DecodeMsg(vppReply.Data, reply) - Expect(err).ShouldNot(HaveOccurred()) - cnt++ - } - - Expect(cnt).To(BeEquivalentTo(10)) -} - -func TestNotifications(t *testing.T) { - ctx := setupTest(t, false) - defer ctx.teardownTest() - - // subscribe for notification - notifChan := make(chan api.Message, 1) - subscription := &api.NotifSubscription{ - NotifChan: notifChan, - MsgFactory: interfaces.NewSwInterfaceSetFlags, - } - ctx.ch.GetNotificationChannel() <- &api.NotifSubscribeRequest{ - Subscription: subscription, - Subscribe: true, - } - err := <-ctx.ch.GetNotificationReplyChannel() - 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{0}) - - // receive the notification - notif := (<-notifChan).(*interfaces.SwInterfaceSetFlags) - - Expect(notif.SwIfIndex).To(BeEquivalentTo(3)) - - // unsubscribe notification - ctx.ch.GetNotificationChannel() <- &api.NotifSubscribeRequest{ - Subscription: subscription, - Subscribe: false, - } - err = <-ctx.ch.GetNotificationReplyChannel() - Expect(err).ShouldNot(HaveOccurred()) -} - func TestNilConnection(t *testing.T) { RegisterTestingT(t) var conn *core.Connection @@ -168,76 +75,35 @@ func TestNilConnection(t *testing.T) { Expect(err.Error()).To(ContainSubstring("nil")) } -func TestDoubleConnection(t *testing.T) { - ctx := setupTest(t, false) - defer ctx.teardownTest() - - conn, err := core.Connect(ctx.mockVpp) - Expect(err).Should(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("only one connection per process")) - Expect(conn).Should(BeNil()) -} - func TestAsyncConnection(t *testing.T) { ctx := setupTest(t, false) defer ctx.teardownTest() ctx.conn.Disconnect() - conn, ch, err := core.AsyncConnect(ctx.mockVpp) + conn, statusChan, err := core.AsyncConnect(ctx.mockVpp, core.DefaultMaxReconnectAttempts, core.DefaultReconnectInterval) ctx.conn = conn Expect(err).ShouldNot(HaveOccurred()) Expect(conn).ShouldNot(BeNil()) - ev := <-ch + ev := <-statusChan Expect(ev.State).Should(BeEquivalentTo(core.Connected)) } -func TestFullBuffer(t *testing.T) { - ctx := setupTest(t, false) - defer ctx.teardownTest() - - // close the default API channel - ctx.ch.Close() - - // create a new channel with limited buffer sizes - var err error - ctx.ch, err = ctx.conn.NewAPIChannelBuffered(10, 1) - Expect(err).ShouldNot(HaveOccurred()) - - // send multiple requests, only one reply should be read - for i := 0; i < 20; i++ { - ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) - ctx.ch.GetRequestChannel() <- &api.VppRequest{Message: &vpe.ControlPing{}} - } - - vppReply := <-ctx.ch.GetReplyChannel() - Expect(vppReply).ShouldNot(BeNil()) - - var received bool - select { - case <-ctx.ch.GetReplyChannel(): - received = true // this should not happen - default: - received = false // no reply to be received - } - Expect(received).Should(BeFalse(), "A reply has been recieved, should had been ignored.") -} - func TestCodec(t *testing.T) { RegisterTestingT(t) - msgCodec := &codec.MsgCodec{} + var msgCodec = codec.DefaultCodec // request - data, err := msgCodec.EncodeMsg(&interfaces.CreateLoopback{MacAddress: []byte{1, 2, 3, 4, 5, 6}}, 11) + data, err := msgCodec.EncodeMsg(&interfaces.CreateLoopback{MacAddress: interfaces.MacAddress{1, 2, 3, 4, 5, 6}}, 11) Expect(err).ShouldNot(HaveOccurred()) Expect(data).ShouldNot(BeEmpty()) msg1 := &interfaces.CreateLoopback{} err = msgCodec.DecodeMsg(data, msg1) Expect(err).ShouldNot(HaveOccurred()) - Expect(msg1.MacAddress).To(BeEquivalentTo([]byte{1, 2, 3, 4, 5, 6})) + Expect(msg1.MacAddress).To(BeEquivalentTo(interfaces.MacAddress{1, 2, 3, 4, 5, 6})) // reply data, err = msgCodec.EncodeMsg(&vpe.ControlPingReply{Retval: 55}, 22) @@ -248,22 +114,12 @@ func TestCodec(t *testing.T) { err = msgCodec.DecodeMsg(data, msg2) Expect(err).ShouldNot(HaveOccurred()) Expect(msg2.Retval).To(BeEquivalentTo(55)) - - // other - data, err = msgCodec.EncodeMsg(&stats.VnetIP4FibCounters{VrfID: 77}, 33) - Expect(err).ShouldNot(HaveOccurred()) - Expect(data).ShouldNot(BeEmpty()) - - msg3 := &stats.VnetIP4FibCounters{} - err = msgCodec.DecodeMsg(data, msg3) - Expect(err).ShouldNot(HaveOccurred()) - Expect(msg3.VrfID).To(BeEquivalentTo(77)) } func TestCodecNegative(t *testing.T) { RegisterTestingT(t) - msgCodec := &codec.MsgCodec{} + var msgCodec = codec.DefaultCodec // nil message for encoding data, err := msgCodec.EncodeMsg(nil, 15) @@ -279,7 +135,7 @@ func TestCodecNegative(t *testing.T) { // nil data for decoding err = msgCodec.DecodeMsg(nil, &vpe.ControlPingReply{}) Expect(err).Should(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("EOF")) + Expect(err.Error()).To(ContainSubstring("panic")) } func TestSimpleRequestsWithSequenceNumbers(t *testing.T) { @@ -288,7 +144,7 @@ func TestSimpleRequestsWithSequenceNumbers(t *testing.T) { var reqCtx []api.RequestCtx for i := 0; i < 10; i++ { - ctx.mockVpp.MockReply(&vpe.ControlPingReply{Retval: int32(i)}) + ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) req := &vpe.ControlPing{} reqCtx = append(reqCtx, ctx.ch.SendRequest(req)) } @@ -297,7 +153,6 @@ func TestSimpleRequestsWithSequenceNumbers(t *testing.T) { reply := &vpe.ControlPingReply{} err := reqCtx[i].ReceiveReply(reply) Expect(err).ShouldNot(HaveOccurred()) - Expect(reply.Retval).To(BeEquivalentTo(i)) } } @@ -305,9 +160,9 @@ func TestMultiRequestsWithSequenceNumbers(t *testing.T) { ctx := setupTest(t, false) defer ctx.teardownTest() - msgs := []api.Message{} + var msgs []api.Message for i := 0; i < 10; i++ { - msgs = append(msgs, &interfaces.SwInterfaceDetails{SwIfIndex: uint32(i)}) + msgs = append(msgs, &interfaces.SwInterfaceDetails{SwIfIndex: interface_types.InterfaceIndex(i)}) } ctx.mockVpp.MockReply(msgs...) ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) @@ -324,7 +179,7 @@ func TestMultiRequestsWithSequenceNumbers(t *testing.T) { lastReplyReceived, err := reqCtx.ReceiveReply(reply) if lastReplyReceived { - break // break out of the loop + break } Expect(err).ShouldNot(HaveOccurred()) @@ -342,7 +197,7 @@ func TestSimpleRequestWithTimeout(t *testing.T) { // reply for a previous timeouted requests to be ignored ctx.mockVpp.MockReplyWithContext(mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{Retval: 1}, + Msg: &vpe.ControlPingReply{}, SeqNum: 0, }) @@ -358,12 +213,12 @@ func TestSimpleRequestWithTimeout(t *testing.T) { ctx.mockVpp.MockReplyWithContext( // reply for the previous request mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{Retval: 1}, + Msg: &vpe.ControlPingReply{}, SeqNum: 1, }, // reply for the next request mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{Retval: 2}, + Msg: &vpe.ControlPingReply{}, SeqNum: 2, }) @@ -375,7 +230,6 @@ func TestSimpleRequestWithTimeout(t *testing.T) { reply = &vpe.ControlPingReply{} err = reqCtx2.ReceiveReply(reply) Expect(err).To(BeNil()) - Expect(reply.Retval).To(BeEquivalentTo(2)) } func TestSimpleRequestsWithMissingReply(t *testing.T) { @@ -392,7 +246,7 @@ func TestSimpleRequestsWithMissingReply(t *testing.T) { // third request with reply ctx.mockVpp.MockReplyWithContext(mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{Retval: 3}, + Msg: &vpe.ControlPingReply{}, SeqNum: 3, }) req3 := &vpe.ControlPing{} @@ -413,7 +267,6 @@ func TestSimpleRequestsWithMissingReply(t *testing.T) { reply = &vpe.ControlPingReply{} err = reqCtx3.ReceiveReply(reply) Expect(err).To(BeNil()) - Expect(reply.Retval).To(BeEquivalentTo(3)) } func TestMultiRequestsWithErrors(t *testing.T) { @@ -421,38 +274,25 @@ func TestMultiRequestsWithErrors(t *testing.T) { defer ctx.teardownTest() // replies for a previous timeouted requests to be ignored - msgs := []mock.MsgWithContext{} - msgs = append(msgs, - mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{Retval: 1}, - SeqNum: 0xffff - 1, - }, - mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{Retval: 1}, - SeqNum: 0xffff, - }, - mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{Retval: 1}, - SeqNum: 0, - }) - + msgs := []mock.MsgWithContext{ + {Msg: &vpe.ControlPingReply{}, SeqNum: 0xffff - 1}, + {Msg: &vpe.ControlPingReply{}, SeqNum: 0xffff}, + {Msg: &vpe.ControlPingReply{}, SeqNum: 0}, + } for i := 0; i < 10; i++ { - msgs = append(msgs, - mock.MsgWithContext{ - Msg: &interfaces.SwInterfaceDetails{SwIfIndex: uint32(i)}, - SeqNum: 1, - Multipart: true, - }) + msgs = append(msgs, mock.MsgWithContext{ + Msg: &interfaces.SwInterfaceDetails{SwIfIndex: interface_types.InterfaceIndex(i)}, + SeqNum: 1, + Multipart: true, + }) } // missing finalizing control ping // reply for a next request - msgs = append(msgs, - mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{Retval: 2}, - SeqNum: 2, - Multipart: false, - }) + msgs = append(msgs, mock.MsgWithContext{ + Msg: &vpe.ControlPingReply{}, + SeqNum: 2, + }) // queue replies ctx.mockVpp.MockReplyWithContext(msgs...) @@ -486,7 +326,6 @@ func TestMultiRequestsWithErrors(t *testing.T) { reply2 := &vpe.ControlPingReply{} err = reqCtx2.ReceiveReply(reply2) Expect(err).To(BeNil()) - Expect(reply2.Retval).To(BeEquivalentTo(2)) } func TestRequestsOrdering(t *testing.T) { @@ -497,12 +336,12 @@ func TestRequestsOrdering(t *testing.T) { // some replies will get thrown away // first request - ctx.mockVpp.MockReply(&vpe.ControlPingReply{Retval: 1}) + ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) req1 := &vpe.ControlPing{} reqCtx1 := ctx.ch.SendRequest(req1) // second request - ctx.mockVpp.MockReply(&vpe.ControlPingReply{Retval: 2}) + ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) req2 := &vpe.ControlPing{} reqCtx2 := ctx.ch.SendRequest(req2) @@ -511,7 +350,6 @@ func TestRequestsOrdering(t *testing.T) { reply2 := &vpe.ControlPingReply{} err := reqCtx2.ReceiveReply(reply2) Expect(err).To(BeNil()) - Expect(reply2.Retval).To(BeEquivalentTo(2)) // first request has already been considered closed reply1 := &vpe.ControlPingReply{} @@ -521,15 +359,15 @@ func TestRequestsOrdering(t *testing.T) { } func TestCycleOverSetOfSequenceNumbers(t *testing.T) { - ctx := setupTest(t, true) + ctx := setupTest(t, false) defer ctx.teardownTest() numIters := 0xffff + 100 reqCtx := make(map[int]api.RequestCtx) - for i := 0; i < numIters+30; /* receiver is 30 reqs behind */ i++ { + for i := 0; i < numIters+30; i++ { if i < numIters { - ctx.mockVpp.MockReply(&vpe.ControlPingReply{Retval: int32(i)}) + ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) req := &vpe.ControlPing{} reqCtx[i] = ctx.ch.SendRequest(req) } @@ -537,7 +375,6 @@ func TestCycleOverSetOfSequenceNumbers(t *testing.T) { reply := &vpe.ControlPingReply{} err := reqCtx[i-30].ReceiveReply(reply) Expect(err).ShouldNot(HaveOccurred()) - Expect(reply.Retval).To(BeEquivalentTo(i - 30)) } } }