github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/ipv4/readwrite_test.go (about) 1 // Copyright 2012 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 package ipv4_test 6 7 import ( 8 "bytes" 9 "net" 10 "runtime" 11 "strings" 12 "sync" 13 "testing" 14 15 "golang.org/x/net/internal/nettest" 16 "golang.org/x/net/ipv4" 17 ) 18 19 func benchmarkUDPListener() (net.PacketConn, net.Addr, error) { 20 c, err := net.ListenPacket("udp4", "127.0.0.1:0") 21 if err != nil { 22 return nil, nil, err 23 } 24 dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String()) 25 if err != nil { 26 c.Close() 27 return nil, nil, err 28 } 29 return c, dst, nil 30 } 31 32 func BenchmarkReadWriteNetUDP(b *testing.B) { 33 c, dst, err := benchmarkUDPListener() 34 if err != nil { 35 b.Fatal(err) 36 } 37 defer c.Close() 38 39 wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128) 40 b.ResetTimer() 41 for i := 0; i < b.N; i++ { 42 benchmarkReadWriteNetUDP(b, c, wb, rb, dst) 43 } 44 } 45 46 func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) { 47 if _, err := c.WriteTo(wb, dst); err != nil { 48 b.Fatal(err) 49 } 50 if _, _, err := c.ReadFrom(rb); err != nil { 51 b.Fatal(err) 52 } 53 } 54 55 func BenchmarkReadWriteIPv4UDP(b *testing.B) { 56 c, dst, err := benchmarkUDPListener() 57 if err != nil { 58 b.Fatal(err) 59 } 60 defer c.Close() 61 62 p := ipv4.NewPacketConn(c) 63 defer p.Close() 64 cf := ipv4.FlagTTL | ipv4.FlagInterface 65 if err := p.SetControlMessage(cf, true); err != nil { 66 b.Fatal(err) 67 } 68 ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) 69 70 wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128) 71 b.ResetTimer() 72 for i := 0; i < b.N; i++ { 73 benchmarkReadWriteIPv4UDP(b, p, wb, rb, dst, ifi) 74 } 75 } 76 77 func benchmarkReadWriteIPv4UDP(b *testing.B, p *ipv4.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) { 78 cm := ipv4.ControlMessage{TTL: 1} 79 if ifi != nil { 80 cm.IfIndex = ifi.Index 81 } 82 if n, err := p.WriteTo(wb, &cm, dst); err != nil { 83 b.Fatal(err) 84 } else if n != len(wb) { 85 b.Fatalf("got %v; want %v", n, len(wb)) 86 } 87 if _, _, _, err := p.ReadFrom(rb); err != nil { 88 b.Fatal(err) 89 } 90 } 91 92 func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) { 93 switch runtime.GOOS { 94 case "nacl", "plan9", "solaris", "windows": 95 t.Skipf("not supported on %s", runtime.GOOS) 96 } 97 98 c, err := net.ListenPacket("udp4", "127.0.0.1:0") 99 if err != nil { 100 t.Fatal(err) 101 } 102 defer c.Close() 103 p := ipv4.NewPacketConn(c) 104 defer p.Close() 105 106 dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String()) 107 if err != nil { 108 t.Fatal(err) 109 } 110 111 ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) 112 cf := ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface 113 wb := []byte("HELLO-R-U-THERE") 114 115 if err := p.SetControlMessage(cf, true); err != nil { // probe before test 116 if nettest.ProtocolNotSupported(err) { 117 t.Skipf("not supported on %s", runtime.GOOS) 118 } 119 t.Fatal(err) 120 } 121 122 var wg sync.WaitGroup 123 reader := func() { 124 defer wg.Done() 125 rb := make([]byte, 128) 126 if n, cm, _, err := p.ReadFrom(rb); err != nil { 127 t.Error(err) 128 return 129 } else if !bytes.Equal(rb[:n], wb) { 130 t.Errorf("got %v; want %v", rb[:n], wb) 131 return 132 } else { 133 s := cm.String() 134 if strings.Contains(s, ",") { 135 t.Errorf("should be space-separated values: %s", s) 136 } 137 } 138 } 139 writer := func(toggle bool) { 140 defer wg.Done() 141 cm := ipv4.ControlMessage{ 142 Src: net.IPv4(127, 0, 0, 1), 143 } 144 if ifi != nil { 145 cm.IfIndex = ifi.Index 146 } 147 if err := p.SetControlMessage(cf, toggle); err != nil { 148 t.Error(err) 149 return 150 } 151 if n, err := p.WriteTo(wb, &cm, dst); err != nil { 152 t.Error(err) 153 return 154 } else if n != len(wb) { 155 t.Errorf("short write: %v", n) 156 return 157 } 158 } 159 160 const N = 10 161 wg.Add(N) 162 for i := 0; i < N; i++ { 163 go reader() 164 } 165 wg.Add(2 * N) 166 for i := 0; i < 2*N; i++ { 167 go writer(i%2 != 0) 168 } 169 wg.Add(N) 170 for i := 0; i < N; i++ { 171 go reader() 172 } 173 wg.Wait() 174 }