If I have code that works with a net.Conn
, how can I write tests for it without actually creating a network connection to localhost?
I've seen no solutions to this online; people seem to either ignore it (no tests), write tests that cannot run in parallel (ie. use an actual network connection, which uses up ports), or use io.Pipe.
However, net.Conn
defines SetReadDeadline
, SetWriteDeadline
; and io.Pipe doesn't. net.Pipe also doesnt, despite superficially claiming to implement the interface, it's simply implemented with:
func (p *pipe) SetDeadline(t time.Time) error {
return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (p *pipe) SetReadDeadline(t time.Time) error {
return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (p *pipe) SetWriteDeadline(t time.Time) error {
return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
(see: https://golang.org/src/net/pipe.go)
So... is there some other way of doing this?
I'll accept any answer that shows how to use a stream in a test with a working deadline that is not an actual network socket.
(Idly, this cloudflare blogpost covers the motivation for using deadlines, and why blocking forever in a goroutine per connection is not an acceptable solution; but regardless of that argument, particularly in this case I'm looking for a solution for tests where we deliberately want to handle edge cases where a bad connection hangs, etc.)
(NB. this may seem like a duplicate of Simulate a tcp connection in Go, but notice that all the solutions proposed in that question do not implement the Deadline functions, which is specifically what I'm asking about how to test here)