add tests for the Client

This commit is contained in:
Marten Seemann 2016-12-05 00:58:08 +07:00
parent dde5ce465c
commit 4b112c325a
No known key found for this signature in database
GPG key ID: 3603F40B121FCDEA
3 changed files with 84 additions and 4 deletions

View file

@ -93,6 +93,8 @@ func (c *Client) Listen() error {
err = c.handlePacket(data) err = c.handlePacket(data)
if err != nil { if err != nil {
utils.Errorf("error handling packet: %s", err.Error()) utils.Errorf("error handling packet: %s", err.Error())
c.session.Close(err)
return err
} }
} }
} }

View file

@ -13,9 +13,12 @@ import (
var _ = Describe("Client", func() { var _ = Describe("Client", func() {
var client *Client var client *Client
var session *mockSession
BeforeEach(func() { BeforeEach(func() {
client = &Client{} client = &Client{}
session = &mockSession{}
client.session = session
}) })
It("errors on invalid public header", func() { It("errors on invalid public header", func() {
@ -33,9 +36,79 @@ var _ = Describe("Client", func() {
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
client.conn, err = net.ListenUDP("udp", addr) client.conn, err = net.ListenUDP("udp", addr)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
client.session = &mockSession{}
err = client.Close() err = client.Close()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(client.session.(*mockSession).closed).To(BeTrue()) Expect(session.closed).To(BeTrue())
Expect(session.closeReason).To(BeNil())
})
Context("handling packets", func() {
It("errors on too large packets", func() {
err := client.handlePacket(bytes.Repeat([]byte{'f'}, int(protocol.MaxPacketSize+1)))
Expect(err).To(MatchError(qerr.PacketTooLarge))
})
It("handles packets", func(done Done) {
var err error
client.addr, err = net.ResolveUDPAddr("udp", "127.0.0.1:0")
Expect(err).ToNot(HaveOccurred())
client.conn, err = net.ListenUDP("udp", client.addr)
Expect(err).NotTo(HaveOccurred())
serverConn, err := net.DialUDP("udp", nil, client.conn.LocalAddr().(*net.UDPAddr))
Expect(err).NotTo(HaveOccurred())
go func() {
defer GinkgoRecover()
listenErr := client.Listen()
Expect(listenErr).ToNot(HaveOccurred())
close(done)
}()
Expect(session.packetCount).To(BeZero())
ph := PublicHeader{
PacketNumber: 1,
PacketNumberLen: protocol.PacketNumberLen2,
ConnectionID: 0x1337,
}
b := &bytes.Buffer{}
err = ph.Write(b, protocol.Version36, protocol.PerspectiveServer)
Expect(err).ToNot(HaveOccurred())
_, err = serverConn.Write(b.Bytes())
Expect(err).ToNot(HaveOccurred())
Eventually(func() int { return session.packetCount }).Should(Equal(1))
Expect(session.closed).To(BeFalse())
err = client.Close()
Expect(err).ToNot(HaveOccurred())
})
It("closes the session when encountering an error while handling a packet", func(done Done) {
var err error
client.addr, err = net.ResolveUDPAddr("udp", "127.0.0.1:0")
Expect(err).ToNot(HaveOccurred())
client.conn, err = net.ListenUDP("udp", client.addr)
Expect(err).NotTo(HaveOccurred())
serverConn, err := net.DialUDP("udp", nil, client.conn.LocalAddr().(*net.UDPAddr))
Expect(err).NotTo(HaveOccurred())
var listenErr error
go func() {
defer GinkgoRecover()
listenErr = client.Listen()
Expect(listenErr).To(HaveOccurred())
close(done)
}()
// cause a PacketTooLarge error
_, err = serverConn.Write(bytes.Repeat([]byte{'f'}, 100))
Expect(err).ToNot(HaveOccurred())
Eventually(func() bool { return session.closed }).Should(BeTrue())
Expect(session.closeReason).To(MatchError(listenErr))
err = client.Close()
Expect(err).ToNot(HaveOccurred())
})
}) })
}) })

View file

@ -20,14 +20,19 @@ type mockSession struct {
connectionID protocol.ConnectionID connectionID protocol.ConnectionID
packetCount int packetCount int
closed bool closed bool
closeReason error
} }
func (s *mockSession) handlePacket(*receivedPacket) { func (s *mockSession) handlePacket(*receivedPacket) {
s.packetCount++ s.packetCount++
} }
func (s *mockSession) run() {} func (s *mockSession) run() {}
func (s *mockSession) Close(error) error { s.closed = true; return nil } func (s *mockSession) Close(e error) error {
s.closed = true
s.closeReason = e
return nil
}
func newMockSession(conn connection, v protocol.VersionNumber, connectionID protocol.ConnectionID, sCfg *handshake.ServerConfig, streamCallback StreamCallback, closeCallback closeCallback) (packetHandler, error) { func newMockSession(conn connection, v protocol.VersionNumber, connectionID protocol.ConnectionID, sCfg *handshake.ServerConfig, streamCallback StreamCallback, closeCallback closeCallback) (packetHandler, error) {
return &mockSession{ return &mockSession{