github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/runner/jujuc/ports_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Copyright 2014 Cloudbase Solutions SRL 3 // Licensed under the AGPLv3, see LICENCE file for details. 4 5 package jujuc_test 6 7 import ( 8 "strconv" 9 "strings" 10 11 "github.com/juju/cmd" 12 "github.com/juju/cmd/cmdtesting" 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/core/network" 17 "github.com/juju/juju/worker/uniter/runner/jujuc" 18 ) 19 20 type PortsSuite struct { 21 ContextSuite 22 } 23 24 var _ = gc.Suite(&PortsSuite{}) 25 26 var portsTests = []struct { 27 cmd []string 28 expect []network.PortRange 29 }{ 30 {[]string{"open-port", "80"}, makeRanges("80/tcp")}, 31 {[]string{"open-port", "99/tcp"}, makeRanges("80/tcp", "99/tcp")}, 32 {[]string{"open-port", "100-200"}, makeRanges("80/tcp", "99/tcp", "100-200/tcp")}, 33 {[]string{"open-port", "443/udp"}, makeRanges("80/tcp", "99/tcp", "100-200/tcp", "443/udp")}, 34 {[]string{"close-port", "80/TCP"}, makeRanges("99/tcp", "100-200/tcp", "443/udp")}, 35 {[]string{"close-port", "100-200/tcP"}, makeRanges("99/tcp", "443/udp")}, 36 {[]string{"close-port", "443"}, makeRanges("99/tcp", "443/udp")}, 37 {[]string{"close-port", "443/udp"}, makeRanges("99/tcp")}, 38 {[]string{"open-port", "123/udp"}, makeRanges("99/tcp", "123/udp")}, 39 {[]string{"close-port", "9999/UDP"}, makeRanges("99/tcp", "123/udp")}, 40 {[]string{"open-port", "icmp"}, makeRanges("icmp", "99/tcp", "123/udp")}, 41 } 42 43 func makeRanges(stringRanges ...string) []network.PortRange { 44 var results []network.PortRange 45 for _, s := range stringRanges { 46 if s == "icmp" { 47 results = append(results, network.PortRange{ 48 FromPort: -1, 49 ToPort: -1, 50 Protocol: "icmp", 51 }) 52 continue 53 } 54 if strings.Contains(s, "-") { 55 parts := strings.Split(s, "-") 56 fromPort, _ := strconv.Atoi(parts[0]) 57 parts = strings.Split(parts[1], "/") 58 toPort, _ := strconv.Atoi(parts[0]) 59 proto := parts[1] 60 results = append(results, network.PortRange{ 61 FromPort: fromPort, 62 ToPort: toPort, 63 Protocol: proto, 64 }) 65 } else { 66 parts := strings.Split(s, "/") 67 port, _ := strconv.Atoi(parts[0]) 68 proto := parts[1] 69 results = append(results, network.PortRange{ 70 FromPort: port, 71 ToPort: port, 72 Protocol: proto, 73 }) 74 } 75 } 76 network.SortPortRanges(results) 77 return results 78 } 79 80 func (s *PortsSuite) TestOpenClose(c *gc.C) { 81 hctx := s.GetHookContext(c, -1, "") 82 for _, t := range portsTests { 83 com, err := jujuc.NewCommand(hctx, cmdString(t.cmd[0])) 84 c.Assert(err, jc.ErrorIsNil) 85 ctx := cmdtesting.Context(c) 86 code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, t.cmd[1:]) 87 c.Check(code, gc.Equals, 0) 88 c.Assert(bufferString(ctx.Stdout), gc.Equals, "") 89 c.Assert(bufferString(ctx.Stderr), gc.Equals, "") 90 hctx.info.CheckPorts(c, t.expect) 91 } 92 } 93 94 var badPortsTests = []struct { 95 args []string 96 err string 97 }{ 98 {nil, "no port or range specified"}, 99 {[]string{"0"}, `port must be in the range \[1, 65535\]; got "0"`}, 100 {[]string{"65536"}, `port must be in the range \[1, 65535\]; got "65536"`}, 101 {[]string{"two"}, `expected <port>\[/<protocol>\] or <from>-<to>\[/<protocol>\] or icmp; got "two"`}, 102 {[]string{"80/http"}, `protocol must be "tcp", "udp", or "icmp"; got "http"`}, 103 {[]string{"blah/blah/blah"}, `expected <port>\[/<protocol>\] or <from>-<to>\[/<protocol>\] or icmp; got "blah/blah/blah"`}, 104 {[]string{"123", "haha"}, `unrecognized args: \["haha"\]`}, 105 {[]string{"1-0"}, `invalid port range 1-0/tcp; expected fromPort <= toPort`}, 106 {[]string{"-42"}, `option provided but not defined: -4`}, 107 {[]string{"99999/UDP"}, `port must be in the range \[1, 65535\]; got "99999"`}, 108 {[]string{"9999/foo"}, `protocol must be "tcp", "udp", or "icmp"; got "foo"`}, 109 {[]string{"80-90/http"}, `protocol must be "tcp", "udp", or "icmp"; got "http"`}, 110 {[]string{"20-10/tcp"}, `invalid port range 20-10/tcp; expected fromPort <= toPort`}, 111 {[]string{"80/icmp"}, `protocol "icmp" doesn't support any ports; got "80"`}, 112 } 113 114 func (s *PortsSuite) TestBadArgs(c *gc.C) { 115 for _, name := range []string{"open-port", "close-port"} { 116 for _, t := range badPortsTests { 117 hctx := s.GetHookContext(c, -1, "") 118 com, err := jujuc.NewCommand(hctx, cmdString(name)) 119 c.Assert(err, jc.ErrorIsNil) 120 err = cmdtesting.InitCommand(jujuc.NewJujucCommandWrappedForTest(com), t.args) 121 c.Assert(err, gc.ErrorMatches, t.err) 122 } 123 } 124 } 125 126 func (s *PortsSuite) TestHelp(c *gc.C) { 127 hctx := s.GetHookContext(c, -1, "") 128 open, err := jujuc.NewCommand(hctx, cmdString("open-port")) 129 c.Assert(err, jc.ErrorIsNil) 130 flags := cmdtesting.NewFlagSet() 131 c.Assert(string(open.Info().Help(flags)), gc.Equals, ` 132 Usage: open-port <port>[/<protocol>] or <from>-<to>[/<protocol>] or icmp 133 134 Summary: 135 register a port or range to open 136 137 Details: 138 The port range will only be open while the application is exposed. 139 `[1:]) 140 141 close, err := jujuc.NewCommand(hctx, cmdString("close-port")) 142 c.Assert(err, jc.ErrorIsNil) 143 c.Assert(string(close.Info().Help(flags)), gc.Equals, ` 144 Usage: close-port <port>[/<protocol>] or <from>-<to>[/<protocol>] or icmp 145 146 Summary: 147 ensure a port or range is always closed 148 `[1:]) 149 } 150 151 // Since the deprecation warning gets output during Run, we really need 152 // some valid commands to run 153 var portsFormatDeprectaionTests = []struct { 154 cmd []string 155 }{ 156 {[]string{"open-port", "--format", "foo", "80"}}, 157 {[]string{"close-port", "--format", "foo", "80/TCP"}}, 158 } 159 160 func (s *PortsSuite) TestOpenCloseDeprecation(c *gc.C) { 161 hctx := s.GetHookContext(c, -1, "") 162 for _, t := range portsFormatDeprectaionTests { 163 name := t.cmd[0] 164 com, err := jujuc.NewCommand(hctx, cmdString(name)) 165 c.Assert(err, jc.ErrorIsNil) 166 ctx := cmdtesting.Context(c) 167 code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, t.cmd[1:]) 168 c.Assert(code, gc.Equals, 0) 169 c.Assert(cmdtesting.Stdout(ctx), gc.Equals, "") 170 c.Assert(cmdtesting.Stderr(ctx), gc.Equals, "--format flag deprecated for command \""+name+"\"") 171 } 172 }