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  }