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