github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/network/portrange_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package network_test
     5  
     6  import (
     7  	jc "github.com/juju/testing/checkers"
     8  	gc "gopkg.in/check.v1"
     9  
    10  	"github.com/juju/juju/network"
    11  	"github.com/juju/juju/testing"
    12  )
    13  
    14  type PortRangeSuite struct {
    15  	testing.BaseSuite
    16  }
    17  
    18  var _ = gc.Suite(&PortRangeSuite{})
    19  
    20  func (*PortRangeSuite) TestConflictsWith(c *gc.C) {
    21  	var testCases = []struct {
    22  		about          string
    23  		first          network.PortRange
    24  		second         network.PortRange
    25  		expectConflict bool
    26  	}{{
    27  		"identical ports",
    28  		network.PortRange{80, 80, "TCP"},
    29  		network.PortRange{80, 80, "TCP"},
    30  		true,
    31  	}, {
    32  		"different ports",
    33  		network.PortRange{80, 80, "TCP"},
    34  		network.PortRange{90, 90, "TCP"},
    35  		false,
    36  	}, {
    37  		"touching ranges",
    38  		network.PortRange{100, 200, "TCP"},
    39  		network.PortRange{201, 240, "TCP"},
    40  		false,
    41  	}, {
    42  		"touching ranges with overlap",
    43  		network.PortRange{100, 200, "TCP"},
    44  		network.PortRange{200, 240, "TCP"},
    45  		true,
    46  	}, {
    47  		"different protocols",
    48  		network.PortRange{80, 80, "UDP"},
    49  		network.PortRange{80, 80, "TCP"},
    50  		false,
    51  	}, {
    52  		"outside range",
    53  		network.PortRange{100, 200, "TCP"},
    54  		network.PortRange{80, 80, "TCP"},
    55  		false,
    56  	}, {
    57  		"overlap end",
    58  		network.PortRange{100, 200, "TCP"},
    59  		network.PortRange{80, 120, "TCP"},
    60  		true,
    61  	}, {
    62  		"complete overlap",
    63  		network.PortRange{100, 200, "TCP"},
    64  		network.PortRange{120, 140, "TCP"},
    65  		true,
    66  	}}
    67  
    68  	for i, t := range testCases {
    69  		c.Logf("test %d: %s", i, t.about)
    70  		c.Check(t.first.ConflictsWith(t.second), gc.Equals, t.expectConflict)
    71  		c.Check(t.second.ConflictsWith(t.first), gc.Equals, t.expectConflict)
    72  	}
    73  }
    74  
    75  func (*PortRangeSuite) TestStrings(c *gc.C) {
    76  	c.Assert(
    77  		network.PortRange{80, 80, "TCP"}.String(),
    78  		gc.Equals,
    79  		"80/tcp",
    80  	)
    81  	c.Assert(
    82  		network.PortRange{80, 80, "TCP"}.GoString(),
    83  		gc.Equals,
    84  		"80/tcp",
    85  	)
    86  	c.Assert(
    87  		network.PortRange{80, 100, "TCP"}.String(),
    88  		gc.Equals,
    89  		"80-100/tcp",
    90  	)
    91  	c.Assert(
    92  		network.PortRange{80, 100, "TCP"}.GoString(),
    93  		gc.Equals,
    94  		"80-100/tcp",
    95  	)
    96  }
    97  
    98  func (*PortRangeSuite) TestValidate(c *gc.C) {
    99  	testCases := []struct {
   100  		about    string
   101  		ports    network.PortRange
   102  		expected string
   103  	}{{
   104  		"single valid port",
   105  		network.PortRange{80, 80, "tcp"},
   106  		"",
   107  	}, {
   108  		"valid port range",
   109  		network.PortRange{80, 90, "tcp"},
   110  		"",
   111  	}, {
   112  		"valid udp port range",
   113  		network.PortRange{80, 90, "UDP"},
   114  		"",
   115  	}, {
   116  		"invalid port range boundaries",
   117  		network.PortRange{90, 80, "tcp"},
   118  		"invalid port range 90-80/tcp",
   119  	}, {
   120  		"both FromPort and ToPort too large",
   121  		network.PortRange{88888, 99999, "tcp"},
   122  		"invalid port range 88888-99999/tcp",
   123  	}, {
   124  		"FromPort too large",
   125  		network.PortRange{88888, 65535, "tcp"},
   126  		"invalid port range 88888-65535/tcp",
   127  	}, {
   128  		"FromPort too small",
   129  		network.PortRange{0, 80, "tcp"},
   130  		"invalid port range 0-80/tcp",
   131  	}, {
   132  		"ToPort too large",
   133  		network.PortRange{1, 99999, "tcp"},
   134  		"invalid port range 1-99999/tcp",
   135  	}, {
   136  		"both ports 0",
   137  		network.PortRange{0, 0, "tcp"},
   138  		"invalid port range 0-0/tcp",
   139  	}, {
   140  		"invalid protocol",
   141  		network.PortRange{80, 80, "some protocol"},
   142  		`invalid protocol "some protocol", expected "tcp" or "udp"`,
   143  	}}
   144  
   145  	for i, t := range testCases {
   146  		c.Logf("test %d: %s", i, t.about)
   147  		if t.expected == "" {
   148  			c.Check(t.ports.Validate(), gc.IsNil)
   149  		} else {
   150  			c.Check(t.ports.Validate(), gc.ErrorMatches, t.expected)
   151  		}
   152  	}
   153  }
   154  
   155  func (*PortRangeSuite) TestSortPortRanges(c *gc.C) {
   156  	ranges := []network.PortRange{
   157  		{10, 100, "udp"},
   158  		{80, 90, "tcp"},
   159  		{80, 80, "tcp"},
   160  	}
   161  	expected := []network.PortRange{
   162  		{80, 80, "tcp"},
   163  		{80, 90, "tcp"},
   164  		{10, 100, "udp"},
   165  	}
   166  	network.SortPortRanges(ranges)
   167  	c.Assert(ranges, gc.DeepEquals, expected)
   168  }
   169  
   170  func (*PortRangeSuite) TestCollapsePorts(c *gc.C) {
   171  	testCases := []struct {
   172  		about    string
   173  		ports    []network.Port
   174  		expected []network.PortRange
   175  	}{{
   176  		"single port",
   177  		[]network.Port{{"tcp", 80}},
   178  		[]network.PortRange{{80, 80, "tcp"}},
   179  	}, {
   180  		"continuous port range (increasing)",
   181  		[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"tcp", 83}},
   182  		[]network.PortRange{{80, 83, "tcp"}},
   183  	}, {
   184  		"continuous port range (decreasing)",
   185  		[]network.Port{{"tcp", 83}, {"tcp", 82}, {"tcp", 81}, {"tcp", 80}},
   186  		[]network.PortRange{{80, 83, "tcp"}},
   187  	}, {
   188  		"non-continuous port range (increasing)",
   189  		[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"tcp", 84}, {"tcp", 85}},
   190  		[]network.PortRange{{80, 82, "tcp"}, {84, 85, "tcp"}},
   191  	}, {
   192  		"non-continuous port range (decreasing)",
   193  		[]network.Port{{"tcp", 85}, {"tcp", 84}, {"tcp", 82}, {"tcp", 81}, {"tcp", 80}},
   194  		[]network.PortRange{{80, 82, "tcp"}, {84, 85, "tcp"}},
   195  	}, {
   196  		"alternating tcp / udp ports (increasing)",
   197  		[]network.Port{{"tcp", 80}, {"udp", 81}, {"tcp", 82}, {"udp", 83}, {"tcp", 84}},
   198  		[]network.PortRange{{80, 80, "tcp"}, {82, 82, "tcp"}, {84, 84, "tcp"}, {81, 81, "udp"}, {83, 83, "udp"}},
   199  	}, {
   200  		"alternating tcp / udp ports (decreasing)",
   201  		[]network.Port{{"tcp", 84}, {"udp", 83}, {"tcp", 82}, {"udp", 81}, {"tcp", 80}},
   202  		[]network.PortRange{{80, 80, "tcp"}, {82, 82, "tcp"}, {84, 84, "tcp"}, {81, 81, "udp"}, {83, 83, "udp"}},
   203  	}, {
   204  		"non-continuous port range (udp vs tcp - increasing)",
   205  		[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"udp", 84}, {"tcp", 83}},
   206  		[]network.PortRange{{80, 83, "tcp"}, {84, 84, "udp"}},
   207  	}, {
   208  		"non-continuous port range (udp vs tcp - decreasing)",
   209  		[]network.Port{{"tcp", 83}, {"udp", 84}, {"tcp", 82}, {"tcp", 81}, {"tcp", 80}},
   210  		[]network.PortRange{{80, 83, "tcp"}, {84, 84, "udp"}},
   211  	}}
   212  	for i, t := range testCases {
   213  		c.Logf("test %d: %s", i, t.about)
   214  		c.Check(network.CollapsePorts(t.ports), jc.DeepEquals, t.expected)
   215  	}
   216  }
   217  
   218  func (*PortRangeSuite) TestParsePortRange(c *gc.C) {
   219  	portRange, err := network.ParsePortRange("8000-8099/tcp")
   220  	c.Assert(err, jc.ErrorIsNil)
   221  
   222  	c.Check(portRange.Protocol, gc.Equals, "tcp")
   223  	c.Check(portRange.FromPort, gc.Equals, 8000)
   224  	c.Check(portRange.ToPort, gc.Equals, 8099)
   225  }
   226  
   227  func (*PortRangeSuite) TestParsePortRangeSingle(c *gc.C) {
   228  	portRange, err := network.ParsePortRange("80/tcp")
   229  	c.Assert(err, jc.ErrorIsNil)
   230  
   231  	c.Check(portRange.Protocol, gc.Equals, "tcp")
   232  	c.Check(portRange.FromPort, gc.Equals, 80)
   233  	c.Check(portRange.ToPort, gc.Equals, 80)
   234  }
   235  
   236  func (*PortRangeSuite) TestParsePortRangeDefaultProtocol(c *gc.C) {
   237  	portRange, err := network.ParsePortRange("80")
   238  	c.Assert(err, jc.ErrorIsNil)
   239  
   240  	c.Check(portRange.Protocol, gc.Equals, "tcp")
   241  	c.Check(portRange.FromPort, gc.Equals, 80)
   242  	c.Check(portRange.ToPort, gc.Equals, 80)
   243  }
   244  
   245  func (*PortRangeSuite) TestParsePortRangeRoundTrip(c *gc.C) {
   246  	portRange, err := network.ParsePortRange("8000-8099/tcp")
   247  	c.Assert(err, jc.ErrorIsNil)
   248  	portRangeStr := portRange.String()
   249  
   250  	c.Check(portRangeStr, gc.Equals, "8000-8099/tcp")
   251  }
   252  
   253  func (*PortRangeSuite) TestParsePortRangeMultiRange(c *gc.C) {
   254  	_, err := network.ParsePortRange("10-55-100")
   255  
   256  	c.Check(err, gc.ErrorMatches, `invalid port range "10-55-100".*`)
   257  }
   258  
   259  func (*PortRangeSuite) TestParsePortRangeNonIntPort(c *gc.C) {
   260  	_, err := network.ParsePortRange("spam-100")
   261  
   262  	c.Check(err, gc.ErrorMatches, `invalid port "spam".*`)
   263  }
   264  
   265  func (*PortRangeSuite) TestParsePortRanges(c *gc.C) {
   266  	portRanges, err := network.ParsePortRanges("80/tcp,8000-8099/tcp")
   267  	c.Assert(err, jc.ErrorIsNil)
   268  
   269  	c.Assert(portRanges, gc.HasLen, 2)
   270  	c.Check(portRanges[0].Protocol, gc.Equals, "tcp")
   271  	c.Check(portRanges[0].FromPort, gc.Equals, 80)
   272  	c.Check(portRanges[0].ToPort, gc.Equals, 80)
   273  	c.Check(portRanges[1].Protocol, gc.Equals, "tcp")
   274  	c.Check(portRanges[1].FromPort, gc.Equals, 8000)
   275  	c.Check(portRanges[1].ToPort, gc.Equals, 8099)
   276  }
   277  
   278  func (*PortRangeSuite) TestParsePortRangesSingle(c *gc.C) {
   279  	portRanges, err := network.ParsePortRanges("80")
   280  	c.Assert(err, jc.ErrorIsNil)
   281  
   282  	c.Assert(portRanges, gc.HasLen, 1)
   283  	c.Check(portRanges[0].Protocol, gc.Equals, "tcp")
   284  	c.Check(portRanges[0].FromPort, gc.Equals, 80)
   285  	c.Check(portRanges[0].ToPort, gc.Equals, 80)
   286  }
   287  
   288  func (*PortRangeSuite) TestParsePortRangesSpaces(c *gc.C) {
   289  	portRanges, err := network.ParsePortRanges(" 80, 	8000-8099  ")
   290  	c.Assert(err, jc.ErrorIsNil)
   291  
   292  	c.Assert(portRanges, gc.HasLen, 2)
   293  	c.Check(portRanges[0].Protocol, gc.Equals, "tcp")
   294  	c.Check(portRanges[0].FromPort, gc.Equals, 80)
   295  	c.Check(portRanges[0].ToPort, gc.Equals, 80)
   296  	c.Check(portRanges[1].Protocol, gc.Equals, "tcp")
   297  	c.Check(portRanges[1].FromPort, gc.Equals, 8000)
   298  	c.Check(portRanges[1].ToPort, gc.Equals, 8099)
   299  }