github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/spaces/spaces_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package spaces_test 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/names" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/apiserver/common" 15 "github.com/juju/juju/apiserver/params" 16 "github.com/juju/juju/apiserver/spaces" 17 apiservertesting "github.com/juju/juju/apiserver/testing" 18 "github.com/juju/juju/network" 19 coretesting "github.com/juju/juju/testing" 20 ) 21 22 type SpacesSuite struct { 23 coretesting.BaseSuite 24 apiservertesting.StubNetwork 25 26 resources *common.Resources 27 authorizer apiservertesting.FakeAuthorizer 28 facade spaces.API 29 } 30 31 var _ = gc.Suite(&SpacesSuite{}) 32 33 func (s *SpacesSuite) SetUpSuite(c *gc.C) { 34 s.StubNetwork.SetUpSuite(c) 35 s.BaseSuite.SetUpSuite(c) 36 } 37 38 func (s *SpacesSuite) TearDownSuite(c *gc.C) { 39 s.BaseSuite.TearDownSuite(c) 40 } 41 42 func (s *SpacesSuite) SetUpTest(c *gc.C) { 43 s.BaseSuite.SetUpTest(c) 44 apiservertesting.BackingInstance.SetUp(c, apiservertesting.StubZonedNetworkingEnvironName, apiservertesting.WithZones, apiservertesting.WithSpaces, apiservertesting.WithSubnets) 45 46 s.resources = common.NewResources() 47 s.authorizer = apiservertesting.FakeAuthorizer{ 48 Tag: names.NewUserTag("admin"), 49 EnvironManager: false, 50 } 51 52 var err error 53 s.facade, err = spaces.NewAPIWithBacking( 54 apiservertesting.BackingInstance, s.resources, s.authorizer, 55 ) 56 c.Assert(err, jc.ErrorIsNil) 57 c.Assert(s.facade, gc.NotNil) 58 } 59 60 func (s *SpacesSuite) TearDownTest(c *gc.C) { 61 if s.resources != nil { 62 s.resources.StopAll() 63 } 64 s.BaseSuite.TearDownTest(c) 65 } 66 67 func (s *SpacesSuite) TestNewAPIWithBacking(c *gc.C) { 68 // Clients are allowed. 69 facade, err := spaces.NewAPIWithBacking( 70 apiservertesting.BackingInstance, s.resources, s.authorizer, 71 ) 72 c.Assert(err, jc.ErrorIsNil) 73 c.Assert(facade, gc.NotNil) 74 // No calls so far. 75 apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub) 76 77 // Agents are not allowed 78 agentAuthorizer := s.authorizer 79 agentAuthorizer.Tag = names.NewMachineTag("42") 80 facade, err = spaces.NewAPIWithBacking( 81 apiservertesting.BackingInstance, s.resources, agentAuthorizer, 82 ) 83 c.Assert(err, jc.DeepEquals, common.ErrPerm) 84 c.Assert(facade, gc.IsNil) 85 // No calls so far. 86 apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub) 87 } 88 89 type checkAddSpacesParams struct { 90 Name string 91 Subnets []string 92 Error string 93 MakesCall bool 94 Public bool 95 } 96 97 func (s *SpacesSuite) checkAddSpaces(c *gc.C, p checkAddSpacesParams) { 98 args := params.CreateSpaceParams{} 99 if p.Name != "" { 100 args.SpaceTag = "space-" + p.Name 101 } 102 if len(p.Subnets) > 0 { 103 for _, cidr := range p.Subnets { 104 args.SubnetTags = append(args.SubnetTags, "subnet-"+cidr) 105 } 106 } 107 args.Public = p.Public 108 109 spaces := params.CreateSpacesParams{} 110 spaces.Spaces = append(spaces.Spaces, args) 111 results, err := s.facade.CreateSpaces(spaces) 112 113 c.Assert(len(results.Results), gc.Equals, 1) 114 c.Assert(err, gc.IsNil) 115 if p.Error == "" { 116 c.Assert(results.Results[0].Error, gc.IsNil) 117 } else { 118 c.Assert(results.Results[0].Error, gc.NotNil) 119 c.Assert(results.Results[0].Error, gc.ErrorMatches, p.Error) 120 } 121 122 baseCalls := []apiservertesting.StubMethodCall{ 123 apiservertesting.BackingCall("ModelConfig"), 124 apiservertesting.ProviderCall("Open", apiservertesting.BackingInstance.EnvConfig), 125 apiservertesting.ZonedNetworkingEnvironCall("SupportsSpaces"), 126 } 127 128 // AddSpace from the api always uses an empty ProviderId. 129 addSpaceCalls := append(baseCalls, apiservertesting.BackingCall("AddSpace", p.Name, network.Id(""), p.Subnets, p.Public)) 130 131 if p.Error == "" || p.MakesCall { 132 apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub, addSpaceCalls...) 133 } else { 134 apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub, baseCalls...) 135 } 136 } 137 138 func (s *SpacesSuite) TestAddSpacesOneSubnet(c *gc.C) { 139 p := checkAddSpacesParams{ 140 Name: "foo", 141 Subnets: []string{"10.0.0.0/24"}, 142 } 143 s.checkAddSpaces(c, p) 144 } 145 146 func (s *SpacesSuite) TestAddSpacesTwoSubnets(c *gc.C) { 147 p := checkAddSpacesParams{ 148 Name: "foo", 149 Subnets: []string{"10.0.0.0/24", "10.0.1.0/24"}, 150 } 151 s.checkAddSpaces(c, p) 152 } 153 154 func (s *SpacesSuite) TestAddSpacesManySubnets(c *gc.C) { 155 p := checkAddSpacesParams{ 156 Name: "foo", 157 Subnets: []string{"10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24", 158 "10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"}, 159 } 160 s.checkAddSpaces(c, p) 161 } 162 163 func (s *SpacesSuite) TestAddSpacesAPIError(c *gc.C) { 164 apiservertesting.SharedStub.SetErrors( 165 nil, // Backing.ModelConfig() 166 nil, // Provider.Open() 167 nil, // ZonedNetworkingEnviron.SupportsSpaces() 168 errors.AlreadyExistsf("space-foo"), // Backing.AddSpace() 169 ) 170 p := checkAddSpacesParams{ 171 Name: "foo", 172 Subnets: []string{"10.0.0.0/24"}, 173 MakesCall: true, 174 Error: "space-foo already exists", 175 } 176 s.checkAddSpaces(c, p) 177 } 178 179 func (s *SpacesSuite) TestCreateInvalidSpace(c *gc.C) { 180 p := checkAddSpacesParams{ 181 Name: "-", 182 Subnets: []string{"10.0.0.0/24"}, 183 Error: `"space--" is not a valid space tag`, 184 } 185 s.checkAddSpaces(c, p) 186 } 187 188 func (s *SpacesSuite) TestCreateInvalidSubnet(c *gc.C) { 189 p := checkAddSpacesParams{ 190 Name: "foo", 191 Subnets: []string{"bar"}, 192 Error: `"subnet-bar" is not a valid subnet tag`, 193 } 194 s.checkAddSpaces(c, p) 195 } 196 197 func (s *SpacesSuite) TestPublic(c *gc.C) { 198 p := checkAddSpacesParams{ 199 Name: "foo", 200 Subnets: []string{"10.0.0.0/24"}, 201 Public: true, 202 } 203 s.checkAddSpaces(c, p) 204 } 205 206 func (s *SpacesSuite) TestEmptySpaceName(c *gc.C) { 207 p := checkAddSpacesParams{ 208 Subnets: []string{"10.0.0.0/24"}, 209 Error: `"" is not a valid tag`, 210 } 211 s.checkAddSpaces(c, p) 212 } 213 214 func (s *SpacesSuite) TestNoSubnets(c *gc.C) { 215 p := checkAddSpacesParams{ 216 Name: "foo", 217 Subnets: nil, 218 } 219 s.checkAddSpaces(c, p) 220 } 221 222 func (s *SpacesSuite) TestListSpacesDefault(c *gc.C) { 223 expected := []params.Space{{ 224 Name: "default", 225 Subnets: []params.Subnet{{ 226 CIDR: "192.168.0.0/24", 227 ProviderId: "provider-192.168.0.0/24", 228 Zones: []string{"foo"}, 229 Status: "in-use", 230 SpaceTag: "space-default", 231 }, { 232 CIDR: "192.168.3.0/24", 233 ProviderId: "provider-192.168.3.0/24", 234 VLANTag: 23, 235 Zones: []string{"bar", "bam"}, 236 SpaceTag: "space-default", 237 }}, 238 }, { 239 Name: "dmz", 240 Subnets: []params.Subnet{{ 241 CIDR: "192.168.1.0/24", 242 ProviderId: "provider-192.168.1.0/24", 243 VLANTag: 23, 244 Zones: []string{"bar", "bam"}, 245 SpaceTag: "space-dmz", 246 }}, 247 }, { 248 Name: "private", 249 Subnets: []params.Subnet{{ 250 CIDR: "192.168.2.0/24", 251 ProviderId: "provider-192.168.2.0/24", 252 Zones: []string{"foo"}, 253 Status: "in-use", 254 SpaceTag: "space-private", 255 }}, 256 }} 257 spaces, err := s.facade.ListSpaces() 258 c.Assert(err, jc.ErrorIsNil) 259 c.Assert(spaces.Results, jc.DeepEquals, expected) 260 } 261 262 func (s *SpacesSuite) TestListSpacesAllSpacesError(c *gc.C) { 263 boom := errors.New("backing boom") 264 apiservertesting.BackingInstance.SetErrors(boom) 265 _, err := s.facade.ListSpaces() 266 c.Assert(err, gc.ErrorMatches, "getting model config: backing boom") 267 } 268 269 func (s *SpacesSuite) TestListSpacesSubnetsError(c *gc.C) { 270 apiservertesting.SharedStub.SetErrors( 271 nil, // Backing.ModelConfig() 272 nil, // Provider.Open() 273 nil, // ZonedNetworkingEnviron.SupportsSpaces() 274 nil, // Backing.AllSpaces() 275 errors.New("space0 subnets failed"), // Space.Subnets() 276 errors.New("space1 subnets failed"), // Space.Subnets() 277 errors.New("space2 subnets failed"), // Space.Subnets() 278 ) 279 280 results, err := s.facade.ListSpaces() 281 for i, space := range results.Results { 282 errmsg := fmt.Sprintf("fetching subnets: space%d subnets failed", i) 283 c.Assert(space.Error, gc.ErrorMatches, errmsg) 284 } 285 c.Assert(err, jc.ErrorIsNil) 286 } 287 288 func (s *SpacesSuite) TestListSpacesSubnetsSingleSubnetError(c *gc.C) { 289 boom := errors.New("boom") 290 apiservertesting.SharedStub.SetErrors( 291 nil, // Backing.ModelConfig() 292 nil, // Provider.Open() 293 nil, // ZonedNetworkingEnviron.SupportsSpaces() 294 nil, // Backing.AllSpaces() 295 nil, // Space.Subnets() (1st no error) 296 boom, // Space.Subnets() (2nd with error) 297 ) 298 299 results, err := s.facade.ListSpaces() 300 for i, space := range results.Results { 301 if i == 1 { 302 c.Assert(space.Error, gc.ErrorMatches, "fetching subnets: boom") 303 } else { 304 c.Assert(space.Error, gc.IsNil) 305 } 306 } 307 c.Assert(err, jc.ErrorIsNil) 308 } 309 310 func (s *SpacesSuite) TestCreateSpacesModelConfigError(c *gc.C) { 311 apiservertesting.SharedStub.SetErrors( 312 errors.New("boom"), // Backing.ModelConfig() 313 ) 314 315 spaces := params.CreateSpacesParams{} 316 _, err := s.facade.CreateSpaces(spaces) 317 c.Assert(err, gc.ErrorMatches, "getting model config: boom") 318 } 319 320 func (s *SpacesSuite) TestCreateSpacesProviderOpenError(c *gc.C) { 321 apiservertesting.SharedStub.SetErrors( 322 nil, // Backing.ModelConfig() 323 errors.New("boom"), // Provider.Open() 324 ) 325 326 spaces := params.CreateSpacesParams{} 327 _, err := s.facade.CreateSpaces(spaces) 328 c.Assert(err, gc.ErrorMatches, "validating model config: boom") 329 } 330 331 func (s *SpacesSuite) TestCreateSpacesNotSupportedError(c *gc.C) { 332 apiservertesting.SharedStub.SetErrors( 333 nil, // Backing.ModelConfig() 334 nil, // Provider.Open() 335 errors.NotSupportedf("spaces"), // ZonedNetworkingEnviron.SupportsSpaces() 336 ) 337 338 spaces := params.CreateSpacesParams{} 339 _, err := s.facade.CreateSpaces(spaces) 340 c.Assert(err, gc.ErrorMatches, "spaces not supported") 341 } 342 343 func (s *SpacesSuite) TestListSpacesNotSupportedError(c *gc.C) { 344 apiservertesting.SharedStub.SetErrors( 345 nil, // Backing.ModelConfig() 346 nil, // Provider.Open 347 errors.NotSupportedf("spaces"), // ZonedNetworkingEnviron.SupportsSpaces() 348 ) 349 350 _, err := s.facade.ListSpaces() 351 c.Assert(err, gc.ErrorMatches, "spaces not supported") 352 }