github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/provider/vsphere/environ_broker_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // +build !gccgo 5 6 package vsphere_test 7 8 import ( 9 "github.com/juju/errors" 10 "github.com/juju/govmomi/vim25/methods" 11 "github.com/juju/govmomi/vim25/soap" 12 "github.com/juju/govmomi/vim25/types" 13 jc "github.com/juju/testing/checkers" 14 "github.com/juju/utils/arch" 15 gc "gopkg.in/check.v1" 16 17 "github.com/juju/juju/cloudconfig/instancecfg" 18 "github.com/juju/juju/constraints" 19 "github.com/juju/juju/environs" 20 "github.com/juju/juju/environs/config" 21 "github.com/juju/juju/environs/imagemetadata" 22 "github.com/juju/juju/instance" 23 "github.com/juju/juju/provider/common" 24 "github.com/juju/juju/provider/vsphere" 25 "github.com/juju/juju/tools" 26 "github.com/juju/juju/version" 27 ) 28 29 type environBrokerSuite struct { 30 vsphere.BaseSuite 31 } 32 33 var _ = gc.Suite(&environBrokerSuite{}) 34 35 func (s *environBrokerSuite) SetUpTest(c *gc.C) { 36 s.BaseSuite.SetUpTest(c) 37 } 38 39 func (s *environBrokerSuite) PrepareStartInstanceFakes(c *gc.C) { 40 // Prevent falling over to the public datasource. 41 s.BaseSuite.PatchValue(&imagemetadata.DefaultBaseURL, "") 42 43 client := vsphere.ExposeEnvFakeClient(s.Env) 44 client.SetPropertyProxyHandler("FakeDatacenter", vsphere.RetrieveDatacenterProperties) 45 s.FakeInstances(client) 46 s.FakeAvailabilityZones(client, "z1") 47 s.FakeAvailabilityZones(client, "z1") 48 s.FakeAvailabilityZones(client, "z1") 49 s.FakeCreateInstance(client, s.ServerUrl, c) 50 } 51 52 func (s *environBrokerSuite) CreateStartInstanceArgs(c *gc.C) environs.StartInstanceParams { 53 tools := []*tools.Tools{{ 54 Version: version.Binary{Arch: arch.AMD64, Series: "trusty"}, 55 URL: "https://example.org", 56 }} 57 58 cons := constraints.Value{} 59 60 instanceConfig, err := instancecfg.NewBootstrapInstanceConfig(cons, "trusty") 61 c.Assert(err, jc.ErrorIsNil) 62 63 instanceConfig.Tools = tools[0] 64 instanceConfig.AuthorizedKeys = s.Config.AuthorizedKeys() 65 66 return environs.StartInstanceParams{ 67 InstanceConfig: instanceConfig, 68 Tools: tools, 69 Constraints: cons, 70 } 71 } 72 73 func (s *environBrokerSuite) TestStartInstance(c *gc.C) { 74 s.PrepareStartInstanceFakes(c) 75 startInstArgs := s.CreateStartInstanceArgs(c) 76 _, err := s.Env.StartInstance(startInstArgs) 77 78 c.Assert(err, jc.ErrorIsNil) 79 } 80 81 func (s *environBrokerSuite) TestStartInstanceWithNetworks(c *gc.C) { 82 s.PrepareStartInstanceFakes(c) 83 startInstArgs := s.CreateStartInstanceArgs(c) 84 startInstArgs.InstanceConfig.Networks = []string{"someNetwork"} 85 _, err := s.Env.StartInstance(startInstArgs) 86 87 c.Assert(err, gc.ErrorMatches, "starting instances with networks is not supported yet") 88 } 89 90 func (s *environBrokerSuite) TestStartInstanceWithUnsupportedConstraints(c *gc.C) { 91 s.PrepareStartInstanceFakes(c) 92 startInstArgs := s.CreateStartInstanceArgs(c) 93 startInstArgs.Tools[0].Version.Arch = "someArch" 94 _, err := s.Env.StartInstance(startInstArgs) 95 96 c.Assert(err, gc.ErrorMatches, "no matching images found for given constraints: .*") 97 } 98 99 // if tools for multiple architectures are avaliable, provider should filter tools by arch of the selected image 100 func (s *environBrokerSuite) TestStartInstanceFilterToolByArch(c *gc.C) { 101 s.PrepareStartInstanceFakes(c) 102 startInstArgs := s.CreateStartInstanceArgs(c) 103 tools := []*tools.Tools{{ 104 Version: version.Binary{Arch: arch.I386, Series: "trusty"}, 105 URL: "https://example.org", 106 }, { 107 Version: version.Binary{Arch: arch.AMD64, Series: "trusty"}, 108 URL: "https://example.org", 109 }} 110 //setting tools to I386, but provider should update them to AMD64, because our fake simplestream server return only AMD 64 image 111 startInstArgs.Tools = tools 112 startInstArgs.InstanceConfig.Tools = tools[0] 113 res, err := s.Env.StartInstance(startInstArgs) 114 115 c.Assert(err, jc.ErrorIsNil) 116 c.Assert(*res.Hardware.Arch, gc.Equals, arch.AMD64) 117 c.Assert(startInstArgs.InstanceConfig.Tools.Version.Arch, gc.Equals, arch.AMD64) 118 } 119 120 func (s *environBrokerSuite) TestStartInstanceDefaultConstraintsApplied(c *gc.C) { 121 s.PrepareStartInstanceFakes(c) 122 startInstArgs := s.CreateStartInstanceArgs(c) 123 res, err := s.Env.StartInstance(startInstArgs) 124 125 c.Assert(err, jc.ErrorIsNil) 126 c.Assert(*res.Hardware.CpuCores, gc.Equals, vsphere.DefaultCpuCores) 127 c.Assert(*res.Hardware.CpuPower, gc.Equals, vsphere.DefaultCpuPower) 128 c.Assert(*res.Hardware.Mem, gc.Equals, vsphere.DefaultMemMb) 129 c.Assert(*res.Hardware.RootDisk, gc.Equals, common.MinRootDiskSizeGiB*1024) 130 } 131 132 func (s *environBrokerSuite) TestStartInstanceCustomConstraintsApplied(c *gc.C) { 133 s.PrepareStartInstanceFakes(c) 134 startInstArgs := s.CreateStartInstanceArgs(c) 135 cpuCores := uint64(4) 136 startInstArgs.Constraints.CpuCores = &cpuCores 137 cpuPower := uint64(2001) 138 startInstArgs.Constraints.CpuPower = &cpuPower 139 mem := uint64(2002) 140 startInstArgs.Constraints.Mem = &mem 141 rootDisk := uint64(10003) 142 startInstArgs.Constraints.RootDisk = &rootDisk 143 res, err := s.Env.StartInstance(startInstArgs) 144 145 c.Assert(err, jc.ErrorIsNil) 146 c.Assert(*res.Hardware.CpuCores, gc.Equals, cpuCores) 147 c.Assert(*res.Hardware.CpuPower, gc.Equals, cpuPower) 148 c.Assert(*res.Hardware.Mem, gc.Equals, mem) 149 c.Assert(*res.Hardware.RootDisk, gc.Equals, rootDisk) 150 151 } 152 153 func (s *environBrokerSuite) TestStartInstanceCallsFinishMachineConfig(c *gc.C) { 154 s.PrepareStartInstanceFakes(c) 155 startInstArgs := s.CreateStartInstanceArgs(c) 156 s.PatchValue(&vsphere.FinishInstanceConfig, func(mcfg *instancecfg.InstanceConfig, cfg *config.Config) (err error) { 157 return errors.New("FinishMachineConfig called") 158 }) 159 _, err := s.Env.StartInstance(startInstArgs) 160 c.Assert(err, gc.ErrorMatches, "FinishMachineConfig called") 161 } 162 163 func (s *environBrokerSuite) TestStartInstanceDefaultDiskSizeIsUsedForSmallConstraintValue(c *gc.C) { 164 s.PrepareStartInstanceFakes(c) 165 startInstArgs := s.CreateStartInstanceArgs(c) 166 rootDisk := uint64(1000) 167 startInstArgs.Constraints.RootDisk = &rootDisk 168 res, err := s.Env.StartInstance(startInstArgs) 169 c.Assert(err, jc.ErrorIsNil) 170 c.Assert(*res.Hardware.RootDisk, gc.Equals, common.MinRootDiskSizeGiB*1024) 171 } 172 173 func (s *environBrokerSuite) TestStartInstanceInvalidPlacement(c *gc.C) { 174 s.PrepareStartInstanceFakes(c) 175 startInstArgs := s.CreateStartInstanceArgs(c) 176 startInstArgs.Placement = "someInvalidPlacement" 177 _, err := s.Env.StartInstance(startInstArgs) 178 c.Assert(err, gc.ErrorMatches, "unknown placement directive: .*") 179 } 180 181 func (s *environBrokerSuite) TestStartInstanceSelectZone(c *gc.C) { 182 client := vsphere.ExposeEnvFakeClient(s.Env) 183 s.FakeAvailabilityZones(client, "z1", "z2") 184 s.FakeAvailabilityZones(client, "z1", "z2") 185 s.FakeCreateInstance(client, s.ServerUrl, c) 186 startInstArgs := s.CreateStartInstanceArgs(c) 187 startInstArgs.Placement = "zone=z2" 188 _, err := s.Env.StartInstance(startInstArgs) 189 c.Assert(err, jc.ErrorIsNil) 190 } 191 192 func (s *environBrokerSuite) TestStartInstanceCallsAvailabilityZoneAllocations(c *gc.C) { 193 s.PrepareStartInstanceFakes(c) 194 startInstArgs := s.CreateStartInstanceArgs(c) 195 startInstArgs.DistributionGroup = func() ([]instance.Id, error) { 196 return []instance.Id{instance.Id("someId")}, nil 197 } 198 s.PatchValue(&vsphere.AvailabilityZoneAllocations, func(env common.ZonedEnviron, group []instance.Id) ([]common.AvailabilityZoneInstances, error) { 199 c.Assert(len(group), gc.Equals, 1) 200 c.Assert(string(group[0]), gc.Equals, "someId") 201 return nil, errors.New("AvailabilityZoneAllocations called") 202 }) 203 _, err := s.Env.StartInstance(startInstArgs) 204 c.Assert(err, gc.ErrorMatches, "AvailabilityZoneAllocations called") 205 } 206 207 func (s *environBrokerSuite) TestStartInstanceTriesToCreateInstanceInAllAvailabilityZones(c *gc.C) { 208 client := vsphere.ExposeEnvFakeClient(s.Env) 209 client.SetPropertyProxyHandler("FakeDatacenter", vsphere.RetrieveDatacenterProperties) 210 s.FakeInstances(client) 211 s.FakeAvailabilityZones(client, "z1", "z2") 212 s.FakeAvailabilityZones(client, "z1", "z2") 213 s.FakeAvailabilityZones(client, "z1", "z2") 214 client.SetPropertyProxyHandler("FakeDatacenter", vsphere.RetrieveDatacenterProperties) 215 client.SetProxyHandler("CreateImportSpec", func(req, res soap.HasFault) { 216 resBody := res.(*methods.CreateImportSpecBody) 217 resBody.Res = &types.CreateImportSpecResponse{ 218 Returnval: types.OvfCreateImportSpecResult{ 219 Error: []types.LocalizedMethodFault{{ 220 LocalizedMessage: "Error zone 1", 221 }}, 222 }, 223 } 224 }) 225 s.FakeAvailabilityZones(client, "z1", "z2") 226 client.SetPropertyProxyHandler("FakeDatacenter", vsphere.RetrieveDatacenterProperties) 227 client.SetProxyHandler("CreateImportSpec", func(req, res soap.HasFault) { 228 resBody := res.(*methods.CreateImportSpecBody) 229 resBody.Res = &types.CreateImportSpecResponse{ 230 Returnval: types.OvfCreateImportSpecResult{ 231 Error: []types.LocalizedMethodFault{{ 232 LocalizedMessage: "Error zone 2", 233 }}, 234 }, 235 } 236 }) 237 startInstArgs := s.CreateStartInstanceArgs(c) 238 _, err := s.Env.StartInstance(startInstArgs) 239 c.Assert(err, gc.ErrorMatches, "Can't create instance in any of availability zones, last error: Failed to import OVA file: Error zone 2") 240 }