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 }