...
Run Format

Source file src/net/file_test.go

Documentation: net

     1  // Copyright 2011 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  	"os"
    11  	"reflect"
    12  	"runtime"
    13  	"sync"
    14  	"testing"
    15  )
    16  
    17  // The full stack test cases for IPConn have been moved to the
    18  // following:
    19  //      golang.org/x/net/ipv4
    20  //      golang.org/x/net/ipv6
    21  //      golang.org/x/net/icmp
    22  
    23  var fileConnTests = []struct {
    24  	network string
    25  }{
    26  	{"tcp"},
    27  	{"udp"},
    28  	{"unix"},
    29  	{"unixpacket"},
    30  }
    31  
    32  func TestFileConn(t *testing.T) {
    33  	switch runtime.GOOS {
    34  	case "nacl", "plan9", "windows":
    35  		t.Skipf("not supported on %s", runtime.GOOS)
    36  	}
    37  
    38  	for _, tt := range fileConnTests {
    39  		if !testableNetwork(tt.network) {
    40  			t.Logf("skipping %s test", tt.network)
    41  			continue
    42  		}
    43  
    44  		var network, address string
    45  		switch tt.network {
    46  		case "udp":
    47  			c, err := newLocalPacketListener(tt.network)
    48  			if err != nil {
    49  				t.Fatal(err)
    50  			}
    51  			defer c.Close()
    52  			network = c.LocalAddr().Network()
    53  			address = c.LocalAddr().String()
    54  		default:
    55  			handler := func(ls *localServer, ln Listener) {
    56  				c, err := ln.Accept()
    57  				if err != nil {
    58  					return
    59  				}
    60  				defer c.Close()
    61  				var b [1]byte
    62  				c.Read(b[:])
    63  			}
    64  			ls, err := newLocalServer(tt.network)
    65  			if err != nil {
    66  				t.Fatal(err)
    67  			}
    68  			defer ls.teardown()
    69  			if err := ls.buildup(handler); err != nil {
    70  				t.Fatal(err)
    71  			}
    72  			network = ls.Listener.Addr().Network()
    73  			address = ls.Listener.Addr().String()
    74  		}
    75  
    76  		c1, err := Dial(network, address)
    77  		if err != nil {
    78  			if perr := parseDialError(err); perr != nil {
    79  				t.Error(perr)
    80  			}
    81  			t.Fatal(err)
    82  		}
    83  		addr := c1.LocalAddr()
    84  
    85  		var f *os.File
    86  		switch c1 := c1.(type) {
    87  		case *TCPConn:
    88  			f, err = c1.File()
    89  		case *UDPConn:
    90  			f, err = c1.File()
    91  		case *UnixConn:
    92  			f, err = c1.File()
    93  		}
    94  		if err := c1.Close(); err != nil {
    95  			if perr := parseCloseError(err, false); perr != nil {
    96  				t.Error(perr)
    97  			}
    98  			t.Error(err)
    99  		}
   100  		if err != nil {
   101  			if perr := parseCommonError(err); perr != nil {
   102  				t.Error(perr)
   103  			}
   104  			t.Fatal(err)
   105  		}
   106  
   107  		c2, err := FileConn(f)
   108  		if err := f.Close(); err != nil {
   109  			t.Error(err)
   110  		}
   111  		if err != nil {
   112  			if perr := parseCommonError(err); perr != nil {
   113  				t.Error(perr)
   114  			}
   115  			t.Fatal(err)
   116  		}
   117  		defer c2.Close()
   118  
   119  		if _, err := c2.Write([]byte("FILECONN TEST")); err != nil {
   120  			if perr := parseWriteError(err); perr != nil {
   121  				t.Error(perr)
   122  			}
   123  			t.Fatal(err)
   124  		}
   125  		if !reflect.DeepEqual(c2.LocalAddr(), addr) {
   126  			t.Fatalf("got %#v; want %#v", c2.LocalAddr(), addr)
   127  		}
   128  	}
   129  }
   130  
   131  var fileListenerTests = []struct {
   132  	network string
   133  }{
   134  	{"tcp"},
   135  	{"unix"},
   136  	{"unixpacket"},
   137  }
   138  
   139  func TestFileListener(t *testing.T) {
   140  	switch runtime.GOOS {
   141  	case "nacl", "plan9", "windows":
   142  		t.Skipf("not supported on %s", runtime.GOOS)
   143  	}
   144  
   145  	for _, tt := range fileListenerTests {
   146  		if !testableNetwork(tt.network) {
   147  			t.Logf("skipping %s test", tt.network)
   148  			continue
   149  		}
   150  
   151  		ln1, err := newLocalListener(tt.network)
   152  		if err != nil {
   153  			t.Fatal(err)
   154  		}
   155  		switch tt.network {
   156  		case "unix", "unixpacket":
   157  			defer os.Remove(ln1.Addr().String())
   158  		}
   159  		addr := ln1.Addr()
   160  
   161  		var f *os.File
   162  		switch ln1 := ln1.(type) {
   163  		case *TCPListener:
   164  			f, err = ln1.File()
   165  		case *UnixListener:
   166  			f, err = ln1.File()
   167  		}
   168  		switch tt.network {
   169  		case "unix", "unixpacket":
   170  			defer ln1.Close() // UnixListener.Close calls syscall.Unlink internally
   171  		default:
   172  			if err := ln1.Close(); err != nil {
   173  				t.Error(err)
   174  			}
   175  		}
   176  		if err != nil {
   177  			if perr := parseCommonError(err); perr != nil {
   178  				t.Error(perr)
   179  			}
   180  			t.Fatal(err)
   181  		}
   182  
   183  		ln2, err := FileListener(f)
   184  		if err := f.Close(); err != nil {
   185  			t.Error(err)
   186  		}
   187  		if err != nil {
   188  			if perr := parseCommonError(err); perr != nil {
   189  				t.Error(perr)
   190  			}
   191  			t.Fatal(err)
   192  		}
   193  		defer ln2.Close()
   194  
   195  		var wg sync.WaitGroup
   196  		wg.Add(1)
   197  		go func() {
   198  			defer wg.Done()
   199  			c, err := Dial(ln2.Addr().Network(), ln2.Addr().String())
   200  			if err != nil {
   201  				if perr := parseDialError(err); perr != nil {
   202  					t.Error(perr)
   203  				}
   204  				t.Error(err)
   205  				return
   206  			}
   207  			c.Close()
   208  		}()
   209  		c, err := ln2.Accept()
   210  		if err != nil {
   211  			if perr := parseAcceptError(err); perr != nil {
   212  				t.Error(perr)
   213  			}
   214  			t.Fatal(err)
   215  		}
   216  		c.Close()
   217  		wg.Wait()
   218  		if !reflect.DeepEqual(ln2.Addr(), addr) {
   219  			t.Fatalf("got %#v; want %#v", ln2.Addr(), addr)
   220  		}
   221  	}
   222  }
   223  
   224  var filePacketConnTests = []struct {
   225  	network string
   226  }{
   227  	{"udp"},
   228  	{"unixgram"},
   229  }
   230  
   231  func TestFilePacketConn(t *testing.T) {
   232  	switch runtime.GOOS {
   233  	case "nacl", "plan9", "windows":
   234  		t.Skipf("not supported on %s", runtime.GOOS)
   235  	}
   236  
   237  	for _, tt := range filePacketConnTests {
   238  		if !testableNetwork(tt.network) {
   239  			t.Logf("skipping %s test", tt.network)
   240  			continue
   241  		}
   242  
   243  		c1, err := newLocalPacketListener(tt.network)
   244  		if err != nil {
   245  			t.Fatal(err)
   246  		}
   247  		switch tt.network {
   248  		case "unixgram":
   249  			defer os.Remove(c1.LocalAddr().String())
   250  		}
   251  		addr := c1.LocalAddr()
   252  
   253  		var f *os.File
   254  		switch c1 := c1.(type) {
   255  		case *UDPConn:
   256  			f, err = c1.File()
   257  		case *UnixConn:
   258  			f, err = c1.File()
   259  		}
   260  		if err := c1.Close(); err != nil {
   261  			if perr := parseCloseError(err, false); perr != nil {
   262  				t.Error(perr)
   263  			}
   264  			t.Error(err)
   265  		}
   266  		if err != nil {
   267  			if perr := parseCommonError(err); perr != nil {
   268  				t.Error(perr)
   269  			}
   270  			t.Fatal(err)
   271  		}
   272  
   273  		c2, err := FilePacketConn(f)
   274  		if err := f.Close(); err != nil {
   275  			t.Error(err)
   276  		}
   277  		if err != nil {
   278  			if perr := parseCommonError(err); perr != nil {
   279  				t.Error(perr)
   280  			}
   281  			t.Fatal(err)
   282  		}
   283  		defer c2.Close()
   284  
   285  		if _, err := c2.WriteTo([]byte("FILEPACKETCONN TEST"), addr); err != nil {
   286  			if perr := parseWriteError(err); perr != nil {
   287  				t.Error(perr)
   288  			}
   289  			t.Fatal(err)
   290  		}
   291  		if !reflect.DeepEqual(c2.LocalAddr(), addr) {
   292  			t.Fatalf("got %#v; want %#v", c2.LocalAddr(), addr)
   293  		}
   294  	}
   295  }
   296  
   297  // Issue 24483.
   298  func TestFileCloseRace(t *testing.T) {
   299  	switch runtime.GOOS {
   300  	case "nacl", "plan9", "windows":
   301  		t.Skipf("not supported on %s", runtime.GOOS)
   302  	}
   303  	if !testableNetwork("tcp") {
   304  		t.Skip("tcp not supported")
   305  	}
   306  
   307  	handler := func(ls *localServer, ln Listener) {
   308  		c, err := ln.Accept()
   309  		if err != nil {
   310  			return
   311  		}
   312  		defer c.Close()
   313  		var b [1]byte
   314  		c.Read(b[:])
   315  	}
   316  
   317  	ls, err := newLocalServer("tcp")
   318  	if err != nil {
   319  		t.Fatal(err)
   320  	}
   321  	defer ls.teardown()
   322  	if err := ls.buildup(handler); err != nil {
   323  		t.Fatal(err)
   324  	}
   325  
   326  	const tries = 100
   327  	for i := 0; i < tries; i++ {
   328  		c1, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   329  		if err != nil {
   330  			t.Fatal(err)
   331  		}
   332  		tc := c1.(*TCPConn)
   333  
   334  		var wg sync.WaitGroup
   335  		wg.Add(2)
   336  		go func() {
   337  			defer wg.Done()
   338  			f, err := tc.File()
   339  			if err == nil {
   340  				f.Close()
   341  			}
   342  		}()
   343  		go func() {
   344  			defer wg.Done()
   345  			c1.Close()
   346  		}()
   347  		wg.Wait()
   348  	}
   349  }
   350  

View as plain text