github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/runner/jujuc/opened-ports_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc_test 5 6 import ( 7 "strings" 8 9 "github.com/juju/cmd/v3" 10 "github.com/juju/cmd/v3/cmdtesting" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/core/network" 15 "github.com/juju/juju/worker/uniter/runner/jujuc" 16 ) 17 18 type OpenedPortsSuite struct { 19 ContextSuite 20 } 21 22 var _ = gc.Suite(&OpenedPortsSuite{}) 23 24 func (s *OpenedPortsSuite) TestRunAllFormats(c *gc.C) { 25 expectedPorts := []network.PortRange{ 26 network.MustParsePortRange("10-20/tcp"), 27 network.MustParsePortRange("80/tcp"), 28 network.MustParsePortRange("53-55/udp"), 29 network.MustParsePortRange("63/udp"), 30 } 31 network.SortPortRanges(expectedPorts) 32 portsAsStrings := make([]string, len(expectedPorts)) 33 for i, portRange := range expectedPorts { 34 portsAsStrings[i] = portRange.String() 35 } 36 defaultOutput := strings.Join(portsAsStrings, "\n") + "\n" 37 jsonOutput := `["` + strings.Join(portsAsStrings, `","`) + `"]` + "\n" 38 yamlOutput := "- " + strings.Join(portsAsStrings, "\n- ") + "\n" 39 40 formatToOutput := map[string]string{ 41 "": defaultOutput, 42 "smart": defaultOutput, 43 "json": jsonOutput, 44 "yaml": yamlOutput, 45 } 46 for format, expectedOutput := range formatToOutput { 47 c.Logf("testing format %q", format) 48 hctx := s.getContextAndOpenPorts(c) 49 stdout := "" 50 stderr := "" 51 if format == "" { 52 stdout, stderr = s.runCommand(c, hctx) 53 } else { 54 stdout, stderr = s.runCommand(c, hctx, "--format", format) 55 } 56 c.Check(stdout, gc.Equals, expectedOutput) 57 c.Check(stderr, gc.Equals, "") 58 } 59 } 60 61 func (s *OpenedPortsSuite) TestRunAllFormatsWithEndpointDetails(c *gc.C) { 62 portsAsStrings := []string{ 63 "10-20/tcp (foo)", 64 "80/tcp (*)", 65 "53-55/udp (*)", 66 "63/udp (bar)", 67 } 68 defaultOutput := strings.Join(portsAsStrings, "\n") + "\n" 69 jsonOutput := `["` + strings.Join(portsAsStrings, `","`) + `"]` + "\n" 70 yamlOutput := "- " + strings.Join(portsAsStrings, "\n- ") + "\n" 71 72 formatToOutput := map[string]string{ 73 "": defaultOutput, 74 "smart": defaultOutput, 75 "json": jsonOutput, 76 "yaml": yamlOutput, 77 } 78 for format, expectedOutput := range formatToOutput { 79 c.Logf("testing format %q", format) 80 hctx := s.getContextAndOpenPorts(c) 81 stdout := "" 82 stderr := "" 83 if format == "" { 84 stdout, stderr = s.runCommand(c, hctx, "--endpoints") 85 } else { 86 stdout, stderr = s.runCommand(c, hctx, "--endpoints", "--format", format) 87 } 88 c.Check(stdout, gc.Equals, expectedOutput) 89 c.Check(stderr, gc.Equals, "") 90 } 91 } 92 93 func (s *OpenedPortsSuite) TestBadArgs(c *gc.C) { 94 hctx := s.GetHookContext(c, -1, "") 95 com, err := jujuc.NewCommand(hctx, "opened-ports") 96 c.Assert(err, jc.ErrorIsNil) 97 err = cmdtesting.InitCommand(jujuc.NewJujucCommandWrappedForTest(com), []string{"foo"}) 98 c.Assert(err, gc.ErrorMatches, `unrecognized args: \["foo"\]`) 99 } 100 101 func (s *OpenedPortsSuite) TestHelp(c *gc.C) { 102 hctx := s.GetHookContext(c, -1, "") 103 openedPorts, err := jujuc.NewCommand(hctx, "opened-ports") 104 c.Assert(err, jc.ErrorIsNil) 105 flags := cmdtesting.NewFlagSet() 106 c.Assert(string(openedPorts.Info().Help(flags)), gc.Equals, ` 107 Usage: opened-ports 108 109 Summary: 110 list all ports or port ranges opened by the unit 111 112 Details: 113 opened-ports lists all ports or port ranges opened by a unit. 114 115 By default, the port range listing does not include information about the 116 application endpoints that each port range applies to. Each list entry is 117 formatted as <port>/<protocol> (e.g. "80/tcp") or <from>-<to>/<protocol> 118 (e.g. "8080-8088/udp"). 119 120 If the --endpoints option is specified, each entry in the port list will be 121 augmented with a comma-delimited list of endpoints that the port range 122 applies to (e.g. "80/tcp (endpoint1, endpoint2)"). If a port range applies to 123 all endpoints, this will be indicated by the presence of a '*' character 124 (e.g. "80/tcp (*)"). 125 `[1:]) 126 } 127 128 func (s *OpenedPortsSuite) getContextAndOpenPorts(c *gc.C) *Context { 129 hctx := s.GetHookContext(c, -1, "") 130 hctx.OpenPortRange("", network.MustParsePortRange("80/tcp")) 131 hctx.OpenPortRange("foo", network.MustParsePortRange("10-20/tcp")) 132 hctx.OpenPortRange("bar", network.MustParsePortRange("63/udp")) 133 hctx.OpenPortRange("", network.MustParsePortRange("53-55/udp")) 134 return hctx 135 } 136 137 func (s *OpenedPortsSuite) runCommand(c *gc.C, hctx *Context, args ...string) (stdout, stderr string) { 138 com, err := jujuc.NewCommand(hctx, "opened-ports") 139 c.Assert(err, jc.ErrorIsNil) 140 ctx := cmdtesting.Context(c) 141 code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, args) 142 c.Assert(code, gc.Equals, 0) 143 return bufferString(ctx.Stdout), bufferString(ctx.Stderr) 144 }