1
0
mirror of https://github.com/golang/go synced 2024-11-25 22:37:59 -07:00
go/src/net/rawconn_test.go
Bryan C. Mills a815078683 net: enable most tests on wasip1 and js
To get them to pass, implement more fake syscalls.
To make those syscalls easier to reason about, replace
the use of sync.Cond with selectable channels.

Fixes #59718.
Fixes #50216.

Change-Id: I135a6656f5c48f0e5c43dc4d4bcbdb48ee5535d2
Reviewed-on: https://go-review.googlesource.com/c/go/+/526117
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Achille Roussel <achille.roussel@gmail.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-09-18 17:20:52 +00:00

210 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.
package net
import (
"bytes"
"runtime"
"testing"
"time"
)
func TestRawConnReadWrite(t *testing.T) {
switch runtime.GOOS {
case "plan9", "js", "wasip1":
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", "js", "wasip1":
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")
}
})
}