github.com/Aoi-hosizora/ahlib@v1.5.1-0.20230404072829-241b93cf91c7/xruntime/xruntime_test.go (about)

     1  package xruntime
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/Aoi-hosizora/ahlib/xtesting"
     6  	"net"
     7  	"os"
     8  	"reflect"
     9  	"runtime/pprof"
    10  	"strings"
    11  	"syscall"
    12  	"testing"
    13  	"unsafe"
    14  )
    15  
    16  func testA() {}
    17  
    18  var testB = func() {} // glob..func1
    19  
    20  var testC = func() {} // glob..func2
    21  
    22  type testStruct struct{}
    23  
    24  func (t testStruct) testD() {}
    25  
    26  func (t *testStruct) testE() {}
    27  
    28  func TestNameOfFunction(t *testing.T) {
    29  	var testF = func() {} // TestNameOfFunction.func1
    30  	testG := func() {}    // TestNameOfFunction.func2
    31  	ts1 := testStruct{}
    32  	ts2 := &testStruct{}
    33  
    34  	for _, tc := range []struct {
    35  		give interface{}
    36  		want string
    37  	}{
    38  		{testA, "github.com/Aoi-hosizora/ahlib/xruntime.testA"},
    39  		{testB, "github.com/Aoi-hosizora/ahlib/xruntime.glob..func1"},
    40  		{testC, "github.com/Aoi-hosizora/ahlib/xruntime.glob..func2"},
    41  		{testStruct.testD, "github.com/Aoi-hosizora/ahlib/xruntime.testStruct.testD"},
    42  		{(*testStruct).testE, "github.com/Aoi-hosizora/ahlib/xruntime.(*testStruct).testE"},
    43  		{ts1.testD, "github.com/Aoi-hosizora/ahlib/xruntime.testStruct.testD-fm"},
    44  		{ts2.testD, "github.com/Aoi-hosizora/ahlib/xruntime.testStruct.testD-fm"},
    45  		{ts1.testE, "github.com/Aoi-hosizora/ahlib/xruntime.(*testStruct).testE-fm"},
    46  		{ts2.testE, "github.com/Aoi-hosizora/ahlib/xruntime.(*testStruct).testE-fm"},
    47  		{testF, "github.com/Aoi-hosizora/ahlib/xruntime.TestNameOfFunction.func1"},
    48  		{testG, "github.com/Aoi-hosizora/ahlib/xruntime.TestNameOfFunction.func2"},
    49  	} {
    50  		xtesting.Equal(t, NameOfFunction(tc.give), tc.want)
    51  	}
    52  
    53  	xtesting.Panic(t, func() { NameOfFunction(nil) })
    54  	xtesting.Panic(t, func() { NameOfFunction(0) })
    55  	xtesting.Panic(t, func() { NameOfFunction("x") })
    56  }
    57  
    58  func printSharp(s string) {
    59  	fmt.Printf("\n%s\n", strings.Repeat("#", len(s)+8))
    60  	fmt.Printf("### %s ###", s)
    61  	fmt.Printf("\n%s\n\n", strings.Repeat("#", len(s)+8))
    62  }
    63  
    64  func TestRawStack(t *testing.T) {
    65  	printSharp("RawStack(false)")
    66  	_, _ = os.Stdout.Write(RawStack(false))
    67  
    68  	/*
    69  		goroutine 19 [running]:
    70  		github.com/Aoi-hosizora/ahlib/xruntime.RawStack(0x7?)
    71  			C:/Files/Codes/Projects/ahlib/xruntime/xruntime.go:46 +0x6a
    72  		github.com/Aoi-hosizora/ahlib/xruntime.TestRawStack(0x0?)
    73  			C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go:65 +0x30
    74  		testing.tRunner(0xc000085380, 0xf682b0)
    75  			C:/Developments/Go/src/testing/testing.go:1439 +0x102
    76  		created by testing.(*T).Run
    77  			C:/Developments/Go/src/testing/testing.go:1486 +0x35f
    78  	*/
    79  
    80  	printSharp("RawStack(true)")
    81  	_, _ = os.Stdout.Write(RawStack(true))
    82  
    83  	/*
    84  		goroutine 19 [running]:
    85  		github.com/Aoi-hosizora/ahlib/xruntime.RawStack(0xdd?)
    86  			C:/Files/Codes/Projects/ahlib/xruntime/xruntime.go:46 +0x6a
    87  		github.com/Aoi-hosizora/ahlib/xruntime.TestRawStack(0x0?)
    88  			C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go:80 +0x65
    89  		testing.tRunner(0xc000085380, 0xf682b0)
    90  			C:/Developments/Go/src/testing/testing.go:1439 +0x102
    91  		created by testing.(*T).Run
    92  			C:/Developments/Go/src/testing/testing.go:1486 +0x35f
    93  
    94  		goroutine 1 [chan receive]:
    95  		testing.(*T).Run(0xc0000851e0, {0xf5d0db?, 0xe87fd3?}, 0xf682b0)
    96  			C:/Developments/Go/src/testing/testing.go:1487 +0x37a
    97  		testing.runTests.func1(0xc0000b8720?)
    98  			C:/Developments/Go/src/testing/testing.go:1839 +0x6e
    99  		testing.tRunner(0xc0000851e0, 0xc0000c3cd8)
   100  			C:/Developments/Go/src/testing/testing.go:1439 +0x102
   101  		testing.runTests(0xc000094280?, {0x104a8a0, 0x8, 0x8}, {0x265fd440598?, 0x40?, 0x0?})
   102  			C:/Developments/Go/src/testing/testing.go:1837 +0x457
   103  		testing.(*M).Run(0xc000094280)
   104  			C:/Developments/Go/src/testing/testing.go:1719 +0x5d9
   105  		main.main()
   106  			_testmain.go:61 +0x1aa
   107  	*/
   108  
   109  	printSharp("RawStack(false)_2")
   110  	var f func(a int)
   111  	f = func(a int) {
   112  		if a > 0 {
   113  			f(a - 1)
   114  		} else if a == 0 {
   115  			_, _ = os.Stdout.Write(RawStack(false))
   116  			return
   117  		}
   118  	}
   119  	f(25)
   120  
   121  	/*
   122  		goroutine 19 [running]:
   123  		github.com/Aoi-hosizora/ahlib/xruntime.RawStack(0x0?)
   124  			C:/Files/Codes/Projects/ahlib/xruntime/xruntime.go:46 +0x6a
   125  		github.com/Aoi-hosizora/ahlib/xruntime.TestRawStack.func1(0x0?)
   126  			C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go:114 +0x26
   127  		github.com/Aoi-hosizora/ahlib/xruntime.TestRawStack.func1(0x0?)
   128  			C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go:112 +0x53
   129  		......
   130  		github.com/Aoi-hosizora/ahlib/xruntime.TestRawStack.func1(0xf5e51a?)
   131  			C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go:112 +0x53
   132  		github.com/Aoi-hosizora/ahlib/xruntime.TestRawStack(0x0?)
   133  			C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go:118 +0xc9
   134  		testing.tRunner(0xc000085380, 0xf682b0)
   135  			C:/Developments/Go/src/testing/testing.go:1439 +0x102
   136  		created by testing.(*T).Run
   137  			C:/Developments/Go/src/testing/testing.go:1486 +0x35f
   138  	*/
   139  
   140  	printSharp("TestRawStack end")
   141  }
   142  
   143  func TestTraceStack(t *testing.T) {
   144  	func() {
   145  		printSharp("RuntimeTraceStack(0)")
   146  		stack := RuntimeTraceStack(0)
   147  		fmt.Println(stack.String())
   148  	}()
   149  
   150  	/*
   151  		File: C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go:145
   152  		Func: github.com/Aoi-hosizora/ahlib/xruntime.TestTraceStack.func1
   153  			stack := RuntimeTraceStack(0)
   154  		File: C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go:147
   155  		Func: github.com/Aoi-hosizora/ahlib/xruntime.TestTraceStack
   156  			}()
   157  		File: C:/Developments/Go/src/testing/testing.go:1439
   158  		Func: testing.tRunner
   159  			fn(t)
   160  		File: C:/Developments/Go/src/runtime/asm_amd64.s:1571
   161  		Func: runtime.goexit
   162  			BYTE	$0x90	// NOP
   163  	*/
   164  
   165  	printSharp("RuntimeTraceStack(1)")
   166  	stack := RuntimeTraceStack(1)
   167  	fmt.Println(stack.String())
   168  
   169  	/*
   170  		File: C:/Developments/Go/src/testing/testing.go:1439
   171  		Func: testing.tRunner
   172  			fn(t)
   173  		File: C:/Developments/Go/src/runtime/asm_amd64.s:1571
   174  		Func: runtime.goexit
   175  			BYTE	$0x90	// NOP
   176  	*/
   177  
   178  	printSharp("RuntimeTraceStackWithInfo(0)")
   179  	s, filename, funcName, lineIndex, lineText := RuntimeTraceStackWithInfo(0)
   180  	fmt.Println("filename:", filename)
   181  	fmt.Println("funcName:", funcName)
   182  	fmt.Println("lineIndex:", lineIndex)
   183  	fmt.Println("lineText:", lineText)
   184  	fmt.Println("======")
   185  	fmt.Println(s[0].String())
   186  	fmt.Println(s[1].String())
   187  
   188  	/*
   189  		filename: C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go
   190  		funcName: xruntime.TestTraceStack
   191  		lineIndex: 178
   192  		lineText: s, filename, funcName, lineIndex, lineText := RuntimeTraceStackWithInfo(0)
   193  		======
   194  		File: C:/Files/Codes/Projects/ahlib/xruntime/xruntime_test.go:178
   195  		Func: github.com/Aoi-hosizora/ahlib/xruntime.TestTraceStack
   196  			s, filename, funcName, lineIndex, lineText := RuntimeTraceStackWithInfo(0)
   197  		File: C:/Developments/Go/src/testing/testing.go:1439
   198  		Func: testing.tRunner
   199  			fn(t)
   200  	*/
   201  
   202  	s, filename, funcName, lineIndex, lineText = RuntimeTraceStackWithInfo(5000)
   203  	xtesting.Equal(t, len(s), 0)
   204  	xtesting.Equal(t, filename, "")
   205  	xtesting.Equal(t, funcName, "")
   206  	xtesting.Equal(t, lineIndex, 0)
   207  	xtesting.Equal(t, lineText, "")
   208  
   209  	printSharp("TestTraceStack end")
   210  }
   211  
   212  func TestHackHideAndGetString(t *testing.T) {
   213  	handler := func() {}
   214  	funcSize := int(reflect.TypeOf(func() {}).Size())
   215  	handlerFn := (*struct{ fn uintptr })(unsafe.Pointer(&handler)).fn
   216  	hackedFn := HackHideString(handlerFn, funcSize, "handlerName")
   217  	hackedHandler := *(*func())(unsafe.Pointer(&struct{ fn uintptr }{fn: hackedFn}))
   218  	xtesting.Equal(t, HackGetHiddenString(hackedFn, funcSize), "handlerName")
   219  	xtesting.NotPanic(t, func() { hackedHandler() })
   220  
   221  	handler2 := func(i int) int { return i + 1000 }
   222  	funcSize2 := int(reflect.TypeOf(func(int) int { return 0 }).Size())
   223  	handlerFn2 := (*struct{ fn uintptr })(unsafe.Pointer(&handler2)).fn
   224  	hackedFn2 := HackHideString(handlerFn2, funcSize2, "测试")
   225  	hackedHandler2 := *(*func(int) int)(unsafe.Pointer(&struct{ fn uintptr }{fn: hackedFn2}))
   226  	xtesting.Equal(t, HackGetHiddenString(hackedFn2, funcSize2), "测试")
   227  	xtesting.NotPanic(t, func() { xtesting.Equal(t, hackedHandler2(123), 1123) })
   228  
   229  	slice := []int{1, 2, 3}
   230  	sliceSize := int(reflect.TypeOf([3]int{}).Size())
   231  	sliceData := (*reflect.SliceHeader)(unsafe.Pointer(&slice)).Data
   232  	hackedData := HackHideString(sliceData, sliceSize, "handlerName")
   233  	hackedSlice := *(*[]int)(unsafe.Pointer(&reflect.SliceHeader{Data: hackedData, Len: 3, Cap: 3}))
   234  	xtesting.Equal(t, HackGetHiddenString(hackedData, sliceSize), "handlerName")
   235  	xtesting.Equal(t, hackedSlice, []int{1, 2, 3})
   236  
   237  	slice2 := []string{"AAA", "BBB", "CCC", "DDD"}
   238  	sliceSize2 := int(reflect.TypeOf([4]string{}).Size())
   239  	sliceData2 := (*reflect.SliceHeader)(unsafe.Pointer(&slice2)).Data
   240  	hackedData2 := HackHideString(sliceData2, sliceSize2, "テスト")
   241  	hackedSlice2 := *(*[]string)(unsafe.Pointer(&reflect.SliceHeader{Data: hackedData2, Len: 4, Cap: 4}))
   242  	xtesting.Equal(t, HackGetHiddenString(hackedData2, sliceSize2), "テスト")
   243  	xtesting.Equal(t, hackedSlice2, []string{"AAA", "BBB", "CCC", "DDD"})
   244  
   245  	httpMethod := "GET"
   246  	hackedMethod := HackHideStringAfterString(httpMethod, "handlerName")
   247  	xtesting.Equal(t, HackGetHiddenStringAfterString(hackedMethod), "handlerName")
   248  	xtesting.Equal(t, hackedMethod, "GET")
   249  
   250  	httpMethod2 := "中文测试"
   251  	hackedMethod2 := HackHideStringAfterString(httpMethod2, "日本語のテスト")
   252  	xtesting.Equal(t, HackGetHiddenStringAfterString(hackedMethod2), "日本語のテスト")
   253  	xtesting.Equal(t, hackedMethod2, "中文测试")
   254  
   255  	xtesting.Equal(t, HackGetHiddenString((*struct{ fn uintptr })(unsafe.Pointer(&handler)).fn, funcSize), "")
   256  	xtesting.Equal(t, HackGetHiddenString((*struct{ fn uintptr })(unsafe.Pointer(&handler2)).fn, funcSize2), "")
   257  	xtesting.Equal(t, HackGetHiddenString((*struct{ fn uintptr })(unsafe.Pointer(&slice)).fn, sliceSize), "")
   258  	xtesting.Equal(t, HackGetHiddenString((*struct{ fn uintptr })(unsafe.Pointer(&slice2)).fn, sliceSize2), "")
   259  	xtesting.Equal(t, HackGetHiddenStringAfterString(httpMethod), "")
   260  	xtesting.Equal(t, HackGetHiddenStringAfterString(httpMethod2), "")
   261  }
   262  
   263  func TestPprofProfile(t *testing.T) {
   264  	for _, tc := range []struct {
   265  		give string
   266  		want bool
   267  	}{
   268  		{"", false},
   269  		{PprofAllocsProfile, true},
   270  		{PprofBlockProfle, true},
   271  		{PprofGoroutineProfile, true},
   272  		{PprofHeapProfile, true},
   273  		{PprofMutexProfile, true},
   274  		{PprofThreadcreateProfile, true},
   275  		{"index", false},
   276  		{"cmdline", false},
   277  		{"profile", false},
   278  		{"symbol", false},
   279  		{"trace", false},
   280  	} {
   281  		xtesting.Equal(t, pprof.Lookup(tc.give) != nil, tc.want)
   282  	}
   283  }
   284  
   285  func TestSignalName(t *testing.T) {
   286  	for _, tc := range []struct {
   287  		give syscall.Signal
   288  		want string
   289  	}{
   290  		{-1, "signal -1"},
   291  		{0, "signal 0"},
   292  		{syscall.SIGHUP, "SIGHUP"},
   293  		{syscall.SIGINT, "SIGINT"},
   294  		{syscall.SIGQUIT, "SIGQUIT"},
   295  		{syscall.SIGILL, "SIGILL"},
   296  		{syscall.SIGTRAP, "SIGTRAP"},
   297  		{syscall.SIGABRT, "SIGABRT"},
   298  		{syscall.SIGBUS, "SIGBUS"},
   299  		{syscall.SIGFPE, "SIGFPE"},
   300  		{syscall.SIGKILL, "SIGKILL"},
   301  		{10, "SIGUSR1"},
   302  		{syscall.SIGSEGV, "SIGSEGV"},
   303  		{12, "SIGUSR2"},
   304  		{syscall.SIGPIPE, "SIGPIPE"},
   305  		{syscall.SIGALRM, "SIGALRM"},
   306  		{syscall.SIGTERM, "SIGTERM"},
   307  		{16, "signal 16"},
   308  	} {
   309  		t.Run(tc.want, func(t *testing.T) {
   310  			xtesting.Equal(t, SignalName(tc.give), tc.want)
   311  		})
   312  	}
   313  
   314  	for _, tc := range []struct {
   315  		give syscall.Signal
   316  		want string
   317  	}{
   318  		{-1, "signal -1"},
   319  		{0, "signal 0"},
   320  		{syscall.SIGHUP, "hangup"},
   321  		{syscall.SIGINT, "interrupt"},
   322  		{syscall.SIGQUIT, "quit"},
   323  		{syscall.SIGILL, "illegal instruction"},
   324  		{syscall.SIGTRAP, "trace/breakpoint trap"},
   325  		{syscall.SIGABRT, "aborted"},
   326  		{syscall.SIGBUS, "bus error"},
   327  		{syscall.SIGFPE, "floating point exception"},
   328  		{syscall.SIGKILL, "killed"},
   329  		{10, "user defined signal 1"},
   330  		{syscall.SIGSEGV, "segmentation fault"},
   331  		{12, "user defined signal 2"},
   332  		{syscall.SIGPIPE, "broken pipe"},
   333  		{syscall.SIGALRM, "alarm clock"},
   334  		{syscall.SIGTERM, "terminated"},
   335  		{16, "signal 16"},
   336  	} {
   337  		t.Run(tc.want, func(t *testing.T) {
   338  			xtesting.Equal(t, SignalReadableName(tc.give), tc.want)
   339  		})
   340  	}
   341  }
   342  
   343  func TestGetProxyEnv(t *testing.T) {
   344  	envs := map[string]string{}
   345  	for _, key := range []string{"no_proxy", "http_proxy", "https_proxy", "socks_proxy"} {
   346  		if env, ok := os.LookupEnv(key); ok {
   347  			envs[key] = env
   348  		}
   349  	}
   350  	defer func() {
   351  		for key, env := range envs {
   352  			os.Setenv(key, env)
   353  		}
   354  	}()
   355  
   356  	os.Setenv("no_proxy", "")
   357  	os.Setenv("http_proxy", "")
   358  	os.Setenv("https_proxy", "")
   359  	os.Setenv("socks_proxy", "")
   360  	env := GetProxyEnv()
   361  	xtesting.Equal(t, env.NoProxy, "")
   362  	xtesting.Equal(t, env.HttpProxy, "")
   363  	xtesting.Equal(t, env.HttpsProxy, "")
   364  	xtesting.Equal(t, env.SocksProxy, "")
   365  	sb := &strings.Builder{}
   366  	env.PrintLog(func(s string) { sb.WriteString(s + "\n") }, "[XXX] ")
   367  	xtesting.Equal(t, sb.String(), "")
   368  
   369  	os.Setenv("no_proxy", "localhost,127.0.0.1,::1")
   370  	os.Setenv("http_proxy", "http://localhost:9000")
   371  	os.Setenv("https_proxy", "https://localhost:9000")
   372  	os.Setenv("socks_proxy", "socks://localhost:9000")
   373  	env = GetProxyEnv()
   374  	xtesting.Equal(t, env.NoProxy, "localhost,127.0.0.1,::1")
   375  	xtesting.Equal(t, env.HttpProxy, "http://localhost:9000")
   376  	xtesting.Equal(t, env.HttpsProxy, "https://localhost:9000")
   377  	xtesting.Equal(t, env.SocksProxy, "socks://localhost:9000")
   378  	sb.Reset()
   379  	env.PrintLog(func(s string) { sb.WriteString(s) }, "[XXX] ")
   380  	lines := []string{
   381  		"[XXX] Using no_proxy: localhost,127.0.0.1,::1",
   382  		"[XXX] Using http_proxy: http://localhost:9000",
   383  		"[XXX] Using https_proxy: https://localhost:9000",
   384  		"[XXX] Using socks_proxy: socks://localhost:9000",
   385  	}
   386  	xtesting.Equal(t, sb.String(), strings.Join(lines, ""))
   387  	env.PrintLog(nil, "") // log
   388  
   389  	os.Setenv("no_proxy", "")
   390  	os.Setenv("http_proxy", "")
   391  	os.Setenv("https_proxy", "")
   392  	os.Setenv("socks_proxy", "")
   393  	env = GetProxyEnv()
   394  	xtesting.Equal(t, env.NoProxy, "")
   395  	xtesting.Equal(t, env.HttpProxy, "")
   396  	xtesting.Equal(t, env.HttpsProxy, "")
   397  	xtesting.Equal(t, env.SocksProxy, "")
   398  	sb.Reset()
   399  	env.PrintLog(func(s string) { sb.WriteString(s + "\n") }, "[XXX] ")
   400  	xtesting.Equal(t, sb.String(), "")
   401  }
   402  
   403  func TestParseNetAddr(t *testing.T) {
   404  	for _, tc := range []struct {
   405  		give NetAddrType
   406  		want string
   407  	}{
   408  		{TCPAddrType, "TCPAddr"},
   409  		{UDPAddrType, "UDPAddr"},
   410  		{IPAddrType, "IPAddr"},
   411  		{UnixAddrType, "UnixAddr"},
   412  	} {
   413  		xtesting.Equal(t, tc.give.String(), tc.want)
   414  	}
   415  
   416  	tcpAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 12345, Zone: "test ipv6 zone"}
   417  	udpAddr := &net.UDPAddr{IP: net.ParseIP("::1"), Port: 12, Zone: "test zone"}
   418  	ipAddr := &net.IPAddr{IP: net.ParseIP("192.168.3.255"), Zone: ""}
   419  	ipAddr2 := &net.IPAddr{IP: net.ParseIP("192.168.1.999"), Zone: "123"}
   420  	unixAddr := &net.UnixAddr{Name: "test.socks", Net: "net"}
   421  	unsupportedAddr := &net.IPNet{}
   422  	for _, tc := range []struct {
   423  		giveAddr net.Addr
   424  		wantOk   bool
   425  		wantType NetAddrType
   426  		wantIP   string
   427  		wantPort int
   428  		wantZone string
   429  		wantName string
   430  		wantNet  string
   431  	}{
   432  		{nil, false, "", "", 0, "", "", ""},
   433  		{tcpAddr, true, TCPAddrType, "127.0.0.1", 12345, "test ipv6 zone", "", ""},
   434  		{udpAddr, true, UDPAddrType, "::1", 12, "test zone", "", ""},
   435  		{ipAddr, true, IPAddrType, "192.168.3.255", 0, "", "", ""},
   436  		{ipAddr2, true, IPAddrType, "", 0, "123", "", ""},
   437  		{unixAddr, true, UnixAddrType, "", 0, "", "test.socks", "net"},
   438  		{unsupportedAddr, false, "", "", 0, "", "", ""},
   439  	} {
   440  		t.Run(tc.wantType.String(), func(t *testing.T) {
   441  			addr, ok := ParseNetAddr(tc.giveAddr)
   442  			xtesting.Equal(t, ok, tc.wantOk)
   443  			if !tc.wantOk {
   444  				xtesting.Nil(t, addr)
   445  			} else {
   446  				xtesting.Equal(t, addr.Type, tc.wantType)
   447  				switch tc.wantType {
   448  				case TCPAddrType:
   449  					xtesting.Equal(t, addr.TCPAddr, tc.giveAddr.(*net.TCPAddr))
   450  				case UDPAddrType:
   451  					xtesting.Equal(t, addr.UDPAddr, tc.giveAddr.(*net.UDPAddr))
   452  				case IPAddrType:
   453  					xtesting.Equal(t, addr.IPAddr, tc.giveAddr.(*net.IPAddr))
   454  				case UnixAddrType:
   455  					xtesting.Equal(t, addr.UnixAddr, tc.giveAddr.(*net.UnixAddr))
   456  				}
   457  				if tc.wantIP != "" {
   458  					xtesting.Equal(t, addr.IP.String(), tc.wantIP)
   459  				} else {
   460  					xtesting.Equal(t, addr.IP, (net.IP)(nil))
   461  				}
   462  				xtesting.Equal(t, addr.Port, tc.wantPort)
   463  				xtesting.Equal(t, addr.Zone, tc.wantZone)
   464  				xtesting.Equal(t, addr.Name, tc.wantName)
   465  				xtesting.Equal(t, addr.Net, tc.wantNet)
   466  			}
   467  		})
   468  	}
   469  }