github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/lxd/environ_policy_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package lxd_test 5 6 import ( 7 "strings" 8 9 "github.com/golang/mock/gomock" 10 jc "github.com/juju/testing/checkers" 11 "github.com/juju/utils/arch" 12 "github.com/lxc/lxd/shared/api" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/core/constraints" 16 "github.com/juju/juju/environs" 17 "github.com/juju/juju/environs/context" 18 "github.com/juju/juju/juju/version" 19 "github.com/juju/juju/provider/lxd" 20 ) 21 22 type environPolicySuite struct { 23 lxd.EnvironSuite 24 25 callCtx context.ProviderCallContext 26 } 27 28 var _ = gc.Suite(&environPolicySuite{}) 29 30 func (s *environPolicySuite) SetUpTest(c *gc.C) { 31 s.BaseSuite.SetUpTest(c) 32 s.callCtx = context.NewCloudCallContext() 33 } 34 35 func (s *environPolicySuite) TestPrecheckInstanceDefaults(c *gc.C) { 36 ctrl := gomock.NewController(c) 37 defer ctrl.Finish() 38 svr := lxd.NewMockServer(ctrl) 39 40 env := s.NewEnviron(c, svr, nil) 41 err := env.PrecheckInstance(context.NewCloudCallContext(), environs.PrecheckInstanceParams{Series: version.SupportedLTS()}) 42 c.Assert(err, jc.ErrorIsNil) 43 } 44 45 func (s *environPolicySuite) TestPrecheckInstanceHasInstanceType(c *gc.C) { 46 ctrl := gomock.NewController(c) 47 defer ctrl.Finish() 48 svr := lxd.NewMockServer(ctrl) 49 50 env := s.NewEnviron(c, svr, nil) 51 52 cons := constraints.MustParse("instance-type=some-instance-type") 53 err := env.PrecheckInstance(context.NewCloudCallContext(), environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons}) 54 55 c.Check(err, jc.ErrorIsNil) 56 } 57 58 func (s *environPolicySuite) TestPrecheckInstanceDiskSize(c *gc.C) { 59 ctrl := gomock.NewController(c) 60 defer ctrl.Finish() 61 svr := lxd.NewMockServer(ctrl) 62 63 env := s.NewEnviron(c, svr, nil) 64 65 cons := constraints.MustParse("root-disk=1G") 66 err := env.PrecheckInstance(context.NewCloudCallContext(), environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons}) 67 68 c.Check(err, jc.ErrorIsNil) 69 } 70 71 func (s *environPolicySuite) TestPrecheckInstanceUnsupportedArch(c *gc.C) { 72 ctrl := gomock.NewController(c) 73 defer ctrl.Finish() 74 svr := lxd.NewMockServer(ctrl) 75 76 cons := constraints.MustParse("arch=i386") 77 78 env := s.NewEnviron(c, svr, nil) 79 err := env.PrecheckInstance(context.NewCloudCallContext(), environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Constraints: cons}) 80 81 c.Check(err, jc.ErrorIsNil) 82 } 83 84 func (s *environPolicySuite) TestPrecheckInstanceAvailZone(c *gc.C) { 85 ctrl := gomock.NewController(c) 86 defer ctrl.Finish() 87 svr := lxd.NewMockServer(ctrl) 88 89 env := s.NewEnviron(c, svr, nil) 90 91 members := []api.ClusterMember{ 92 { 93 ServerName: "node01", 94 Status: "ONLINE", 95 }, 96 { 97 ServerName: "node02", 98 Status: "ONLINE", 99 }, 100 } 101 102 exp := svr.EXPECT() 103 gomock.InOrder( 104 exp.IsClustered().Return(true), 105 exp.GetClusterMembers().Return(members, nil), 106 ) 107 108 placement := "zone=a-zone" 109 err := env.PrecheckInstance(context.NewCloudCallContext(), environs.PrecheckInstanceParams{Series: version.SupportedLTS(), Placement: placement}) 110 111 c.Check(err, gc.ErrorMatches, `availability zone "a-zone" not valid`) 112 } 113 114 func (s *environPolicySuite) TestConstraintsValidatorOkay(c *gc.C) { 115 ctrl := gomock.NewController(c) 116 defer ctrl.Finish() 117 svr := lxd.NewMockServer(ctrl) 118 119 env := s.NewEnviron(c, svr, nil) 120 121 exp := svr.EXPECT() 122 exp.HostArch().Return(arch.AMD64) 123 124 validator, err := env.ConstraintsValidator(context.NewCloudCallContext()) 125 c.Assert(err, jc.ErrorIsNil) 126 127 cons := constraints.MustParse("arch=amd64") 128 unsupported, err := validator.Validate(cons) 129 c.Assert(err, jc.ErrorIsNil) 130 131 c.Check(unsupported, gc.HasLen, 0) 132 } 133 134 func (s *environPolicySuite) TestConstraintsValidatorEmpty(c *gc.C) { 135 ctrl := gomock.NewController(c) 136 defer ctrl.Finish() 137 svr := lxd.NewMockServer(ctrl) 138 139 env := s.NewEnviron(c, svr, nil) 140 141 exp := svr.EXPECT() 142 exp.HostArch().Return(arch.AMD64) 143 144 validator, err := env.ConstraintsValidator(context.NewCloudCallContext()) 145 c.Assert(err, jc.ErrorIsNil) 146 147 unsupported, err := validator.Validate(constraints.Value{}) 148 c.Assert(err, jc.ErrorIsNil) 149 150 c.Check(unsupported, gc.HasLen, 0) 151 } 152 153 func (s *environPolicySuite) TestConstraintsValidatorUnsupported(c *gc.C) { 154 ctrl := gomock.NewController(c) 155 defer ctrl.Finish() 156 svr := lxd.NewMockServer(ctrl) 157 158 env := s.NewEnviron(c, svr, nil) 159 160 exp := svr.EXPECT() 161 exp.HostArch().Return(arch.AMD64) 162 163 validator, err := env.ConstraintsValidator(context.NewCloudCallContext()) 164 c.Assert(err, jc.ErrorIsNil) 165 166 cons := constraints.MustParse(strings.Join([]string{ 167 "arch=amd64", 168 "tags=foo", 169 "mem=3", 170 "instance-type=some-type", 171 "cores=2", 172 "cpu-power=250", 173 "virt-type=kvm", 174 }, " ")) 175 unsupported, err := validator.Validate(cons) 176 c.Assert(err, jc.ErrorIsNil) 177 178 expected := []string{ 179 "tags", 180 "cpu-power", 181 "virt-type", 182 } 183 c.Check(unsupported, jc.SameContents, expected) 184 } 185 186 func (s *environPolicySuite) TestConstraintsValidatorVocabArchKnown(c *gc.C) { 187 ctrl := gomock.NewController(c) 188 defer ctrl.Finish() 189 svr := lxd.NewMockServer(ctrl) 190 191 env := s.NewEnviron(c, svr, nil) 192 193 exp := svr.EXPECT() 194 exp.HostArch().Return(arch.AMD64) 195 196 validator, err := env.ConstraintsValidator(context.NewCloudCallContext()) 197 c.Assert(err, jc.ErrorIsNil) 198 199 cons := constraints.MustParse("arch=amd64") 200 _, err = validator.Validate(cons) 201 202 c.Check(err, jc.ErrorIsNil) 203 } 204 205 func (s *environPolicySuite) TestConstraintsValidatorVocabArchUnknown(c *gc.C) { 206 ctrl := gomock.NewController(c) 207 defer ctrl.Finish() 208 svr := lxd.NewMockServer(ctrl) 209 210 env := s.NewEnviron(c, svr, nil) 211 212 exp := svr.EXPECT() 213 exp.HostArch().Return(arch.AMD64) 214 215 validator, err := env.ConstraintsValidator(context.NewCloudCallContext()) 216 c.Assert(err, jc.ErrorIsNil) 217 218 cons := constraints.MustParse("arch=ppc64el") 219 _, err = validator.Validate(cons) 220 221 c.Check(err, gc.ErrorMatches, "invalid constraint value: arch=ppc64el\nvalid values are: \\[amd64\\]") 222 } 223 224 func (s *environPolicySuite) TestConstraintsValidatorVocabContainerUnknown(c *gc.C) { 225 c.Skip("this will fail until we add a container vocabulary") 226 ctrl := gomock.NewController(c) 227 defer ctrl.Finish() 228 svr := lxd.NewMockServer(ctrl) 229 230 env := s.NewEnviron(c, svr, nil) 231 232 validator, err := env.ConstraintsValidator(context.NewCloudCallContext()) 233 c.Assert(err, jc.ErrorIsNil) 234 235 cons := constraints.MustParse("container=lxd") 236 _, err = validator.Validate(cons) 237 238 c.Check(err, gc.ErrorMatches, "invalid constraint value: container=lxd\nvalid values are:.*") 239 } 240 241 func (s *environPolicySuite) TestConstraintsValidatorConflicts(c *gc.C) { 242 ctrl := gomock.NewController(c) 243 defer ctrl.Finish() 244 svr := lxd.NewMockServer(ctrl) 245 246 env := s.NewEnviron(c, svr, nil) 247 248 exp := svr.EXPECT() 249 exp.HostArch().Return(arch.AMD64) 250 251 validator, err := env.ConstraintsValidator(context.NewCloudCallContext()) 252 c.Assert(err, jc.ErrorIsNil) 253 254 cons := constraints.MustParse("instance-type=n1-standard-1") 255 consFallback := constraints.MustParse("cores=2 cpu-power=1000 mem=10000 tags=bar") 256 merged, err := validator.Merge(consFallback, cons) 257 c.Assert(err, jc.ErrorIsNil) 258 259 // tags is not supported, but we're not validating here... 260 expected := constraints.MustParse("instance-type=n1-standard-1 tags=bar cores=2 cpu-power=1000 mem=10000") 261 c.Check(merged, jc.DeepEquals, expected) 262 } 263 264 func (s *environPolicySuite) TestSupportNetworks(c *gc.C) { 265 ctrl := gomock.NewController(c) 266 defer ctrl.Finish() 267 svr := lxd.NewMockServer(ctrl) 268 269 env := s.NewEnviron(c, svr, nil) 270 271 isSupported := env.(interface { 272 SupportNetworks(context.ProviderCallContext) bool 273 }).SupportNetworks(context.NewCloudCallContext()) 274 275 c.Check(isSupported, jc.IsFalse) 276 }