github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/net/packetconn_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  // This file implements API tests across platforms and will never have a build
     6  // tag.
     7  
     8  package net
     9  
    10  import (
    11  	"os"
    12  	"runtime"
    13  	"strings"
    14  	"testing"
    15  	"time"
    16  )
    17  
    18  func packetConnTestData(t *testing.T, net string, i int) ([]byte, func()) {
    19  	switch net {
    20  	case "udp":
    21  		return []byte("UDP PACKETCONN TEST"), nil
    22  	case "ip":
    23  		if skip, skipmsg := skipRawSocketTest(t); skip {
    24  			return nil, func() {
    25  				t.Logf(skipmsg)
    26  			}
    27  		}
    28  		b, err := (&icmpMessage{
    29  			Type: icmpv4EchoRequest, Code: 0,
    30  			Body: &icmpEcho{
    31  				ID: os.Getpid() & 0xffff, Seq: i + 1,
    32  				Data: []byte("IP PACKETCONN TEST"),
    33  			},
    34  		}).Marshal()
    35  		if err != nil {
    36  			return nil, func() {
    37  				t.Fatalf("icmpMessage.Marshal failed: %v", err)
    38  			}
    39  		}
    40  		return b, nil
    41  	case "unixgram":
    42  		switch runtime.GOOS {
    43  		case "nacl", "plan9", "windows":
    44  			return nil, func() {
    45  				t.Logf("skipping %q test on %q", net, runtime.GOOS)
    46  			}
    47  		default:
    48  			return []byte("UNIXGRAM PACKETCONN TEST"), nil
    49  		}
    50  	default:
    51  		return nil, func() {
    52  			t.Logf("skipping %q test", net)
    53  		}
    54  	}
    55  }
    56  
    57  var packetConnTests = []struct {
    58  	net   string
    59  	addr1 string
    60  	addr2 string
    61  }{
    62  	{"udp", "127.0.0.1:0", "127.0.0.1:0"},
    63  	{"ip:icmp", "127.0.0.1", "127.0.0.1"},
    64  	{"unixgram", testUnixAddr(), testUnixAddr()},
    65  }
    66  
    67  func TestPacketConn(t *testing.T) {
    68  	closer := func(c PacketConn, net, addr1, addr2 string) {
    69  		c.Close()
    70  		switch net {
    71  		case "unixgram":
    72  			os.Remove(addr1)
    73  			os.Remove(addr2)
    74  		}
    75  	}
    76  
    77  	for i, tt := range packetConnTests {
    78  		netstr := strings.Split(tt.net, ":")
    79  		wb, skipOrFatalFn := packetConnTestData(t, netstr[0], i)
    80  		if skipOrFatalFn != nil {
    81  			skipOrFatalFn()
    82  			continue
    83  		}
    84  
    85  		c1, err := ListenPacket(tt.net, tt.addr1)
    86  		if err != nil {
    87  			t.Fatalf("ListenPacket failed: %v", err)
    88  		}
    89  		defer closer(c1, netstr[0], tt.addr1, tt.addr2)
    90  		c1.LocalAddr()
    91  		c1.SetDeadline(time.Now().Add(100 * time.Millisecond))
    92  		c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
    93  		c1.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
    94  
    95  		c2, err := ListenPacket(tt.net, tt.addr2)
    96  		if err != nil {
    97  			t.Fatalf("ListenPacket failed: %v", err)
    98  		}
    99  		defer closer(c2, netstr[0], tt.addr1, tt.addr2)
   100  		c2.LocalAddr()
   101  		c2.SetDeadline(time.Now().Add(100 * time.Millisecond))
   102  		c2.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
   103  		c2.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
   104  
   105  		if _, err := c1.WriteTo(wb, c2.LocalAddr()); err != nil {
   106  			t.Fatalf("PacketConn.WriteTo failed: %v", err)
   107  		}
   108  		rb2 := make([]byte, 128)
   109  		if _, _, err := c2.ReadFrom(rb2); err != nil {
   110  			t.Fatalf("PacketConn.ReadFrom failed: %v", err)
   111  		}
   112  		if _, err := c2.WriteTo(wb, c1.LocalAddr()); err != nil {
   113  			t.Fatalf("PacketConn.WriteTo failed: %v", err)
   114  		}
   115  		rb1 := make([]byte, 128)
   116  		if _, _, err := c1.ReadFrom(rb1); err != nil {
   117  			t.Fatalf("PacketConn.ReadFrom failed: %v", err)
   118  		}
   119  	}
   120  }
   121  
   122  func TestConnAndPacketConn(t *testing.T) {
   123  	closer := func(c PacketConn, net, addr1, addr2 string) {
   124  		c.Close()
   125  		switch net {
   126  		case "unixgram":
   127  			os.Remove(addr1)
   128  			os.Remove(addr2)
   129  		}
   130  	}
   131  
   132  	for i, tt := range packetConnTests {
   133  		var wb []byte
   134  		netstr := strings.Split(tt.net, ":")
   135  		wb, skipOrFatalFn := packetConnTestData(t, netstr[0], i)
   136  		if skipOrFatalFn != nil {
   137  			skipOrFatalFn()
   138  			continue
   139  		}
   140  
   141  		c1, err := ListenPacket(tt.net, tt.addr1)
   142  		if err != nil {
   143  			t.Fatalf("ListenPacket failed: %v", err)
   144  		}
   145  		defer closer(c1, netstr[0], tt.addr1, tt.addr2)
   146  		c1.LocalAddr()
   147  		c1.SetDeadline(time.Now().Add(100 * time.Millisecond))
   148  		c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
   149  		c1.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
   150  
   151  		c2, err := Dial(tt.net, c1.LocalAddr().String())
   152  		if err != nil {
   153  			t.Fatalf("Dial failed: %v", err)
   154  		}
   155  		defer c2.Close()
   156  		c2.LocalAddr()
   157  		c2.RemoteAddr()
   158  		c2.SetDeadline(time.Now().Add(100 * time.Millisecond))
   159  		c2.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
   160  		c2.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
   161  
   162  		if _, err := c2.Write(wb); err != nil {
   163  			t.Fatalf("Conn.Write failed: %v", err)
   164  		}
   165  		rb1 := make([]byte, 128)
   166  		if _, _, err := c1.ReadFrom(rb1); err != nil {
   167  			t.Fatalf("PacketConn.ReadFrom failed: %v", err)
   168  		}
   169  		var dst Addr
   170  		switch netstr[0] {
   171  		case "ip":
   172  			dst = &IPAddr{IP: IPv4(127, 0, 0, 1)}
   173  		case "unixgram":
   174  			continue
   175  		default:
   176  			dst = c2.LocalAddr()
   177  		}
   178  		if _, err := c1.WriteTo(wb, dst); err != nil {
   179  			t.Fatalf("PacketConn.WriteTo failed: %v", err)
   180  		}
   181  		rb2 := make([]byte, 128)
   182  		if _, err := c2.Read(rb2); err != nil {
   183  			t.Fatalf("Conn.Read failed: %v", err)
   184  		}
   185  	}
   186  }