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