Skip to content

Commit

Permalink
Workaround for Go 1.16 (#642)
Browse files Browse the repository at this point in the history
* Fix Go1.16

* Add more tests

* Add build tag

* Add Go 1.16 to appveyor.yml
  • Loading branch information
robinknaapen committed Apr 11, 2021
1 parent 045585d commit d9abbec
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 20 deletions.
3 changes: 3 additions & 0 deletions appveyor.yml
Expand Up @@ -39,6 +39,9 @@ environment:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
GOVERSION: 115
SQLINSTANCE: SQL2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
GOVERSION: 116
SQLINSTANCE: SQL2017

install:
- set GOROOT=c:\go%GOVERSION%
Expand Down
40 changes: 20 additions & 20 deletions net.go
Expand Up @@ -7,8 +7,8 @@ import (
)

type timeoutConn struct {
c net.Conn
timeout time.Duration
c net.Conn
timeout time.Duration
}

func newTimeoutConn(conn net.Conn, timeout time.Duration) *timeoutConn {
Expand Down Expand Up @@ -51,21 +51,21 @@ func (c timeoutConn) RemoteAddr() net.Addr {
}

func (c timeoutConn) SetDeadline(t time.Time) error {
panic("Not implemented")
return c.c.SetDeadline(t)
}

func (c timeoutConn) SetReadDeadline(t time.Time) error {
panic("Not implemented")
return c.c.SetReadDeadline(t)
}

func (c timeoutConn) SetWriteDeadline(t time.Time) error {
panic("Not implemented")
return c.c.SetWriteDeadline(t)
}

// this connection is used during TLS Handshake
// TDS protocol requires TLS handshake messages to be sent inside TDS packets
type tlsHandshakeConn struct {
buf *tdsBuffer
buf *tdsBuffer
packetPending bool
continueRead bool
}
Expand Down Expand Up @@ -105,27 +105,27 @@ func (c *tlsHandshakeConn) Write(b []byte) (n int, err error) {
}

func (c *tlsHandshakeConn) Close() error {
panic("Not implemented")
return c.buf.transport.Close()
}

func (c *tlsHandshakeConn) LocalAddr() net.Addr {
panic("Not implemented")
return nil
}

func (c *tlsHandshakeConn) RemoteAddr() net.Addr {
panic("Not implemented")
return nil
}

func (c *tlsHandshakeConn) SetDeadline(t time.Time) error {
panic("Not implemented")
func (c *tlsHandshakeConn) SetDeadline(_ time.Time) error {
return nil
}

func (c *tlsHandshakeConn) SetReadDeadline(t time.Time) error {
panic("Not implemented")
func (c *tlsHandshakeConn) SetReadDeadline(_ time.Time) error {
return nil
}

func (c *tlsHandshakeConn) SetWriteDeadline(t time.Time) error {
panic("Not implemented")
func (c *tlsHandshakeConn) SetWriteDeadline(_ time.Time) error {
return nil
}

// this connection just delegates all methods to it's wrapped connection
Expand All @@ -148,21 +148,21 @@ func (c passthroughConn) Close() error {
}

func (c passthroughConn) LocalAddr() net.Addr {
panic("Not implemented")
return c.c.LocalAddr()
}

func (c passthroughConn) RemoteAddr() net.Addr {
panic("Not implemented")
return c.c.RemoteAddr()
}

func (c passthroughConn) SetDeadline(t time.Time) error {
panic("Not implemented")
return c.c.SetDeadline(t)
}

func (c passthroughConn) SetReadDeadline(t time.Time) error {
panic("Not implemented")
return c.c.SetReadDeadline(t)
}

func (c passthroughConn) SetWriteDeadline(t time.Time) error {
panic("Not implemented")
return c.c.SetWriteDeadline(t)
}
172 changes: 172 additions & 0 deletions net_go116_test.go
@@ -0,0 +1,172 @@
// +build go1.16

package mssql

import (
"context"
"net"
"testing"
"time"
)

func assertPanic(t *testing.T, paniced bool) {
v := recover()
if paniced && v == nil {
t.Fatalf(`expected panic but it did not`)
}

if !paniced && v != nil {
t.Fatalf(`expected no panic but it did`)
}
}

func TestTimeoutConn(t *testing.T) {
_, conn := net.Pipe()

tconn := newTimeoutConn(conn, time.Minute)
t.Run(`set deadline`, func(t *testing.T) {
defer assertPanic(t, false)
deadline := time.Now().Add(time.Millisecond * 100)

err := tconn.SetDeadline(deadline)
if err != nil {
t.Fatalf(`SetDeadline should return nil`)
}
})

t.Run(`set read deadline`, func(t *testing.T) {
defer assertPanic(t, false)
deadline := time.Now().Add(time.Minute)

err := tconn.SetReadDeadline(deadline)
if err != nil {
t.Fatalf(`SetReadDeadline should return nil`)
}
})

t.Run(`set write deadline`, func(t *testing.T) {
defer assertPanic(t, false)
deadline := time.Now().Add(time.Minute)

err := tconn.SetWriteDeadline(deadline)
if err != nil {
t.Fatalf(`SetWriteDeadline should return nil`)
}
})
}

func TestTLSHandshakeConn(t *testing.T) {
SetLogger(testLogger{t})

connector, err := NewConnector(makeConnStr(t).String())
if err != nil {
t.Error(err)
}

ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()

toconn, err := dialConnection(ctx, connector, connector.params)
if err != nil {
t.Error(err)
}

outbuf := newTdsBuffer(connector.params.packetSize, toconn)
handshakeConn := tlsHandshakeConn{buf: outbuf}

t.Run(`set deadline`, func(t *testing.T) {
defer assertPanic(t, false)
deadline := time.Now().Add(time.Millisecond * 100)

err := handshakeConn.SetDeadline(deadline)
if err != nil {
t.Fatalf(`SetDeadline should return nil`)
}
})

t.Run(`set read deadline`, func(t *testing.T) {
defer assertPanic(t, false)
deadline := time.Now().Add(time.Minute)

err := handshakeConn.SetReadDeadline(deadline)
if err != nil {
t.Fatalf(`SetReadDeadline should return nil`)
}
})

t.Run(`set write deadline`, func(t *testing.T) {
defer assertPanic(t, false)
deadline := time.Now().Add(time.Minute)

err := handshakeConn.SetWriteDeadline(deadline)
if err != nil {
t.Fatalf(`SetWriteDeadline should return nil`)
}
})

t.Run(`get remote addr`, func(t *testing.T) {
addr := handshakeConn.RemoteAddr()
if addr != nil {
t.Fatalf(`RemoteAddr should return nil`)
}
})
}

func TestPassthroughConn(t *testing.T) {
SetLogger(testLogger{t})

connector, err := NewConnector(makeConnStr(t).String())
if err != nil {
t.Error(err)
}

ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()

toconn, err := dialConnection(ctx, connector, connector.params)
if err != nil {
t.Error(err)
}

outbuf := newTdsBuffer(connector.params.packetSize, toconn)

handshakeConn := tlsHandshakeConn{buf: outbuf}
passthrough := passthroughConn{c: &handshakeConn}

t.Run(`set deadline`, func(t *testing.T) {
defer assertPanic(t, false)
deadline := time.Now().Add(time.Millisecond * 100)

err := passthrough.SetDeadline(deadline)
if err != nil {
t.Fatalf(`SetDeadline should return nil`)
}
})

t.Run(`set read deadline`, func(t *testing.T) {
defer assertPanic(t, false)
deadline := time.Now().Add(time.Minute)

err := passthrough.SetReadDeadline(deadline)
if err != nil {
t.Fatalf(`SetReadDeadline should return nil`)
}
})

t.Run(`set write deadline`, func(t *testing.T) {
defer assertPanic(t, false)
deadline := time.Now().Add(time.Minute)

err := passthrough.SetWriteDeadline(deadline)
if err != nil {
t.Fatalf(`SetWriteDeadline should return nil`)
}
})

t.Run(`get remote addr`, func(t *testing.T) {
addr := passthrough.RemoteAddr()
if addr != nil {
t.Fatalf(`RemoteAddr should return nil`)
}
})
}
13 changes: 13 additions & 0 deletions queries_test.go
Expand Up @@ -2230,3 +2230,16 @@ func TestDisconnect2(t *testing.T) {
t.Fatal("timeout")
}
}

func TestClose(t *testing.T) {
conn := open(t)

defer func() {
v := recover()
if v != nil {
t.Fatal(`Close should not panic:`, v)
}
}()

conn.Close()
}

0 comments on commit d9abbec

Please sign in to comment.