github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/spaces_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state_test 5 6 import ( 7 "fmt" 8 "net" 9 10 "github.com/juju/errors" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/network" 15 "github.com/juju/juju/state" 16 ) 17 18 type SpacesSuite struct { 19 ConnSuite 20 } 21 22 var _ = gc.Suite(&SpacesSuite{}) 23 24 func (s *SpacesSuite) addSubnets(c *gc.C, CIDRs []string) { 25 s.addSubnetsForState(c, CIDRs, s.State) 26 } 27 28 func (s *SpacesSuite) addSubnetsForState(c *gc.C, CIDRs []string, st *state.State) { 29 if len(CIDRs) == 0 { 30 return 31 } 32 for _, info := range s.makeSubnetInfosForCIDRs(c, CIDRs) { 33 _, err := st.AddSubnet(info) 34 c.Assert(err, jc.ErrorIsNil) 35 } 36 } 37 38 func (s *SpacesSuite) makeSubnetInfosForCIDRs(c *gc.C, CIDRs []string) []state.SubnetInfo { 39 infos := make([]state.SubnetInfo, len(CIDRs)) 40 for i, cidr := range CIDRs { 41 _, _, err := net.ParseCIDR(cidr) 42 c.Assert(err, jc.ErrorIsNil) 43 44 infos[i] = state.SubnetInfo{ 45 CIDR: cidr, 46 VLANTag: 79, 47 AvailabilityZone: "AvailabilityZone", 48 } 49 50 } 51 return infos 52 } 53 54 type addSpaceArgs struct { 55 Name string 56 ProviderId network.Id 57 SubnetCIDRs []string 58 IsPublic bool 59 ForState *state.State 60 } 61 62 func (s *SpacesSuite) addSpaceWithSubnets(c *gc.C, args addSpaceArgs) (*state.Space, error) { 63 if args.ForState == nil { 64 args.ForState = s.State 65 } 66 s.addSubnetsForState(c, args.SubnetCIDRs, args.ForState) 67 return args.ForState.AddSpace(args.Name, args.ProviderId, args.SubnetCIDRs, args.IsPublic) 68 } 69 70 func (s *SpacesSuite) assertSpaceNotFound(c *gc.C, name string) { 71 s.assertSpaceNotFoundForState(c, name, s.State) 72 } 73 74 func (s *SpacesSuite) assertSpaceNotFoundForState(c *gc.C, name string, st *state.State) { 75 _, err := st.Space(name) 76 s.assertSpaceNotFoundError(c, err, name) 77 } 78 79 func (s *SpacesSuite) assertSpaceNotFoundError(c *gc.C, err error, name string) { 80 c.Assert(err, gc.ErrorMatches, fmt.Sprintf("space %q not found", name)) 81 82 c.Assert(err, jc.Satisfies, errors.IsNotFound) 83 } 84 85 func (s *SpacesSuite) assertSpaceMatchesArgs(c *gc.C, space *state.Space, args addSpaceArgs) { 86 c.Assert(space.Name(), gc.Equals, args.Name) 87 c.Assert(space.ProviderId(), gc.Equals, args.ProviderId) 88 89 actualSubnets, err := space.Subnets() 90 c.Assert(err, jc.ErrorIsNil) 91 actualSubnetIds := make([]string, len(actualSubnets)) 92 for i, subnet := range actualSubnets { 93 actualSubnetIds[i] = subnet.CIDR() 94 } 95 c.Assert(actualSubnetIds, jc.SameContents, args.SubnetCIDRs) 96 c.Assert(state.SpaceDoc(space).IsPublic, gc.Equals, args.IsPublic) 97 98 c.Assert(space.Life(), gc.Equals, state.Alive) 99 c.Assert(space.String(), gc.Equals, args.Name) 100 } 101 102 func (s *SpacesSuite) TestAddSpaceWithNoSubnetsAndEmptyProviderId(c *gc.C) { 103 args := addSpaceArgs{ 104 Name: "my-space", 105 ProviderId: "", 106 SubnetCIDRs: nil, 107 } 108 space, err := s.addSpaceWithSubnets(c, args) 109 c.Assert(err, jc.ErrorIsNil) 110 s.assertSpaceMatchesArgs(c, space, args) 111 112 } 113 114 func (s *SpacesSuite) TestAddSpaceWithNoSubnetsAndNonEmptyProviderId(c *gc.C) { 115 args := addSpaceArgs{ 116 Name: "my-space", 117 ProviderId: network.Id("my provider id"), 118 SubnetCIDRs: nil, 119 } 120 space, err := s.addSpaceWithSubnets(c, args) 121 c.Assert(err, jc.ErrorIsNil) 122 s.assertSpaceMatchesArgs(c, space, args) 123 } 124 125 func (s *SpacesSuite) TestAddSpaceWithOneIPv4SubnetAndEmptyProviderId(c *gc.C) { 126 args := addSpaceArgs{ 127 Name: "my-space", 128 ProviderId: "", 129 SubnetCIDRs: []string{"1.1.1.0/24"}, 130 } 131 space, err := s.addSpaceWithSubnets(c, args) 132 c.Assert(err, jc.ErrorIsNil) 133 s.assertSpaceMatchesArgs(c, space, args) 134 } 135 136 func (s *SpacesSuite) TestAddSpaceWithOneIPv4SubnetAndNonEmptyProviderId(c *gc.C) { 137 args := addSpaceArgs{ 138 Name: "my-space", 139 ProviderId: network.Id("some id"), 140 SubnetCIDRs: []string{"1.1.1.0/24"}, 141 } 142 space, err := s.addSpaceWithSubnets(c, args) 143 c.Assert(err, jc.ErrorIsNil) 144 s.assertSpaceMatchesArgs(c, space, args) 145 } 146 147 func (s *SpacesSuite) TestAddSpaceWithOneIPv6SubnetAndEmptyProviderId(c *gc.C) { 148 args := addSpaceArgs{ 149 Name: "my-space", 150 ProviderId: "", 151 SubnetCIDRs: []string{"fc00:123::/64"}, 152 } 153 space, err := s.addSpaceWithSubnets(c, args) 154 c.Assert(err, jc.ErrorIsNil) 155 s.assertSpaceMatchesArgs(c, space, args) 156 } 157 158 func (s *SpacesSuite) TestAddSpaceWithOneIPv6SubnetAndNonEmptyProviderId(c *gc.C) { 159 args := addSpaceArgs{ 160 Name: "my-space", 161 ProviderId: network.Id("provider id"), 162 SubnetCIDRs: []string{"fc00:123::/64"}, 163 } 164 space, err := s.addSpaceWithSubnets(c, args) 165 c.Assert(err, jc.ErrorIsNil) 166 s.assertSpaceMatchesArgs(c, space, args) 167 } 168 169 func (s *SpacesSuite) TestAddSpaceWithOneIPv4AndOneIPv6SubnetAndEmptyProviderId(c *gc.C) { 170 args := addSpaceArgs{ 171 Name: "my-space", 172 ProviderId: "", 173 SubnetCIDRs: []string{"1.1.1.0/24", "fc00::123/64"}, 174 } 175 space, err := s.addSpaceWithSubnets(c, args) 176 c.Assert(err, jc.ErrorIsNil) 177 s.assertSpaceMatchesArgs(c, space, args) 178 } 179 180 func (s *SpacesSuite) TestAddSpaceWithOneIPv4AndOneIPv6SubnetAndNonEmptyProviderId(c *gc.C) { 181 args := addSpaceArgs{ 182 Name: "my-space", 183 ProviderId: network.Id("foo bar"), 184 SubnetCIDRs: []string{"1.1.1.0/24", "fc00::123/64"}, 185 } 186 space, err := s.addSpaceWithSubnets(c, args) 187 c.Assert(err, jc.ErrorIsNil) 188 s.assertSpaceMatchesArgs(c, space, args) 189 } 190 191 func (s *SpacesSuite) TestAddSpaceWithMultipleIPv4SubnetsAndEmptyProviderId(c *gc.C) { 192 args := addSpaceArgs{ 193 Name: "my-space", 194 ProviderId: "", 195 SubnetCIDRs: []string{"1.1.1.0/24", "1.2.2.0/24"}, 196 } 197 space, err := s.addSpaceWithSubnets(c, args) 198 c.Assert(err, jc.ErrorIsNil) 199 s.assertSpaceMatchesArgs(c, space, args) 200 } 201 202 func (s *SpacesSuite) TestAddSpaceWithMultipleIPv4SubnetsAndNonEmptyProviderId(c *gc.C) { 203 args := addSpaceArgs{ 204 Name: "my-space", 205 ProviderId: network.Id("My Provider ID"), 206 SubnetCIDRs: []string{"1.1.1.0/24", "1.2.2.0/24"}, 207 } 208 space, err := s.addSpaceWithSubnets(c, args) 209 c.Assert(err, jc.ErrorIsNil) 210 s.assertSpaceMatchesArgs(c, space, args) 211 } 212 213 func (s *SpacesSuite) TestAddSpaceWithMultipleIPv6SubnetsAndEmptyProviderId(c *gc.C) { 214 args := addSpaceArgs{ 215 Name: "my-space", 216 ProviderId: "", 217 SubnetCIDRs: []string{"fc00:123::/64", "fc00:321::/64"}, 218 } 219 space, err := s.addSpaceWithSubnets(c, args) 220 c.Assert(err, jc.ErrorIsNil) 221 s.assertSpaceMatchesArgs(c, space, args) 222 } 223 224 func (s *SpacesSuite) TestAddSpaceWithMultipleIPv6SubnetsAndNonEmptyProviderId(c *gc.C) { 225 args := addSpaceArgs{ 226 Name: "my-space", 227 ProviderId: network.Id("My Provider ID"), 228 SubnetCIDRs: []string{"fc00:123::/64", "fc00:321::/64"}, 229 } 230 space, err := s.addSpaceWithSubnets(c, args) 231 232 c.Assert(err, jc.ErrorIsNil) 233 s.assertSpaceMatchesArgs(c, space, args) 234 } 235 236 func (s *SpacesSuite) TestAddSpaceWithMultipleIPv4AndIPv6SubnetsAndEmptyProviderId(c *gc.C) { 237 args := addSpaceArgs{ 238 Name: "my-space", 239 ProviderId: "", 240 SubnetCIDRs: []string{"fc00:123::/64", "2.2.2.0/20", "fc00:321::/64", "1.1.1.0/24"}, 241 } 242 space, err := s.addSpaceWithSubnets(c, args) 243 244 c.Assert(err, jc.ErrorIsNil) 245 s.assertSpaceMatchesArgs(c, space, args) 246 247 } 248 249 func (s *SpacesSuite) TestAddSpaceWithMultipleIPv4AndIPv6SubnetsAndNonEmptyProviderId(c *gc.C) { 250 args := addSpaceArgs{ 251 Name: "my-space", 252 ProviderId: network.Id("My Provider ID"), 253 SubnetCIDRs: []string{"fc00:123::/64", "2.2.2.0/20", "fc00:321::/64", "1.1.1.0/24"}, 254 } 255 space, err := s.addSpaceWithSubnets(c, args) 256 c.Assert(err, jc.ErrorIsNil) 257 s.assertSpaceMatchesArgs(c, space, args) 258 } 259 260 func (s *SpacesSuite) addTwoSpacesReturnSecond(c *gc.C, args1, args2 addSpaceArgs) (*state.Space, error) { 261 space1, err := s.addSpaceWithSubnets(c, args1) 262 263 c.Assert(err, jc.ErrorIsNil) 264 s.assertSpaceMatchesArgs(c, space1, args1) 265 266 return s.addSpaceWithSubnets(c, args2) 267 } 268 269 func (s *SpacesSuite) TestAddTwoSpacesWithDifferentNamesButSameProviderIdFailsInSameModel(c *gc.C) { 270 args1 := addSpaceArgs{ 271 Name: "my-space", 272 ProviderId: network.Id("provider id"), 273 } 274 args2 := args1 275 args2.Name = "different" 276 277 _, err := s.addTwoSpacesReturnSecond(c, args1, args2) 278 s.assertProviderIdNotUniqueErrorForArgs(c, err, args2) 279 } 280 281 func (s *SpacesSuite) assertProviderIdNotUniqueErrorForArgs(c *gc.C, err error, args addSpaceArgs) { 282 expectedError := fmt.Sprintf("adding space %q: ProviderId %q not unique", args.Name, args.ProviderId) 283 c.Assert(err, gc.ErrorMatches, expectedError) 284 } 285 286 func (s *SpacesSuite) TestAddTwoSpacesWithDifferentNamesButSameProviderIdSucceedsInDifferentModels(c *gc.C) { 287 args1 := addSpaceArgs{ 288 Name: "my-space", 289 ProviderId: network.Id("provider id"), 290 ForState: s.State, 291 } 292 args2 := args1 293 args2.Name = "different" 294 args2.ForState = s.NewStateForModelNamed(c, "other") 295 296 space2, err := s.addTwoSpacesReturnSecond(c, args1, args2) 297 298 c.Assert(err, jc.ErrorIsNil) 299 s.assertSpaceMatchesArgs(c, space2, args2) 300 } 301 302 func (s *SpacesSuite) TestAddTwoSpacesWithDifferentNamesAndEmptyProviderIdSucceedsInSameModel(c *gc.C) { 303 args1 := addSpaceArgs{ 304 Name: "my-space", 305 ProviderId: "", 306 } 307 args2 := args1 308 args2.Name = "different" 309 310 space2, err := s.addTwoSpacesReturnSecond(c, args1, args2) 311 c.Assert(err, jc.ErrorIsNil) 312 s.assertSpaceMatchesArgs(c, space2, args2) 313 } 314 315 func (s *SpacesSuite) TestAddTwoSpacesWithDifferentNamesAndEmptyProviderIdSucceedsInDifferentModels(c *gc.C) { 316 args1 := addSpaceArgs{ 317 Name: "my-space", 318 ProviderId: "", 319 ForState: s.State, 320 } 321 args2 := args1 322 args2.Name = "different" 323 args2.ForState = s.NewStateForModelNamed(c, "other") 324 325 space2, err := s.addTwoSpacesReturnSecond(c, args1, args2) 326 327 c.Assert(err, jc.ErrorIsNil) 328 s.assertSpaceMatchesArgs(c, space2, args2) 329 } 330 331 func (s *SpacesSuite) TestAddTwoSpacesWithSameNamesAndEmptyProviderIdsFailsInSameModel(c *gc.C) { 332 args := addSpaceArgs{ 333 Name: "my-space", 334 ProviderId: "", 335 } 336 337 _, err := s.addTwoSpacesReturnSecond(c, args, args) 338 s.assertSpaceAlreadyExistsErrorForArgs(c, err, args) 339 } 340 341 func (s *SpacesSuite) assertSpaceAlreadyExistsErrorForArgs(c *gc.C, err error, args addSpaceArgs) { 342 expectedError := fmt.Sprintf("adding space %q: space %q already exists", args.Name, args.Name) 343 c.Assert(err, gc.ErrorMatches, expectedError) 344 c.Assert(err, jc.Satisfies, errors.IsAlreadyExists) 345 } 346 347 func (s *SpacesSuite) TestAddTwoSpacesWithSameNamesAndProviderIdsFailsInTheSameModel(c *gc.C) { 348 args := addSpaceArgs{ 349 Name: "my-space", 350 ProviderId: network.Id("does not matter if not empty"), 351 } 352 353 _, err := s.addTwoSpacesReturnSecond(c, args, args) 354 s.assertSpaceAlreadyExistsErrorForArgs(c, err, args) 355 } 356 357 func (s *SpacesSuite) TestAddTwoSpacesWithSameNamesAndEmptyProviderIdsSuccedsInDifferentModels(c *gc.C) { 358 args1 := addSpaceArgs{ 359 Name: "my-space", 360 ProviderId: "", 361 ForState: s.State, 362 } 363 args2 := args1 364 args2.ForState = s.NewStateForModelNamed(c, "other") 365 366 space2, err := s.addTwoSpacesReturnSecond(c, args1, args2) 367 c.Assert(err, jc.ErrorIsNil) 368 s.assertSpaceMatchesArgs(c, space2, args2) 369 } 370 371 func (s *SpacesSuite) TestAddTwoSpacesWithSameNamesAndProviderIdsSuccedsInDifferentModels(c *gc.C) { 372 args1 := addSpaceArgs{ 373 Name: "my-space", 374 ProviderId: network.Id("same provider id"), 375 ForState: s.State, 376 } 377 args2 := args1 378 args2.ForState = s.NewStateForModelNamed(c, "other") 379 380 space2, err := s.addTwoSpacesReturnSecond(c, args1, args2) 381 c.Assert(err, jc.ErrorIsNil) 382 s.assertSpaceMatchesArgs(c, space2, args2) 383 } 384 385 func (s *SpacesSuite) TestAddSpaceWhenSubnetNotFound(c *gc.C) { 386 name := "my-space" 387 subnets := []string{"1.1.1.0/24"} 388 isPublic := false 389 390 _, err := s.State.AddSpace(name, "", subnets, isPublic) 391 c.Assert(err, gc.ErrorMatches, `adding space "my-space": subnet "1.1.1.0/24" not found`) 392 s.assertSpaceNotFound(c, name) 393 } 394 395 func (s *SpacesSuite) TestAddSpaceWithNonEmptyProviderIdAndInvalidNameFails(c *gc.C) { 396 args := addSpaceArgs{ 397 Name: "-bad name-", 398 ProviderId: network.Id("My Provider ID"), 399 } 400 _, err := s.addSpaceWithSubnets(c, args) 401 s.assertInvalidSpaceNameErrorAndWasNotAdded(c, err, args.Name) 402 } 403 404 func (s *SpacesSuite) assertInvalidSpaceNameErrorAndWasNotAdded(c *gc.C, err error, name string) { 405 expectedError := fmt.Sprintf("adding space %q: invalid space name", name) 406 c.Assert(err, gc.ErrorMatches, expectedError) 407 s.assertSpaceNotFound(c, name) 408 } 409 410 func (s *SpacesSuite) TestAddSpaceWithEmptyProviderIdAndInvalidNameFails(c *gc.C) { 411 args := addSpaceArgs{ 412 Name: "-bad name-", 413 ProviderId: "", 414 } 415 _, err := s.addSpaceWithSubnets(c, args) 416 s.assertInvalidSpaceNameErrorAndWasNotAdded(c, err, args.Name) 417 } 418 419 func (s *SpacesSuite) TestAddSpaceWithEmptyNameAndProviderIdFails(c *gc.C) { 420 args := addSpaceArgs{ 421 Name: "", 422 ProviderId: "", 423 } 424 _, err := s.addSpaceWithSubnets(c, args) 425 s.assertInvalidSpaceNameErrorAndWasNotAdded(c, err, args.Name) 426 } 427 428 func (s *SpacesSuite) TestAddSpaceWithEmptyNameAndNonEmptyProviderIdFails(c *gc.C) { 429 args := addSpaceArgs{ 430 Name: "", 431 ProviderId: network.Id("doesn't matter"), 432 } 433 _, err := s.addSpaceWithSubnets(c, args) 434 s.assertInvalidSpaceNameErrorAndWasNotAdded(c, err, args.Name) 435 } 436 437 func (s *SpacesSuite) TestSubnetsReturnsExpectedSubnets(c *gc.C) { 438 args := addSpaceArgs{ 439 Name: "my-space", 440 SubnetCIDRs: []string{"1.1.1.0/24", "2.1.1.0/24", "3.1.1.0/24", "4.1.1.0/24", "5.1.1.0/24"}, 441 } 442 space, err := s.addSpaceWithSubnets(c, args) 443 c.Assert(err, jc.ErrorIsNil) 444 445 expected := []*state.Subnet{} 446 for _, cidr := range args.SubnetCIDRs { 447 subnet, err := s.State.Subnet(cidr) 448 c.Assert(err, jc.ErrorIsNil) 449 expected = append(expected, subnet) 450 } 451 actual, err := space.Subnets() 452 c.Assert(err, jc.ErrorIsNil) 453 c.Assert(actual, jc.DeepEquals, expected) 454 } 455 456 func (s *SpacesSuite) TestAllSpaces(c *gc.C) { 457 spaces, err := s.State.AllSpaces() 458 c.Assert(err, jc.ErrorIsNil) 459 c.Assert(spaces, jc.DeepEquals, []*state.Space{}) 460 461 subnets := []string{"1.1.1.0/24", "2.1.1.0/24", "3.1.1.0/24"} 462 isPublic := false 463 s.addSubnets(c, subnets) 464 465 first, err := s.State.AddSpace("first", "", []string{"1.1.1.0/24"}, isPublic) 466 c.Assert(err, jc.ErrorIsNil) 467 second, err := s.State.AddSpace("second", "", []string{"2.1.1.0/24"}, isPublic) 468 c.Assert(err, jc.ErrorIsNil) 469 third, err := s.State.AddSpace("third", "", []string{"3.1.1.0/24"}, isPublic) 470 c.Assert(err, jc.ErrorIsNil) 471 472 actual, err := s.State.AllSpaces() 473 c.Assert(err, jc.ErrorIsNil) 474 c.Assert(actual, jc.SameContents, []*state.Space{first, second, third}) 475 } 476 477 func (s *SpacesSuite) TestEnsureDeadSetsLifeToDeadWhenAlive(c *gc.C) { 478 space := s.addAliveSpace(c, "alive") 479 480 s.ensureDeadAndAssertLifeIsDead(c, space) 481 s.refreshAndAssertSpaceLifeIs(c, space, state.Dead) 482 } 483 484 func (s *SpacesSuite) addAliveSpace(c *gc.C, name string) *state.Space { 485 space, err := s.State.AddSpace(name, "", nil, false) 486 c.Assert(err, jc.ErrorIsNil) 487 c.Assert(space.Life(), gc.Equals, state.Alive) 488 return space 489 } 490 491 func (s *SpacesSuite) ensureDeadAndAssertLifeIsDead(c *gc.C, space *state.Space) { 492 err := space.EnsureDead() 493 c.Assert(err, jc.ErrorIsNil) 494 c.Assert(space.Life(), gc.Equals, state.Dead) 495 } 496 497 func (s *SpacesSuite) refreshAndAssertSpaceLifeIs(c *gc.C, space *state.Space, expectedLife state.Life) { 498 err := space.Refresh() 499 c.Assert(err, jc.ErrorIsNil) 500 c.Assert(space.Life(), gc.Equals, expectedLife) 501 } 502 503 func (s *SpacesSuite) TestEnsureDeadSetsLifeToDeadWhenNotAlive(c *gc.C) { 504 space := s.addAliveSpace(c, "soon-dead") 505 s.ensureDeadAndAssertLifeIsDead(c, space) 506 507 s.ensureDeadAndAssertLifeIsDead(c, space) 508 } 509 510 func (s *SpacesSuite) TestRemoveFailsIfStillAlive(c *gc.C) { 511 space := s.addAliveSpace(c, "still-alive") 512 513 err := space.Remove() 514 c.Assert(err, gc.ErrorMatches, `cannot remove space "still-alive": space is not dead`) 515 516 s.refreshAndAssertSpaceLifeIs(c, space, state.Alive) 517 } 518 519 func (s *SpacesSuite) TestRemoveSucceedsWhenSpaceIsNotAlive(c *gc.C) { 520 space := s.addAliveSpace(c, "not-alive-soon") 521 s.ensureDeadAndAssertLifeIsDead(c, space) 522 523 s.removeSpaceAndAssertNotFound(c, space) 524 } 525 526 func (s *SpacesSuite) removeSpaceAndAssertNotFound(c *gc.C, space *state.Space) { 527 err := space.Remove() 528 c.Assert(err, jc.ErrorIsNil) 529 s.assertSpaceNotFound(c, space.Name()) 530 } 531 532 func (s *SpacesSuite) TestRemoveSucceedsWhenCalledTwice(c *gc.C) { 533 space := s.addAliveSpace(c, "twice-deleted") 534 s.ensureDeadAndAssertLifeIsDead(c, space) 535 s.removeSpaceAndAssertNotFound(c, space) 536 537 err := space.Remove() 538 c.Assert(err, gc.ErrorMatches, `cannot remove space "twice-deleted": not found or not dead`) 539 } 540 541 func (s *SpacesSuite) TestRefreshUpdatesStaleDocData(c *gc.C) { 542 space := s.addAliveSpace(c, "original") 543 spaceCopy, err := s.State.Space(space.Name()) 544 c.Assert(err, jc.ErrorIsNil) 545 546 s.ensureDeadAndAssertLifeIsDead(c, space) 547 c.Assert(spaceCopy.Life(), gc.Equals, state.Alive) 548 549 err = spaceCopy.Refresh() 550 c.Assert(err, jc.ErrorIsNil) 551 c.Assert(spaceCopy.Life(), gc.Equals, state.Dead) 552 } 553 554 func (s *SpacesSuite) TestRefreshFailsWithNotFoundWhenRemoved(c *gc.C) { 555 space := s.addAliveSpace(c, "soon-removed") 556 s.ensureDeadAndAssertLifeIsDead(c, space) 557 s.removeSpaceAndAssertNotFound(c, space) 558 559 err := space.Refresh() 560 s.assertSpaceNotFoundError(c, err, "soon-removed") 561 }