github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/state/ports_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state_test 5 6 import ( 7 "fmt" 8 "strings" 9 10 "github.com/juju/errors" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/network" 15 "github.com/juju/juju/state" 16 statetesting "github.com/juju/juju/state/testing" 17 "github.com/juju/juju/testing/factory" 18 ) 19 20 type PortsDocSuite struct { 21 ConnSuite 22 charm *state.Charm 23 service *state.Service 24 unit1 *state.Unit 25 unit2 *state.Unit 26 machine *state.Machine 27 ports *state.Ports 28 } 29 30 var _ = gc.Suite(&PortsDocSuite{}) 31 32 func (s *PortsDocSuite) SetUpTest(c *gc.C) { 33 s.ConnSuite.SetUpTest(c) 34 35 f := factory.NewFactory(s.State) 36 s.charm = f.MakeCharm(c, &factory.CharmParams{Name: "wordpress"}) 37 s.service = f.MakeService(c, &factory.ServiceParams{Name: "wordpress", Charm: s.charm}) 38 s.machine = f.MakeMachine(c, &factory.MachineParams{Series: "quantal"}) 39 s.unit1 = f.MakeUnit(c, &factory.UnitParams{Service: s.service, Machine: s.machine}) 40 s.unit2 = f.MakeUnit(c, &factory.UnitParams{Service: s.service, Machine: s.machine}) 41 42 var err error 43 s.ports, err = state.GetOrCreatePorts(s.State, s.machine.Id(), network.DefaultPublic) 44 c.Assert(err, jc.ErrorIsNil) 45 c.Assert(s.ports, gc.NotNil) 46 } 47 48 func (s *PortsDocSuite) TestCreatePorts(c *gc.C) { 49 ports, err := state.GetOrCreatePorts(s.State, s.machine.Id(), network.DefaultPublic) 50 c.Assert(err, jc.ErrorIsNil) 51 c.Assert(ports, gc.NotNil) 52 err = ports.OpenPorts(state.PortRange{ 53 FromPort: 100, 54 ToPort: 200, 55 UnitName: s.unit1.Name(), 56 Protocol: "TCP", 57 }) 58 c.Assert(err, jc.ErrorIsNil) 59 60 ports, err = state.GetPorts(s.State, s.machine.Id(), network.DefaultPublic) 61 c.Assert(err, jc.ErrorIsNil) 62 c.Assert(ports, gc.NotNil) 63 64 c.Assert(ports.PortsForUnit(s.unit1.Name()), gc.HasLen, 1) 65 } 66 67 func (s *PortsDocSuite) TestOpenAndClosePorts(c *gc.C) { 68 69 testCases := []struct { 70 about string 71 existing []state.PortRange 72 open *state.PortRange 73 close *state.PortRange 74 expected string 75 }{{ 76 about: "open and close same port range", 77 existing: nil, 78 open: &state.PortRange{ 79 FromPort: 100, 80 ToPort: 200, 81 UnitName: s.unit1.Name(), 82 Protocol: "TCP", 83 }, 84 close: &state.PortRange{ 85 FromPort: 100, 86 ToPort: 200, 87 UnitName: s.unit1.Name(), 88 Protocol: "TCP", 89 }, 90 expected: "", 91 }, { 92 about: "try to close part of a port range", 93 existing: []state.PortRange{{ 94 FromPort: 100, 95 ToPort: 200, 96 UnitName: s.unit1.Name(), 97 Protocol: "TCP", 98 }}, 99 open: nil, 100 close: &state.PortRange{ 101 FromPort: 100, 102 ToPort: 150, 103 UnitName: s.unit1.Name(), 104 Protocol: "TCP", 105 }, 106 expected: `cannot close ports 100-150/tcp \("wordpress/0"\): port ranges 100-200/tcp \("wordpress/0"\) and 100-150/tcp \("wordpress/0"\) conflict`, 107 }, { 108 about: "close an unopened port range with existing clash from other unit", 109 existing: []state.PortRange{{ 110 FromPort: 100, 111 ToPort: 150, 112 UnitName: s.unit2.Name(), 113 Protocol: "TCP", 114 }}, 115 open: nil, 116 close: &state.PortRange{ 117 FromPort: 100, 118 ToPort: 150, 119 UnitName: s.unit1.Name(), 120 Protocol: "TCP", 121 }, 122 expected: "", 123 }, { 124 about: "open twice the same port range", 125 existing: []state.PortRange{{ 126 FromPort: 100, 127 ToPort: 150, 128 UnitName: s.unit1.Name(), 129 Protocol: "TCP", 130 }}, 131 open: &state.PortRange{ 132 FromPort: 100, 133 ToPort: 150, 134 UnitName: s.unit1.Name(), 135 Protocol: "TCP", 136 }, 137 close: nil, 138 expected: "", 139 }, { 140 about: "close an unopened port range", 141 existing: nil, 142 open: nil, 143 close: &state.PortRange{ 144 FromPort: 100, 145 ToPort: 150, 146 UnitName: s.unit1.Name(), 147 Protocol: "TCP", 148 }, 149 expected: "", 150 }, { 151 about: "try to close an overlapping port range", 152 existing: []state.PortRange{{ 153 FromPort: 100, 154 ToPort: 200, 155 UnitName: s.unit1.Name(), 156 Protocol: "TCP", 157 }}, 158 open: nil, 159 close: &state.PortRange{ 160 FromPort: 100, 161 ToPort: 300, 162 UnitName: s.unit1.Name(), 163 Protocol: "TCP", 164 }, 165 expected: `cannot close ports 100-300/tcp \("wordpress/0"\): port ranges 100-200/tcp \("wordpress/0"\) and 100-300/tcp \("wordpress/0"\) conflict`, 166 }, { 167 about: "try to open an overlapping port range with different unit", 168 existing: []state.PortRange{{ 169 FromPort: 100, 170 ToPort: 200, 171 UnitName: s.unit1.Name(), 172 Protocol: "TCP", 173 }}, 174 open: &state.PortRange{ 175 FromPort: 100, 176 ToPort: 300, 177 UnitName: s.unit2.Name(), 178 Protocol: "TCP", 179 }, 180 expected: `cannot open ports 100-300/tcp \("wordpress/1"\): port ranges 100-200/tcp \("wordpress/0"\) and 100-300/tcp \("wordpress/1"\) conflict`, 181 }, { 182 about: "try to open an identical port range with different unit", 183 existing: []state.PortRange{{ 184 FromPort: 100, 185 ToPort: 200, 186 UnitName: s.unit1.Name(), 187 Protocol: "TCP", 188 }}, 189 open: &state.PortRange{ 190 FromPort: 100, 191 ToPort: 200, 192 UnitName: s.unit2.Name(), 193 Protocol: "TCP", 194 }, 195 expected: `cannot open ports 100-200/tcp \("wordpress/1"\): port ranges 100-200/tcp \("wordpress/0"\) and 100-200/tcp \("wordpress/1"\) conflict`, 196 }, { 197 about: "try to open a port range with different protocol with different unit", 198 existing: []state.PortRange{{ 199 FromPort: 100, 200 ToPort: 200, 201 UnitName: s.unit1.Name(), 202 Protocol: "TCP", 203 }}, 204 open: &state.PortRange{ 205 FromPort: 100, 206 ToPort: 200, 207 UnitName: s.unit2.Name(), 208 Protocol: "UDP", 209 }, 210 expected: "", 211 }, { 212 about: "try to open a non-overlapping port range with different unit", 213 existing: []state.PortRange{{ 214 FromPort: 100, 215 ToPort: 200, 216 UnitName: s.unit1.Name(), 217 Protocol: "TCP", 218 }}, 219 open: &state.PortRange{ 220 FromPort: 300, 221 ToPort: 400, 222 UnitName: s.unit2.Name(), 223 Protocol: "TCP", 224 }, 225 expected: "", 226 }} 227 228 for i, t := range testCases { 229 c.Logf("test %d: %s", i, t.about) 230 231 ports, err := state.GetOrCreatePorts(s.State, s.machine.Id(), network.DefaultPublic) 232 c.Assert(err, jc.ErrorIsNil) 233 c.Assert(ports, gc.NotNil) 234 235 // open ports that should exist for the test case 236 for _, portRange := range t.existing { 237 err := ports.OpenPorts(portRange) 238 c.Check(err, jc.ErrorIsNil) 239 } 240 if t.existing != nil { 241 err = ports.Refresh() 242 c.Check(err, jc.ErrorIsNil) 243 } 244 if t.open != nil { 245 err = ports.OpenPorts(*t.open) 246 if t.expected == "" { 247 c.Check(err, jc.ErrorIsNil) 248 } else { 249 c.Check(err, gc.ErrorMatches, t.expected) 250 } 251 err = ports.Refresh() 252 c.Check(err, jc.ErrorIsNil) 253 254 } 255 256 if t.close != nil { 257 err := ports.ClosePorts(*t.close) 258 if t.expected == "" { 259 c.Check(err, jc.ErrorIsNil) 260 } else { 261 c.Check(err, gc.ErrorMatches, t.expected) 262 } 263 } 264 err = ports.Remove() 265 c.Check(err, jc.ErrorIsNil) 266 } 267 } 268 269 func (s *PortsDocSuite) TestAllPortRanges(c *gc.C) { 270 portRange := state.PortRange{ 271 FromPort: 100, 272 ToPort: 200, 273 UnitName: s.unit1.Name(), 274 Protocol: "TCP", 275 } 276 err := s.ports.OpenPorts(portRange) 277 c.Assert(err, jc.ErrorIsNil) 278 279 ranges := s.ports.AllPortRanges() 280 c.Assert(ranges, gc.HasLen, 1) 281 282 c.Assert(ranges[network.PortRange{100, 200, "TCP"}], gc.Equals, s.unit1.Name()) 283 } 284 285 func (s *PortsDocSuite) TestOpenInvalidRange(c *gc.C) { 286 portRange := state.PortRange{ 287 FromPort: 400, 288 ToPort: 200, 289 UnitName: s.unit1.Name(), 290 Protocol: "TCP", 291 } 292 err := s.ports.OpenPorts(portRange) 293 c.Assert(err, gc.ErrorMatches, `cannot open ports 400-200/tcp \("wordpress/0"\): invalid port range 400-200`) 294 } 295 296 func (s *PortsDocSuite) TestCloseInvalidRange(c *gc.C) { 297 portRange := state.PortRange{ 298 FromPort: 100, 299 ToPort: 200, 300 UnitName: s.unit1.Name(), 301 Protocol: "TCP", 302 } 303 err := s.ports.OpenPorts(portRange) 304 c.Assert(err, jc.ErrorIsNil) 305 306 err = s.ports.Refresh() 307 c.Assert(err, jc.ErrorIsNil) 308 err = s.ports.ClosePorts(state.PortRange{ 309 FromPort: 150, 310 ToPort: 200, 311 UnitName: s.unit1.Name(), 312 Protocol: "TCP", 313 }) 314 c.Assert(err, gc.ErrorMatches, `cannot close ports 150-200/tcp \("wordpress/0"\): port ranges 100-200/tcp \("wordpress/0"\) and 150-200/tcp \("wordpress/0"\) conflict`) 315 } 316 317 func (s *PortsDocSuite) TestRemovePortsDoc(c *gc.C) { 318 portRange := state.PortRange{ 319 FromPort: 100, 320 ToPort: 200, 321 UnitName: s.unit1.Name(), 322 Protocol: "TCP", 323 } 324 err := s.ports.OpenPorts(portRange) 325 c.Assert(err, jc.ErrorIsNil) 326 327 ports, err := state.GetPorts(s.State, s.machine.Id(), network.DefaultPublic) 328 c.Assert(err, jc.ErrorIsNil) 329 c.Assert(ports, gc.NotNil) 330 331 allPorts, err := s.machine.AllPorts() 332 c.Assert(err, jc.ErrorIsNil) 333 334 for _, prt := range allPorts { 335 err := prt.Remove() 336 c.Assert(err, jc.ErrorIsNil) 337 } 338 339 ports, err = state.GetPorts(s.State, s.machine.Id(), network.DefaultPublic) 340 c.Assert(ports, gc.IsNil) 341 c.Assert(err, jc.Satisfies, errors.IsNotFound) 342 c.Assert(err, gc.ErrorMatches, `ports for machine "0", network "juju-public" not found`) 343 } 344 345 func (s *PortsDocSuite) TestWatchPorts(c *gc.C) { 346 // No port ranges open initially, no changes. 347 w := s.State.WatchOpenedPorts() 348 c.Assert(w, gc.NotNil) 349 350 defer statetesting.AssertStop(c, w) 351 wc := statetesting.NewStringsWatcherC(c, s.State, w) 352 // The first change we get is an empty one, as there are no ports 353 // opened yet and we need an initial event for the API watcher to 354 // work. 355 wc.AssertChange() 356 wc.AssertNoChange() 357 358 portRange := state.PortRange{ 359 FromPort: 100, 360 ToPort: 200, 361 UnitName: s.unit1.Name(), 362 Protocol: "TCP", 363 } 364 expectChange := fmt.Sprintf("%s:%s", s.machine.Id(), network.DefaultPublic) 365 // Open a port range, detect a change. 366 err := s.ports.OpenPorts(portRange) 367 c.Assert(err, jc.ErrorIsNil) 368 wc.AssertChange(expectChange) 369 wc.AssertNoChange() 370 371 // Close the port range, detect a change. 372 err = s.ports.ClosePorts(portRange) 373 c.Assert(err, jc.ErrorIsNil) 374 wc.AssertChange(expectChange) 375 wc.AssertNoChange() 376 377 // Close the port range again, no changes. 378 err = s.ports.ClosePorts(portRange) 379 c.Assert(err, jc.ErrorIsNil) 380 wc.AssertNoChange() 381 382 // Open another range, detect a change. 383 portRange = state.PortRange{ 384 FromPort: 999, 385 ToPort: 1999, 386 UnitName: s.unit2.Name(), 387 Protocol: "udp", 388 } 389 err = s.ports.OpenPorts(portRange) 390 c.Assert(err, jc.ErrorIsNil) 391 wc.AssertChange(expectChange) 392 wc.AssertNoChange() 393 394 // Open the same range again, no changes. 395 err = s.ports.OpenPorts(portRange) 396 c.Assert(err, jc.ErrorIsNil) 397 wc.AssertNoChange() 398 399 // Open another range, detect a change. 400 otherRange := state.PortRange{ 401 FromPort: 1, 402 ToPort: 100, 403 UnitName: s.unit1.Name(), 404 Protocol: "tcp", 405 } 406 err = s.ports.OpenPorts(otherRange) 407 c.Assert(err, jc.ErrorIsNil) 408 wc.AssertChange(expectChange) 409 wc.AssertNoChange() 410 411 // Close the other range, detect a change. 412 err = s.ports.ClosePorts(otherRange) 413 c.Assert(err, jc.ErrorIsNil) 414 wc.AssertChange(expectChange) 415 wc.AssertNoChange() 416 417 // Remove the ports document, detect a change. 418 err = s.ports.Remove() 419 c.Assert(err, jc.ErrorIsNil) 420 wc.AssertChange(expectChange) 421 wc.AssertNoChange() 422 423 // And again - no change. 424 err = s.ports.Remove() 425 c.Assert(err, jc.ErrorIsNil) 426 wc.AssertNoChange() 427 } 428 429 type PortRangeSuite struct{} 430 431 var _ = gc.Suite(&PortRangeSuite{}) 432 433 // Create a port range or panic if it is invalid. 434 func MustPortRange(unitName string, fromPort, toPort int, protocol string) state.PortRange { 435 portRange, err := state.NewPortRange(unitName, fromPort, toPort, protocol) 436 if err != nil { 437 panic(err) 438 } 439 return portRange 440 } 441 442 func (p *PortRangeSuite) TestPortRangeConflicts(c *gc.C) { 443 var testCases = []struct { 444 about string 445 first state.PortRange 446 second state.PortRange 447 expected interface{} 448 }{{ 449 "identical ports", 450 MustPortRange("wordpress/0", 80, 80, "TCP"), 451 MustPortRange("wordpress/0", 80, 80, "TCP"), 452 nil, 453 }, { 454 "identical port ranges", 455 MustPortRange("wordpress/0", 80, 100, "TCP"), 456 MustPortRange("wordpress/0", 80, 100, "TCP"), 457 nil, 458 }, { 459 "different ports", 460 MustPortRange("wordpress/0", 80, 80, "TCP"), 461 MustPortRange("wordpress/0", 90, 90, "TCP"), 462 nil, 463 }, { 464 "touching ranges", 465 MustPortRange("wordpress/0", 100, 200, "TCP"), 466 MustPortRange("wordpress/0", 201, 240, "TCP"), 467 nil, 468 }, { 469 "touching ranges with overlap", 470 MustPortRange("wordpress/0", 100, 200, "TCP"), 471 MustPortRange("wordpress/0", 200, 240, "TCP"), 472 "port ranges .* conflict", 473 }, { 474 "identical ports with different protocols", 475 MustPortRange("wordpress/0", 80, 80, "UDP"), 476 MustPortRange("wordpress/0", 80, 80, "TCP"), 477 nil, 478 }, { 479 "overlapping ranges with different protocols", 480 MustPortRange("wordpress/0", 80, 200, "UDP"), 481 MustPortRange("wordpress/0", 80, 300, "TCP"), 482 nil, 483 }, { 484 "outside range", 485 MustPortRange("wordpress/0", 100, 200, "TCP"), 486 MustPortRange("wordpress/0", 80, 80, "TCP"), 487 nil, 488 }, { 489 "overlap end", 490 MustPortRange("wordpress/0", 100, 200, "TCP"), 491 MustPortRange("wordpress/0", 80, 120, "TCP"), 492 "port ranges .* conflict", 493 }, { 494 "complete overlap", 495 MustPortRange("wordpress/0", 100, 200, "TCP"), 496 MustPortRange("wordpress/0", 120, 140, "TCP"), 497 "port ranges .* conflict", 498 }, { 499 "overlap with same end", 500 MustPortRange("wordpress/0", 100, 200, "TCP"), 501 MustPortRange("wordpress/0", 120, 200, "TCP"), 502 "port ranges .* conflict", 503 }, { 504 "overlap with same start", 505 MustPortRange("wordpress/0", 100, 200, "TCP"), 506 MustPortRange("wordpress/0", 100, 120, "TCP"), 507 "port ranges .* conflict", 508 }, { 509 "invalid port range", 510 state.PortRange{"wordpress/0", 100, 80, "TCP"}, 511 MustPortRange("wordpress/0", 80, 80, "TCP"), 512 "invalid port range 100-80", 513 }, { 514 "different units, same port", 515 MustPortRange("mysql/0", 80, 80, "TCP"), 516 MustPortRange("wordpress/0", 80, 80, "TCP"), 517 "port ranges .* conflict", 518 }, { 519 "different units, different port ranges", 520 MustPortRange("mysql/0", 80, 100, "TCP"), 521 MustPortRange("wordpress/0", 180, 280, "TCP"), 522 nil, 523 }, { 524 "different units, overlapping port ranges", 525 MustPortRange("mysql/0", 80, 100, "TCP"), 526 MustPortRange("wordpress/0", 90, 280, "TCP"), 527 "port ranges .* conflict", 528 }} 529 530 for i, t := range testCases { 531 c.Logf("test %d: %s", i, t.about) 532 if t.expected == nil { 533 c.Check(t.first.CheckConflicts(t.second), gc.IsNil) 534 c.Check(t.second.CheckConflicts(t.first), gc.IsNil) 535 } else if _, isString := t.expected.(string); isString { 536 c.Check(t.first.CheckConflicts(t.second), gc.ErrorMatches, t.expected.(string)) 537 c.Check(t.second.CheckConflicts(t.first), gc.ErrorMatches, t.expected.(string)) 538 } 539 // change test case protocols and test again 540 c.Logf("test %d: %s (after protocol swap)", i, t.about) 541 t.first.Protocol = swapProtocol(t.first.Protocol) 542 t.second.Protocol = swapProtocol(t.second.Protocol) 543 c.Logf("%+v %+v %v", t.first, t.second, t.expected) 544 if t.expected == nil { 545 c.Check(t.first.CheckConflicts(t.second), gc.IsNil) 546 c.Check(t.second.CheckConflicts(t.first), gc.IsNil) 547 } else if _, isString := t.expected.(string); isString { 548 c.Check(t.first.CheckConflicts(t.second), gc.ErrorMatches, t.expected.(string)) 549 c.Check(t.second.CheckConflicts(t.first), gc.ErrorMatches, t.expected.(string)) 550 } 551 552 } 553 } 554 555 func swapProtocol(protocol string) string { 556 if strings.ToLower(protocol) == "tcp" { 557 return "udp" 558 } 559 if strings.ToLower(protocol) == "udp" { 560 return "tcp" 561 } 562 return protocol 563 } 564 565 func (p *PortRangeSuite) TestPortRangeString(c *gc.C) { 566 c.Assert(state.PortRange{"wordpress/42", 80, 80, "TCP"}.String(), 567 gc.Equals, 568 `80-80/tcp ("wordpress/42")`, 569 ) 570 c.Assert(state.PortRange{"wordpress/0", 80, 100, "TCP"}.String(), 571 gc.Equals, 572 `80-100/tcp ("wordpress/0")`, 573 ) 574 } 575 576 func (p *PortRangeSuite) TestPortRangeValidityAndLength(c *gc.C) { 577 testCases := []struct { 578 about string 579 ports state.PortRange 580 expectLength int 581 expectedErr string 582 }{{ 583 "single valid port", 584 state.PortRange{"wordpress/0", 80, 80, "tcp"}, 585 1, 586 "", 587 }, { 588 "valid tcp port range", 589 state.PortRange{"wordpress/0", 80, 90, "tcp"}, 590 11, 591 "", 592 }, { 593 "valid udp port range", 594 state.PortRange{"wordpress/0", 80, 90, "UDP"}, 595 11, 596 "", 597 }, { 598 "invalid port range boundaries", 599 state.PortRange{"wordpress/0", 90, 80, "tcp"}, 600 0, 601 "invalid port range.*", 602 }, { 603 "invalid protocol", 604 state.PortRange{"wordpress/0", 80, 80, "some protocol"}, 605 0, 606 "invalid protocol.*", 607 }, { 608 "invalid unit", 609 state.PortRange{"invalid unit", 80, 80, "tcp"}, 610 0, 611 "invalid unit.*", 612 }, { 613 "negative lower bound", 614 state.PortRange{"wordpress/0", -10, 10, "tcp"}, 615 0, 616 "port range bounds must be between 1 and 65535.*", 617 }, { 618 "zero lower bound", 619 state.PortRange{"wordpress/0", 0, 10, "tcp"}, 620 0, 621 "port range bounds must be between 1 and 65535.*", 622 }, { 623 "negative upper bound", 624 state.PortRange{"wordpress/0", 10, -10, "tcp"}, 625 0, 626 "invalid port range.*", 627 }, { 628 "zero upper bound", 629 state.PortRange{"wordpress/0", 10, 0, "tcp"}, 630 0, 631 "invalid port range.*", 632 }, { 633 "too large lower bound", 634 state.PortRange{"wordpress/0", 65540, 99999, "tcp"}, 635 0, 636 "port range bounds must be between 1 and 65535.*", 637 }, { 638 "too large upper bound", 639 state.PortRange{"wordpress/0", 10, 99999, "tcp"}, 640 0, 641 "port range bounds must be between 1 and 65535.*", 642 }, { 643 "longest valid range", 644 state.PortRange{"wordpress/0", 1, 65535, "tcp"}, 645 65535, 646 "", 647 }} 648 649 for i, t := range testCases { 650 c.Logf("test %d: %s", i, t.about) 651 c.Check(t.ports.Length(), gc.Equals, t.expectLength) 652 if t.expectedErr == "" { 653 c.Check(t.ports.Validate(), gc.IsNil) 654 } else { 655 c.Check(t.ports.Validate(), gc.ErrorMatches, t.expectedErr) 656 } 657 } 658 } 659 660 func (p *PortRangeSuite) TestSanitizeBounds(c *gc.C) { 661 tests := []struct { 662 about string 663 input state.PortRange 664 output state.PortRange 665 }{{ 666 "valid range", 667 state.PortRange{"", 100, 200, ""}, 668 state.PortRange{"", 100, 200, ""}, 669 }, { 670 "negative lower bound", 671 state.PortRange{"", -10, 10, ""}, 672 state.PortRange{"", 1, 10, ""}, 673 }, { 674 "zero lower bound", 675 state.PortRange{"", 0, 10, ""}, 676 state.PortRange{"", 1, 10, ""}, 677 }, { 678 "negative upper bound", 679 state.PortRange{"", 42, -20, ""}, 680 state.PortRange{"", 1, 42, ""}, 681 }, { 682 "zero upper bound", 683 state.PortRange{"", 42, 0, ""}, 684 state.PortRange{"", 1, 42, ""}, 685 }, { 686 "both bounds negative", 687 state.PortRange{"", -10, -20, ""}, 688 state.PortRange{"", 1, 1, ""}, 689 }, { 690 "both bounds zero", 691 state.PortRange{"", 0, 0, ""}, 692 state.PortRange{"", 1, 1, ""}, 693 }, { 694 "swapped bounds", 695 state.PortRange{"", 20, 10, ""}, 696 state.PortRange{"", 10, 20, ""}, 697 }, { 698 "too large upper bound", 699 state.PortRange{"", 20, 99999, ""}, 700 state.PortRange{"", 20, 65535, ""}, 701 }, { 702 "too large lower bound", 703 state.PortRange{"", 99999, 10, ""}, 704 state.PortRange{"", 10, 65535, ""}, 705 }, { 706 "both bounds too large", 707 state.PortRange{"", 88888, 99999, ""}, 708 state.PortRange{"", 65535, 65535, ""}, 709 }, { 710 "lower negative, upper too large", 711 state.PortRange{"", -10, 99999, ""}, 712 state.PortRange{"", 1, 65535, ""}, 713 }, { 714 "lower zero, upper too large", 715 state.PortRange{"", 0, 99999, ""}, 716 state.PortRange{"", 1, 65535, ""}, 717 }} 718 for i, t := range tests { 719 c.Logf("test %d: %s", i, t.about) 720 c.Check(t.input.SanitizeBounds(), jc.DeepEquals, t.output) 721 } 722 }