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(¶ms.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 }