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 }