github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/network" 16 "github.com/juju/juju/testing" 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 } 41 42 func makeRanges(stringRanges ...string) []network.PortRange { 43 var results []network.PortRange 44 for _, s := range stringRanges { 45 if strings.Contains(s, "-") { 46 parts := strings.Split(s, "-") 47 fromPort, _ := strconv.Atoi(parts[0]) 48 parts = strings.Split(parts[1], "/") 49 toPort, _ := strconv.Atoi(parts[0]) 50 proto := parts[1] 51 results = append(results, network.PortRange{ 52 FromPort: fromPort, 53 ToPort: toPort, 54 Protocol: proto, 55 }) 56 } else { 57 parts := strings.Split(s, "/") 58 port, _ := strconv.Atoi(parts[0]) 59 proto := parts[1] 60 results = append(results, network.PortRange{ 61 FromPort: port, 62 ToPort: port, 63 Protocol: proto, 64 }) 65 } 66 } 67 network.SortPortRanges(results) 68 return results 69 } 70 71 func (s *PortsSuite) TestOpenClose(c *gc.C) { 72 hctx := s.GetHookContext(c, -1, "") 73 for _, t := range portsTests { 74 com, err := jujuc.NewCommand(hctx, cmdString(t.cmd[0])) 75 c.Assert(err, jc.ErrorIsNil) 76 ctx := testing.Context(c) 77 code := cmd.Main(com, ctx, t.cmd[1:]) 78 c.Assert(code, gc.Equals, 0) 79 c.Assert(bufferString(ctx.Stdout), gc.Equals, "") 80 c.Assert(bufferString(ctx.Stderr), gc.Equals, "") 81 hctx.info.CheckPorts(c, t.expect) 82 } 83 } 84 85 var badPortsTests = []struct { 86 args []string 87 err string 88 }{ 89 {nil, "no port or range specified"}, 90 {[]string{"0"}, `port must be in the range \[1, 65535\]; got "0"`}, 91 {[]string{"65536"}, `port must be in the range \[1, 65535\]; got "65536"`}, 92 {[]string{"two"}, `expected <port>\[/<protocol>\] or <from>-<to>\[/<protocol>\]; got "two"`}, 93 {[]string{"80/http"}, `protocol must be "tcp" or "udp"; got "http"`}, 94 {[]string{"blah/blah/blah"}, `expected <port>\[/<protocol>\] or <from>-<to>\[/<protocol>\]; got "blah/blah/blah"`}, 95 {[]string{"123", "haha"}, `unrecognized args: \["haha"\]`}, 96 {[]string{"1-0"}, `invalid port range 1-0/tcp; expected fromPort <= toPort`}, 97 {[]string{"-42"}, `flag provided but not defined: -4`}, 98 {[]string{"99999/UDP"}, `port must be in the range \[1, 65535\]; got "99999"`}, 99 {[]string{"9999/foo"}, `protocol must be "tcp" or "udp"; got "foo"`}, 100 {[]string{"80-90/http"}, `protocol must be "tcp" or "udp"; got "http"`}, 101 {[]string{"20-10/tcp"}, `invalid port range 20-10/tcp; expected fromPort <= toPort`}, 102 } 103 104 func (s *PortsSuite) TestBadArgs(c *gc.C) { 105 for _, name := range []string{"open-port", "close-port"} { 106 for _, t := range badPortsTests { 107 hctx := s.GetHookContext(c, -1, "") 108 com, err := jujuc.NewCommand(hctx, cmdString(name)) 109 c.Assert(err, jc.ErrorIsNil) 110 err = testing.InitCommand(com, t.args) 111 c.Assert(err, gc.ErrorMatches, t.err) 112 } 113 } 114 } 115 116 func (s *PortsSuite) TestHelp(c *gc.C) { 117 hctx := s.GetHookContext(c, -1, "") 118 open, err := jujuc.NewCommand(hctx, cmdString("open-port")) 119 c.Assert(err, jc.ErrorIsNil) 120 flags := testing.NewFlagSet() 121 c.Assert(string(open.Info().Help(flags)), gc.Equals, ` 122 Usage: open-port <port>[/<protocol>] or <from>-<to>[/<protocol>] 123 124 Summary: 125 register a port or range to open 126 127 Details: 128 The port range will only be open while the service is exposed. 129 `[1:]) 130 131 close, err := jujuc.NewCommand(hctx, cmdString("close-port")) 132 c.Assert(err, jc.ErrorIsNil) 133 c.Assert(string(close.Info().Help(flags)), gc.Equals, ` 134 Usage: close-port <port>[/<protocol>] or <from>-<to>[/<protocol>] 135 136 Summary: 137 ensure a port or range is always closed 138 `[1:]) 139 } 140 141 // Since the deprecation warning gets output during Run, we really need 142 // some valid commands to run 143 var portsFormatDeprectaionTests = []struct { 144 cmd []string 145 }{ 146 {[]string{"open-port", "--format", "foo", "80"}}, 147 {[]string{"close-port", "--format", "foo", "80/TCP"}}, 148 } 149 150 func (s *PortsSuite) TestOpenCloseDeprecation(c *gc.C) { 151 hctx := s.GetHookContext(c, -1, "") 152 for _, t := range portsFormatDeprectaionTests { 153 name := t.cmd[0] 154 com, err := jujuc.NewCommand(hctx, cmdString(name)) 155 c.Assert(err, jc.ErrorIsNil) 156 ctx := testing.Context(c) 157 code := cmd.Main(com, ctx, t.cmd[1:]) 158 c.Assert(code, gc.Equals, 0) 159 c.Assert(testing.Stdout(ctx), gc.Equals, "") 160 c.Assert(testing.Stderr(ctx), gc.Equals, "--format flag deprecated for command \""+name+"\"") 161 } 162 }