github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/libnetwork/types/types_test.go (about)

     1  package types
     2  
     3  import (
     4  	"net"
     5  	"testing"
     6  
     7  	_ "github.com/docker/libnetwork/testutils"
     8  	"gotest.tools/v3/assert"
     9  	is "gotest.tools/v3/assert/cmp"
    10  )
    11  
    12  func TestTransportPortConv(t *testing.T) {
    13  	sform := "tcp/23"
    14  	tp := &TransportPort{Proto: TCP, Port: uint16(23)}
    15  
    16  	if sform != tp.String() {
    17  		t.Fatalf("String() method failed")
    18  	}
    19  
    20  	rc := new(TransportPort)
    21  	if err := rc.FromString(sform); err != nil {
    22  		t.Fatal(err)
    23  	}
    24  	if !tp.Equal(rc) {
    25  		t.Fatalf("FromString() method failed")
    26  	}
    27  }
    28  
    29  func TestTransportPortBindingConv(t *testing.T) {
    30  	input := []struct {
    31  		sform      string
    32  		pb         PortBinding
    33  		shouldFail bool
    34  	}{
    35  		{ // IPv4 -> IPv4
    36  			sform: "tcp/172.28.30.23:80/112.0.43.56:8001",
    37  			pb: PortBinding{
    38  				Proto:    TCP,
    39  				IP:       net.IPv4(172, 28, 30, 23),
    40  				Port:     uint16(80),
    41  				HostIP:   net.IPv4(112, 0, 43, 56),
    42  				HostPort: uint16(8001),
    43  			},
    44  		},
    45  		{ // IPv6 -> IPv4
    46  			sform: "tcp/[2001:db8::1]:80/112.0.43.56:8001",
    47  			pb: PortBinding{
    48  				Proto:    TCP,
    49  				IP:       net.IP{0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    50  				Port:     uint16(80),
    51  				HostIP:   net.IPv4(112, 0, 43, 56),
    52  				HostPort: uint16(8001),
    53  			},
    54  		},
    55  		{ // IPv4inIPv6 -> IPv4
    56  			sform: "tcp/[::ffff:172.28.30.23]:80/112.0.43.56:8001",
    57  			pb: PortBinding{
    58  				Proto:    TCP,
    59  				IP:       net.IPv4(172, 28, 30, 23),
    60  				Port:     uint16(80),
    61  				HostIP:   net.IPv4(112, 0, 43, 56),
    62  				HostPort: uint16(8001),
    63  			},
    64  		},
    65  		{ // IPv4 -> IPv4 zoned
    66  			sform:      "tcp/172.28.30.23:80/169.254.0.23%eth0:8001",
    67  			shouldFail: true,
    68  		},
    69  		{ // IPv4 -> IPv6 zoned
    70  			sform:      "tcp/172.28.30.23:80/[fe80::1ff:fe23:4567:890a%eth0]:8001",
    71  			shouldFail: true,
    72  		},
    73  	}
    74  
    75  	for _, in := range input {
    76  		rc := new(PortBinding)
    77  		err := rc.FromString(in.sform)
    78  		if in.shouldFail {
    79  			assert.Assert(t, is.ErrorContains(err, ""), "Unexpected success parsing %s", in.sform)
    80  		} else {
    81  			assert.NilError(t, err)
    82  			assert.Assert(t, is.DeepEqual(in.pb, *rc), "input %s: expected %#v, got %#v", in.sform, in.pb, rc)
    83  		}
    84  	}
    85  }
    86  
    87  func TestErrorConstructors(t *testing.T) {
    88  	var err error
    89  
    90  	err = BadRequestErrorf("Io ho %d uccello", 1)
    91  	if err.Error() != "Io ho 1 uccello" {
    92  		t.Fatal(err)
    93  	}
    94  	if _, ok := err.(BadRequestError); !ok {
    95  		t.Fatal(err)
    96  	}
    97  	if _, ok := err.(MaskableError); ok {
    98  		t.Fatal(err)
    99  	}
   100  
   101  	err = RetryErrorf("Incy wincy %s went up the spout again", "spider")
   102  	if err.Error() != "Incy wincy spider went up the spout again" {
   103  		t.Fatal(err)
   104  	}
   105  	if _, ok := err.(RetryError); !ok {
   106  		t.Fatal(err)
   107  	}
   108  	if _, ok := err.(MaskableError); ok {
   109  		t.Fatal(err)
   110  	}
   111  
   112  	err = NotFoundErrorf("Can't find the %s", "keys")
   113  	if err.Error() != "Can't find the keys" {
   114  		t.Fatal(err)
   115  	}
   116  	if _, ok := err.(NotFoundError); !ok {
   117  		t.Fatal(err)
   118  	}
   119  	if _, ok := err.(MaskableError); ok {
   120  		t.Fatal(err)
   121  	}
   122  
   123  	err = ForbiddenErrorf("Can't open door %d", 2)
   124  	if err.Error() != "Can't open door 2" {
   125  		t.Fatal(err)
   126  	}
   127  	if _, ok := err.(ForbiddenError); !ok {
   128  		t.Fatal(err)
   129  	}
   130  	if _, ok := err.(MaskableError); ok {
   131  		t.Fatal(err)
   132  	}
   133  
   134  	err = NotImplementedErrorf("Functionality %s is not implemented", "x")
   135  	if err.Error() != "Functionality x is not implemented" {
   136  		t.Fatal(err)
   137  	}
   138  	if _, ok := err.(NotImplementedError); !ok {
   139  		t.Fatal(err)
   140  	}
   141  	if _, ok := err.(MaskableError); ok {
   142  		t.Fatal(err)
   143  	}
   144  
   145  	err = TimeoutErrorf("Process %s timed out", "abc")
   146  	if err.Error() != "Process abc timed out" {
   147  		t.Fatal(err)
   148  	}
   149  	if _, ok := err.(TimeoutError); !ok {
   150  		t.Fatal(err)
   151  	}
   152  	if _, ok := err.(MaskableError); ok {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	err = NoServiceErrorf("Driver %s is not available", "mh")
   157  	if err.Error() != "Driver mh is not available" {
   158  		t.Fatal(err)
   159  	}
   160  	if _, ok := err.(NoServiceError); !ok {
   161  		t.Fatal(err)
   162  	}
   163  	if _, ok := err.(MaskableError); ok {
   164  		t.Fatal(err)
   165  	}
   166  
   167  	err = InternalErrorf("Not sure what happened")
   168  	if err.Error() != "Not sure what happened" {
   169  		t.Fatal(err)
   170  	}
   171  	if _, ok := err.(InternalError); !ok {
   172  		t.Fatal(err)
   173  	}
   174  	if _, ok := err.(MaskableError); ok {
   175  		t.Fatal(err)
   176  	}
   177  
   178  	err = InternalMaskableErrorf("Minor issue, it can be ignored")
   179  	if err.Error() != "Minor issue, it can be ignored" {
   180  		t.Fatal(err)
   181  	}
   182  	if _, ok := err.(InternalError); !ok {
   183  		t.Fatal(err)
   184  	}
   185  	if _, ok := err.(MaskableError); !ok {
   186  		t.Fatal(err)
   187  	}
   188  }
   189  
   190  func TestCompareIPMask(t *testing.T) {
   191  	input := []struct {
   192  		ip    net.IP
   193  		mask  net.IPMask
   194  		is    int
   195  		ms    int
   196  		isErr bool
   197  	}{
   198  		{ // ip in v4Inv6 representation, mask in v4 representation
   199  			ip:   net.IPv4(172, 28, 30, 1),
   200  			mask: []byte{0xff, 0xff, 0xff, 0},
   201  			is:   12,
   202  			ms:   0,
   203  		},
   204  		{ // ip and mask in v4Inv6 representation
   205  			ip:   net.IPv4(172, 28, 30, 2),
   206  			mask: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0},
   207  			is:   12,
   208  			ms:   12,
   209  		},
   210  		{ // ip in v4 representation, mask in v4Inv6 representation
   211  			ip:   net.IPv4(172, 28, 30, 3)[12:],
   212  			mask: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0},
   213  			is:   0,
   214  			ms:   12,
   215  		},
   216  		{ // ip and mask in v4 representation
   217  			ip:   net.IPv4(172, 28, 30, 4)[12:],
   218  			mask: []byte{0xff, 0xff, 0xff, 0},
   219  			is:   0,
   220  			ms:   0,
   221  		},
   222  		{ // ip and mask as v6
   223  			ip:   net.ParseIP("2001:DB8:2002:2001:FFFF:ABCD:EEAB:00CD"),
   224  			mask: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0},
   225  			is:   0,
   226  			ms:   0,
   227  		},
   228  		{
   229  			ip:    net.ParseIP("2001:DB8:2002:2001:FFFF:ABCD:EEAB:00CD"),
   230  			mask:  []byte{0xff, 0xff, 0xff, 0},
   231  			isErr: true,
   232  		},
   233  		{
   234  			ip:    net.ParseIP("173.32.4.5"),
   235  			mask:  []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0},
   236  			isErr: true,
   237  		},
   238  		{
   239  			ip:    net.ParseIP("173.32.4.5"),
   240  			mask:  []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0},
   241  			isErr: true,
   242  		},
   243  	}
   244  
   245  	for ind, i := range input {
   246  		is, ms, err := compareIPMask(i.ip, i.mask)
   247  		if i.isErr {
   248  			if err == nil {
   249  				t.Fatalf("Incorrect error condition for element %d. is: %d, ms: %d, err: %v", ind, is, ms, err)
   250  			}
   251  		} else {
   252  			if i.is != is || i.ms != ms {
   253  				t.Fatalf("expected is: %d, ms: %d. Got is: %d, ms: %d for element %d", i.is, i.ms, is, ms, ind)
   254  			}
   255  		}
   256  	}
   257  }
   258  
   259  func TestUtilGetHostPartIP(t *testing.T) {
   260  	input := []struct {
   261  		ip   net.IP
   262  		mask net.IPMask
   263  		host net.IP
   264  		err  error
   265  	}{
   266  		{ // ip in v4Inv6 representation, mask in v4 representation
   267  			ip:   net.IPv4(172, 28, 30, 1),
   268  			mask: []byte{0xff, 0xff, 0xff, 0},
   269  			host: net.IPv4(0, 0, 0, 1),
   270  		},
   271  		{ // ip and mask in v4Inv6 representation
   272  			ip:   net.IPv4(172, 28, 30, 2),
   273  			mask: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0},
   274  			host: net.IPv4(0, 0, 0, 2),
   275  		},
   276  		{ // ip in v4 representation, mask in v4Inv6 representation
   277  			ip:   net.IPv4(172, 28, 30, 3)[12:],
   278  			mask: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0},
   279  			host: net.IPv4(0, 0, 0, 3)[12:],
   280  		},
   281  		{ // ip and mask in v4 representation
   282  			ip:   net.IPv4(172, 28, 30, 4)[12:],
   283  			mask: []byte{0xff, 0xff, 0xff, 0},
   284  			host: net.IPv4(0, 0, 0, 4)[12:],
   285  		},
   286  		{ // ip and mask as v6
   287  			ip:   net.ParseIP("2001:DB8:2002:2001:FFFF:ABCD:EEAB:00CD"),
   288  			mask: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0},
   289  			host: net.ParseIP("0::AB:00CD"),
   290  		},
   291  	}
   292  
   293  	for _, i := range input {
   294  		h, err := GetHostPartIP(i.ip, i.mask)
   295  		if err != nil {
   296  			t.Fatal(err)
   297  		}
   298  		if !i.host.Equal(h) {
   299  			t.Fatalf("Failed to return expected host ip. Expected: %s. Got: %s", i.host, h)
   300  		}
   301  	}
   302  
   303  	// ip as v6 and mask as v4 are not compatible
   304  	if _, err := GetHostPartIP(net.ParseIP("2001:DB8:2002:2001:FFFF:ABCD:EEAB:00CD"), []byte{0xff, 0xff, 0xff, 0}); err == nil {
   305  		t.Fatalf("Unexpected success")
   306  	}
   307  	// ip as v4 and non conventional mask
   308  	if _, err := GetHostPartIP(net.ParseIP("173.32.4.5"), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0}); err == nil {
   309  		t.Fatalf("Unexpected success")
   310  	}
   311  	// ip as v4 and non conventional mask
   312  	if _, err := GetHostPartIP(net.ParseIP("173.32.4.5"), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0}); err == nil {
   313  		t.Fatalf("Unexpected success")
   314  	}
   315  }
   316  
   317  func TestUtilGetBroadcastIP(t *testing.T) {
   318  	input := []struct {
   319  		ip    net.IP
   320  		mask  net.IPMask
   321  		bcast net.IP
   322  		err   error
   323  	}{
   324  		// ip in v4Inv6 representation, mask in v4 representation
   325  		{
   326  			ip:    net.IPv4(172, 28, 30, 1),
   327  			mask:  []byte{0xff, 0xff, 0xff, 0},
   328  			bcast: net.IPv4(172, 28, 30, 255),
   329  		},
   330  		{
   331  			ip:    net.IPv4(10, 28, 30, 1),
   332  			mask:  []byte{0xff, 0, 0, 0},
   333  			bcast: net.IPv4(10, 255, 255, 255),
   334  		},
   335  		// ip and mask in v4Inv6 representation
   336  		{
   337  			ip:    net.IPv4(172, 28, 30, 2),
   338  			mask:  []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0},
   339  			bcast: net.IPv4(172, 28, 30, 255),
   340  		},
   341  		{
   342  			ip:    net.IPv4(172, 28, 30, 2),
   343  			mask:  []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0},
   344  			bcast: net.IPv4(172, 28, 255, 255),
   345  		},
   346  		// ip in v4 representation, mask in v4Inv6 representation
   347  		{
   348  			ip:    net.IPv4(172, 28, 30, 3)[12:],
   349  			mask:  []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0},
   350  			bcast: net.IPv4(172, 28, 30, 255)[12:],
   351  		},
   352  		{
   353  			ip:    net.IPv4(172, 28, 30, 3)[12:],
   354  			mask:  []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0},
   355  			bcast: net.IPv4(172, 255, 255, 255)[12:],
   356  		},
   357  		// ip and mask in v4 representation
   358  		{
   359  			ip:    net.IPv4(172, 28, 30, 4)[12:],
   360  			mask:  []byte{0xff, 0xff, 0xff, 0},
   361  			bcast: net.IPv4(172, 28, 30, 255)[12:],
   362  		},
   363  		{
   364  			ip:    net.IPv4(172, 28, 30, 4)[12:],
   365  			mask:  []byte{0xff, 0xff, 0, 0},
   366  			bcast: net.IPv4(172, 28, 255, 255)[12:],
   367  		},
   368  		{ // ip and mask as v6
   369  			ip:    net.ParseIP("2001:DB8:2002:2001:FFFF:ABCD:EEAB:00CD"),
   370  			mask:  []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0},
   371  			bcast: net.ParseIP("2001:DB8:2002:2001:FFFF:ABCD:EEFF:FFFF"),
   372  		},
   373  	}
   374  
   375  	for _, i := range input {
   376  		h, err := GetBroadcastIP(i.ip, i.mask)
   377  		if err != nil {
   378  			t.Fatal(err)
   379  		}
   380  		if !i.bcast.Equal(h) {
   381  			t.Fatalf("Failed to return expected host ip. Expected: %s. Got: %s", i.bcast, h)
   382  		}
   383  	}
   384  
   385  	// ip as v6 and mask as v4 are not compatible
   386  	if _, err := GetBroadcastIP(net.ParseIP("2001:DB8:2002:2001:FFFF:ABCD:EEAB:00CD"), []byte{0xff, 0xff, 0xff, 0}); err == nil {
   387  		t.Fatalf("Unexpected success")
   388  	}
   389  	// ip as v4 and non conventional mask
   390  	if _, err := GetBroadcastIP(net.ParseIP("173.32.4.5"), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0}); err == nil {
   391  		t.Fatalf("Unexpected success")
   392  	}
   393  	// ip as v4 and non conventional mask
   394  	if _, err := GetBroadcastIP(net.ParseIP("173.32.4.5"), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0}); err == nil {
   395  		t.Fatalf("Unexpected success")
   396  	}
   397  }
   398  
   399  func TestParseCIDR(t *testing.T) {
   400  	input := []struct {
   401  		cidr string
   402  		ipnw *net.IPNet
   403  	}{
   404  		{"192.168.22.44/16", &net.IPNet{IP: net.IP{192, 168, 22, 44}, Mask: net.IPMask{255, 255, 0, 0}}},
   405  		{"10.10.2.0/24", &net.IPNet{IP: net.IP{10, 10, 2, 0}, Mask: net.IPMask{255, 255, 255, 0}}},
   406  		{"10.0.0.100/17", &net.IPNet{IP: net.IP{10, 0, 0, 100}, Mask: net.IPMask{255, 255, 128, 0}}},
   407  	}
   408  
   409  	for _, i := range input {
   410  		nw, err := ParseCIDR(i.cidr)
   411  		if err != nil {
   412  			t.Fatal(err)
   413  		}
   414  		if !CompareIPNet(nw, i.ipnw) {
   415  			t.Fatalf("network differ. Expected %v. Got: %v", i.ipnw, nw)
   416  		}
   417  	}
   418  }