introduce an interface for the send queue, use a mock in session tests

This commit is contained in:
Marten Seemann 2020-12-31 13:34:34 +08:00
parent e9848fadf9
commit f1c6421845
6 changed files with 117 additions and 22 deletions

72
mock_sender_test.go Normal file
View file

@ -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)
}

View file

@ -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"

View file

@ -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{}),

View file

@ -9,7 +9,7 @@ import (
)
var _ = Describe("Send Queue", func() {
var q *sendQueue
var q sender
var c *MockSendConn
BeforeEach(func() {

View file

@ -137,7 +137,7 @@ type session struct {
config *Config
conn sendConn
sendQueue *sendQueue
sendQueue sender
streamsMap streamManager
connIDManager *connIDManager

View file

@ -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()