1
0
mirror of https://github.com/golang/go synced 2024-11-26 12:37:57 -07:00
go/src/net/rawconn_test.go
Bryan C. Mills b55cbbb9e7 net: pass a testing.TB to newLocal* helpers
Passing in an explicit testing.TB gives two benefits:

1. It allows the helper to fail the test itself, instead of returning
   an error to the caller. A non-nil error invariably fails the
   calling test, and none of these callers bother to add detail to the
   error when logging it anyway so returning the error just added
   noise to the test bodies.

2. It allows the helper to use t.Cleanup to perform any needed cleanup
   tasks, which will be used in CL 370695 to clean up temp directories
   used as namespaces for unix socket paths.

For #34611

Change-Id: I805e701687c12de2caca955649369294229c10b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/370696
Trust: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-13 16:42:23 +00:00

212 lines
4.3 KiB
Go

// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !js
package net
import (
"bytes"
"runtime"
"testing"
"time"
)
func TestRawConnReadWrite(t *testing.T) {
switch runtime.GOOS {
case "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
t.Run("TCP", func(t *testing.T) {
handler := func(ls *localServer, ln Listener) {
c, err := ln.Accept()
if err != nil {
t.Error(err)
return
}
defer c.Close()
cc, err := ln.(*TCPListener).SyscallConn()
if err != nil {
t.Fatal(err)
}
called := false
op := func(uintptr) bool {
called = true
return true
}
err = cc.Write(op)
if err == nil {
t.Error("Write should return an error")
}
if called {
t.Error("Write shouldn't call op")
}
called = false
err = cc.Read(op)
if err == nil {
t.Error("Read should return an error")
}
if called {
t.Error("Read shouldn't call op")
}
var b [32]byte
n, err := c.Read(b[:])
if err != nil {
t.Error(err)
return
}
if _, err := c.Write(b[:n]); err != nil {
t.Error(err)
return
}
}
ls := newLocalServer(t, "tcp")
defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
if err != nil {
t.Fatal(err)
}
defer c.Close()
cc, err := c.(*TCPConn).SyscallConn()
if err != nil {
t.Fatal(err)
}
data := []byte("HELLO-R-U-THERE")
if err := writeRawConn(cc, data); err != nil {
t.Fatal(err)
}
var b [32]byte
n, err := readRawConn(cc, b[:])
if err != nil {
t.Fatal(err)
}
if bytes.Compare(b[:n], data) != 0 {
t.Fatalf("got %q; want %q", b[:n], data)
}
})
t.Run("Deadline", func(t *testing.T) {
switch runtime.GOOS {
case "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ln := newLocalListener(t, "tcp")
defer ln.Close()
c, err := Dial(ln.Addr().Network(), ln.Addr().String())
if err != nil {
t.Fatal(err)
}
defer c.Close()
cc, err := c.(*TCPConn).SyscallConn()
if err != nil {
t.Fatal(err)
}
var b [1]byte
c.SetDeadline(noDeadline)
if err := c.SetDeadline(time.Now().Add(-1)); err != nil {
t.Fatal(err)
}
if err = writeRawConn(cc, b[:]); err == nil {
t.Fatal("Write should fail")
}
if perr := parseWriteError(err); perr != nil {
t.Error(perr)
}
if !isDeadlineExceeded(err) {
t.Errorf("got %v; want timeout", err)
}
if _, err = readRawConn(cc, b[:]); err == nil {
t.Fatal("Read should fail")
}
if perr := parseReadError(err); perr != nil {
t.Error(perr)
}
if !isDeadlineExceeded(err) {
t.Errorf("got %v; want timeout", err)
}
c.SetReadDeadline(noDeadline)
if err := c.SetReadDeadline(time.Now().Add(-1)); err != nil {
t.Fatal(err)
}
if _, err = readRawConn(cc, b[:]); err == nil {
t.Fatal("Read should fail")
}
if perr := parseReadError(err); perr != nil {
t.Error(perr)
}
if !isDeadlineExceeded(err) {
t.Errorf("got %v; want timeout", err)
}
c.SetWriteDeadline(noDeadline)
if err := c.SetWriteDeadline(time.Now().Add(-1)); err != nil {
t.Fatal(err)
}
if err = writeRawConn(cc, b[:]); err == nil {
t.Fatal("Write should fail")
}
if perr := parseWriteError(err); perr != nil {
t.Error(perr)
}
if !isDeadlineExceeded(err) {
t.Errorf("got %v; want timeout", err)
}
})
}
func TestRawConnControl(t *testing.T) {
switch runtime.GOOS {
case "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
t.Run("TCP", func(t *testing.T) {
ln := newLocalListener(t, "tcp")
defer ln.Close()
cc1, err := ln.(*TCPListener).SyscallConn()
if err != nil {
t.Fatal(err)
}
if err := controlRawConn(cc1, ln.Addr()); err != nil {
t.Fatal(err)
}
c, err := Dial(ln.Addr().Network(), ln.Addr().String())
if err != nil {
t.Fatal(err)
}
defer c.Close()
cc2, err := c.(*TCPConn).SyscallConn()
if err != nil {
t.Fatal(err)
}
if err := controlRawConn(cc2, c.LocalAddr()); err != nil {
t.Fatal(err)
}
ln.Close()
if err := controlRawConn(cc1, ln.Addr()); err == nil {
t.Fatal("Control after Close should fail")
}
c.Close()
if err := controlRawConn(cc2, c.LocalAddr()); err == nil {
t.Fatal("Control after Close should fail")
}
})
}