github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/featuretests/cmd_juju_space_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package featuretests
     5  
     6  import (
     7  	"fmt"
     8  	"math/rand"
     9  
    10  	"github.com/juju/cmd"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/cmd/envcmd"
    15  	cmdspace "github.com/juju/juju/cmd/juju/space"
    16  	jujutesting "github.com/juju/juju/juju/testing"
    17  	"github.com/juju/juju/state"
    18  	"github.com/juju/juju/testing"
    19  )
    20  
    21  type cmdSpaceSuite struct {
    22  	jujutesting.JujuConnSuite
    23  }
    24  
    25  func (s *cmdSpaceSuite) AddSubnets(c *gc.C, infos []state.SubnetInfo) []*state.Subnet {
    26  	results := make([]*state.Subnet, len(infos))
    27  	for i, info := range infos {
    28  		subnet, err := s.State.AddSubnet(info)
    29  		c.Assert(err, jc.ErrorIsNil)
    30  		c.Assert(subnet.CIDR(), gc.Equals, info.CIDR)
    31  		results[i] = subnet
    32  	}
    33  	return results
    34  }
    35  
    36  func (s *cmdSpaceSuite) MakeSubnetInfos(c *gc.C, space string, cidrTemplate string, count int) (
    37  	infos []state.SubnetInfo,
    38  	ids []string,
    39  ) {
    40  	infos = make([]state.SubnetInfo, count)
    41  	ids = make([]string, count)
    42  	for i := range infos {
    43  		ids[i] = fmt.Sprintf(cidrTemplate, i)
    44  		infos[i] = state.SubnetInfo{
    45  			// ProviderId it needs to be unique in state.
    46  			ProviderId:       fmt.Sprintf("sub-%d", rand.Int()),
    47  			CIDR:             ids[i],
    48  			SpaceName:        space,
    49  			AvailabilityZone: "zone1",
    50  		}
    51  	}
    52  	return infos, ids
    53  }
    54  
    55  func (s *cmdSpaceSuite) AddSpace(c *gc.C, name string, ids []string, public bool) *state.Space {
    56  	space, err := s.State.AddSpace(name, ids, public)
    57  	c.Assert(err, jc.ErrorIsNil)
    58  	c.Assert(space.Name(), gc.Equals, name)
    59  	subnets, err := space.Subnets()
    60  	c.Assert(err, jc.ErrorIsNil)
    61  	c.Assert(subnets, gc.HasLen, len(ids))
    62  	return space
    63  }
    64  
    65  const expectedSuccess = ""
    66  
    67  func (s *cmdSpaceSuite) Run(c *gc.C, command cmd.Command, expectedError string, args ...string) *cmd.Context {
    68  	context, err := testing.RunCommand(c, command, args...)
    69  	if expectedError != "" {
    70  		c.Assert(err, gc.ErrorMatches, expectedError)
    71  	} else {
    72  		c.Assert(err, jc.ErrorIsNil)
    73  	}
    74  	return context
    75  }
    76  
    77  func (s *cmdSpaceSuite) RunSuper(c *gc.C, expectedError string, args ...string) *cmd.Context {
    78  	return s.Run(c, cmdspace.NewSuperCommand(), expectedError, args...)
    79  }
    80  
    81  func (s *cmdSpaceSuite) RunCreate(c *gc.C, expectedError string, args ...string) *cmd.Context {
    82  	// To capture subcommand errors, we must *NOT* to run it through
    83  	// the supercommand, otherwise there error is logged and
    84  	// swallowed!
    85  	createCommand := envcmd.Wrap(&cmdspace.CreateCommand{})
    86  	return s.Run(c, createCommand, expectedError, args...)
    87  }
    88  
    89  func (s *cmdSpaceSuite) AssertOutput(c *gc.C, context *cmd.Context, expectedOut, expectedErr string) {
    90  	c.Assert(testing.Stdout(context), gc.Equals, expectedOut)
    91  	c.Assert(testing.Stderr(context), gc.Equals, expectedErr)
    92  }
    93  
    94  func (s *cmdSpaceSuite) TestSpaceCreateNoName(c *gc.C) {
    95  	expectedError := "invalid arguments specified: space name is required"
    96  	s.RunSuper(c, expectedError, "create")
    97  }
    98  
    99  func (s *cmdSpaceSuite) TestSpaceCreateInvalidName(c *gc.C) {
   100  	expectedError := `invalid arguments specified: " f o o " is not a valid space name`
   101  	s.RunSuper(c, expectedError, "create", " f o o ")
   102  }
   103  
   104  func (s *cmdSpaceSuite) TestSpaceCreateWithInvalidSubnets(c *gc.C) {
   105  	expectedError := `invalid arguments specified: "nonsense" is not a valid CIDR`
   106  	s.RunSuper(c, expectedError, "create", "myspace", "nonsense", "10.20.0.0/16")
   107  }
   108  
   109  func (s *cmdSpaceSuite) TestSpaceCreateWithUnknownSubnet(c *gc.C) {
   110  	expectedError := `cannot create space "foo": adding space "foo": subnet "10.10.0.0/16" not found`
   111  	s.RunCreate(c, expectedError, "foo", "10.10.0.0/16")
   112  }
   113  
   114  func (s *cmdSpaceSuite) TestSpaceCreateAlreadyExistingName(c *gc.C) {
   115  	s.AddSpace(c, "foo", nil, true)
   116  
   117  	expectedError := `cannot create space "foo": adding space "foo": space "foo" already exists`
   118  	s.RunCreate(c, expectedError, "foo")
   119  }
   120  
   121  func (s *cmdSpaceSuite) TestSpaceCreateNoSubnets(c *gc.C) {
   122  	context := s.RunSuper(c, expectedSuccess, "create", "myspace")
   123  	s.AssertOutput(c, context,
   124  		"", // no stdout output
   125  		"created space \"myspace\" with no subnets\n",
   126  	)
   127  
   128  	space, err := s.State.Space("myspace")
   129  	c.Assert(err, jc.ErrorIsNil)
   130  	c.Assert(space.Name(), gc.Equals, "myspace")
   131  	subnets, err := space.Subnets()
   132  	c.Assert(err, jc.ErrorIsNil)
   133  	c.Assert(subnets, gc.HasLen, 0)
   134  }
   135  
   136  func (s *cmdSpaceSuite) TestSpaceCreateWithSubnets(c *gc.C) {
   137  	infos, _ := s.MakeSubnetInfos(c, "", "10.1%d.0.0/16", 2)
   138  	s.AddSubnets(c, infos)
   139  
   140  	context := s.RunSuper(
   141  		c, expectedSuccess,
   142  		"create", "myspace", "10.10.0.0/16", "10.11.0.0/16",
   143  	)
   144  	s.AssertOutput(c, context,
   145  		"", // no stdout output
   146  		"created space \"myspace\" with subnets 10.10.0.0/16, 10.11.0.0/16\n",
   147  	)
   148  
   149  	space, err := s.State.Space("myspace")
   150  	c.Assert(err, jc.ErrorIsNil)
   151  	c.Assert(space.Name(), gc.Equals, "myspace")
   152  	subnets, err := space.Subnets()
   153  	c.Assert(err, jc.ErrorIsNil)
   154  	c.Assert(subnets, gc.HasLen, 2)
   155  	c.Assert(subnets[0].SpaceName(), gc.Equals, "myspace")
   156  	c.Assert(subnets[1].SpaceName(), gc.Equals, "myspace")
   157  }
   158  
   159  func (s *cmdSpaceSuite) TestSpaceListNoResults(c *gc.C) {
   160  	context := s.RunSuper(c, expectedSuccess, "list")
   161  	s.AssertOutput(c, context,
   162  		"", // no stdout output
   163  		"no spaces to display\n",
   164  	)
   165  }
   166  
   167  func (s *cmdSpaceSuite) TestSpaceListOneResultNoSubnets(c *gc.C) {
   168  	s.AddSpace(c, "myspace", nil, true)
   169  
   170  	expectedOutput := "{\"spaces\":{\"myspace\":{}}}\n"
   171  	context := s.RunSuper(c, expectedSuccess, "list", "--format", "json")
   172  	s.AssertOutput(c, context,
   173  		expectedOutput,
   174  		"", // no stderr output
   175  	)
   176  }
   177  
   178  func (s *cmdSpaceSuite) TestSpaceListMoreResults(c *gc.C) {
   179  	infos1, ids1 := s.MakeSubnetInfos(c, "space1", "10.10.%d.0/24", 3)
   180  	s.AddSubnets(c, infos1)
   181  	s.AddSpace(c, "space1", ids1, true)
   182  
   183  	infos2, ids2 := s.MakeSubnetInfos(c, "space2", "10.20.%d.0/24", 1)
   184  	s.AddSubnets(c, infos2)
   185  	s.AddSpace(c, "space2", ids2, false)
   186  
   187  	context := s.RunSuper(c, expectedSuccess, "list", "--format", "yaml")
   188  	c.Assert(testing.Stderr(context), gc.Equals, "") // no stderr output
   189  
   190  	// We dont' check the output in detail, just a few things - the
   191  	// rest it tested separately.
   192  	stdout := testing.Stdout(context)
   193  	c.Assert(stdout, jc.Contains, "spaces:")
   194  	c.Assert(stdout, jc.Contains, "space1:")
   195  	c.Assert(stdout, jc.Contains, "10.10.2.0/24:")
   196  	c.Assert(stdout, jc.Contains, "space2:")
   197  	c.Assert(stdout, jc.Contains, "10.20.0.0/24:")
   198  	c.Assert(stdout, jc.Contains, "zones:")
   199  	c.Assert(stdout, jc.Contains, "zone1")
   200  }