github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/gce/environ_policy_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package gce_test 5 6 import ( 7 "github.com/juju/errors" 8 jc "github.com/juju/testing/checkers" 9 gc "gopkg.in/check.v1" 10 11 "github.com/juju/juju/core/constraints" 12 "github.com/juju/juju/environs" 13 "github.com/juju/juju/juju/version" 14 "github.com/juju/juju/provider/gce" 15 "github.com/juju/juju/provider/gce/google" 16 "github.com/juju/juju/storage" 17 ) 18 19 type environPolSuite struct { 20 gce.BaseSuite 21 } 22 23 var _ = gc.Suite(&environPolSuite{}) 24 25 func (s *environPolSuite) TestPrecheckInstanceDefaults(c *gc.C) { 26 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS()}) 27 c.Assert(err, jc.ErrorIsNil) 28 29 c.Check(s.FakeConn.Calls, gc.HasLen, 0) 30 } 31 32 func (s *environPolSuite) TestPrecheckInstanceFullAPI(c *gc.C) { 33 s.FakeConn.Zones = []google.AvailabilityZone{ 34 google.NewZone("home-zone", google.StatusUp, "", ""), 35 } 36 37 cons := constraints.MustParse("instance-type=n1-standard-1 arch=amd64 root-disk=1G") 38 placement := "zone=home-zone" 39 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons, Placement: placement}) 40 c.Assert(err, jc.ErrorIsNil) 41 42 c.Check(s.FakeConn.Calls, gc.HasLen, 1) 43 c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "AvailabilityZones") 44 c.Check(s.FakeConn.Calls[0].Region, gc.Equals, "us-east1") 45 } 46 47 func (s *environPolSuite) TestPrecheckInstanceValidInstanceType(c *gc.C) { 48 cons := constraints.MustParse("instance-type=n1-standard-1") 49 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons}) 50 51 c.Check(err, jc.ErrorIsNil) 52 } 53 54 func (s *environPolSuite) TestPrecheckInstanceInvalidInstanceType(c *gc.C) { 55 cons := constraints.MustParse("instance-type=n1-standard-1.invalid") 56 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons}) 57 58 c.Check(err, gc.ErrorMatches, `.*invalid GCE instance type.*`) 59 } 60 61 func (s *environPolSuite) TestPrecheckInstanceDiskSize(c *gc.C) { 62 cons := constraints.MustParse("instance-type=n1-standard-1 root-disk=1G") 63 placement := "" 64 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons, Placement: placement}) 65 66 c.Check(err, jc.ErrorIsNil) 67 } 68 69 func (s *environPolSuite) TestPrecheckInstanceUnsupportedArch(c *gc.C) { 70 cons := constraints.MustParse("instance-type=n1-standard-1 arch=i386") 71 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons}) 72 73 c.Check(err, jc.ErrorIsNil) 74 } 75 76 func (s *environPolSuite) TestPrecheckInstanceAvailZone(c *gc.C) { 77 s.FakeConn.Zones = []google.AvailabilityZone{ 78 google.NewZone("a-zone", google.StatusUp, "", ""), 79 } 80 81 placement := "zone=a-zone" 82 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Placement: placement}) 83 84 c.Check(err, jc.ErrorIsNil) 85 } 86 87 func (s *environPolSuite) TestPrecheckInstanceAvailZoneUnavailable(c *gc.C) { 88 s.FakeConn.Zones = []google.AvailabilityZone{ 89 google.NewZone("a-zone", google.StatusDown, "", ""), 90 } 91 92 placement := "zone=a-zone" 93 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Placement: placement}) 94 95 c.Check(err, gc.ErrorMatches, `.*availability zone "a-zone" is DOWN`) 96 } 97 98 func (s *environPolSuite) TestPrecheckInstanceAvailZoneUnknown(c *gc.C) { 99 s.FakeConn.Zones = []google.AvailabilityZone{ 100 google.NewZone("home-zone", google.StatusUp, "", ""), 101 } 102 103 placement := "zone=a-zone" 104 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Placement: placement}) 105 106 c.Check(err, jc.Satisfies, errors.IsNotFound) 107 } 108 109 func (s *environPolSuite) TestPrecheckInstanceVolumeAvailZoneNoPlacement(c *gc.C) { 110 s.testPrecheckInstanceVolumeAvailZone(c, "") 111 } 112 113 func (s *environPolSuite) TestPrecheckInstanceVolumeAvailZoneSameZonePlacement(c *gc.C) { 114 s.testPrecheckInstanceVolumeAvailZone(c, "zone=away-zone") 115 } 116 117 func (s *environPolSuite) testPrecheckInstanceVolumeAvailZone(c *gc.C, placement string) { 118 s.FakeConn.Zones = []google.AvailabilityZone{ 119 google.NewZone("away-zone", google.StatusUp, "", ""), 120 } 121 122 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{ 123 Series: version.SupportedLTS(), 124 Placement: placement, 125 VolumeAttachments: []storage.VolumeAttachmentParams{{ 126 VolumeId: "away-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4", 127 }}, 128 }) 129 c.Check(err, jc.ErrorIsNil) 130 } 131 132 func (s *environPolSuite) TestPrecheckInstanceAvailZoneConflictsVolume(c *gc.C) { 133 s.FakeConn.Zones = []google.AvailabilityZone{ 134 google.NewZone("away-zone", google.StatusUp, "", ""), 135 } 136 137 err := s.Env.PrecheckInstance(s.CallCtx, environs.PrecheckInstanceParams{ 138 Series: version.SupportedLTS(), 139 Placement: "zone=away-zone", 140 VolumeAttachments: []storage.VolumeAttachmentParams{{ 141 VolumeId: "home-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4", 142 }}, 143 }) 144 145 c.Check(err, gc.ErrorMatches, `cannot create instance with placement "zone=away-zone", as this will prevent attaching the requested disks in zone "home-zone"`) 146 } 147 148 func (s *environPolSuite) TestConstraintsValidator(c *gc.C) { 149 validator, err := s.Env.ConstraintsValidator(s.CallCtx) 150 c.Assert(err, jc.ErrorIsNil) 151 152 cons := constraints.MustParse("arch=amd64") 153 unsupported, err := validator.Validate(cons) 154 c.Assert(err, jc.ErrorIsNil) 155 c.Check(unsupported, gc.HasLen, 0) 156 } 157 158 func (s *environPolSuite) TestConstraintsValidatorEmpty(c *gc.C) { 159 validator, err := s.Env.ConstraintsValidator(s.CallCtx) 160 c.Assert(err, jc.ErrorIsNil) 161 162 unsupported, err := validator.Validate(constraints.Value{}) 163 c.Assert(err, jc.ErrorIsNil) 164 165 c.Check(unsupported, gc.HasLen, 0) 166 } 167 168 func (s *environPolSuite) TestConstraintsValidatorUnsupported(c *gc.C) { 169 validator, err := s.Env.ConstraintsValidator(s.CallCtx) 170 c.Assert(err, jc.ErrorIsNil) 171 172 cons := constraints.MustParse("arch=amd64 tags=foo virt-type=kvm") 173 unsupported, err := validator.Validate(cons) 174 c.Assert(err, jc.ErrorIsNil) 175 176 c.Check(unsupported, jc.SameContents, []string{"tags", "virt-type"}) 177 } 178 179 func (s *environPolSuite) TestConstraintsValidatorVocabInstType(c *gc.C) { 180 validator, err := s.Env.ConstraintsValidator(s.CallCtx) 181 c.Assert(err, jc.ErrorIsNil) 182 183 cons := constraints.MustParse("instance-type=foo") 184 _, err = validator.Validate(cons) 185 186 c.Check(err, gc.ErrorMatches, "invalid constraint value: instance-type=foo\nvalid values are:.*") 187 } 188 189 func (s *environPolSuite) TestConstraintsValidatorVocabContainer(c *gc.C) { 190 validator, err := s.Env.ConstraintsValidator(s.CallCtx) 191 c.Assert(err, jc.ErrorIsNil) 192 193 cons := constraints.MustParse("container=lxd") 194 _, err = validator.Validate(cons) 195 196 c.Check(err, gc.ErrorMatches, "invalid constraint value: container=lxd\nvalid values are:.*") 197 } 198 199 func (s *environPolSuite) TestConstraintsValidatorConflicts(c *gc.C) { 200 validator, err := s.Env.ConstraintsValidator(s.CallCtx) 201 c.Assert(err, jc.ErrorIsNil) 202 203 cons := constraints.MustParse("instance-type=n1-standard-1") 204 // We do not check arch or container since there is only one valid 205 // value for each and will always match. 206 consFallback := constraints.MustParse("cores=2 cpu-power=1000 mem=10000 tags=bar") 207 merged, err := validator.Merge(consFallback, cons) 208 c.Assert(err, jc.ErrorIsNil) 209 210 // tags is not supported, but we're not validating here... 211 expected := constraints.MustParse("instance-type=n1-standard-1 tags=bar") 212 c.Check(merged, jc.DeepEquals, expected) 213 } 214 215 func (s *environPolSuite) TestSupportNetworks(c *gc.C) { 216 isSupported := s.Env.SupportNetworks(s.CallCtx) 217 218 c.Check(isSupported, jc.IsFalse) 219 }