...

Source file src/net/rawconn_test.go

Documentation: net

		 1  // Copyright 2018 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  //go:build !js
		 6  // +build !js
		 7  
		 8  package net
		 9  
		10  import (
		11  	"bytes"
		12  	"runtime"
		13  	"testing"
		14  	"time"
		15  )
		16  
		17  func TestRawConnReadWrite(t *testing.T) {
		18  	switch runtime.GOOS {
		19  	case "plan9":
		20  		t.Skipf("not supported on %s", runtime.GOOS)
		21  	}
		22  
		23  	t.Run("TCP", func(t *testing.T) {
		24  		handler := func(ls *localServer, ln Listener) {
		25  			c, err := ln.Accept()
		26  			if err != nil {
		27  				t.Error(err)
		28  				return
		29  			}
		30  			defer c.Close()
		31  
		32  			cc, err := ln.(*TCPListener).SyscallConn()
		33  			if err != nil {
		34  				t.Fatal(err)
		35  			}
		36  			called := false
		37  			op := func(uintptr) bool {
		38  				called = true
		39  				return true
		40  			}
		41  			err = cc.Write(op)
		42  			if err == nil {
		43  				t.Error("Write should return an error")
		44  			}
		45  			if called {
		46  				t.Error("Write shouldn't call op")
		47  			}
		48  			called = false
		49  			err = cc.Read(op)
		50  			if err == nil {
		51  				t.Error("Read should return an error")
		52  			}
		53  			if called {
		54  				t.Error("Read shouldn't call op")
		55  			}
		56  
		57  			var b [32]byte
		58  			n, err := c.Read(b[:])
		59  			if err != nil {
		60  				t.Error(err)
		61  				return
		62  			}
		63  			if _, err := c.Write(b[:n]); err != nil {
		64  				t.Error(err)
		65  				return
		66  			}
		67  		}
		68  		ls, err := newLocalServer("tcp")
		69  		if err != nil {
		70  			t.Fatal(err)
		71  		}
		72  		defer ls.teardown()
		73  		if err := ls.buildup(handler); err != nil {
		74  			t.Fatal(err)
		75  		}
		76  
		77  		c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
		78  		if err != nil {
		79  			t.Fatal(err)
		80  		}
		81  		defer c.Close()
		82  
		83  		cc, err := c.(*TCPConn).SyscallConn()
		84  		if err != nil {
		85  			t.Fatal(err)
		86  		}
		87  		data := []byte("HELLO-R-U-THERE")
		88  		if err := writeRawConn(cc, data); err != nil {
		89  			t.Fatal(err)
		90  		}
		91  		var b [32]byte
		92  		n, err := readRawConn(cc, b[:])
		93  		if err != nil {
		94  			t.Fatal(err)
		95  		}
		96  		if bytes.Compare(b[:n], data) != 0 {
		97  			t.Fatalf("got %q; want %q", b[:n], data)
		98  		}
		99  	})
	 100  	t.Run("Deadline", func(t *testing.T) {
	 101  		switch runtime.GOOS {
	 102  		case "windows":
	 103  			t.Skipf("not supported on %s", runtime.GOOS)
	 104  		}
	 105  
	 106  		ln, err := newLocalListener("tcp")
	 107  		if err != nil {
	 108  			t.Fatal(err)
	 109  		}
	 110  		defer ln.Close()
	 111  
	 112  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
	 113  		if err != nil {
	 114  			t.Fatal(err)
	 115  		}
	 116  		defer c.Close()
	 117  
	 118  		cc, err := c.(*TCPConn).SyscallConn()
	 119  		if err != nil {
	 120  			t.Fatal(err)
	 121  		}
	 122  		var b [1]byte
	 123  
	 124  		c.SetDeadline(noDeadline)
	 125  		if err := c.SetDeadline(time.Now().Add(-1)); err != nil {
	 126  			t.Fatal(err)
	 127  		}
	 128  		if err = writeRawConn(cc, b[:]); err == nil {
	 129  			t.Fatal("Write should fail")
	 130  		}
	 131  		if perr := parseWriteError(err); perr != nil {
	 132  			t.Error(perr)
	 133  		}
	 134  		if !isDeadlineExceeded(err) {
	 135  			t.Errorf("got %v; want timeout", err)
	 136  		}
	 137  		if _, err = readRawConn(cc, b[:]); err == nil {
	 138  			t.Fatal("Read should fail")
	 139  		}
	 140  		if perr := parseReadError(err); perr != nil {
	 141  			t.Error(perr)
	 142  		}
	 143  		if !isDeadlineExceeded(err) {
	 144  			t.Errorf("got %v; want timeout", err)
	 145  		}
	 146  
	 147  		c.SetReadDeadline(noDeadline)
	 148  		if err := c.SetReadDeadline(time.Now().Add(-1)); err != nil {
	 149  			t.Fatal(err)
	 150  		}
	 151  		if _, err = readRawConn(cc, b[:]); err == nil {
	 152  			t.Fatal("Read should fail")
	 153  		}
	 154  		if perr := parseReadError(err); perr != nil {
	 155  			t.Error(perr)
	 156  		}
	 157  		if !isDeadlineExceeded(err) {
	 158  			t.Errorf("got %v; want timeout", err)
	 159  		}
	 160  
	 161  		c.SetWriteDeadline(noDeadline)
	 162  		if err := c.SetWriteDeadline(time.Now().Add(-1)); err != nil {
	 163  			t.Fatal(err)
	 164  		}
	 165  		if err = writeRawConn(cc, b[:]); err == nil {
	 166  			t.Fatal("Write should fail")
	 167  		}
	 168  		if perr := parseWriteError(err); perr != nil {
	 169  			t.Error(perr)
	 170  		}
	 171  		if !isDeadlineExceeded(err) {
	 172  			t.Errorf("got %v; want timeout", err)
	 173  		}
	 174  	})
	 175  }
	 176  
	 177  func TestRawConnControl(t *testing.T) {
	 178  	switch runtime.GOOS {
	 179  	case "plan9":
	 180  		t.Skipf("not supported on %s", runtime.GOOS)
	 181  	}
	 182  
	 183  	t.Run("TCP", func(t *testing.T) {
	 184  		ln, err := newLocalListener("tcp")
	 185  		if err != nil {
	 186  			t.Fatal(err)
	 187  		}
	 188  		defer ln.Close()
	 189  
	 190  		cc1, err := ln.(*TCPListener).SyscallConn()
	 191  		if err != nil {
	 192  			t.Fatal(err)
	 193  		}
	 194  		if err := controlRawConn(cc1, ln.Addr()); err != nil {
	 195  			t.Fatal(err)
	 196  		}
	 197  
	 198  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
	 199  		if err != nil {
	 200  			t.Fatal(err)
	 201  		}
	 202  		defer c.Close()
	 203  
	 204  		cc2, err := c.(*TCPConn).SyscallConn()
	 205  		if err != nil {
	 206  			t.Fatal(err)
	 207  		}
	 208  		if err := controlRawConn(cc2, c.LocalAddr()); err != nil {
	 209  			t.Fatal(err)
	 210  		}
	 211  
	 212  		ln.Close()
	 213  		if err := controlRawConn(cc1, ln.Addr()); err == nil {
	 214  			t.Fatal("Control after Close should fail")
	 215  		}
	 216  		c.Close()
	 217  		if err := controlRawConn(cc2, c.LocalAddr()); err == nil {
	 218  			t.Fatal("Control after Close should fail")
	 219  		}
	 220  	})
	 221  }
	 222  

View as plain text