gnp
gnp copied to clipboard
Issue with Chapter03 dial_context_test.go
Hi Adam,
Thanks for your efforts and energy on writing this book :)
I am going through the book, having a problem with the test dia_context_test.go
:
Code
package main
// A context is an object that you can use to send cancellation signals to your
// asynchronous processes. Also allows to send a cancellation signal after it
// reaches a deadline or after its timer expires.
// Use case: Monitor for specific signals from the operating system, such as the
// one sent to the application when a user presses the CTRL-C key combination,
// to gracefully abort connection attempts and tear down existing connections
// before terminating the application
import (
"context"
"net"
"syscall"
"testing"
"time"
)
func TestDialContext(t *testing.T) {
// create a deadline of five seconds into the future
dl := time.Now().Add(5 * time.Second)
// create a context with a 5 seconds deadline into the future
// and get the cancel function
ctx, cancel := context.WithDeadline(context.Background(), dl)
// it's a good practice to defer the cancel function to make sure the
// context is garbage collected as soon as possible.
defer cancel()
var d net.Dialer
// overrides the Control function of the dialer
// delays the connection long enough to ensure we exceed the
// context deadline (5.001s)
d.Control = func(_, _ string, _ syscall.RawConn) error {
// sleep long enough to reach the context deadline
time.Sleep(5*time.Second + time.Millisecond)
return nil
}
// pass the context (ctx) to the DialContext function
// of the dialer
conn, err := d.DialContext(ctx, "tcp", "10.0.0.0:80")
if err != nil {
if conn != nil {
conn.Close()
}
t.Fatal("connection did not time out")
}
nErr, ok := err.(net.Error)
if !ok {
t.Error(err)
} else {
if !nErr.Timeout() {
t.Errorf("error is not a timeout: %v", err)
}
}
if ctx.Err() != context.DeadlineExceeded {
t.Errorf("expected deadline exceeded; actual: %v", ctx.Err())
}
}
Error
λ walter [workspace/npgo/ch03] → go test -run TestDialContext
--- FAIL: TestDialContext (5.00s)
dial_context_test.go:50: connection did not time out
FAIL
exit status 1
FAIL github.com/walterbio/npgo/ch03 5.004s
The conn
reference returned by d.DialContext(ctx, "tcp", "10.0.0.0:80")
is nil
.
(dlv) l
> github.com/walterbio/npgo/ch03.TestDialContext() ./dial_context_test.go:46 (PC: 0x5998ce)
41: }
42:
43: // pass the context (ctx) to the DialContext function
44: // of the dialer
45: conn, err := d.DialContext(ctx, "tcp", "10.0.0.0:80")
=> 46: if err != nil {
47: if conn != nil {
48: conn.Close()
49: }
50: t.Fatal("connection did not time out")
51: }
(dlv) p conn
net.Conn nil
(dlv) p err
error(*net.OpError) *{
Op: "dial",
Net: "tcp",
Source: net.Addr nil,
Addr: net.Addr(*net.TCPAddr) *{
IP: net.IP len: 16, cap: 16, [0,0,0,0,0,0,0,0,0,0,255,255,10,0,0,0],
Port: 80,
Zone: "",},
Err: error(*net.timeoutError) *{},}
(dlv)
Thanks for your help or advice here :)
Kind Regards
Hey Walter, not the author but I'm working through this book now and I think you may have just copied the code incorrectly? The book and the repo has the following (unless there has been an update since you came across this):
if err == nil {
conn.Close()
t.Fatal("connection did not time out")
}
But you have:
if err != nil {
if conn != nil {
conn.Close()
}
t.Fatal("connection did not time out")
}
In this example, I believe the connection should be timing out since the deadline is set to 5, but we call time.Sleep() for 5.001 seconds. Hope this helps 🙂
Nick is spot on.
Walter, please reach out if you need further assistance. Feel free to email me: adam at woodbeck.net.