github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/apiserver/addresser/addresser_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package addresser_test 5 6 import ( 7 "github.com/juju/errors" 8 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/apiserver/addresser" 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/params" 15 apiservertesting "github.com/juju/juju/apiserver/testing" 16 "github.com/juju/juju/cmd/envcmd" 17 "github.com/juju/juju/environs" 18 "github.com/juju/juju/environs/config" 19 "github.com/juju/juju/environs/configstore" 20 "github.com/juju/juju/feature" 21 "github.com/juju/juju/instance" 22 "github.com/juju/juju/network" 23 "github.com/juju/juju/provider/dummy" 24 "github.com/juju/juju/state" 25 statetesting "github.com/juju/juju/state/testing" 26 coretesting "github.com/juju/juju/testing" 27 ) 28 29 type AddresserSuite struct { 30 coretesting.BaseSuite 31 32 st *mockState 33 api *addresser.AddresserAPI 34 authoriser apiservertesting.FakeAuthorizer 35 resources *common.Resources 36 } 37 38 var _ = gc.Suite(&AddresserSuite{}) 39 40 func (s *AddresserSuite) SetUpSuite(c *gc.C) { 41 s.BaseSuite.SetUpSuite(c) 42 environs.RegisterProvider("mock", mockEnvironProvider{}) 43 } 44 45 func (s *AddresserSuite) SetUpTest(c *gc.C) { 46 s.BaseSuite.SetUpTest(c) 47 s.SetFeatureFlags(feature.AddressAllocation) 48 49 s.authoriser = apiservertesting.FakeAuthorizer{ 50 EnvironManager: true, 51 } 52 s.resources = common.NewResources() 53 s.AddCleanup(func(*gc.C) { s.resources.StopAll() }) 54 55 s.st = newMockState() 56 addresser.PatchState(s, s.st) 57 58 var err error 59 s.api, err = addresser.NewAddresserAPI(nil, s.resources, s.authoriser) 60 c.Assert(err, jc.ErrorIsNil) 61 } 62 63 func (s *AddresserSuite) TearDownTest(c *gc.C) { 64 dummy.Reset() 65 s.BaseSuite.TearDownTest(c) 66 } 67 68 func (s *AddresserSuite) TestCanDeallocateAddressesEnabled(c *gc.C) { 69 config := testingEnvConfig(c) 70 s.st.setConfig(c, config) 71 72 result := s.api.CanDeallocateAddresses() 73 c.Assert(result, jc.DeepEquals, params.BoolResult{ 74 Error: nil, 75 Result: true, 76 }) 77 } 78 79 func (s *AddresserSuite) TestCanDeallocateAddressesDisabled(c *gc.C) { 80 config := testingEnvConfig(c) 81 s.st.setConfig(c, config) 82 s.SetFeatureFlags() 83 84 result := s.api.CanDeallocateAddresses() 85 c.Assert(result, jc.DeepEquals, params.BoolResult{ 86 Error: nil, 87 Result: false, 88 }) 89 } 90 91 func (s *AddresserSuite) TestCanDeallocateAddressesConfigGetFailure(c *gc.C) { 92 config := testingEnvConfig(c) 93 s.st.setConfig(c, config) 94 95 s.st.stub.SetErrors(errors.New("ouch")) 96 97 result := s.api.CanDeallocateAddresses() 98 c.Assert(result.Error, gc.ErrorMatches, "getting environment config: ouch") 99 c.Assert(result.Result, jc.IsFalse) 100 } 101 102 func (s *AddresserSuite) TestCanDeallocateAddressesEnvironmentNewFailure(c *gc.C) { 103 config := nonexTestingEnvConfig(c) 104 s.st.setConfig(c, config) 105 106 result := s.api.CanDeallocateAddresses() 107 c.Assert(result.Error, gc.ErrorMatches, `validating environment config: no registered provider for "nonex"`) 108 c.Assert(result.Result, jc.IsFalse) 109 } 110 111 func (s *AddresserSuite) TestCanDeallocateAddressesNotSupportedFailure(c *gc.C) { 112 config := mockTestingEnvConfig(c) 113 s.st.setConfig(c, config) 114 115 result := s.api.CanDeallocateAddresses() 116 c.Assert(result, jc.DeepEquals, params.BoolResult{ 117 Error: nil, 118 Result: false, 119 }) 120 } 121 122 func (s *AddresserSuite) TestCleanupIPAddressesSuccess(c *gc.C) { 123 config := testingEnvConfig(c) 124 s.st.setConfig(c, config) 125 126 dead, err := s.st.DeadIPAddresses() 127 c.Assert(err, jc.ErrorIsNil) 128 c.Assert(dead, gc.HasLen, 2) 129 130 apiErr := s.api.CleanupIPAddresses() 131 c.Assert(apiErr, jc.DeepEquals, params.ErrorResult{}) 132 133 dead, err = s.st.DeadIPAddresses() 134 c.Assert(err, jc.ErrorIsNil) 135 c.Assert(dead, gc.HasLen, 0) 136 } 137 138 func (s *AddresserSuite) TestReleaseAddress(c *gc.C) { 139 config := testingEnvConfig(c) 140 s.st.setConfig(c, config) 141 142 // Cleanup initial dead IP addresses. 143 dead, err := s.st.DeadIPAddresses() 144 c.Assert(err, jc.ErrorIsNil) 145 c.Assert(dead, gc.HasLen, 2) 146 147 apiErr := s.api.CleanupIPAddresses() 148 c.Assert(apiErr, jc.DeepEquals, params.ErrorResult{}) 149 150 dead, err = s.st.DeadIPAddresses() 151 c.Assert(err, jc.ErrorIsNil) 152 c.Assert(dead, gc.HasLen, 0) 153 154 // Prepare tests. 155 called := 0 156 s.PatchValue(addresser.NetEnvReleaseAddress, func(env environs.NetworkingEnviron, 157 instId instance.Id, subnetId network.Id, addr network.Address, macAddress string) error { 158 called++ 159 c.Assert(instId, gc.Equals, instance.Id("a3")) 160 c.Assert(subnetId, gc.Equals, network.Id("a")) 161 c.Assert(addr, gc.Equals, network.NewAddress("0.1.2.3")) 162 c.Assert(macAddress, gc.Equals, "fff3") 163 return nil 164 }) 165 166 // Set address 0.1.2.3 to dead. 167 s.st.setDead(c, "0.1.2.3") 168 169 dead, err = s.st.DeadIPAddresses() 170 c.Assert(err, jc.ErrorIsNil) 171 c.Assert(dead, gc.HasLen, 1) 172 173 apiErr = s.api.CleanupIPAddresses() 174 c.Assert(apiErr, jc.DeepEquals, params.ErrorResult{}) 175 c.Assert(called, gc.Equals, 1) 176 177 dead, err = s.st.DeadIPAddresses() 178 c.Assert(err, jc.ErrorIsNil) 179 c.Assert(dead, gc.HasLen, 0) 180 } 181 182 func (s *AddresserSuite) TestCleanupIPAddressesConfigGetFailure(c *gc.C) { 183 config := testingEnvConfig(c) 184 s.st.setConfig(c, config) 185 186 dead, err := s.st.DeadIPAddresses() 187 c.Assert(err, jc.ErrorIsNil) 188 c.Assert(dead, gc.HasLen, 2) 189 190 s.st.stub.SetErrors(errors.New("ouch")) 191 192 // First action is getting the environment configuration, 193 // so the injected error is returned here. 194 apiErr := s.api.CleanupIPAddresses() 195 c.Assert(apiErr.Error, gc.ErrorMatches, "getting environment config: ouch") 196 197 // Still has two dead addresses. 198 dead, err = s.st.DeadIPAddresses() 199 c.Assert(err, jc.ErrorIsNil) 200 c.Assert(dead, gc.HasLen, 2) 201 } 202 203 func (s *AddresserSuite) TestCleanupIPAddressesEnvironmentNewFailure(c *gc.C) { 204 config := nonexTestingEnvConfig(c) 205 s.st.setConfig(c, config) 206 207 dead, err := s.st.DeadIPAddresses() 208 c.Assert(err, jc.ErrorIsNil) 209 c.Assert(dead, gc.HasLen, 2) 210 211 // Validation of configuration fails due to illegal provider. 212 apiErr := s.api.CleanupIPAddresses() 213 c.Assert(apiErr.Error, gc.ErrorMatches, `validating environment config: no registered provider for "nonex"`) 214 215 // Still has two dead addresses. 216 dead, err = s.st.DeadIPAddresses() 217 c.Assert(err, jc.ErrorIsNil) 218 c.Assert(dead, gc.HasLen, 2) 219 } 220 221 func (s *AddresserSuite) TestCleanupIPAddressesNotSupportedFailure(c *gc.C) { 222 config := mockTestingEnvConfig(c) 223 s.st.setConfig(c, config) 224 225 dead, err := s.st.DeadIPAddresses() 226 c.Assert(err, jc.ErrorIsNil) 227 c.Assert(dead, gc.HasLen, 2) 228 229 // The tideland environment does not support networking. 230 apiErr := s.api.CleanupIPAddresses() 231 c.Assert(apiErr.Error, gc.ErrorMatches, "IP address deallocation not supported") 232 233 // Still has two dead addresses. 234 dead, err = s.st.DeadIPAddresses() 235 c.Assert(err, jc.ErrorIsNil) 236 c.Assert(dead, gc.HasLen, 2) 237 } 238 239 func (s *AddresserSuite) TestWatchIPAddresses(c *gc.C) { 240 c.Assert(s.resources.Count(), gc.Equals, 0) 241 242 s.st.addIPAddressWatcher("0.1.2.3", "0.1.2.4", "0.1.2.7") 243 244 result, err := s.api.WatchIPAddresses() 245 c.Assert(err, jc.ErrorIsNil) 246 c.Assert(result, gc.DeepEquals, params.EntityWatchResult{ 247 EntityWatcherId: "1", 248 Changes: []string{ 249 "ipaddress-00000000-1111-2222-3333-0123456789ab", 250 "ipaddress-00000000-1111-2222-4444-0123456789ab", 251 "ipaddress-00000000-1111-2222-7777-0123456789ab", 252 }, 253 Error: nil, 254 }) 255 256 // Verify the resource was registered and stop when done. 257 c.Assert(s.resources.Count(), gc.Equals, 1) 258 resource := s.resources.Get("1") 259 defer statetesting.AssertStop(c, resource) 260 261 // Check that the Watch has consumed the initial event ("returned" in 262 // the Watch call) 263 wc := statetesting.NewStringsWatcherC(c, s.st, resource.(state.StringsWatcher)) 264 wc.AssertNoChange() 265 } 266 267 // testingEnvConfig prepares an environment configuration using 268 // the dummy provider. 269 func testingEnvConfig(c *gc.C) *config.Config { 270 cfg, err := config.New(config.NoDefaults, dummy.SampleConfig()) 271 c.Assert(err, jc.ErrorIsNil) 272 env, err := environs.Prepare(cfg, envcmd.BootstrapContext(coretesting.Context(c)), configstore.NewMem()) 273 c.Assert(err, jc.ErrorIsNil) 274 return env.Config() 275 } 276 277 // nonexTestingEnvConfig prepares an environment configuration using 278 // a non-existent provider. 279 func nonexTestingEnvConfig(c *gc.C) *config.Config { 280 attrs := dummy.SampleConfig().Merge(coretesting.Attrs{ 281 "type": "nonex", 282 }) 283 cfg, err := config.New(config.NoDefaults, attrs) 284 c.Assert(err, jc.ErrorIsNil) 285 return cfg 286 } 287 288 // mockTestingEnvConfig prepares an environment configuration using 289 // the mock provider which does not support networking. 290 func mockTestingEnvConfig(c *gc.C) *config.Config { 291 cfg, err := config.New(config.NoDefaults, mockConfig()) 292 c.Assert(err, jc.ErrorIsNil) 293 env, err := environs.Prepare(cfg, envcmd.BootstrapContext(coretesting.Context(c)), configstore.NewMem()) 294 c.Assert(err, jc.ErrorIsNil) 295 return env.Config() 296 }