github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/dummy/environs_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package dummy_test 5 6 import ( 7 "strings" 8 stdtesting "testing" 9 "time" 10 11 "github.com/juju/errors" 12 gitjujutesting "github.com/juju/testing" 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/cloud" 17 "github.com/juju/juju/core/instance" 18 "github.com/juju/juju/environs" 19 "github.com/juju/juju/environs/bootstrap" 20 "github.com/juju/juju/environs/context" 21 "github.com/juju/juju/environs/jujutest" 22 sstesting "github.com/juju/juju/environs/simplestreams/testing" 23 envtesting "github.com/juju/juju/environs/testing" 24 "github.com/juju/juju/juju/keys" 25 jujutesting "github.com/juju/juju/juju/testing" 26 "github.com/juju/juju/network" 27 "github.com/juju/juju/provider/dummy" 28 "github.com/juju/juju/testing" 29 jujuversion "github.com/juju/juju/version" 30 ) 31 32 const AdminSecret = "admin-secret" 33 34 func TestPackage(t *stdtesting.T) { 35 testing.MgoTestPackage(t) 36 } 37 38 func init() { 39 gc.Suite(&liveSuite{ 40 LiveTests: jujutest.LiveTests{ 41 TestConfig: dummy.SampleConfig(), 42 CanOpenState: true, 43 HasProvisioner: false, 44 }, 45 }) 46 gc.Suite(&suite{ 47 Tests: jujutest.Tests{ 48 TestConfig: dummy.SampleConfig(), 49 }, 50 }) 51 } 52 53 type liveSuite struct { 54 testing.BaseSuite 55 gitjujutesting.MgoSuite 56 jujutest.LiveTests 57 } 58 59 func (s *liveSuite) SetUpSuite(c *gc.C) { 60 s.BaseSuite.SetUpSuite(c) 61 s.MgoSuite.SetUpSuite(c) 62 s.LiveTests.SetUpSuite(c) 63 s.BaseSuite.PatchValue(&keys.JujuPublicKey, sstesting.SignedMetadataPublicKey) 64 } 65 66 func (s *liveSuite) TearDownSuite(c *gc.C) { 67 s.LiveTests.TearDownSuite(c) 68 s.MgoSuite.TearDownSuite(c) 69 s.BaseSuite.TearDownSuite(c) 70 } 71 72 func (s *liveSuite) SetUpTest(c *gc.C) { 73 s.BaseSuite.SetUpTest(c) 74 s.MgoSuite.SetUpTest(c) 75 s.LiveTests.SetUpTest(c) 76 s.BaseSuite.PatchValue(&dummy.LogDir, c.MkDir()) 77 } 78 79 func (s *liveSuite) TearDownTest(c *gc.C) { 80 s.Destroy(c) 81 s.LiveTests.TearDownTest(c) 82 s.MgoSuite.TearDownTest(c) 83 s.BaseSuite.TearDownTest(c) 84 } 85 86 type suite struct { 87 testing.BaseSuite 88 gitjujutesting.MgoSuite 89 jujutest.Tests 90 91 callCtx context.ProviderCallContext 92 } 93 94 func (s *suite) SetUpSuite(c *gc.C) { 95 s.BaseSuite.SetUpSuite(c) 96 s.MgoSuite.SetUpSuite(c) 97 } 98 99 func (s *suite) TearDownSuite(c *gc.C) { 100 s.MgoSuite.TearDownSuite(c) 101 s.BaseSuite.TearDownSuite(c) 102 } 103 104 func (s *suite) SetUpTest(c *gc.C) { 105 s.BaseSuite.SetUpTest(c) 106 s.PatchValue(&jujuversion.Current, testing.FakeVersionNumber) 107 s.MgoSuite.SetUpTest(c) 108 s.Tests.SetUpTest(c) 109 s.PatchValue(&dummy.LogDir, c.MkDir()) 110 s.callCtx = context.NewCloudCallContext() 111 } 112 113 func (s *suite) TearDownTest(c *gc.C) { 114 s.Tests.TearDownTest(c) 115 s.MgoSuite.TearDownTest(c) 116 dummy.Reset(c) 117 s.BaseSuite.TearDownTest(c) 118 } 119 120 func (s *suite) bootstrapTestEnviron(c *gc.C) environs.NetworkingEnviron { 121 e, err := bootstrap.PrepareController( 122 false, 123 envtesting.BootstrapContext(c), 124 s.ControllerStore, 125 bootstrap.PrepareParams{ 126 ControllerConfig: testing.FakeControllerConfig(), 127 ModelConfig: s.TestConfig, 128 ControllerName: s.TestConfig["name"].(string), 129 Cloud: dummy.SampleCloudSpec(), 130 AdminSecret: AdminSecret, 131 }, 132 ) 133 c.Assert(err, gc.IsNil, gc.Commentf("preparing environ %#v", s.TestConfig)) 134 c.Assert(e, gc.NotNil) 135 env := e.(environs.Environ) 136 netenv, supported := environs.SupportsNetworking(env) 137 c.Assert(supported, jc.IsTrue) 138 139 err = bootstrap.Bootstrap(envtesting.BootstrapContext(c), netenv, 140 context.NewCloudCallContext(), bootstrap.BootstrapParams{ 141 ControllerConfig: testing.FakeControllerConfig(), 142 Cloud: cloud.Cloud{ 143 Name: "dummy", 144 Type: "dummy", 145 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType}, 146 }, 147 AdminSecret: AdminSecret, 148 CAPrivateKey: testing.CAKey, 149 }) 150 c.Assert(err, jc.ErrorIsNil) 151 return netenv 152 } 153 154 func (s *suite) TestAvailabilityZone(c *gc.C) { 155 e := s.bootstrapTestEnviron(c) 156 defer func() { 157 err := e.Destroy(s.callCtx) 158 c.Assert(err, jc.ErrorIsNil) 159 }() 160 161 inst, hwc := jujutesting.AssertStartInstance(c, e, s.callCtx, s.ControllerUUID, "0") 162 c.Assert(inst, gc.NotNil) 163 c.Check(hwc.AvailabilityZone, gc.NotNil) 164 } 165 166 func (s *suite) TestSupportsSpaces(c *gc.C) { 167 e := s.bootstrapTestEnviron(c) 168 defer func() { 169 err := e.Destroy(s.callCtx) 170 c.Assert(err, jc.ErrorIsNil) 171 }() 172 173 // Without change spaces are supported. 174 ok, err := e.SupportsSpaces(s.callCtx) 175 c.Assert(ok, jc.IsTrue) 176 c.Assert(err, jc.ErrorIsNil) 177 178 // Now turn it off. 179 isEnabled := dummy.SetSupportsSpaces(false) 180 c.Assert(isEnabled, jc.IsTrue) 181 ok, err = e.SupportsSpaces(s.callCtx) 182 c.Assert(ok, jc.IsFalse) 183 c.Assert(err, jc.Satisfies, errors.IsNotSupported) 184 185 // And finally turn it on again. 186 isEnabled = dummy.SetSupportsSpaces(true) 187 c.Assert(isEnabled, jc.IsFalse) 188 ok, err = e.SupportsSpaces(s.callCtx) 189 c.Assert(ok, jc.IsTrue) 190 c.Assert(err, jc.ErrorIsNil) 191 } 192 193 func (s *suite) TestSupportsSpaceDiscovery(c *gc.C) { 194 e := s.bootstrapTestEnviron(c) 195 defer func() { 196 err := e.Destroy(s.callCtx) 197 c.Assert(err, jc.ErrorIsNil) 198 }() 199 200 // Without change space discovery is not supported. 201 ok, err := e.SupportsSpaceDiscovery(s.callCtx) 202 c.Assert(ok, jc.IsFalse) 203 c.Assert(err, jc.ErrorIsNil) 204 205 // Now turn it on. 206 isEnabled := dummy.SetSupportsSpaceDiscovery(true) 207 c.Assert(isEnabled, jc.IsFalse) 208 ok, err = e.SupportsSpaceDiscovery(s.callCtx) 209 c.Assert(ok, jc.IsTrue) 210 c.Assert(err, jc.ErrorIsNil) 211 212 // And finally turn it off again. 213 isEnabled = dummy.SetSupportsSpaceDiscovery(false) 214 c.Assert(isEnabled, jc.IsTrue) 215 ok, err = e.SupportsSpaceDiscovery(s.callCtx) 216 c.Assert(ok, jc.IsFalse) 217 c.Assert(err, jc.ErrorIsNil) 218 } 219 220 func (s *suite) breakMethods(c *gc.C, e environs.NetworkingEnviron, names ...string) { 221 cfg := e.Config() 222 brokenCfg, err := cfg.Apply(map[string]interface{}{ 223 "broken": strings.Join(names, " "), 224 }) 225 c.Assert(err, jc.ErrorIsNil) 226 err = e.SetConfig(brokenCfg) 227 c.Assert(err, jc.ErrorIsNil) 228 } 229 230 func (s *suite) TestNetworkInterfaces(c *gc.C) { 231 e := s.bootstrapTestEnviron(c) 232 defer func() { 233 err := e.Destroy(s.callCtx) 234 c.Assert(err, jc.ErrorIsNil) 235 }() 236 237 opc := make(chan dummy.Operation, 200) 238 dummy.Listen(opc) 239 240 expectInfo := []network.InterfaceInfo{{ 241 ProviderId: "dummy-eth0", 242 ProviderSubnetId: "dummy-private", 243 CIDR: "0.10.0.0/24", 244 DeviceIndex: 0, 245 InterfaceName: "eth0", 246 InterfaceType: "ethernet", 247 VLANTag: 0, 248 MACAddress: "aa:bb:cc:dd:ee:f0", 249 Disabled: false, 250 NoAutoStart: false, 251 ConfigType: network.ConfigDHCP, 252 Address: network.NewAddress("0.10.0.2"), 253 DNSServers: network.NewAddresses("ns1.dummy", "ns2.dummy"), 254 GatewayAddress: network.NewAddress("0.10.0.1"), 255 }, { 256 ProviderId: "dummy-eth1", 257 ProviderSubnetId: "dummy-public", 258 CIDR: "0.20.0.0/24", 259 DeviceIndex: 1, 260 InterfaceName: "eth1", 261 InterfaceType: "ethernet", 262 VLANTag: 1, 263 MACAddress: "aa:bb:cc:dd:ee:f1", 264 Disabled: false, 265 NoAutoStart: true, 266 ConfigType: network.ConfigDHCP, 267 Address: network.NewAddress("0.20.0.2"), 268 DNSServers: network.NewAddresses("ns1.dummy", "ns2.dummy"), 269 GatewayAddress: network.NewAddress("0.20.0.1"), 270 }, { 271 ProviderId: "dummy-eth2", 272 ProviderSubnetId: "dummy-disabled", 273 CIDR: "0.30.0.0/24", 274 DeviceIndex: 2, 275 InterfaceName: "eth2", 276 InterfaceType: "ethernet", 277 VLANTag: 2, 278 MACAddress: "aa:bb:cc:dd:ee:f2", 279 Disabled: true, 280 NoAutoStart: false, 281 ConfigType: network.ConfigDHCP, 282 Address: network.NewAddress("0.30.0.2"), 283 DNSServers: network.NewAddresses("ns1.dummy", "ns2.dummy"), 284 GatewayAddress: network.NewAddress("0.30.0.1"), 285 }} 286 info, err := e.NetworkInterfaces(s.callCtx, "i-42") 287 c.Assert(err, jc.ErrorIsNil) 288 c.Assert(info, jc.DeepEquals, expectInfo) 289 assertInterfaces(c, e, opc, "i-42", expectInfo) 290 291 // Test we can induce errors. 292 s.breakMethods(c, e, "NetworkInterfaces") 293 info, err = e.NetworkInterfaces(s.callCtx, "i-any") 294 c.Assert(err, gc.ErrorMatches, `dummy\.NetworkInterfaces is broken`) 295 c.Assert(info, gc.HasLen, 0) 296 } 297 298 func (s *suite) TestSubnets(c *gc.C) { 299 e := s.bootstrapTestEnviron(c) 300 defer func() { 301 err := e.Destroy(s.callCtx) 302 c.Assert(err, jc.ErrorIsNil) 303 }() 304 305 opc := make(chan dummy.Operation, 200) 306 dummy.Listen(opc) 307 308 expectInfo := []network.SubnetInfo{{ 309 CIDR: "0.10.0.0/24", 310 ProviderId: "dummy-private", 311 AvailabilityZones: []string{"zone1", "zone2"}, 312 }, { 313 CIDR: "0.20.0.0/24", 314 ProviderId: "dummy-public", 315 }} 316 317 ids := []network.Id{"dummy-private", "dummy-public", "foo-bar"} 318 netInfo, err := e.Subnets(s.callCtx, "i-foo", ids) 319 c.Assert(err, jc.ErrorIsNil) 320 c.Assert(netInfo, jc.DeepEquals, expectInfo) 321 assertSubnets(c, e, opc, "i-foo", ids, expectInfo) 322 323 // Test filtering by id(s). 324 netInfo, err = e.Subnets(s.callCtx, "i-foo", nil) 325 c.Assert(err, jc.ErrorIsNil) 326 c.Assert(netInfo, jc.DeepEquals, expectInfo) 327 assertSubnets(c, e, opc, "i-foo", nil, expectInfo) 328 netInfo, err = e.Subnets(s.callCtx, "i-foo", ids[0:1]) 329 c.Assert(err, jc.ErrorIsNil) 330 c.Assert(netInfo, jc.DeepEquals, expectInfo[0:1]) 331 assertSubnets(c, e, opc, "i-foo", ids[0:1], expectInfo[0:1]) 332 netInfo, err = e.Subnets(s.callCtx, "i-foo", ids[1:]) 333 c.Assert(err, jc.ErrorIsNil) 334 c.Assert(netInfo, jc.DeepEquals, expectInfo[1:]) 335 assertSubnets(c, e, opc, "i-foo", ids[1:], expectInfo[1:]) 336 337 // Test we can induce errors. 338 s.breakMethods(c, e, "Subnets") 339 netInfo, err = e.Subnets(s.callCtx, "i-any", nil) 340 c.Assert(err, gc.ErrorMatches, `dummy\.Subnets is broken`) 341 c.Assert(netInfo, gc.HasLen, 0) 342 } 343 344 func assertInterfaces(c *gc.C, e environs.Environ, opc chan dummy.Operation, expectInstId instance.Id, expectInfo []network.InterfaceInfo) { 345 select { 346 case op := <-opc: 347 netOp, ok := op.(dummy.OpNetworkInterfaces) 348 if !ok { 349 c.Fatalf("unexpected op: %#v", op) 350 } 351 c.Check(netOp.Env, gc.Equals, e.Config().Name()) 352 c.Check(netOp.InstanceId, gc.Equals, expectInstId) 353 c.Check(netOp.Info, jc.DeepEquals, expectInfo) 354 return 355 case <-time.After(testing.ShortWait): 356 c.Fatalf("time out wating for operation") 357 } 358 } 359 360 func assertSubnets( 361 c *gc.C, 362 e environs.Environ, 363 opc chan dummy.Operation, 364 instId instance.Id, 365 subnetIds []network.Id, 366 expectInfo []network.SubnetInfo, 367 ) { 368 select { 369 case op := <-opc: 370 netOp, ok := op.(dummy.OpSubnets) 371 if !ok { 372 c.Fatalf("unexpected op: %#v", op) 373 } 374 c.Check(netOp.InstanceId, gc.Equals, instId) 375 c.Check(netOp.SubnetIds, jc.DeepEquals, subnetIds) 376 c.Check(netOp.Info, jc.DeepEquals, expectInfo) 377 return 378 case <-time.After(testing.ShortWait): 379 c.Fatalf("time out wating for operation") 380 } 381 }