X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=core%2Fconnection_test.go;h=fe2f191b0458f09dac8528a53fda29a27befc57b;hb=67cea0df30f7ef348e265c9326f7a9f15ba26240;hp=643d4a38ade235080d1c71f702353ebc6d7d9f45;hpb=ceed73403bdb61387d04be8b47183e9c4a970749;p=govpp.git diff --git a/core/connection_test.go b/core/connection_test.go index 643d4a3..fe2f191 100644 --- a/core/connection_test.go +++ b/core/connection_test.go @@ -16,15 +16,18 @@ package core_test import ( "testing" + "time" . "github.com/onsi/gomega" - "git.fd.io/govpp.git/adapter/mock" - "git.fd.io/govpp.git/api" - "git.fd.io/govpp.git/codec" - "git.fd.io/govpp.git/core" - "git.fd.io/govpp.git/examples/binapi/interfaces" - "git.fd.io/govpp.git/examples/binapi/vpe" + "go.fd.io/govpp/adapter/mock" + "go.fd.io/govpp/api" + "go.fd.io/govpp/binapi/ethernet_types" + interfaces "go.fd.io/govpp/binapi/interface" + "go.fd.io/govpp/binapi/interface_types" + memclnt "go.fd.io/govpp/binapi/memclnt" + "go.fd.io/govpp/codec" + "go.fd.io/govpp/core" ) type testCtx struct { @@ -89,27 +92,49 @@ func TestAsyncConnection(t *testing.T) { Expect(ev.State).Should(BeEquivalentTo(core.Connected)) } +func TestAsyncConnectionProcessesVppTimeout(t *testing.T) { + ctx := setupTest(t, false) + defer ctx.teardownTest() + + ctx.conn.Disconnect() + conn, statusChan, err := core.AsyncConnect(ctx.mockVpp, core.DefaultMaxReconnectAttempts, core.DefaultReconnectInterval) + ctx.conn = conn + + Expect(err).ShouldNot(HaveOccurred()) + Expect(conn).ShouldNot(BeNil()) + + ev := <-statusChan + Expect(ev.State).Should(BeEquivalentTo(core.Connected)) + + // make control ping reply fail so that connection.healthCheckLoop() + // initiates reconnection. + ctx.mockVpp.MockReply(&memclnt.ControlPingReply{ + Retval: -1, + }) + time.Sleep(time.Duration(1+core.HealthCheckThreshold) * (core.HealthCheckInterval + 2*core.HealthCheckReplyTimeout)) +} + func TestCodec(t *testing.T) { RegisterTestingT(t) var msgCodec = codec.DefaultCodec // request - data, err := msgCodec.EncodeMsg(&interfaces.CreateLoopback{MacAddress: interfaces.MacAddress{1, 2, 3, 4, 5, 6}}, 11) + data, err := msgCodec.EncodeMsg(&interfaces.CreateLoopback{MacAddress: ethernet_types.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(interfaces.MacAddress{1, 2, 3, 4, 5, 6})) + Expect(msg1.MacAddress).To(BeEquivalentTo(ethernet_types.MacAddress{1, 2, 3, 4, 5, 6})) // reply - data, err = msgCodec.EncodeMsg(&vpe.ControlPingReply{Retval: 55}, 22) + data, err = msgCodec.EncodeMsg(&memclnt.ControlPingReply{Retval: 55}, 22) Expect(err).ShouldNot(HaveOccurred()) Expect(data).ShouldNot(BeEmpty()) - msg2 := &vpe.ControlPingReply{} + msg2 := &memclnt.ControlPingReply{} err = msgCodec.DecodeMsg(data, msg2) Expect(err).ShouldNot(HaveOccurred()) Expect(msg2.Retval).To(BeEquivalentTo(55)) @@ -132,7 +157,7 @@ func TestCodecNegative(t *testing.T) { Expect(err.Error()).To(ContainSubstring("nil message")) // nil data for decoding - err = msgCodec.DecodeMsg(nil, &vpe.ControlPingReply{}) + err = msgCodec.DecodeMsg(nil, &memclnt.ControlPingReply{}) Expect(err).Should(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("panic")) } @@ -143,13 +168,13 @@ func TestSimpleRequestsWithSequenceNumbers(t *testing.T) { var reqCtx []api.RequestCtx for i := 0; i < 10; i++ { - ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) - req := &vpe.ControlPing{} + ctx.mockVpp.MockReply(&memclnt.ControlPingReply{}) + req := &memclnt.ControlPing{} reqCtx = append(reqCtx, ctx.ch.SendRequest(req)) } for i := 0; i < 10; i++ { - reply := &vpe.ControlPingReply{} + reply := &memclnt.ControlPingReply{} err := reqCtx[i].ReceiveReply(reply) Expect(err).ShouldNot(HaveOccurred()) } @@ -161,10 +186,10 @@ func TestMultiRequestsWithSequenceNumbers(t *testing.T) { var msgs []api.Message for i := 0; i < 10; i++ { - msgs = append(msgs, &interfaces.SwInterfaceDetails{SwIfIndex: interfaces.InterfaceIndex(i)}) + msgs = append(msgs, &interfaces.SwInterfaceDetails{SwIfIndex: interface_types.InterfaceIndex(i)}) } ctx.mockVpp.MockReply(msgs...) - ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) + ctx.mockVpp.MockReply(&memclnt.ControlPingReply{}) // send multipart request reqCtx := ctx.ch.SendMultiRequest(&interfaces.SwInterfaceDump{}) @@ -196,15 +221,15 @@ func TestSimpleRequestWithTimeout(t *testing.T) { // reply for a previous timeouted requests to be ignored ctx.mockVpp.MockReplyWithContext(mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{}, + Msg: &memclnt.ControlPingReply{}, SeqNum: 0, }) // send reply later - req1 := &vpe.ControlPing{} + req1 := &memclnt.ControlPing{} reqCtx1 := ctx.ch.SendRequest(req1) - reply := &vpe.ControlPingReply{} + reply := &memclnt.ControlPingReply{} err := reqCtx1.ReceiveReply(reply) Expect(err).ToNot(BeNil()) Expect(err.Error()).To(HavePrefix("no reply received within the timeout period")) @@ -212,21 +237,21 @@ func TestSimpleRequestWithTimeout(t *testing.T) { ctx.mockVpp.MockReplyWithContext( // reply for the previous request mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{}, + Msg: &memclnt.ControlPingReply{}, SeqNum: 1, }, // reply for the next request mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{}, + Msg: &memclnt.ControlPingReply{}, SeqNum: 2, }) // next request - req2 := &vpe.ControlPing{} + req2 := &memclnt.ControlPing{} reqCtx2 := ctx.ch.SendRequest(req2) // second request should ignore the first reply and return the second one - reply = &vpe.ControlPingReply{} + reply = &memclnt.ControlPingReply{} err = reqCtx2.ReceiveReply(reply) Expect(err).To(BeNil()) } @@ -236,34 +261,34 @@ func TestSimpleRequestsWithMissingReply(t *testing.T) { defer ctx.teardownTest() // request without reply - req1 := &vpe.ControlPing{} + req1 := &memclnt.ControlPing{} reqCtx1 := ctx.ch.SendRequest(req1) // another request without reply - req2 := &vpe.ControlPing{} + req2 := &memclnt.ControlPing{} reqCtx2 := ctx.ch.SendRequest(req2) // third request with reply ctx.mockVpp.MockReplyWithContext(mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{}, + Msg: &memclnt.ControlPingReply{}, SeqNum: 3, }) - req3 := &vpe.ControlPing{} + req3 := &memclnt.ControlPing{} reqCtx3 := ctx.ch.SendRequest(req3) // the first two should fail, but not consume reply for the 3rd - reply := &vpe.ControlPingReply{} + reply := &memclnt.ControlPingReply{} err := reqCtx1.ReceiveReply(reply) Expect(err).ToNot(BeNil()) Expect(err.Error()).To(Equal("missing binary API reply with sequence number: 1")) - reply = &vpe.ControlPingReply{} + reply = &memclnt.ControlPingReply{} err = reqCtx2.ReceiveReply(reply) Expect(err).ToNot(BeNil()) Expect(err.Error()).To(Equal("missing binary API reply with sequence number: 2")) // the second request should succeed - reply = &vpe.ControlPingReply{} + reply = &memclnt.ControlPingReply{} err = reqCtx3.ReceiveReply(reply) Expect(err).To(BeNil()) } @@ -274,13 +299,13 @@ func TestMultiRequestsWithErrors(t *testing.T) { // replies for a previous timeouted requests to be ignored msgs := []mock.MsgWithContext{ - {Msg: &vpe.ControlPingReply{}, SeqNum: 0xffff - 1}, - {Msg: &vpe.ControlPingReply{}, SeqNum: 0xffff}, - {Msg: &vpe.ControlPingReply{}, SeqNum: 0}, + {Msg: &memclnt.ControlPingReply{}, SeqNum: 0xffff - 1}, + {Msg: &memclnt.ControlPingReply{}, SeqNum: 0xffff}, + {Msg: &memclnt.ControlPingReply{}, SeqNum: 0}, } for i := 0; i < 10; i++ { msgs = append(msgs, mock.MsgWithContext{ - Msg: &interfaces.SwInterfaceDetails{SwIfIndex: interfaces.InterfaceIndex(i)}, + Msg: &interfaces.SwInterfaceDetails{SwIfIndex: interface_types.InterfaceIndex(i)}, SeqNum: 1, Multipart: true, }) @@ -289,7 +314,7 @@ func TestMultiRequestsWithErrors(t *testing.T) { // reply for a next request msgs = append(msgs, mock.MsgWithContext{ - Msg: &vpe.ControlPingReply{}, + Msg: &memclnt.ControlPingReply{}, SeqNum: 2, }) @@ -321,8 +346,8 @@ func TestMultiRequestsWithErrors(t *testing.T) { Expect(err.Error()).To(Equal("missing binary API reply with sequence number: 1")) // reply for the second request has not been consumed - reqCtx2 := ctx.ch.SendRequest(&vpe.ControlPing{}) - reply2 := &vpe.ControlPingReply{} + reqCtx2 := ctx.ch.SendRequest(&memclnt.ControlPing{}) + reply2 := &memclnt.ControlPingReply{} err = reqCtx2.ReceiveReply(reply2) Expect(err).To(BeNil()) } @@ -335,23 +360,23 @@ func TestRequestsOrdering(t *testing.T) { // some replies will get thrown away // first request - ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) - req1 := &vpe.ControlPing{} + ctx.mockVpp.MockReply(&memclnt.ControlPingReply{}) + req1 := &memclnt.ControlPing{} reqCtx1 := ctx.ch.SendRequest(req1) // second request - ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) - req2 := &vpe.ControlPing{} + ctx.mockVpp.MockReply(&memclnt.ControlPingReply{}) + req2 := &memclnt.ControlPing{} reqCtx2 := ctx.ch.SendRequest(req2) // if reply for the second request is read first, the reply for the first // request gets thrown away. - reply2 := &vpe.ControlPingReply{} + reply2 := &memclnt.ControlPingReply{} err := reqCtx2.ReceiveReply(reply2) Expect(err).To(BeNil()) // first request has already been considered closed - reply1 := &vpe.ControlPingReply{} + reply1 := &memclnt.ControlPingReply{} err = reqCtx1.ReceiveReply(reply1) Expect(err).ToNot(BeNil()) Expect(err.Error()).To(HavePrefix("no reply received within the timeout period")) @@ -366,12 +391,12 @@ func TestCycleOverSetOfSequenceNumbers(t *testing.T) { for i := 0; i < numIters+30; i++ { if i < numIters { - ctx.mockVpp.MockReply(&vpe.ControlPingReply{}) - req := &vpe.ControlPing{} + ctx.mockVpp.MockReply(&memclnt.ControlPingReply{}) + req := &memclnt.ControlPing{} reqCtx[i] = ctx.ch.SendRequest(req) } if i > 30 { - reply := &vpe.ControlPingReply{} + reply := &memclnt.ControlPingReply{} err := reqCtx[i-30].ReceiveReply(reply) Expect(err).ShouldNot(HaveOccurred()) }