github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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 "os" 8 9 "github.com/juju/errors" 10 "github.com/juju/testing" 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils/arch" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/constraints" 16 "github.com/juju/juju/environs" 17 "github.com/juju/juju/instance" 18 coretesting "github.com/juju/juju/testing" 19 ) 20 21 type environSuite struct { 22 coretesting.FakeJujuXDGDataHomeSuite 23 env *manualEnviron 24 } 25 26 var _ = gc.Suite(&environSuite{}) 27 28 func (s *environSuite) SetUpTest(c *gc.C) { 29 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 30 env, err := manualProvider{}.Open(MinimalConfig(c)) 31 c.Assert(err, jc.ErrorIsNil) 32 s.env = env.(*manualEnviron) 33 } 34 35 func (s *environSuite) TestSetConfig(c *gc.C) { 36 err := s.env.SetConfig(MinimalConfig(c)) 37 c.Assert(err, jc.ErrorIsNil) 38 39 testConfig := MinimalConfig(c) 40 testConfig, err = testConfig.Apply(map[string]interface{}{"bootstrap-host": ""}) 41 c.Assert(err, jc.ErrorIsNil) 42 err = s.env.SetConfig(testConfig) 43 c.Assert(err, gc.ErrorMatches, "bootstrap-host must be specified") 44 } 45 46 func (s *environSuite) TestInstances(c *gc.C) { 47 var ids []instance.Id 48 49 instances, err := s.env.Instances(ids) 50 c.Assert(err, gc.Equals, environs.ErrNoInstances) 51 c.Assert(instances, gc.HasLen, 0) 52 53 ids = append(ids, BootstrapInstanceId) 54 instances, err = s.env.Instances(ids) 55 c.Assert(err, jc.ErrorIsNil) 56 c.Assert(instances, gc.HasLen, 1) 57 c.Assert(instances[0], gc.NotNil) 58 59 ids = append(ids, BootstrapInstanceId) 60 instances, err = s.env.Instances(ids) 61 c.Assert(err, jc.ErrorIsNil) 62 c.Assert(instances, gc.HasLen, 2) 63 c.Assert(instances[0], gc.NotNil) 64 c.Assert(instances[1], gc.NotNil) 65 66 ids = append(ids, instance.Id("invalid")) 67 instances, err = s.env.Instances(ids) 68 c.Assert(err, gc.Equals, environs.ErrPartialInstances) 69 c.Assert(instances, gc.HasLen, 3) 70 c.Assert(instances[0], gc.NotNil) 71 c.Assert(instances[1], gc.NotNil) 72 c.Assert(instances[2], gc.IsNil) 73 74 ids = []instance.Id{instance.Id("invalid")} 75 instances, err = s.env.Instances(ids) 76 c.Assert(err, gc.Equals, environs.ErrNoInstances) 77 c.Assert(instances, gc.HasLen, 1) 78 c.Assert(instances[0], gc.IsNil) 79 } 80 81 func (s *environSuite) TestDestroy(c *gc.C) { 82 var resultStderr string 83 var resultErr error 84 runSSHCommandTesting := func(host string, command []string, stdin string) (string, error) { 85 c.Assert(host, gc.Equals, "ubuntu@hostname") 86 c.Assert(command, gc.DeepEquals, []string{"sudo", "/bin/bash"}) 87 c.Assert(stdin, jc.DeepEquals, ` 88 set -x 89 touch '/var/lib/juju/uninstall-agent' 90 pkill -6 jujud && exit 91 stop juju-db 92 rm -f /etc/init/juju* 93 rm -fr '/var/lib/juju' '/var/log/juju' 94 exit 0 95 `) 96 return resultStderr, resultErr 97 } 98 s.PatchValue(&runSSHCommand, runSSHCommandTesting) 99 type test struct { 100 stderr string 101 err error 102 match string 103 } 104 tests := []test{ 105 {"", nil, ""}, 106 {"abc", nil, ""}, 107 {"", errors.New("oh noes"), "oh noes"}, 108 } 109 for i, t := range tests { 110 c.Logf("test %d: %v", i, t) 111 resultStderr, resultErr = t.stderr, t.err 112 err := s.env.Destroy() 113 if t.match == "" { 114 c.Assert(err, jc.ErrorIsNil) 115 } else { 116 c.Assert(err, gc.ErrorMatches, t.match) 117 } 118 } 119 } 120 121 func (s *environSuite) TestSupportedArchitectures(c *gc.C) { 122 arches, err := s.env.SupportedArchitectures() 123 c.Assert(err, jc.ErrorIsNil) 124 c.Assert(arches, gc.DeepEquals, arch.AllSupportedArches) 125 } 126 127 func (s *environSuite) TestSupportsNetworking(c *gc.C) { 128 _, ok := environs.SupportsNetworking(s.env) 129 c.Assert(ok, jc.IsFalse) 130 } 131 132 func (s *environSuite) TestConstraintsValidator(c *gc.C) { 133 validator, err := s.env.ConstraintsValidator() 134 c.Assert(err, jc.ErrorIsNil) 135 cons := constraints.MustParse("arch=amd64 instance-type=foo tags=bar cpu-power=10 cpu-cores=2 mem=1G virt-type=kvm") 136 unsupported, err := validator.Validate(cons) 137 c.Assert(err, jc.ErrorIsNil) 138 c.Assert(unsupported, jc.SameContents, []string{"cpu-power", "instance-type", "tags", "virt-type"}) 139 } 140 141 type bootstrapSuite struct { 142 coretesting.FakeJujuXDGDataHomeSuite 143 env *manualEnviron 144 } 145 146 var _ = gc.Suite(&bootstrapSuite{}) 147 148 func (s *bootstrapSuite) SetUpTest(c *gc.C) { 149 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 150 env, err := manualProvider{}.Open(MinimalConfig(c)) 151 c.Assert(err, jc.ErrorIsNil) 152 s.env = env.(*manualEnviron) 153 } 154 155 type controllerInstancesSuite struct { 156 coretesting.FakeJujuXDGDataHomeSuite 157 env *manualEnviron 158 } 159 160 var _ = gc.Suite(&controllerInstancesSuite{}) 161 162 func (s *controllerInstancesSuite) SetUpTest(c *gc.C) { 163 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 164 env, err := manualProvider{}.Open(MinimalConfig(c)) 165 c.Assert(err, jc.ErrorIsNil) 166 s.env = env.(*manualEnviron) 167 } 168 169 func (s *controllerInstancesSuite) TestControllerInstances(c *gc.C) { 170 var outputResult string 171 var errResult error 172 runSSHCommandTesting := func(host string, command []string, stdin string) (string, error) { 173 return outputResult, errResult 174 } 175 s.PatchValue(&runSSHCommand, runSSHCommandTesting) 176 177 type test struct { 178 output string 179 err error 180 expectedErr string 181 } 182 tests := []test{{ 183 output: "", 184 }, { 185 output: "no-agent-dir", 186 expectedErr: "model is not bootstrapped", 187 }, { 188 output: "woo", 189 expectedErr: `unexpected output: "woo"`, 190 }, { 191 err: errors.New("an error"), 192 expectedErr: "an error", 193 }} 194 195 for i, test := range tests { 196 c.Logf("test %d", i) 197 outputResult = test.output 198 errResult = test.err 199 instances, err := s.env.ControllerInstances() 200 if test.expectedErr == "" { 201 c.Assert(err, jc.ErrorIsNil) 202 c.Assert(instances, gc.DeepEquals, []instance.Id{BootstrapInstanceId}) 203 } else { 204 c.Assert(err, gc.ErrorMatches, test.expectedErr) 205 c.Assert(instances, gc.HasLen, 0) 206 } 207 } 208 } 209 210 func (s *controllerInstancesSuite) TestControllerInstancesStderr(c *gc.C) { 211 // Stderr should not affect the behaviour of ControllerInstances. 212 testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 0") 213 _, err := s.env.ControllerInstances() 214 c.Assert(err, jc.ErrorIsNil) 215 } 216 217 func (s *controllerInstancesSuite) TestControllerInstancesError(c *gc.C) { 218 // If the ssh execution fails, its stderr will be captured in the error message. 219 testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 1") 220 _, err := s.env.ControllerInstances() 221 c.Assert(err, gc.ErrorMatches, "abc: .*") 222 } 223 224 func (s *controllerInstancesSuite) TestControllerInstancesInternal(c *gc.C) { 225 // Patch os.Args so it appears that we're running in "jujud". 226 s.PatchValue(&os.Args, []string{"/some/where/containing/jujud", "whatever"}) 227 // Patch the ssh executable so that it would cause an error if we 228 // were to call it. 229 testing.PatchExecutable(c, s, "ssh", "#!/bin/sh\nhead -n1 > /dev/null; echo abc >&2; exit 1") 230 instances, err := s.env.ControllerInstances() 231 c.Assert(err, jc.ErrorIsNil) 232 c.Assert(instances, gc.DeepEquals, []instance.Id{BootstrapInstanceId}) 233 }