github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/cmd/juju/space/package_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package space_test
     5  
     6  import (
     7  	"net"
     8  	"regexp"
     9  	stdtesting "testing"
    10  
    11  	"github.com/juju/cmd"
    12  	"github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	"github.com/juju/utils/featureflag"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/juju/apiserver/params"
    18  	"github.com/juju/juju/cmd/juju/space"
    19  	"github.com/juju/juju/feature"
    20  	coretesting "github.com/juju/juju/testing"
    21  )
    22  
    23  func TestPackage(t *stdtesting.T) {
    24  	gc.TestingT(t)
    25  }
    26  
    27  // BaseSpaceSuite is used for embedding in other suites.
    28  type BaseSpaceSuite struct {
    29  	coretesting.FakeJujuHomeSuite
    30  	coretesting.BaseSuite
    31  
    32  	superCmd cmd.Command
    33  	command  cmd.Command
    34  	api      *StubAPI
    35  }
    36  
    37  var _ = gc.Suite(&BaseSpaceSuite{})
    38  
    39  func (s *BaseSpaceSuite) SetUpTest(c *gc.C) {
    40  	// If any post-MVP command suite enabled the flag, keep it.
    41  	hasFeatureFlag := featureflag.Enabled(feature.PostNetCLIMVP)
    42  
    43  	s.BaseSuite.SetUpTest(c)
    44  	s.FakeJujuHomeSuite.SetUpTest(c)
    45  
    46  	if hasFeatureFlag {
    47  		s.BaseSuite.SetFeatureFlags(feature.PostNetCLIMVP)
    48  	}
    49  
    50  	s.superCmd = space.NewSuperCommand()
    51  	c.Assert(s.superCmd, gc.NotNil)
    52  
    53  	s.api = NewStubAPI()
    54  	c.Assert(s.api, gc.NotNil)
    55  
    56  	// All subcommand suites embedding this one should initialize
    57  	// s.command immediately after calling this method!
    58  }
    59  
    60  // RunSuperCommand executes the super command passing any args and
    61  // returning the stdout and stderr output as strings, as well as any
    62  // error. If s.command is set, the subcommand's name will be passed as
    63  // first argument.
    64  func (s *BaseSpaceSuite) RunSuperCommand(c *gc.C, args ...string) (string, string, error) {
    65  	if s.command != nil {
    66  		args = append([]string{s.command.Info().Name}, args...)
    67  	}
    68  	ctx, err := coretesting.RunCommand(c, s.superCmd, args...)
    69  	if ctx != nil {
    70  		return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err
    71  	}
    72  	return "", "", err
    73  }
    74  
    75  // RunSubCommand executes the s.command subcommand passing any args
    76  // and returning the stdout and stderr output as strings, as well as
    77  // any error.
    78  func (s *BaseSpaceSuite) RunSubCommand(c *gc.C, args ...string) (string, string, error) {
    79  	if s.command == nil {
    80  		panic("subcommand is nil")
    81  	}
    82  	ctx, err := coretesting.RunCommand(c, s.command, args...)
    83  	if ctx != nil {
    84  		return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err
    85  	}
    86  	return "", "", err
    87  }
    88  
    89  // AssertRunFails is a shortcut for calling RunSubCommand with the
    90  // passed args then asserting the output is empty and the error is as
    91  // expected, finally returning the error.
    92  func (s *BaseSpaceSuite) AssertRunFails(c *gc.C, expectErr string, args ...string) error {
    93  	stdout, stderr, err := s.RunSubCommand(c, args...)
    94  	c.Assert(err, gc.ErrorMatches, expectErr)
    95  	c.Assert(stdout, gc.Equals, "")
    96  	c.Assert(stderr, gc.Equals, "")
    97  	return err
    98  }
    99  
   100  // AssertRunSucceeds is a shortcut for calling RunSuperCommand with
   101  // the passed args then asserting the stderr output matches
   102  // expectStderr, stdout is equal to expectStdout, and the error is
   103  // nil.
   104  func (s *BaseSpaceSuite) AssertRunSucceeds(c *gc.C, expectStderr, expectStdout string, args ...string) {
   105  	stdout, stderr, err := s.RunSubCommand(c, args...)
   106  	c.Assert(err, jc.ErrorIsNil)
   107  	c.Assert(stdout, gc.Equals, expectStdout)
   108  	c.Assert(stderr, gc.Matches, expectStderr)
   109  }
   110  
   111  // TestHelp runs the command with --help as argument and verifies the
   112  // output.
   113  func (s *BaseSpaceSuite) TestHelp(c *gc.C) {
   114  	stderr, stdout, err := s.RunSuperCommand(c, "--help")
   115  	c.Assert(err, jc.ErrorIsNil)
   116  	c.Check(stdout, gc.Equals, "")
   117  	c.Check(stderr, gc.Not(gc.Equals), "")
   118  
   119  	// If s.command is set, use it instead of s.superCmd.
   120  	cmdInfo := s.superCmd.Info()
   121  	var expected string
   122  	if s.command != nil {
   123  		// Subcommands embed EnvCommandBase
   124  		cmdInfo = s.command.Info()
   125  		expected = "(?sm).*^usage: juju space " +
   126  			regexp.QuoteMeta(cmdInfo.Name) +
   127  			`( \[options\])? ` + regexp.QuoteMeta(cmdInfo.Args) + ".+"
   128  	} else {
   129  		expected = "(?sm).*^usage: juju space" +
   130  			`( \[options\])? ` + regexp.QuoteMeta(cmdInfo.Args) + ".+"
   131  	}
   132  	c.Check(cmdInfo, gc.NotNil)
   133  	c.Check(stderr, gc.Matches, expected)
   134  
   135  	expected = "(?sm).*^purpose: " + regexp.QuoteMeta(cmdInfo.Purpose) + "$.*"
   136  	c.Check(stderr, gc.Matches, expected)
   137  
   138  	expected = "(?sm).*^" + regexp.QuoteMeta(cmdInfo.Doc) + "$.*"
   139  	c.Check(stderr, gc.Matches, expected)
   140  }
   141  
   142  // Strings is makes tests taking a slice of strings slightly easier to
   143  // write: e.g. s.Strings("foo", "bar") vs. []string{"foo", "bar"}.
   144  func (s *BaseSpaceSuite) Strings(values ...string) []string {
   145  	return values
   146  }
   147  
   148  // StubAPI defines a testing stub for the SpaceAPI interface.
   149  type StubAPI struct {
   150  	*testing.Stub
   151  
   152  	Spaces  []params.Space
   153  	Subnets []params.Subnet
   154  }
   155  
   156  var _ space.SpaceAPI = (*StubAPI)(nil)
   157  
   158  // NewStubAPI creates a StubAPI suitable for passing to
   159  // space.New*Command().
   160  func NewStubAPI() *StubAPI {
   161  	subnets := []params.Subnet{{
   162  		// IPv6 subnet.
   163  		CIDR:       "2001:db8::/32",
   164  		ProviderId: "subnet-public",
   165  		Life:       params.Dying,
   166  		SpaceTag:   "space-space1",
   167  		Zones:      []string{"zone2"},
   168  	}, {
   169  		// Invalid subnet (just for 100% coverage, otherwise it can't happen).
   170  		CIDR:       "invalid",
   171  		ProviderId: "no-such",
   172  		SpaceTag:   "space-space1",
   173  		Zones:      []string{"zone1"},
   174  	}, {
   175  		// IPv4 subnet.
   176  		CIDR:              "10.1.2.0/24",
   177  		ProviderId:        "subnet-private",
   178  		Life:              params.Alive,
   179  		SpaceTag:          "space-space2",
   180  		Zones:             []string{"zone1", "zone2"},
   181  		StaticRangeLowIP:  net.ParseIP("10.1.2.10"),
   182  		StaticRangeHighIP: net.ParseIP("10.1.2.200"),
   183  	}, {
   184  		// IPv4 VLAN subnet.
   185  		CIDR:              "4.3.2.0/28",
   186  		Life:              params.Dead,
   187  		ProviderId:        "vlan-42",
   188  		SpaceTag:          "space-space2",
   189  		Zones:             []string{"zone1"},
   190  		VLANTag:           42,
   191  		StaticRangeLowIP:  net.ParseIP("4.3.2.2"),
   192  		StaticRangeHighIP: net.ParseIP("4.3.2.4"),
   193  	}}
   194  	spaces := []params.Space{{
   195  		Name:    "space1",
   196  		Subnets: append([]params.Subnet{}, subnets[:2]...),
   197  	}, {
   198  		Name:    "space2",
   199  		Subnets: append([]params.Subnet{}, subnets[2:]...),
   200  	}}
   201  	return &StubAPI{
   202  		Stub:    &testing.Stub{},
   203  		Spaces:  spaces,
   204  		Subnets: subnets,
   205  	}
   206  }
   207  
   208  func (sa *StubAPI) Close() error {
   209  	sa.MethodCall(sa, "Close")
   210  	return sa.NextErr()
   211  }
   212  
   213  func (sa *StubAPI) ListSpaces() ([]params.Space, error) {
   214  	sa.MethodCall(sa, "ListSpaces")
   215  	if err := sa.NextErr(); err != nil {
   216  		return nil, err
   217  	}
   218  	return sa.Spaces, nil
   219  }
   220  
   221  func (sa *StubAPI) CreateSpace(name string, subnetIds []string, public bool) error {
   222  	sa.MethodCall(sa, "CreateSpace", name, subnetIds, public)
   223  	return sa.NextErr()
   224  }
   225  
   226  func (sa *StubAPI) RemoveSpace(name string) error {
   227  	sa.MethodCall(sa, "RemoveSpace", name)
   228  	return sa.NextErr()
   229  }
   230  
   231  func (sa *StubAPI) UpdateSpace(name string, subnetIds []string) error {
   232  	sa.MethodCall(sa, "UpdateSpace", name, subnetIds)
   233  	return sa.NextErr()
   234  }
   235  
   236  func (sa *StubAPI) RenameSpace(name, newName string) error {
   237  	sa.MethodCall(sa, "RenameSpace", name, newName)
   238  	return sa.NextErr()
   239  }