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