1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
7
jc "github.com/juju/testing/checkers"
10
"github.com/juju/juju/network"
11
"github.com/juju/juju/testing"
14
type PortRangeSuite struct {
18
var _ = gc.Suite(&PortRangeSuite{})
20
func (*PortRangeSuite) TestConflictsWith(c *gc.C) {
21
var testCases = []struct {
23
first network.PortRange
24
second network.PortRange
28
network.PortRange{80, 80, "TCP"},
29
network.PortRange{80, 80, "TCP"},
33
network.PortRange{80, 80, "TCP"},
34
network.PortRange{90, 90, "TCP"},
38
network.PortRange{100, 200, "TCP"},
39
network.PortRange{201, 240, "TCP"},
42
"touching ranges with overlap",
43
network.PortRange{100, 200, "TCP"},
44
network.PortRange{200, 240, "TCP"},
47
"different protocols",
48
network.PortRange{80, 80, "UDP"},
49
network.PortRange{80, 80, "TCP"},
53
network.PortRange{100, 200, "TCP"},
54
network.PortRange{80, 80, "TCP"},
58
network.PortRange{100, 200, "TCP"},
59
network.PortRange{80, 120, "TCP"},
63
network.PortRange{100, 200, "TCP"},
64
network.PortRange{120, 140, "TCP"},
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)
75
func (*PortRangeSuite) TestStrings(c *gc.C) {
77
network.PortRange{80, 80, "TCP"}.String(),
82
network.PortRange{80, 80, "TCP"}.GoString(),
87
network.PortRange{80, 100, "TCP"}.String(),
92
network.PortRange{80, 100, "TCP"}.GoString(),
98
func (*PortRangeSuite) TestValidate(c *gc.C) {
99
testCases := []struct {
101
ports network.PortRange
105
network.PortRange{80, 80, "tcp"},
109
network.PortRange{80, 90, "tcp"},
112
"valid udp port range",
113
network.PortRange{80, 90, "UDP"},
116
"invalid port range boundaries",
117
network.PortRange{90, 80, "tcp"},
118
"invalid port range 90-80/tcp",
120
"both FromPort and ToPort too large",
121
network.PortRange{88888, 99999, "tcp"},
122
"invalid port range 88888-99999/tcp",
124
"FromPort too large",
125
network.PortRange{88888, 65535, "tcp"},
126
"invalid port range 88888-65535/tcp",
128
"FromPort too small",
129
network.PortRange{0, 80, "tcp"},
130
"invalid port range 0-80/tcp",
133
network.PortRange{1, 99999, "tcp"},
134
"invalid port range 1-99999/tcp",
137
network.PortRange{0, 0, "tcp"},
138
"invalid port range 0-0/tcp",
141
network.PortRange{80, 80, "some protocol"},
142
`invalid protocol "some protocol", expected "tcp" or "udp"`,
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)
150
c.Check(t.ports.Validate(), gc.ErrorMatches, t.expected)
155
func (*PortRangeSuite) TestSortPortRanges(c *gc.C) {
156
ranges := []network.PortRange{
161
expected := []network.PortRange{
166
network.SortPortRanges(ranges)
167
c.Assert(ranges, gc.DeepEquals, expected)
170
func (*PortRangeSuite) TestCollapsePorts(c *gc.C) {
171
testCases := []struct {
174
expected []network.PortRange
177
[]network.Port{{"tcp", 80}},
178
[]network.PortRange{{80, 80, "tcp"}},
180
"continuous port range (increasing)",
181
[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"tcp", 83}},
182
[]network.PortRange{{80, 83, "tcp"}},
184
"continuous port range (decreasing)",
185
[]network.Port{{"tcp", 83}, {"tcp", 82}, {"tcp", 81}, {"tcp", 80}},
186
[]network.PortRange{{80, 83, "tcp"}},
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"}},
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"}},
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"}},
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"}},
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"}},
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"}},
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)
218
func (*PortRangeSuite) TestParsePortRange(c *gc.C) {
219
portRange, err := network.ParsePortRange("8000-8099/tcp")
220
c.Assert(err, jc.ErrorIsNil)
222
c.Check(portRange.Protocol, gc.Equals, "tcp")
223
c.Check(portRange.FromPort, gc.Equals, 8000)
224
c.Check(portRange.ToPort, gc.Equals, 8099)
227
func (*PortRangeSuite) TestParsePortRangeSingle(c *gc.C) {
228
portRange, err := network.ParsePortRange("80/tcp")
229
c.Assert(err, jc.ErrorIsNil)
231
c.Check(portRange.Protocol, gc.Equals, "tcp")
232
c.Check(portRange.FromPort, gc.Equals, 80)
233
c.Check(portRange.ToPort, gc.Equals, 80)
236
func (*PortRangeSuite) TestParsePortRangeDefaultProtocol(c *gc.C) {
237
portRange, err := network.ParsePortRange("80")
238
c.Assert(err, jc.ErrorIsNil)
240
c.Check(portRange.Protocol, gc.Equals, "tcp")
241
c.Check(portRange.FromPort, gc.Equals, 80)
242
c.Check(portRange.ToPort, gc.Equals, 80)
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()
250
c.Check(portRangeStr, gc.Equals, "8000-8099/tcp")
253
func (*PortRangeSuite) TestParsePortRangeMultiRange(c *gc.C) {
254
_, err := network.ParsePortRange("10-55-100")
256
c.Check(err, gc.ErrorMatches, `invalid port range "10-55-100".*`)
259
func (*PortRangeSuite) TestParsePortRangeNonIntPort(c *gc.C) {
260
_, err := network.ParsePortRange("spam-100")
262
c.Check(err, gc.ErrorMatches, `invalid port "spam".*`)
265
func (*PortRangeSuite) TestMustParsePortRange(c *gc.C) {
266
portRange := network.MustParsePortRange("8000-8099/tcp")
268
c.Check(portRange.Protocol, gc.Equals, "tcp")
269
c.Check(portRange.FromPort, gc.Equals, 8000)
270
c.Check(portRange.ToPort, gc.Equals, 8099)
273
func (*PortRangeSuite) TestMustParsePortRangeInvalid(c *gc.C) {
275
network.MustParsePortRange("10-55-100")
278
c.Check(f, gc.PanicMatches, `invalid port range "10-55-100".*`)
281
func (*PortRangeSuite) TestParsePortRanges(c *gc.C) {
282
portRanges, err := network.ParsePortRanges("80/tcp,8000-8099/tcp")
283
c.Assert(err, jc.ErrorIsNil)
285
c.Assert(portRanges, gc.HasLen, 2)
286
c.Check(portRanges[0].Protocol, gc.Equals, "tcp")
287
c.Check(portRanges[0].FromPort, gc.Equals, 80)
288
c.Check(portRanges[0].ToPort, gc.Equals, 80)
289
c.Check(portRanges[1].Protocol, gc.Equals, "tcp")
290
c.Check(portRanges[1].FromPort, gc.Equals, 8000)
291
c.Check(portRanges[1].ToPort, gc.Equals, 8099)
294
func (*PortRangeSuite) TestParsePortRangesSingle(c *gc.C) {
295
portRanges, err := network.ParsePortRanges("80")
296
c.Assert(err, jc.ErrorIsNil)
298
c.Assert(portRanges, gc.HasLen, 1)
299
c.Check(portRanges[0].Protocol, gc.Equals, "tcp")
300
c.Check(portRanges[0].FromPort, gc.Equals, 80)
301
c.Check(portRanges[0].ToPort, gc.Equals, 80)
304
func (*PortRangeSuite) TestParsePortRangesSpaces(c *gc.C) {
305
portRanges, err := network.ParsePortRanges(" 80, 8000-8099 ")
306
c.Assert(err, jc.ErrorIsNil)
308
c.Assert(portRanges, gc.HasLen, 2)
309
c.Check(portRanges[0].Protocol, gc.Equals, "tcp")
310
c.Check(portRanges[0].FromPort, gc.Equals, 80)
311
c.Check(portRanges[0].ToPort, gc.Equals, 80)
312
c.Check(portRanges[1].Protocol, gc.Equals, "tcp")
313
c.Check(portRanges[1].FromPort, gc.Equals, 8000)
314
c.Check(portRanges[1].ToPort, gc.Equals, 8099)