Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with Chapter03 dial_context_test.go #6

Closed
waltervargas opened this issue Jan 20, 2022 · 2 comments
Closed

Issue with Chapter03 dial_context_test.go #6

waltervargas opened this issue Jan 20, 2022 · 2 comments

Comments

@waltervargas
Copy link

waltervargas commented Jan 20, 2022

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

@waltervargas waltervargas changed the title Issue in Chapter03 ccccccngfdrjlidrrcjkdfbeefebredrubjbuvfguuuf Issue with Chapter03 dial_context_test.go Jan 20, 2022
@nickfiggins
Copy link

nickfiggins commented Apr 23, 2022

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 🙂

@awoodbeck
Copy link
Owner

Nick is spot on.

Walter, please reach out if you need further assistance. Feel free to email me: adam at woodbeck.net.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants