The Go Programming Language

Source file src/pkg/net/ip_test.go

     1	// Copyright 2009 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		"bytes"
     9		"reflect"
    10		"testing"
    11		"os"
    12		"runtime"
    13	)
    14	
    15	func isEqual(a, b []byte) bool {
    16		if a == nil && b == nil {
    17			return true
    18		}
    19		if a == nil || b == nil {
    20			return false
    21		}
    22		return bytes.Equal(a, b)
    23	}
    24	
    25	var parseiptests = []struct {
    26		in  string
    27		out IP
    28	}{
    29		{"127.0.1.2", IPv4(127, 0, 1, 2)},
    30		{"127.0.0.1", IPv4(127, 0, 0, 1)},
    31		{"127.0.0.256", nil},
    32		{"abc", nil},
    33		{"123:", nil},
    34		{"::ffff:127.0.0.1", IPv4(127, 0, 0, 1)},
    35		{"2001:4860:0:2001::68", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},
    36		{"::ffff:4a7d:1363", IPv4(74, 125, 19, 99)},
    37	}
    38	
    39	func TestParseIP(t *testing.T) {
    40		for _, tt := range parseiptests {
    41			if out := ParseIP(tt.in); !isEqual(out, tt.out) {
    42				t.Errorf("ParseIP(%#q) = %v, want %v", tt.in, out, tt.out)
    43			}
    44		}
    45	}
    46	
    47	var ipstringtests = []struct {
    48		in  IP
    49		out string
    50	}{
    51		// cf. RFC 5952 (A Recommendation for IPv6 Address Text Representation)
    52		{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1},
    53			"2001:db8::123:12:1"},
    54		{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1},
    55			"2001:db8::1"},
    56		{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1},
    57			"2001:db8:0:1:0:1:0:1"},
    58		{IP{0x20, 0x1, 0xd, 0xb8, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0},
    59			"2001:db8:1:0:1:0:1:0"},
    60		{IP{0x20, 0x1, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1},
    61			"2001::1:0:0:1"},
    62		{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0},
    63			"2001:db8:0:0:1::"},
    64		{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1},
    65			"2001:db8::1:0:0:1"},
    66		{IP{0x20, 0x1, 0xD, 0xB8, 0, 0, 0, 0, 0, 0xA, 0, 0xB, 0, 0xC, 0, 0xD},
    67			"2001:db8::a:b:c:d"},
    68	}
    69	
    70	func TestIPString(t *testing.T) {
    71		for _, tt := range ipstringtests {
    72			if out := tt.in.String(); out != tt.out {
    73				t.Errorf("IP.String(%v) = %#q, want %#q", tt.in, out, tt.out)
    74			}
    75		}
    76	}
    77	
    78	var parsecidrtests = []struct {
    79		in   string
    80		ip   IP
    81		mask IPMask
    82		err  os.Error
    83	}{
    84		{"135.104.0.0/32", IPv4(135, 104, 0, 0), IPv4Mask(255, 255, 255, 255), nil},
    85		{"0.0.0.0/24", IPv4(0, 0, 0, 0), IPv4Mask(255, 255, 255, 0), nil},
    86		{"135.104.0.0/24", IPv4(135, 104, 0, 0), IPv4Mask(255, 255, 255, 0), nil},
    87		{"135.104.0.1/32", IPv4(135, 104, 0, 1), IPv4Mask(255, 255, 255, 255), nil},
    88		{"135.104.0.1/24", nil, nil, &ParseError{"CIDR address", "135.104.0.1/24"}},
    89		{"::1/128", ParseIP("::1"), IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")), nil},
    90		{"abcd:2345::/127", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe")), nil},
    91		{"abcd:2345::/65", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:ffff:ffff:8000::")), nil},
    92		{"abcd:2345::/64", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:ffff:ffff::")), nil},
    93		{"abcd:2345::/63", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:ffff:fffe::")), nil},
    94		{"abcd:2345::/33", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff:8000::")), nil},
    95		{"abcd:2345::/32", ParseIP("abcd:2345::"), IPMask(ParseIP("ffff:ffff::")), nil},
    96		{"abcd:2344::/31", ParseIP("abcd:2344::"), IPMask(ParseIP("ffff:fffe::")), nil},
    97		{"abcd:2300::/24", ParseIP("abcd:2300::"), IPMask(ParseIP("ffff:ff00::")), nil},
    98		{"abcd:2345::/24", nil, nil, &ParseError{"CIDR address", "abcd:2345::/24"}},
    99		{"2001:DB8::/48", ParseIP("2001:DB8::"), IPMask(ParseIP("ffff:ffff:ffff::")), nil},
   100	}
   101	
   102	func TestParseCIDR(t *testing.T) {
   103		for _, tt := range parsecidrtests {
   104			if ip, mask, err := ParseCIDR(tt.in); !isEqual(ip, tt.ip) || !isEqual(mask, tt.mask) || !reflect.DeepEqual(err, tt.err) {
   105				t.Errorf("ParseCIDR(%q) = %v, %v, %v; want %v, %v, %v", tt.in, ip, mask, err, tt.ip, tt.mask, tt.err)
   106			}
   107		}
   108	}
   109	
   110	var splitjointests = []struct {
   111		Host string
   112		Port string
   113		Join string
   114	}{
   115		{"www.google.com", "80", "www.google.com:80"},
   116		{"127.0.0.1", "1234", "127.0.0.1:1234"},
   117		{"::1", "80", "[::1]:80"},
   118	}
   119	
   120	func TestSplitHostPort(t *testing.T) {
   121		for _, tt := range splitjointests {
   122			if host, port, err := SplitHostPort(tt.Join); host != tt.Host || port != tt.Port || err != nil {
   123				t.Errorf("SplitHostPort(%q) = %q, %q, %v; want %q, %q, nil", tt.Join, host, port, err, tt.Host, tt.Port)
   124			}
   125		}
   126	}
   127	
   128	func TestJoinHostPort(t *testing.T) {
   129		for _, tt := range splitjointests {
   130			if join := JoinHostPort(tt.Host, tt.Port); join != tt.Join {
   131				t.Errorf("JoinHostPort(%q, %q) = %q; want %q", tt.Host, tt.Port, join, tt.Join)
   132			}
   133		}
   134	}
   135	
   136	var ipaftests = []struct {
   137		in  IP
   138		af4 bool
   139		af6 bool
   140	}{
   141		{IPv4bcast, true, false},
   142		{IPv4allsys, true, false},
   143		{IPv4allrouter, true, false},
   144		{IPv4zero, true, false},
   145		{IPv4(224, 0, 0, 1), true, false},
   146		{IPv4(127, 0, 0, 1), true, false},
   147		{IPv4(240, 0, 0, 1), true, false},
   148		{IPv6unspecified, false, true},
   149		{IPv6loopback, false, true},
   150		{IPv6interfacelocalallnodes, false, true},
   151		{IPv6linklocalallnodes, false, true},
   152		{IPv6linklocalallrouters, false, true},
   153		{ParseIP("ff05::a:b:c:d"), false, true},
   154		{ParseIP("fe80::1:2:3:4"), false, true},
   155		{ParseIP("2001:db8::123:12:1"), false, true},
   156	}
   157	
   158	func TestIPAddrFamily(t *testing.T) {
   159		for _, tt := range ipaftests {
   160			if af := tt.in.To4() != nil; af != tt.af4 {
   161				t.Errorf("verifying IPv4 address family for %#q = %v, want %v", tt.in, af, tt.af4)
   162			}
   163			if af := len(tt.in) == IPv6len && tt.in.To4() == nil; af != tt.af6 {
   164				t.Errorf("verifying IPv6 address family for %#q = %v, want %v", tt.in, af, tt.af6)
   165			}
   166		}
   167	}
   168	
   169	var ipscopetests = []struct {
   170		scope func(IP) bool
   171		in    IP
   172		ok    bool
   173	}{
   174		{IP.IsUnspecified, IPv4zero, true},
   175		{IP.IsUnspecified, IPv4(127, 0, 0, 1), false},
   176		{IP.IsUnspecified, IPv6unspecified, true},
   177		{IP.IsUnspecified, IPv6interfacelocalallnodes, false},
   178		{IP.IsLoopback, IPv4(127, 0, 0, 1), true},
   179		{IP.IsLoopback, IPv4(127, 255, 255, 254), true},
   180		{IP.IsLoopback, IPv4(128, 1, 2, 3), false},
   181		{IP.IsLoopback, IPv6loopback, true},
   182		{IP.IsLoopback, IPv6linklocalallrouters, false},
   183		{IP.IsMulticast, IPv4(224, 0, 0, 0), true},
   184		{IP.IsMulticast, IPv4(239, 0, 0, 0), true},
   185		{IP.IsMulticast, IPv4(240, 0, 0, 0), false},
   186		{IP.IsMulticast, IPv6linklocalallnodes, true},
   187		{IP.IsMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
   188		{IP.IsMulticast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
   189		{IP.IsLinkLocalMulticast, IPv4(224, 0, 0, 0), true},
   190		{IP.IsLinkLocalMulticast, IPv4(239, 0, 0, 0), false},
   191		{IP.IsLinkLocalMulticast, IPv6linklocalallrouters, true},
   192		{IP.IsLinkLocalMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
   193		{IP.IsLinkLocalUnicast, IPv4(169, 254, 0, 0), true},
   194		{IP.IsLinkLocalUnicast, IPv4(169, 255, 0, 0), false},
   195		{IP.IsLinkLocalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
   196		{IP.IsLinkLocalUnicast, IP{0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
   197		{IP.IsGlobalUnicast, IPv4(240, 0, 0, 0), true},
   198		{IP.IsGlobalUnicast, IPv4(232, 0, 0, 0), false},
   199		{IP.IsGlobalUnicast, IPv4(169, 254, 0, 0), false},
   200		{IP.IsGlobalUnicast, IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, true},
   201		{IP.IsGlobalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
   202		{IP.IsGlobalUnicast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
   203	}
   204	
   205	func name(f interface{}) string {
   206		return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
   207	}
   208	
   209	func TestIPAddrScope(t *testing.T) {
   210		for _, tt := range ipscopetests {
   211			if ok := tt.scope(tt.in); ok != tt.ok {
   212				t.Errorf("%s(%#q) = %v, want %v", name(tt.scope), tt.in, ok, tt.ok)
   213			}
   214		}
   215	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.