...

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

View as plain text