github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/cmd/juju/subnet/add_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package subnet_test
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/juju/errors"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/names.v2"
    14  
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/cmd/juju/subnet"
    17  	"github.com/juju/juju/network"
    18  	coretesting "github.com/juju/juju/testing"
    19  )
    20  
    21  type AddSuite struct {
    22  	BaseSubnetSuite
    23  }
    24  
    25  var _ = gc.Suite(&AddSuite{})
    26  
    27  func (s *AddSuite) SetUpTest(c *gc.C) {
    28  	s.BaseSubnetSuite.SetUpTest(c)
    29  	s.command, _ = subnet.NewAddCommandForTest(s.api)
    30  	c.Assert(s.command, gc.NotNil)
    31  }
    32  
    33  func (s *AddSuite) TestInit(c *gc.C) {
    34  	for i, test := range []struct {
    35  		about            string
    36  		args             []string
    37  		expectCIDR       string
    38  		expectRawCIDR    string
    39  		expectProviderId string
    40  		expectSpace      string
    41  		expectZones      []string
    42  		expectErr        string
    43  	}{{
    44  		about:     "no arguments",
    45  		expectErr: "either CIDR or provider ID is required",
    46  	}, {
    47  		about:     "single argument - invalid CIDR: space name is required",
    48  		args:      s.Strings("anything"),
    49  		expectErr: "space name is required",
    50  	}, {
    51  		about:     "single argument - valid CIDR: space name is required",
    52  		args:      s.Strings("10.0.0.0/8"),
    53  		expectErr: "space name is required",
    54  	}, {
    55  		about:     "single argument - incorrect CIDR: space name is required",
    56  		args:      s.Strings("10.10.0.0/8"),
    57  		expectErr: "space name is required",
    58  	}, {
    59  		about:            "two arguments: an invalid CIDR is assumed to mean ProviderId",
    60  		args:             s.Strings("foo", "bar"),
    61  		expectProviderId: "foo",
    62  		expectSpace:      "bar",
    63  	}, {
    64  		about:         "two arguments: an incorrectly specified CIDR is fixed",
    65  		args:          s.Strings("10.10.0.0/8", "bar"),
    66  		expectCIDR:    "10.0.0.0/8",
    67  		expectRawCIDR: "10.10.0.0/8",
    68  		expectSpace:   "bar",
    69  	}, {
    70  		about:         "more arguments parsed as zones",
    71  		args:          s.Strings("10.0.0.0/8", "new-space", "zone1", "zone2"),
    72  		expectCIDR:    "10.0.0.0/8",
    73  		expectRawCIDR: "10.0.0.0/8",
    74  		expectSpace:   "new-space",
    75  		expectZones:   s.Strings("zone1", "zone2"),
    76  	}, {
    77  		about:         "CIDR and invalid space name, one zone",
    78  		args:          s.Strings("10.10.0.0/24", "%inv$alid", "zone"),
    79  		expectCIDR:    "10.10.0.0/24",
    80  		expectRawCIDR: "10.10.0.0/24",
    81  		expectErr:     `"%inv\$alid" is not a valid space name`,
    82  	}, {
    83  		about:         "incorrect CIDR and invalid space name, no zones",
    84  		args:          s.Strings("10.10.0.0/8", "%inv$alid"),
    85  		expectCIDR:    "10.0.0.0/8",
    86  		expectRawCIDR: "10.10.0.0/8",
    87  		expectErr:     `"%inv\$alid" is not a valid space name`,
    88  	}, {
    89  		about:            "ProviderId and invalid space name, two zones",
    90  		args:             s.Strings("foo", "%inv$alid", "zone1", "zone2"),
    91  		expectProviderId: "foo",
    92  		expectErr:        `"%inv\$alid" is not a valid space name`,
    93  	}} {
    94  		c.Logf("test #%d: %s", i, test.about)
    95  		// Create a new instance of the subcommand for each test, but
    96  		// since we're not running the command no need to use
    97  		// modelcmd.Wrap().
    98  		wrappedCommand, command := subnet.NewAddCommandForTest(s.api)
    99  		err := coretesting.InitCommand(wrappedCommand, test.args)
   100  		if test.expectErr != "" {
   101  			prefixedErr := "invalid arguments specified: " + test.expectErr
   102  			c.Check(err, gc.ErrorMatches, prefixedErr)
   103  		} else {
   104  			c.Check(err, jc.ErrorIsNil)
   105  			c.Check(command.CIDR.Id(), gc.Equals, test.expectCIDR)
   106  			c.Check(command.RawCIDR, gc.Equals, test.expectRawCIDR)
   107  			c.Check(command.ProviderId, gc.Equals, test.expectProviderId)
   108  			c.Check(command.Space.Id(), gc.Equals, test.expectSpace)
   109  			c.Check(command.Zones, jc.DeepEquals, test.expectZones)
   110  		}
   111  		// No API calls should be recorded at this stage.
   112  		s.api.CheckCallNames(c)
   113  	}
   114  }
   115  
   116  func (s *AddSuite) TestRunWithIPv4CIDRSucceeds(c *gc.C) {
   117  	s.AssertRunSucceeds(c,
   118  		`added subnet with CIDR "10.20.0.0/24" in space "myspace"\n`,
   119  		"", // empty stdout.
   120  		"10.20.0.0/24", "myspace",
   121  	)
   122  
   123  	s.api.CheckCallNames(c, "AddSubnet", "Close")
   124  	s.api.CheckCall(c, 0, "AddSubnet",
   125  		names.NewSubnetTag("10.20.0.0/24"),
   126  		network.Id(""),
   127  		names.NewSpaceTag("myspace"),
   128  		[]string(nil),
   129  	)
   130  }
   131  
   132  func (s *AddSuite) TestRunWithIncorrectlyGivenCIDRSucceedsWithWarning(c *gc.C) {
   133  	expectStderr := strings.Join([]string{
   134  		"(.|\n)*",
   135  		"WARNING: using CIDR \"10.0.0.0/8\" instead of ",
   136  		"the incorrectly specified \"10.10.0.0/8\".\n",
   137  		"added subnet with CIDR \"10.0.0.0/8\" in space \"myspace\"\n",
   138  	}, "")
   139  
   140  	s.AssertRunSucceeds(c,
   141  		expectStderr,
   142  		"", // empty stdout.
   143  		"10.10.0.0/8", "myspace",
   144  	)
   145  
   146  	s.api.CheckCallNames(c, "AddSubnet", "Close")
   147  	s.api.CheckCall(c, 0, "AddSubnet",
   148  		names.NewSubnetTag("10.0.0.0/8"),
   149  		network.Id(""),
   150  		names.NewSpaceTag("myspace"),
   151  		[]string(nil),
   152  	)
   153  }
   154  
   155  func (s *AddSuite) TestRunWithProviderIdSucceeds(c *gc.C) {
   156  	s.AssertRunSucceeds(c,
   157  		`added subnet with ProviderId "foo" in space "myspace"\n`,
   158  		"", // empty stdout.
   159  		"foo", "myspace", "zone1", "zone2",
   160  	)
   161  
   162  	s.api.CheckCallNames(c, "AddSubnet", "Close")
   163  	s.api.CheckCall(c, 0, "AddSubnet",
   164  		names.SubnetTag{},
   165  		network.Id("foo"),
   166  		names.NewSpaceTag("myspace"),
   167  		s.Strings("zone1", "zone2"),
   168  	)
   169  }
   170  
   171  func (s *AddSuite) TestRunWithIPv6CIDRSucceeds(c *gc.C) {
   172  	s.AssertRunSucceeds(c,
   173  		`added subnet with CIDR "2001:db8::/32" in space "hyperspace"\n`,
   174  		"", // empty stdout.
   175  		"2001:db8::/32", "hyperspace",
   176  	)
   177  
   178  	s.api.CheckCallNames(c, "AddSubnet", "Close")
   179  	s.api.CheckCall(c, 0, "AddSubnet",
   180  		names.NewSubnetTag("2001:db8::/32"),
   181  		network.Id(""),
   182  		names.NewSpaceTag("hyperspace"),
   183  		[]string(nil),
   184  	)
   185  }
   186  
   187  func (s *AddSuite) TestRunWithExistingSubnetFails(c *gc.C) {
   188  	s.api.SetErrors(errors.AlreadyExistsf("subnet %q", "10.10.0.0/24"))
   189  
   190  	err := s.AssertRunFails(c,
   191  		`cannot add subnet: subnet "10.10.0.0/24" already exists`,
   192  		"10.10.0.0/24", "space",
   193  	)
   194  	c.Assert(err, jc.Satisfies, errors.IsAlreadyExists)
   195  
   196  	s.api.CheckCallNames(c, "AddSubnet", "Close")
   197  	s.api.CheckCall(c, 0, "AddSubnet",
   198  		names.NewSubnetTag("10.10.0.0/24"),
   199  		network.Id(""),
   200  		names.NewSpaceTag("space"),
   201  		[]string(nil),
   202  	)
   203  }
   204  
   205  func (s *AddSuite) TestRunWithNonExistingSpaceFails(c *gc.C) {
   206  	s.api.SetErrors(errors.NotFoundf("space %q", "space"))
   207  
   208  	err := s.AssertRunFails(c,
   209  		`cannot add subnet: space "space" not found`,
   210  		"10.10.0.0/24", "space", "zone1", "zone2",
   211  	)
   212  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   213  
   214  	s.api.CheckCallNames(c, "AddSubnet", "Close")
   215  	s.api.CheckCall(c, 0, "AddSubnet",
   216  		names.NewSubnetTag("10.10.0.0/24"),
   217  		network.Id(""),
   218  		names.NewSpaceTag("space"),
   219  		s.Strings("zone1", "zone2"),
   220  	)
   221  }
   222  
   223  func (s *AddSuite) TestRunUnauthorizedMentionsJujuGrant(c *gc.C) {
   224  	s.api.SetErrors(&params.Error{
   225  		Message: "permission denied",
   226  		Code:    params.CodeUnauthorized,
   227  	})
   228  	_, stderr, _ := s.RunCommand(c, "10.10.0.0/24", "myspace")
   229  	c.Assert(strings.Replace(stderr, "\n", " ", -1), gc.Matches, `.*juju grant.*`)
   230  }
   231  
   232  func (s *AddSuite) TestRunWithAmbiguousCIDRDisplaysError(c *gc.C) {
   233  	apiError := errors.New(`multiple subnets with CIDR "10.10.0.0/24" <snip>`)
   234  	s.api.SetErrors(apiError)
   235  
   236  	s.AssertRunSucceeds(c,
   237  		fmt.Sprintf("ERROR: %v.\n", apiError),
   238  		"",
   239  		"10.10.0.0/24", "space", "zone1", "zone2",
   240  	)
   241  
   242  	s.api.CheckCallNames(c, "AddSubnet", "Close")
   243  	s.api.CheckCall(c, 0, "AddSubnet",
   244  		names.NewSubnetTag("10.10.0.0/24"),
   245  		network.Id(""),
   246  		names.NewSpaceTag("space"),
   247  		s.Strings("zone1", "zone2"),
   248  	)
   249  }