From f1c6421845a1e45345d7921a47d9901158234d4d Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 31 Dec 2020 13:34:34 +0800 Subject: [PATCH] introduce an interface for the send queue, use a mock in session tests --- mock_sender_test.go | 72 +++++++++++++++++++++++++++++++++++++++++++++ mockgen.go | 1 + send_queue.go | 10 ++++++- send_queue_test.go | 2 +- session.go | 2 +- session_test.go | 52 ++++++++++++++++++++------------ 6 files changed, 117 insertions(+), 22 deletions(-) create mode 100644 mock_sender_test.go diff --git a/mock_sender_test.go b/mock_sender_test.go new file mode 100644 index 00000000..462e9763 --- /dev/null +++ b/mock_sender_test.go @@ -0,0 +1,72 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/lucas-clemente/quic-go (interfaces: Sender) + +// Package quic is a generated GoMock package. +package quic + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockSender is a mock of Sender interface +type MockSender struct { + ctrl *gomock.Controller + recorder *MockSenderMockRecorder +} + +// MockSenderMockRecorder is the mock recorder for MockSender +type MockSenderMockRecorder struct { + mock *MockSender +} + +// NewMockSender creates a new mock instance +func NewMockSender(ctrl *gomock.Controller) *MockSender { + mock := &MockSender{ctrl: ctrl} + mock.recorder = &MockSenderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockSender) EXPECT() *MockSenderMockRecorder { + return m.recorder +} + +// Close mocks base method +func (m *MockSender) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close +func (mr *MockSenderMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSender)(nil).Close)) +} + +// Run mocks base method +func (m *MockSender) Run() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Run") + ret0, _ := ret[0].(error) + return ret0 +} + +// Run indicates an expected call of Run +func (mr *MockSenderMockRecorder) Run() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockSender)(nil).Run)) +} + +// Send mocks base method +func (m *MockSender) Send(arg0 *packetBuffer) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Send", arg0) +} + +// Send indicates an expected call of Send +func (mr *MockSenderMockRecorder) Send(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockSender)(nil).Send), arg0) +} diff --git a/mockgen.go b/mockgen.go index 7f0ba432..8f6b0578 100644 --- a/mockgen.go +++ b/mockgen.go @@ -1,6 +1,7 @@ package quic //go:generate sh -c "./mockgen_private.sh quic mock_send_conn_test.go github.com/lucas-clemente/quic-go sendConn" +//go:generate sh -c "./mockgen_private.sh quic mock_sender_test.go github.com/lucas-clemente/quic-go sender" //go:generate sh -c "./mockgen_private.sh quic mock_stream_internal_test.go github.com/lucas-clemente/quic-go streamI" //go:generate sh -c "./mockgen_private.sh quic mock_crypto_stream_test.go github.com/lucas-clemente/quic-go cryptoStream" //go:generate sh -c "./mockgen_private.sh quic mock_receive_stream_internal_test.go github.com/lucas-clemente/quic-go receiveStreamI" diff --git a/send_queue.go b/send_queue.go index 97d04dba..04ba48ed 100644 --- a/send_queue.go +++ b/send_queue.go @@ -1,5 +1,11 @@ package quic +type sender interface { + Send(p *packetBuffer) + Run() error + Close() +} + type sendQueue struct { queue chan *packetBuffer closeCalled chan struct{} // runStopped when Close() is called @@ -7,7 +13,9 @@ type sendQueue struct { conn sendConn } -func newSendQueue(conn sendConn) *sendQueue { +var _ sender = &sendQueue{} + +func newSendQueue(conn sendConn) sender { s := &sendQueue{ conn: conn, runStopped: make(chan struct{}), diff --git a/send_queue_test.go b/send_queue_test.go index b82b6dfc..710206fd 100644 --- a/send_queue_test.go +++ b/send_queue_test.go @@ -9,7 +9,7 @@ import ( ) var _ = Describe("Send Queue", func() { - var q *sendQueue + var q sender var c *MockSendConn BeforeEach(func() { diff --git a/session.go b/session.go index eef65d2e..3a8746f6 100644 --- a/session.go +++ b/session.go @@ -137,7 +137,7 @@ type session struct { config *Config conn sendConn - sendQueue *sendQueue + sendQueue sender streamsMap streamManager connIDManager *connIDManager diff --git a/session_test.go b/session_test.go index 9163d44d..9761c008 100644 --- a/session_test.go +++ b/session_test.go @@ -1207,10 +1207,16 @@ var _ = Describe("Session", func() { }) Context("sending packets", func() { - var sessionDone chan struct{} + var ( + sessionDone chan struct{} + sender *MockSender + ) BeforeEach(func() { + sender = NewMockSender(mockCtrl) + sess.sendQueue = sender sessionDone = make(chan struct{}) + sender.EXPECT().Run() }) AfterEach(func() { @@ -1221,6 +1227,7 @@ var _ = Describe("Session", func() { mconn.EXPECT().Write(gomock.Any()) tracer.EXPECT().ClosedConnection(gomock.Any()) tracer.EXPECT().Close() + sender.EXPECT().Close() sess.shutdown() Eventually(sess.Context().Done()).Should(BeClosed()) Eventually(sessionDone).Should(BeClosed()) @@ -1249,7 +1256,7 @@ var _ = Describe("Session", func() { packer.EXPECT().PackPacket().Return(p, nil) packer.EXPECT().PackPacket().Return(nil, nil).AnyTimes() sent := make(chan struct{}) - mconn.EXPECT().Write(gomock.Any()).Do(func([]byte) { close(sent) }) + sender.EXPECT().Send(gomock.Any()).Do(func(packet *packetBuffer) { close(sent) }) tracer.EXPECT().SentPacket(p.header, p.buffer.Len(), nil, []logging.Frame{}) sess.scheduleSending() Eventually(sent).Should(BeClosed()) @@ -1295,7 +1302,7 @@ var _ = Describe("Session", func() { sess.connFlowController = fc runSession() sent := make(chan struct{}) - mconn.EXPECT().Write(gomock.Any()).Do(func([]byte) { close(sent) }) + sender.EXPECT().Send(gomock.Any()).Do(func(packet *packetBuffer) { close(sent) }) tracer.EXPECT().SentPacket(p.header, p.length, nil, []logging.Frame{}) sess.scheduleSending() Eventually(sent).Should(BeClosed()) @@ -1351,7 +1358,7 @@ var _ = Describe("Session", func() { sess.sentPacketHandler = sph runSession() sent := make(chan struct{}) - mconn.EXPECT().Write(gomock.Any()).Do(func([]byte) { close(sent) }) + sender.EXPECT().Send(gomock.Any()).Do(func(packet *packetBuffer) { close(sent) }) tracer.EXPECT().SentPacket(p.header, p.length, gomock.Any(), gomock.Any()) sess.scheduleSending() Eventually(sent).Should(BeClosed()) @@ -1372,7 +1379,7 @@ var _ = Describe("Session", func() { sess.sentPacketHandler = sph runSession() sent := make(chan struct{}) - mconn.EXPECT().Write(gomock.Any()).Do(func([]byte) { close(sent) }) + sender.EXPECT().Send(gomock.Any()).Do(func(packet *packetBuffer) { close(sent) }) tracer.EXPECT().SentPacket(p.header, p.length, gomock.Any(), gomock.Any()) sess.scheduleSending() Eventually(sent).Should(BeClosed()) @@ -1385,7 +1392,10 @@ var _ = Describe("Session", func() { }) Context("packet pacing", func() { - var sph *mockackhandler.MockSentPacketHandler + var ( + sph *mockackhandler.MockSentPacketHandler + sender *MockSender + ) BeforeEach(func() { tracer.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() @@ -1394,6 +1404,9 @@ var _ = Describe("Session", func() { sess.handshakeConfirmed = true sess.handshakeComplete = true sess.sentPacketHandler = sph + sender = NewMockSender(mockCtrl) + sender.EXPECT().Run() + sess.sendQueue = sender streamManager.EXPECT().CloseWithError(gomock.Any()) }) @@ -1405,6 +1418,7 @@ var _ = Describe("Session", func() { mconn.EXPECT().Write(gomock.Any()) tracer.EXPECT().ClosedConnection(gomock.Any()) tracer.EXPECT().Close() + sender.EXPECT().Close() sess.shutdown() Eventually(sess.Context().Done()).Should(BeClosed()) }) @@ -1417,7 +1431,7 @@ var _ = Describe("Session", func() { sph.EXPECT().SendMode().Return(ackhandler.SendAny).Times(3) packer.EXPECT().PackPacket().Return(getPacket(10), nil) packer.EXPECT().PackPacket().Return(getPacket(11), nil) - mconn.EXPECT().Write(gomock.Any()).Times(2) + sender.EXPECT().Send(gomock.Any()).Times(2) go func() { defer GinkgoRecover() cryptoSetup.EXPECT().RunHandshake().MaxTimes(1) @@ -1435,7 +1449,7 @@ var _ = Describe("Session", func() { sph.EXPECT().SendMode().Return(ackhandler.SendAny).Times(3) packer.EXPECT().PackPacket().Return(getPacket(10), nil) packer.EXPECT().PackPacket().Return(nil, nil) - mconn.EXPECT().Write(gomock.Any()) + sender.EXPECT().Send(gomock.Any()) go func() { defer GinkgoRecover() cryptoSetup.EXPECT().RunHandshake().MaxTimes(1) @@ -1453,7 +1467,7 @@ var _ = Describe("Session", func() { sph.EXPECT().SendMode().Return(ackhandler.SendAny) sph.EXPECT().SendMode().Return(ackhandler.SendAck) packer.EXPECT().PackPacket().Return(getPacket(100), nil) - mconn.EXPECT().Write(gomock.Any()) + sender.EXPECT().Send(gomock.Any()) go func() { defer GinkgoRecover() cryptoSetup.EXPECT().RunHandshake().MaxTimes(1) @@ -1479,10 +1493,7 @@ var _ = Describe("Session", func() { sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour)), ) written := make(chan struct{}, 2) - mconn.EXPECT().Write(gomock.Any()).DoAndReturn(func(p []byte) (int, error) { - written <- struct{}{} - return len(p), nil - }).Times(2) + sender.EXPECT().Send(gomock.Any()).DoAndReturn(func(p *packetBuffer) { written <- struct{}{} }).Times(2) go func() { defer GinkgoRecover() cryptoSetup.EXPECT().RunHandshake().MaxTimes(1) @@ -1504,10 +1515,7 @@ var _ = Describe("Session", func() { packer.EXPECT().PackPacket().Return(getPacket(1001), nil) packer.EXPECT().PackPacket().Return(getPacket(1002), nil) written := make(chan struct{}, 3) - mconn.EXPECT().Write(gomock.Any()).DoAndReturn(func(p []byte) (int, error) { - written <- struct{}{} - return len(p), nil - }).Times(3) + sender.EXPECT().Send(gomock.Any()).DoAndReturn(func(p *packetBuffer) { written <- struct{}{} }).Times(3) go func() { defer GinkgoRecover() cryptoSetup.EXPECT().RunHandshake().MaxTimes(1) @@ -1533,7 +1541,12 @@ var _ = Describe("Session", func() { }) Context("scheduling sending", func() { + var sender *MockSender + BeforeEach(func() { + sender = NewMockSender(mockCtrl) + sender.EXPECT().Run() + sess.sendQueue = sender sess.handshakeConfirmed = true }) @@ -1544,6 +1557,7 @@ var _ = Describe("Session", func() { packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil) cryptoSetup.EXPECT().Close() mconn.EXPECT().Write(gomock.Any()) + sender.EXPECT().Close() tracer.EXPECT().ClosedConnection(gomock.Any()) tracer.EXPECT().Close() sess.shutdown() @@ -1570,7 +1584,7 @@ var _ = Describe("Session", func() { time.Sleep(50 * time.Millisecond) // only EXPECT calls after scheduleSending is called written := make(chan struct{}) - mconn.EXPECT().Write(gomock.Any()).Do(func([]byte) { close(written) }) + sender.EXPECT().Send(gomock.Any()).Do(func(*packetBuffer) { close(written) }) tracer.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() sess.scheduleSending() Eventually(written).Should(BeClosed()) @@ -1594,7 +1608,7 @@ var _ = Describe("Session", func() { sess.receivedPacketHandler = rph written := make(chan struct{}) - mconn.EXPECT().Write(gomock.Any()).Do(func([]byte) { close(written) }) + sender.EXPECT().Send(gomock.Any()).Do(func(*packetBuffer) { close(written) }) tracer.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() go func() { defer GinkgoRecover()