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  }