github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/environs/space/spaces_test.go (about)

     1  // Copyright 2020 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package space
     5  
     6  import (
     7  	"github.com/juju/collections/set"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	"go.uber.org/mock/gomock"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	instance "github.com/juju/juju/core/instance"
    15  	"github.com/juju/juju/core/network"
    16  	"github.com/juju/juju/state"
    17  )
    18  
    19  type spacesSuite struct {
    20  	testing.IsolationSuite
    21  }
    22  
    23  var _ = gc.Suite(&spacesSuite{})
    24  
    25  func (s *spacesSuite) TestReloadSpacesUsingSubnets(c *gc.C) {
    26  	ctrl := gomock.NewController(c)
    27  	defer ctrl.Finish()
    28  
    29  	subnets := []network.SubnetInfo{
    30  		{CIDR: "10.0.0.1/12"},
    31  		{CIDR: "10.12.24.1/24"},
    32  	}
    33  
    34  	context := NewMockProviderCallContext(ctrl)
    35  
    36  	environ := NewMockNetworkingEnviron(ctrl)
    37  	environ.EXPECT().SupportsSpaceDiscovery(context).Return(false, nil)
    38  	environ.EXPECT().Subnets(context, instance.UnknownId, nil).Return(subnets, nil)
    39  
    40  	state := NewMockReloadSpacesState(ctrl)
    41  	state.EXPECT().SaveProviderSubnets(subnets, "")
    42  
    43  	err := ReloadSpaces(context, state, environ)
    44  	c.Assert(err, jc.ErrorIsNil)
    45  }
    46  
    47  func (s *spacesSuite) TestReloadSpacesUsingSubnetsFailsOnSave(c *gc.C) {
    48  	ctrl := gomock.NewController(c)
    49  	defer ctrl.Finish()
    50  
    51  	subnets := []network.SubnetInfo{
    52  		{CIDR: "10.0.0.1/12"},
    53  		{CIDR: "10.12.24.1/24"},
    54  	}
    55  
    56  	context := NewMockProviderCallContext(ctrl)
    57  
    58  	environ := NewMockNetworkingEnviron(ctrl)
    59  	environ.EXPECT().SupportsSpaceDiscovery(context).Return(false, nil)
    60  	environ.EXPECT().Subnets(context, instance.UnknownId, nil).Return(subnets, nil)
    61  
    62  	state := NewMockReloadSpacesState(ctrl)
    63  	state.EXPECT().SaveProviderSubnets(subnets, "").Return(errors.New("boom"))
    64  
    65  	err := ReloadSpaces(context, state, environ)
    66  	c.Assert(err, gc.ErrorMatches, "boom")
    67  }
    68  
    69  func (s *spacesSuite) TestReloadSpacesNotNetworkEnviron(c *gc.C) {
    70  	ctrl := gomock.NewController(c)
    71  	defer ctrl.Finish()
    72  
    73  	context := NewMockProviderCallContext(ctrl)
    74  	state := NewMockReloadSpacesState(ctrl)
    75  	environ := NewMockBootstrapEnviron(ctrl)
    76  
    77  	err := ReloadSpaces(context, state, environ)
    78  	c.Assert(err, gc.ErrorMatches, "spaces discovery in a non-networking environ not supported")
    79  }
    80  
    81  type providerSpacesSuite struct {
    82  	testing.IsolationSuite
    83  }
    84  
    85  var _ = gc.Suite(&providerSpacesSuite{})
    86  
    87  func (s *providerSpacesSuite) TestSaveSpaces(c *gc.C) {
    88  	ctrl := gomock.NewController(c)
    89  	defer ctrl.Finish()
    90  
    91  	mockSpace := NewMockSpace(ctrl)
    92  	mockSpace.EXPECT().ProviderId().Return(network.Id("1"))
    93  	mockSpace.EXPECT().Name().Return("space1")
    94  	mockSpace.EXPECT().Id().Return("1")
    95  
    96  	mockState := NewMockReloadSpacesState(ctrl)
    97  	mockState.EXPECT().AllSpaces().Return([]Space{mockSpace}, nil)
    98  	mockState.EXPECT().SaveProviderSubnets([]network.SubnetInfo{{CIDR: "10.0.0.1/12"}}, "1")
    99  
   100  	subnets := []network.SpaceInfo{
   101  		{ProviderId: network.Id("1"), Subnets: []network.SubnetInfo{{CIDR: "10.0.0.1/12"}}},
   102  	}
   103  
   104  	provider := NewProviderSpaces(mockState)
   105  	err := provider.SaveSpaces(subnets)
   106  	c.Assert(err, jc.ErrorIsNil)
   107  	c.Assert(provider.modelSpaceMap, gc.DeepEquals, map[network.Id]Space{
   108  		network.Id("1"): mockSpace,
   109  	})
   110  }
   111  
   112  func (s *providerSpacesSuite) TestSaveSpacesWithoutProviderId(c *gc.C) {
   113  	ctrl := gomock.NewController(c)
   114  	defer ctrl.Finish()
   115  
   116  	mockSpace := NewMockSpace(ctrl)
   117  	mockSpace.EXPECT().ProviderId().Return(network.Id("1"))
   118  	mockSpace.EXPECT().Name().Return("space1")
   119  
   120  	newMockSpace := NewMockSpace(ctrl)
   121  	newMockSpace.EXPECT().Id().Return("2")
   122  	newMockSpace.EXPECT().ProviderId().Return(network.Id("2"))
   123  
   124  	mockState := NewMockReloadSpacesState(ctrl)
   125  	mockState.EXPECT().AllSpaces().Return([]Space{mockSpace}, nil)
   126  	mockState.EXPECT().AddSpace("empty", network.Id("2"), []string{}, false).Return(newMockSpace, nil)
   127  
   128  	mockState.EXPECT().SaveProviderSubnets([]network.SubnetInfo{{CIDR: "10.0.0.1/12"}}, "2")
   129  
   130  	subnets := []network.SpaceInfo{
   131  		{ProviderId: network.Id("2"), Subnets: []network.SubnetInfo{{CIDR: "10.0.0.1/12"}}},
   132  	}
   133  
   134  	provider := NewProviderSpaces(mockState)
   135  	err := provider.SaveSpaces(subnets)
   136  	c.Assert(err, jc.ErrorIsNil)
   137  	c.Assert(provider.modelSpaceMap, gc.DeepEquals, map[network.Id]Space{
   138  		network.Id("1"): mockSpace,
   139  		network.Id("2"): newMockSpace,
   140  	})
   141  }
   142  
   143  func (s *providerSpacesSuite) TestSaveSpacesDeltaSpaces(c *gc.C) {
   144  	ctrl := gomock.NewController(c)
   145  	defer ctrl.Finish()
   146  
   147  	mockState := NewMockReloadSpacesState(ctrl)
   148  
   149  	provider := NewProviderSpaces(mockState)
   150  	c.Assert(provider.DeltaSpaces(), gc.DeepEquals, network.MakeIDSet())
   151  }
   152  
   153  func (s *providerSpacesSuite) TestSaveSpacesDeltaSpacesAfterNotUpdated(c *gc.C) {
   154  	ctrl := gomock.NewController(c)
   155  	defer ctrl.Finish()
   156  
   157  	mockSpace := NewMockSpace(ctrl)
   158  	mockSpace.EXPECT().ProviderId().Return(network.Id("1"))
   159  	mockSpace.EXPECT().Name().Return("space1")
   160  
   161  	newMockSpace := NewMockSpace(ctrl)
   162  	newMockSpace.EXPECT().Id().Return("2")
   163  	newMockSpace.EXPECT().ProviderId().Return(network.Id("2"))
   164  
   165  	mockState := NewMockReloadSpacesState(ctrl)
   166  	mockState.EXPECT().AllSpaces().Return([]Space{mockSpace}, nil)
   167  	mockState.EXPECT().AddSpace("empty", network.Id("2"), []string{}, false).Return(newMockSpace, nil)
   168  
   169  	mockState.EXPECT().SaveProviderSubnets([]network.SubnetInfo{{CIDR: "10.0.0.1/12"}}, "2")
   170  
   171  	subnets := []network.SpaceInfo{
   172  		{ProviderId: network.Id("2"), Subnets: []network.SubnetInfo{{CIDR: "10.0.0.1/12"}}},
   173  	}
   174  
   175  	provider := NewProviderSpaces(mockState)
   176  	err := provider.SaveSpaces(subnets)
   177  	c.Assert(err, jc.ErrorIsNil)
   178  	c.Assert(provider.DeltaSpaces(), gc.DeepEquals, network.MakeIDSet(network.Id("1")))
   179  }
   180  
   181  func (s *providerSpacesSuite) TestDeleteSpacesWithNoDeltas(c *gc.C) {
   182  	ctrl := gomock.NewController(c)
   183  	defer ctrl.Finish()
   184  
   185  	mockState := NewMockReloadSpacesState(ctrl)
   186  
   187  	provider := NewProviderSpaces(mockState)
   188  	warnings, err := provider.DeleteSpaces()
   189  	c.Assert(err, jc.ErrorIsNil)
   190  	c.Assert(warnings, gc.DeepEquals, []string(nil))
   191  }
   192  
   193  func (s *providerSpacesSuite) TestDeleteSpaces(c *gc.C) {
   194  	ctrl := gomock.NewController(c)
   195  	defer ctrl.Finish()
   196  
   197  	mockSpace := NewMockSpace(ctrl)
   198  	mockSpace.EXPECT().Name().Return("1").MinTimes(1)
   199  	mockSpace.EXPECT().Id().Return("1").MinTimes(1)
   200  	mockSpace.EXPECT().Life().Return(state.Alive)
   201  
   202  	// These are the important calls to check for.
   203  	mockSpace.EXPECT().EnsureDead().Return(nil)
   204  	mockSpace.EXPECT().Remove().Return(nil)
   205  
   206  	mockState := NewMockReloadSpacesState(ctrl)
   207  	mockState.EXPECT().DefaultEndpointBindingSpace().Return("2", nil)
   208  	mockState.EXPECT().AllEndpointBindingsSpaceNames().Return(set.NewStrings(), nil)
   209  	mockState.EXPECT().ConstraintsBySpaceName("1").Return(nil, nil)
   210  
   211  	provider := NewProviderSpaces(mockState)
   212  	provider.modelSpaceMap = map[network.Id]Space{
   213  		network.Id("1"): mockSpace,
   214  	}
   215  
   216  	warnings, err := provider.DeleteSpaces()
   217  	c.Assert(err, jc.ErrorIsNil)
   218  	c.Assert(warnings, gc.DeepEquals, []string(nil))
   219  }
   220  
   221  func (s *providerSpacesSuite) TestDeleteSpacesMatchesAlphaSpace(c *gc.C) {
   222  	ctrl := gomock.NewController(c)
   223  	defer ctrl.Finish()
   224  
   225  	mockSpace := NewMockSpace(ctrl)
   226  	mockSpace.EXPECT().Name().Return("alpha").MinTimes(1)
   227  
   228  	mockState := NewMockReloadSpacesState(ctrl)
   229  	mockState.EXPECT().DefaultEndpointBindingSpace().Return("1", nil)
   230  	mockState.EXPECT().AllEndpointBindingsSpaceNames().Return(set.NewStrings(), nil)
   231  
   232  	provider := NewProviderSpaces(mockState)
   233  	provider.modelSpaceMap = map[network.Id]Space{
   234  		network.Id("1"): mockSpace,
   235  	}
   236  
   237  	warnings, err := provider.DeleteSpaces()
   238  	c.Assert(err, jc.ErrorIsNil)
   239  	c.Assert(warnings, gc.DeepEquals, []string{
   240  		`Unable to delete space "alpha". Space is used as the default space.`,
   241  	})
   242  }
   243  
   244  func (s *providerSpacesSuite) TestDeleteSpacesMatchesDefaultBindingSpace(c *gc.C) {
   245  	ctrl := gomock.NewController(c)
   246  	defer ctrl.Finish()
   247  
   248  	mockSpace := NewMockSpace(ctrl)
   249  	mockSpace.EXPECT().Name().Return("1").MinTimes(1)
   250  	mockSpace.EXPECT().Id().Return("1").MinTimes(1)
   251  
   252  	mockState := NewMockReloadSpacesState(ctrl)
   253  	mockState.EXPECT().DefaultEndpointBindingSpace().Return("1", nil)
   254  	mockState.EXPECT().AllEndpointBindingsSpaceNames().Return(set.NewStrings(), nil)
   255  
   256  	provider := NewProviderSpaces(mockState)
   257  	provider.modelSpaceMap = map[network.Id]Space{
   258  		network.Id("1"): mockSpace,
   259  	}
   260  
   261  	warnings, err := provider.DeleteSpaces()
   262  	c.Assert(err, jc.ErrorIsNil)
   263  	c.Assert(warnings, gc.DeepEquals, []string{
   264  		`Unable to delete space "1". Space is used as the default space.`,
   265  	})
   266  }
   267  
   268  func (s *providerSpacesSuite) TestDeleteSpacesContainedInAllEndpointBindings(c *gc.C) {
   269  	ctrl := gomock.NewController(c)
   270  	defer ctrl.Finish()
   271  
   272  	mockSpace := NewMockSpace(ctrl)
   273  	mockSpace.EXPECT().Name().Return("1").MinTimes(1)
   274  	mockSpace.EXPECT().Id().Return("1").MinTimes(1)
   275  
   276  	mockState := NewMockReloadSpacesState(ctrl)
   277  	mockState.EXPECT().DefaultEndpointBindingSpace().Return("2", nil)
   278  	mockState.EXPECT().AllEndpointBindingsSpaceNames().Return(set.NewStrings("1"), nil)
   279  
   280  	provider := NewProviderSpaces(mockState)
   281  	provider.modelSpaceMap = map[network.Id]Space{
   282  		network.Id("1"): mockSpace,
   283  	}
   284  
   285  	warnings, err := provider.DeleteSpaces()
   286  	c.Assert(err, jc.ErrorIsNil)
   287  	c.Assert(warnings, gc.DeepEquals, []string{
   288  		`Unable to delete space "1". Space is used as a endpoint binding.`,
   289  	})
   290  }
   291  
   292  func (s *providerSpacesSuite) TestDeleteSpacesContainsConstraintsSpace(c *gc.C) {
   293  	ctrl := gomock.NewController(c)
   294  	defer ctrl.Finish()
   295  
   296  	mockSpace := NewMockSpace(ctrl)
   297  	mockSpace.EXPECT().Name().Return("1").MinTimes(1)
   298  	mockSpace.EXPECT().Id().Return("1").MinTimes(1)
   299  
   300  	mockState := NewMockReloadSpacesState(ctrl)
   301  	mockState.EXPECT().DefaultEndpointBindingSpace().Return("2", nil)
   302  	mockState.EXPECT().AllEndpointBindingsSpaceNames().Return(set.NewStrings(), nil)
   303  	mockState.EXPECT().ConstraintsBySpaceName("1").Return([]Constraints{struct{}{}}, nil)
   304  
   305  	provider := NewProviderSpaces(mockState)
   306  	provider.modelSpaceMap = map[network.Id]Space{
   307  		network.Id("1"): mockSpace,
   308  	}
   309  
   310  	warnings, err := provider.DeleteSpaces()
   311  	c.Assert(err, jc.ErrorIsNil)
   312  	c.Assert(warnings, gc.DeepEquals, []string{
   313  		`Unable to delete space "1". Space is used in a constraint.`,
   314  	})
   315  }
   316  
   317  func (s *providerSpacesSuite) TestProviderSpacesRun(c *gc.C) {
   318  	ctrl := gomock.NewController(c)
   319  	defer ctrl.Finish()
   320  
   321  	mockSpace := NewMockSpace(ctrl)
   322  	mockSpace.EXPECT().ProviderId().Return(network.Id("1")).MinTimes(1)
   323  	mockSpace.EXPECT().Name().Return("1").MinTimes(1)
   324  	mockSpace.EXPECT().Id().Return("1").MinTimes(1)
   325  	mockSpace.EXPECT().Life().Return(state.Alive)
   326  	mockSpace.EXPECT().EnsureDead().Return(nil)
   327  	mockSpace.EXPECT().Remove().Return(nil)
   328  
   329  	newMockSpace := NewMockSpace(ctrl)
   330  	newMockSpace.EXPECT().Id().Return("2")
   331  	newMockSpace.EXPECT().ProviderId().Return(network.Id("2"))
   332  
   333  	mockState := NewMockReloadSpacesState(ctrl)
   334  	mockState.EXPECT().AllSpaces().Return([]Space{mockSpace}, nil)
   335  	mockState.EXPECT().AddSpace("empty", network.Id("2"), []string{}, false).Return(newMockSpace, nil)
   336  
   337  	mockState.EXPECT().SaveProviderSubnets([]network.SubnetInfo{{CIDR: "10.0.0.1/12"}}, "2")
   338  
   339  	subnets := []network.SpaceInfo{
   340  		{ProviderId: network.Id("2"), Subnets: []network.SubnetInfo{{CIDR: "10.0.0.1/12"}}},
   341  	}
   342  
   343  	provider := NewProviderSpaces(mockState)
   344  	err := provider.SaveSpaces(subnets)
   345  	c.Assert(err, jc.ErrorIsNil)
   346  	c.Assert(provider.modelSpaceMap, gc.DeepEquals, map[network.Id]Space{
   347  		network.Id("1"): mockSpace,
   348  		network.Id("2"): newMockSpace,
   349  	})
   350  
   351  	mockState.EXPECT().DefaultEndpointBindingSpace().Return("2", nil)
   352  	mockState.EXPECT().AllEndpointBindingsSpaceNames().Return(set.NewStrings(), nil)
   353  	mockState.EXPECT().ConstraintsBySpaceName("1").Return(nil, nil)
   354  
   355  	warnings, err := provider.DeleteSpaces()
   356  	c.Assert(err, jc.ErrorIsNil)
   357  	c.Assert(warnings, gc.DeepEquals, []string(nil))
   358  }