github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/provider/manual/environ_test.go (about) 1 // Copyright 2012 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package manual 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/testing" 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/constraints" 13 "github.com/juju/juju/environs" 14 "github.com/juju/juju/environs/storage" 15 envtesting "github.com/juju/juju/environs/testing" 16 "github.com/juju/juju/instance" 17 "github.com/juju/juju/juju/arch" 18 coretesting "github.com/juju/juju/testing" 19 "github.com/juju/juju/version" 20 ) 21 22 type environSuite struct { 23 coretesting.FakeJujuHomeSuite 24 env *manualEnviron 25 } 26 27 type dummyStorage struct { 28 storage.Storage 29 } 30 31 var _ = gc.Suite(&environSuite{}) 32 33 func (s *environSuite) SetUpTest(c *gc.C) { 34 s.FakeJujuHomeSuite.SetUpTest(c) 35 env, err := manualProvider{}.Open(MinimalConfig(c)) 36 c.Assert(err, jc.ErrorIsNil) 37 s.env = env.(*manualEnviron) 38 } 39 40 func (s *environSuite) TestSetConfig(c *gc.C) { 41 err := s.env.SetConfig(MinimalConfig(c)) 42 c.Assert(err, jc.ErrorIsNil) 43 44 testConfig := MinimalConfig(c) 45 testConfig, err = testConfig.Apply(map[string]interface{}{"bootstrap-host": ""}) 46 c.Assert(err, jc.ErrorIsNil) 47 err = s.env.SetConfig(testConfig) 48 c.Assert(err, gc.ErrorMatches, "bootstrap-host must be specified") 49 } 50 51 func (s *environSuite) TestInstances(c *gc.C) { 52 var ids []instance.Id 53 54 instances, err := s.env.Instances(ids) 55 c.Assert(err, gc.Equals, environs.ErrNoInstances) 56 c.Assert(instances, gc.HasLen, 0) 57 58 ids = append(ids, BootstrapInstanceId) 59 instances, err = s.env.Instances(ids) 60 c.Assert(err, jc.ErrorIsNil) 61 c.Assert(instances, gc.HasLen, 1) 62 c.Assert(instances[0], gc.NotNil) 63 64 ids = append(ids, BootstrapInstanceId) 65 instances, err = s.env.Instances(ids) 66 c.Assert(err, jc.ErrorIsNil) 67 c.Assert(instances, gc.HasLen, 2) 68 c.Assert(instances[0], gc.NotNil) 69 c.Assert(instances[1], gc.NotNil) 70 71 ids = append(ids, instance.Id("invalid")) 72 instances, err = s.env.Instances(ids) 73 c.Assert(err, gc.Equals, environs.ErrPartialInstances) 74 c.Assert(instances, gc.HasLen, 3) 75 c.Assert(instances[0], gc.NotNil) 76 c.Assert(instances[1], gc.NotNil) 77 c.Assert(instances[2], gc.IsNil) 78 79 ids = []instance.Id{instance.Id("invalid")} 80 instances, err = s.env.Instances(ids) 81 c.Assert(err, gc.Equals, environs.ErrNoInstances) 82 c.Assert(instances, gc.HasLen, 1) 83 c.Assert(instances[0], gc.IsNil) 84 } 85 86 func (s *environSuite) TestDestroy(c *gc.C) { 87 var resultStderr string 88 var resultErr error 89 runSSHCommandTesting := func(host string, command []string, stdin string) (string, error) { 90 c.Assert(host, gc.Equals, "ubuntu@hostname") 91 c.Assert(command, gc.DeepEquals, []string{"sudo", "/bin/bash"}) 92 c.Assert(stdin, gc.DeepEquals, ` 93 set -x 94 pkill -6 jujud && exit 95 stop juju-db 96 rm -f /etc/init/juju* 97 rm -f /etc/rsyslog.d/*juju* 98 rm -fr '/var/lib/juju' '/var/log/juju' 99 exit 0 100 `) 101 return resultStderr, resultErr 102 } 103 s.PatchValue(&runSSHCommand, runSSHCommandTesting) 104 type test struct { 105 stderr string 106 err error 107 match string 108 } 109 tests := []test{ 110 {"", nil, ""}, 111 {"abc", nil, ""}, 112 {"", errors.New("oh noes"), "oh noes"}, 113 } 114 for i, t := range tests { 115 c.Logf("test %d: %v", i, t) 116 resultStderr, resultErr = t.stderr, t.err 117 err := s.env.Destroy() 118 if t.match == "" { 119 c.Assert(err, jc.ErrorIsNil) 120 } else { 121 c.Assert(err, gc.ErrorMatches, t.match) 122 } 123 } 124 } 125 126 func (s *environSuite) TestLocalStorageConfig(c *gc.C) { 127 c.Assert(s.env.StorageDir(), gc.Equals, "/var/lib/juju/storage") 128 c.Assert(s.env.cfg.storageListenAddr(), gc.Equals, ":8040") 129 c.Assert(s.env.StorageAddr(), gc.Equals, s.env.cfg.storageListenAddr()) 130 c.Assert(s.env.SharedStorageAddr(), gc.Equals, "") 131 c.Assert(s.env.SharedStorageDir(), gc.Equals, "") 132 } 133 134 func (s *environSuite) TestSupportedArchitectures(c *gc.C) { 135 arches, err := s.env.SupportedArchitectures() 136 c.Assert(err, jc.ErrorIsNil) 137 c.Assert(arches, gc.DeepEquals, arch.AllSupportedArches) 138 } 139 140 func (s *environSuite) TestSupportsNetworking(c *gc.C) { 141 _, ok := environs.SupportsNetworking(s.env) 142 c.Assert(ok, jc.IsFalse) 143 } 144 145 func (s *environSuite) TestConstraintsValidator(c *gc.C) { 146 validator, err := s.env.ConstraintsValidator() 147 c.Assert(err, jc.ErrorIsNil) 148 cons := constraints.MustParse("arch=amd64 instance-type=foo tags=bar cpu-power=10 cpu-cores=2 mem=1G") 149 unsupported, err := validator.Validate(cons) 150 c.Assert(err, jc.ErrorIsNil) 151 c.Assert(unsupported, jc.SameContents, []string{"cpu-power", "instance-type", "tags"}) 152 } 153 154 type bootstrapSuite struct { 155 coretesting.FakeJujuHomeSuite 156 env *manualEnviron 157 } 158 159 var _ = gc.Suite(&bootstrapSuite{}) 160 161 func (s *bootstrapSuite) SetUpTest(c *gc.C) { 162 s.FakeJujuHomeSuite.SetUpTest(c) 163 164 // ensure use-sshstorage=true to mimic what happens 165 // in the real client: the environment is Prepared, 166 // at which point use-sshstorage=true. 167 cfg := MinimalConfig(c) 168 cfg, err := cfg.Apply(map[string]interface{}{ 169 "use-sshstorage": true, 170 }) 171 c.Assert(err, jc.ErrorIsNil) 172 173 env, err := manualProvider{}.Open(cfg) 174 c.Assert(err, jc.ErrorIsNil) 175 s.env = env.(*manualEnviron) 176 } 177 178 func (s *bootstrapSuite) TestBootstrapClearsUseSSHStorage(c *gc.C) { 179 s.PatchValue(&manualDetectSeriesAndHardwareCharacteristics, func(string) (instance.HardwareCharacteristics, string, error) { 180 arch := version.Current.Arch 181 return instance.HardwareCharacteristics{Arch: &arch}, "precise", nil 182 }) 183 s.PatchValue(&manualCheckProvisioned, func(string) (bool, error) { 184 return false, nil 185 }) 186 187 // use-sshstorage is initially true. 188 cfg := s.env.Config() 189 c.Assert(cfg.UnknownAttrs()["use-sshstorage"], jc.IsTrue) 190 191 _, _, _, err := s.env.Bootstrap(envtesting.BootstrapContext(c), environs.BootstrapParams{}) 192 c.Assert(err, jc.ErrorIsNil) 193 194 // Bootstrap must set use-sshstorage to false within the environment. 195 cfg = s.env.Config() 196 c.Assert(cfg.UnknownAttrs()["use-sshstorage"], jc.IsFalse) 197 } 198 199 type stateServerInstancesSuite struct { 200 coretesting.FakeJujuHomeSuite 201 env *manualEnviron 202 } 203 204 var _ = gc.Suite(&stateServerInstancesSuite{}) 205 206 func (s *stateServerInstancesSuite) SetUpTest(c *gc.C) { 207 s.FakeJujuHomeSuite.SetUpTest(c) 208 209 // ensure use-sshstorage=true, or bootstrap-host 210 // verification won't happen in StateServerInstances. 211 cfg := MinimalConfig(c) 212 cfg, err := cfg.Apply(map[string]interface{}{ 213 "use-sshstorage": true, 214 }) 215 c.Assert(err, jc.ErrorIsNil) 216 217 env, err := manualProvider{}.Open(cfg) 218 c.Assert(err, jc.ErrorIsNil) 219 s.env = env.(*manualEnviron) 220 } 221 222 func (s *stateServerInstancesSuite) TestStateServerInstances(c *gc.C) { 223 var outputResult string 224 var errResult error 225 runSSHCommandTesting := func(host string, command []string, stdin string) (string, error) { 226 return outputResult, errResult 227 } 228 s.PatchValue(&runSSHCommand, runSSHCommandTesting) 229 230 type test struct { 231 output string 232 err error 233 expectedErr string 234 } 235 tests := []test{{ 236 output: "", 237 }, { 238 output: "no-agent-dir", 239 expectedErr: "environment is not bootstrapped", 240 }, { 241 output: "woo", 242 expectedErr: `unexpected output: "woo"`, 243 }, { 244 err: errors.New("an error"), 245 expectedErr: "an error", 246 }} 247 248 for i, test := range tests { 249 c.Logf("test %d", i) 250 outputResult = test.output 251 errResult = test.err 252 instances, err := s.env.StateServerInstances() 253 if test.expectedErr == "" { 254 c.Assert(err, jc.ErrorIsNil) 255 c.Assert(instances, gc.DeepEquals, []instance.Id{BootstrapInstanceId}) 256 } else { 257 c.Assert(err, gc.ErrorMatches, test.expectedErr) 258 c.Assert(instances, gc.HasLen, 0) 259 } 260 } 261 } 262 263 func (s *stateServerInstancesSuite) TestStateServerInstancesStderr(c *gc.C) { 264 // Stderr should not affect the behaviour of StateServerInstances. 265 testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 0") 266 _, err := s.env.StateServerInstances() 267 c.Assert(err, jc.ErrorIsNil) 268 } 269 270 func (s *stateServerInstancesSuite) TestStateServerInstancesError(c *gc.C) { 271 // If the ssh execution fails, its stderr will be captured in the error message. 272 testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 1") 273 _, err := s.env.StateServerInstances() 274 c.Assert(err, gc.ErrorMatches, "abc: .*") 275 } 276 277 func (s *stateServerInstancesSuite) TestStateServerInstancesInternal(c *gc.C) { 278 // If use-sshstorage=false, then we're on the bootstrap host; 279 // verification is elided. 280 env, err := manualProvider{}.Open(MinimalConfig(c)) 281 c.Assert(err, jc.ErrorIsNil) 282 283 testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 1") 284 instances, err := env.StateServerInstances() 285 c.Assert(err, jc.ErrorIsNil) 286 c.Assert(instances, gc.DeepEquals, []instance.Id{BootstrapInstanceId}) 287 }