...

Source file src/net/ipsock_test.go

Documentation: net

		 1  // Copyright 2013 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 net
		 6  
		 7  import (
		 8  	"reflect"
		 9  	"testing"
		10  )
		11  
		12  var testInetaddr = func(ip IPAddr) Addr { return &TCPAddr{IP: ip.IP, Port: 5682, Zone: ip.Zone} }
		13  
		14  var addrListTests = []struct {
		15  	filter		func(IPAddr) bool
		16  	ips			 []IPAddr
		17  	inetaddr	func(IPAddr) Addr
		18  	first		 Addr
		19  	primaries addrList
		20  	fallbacks addrList
		21  	err			 error
		22  }{
		23  	{
		24  		nil,
		25  		[]IPAddr{
		26  			{IP: IPv4(127, 0, 0, 1)},
		27  			{IP: IPv6loopback},
		28  		},
		29  		testInetaddr,
		30  		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
		31  		addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
		32  		addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
		33  		nil,
		34  	},
		35  	{
		36  		nil,
		37  		[]IPAddr{
		38  			{IP: IPv6loopback},
		39  			{IP: IPv4(127, 0, 0, 1)},
		40  		},
		41  		testInetaddr,
		42  		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
		43  		addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
		44  		addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
		45  		nil,
		46  	},
		47  	{
		48  		nil,
		49  		[]IPAddr{
		50  			{IP: IPv4(127, 0, 0, 1)},
		51  			{IP: IPv4(192, 168, 0, 1)},
		52  		},
		53  		testInetaddr,
		54  		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
		55  		addrList{
		56  			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
		57  			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
		58  		},
		59  		nil,
		60  		nil,
		61  	},
		62  	{
		63  		nil,
		64  		[]IPAddr{
		65  			{IP: IPv6loopback},
		66  			{IP: ParseIP("fe80::1"), Zone: "eth0"},
		67  		},
		68  		testInetaddr,
		69  		&TCPAddr{IP: IPv6loopback, Port: 5682},
		70  		addrList{
		71  			&TCPAddr{IP: IPv6loopback, Port: 5682},
		72  			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
		73  		},
		74  		nil,
		75  		nil,
		76  	},
		77  	{
		78  		nil,
		79  		[]IPAddr{
		80  			{IP: IPv4(127, 0, 0, 1)},
		81  			{IP: IPv4(192, 168, 0, 1)},
		82  			{IP: IPv6loopback},
		83  			{IP: ParseIP("fe80::1"), Zone: "eth0"},
		84  		},
		85  		testInetaddr,
		86  		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
		87  		addrList{
		88  			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
		89  			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
		90  		},
		91  		addrList{
		92  			&TCPAddr{IP: IPv6loopback, Port: 5682},
		93  			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
		94  		},
		95  		nil,
		96  	},
		97  	{
		98  		nil,
		99  		[]IPAddr{
	 100  			{IP: IPv6loopback},
	 101  			{IP: ParseIP("fe80::1"), Zone: "eth0"},
	 102  			{IP: IPv4(127, 0, 0, 1)},
	 103  			{IP: IPv4(192, 168, 0, 1)},
	 104  		},
	 105  		testInetaddr,
	 106  		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
	 107  		addrList{
	 108  			&TCPAddr{IP: IPv6loopback, Port: 5682},
	 109  			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
	 110  		},
	 111  		addrList{
	 112  			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
	 113  			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
	 114  		},
	 115  		nil,
	 116  	},
	 117  	{
	 118  		nil,
	 119  		[]IPAddr{
	 120  			{IP: IPv4(127, 0, 0, 1)},
	 121  			{IP: IPv6loopback},
	 122  			{IP: IPv4(192, 168, 0, 1)},
	 123  			{IP: ParseIP("fe80::1"), Zone: "eth0"},
	 124  		},
	 125  		testInetaddr,
	 126  		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
	 127  		addrList{
	 128  			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
	 129  			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
	 130  		},
	 131  		addrList{
	 132  			&TCPAddr{IP: IPv6loopback, Port: 5682},
	 133  			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
	 134  		},
	 135  		nil,
	 136  	},
	 137  	{
	 138  		nil,
	 139  		[]IPAddr{
	 140  			{IP: IPv6loopback},
	 141  			{IP: IPv4(127, 0, 0, 1)},
	 142  			{IP: ParseIP("fe80::1"), Zone: "eth0"},
	 143  			{IP: IPv4(192, 168, 0, 1)},
	 144  		},
	 145  		testInetaddr,
	 146  		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
	 147  		addrList{
	 148  			&TCPAddr{IP: IPv6loopback, Port: 5682},
	 149  			&TCPAddr{IP: ParseIP("fe80::1"), Port: 5682, Zone: "eth0"},
	 150  		},
	 151  		addrList{
	 152  			&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
	 153  			&TCPAddr{IP: IPv4(192, 168, 0, 1), Port: 5682},
	 154  		},
	 155  		nil,
	 156  	},
	 157  
	 158  	{
	 159  		ipv4only,
	 160  		[]IPAddr{
	 161  			{IP: IPv4(127, 0, 0, 1)},
	 162  			{IP: IPv6loopback},
	 163  		},
	 164  		testInetaddr,
	 165  		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
	 166  		addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
	 167  		nil,
	 168  		nil,
	 169  	},
	 170  	{
	 171  		ipv4only,
	 172  		[]IPAddr{
	 173  			{IP: IPv6loopback},
	 174  			{IP: IPv4(127, 0, 0, 1)},
	 175  		},
	 176  		testInetaddr,
	 177  		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682},
	 178  		addrList{&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 5682}},
	 179  		nil,
	 180  		nil,
	 181  	},
	 182  
	 183  	{
	 184  		ipv6only,
	 185  		[]IPAddr{
	 186  			{IP: IPv4(127, 0, 0, 1)},
	 187  			{IP: IPv6loopback},
	 188  		},
	 189  		testInetaddr,
	 190  		&TCPAddr{IP: IPv6loopback, Port: 5682},
	 191  		addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
	 192  		nil,
	 193  		nil,
	 194  	},
	 195  	{
	 196  		ipv6only,
	 197  		[]IPAddr{
	 198  			{IP: IPv6loopback},
	 199  			{IP: IPv4(127, 0, 0, 1)},
	 200  		},
	 201  		testInetaddr,
	 202  		&TCPAddr{IP: IPv6loopback, Port: 5682},
	 203  		addrList{&TCPAddr{IP: IPv6loopback, Port: 5682}},
	 204  		nil,
	 205  		nil,
	 206  	},
	 207  
	 208  	{nil, nil, testInetaddr, nil, nil, nil, &AddrError{errNoSuitableAddress.Error(), "ADDR"}},
	 209  
	 210  	{ipv4only, nil, testInetaddr, nil, nil, nil, &AddrError{errNoSuitableAddress.Error(), "ADDR"}},
	 211  	{ipv4only, []IPAddr{{IP: IPv6loopback}}, testInetaddr, nil, nil, nil, &AddrError{errNoSuitableAddress.Error(), "ADDR"}},
	 212  
	 213  	{ipv6only, nil, testInetaddr, nil, nil, nil, &AddrError{errNoSuitableAddress.Error(), "ADDR"}},
	 214  	{ipv6only, []IPAddr{{IP: IPv4(127, 0, 0, 1)}}, testInetaddr, nil, nil, nil, &AddrError{errNoSuitableAddress.Error(), "ADDR"}},
	 215  }
	 216  
	 217  func TestAddrList(t *testing.T) {
	 218  	if !supportsIPv4() || !supportsIPv6() {
	 219  		t.Skip("both IPv4 and IPv6 are required")
	 220  	}
	 221  
	 222  	for i, tt := range addrListTests {
	 223  		addrs, err := filterAddrList(tt.filter, tt.ips, tt.inetaddr, "ADDR")
	 224  		if !reflect.DeepEqual(err, tt.err) {
	 225  			t.Errorf("#%v: got %v; want %v", i, err, tt.err)
	 226  		}
	 227  		if tt.err != nil {
	 228  			if len(addrs) != 0 {
	 229  				t.Errorf("#%v: got %v; want 0", i, len(addrs))
	 230  			}
	 231  			continue
	 232  		}
	 233  		first := addrs.first(isIPv4)
	 234  		if !reflect.DeepEqual(first, tt.first) {
	 235  			t.Errorf("#%v: got %v; want %v", i, first, tt.first)
	 236  		}
	 237  		primaries, fallbacks := addrs.partition(isIPv4)
	 238  		if !reflect.DeepEqual(primaries, tt.primaries) {
	 239  			t.Errorf("#%v: got %v; want %v", i, primaries, tt.primaries)
	 240  		}
	 241  		if !reflect.DeepEqual(fallbacks, tt.fallbacks) {
	 242  			t.Errorf("#%v: got %v; want %v", i, fallbacks, tt.fallbacks)
	 243  		}
	 244  		expectedLen := len(primaries) + len(fallbacks)
	 245  		if len(addrs) != expectedLen {
	 246  			t.Errorf("#%v: got %v; want %v", i, len(addrs), expectedLen)
	 247  		}
	 248  	}
	 249  }
	 250  
	 251  func TestAddrListPartition(t *testing.T) {
	 252  	addrs := addrList{
	 253  		&IPAddr{IP: ParseIP("fe80::"), Zone: "eth0"},
	 254  		&IPAddr{IP: ParseIP("fe80::1"), Zone: "eth0"},
	 255  		&IPAddr{IP: ParseIP("fe80::2"), Zone: "eth0"},
	 256  	}
	 257  	cases := []struct {
	 258  		lastByte	byte
	 259  		primaries addrList
	 260  		fallbacks addrList
	 261  	}{
	 262  		{0, addrList{addrs[0]}, addrList{addrs[1], addrs[2]}},
	 263  		{1, addrList{addrs[0], addrs[2]}, addrList{addrs[1]}},
	 264  		{2, addrList{addrs[0], addrs[1]}, addrList{addrs[2]}},
	 265  		{3, addrList{addrs[0], addrs[1], addrs[2]}, nil},
	 266  	}
	 267  	for i, tt := range cases {
	 268  		// Inverting the function's output should not affect the outcome.
	 269  		for _, invert := range []bool{false, true} {
	 270  			primaries, fallbacks := addrs.partition(func(a Addr) bool {
	 271  				ip := a.(*IPAddr).IP
	 272  				return (ip[len(ip)-1] == tt.lastByte) != invert
	 273  			})
	 274  			if !reflect.DeepEqual(primaries, tt.primaries) {
	 275  				t.Errorf("#%v: got %v; want %v", i, primaries, tt.primaries)
	 276  			}
	 277  			if !reflect.DeepEqual(fallbacks, tt.fallbacks) {
	 278  				t.Errorf("#%v: got %v; want %v", i, fallbacks, tt.fallbacks)
	 279  			}
	 280  		}
	 281  	}
	 282  }
	 283  

View as plain text