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 }