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  }