github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/subnet/create_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  	"github.com/juju/errors"
     8  	"github.com/juju/names"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/cmd/juju/subnet"
    13  	"github.com/juju/juju/feature"
    14  	coretesting "github.com/juju/juju/testing"
    15  )
    16  
    17  type CreateSuite struct {
    18  	BaseSubnetSuite
    19  }
    20  
    21  var _ = gc.Suite(&CreateSuite{})
    22  
    23  func (s *CreateSuite) SetUpTest(c *gc.C) {
    24  	s.BaseSuite.SetFeatureFlags(feature.PostNetCLIMVP)
    25  	s.BaseSubnetSuite.SetUpTest(c)
    26  	s.command, _ = subnet.NewCreateCommandForTest(s.api)
    27  	c.Assert(s.command, gc.NotNil)
    28  }
    29  
    30  func (s *CreateSuite) TestInit(c *gc.C) {
    31  	for i, test := range []struct {
    32  		about         string
    33  		args          []string
    34  		expectCIDR    string
    35  		expectSpace   string
    36  		expectZones   []string
    37  		expectPublic  bool
    38  		expectPrivate bool
    39  		expectErr     string
    40  	}{{
    41  		about:         "no arguments",
    42  		expectErr:     "CIDR is required",
    43  		expectPrivate: true,
    44  	}, {
    45  		about:         "only a subnet argument (invalid)",
    46  		args:          s.Strings("foo"),
    47  		expectPrivate: true,
    48  		expectErr:     "space name is required",
    49  	}, {
    50  		about:         "no zone arguments (both CIDR and space are invalid)",
    51  		args:          s.Strings("foo", "%invalid"),
    52  		expectPrivate: true,
    53  		expectErr:     "at least one zone is required",
    54  	}, {
    55  		about:         "invalid CIDR",
    56  		args:          s.Strings("foo", "space", "zone"),
    57  		expectPrivate: true,
    58  		expectErr:     `"foo" is not a valid CIDR`,
    59  	}, {
    60  		about:         "incorrectly specified CIDR",
    61  		args:          s.Strings("5.4.3.2/10", "space", "zone"),
    62  		expectPrivate: true,
    63  		expectErr:     `"5.4.3.2/10" is not correctly specified, expected "5.0.0.0/10"`,
    64  	}, {
    65  		about:         "invalid space name",
    66  		args:          s.Strings("10.10.0.0/24", "%inv$alid", "zone"),
    67  		expectCIDR:    "10.10.0.0/24",
    68  		expectPrivate: true,
    69  		expectErr:     `"%inv\$alid" is not a valid space name`,
    70  	}, {
    71  		about:         "duplicate zones specified",
    72  		args:          s.Strings("10.10.0.0/24", "myspace", "zone1", "zone2", "zone1"),
    73  		expectCIDR:    "10.10.0.0/24",
    74  		expectSpace:   "myspace",
    75  		expectZones:   s.Strings("zone1", "zone2"),
    76  		expectPrivate: true,
    77  		expectErr:     `duplicate zone "zone1" specified`,
    78  	}, {
    79  		about:         "both --public and --private specified",
    80  		args:          s.Strings("10.1.0.0/16", "new-space", "zone", "--public", "--private"),
    81  		expectCIDR:    "10.1.0.0/16",
    82  		expectSpace:   "new-space",
    83  		expectZones:   s.Strings("zone"),
    84  		expectErr:     `cannot specify both --public and --private`,
    85  		expectPublic:  true,
    86  		expectPrivate: true,
    87  	}, {
    88  		about:         "--public specified",
    89  		args:          s.Strings("10.1.0.0/16", "new-space", "zone", "--public"),
    90  		expectCIDR:    "10.1.0.0/16",
    91  		expectSpace:   "new-space",
    92  		expectZones:   s.Strings("zone"),
    93  		expectPublic:  true,
    94  		expectPrivate: false,
    95  		expectErr:     "",
    96  	}, {
    97  		about:         "--private explicitly specified",
    98  		args:          s.Strings("10.1.0.0/16", "new-space", "zone", "--private"),
    99  		expectCIDR:    "10.1.0.0/16",
   100  		expectSpace:   "new-space",
   101  		expectZones:   s.Strings("zone"),
   102  		expectPublic:  false,
   103  		expectPrivate: true,
   104  		expectErr:     "",
   105  	}, {
   106  		about:         "--private specified out of order",
   107  		args:          s.Strings("2001:db8::/32", "--private", "space", "zone"),
   108  		expectCIDR:    "2001:db8::/32",
   109  		expectSpace:   "space",
   110  		expectZones:   s.Strings("zone"),
   111  		expectPublic:  false,
   112  		expectPrivate: true,
   113  		expectErr:     "",
   114  	}, {
   115  		about:         "--public specified twice",
   116  		args:          s.Strings("--public", "2001:db8::/32", "--public", "space", "zone"),
   117  		expectCIDR:    "2001:db8::/32",
   118  		expectSpace:   "space",
   119  		expectZones:   s.Strings("zone"),
   120  		expectPublic:  true,
   121  		expectPrivate: false,
   122  		expectErr:     "",
   123  	}} {
   124  		c.Logf("test #%d: %s", i, test.about)
   125  		// Create a new instance of the subcommand for each test, but
   126  		// since we're not running the command no need to use
   127  		// modelcmd.Wrap().
   128  		wrappedCommand, command := subnet.NewCreateCommandForTest(s.api)
   129  		err := coretesting.InitCommand(wrappedCommand, test.args)
   130  		if test.expectErr != "" {
   131  			c.Check(err, gc.ErrorMatches, test.expectErr)
   132  		} else {
   133  			c.Check(err, jc.ErrorIsNil)
   134  			c.Check(command.CIDR.Id(), gc.Equals, test.expectCIDR)
   135  			c.Check(command.Space.Id(), gc.Equals, test.expectSpace)
   136  			c.Check(command.Zones.SortedValues(), jc.DeepEquals, test.expectZones)
   137  			c.Check(command.IsPublic, gc.Equals, test.expectPublic)
   138  			c.Check(command.IsPrivate, gc.Equals, test.expectPrivate)
   139  		}
   140  		// No API calls should be recorded at this stage.
   141  		s.api.CheckCallNames(c)
   142  	}
   143  }
   144  
   145  func (s *CreateSuite) TestRunOneZoneSucceeds(c *gc.C) {
   146  	s.AssertRunSucceeds(c,
   147  		`created a private subnet "10.20.0.0/24" in space "myspace" with zones zone1\n`,
   148  		"", // empty stdout.
   149  		"10.20.0.0/24", "myspace", "zone1",
   150  	)
   151  
   152  	s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close")
   153  	s.api.CheckCall(c, 1, "CreateSubnet",
   154  		names.NewSubnetTag("10.20.0.0/24"), names.NewSpaceTag("myspace"), s.Strings("zone1"), false,
   155  	)
   156  }
   157  
   158  func (s *CreateSuite) TestRunWithPublicAndIPv6CIDRSucceeds(c *gc.C) {
   159  	s.AssertRunSucceeds(c,
   160  		`created a public subnet "2001:db8::/32" in space "space" with zones zone1\n`,
   161  		"", // empty stdout.
   162  		"2001:db8::/32", "space", "zone1", "--public",
   163  	)
   164  
   165  	s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close")
   166  	s.api.CheckCall(c, 1, "CreateSubnet",
   167  		names.NewSubnetTag("2001:db8::/32"), names.NewSpaceTag("space"), s.Strings("zone1"), true,
   168  	)
   169  }
   170  
   171  func (s *CreateSuite) TestRunWithMultipleZonesSucceeds(c *gc.C) {
   172  	s.AssertRunSucceeds(c,
   173  		// The list of zones is sorted both when displayed and passed
   174  		// to CreateSubnet.
   175  		`created a private subnet "10.20.0.0/24" in space "foo" with zones zone1, zone2\n`,
   176  		"",                                      // empty stdout.
   177  		"10.20.0.0/24", "foo", "zone2", "zone1", // unsorted zones
   178  	)
   179  
   180  	s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close")
   181  	s.api.CheckCall(c, 1, "CreateSubnet",
   182  		names.NewSubnetTag("10.20.0.0/24"), names.NewSpaceTag("foo"), s.Strings("zone1", "zone2"), false,
   183  	)
   184  }
   185  
   186  func (s *CreateSuite) TestRunWithAllZonesErrorFails(c *gc.C) {
   187  	s.api.SetErrors(errors.New("boom"))
   188  
   189  	s.AssertRunFails(c,
   190  		`cannot fetch availability zones: boom`,
   191  		"10.10.0.0/24", "space", "zone1",
   192  	)
   193  	s.api.CheckCallNames(c, "AllZones", "Close")
   194  }
   195  
   196  func (s *CreateSuite) TestRunWithExistingSubnetFails(c *gc.C) {
   197  	s.api.SetErrors(nil, errors.AlreadyExistsf("subnet %q", "10.10.0.0/24"))
   198  
   199  	err := s.AssertRunFails(c,
   200  		`cannot create subnet "10.10.0.0/24": subnet "10.10.0.0/24" already exists`,
   201  		"10.10.0.0/24", "space", "zone1",
   202  	)
   203  	c.Assert(err, jc.Satisfies, errors.IsAlreadyExists)
   204  
   205  	s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close")
   206  	s.api.CheckCall(c, 1, "CreateSubnet",
   207  		names.NewSubnetTag("10.10.0.0/24"), names.NewSpaceTag("space"), s.Strings("zone1"), false,
   208  	)
   209  }
   210  
   211  func (s *CreateSuite) TestRunWithNonExistingSpaceFails(c *gc.C) {
   212  	s.api.SetErrors(nil, errors.NotFoundf("space %q", "space"))
   213  
   214  	err := s.AssertRunFails(c,
   215  		`cannot create subnet "10.10.0.0/24": space "space" not found`,
   216  		"10.10.0.0/24", "space", "zone1",
   217  	)
   218  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   219  
   220  	s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close")
   221  	s.api.CheckCall(c, 1, "CreateSubnet",
   222  		names.NewSubnetTag("10.10.0.0/24"), names.NewSpaceTag("space"), s.Strings("zone1"), false,
   223  	)
   224  }
   225  
   226  func (s *CreateSuite) TestRunWithUnknownZonesFails(c *gc.C) {
   227  	s.AssertRunFails(c,
   228  		// The list of unknown zones is sorted.
   229  		"unknown zones specified: foo, no-zone",
   230  		"10.30.30.0/24", "space", "no-zone", "zone1", "foo",
   231  	)
   232  
   233  	s.api.CheckCallNames(c, "AllZones", "Close")
   234  }