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