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 }