github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/provider/local/environprovider_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package local_test 5 6 import ( 7 "errors" 8 "os/user" 9 10 "github.com/juju/loggo" 11 "github.com/juju/testing" 12 "github.com/juju/utils/apt" 13 "github.com/juju/utils/proxy" 14 gc "launchpad.net/gocheck" 15 16 lxctesting "github.com/juju/juju/container/lxc/testing" 17 "github.com/juju/juju/environs" 18 "github.com/juju/juju/environs/config" 19 "github.com/juju/juju/provider" 20 "github.com/juju/juju/provider/local" 21 coretesting "github.com/juju/juju/testing" 22 ) 23 24 type baseProviderSuite struct { 25 lxctesting.TestSuite 26 restore func() 27 } 28 29 func (s *baseProviderSuite) SetUpTest(c *gc.C) { 30 s.TestSuite.SetUpTest(c) 31 loggo.GetLogger("juju.provider.local").SetLogLevel(loggo.TRACE) 32 s.restore = local.MockAddressForInterface() 33 } 34 35 func (s *baseProviderSuite) TearDownTest(c *gc.C) { 36 s.restore() 37 s.TestSuite.TearDownTest(c) 38 } 39 40 type prepareSuite struct { 41 coretesting.FakeJujuHomeSuite 42 } 43 44 var _ = gc.Suite(&prepareSuite{}) 45 46 func (s *prepareSuite) SetUpTest(c *gc.C) { 47 s.FakeJujuHomeSuite.SetUpTest(c) 48 loggo.GetLogger("juju.provider.local").SetLogLevel(loggo.TRACE) 49 s.PatchEnvironment("http_proxy", "") 50 s.PatchEnvironment("HTTP_PROXY", "") 51 s.PatchEnvironment("https_proxy", "") 52 s.PatchEnvironment("HTTPS_PROXY", "") 53 s.PatchEnvironment("ftp_proxy", "") 54 s.PatchEnvironment("FTP_PROXY", "") 55 s.PatchEnvironment("no_proxy", "") 56 s.PatchEnvironment("NO_PROXY", "") 57 s.HookCommandOutput(&apt.CommandOutput, nil, nil) 58 s.PatchValue(local.CheckLocalPort, func(port int, desc string) error { 59 return nil 60 }) 61 restore := local.MockAddressForInterface() 62 s.AddCleanup(func(*gc.C) { restore() }) 63 } 64 65 func (s *prepareSuite) TestPrepareCapturesEnvironment(c *gc.C) { 66 baseConfig, err := config.New(config.UseDefaults, map[string]interface{}{ 67 "type": provider.Local, 68 "name": "test", 69 }) 70 c.Assert(err, gc.IsNil) 71 provider, err := environs.Provider(provider.Local) 72 c.Assert(err, gc.IsNil) 73 74 for i, test := range []struct { 75 message string 76 extraConfig map[string]interface{} 77 env map[string]string 78 aptOutput string 79 expectedProxy proxy.Settings 80 expectedAptProxy proxy.Settings 81 }{{ 82 message: "nothing set", 83 }, { 84 message: "grabs proxy from environment", 85 env: map[string]string{ 86 "http_proxy": "http://user@10.0.0.1", 87 "HTTPS_PROXY": "https://user@10.0.0.1", 88 "ftp_proxy": "ftp://user@10.0.0.1", 89 "no_proxy": "localhost,10.0.3.1", 90 }, 91 expectedProxy: proxy.Settings{ 92 Http: "http://user@10.0.0.1", 93 Https: "https://user@10.0.0.1", 94 Ftp: "ftp://user@10.0.0.1", 95 NoProxy: "localhost,10.0.3.1", 96 }, 97 expectedAptProxy: proxy.Settings{ 98 Http: "http://user@10.0.0.1", 99 Https: "https://user@10.0.0.1", 100 Ftp: "ftp://user@10.0.0.1", 101 }, 102 }, { 103 message: "skips proxy from environment if http-proxy set", 104 extraConfig: map[string]interface{}{ 105 "http-proxy": "http://user@10.0.0.42", 106 }, 107 env: map[string]string{ 108 "http_proxy": "http://user@10.0.0.1", 109 "HTTPS_PROXY": "https://user@10.0.0.1", 110 "ftp_proxy": "ftp://user@10.0.0.1", 111 }, 112 expectedProxy: proxy.Settings{ 113 Http: "http://user@10.0.0.42", 114 }, 115 expectedAptProxy: proxy.Settings{ 116 Http: "http://user@10.0.0.42", 117 }, 118 }, { 119 message: "skips proxy from environment if https-proxy set", 120 extraConfig: map[string]interface{}{ 121 "https-proxy": "https://user@10.0.0.42", 122 }, 123 env: map[string]string{ 124 "http_proxy": "http://user@10.0.0.1", 125 "HTTPS_PROXY": "https://user@10.0.0.1", 126 "ftp_proxy": "ftp://user@10.0.0.1", 127 }, 128 expectedProxy: proxy.Settings{ 129 Https: "https://user@10.0.0.42", 130 }, 131 expectedAptProxy: proxy.Settings{ 132 Https: "https://user@10.0.0.42", 133 }, 134 }, { 135 message: "skips proxy from environment if ftp-proxy set", 136 extraConfig: map[string]interface{}{ 137 "ftp-proxy": "ftp://user@10.0.0.42", 138 }, 139 env: map[string]string{ 140 "http_proxy": "http://user@10.0.0.1", 141 "HTTPS_PROXY": "https://user@10.0.0.1", 142 "ftp_proxy": "ftp://user@10.0.0.1", 143 }, 144 expectedProxy: proxy.Settings{ 145 Ftp: "ftp://user@10.0.0.42", 146 }, 147 expectedAptProxy: proxy.Settings{ 148 Ftp: "ftp://user@10.0.0.42", 149 }, 150 }, { 151 message: "skips proxy from environment if no-proxy set", 152 extraConfig: map[string]interface{}{ 153 "no-proxy": "localhost,10.0.3.1", 154 }, 155 env: map[string]string{ 156 "http_proxy": "http://user@10.0.0.1", 157 "HTTPS_PROXY": "https://user@10.0.0.1", 158 "ftp_proxy": "ftp://user@10.0.0.1", 159 }, 160 expectedProxy: proxy.Settings{ 161 NoProxy: "localhost,10.0.3.1", 162 }, 163 }, { 164 message: "apt-proxies detected", 165 aptOutput: `CommandLine::AsString "apt-config dump"; 166 Acquire::http::Proxy "10.0.3.1:3142"; 167 Acquire::https::Proxy "false"; 168 Acquire::ftp::Proxy "none"; 169 Acquire::magic::Proxy "none"; 170 `, 171 expectedAptProxy: proxy.Settings{ 172 Http: "10.0.3.1:3142", 173 Https: "false", 174 Ftp: "none", 175 }, 176 }, { 177 message: "apt-proxies not used if apt-http-proxy set", 178 extraConfig: map[string]interface{}{ 179 "apt-http-proxy": "value-set", 180 }, 181 aptOutput: `CommandLine::AsString "apt-config dump"; 182 Acquire::http::Proxy "10.0.3.1:3142"; 183 Acquire::https::Proxy "false"; 184 Acquire::ftp::Proxy "none"; 185 Acquire::magic::Proxy "none"; 186 `, 187 expectedAptProxy: proxy.Settings{ 188 Http: "value-set", 189 }, 190 }, { 191 message: "apt-proxies not used if apt-https-proxy set", 192 extraConfig: map[string]interface{}{ 193 "apt-https-proxy": "value-set", 194 }, 195 aptOutput: `CommandLine::AsString "apt-config dump"; 196 Acquire::http::Proxy "10.0.3.1:3142"; 197 Acquire::https::Proxy "false"; 198 Acquire::ftp::Proxy "none"; 199 Acquire::magic::Proxy "none"; 200 `, 201 expectedAptProxy: proxy.Settings{ 202 Https: "value-set", 203 }, 204 }, { 205 message: "apt-proxies not used if apt-ftp-proxy set", 206 extraConfig: map[string]interface{}{ 207 "apt-ftp-proxy": "value-set", 208 }, 209 aptOutput: `CommandLine::AsString "apt-config dump"; 210 Acquire::http::Proxy "10.0.3.1:3142"; 211 Acquire::https::Proxy "false"; 212 Acquire::ftp::Proxy "none"; 213 Acquire::magic::Proxy "none"; 214 `, 215 expectedAptProxy: proxy.Settings{ 216 Ftp: "value-set", 217 }, 218 }} { 219 c.Logf("\n%v: %s", i, test.message) 220 cleanup := []func(){} 221 for key, value := range test.env { 222 restore := testing.PatchEnvironment(key, value) 223 cleanup = append(cleanup, restore) 224 } 225 _, restore := testing.HookCommandOutput(&apt.CommandOutput, []byte(test.aptOutput), nil) 226 cleanup = append(cleanup, restore) 227 testConfig := baseConfig 228 if test.extraConfig != nil { 229 testConfig, err = baseConfig.Apply(test.extraConfig) 230 c.Assert(err, gc.IsNil) 231 } 232 env, err := provider.Prepare(coretesting.Context(c), testConfig) 233 c.Assert(err, gc.IsNil) 234 235 envConfig := env.Config() 236 c.Assert(envConfig.HttpProxy(), gc.Equals, test.expectedProxy.Http) 237 c.Assert(envConfig.HttpsProxy(), gc.Equals, test.expectedProxy.Https) 238 c.Assert(envConfig.FtpProxy(), gc.Equals, test.expectedProxy.Ftp) 239 c.Assert(envConfig.NoProxy(), gc.Equals, test.expectedProxy.NoProxy) 240 241 c.Assert(envConfig.AptHttpProxy(), gc.Equals, test.expectedAptProxy.Http) 242 c.Assert(envConfig.AptHttpsProxy(), gc.Equals, test.expectedAptProxy.Https) 243 c.Assert(envConfig.AptFtpProxy(), gc.Equals, test.expectedAptProxy.Ftp) 244 245 for _, clean := range cleanup { 246 clean() 247 } 248 } 249 } 250 251 func (s *prepareSuite) TestPrepareNamespace(c *gc.C) { 252 s.PatchValue(local.DetectAptProxies, func() (proxy.Settings, error) { 253 return proxy.Settings{}, nil 254 }) 255 basecfg, err := config.New(config.UseDefaults, map[string]interface{}{ 256 "type": "local", 257 "name": "test", 258 }) 259 provider, err := environs.Provider("local") 260 c.Assert(err, gc.IsNil) 261 262 type test struct { 263 userEnv string 264 userOS string 265 userOSErr error 266 namespace string 267 err string 268 } 269 tests := []test{{ 270 userEnv: "someone", 271 userOS: "other", 272 namespace: "someone-test", 273 }, { 274 userOS: "other", 275 namespace: "other-test", 276 }, { 277 userOSErr: errors.New("oh noes"), 278 err: "failed to determine username for namespace: oh noes", 279 }} 280 281 for i, test := range tests { 282 c.Logf("test %d: %v", i, test) 283 s.PatchEnvironment("USER", test.userEnv) 284 s.PatchValue(local.UserCurrent, func() (*user.User, error) { 285 return &user.User{Username: test.userOS}, test.userOSErr 286 }) 287 env, err := provider.Prepare(coretesting.Context(c), basecfg) 288 if test.err == "" { 289 c.Assert(err, gc.IsNil) 290 cfg := env.Config() 291 c.Assert(cfg.UnknownAttrs()["namespace"], gc.Equals, test.namespace) 292 } else { 293 c.Assert(err, gc.ErrorMatches, test.err) 294 } 295 } 296 } 297 298 func (s *prepareSuite) TestPrepareProxySSH(c *gc.C) { 299 s.PatchValue(local.DetectAptProxies, func() (proxy.Settings, error) { 300 return proxy.Settings{}, nil 301 }) 302 basecfg, err := config.New(config.UseDefaults, map[string]interface{}{ 303 "type": "local", 304 "name": "test", 305 }) 306 provider, err := environs.Provider("local") 307 c.Assert(err, gc.IsNil) 308 env, err := provider.Prepare(coretesting.Context(c), basecfg) 309 c.Assert(err, gc.IsNil) 310 // local provider sets proxy-ssh to false 311 c.Assert(env.Config().ProxySSH(), gc.Equals, false) 312 }