github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/proxyupdater/proxyupdater_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package proxyupdater_test
     5  
     6  import (
     7  	"io/ioutil"
     8  	"os"
     9  	"path"
    10  	"runtime"
    11  	"strings"
    12  	"time"
    13  
    14  	jc "github.com/juju/testing/checkers"
    15  	"github.com/juju/utils/packaging/commands"
    16  	pacconfig "github.com/juju/utils/packaging/config"
    17  	"github.com/juju/utils/proxy"
    18  	proxyutils "github.com/juju/utils/proxy"
    19  	"github.com/juju/utils/series"
    20  	gc "gopkg.in/check.v1"
    21  
    22  	coretesting "github.com/juju/juju/testing"
    23  	"github.com/juju/juju/watcher"
    24  	"github.com/juju/juju/worker"
    25  	"github.com/juju/juju/worker/proxyupdater"
    26  	"github.com/juju/juju/worker/workertest"
    27  )
    28  
    29  type ProxyUpdaterSuite struct {
    30  	coretesting.BaseSuite
    31  
    32  	api              *fakeAPI
    33  	proxyFile        string
    34  	detectedSettings proxy.Settings
    35  	config           proxyupdater.Config
    36  }
    37  
    38  var _ = gc.Suite(&ProxyUpdaterSuite{})
    39  
    40  func newNotAWatcher() notAWatcher {
    41  	return notAWatcher{workertest.NewFakeWatcher(2, 2)}
    42  }
    43  
    44  type notAWatcher struct {
    45  	workertest.NotAWatcher
    46  }
    47  
    48  func (w notAWatcher) Changes() watcher.NotifyChannel {
    49  	return w.NotAWatcher.Changes()
    50  }
    51  
    52  type fakeAPI struct {
    53  	Proxy    proxyutils.Settings
    54  	APTProxy proxyutils.Settings
    55  	Err      error
    56  	Watcher  *notAWatcher
    57  }
    58  
    59  func NewFakeAPI() *fakeAPI {
    60  	f := &fakeAPI{}
    61  	return f
    62  }
    63  
    64  func (api fakeAPI) ProxyConfig() (proxyutils.Settings, proxyutils.Settings, error) {
    65  	return api.Proxy, api.APTProxy, api.Err
    66  
    67  }
    68  
    69  func (api fakeAPI) WatchForProxyConfigAndAPIHostPortChanges() (watcher.NotifyWatcher, error) {
    70  	if api.Watcher == nil {
    71  		w := newNotAWatcher()
    72  		api.Watcher = &w
    73  	}
    74  	return api.Watcher, nil
    75  }
    76  
    77  func (s *ProxyUpdaterSuite) SetUpTest(c *gc.C) {
    78  	s.BaseSuite.SetUpTest(c)
    79  	s.api = NewFakeAPI()
    80  
    81  	s.config.Directory = c.MkDir()
    82  	s.config.Filename = "juju-proxy-settings"
    83  	s.config.API = s.api
    84  	s.PatchValue(&pacconfig.AptProxyConfigFile, path.Join(s.config.Directory, "juju-apt-proxy"))
    85  	s.proxyFile = path.Join(s.config.Directory, s.config.Filename)
    86  }
    87  
    88  func (s *ProxyUpdaterSuite) TearDownTest(c *gc.C) {
    89  	s.BaseSuite.TearDownTest(c)
    90  	if s.api.Watcher != nil {
    91  		s.api.Watcher.Close()
    92  	}
    93  }
    94  
    95  func (s *ProxyUpdaterSuite) waitProxySettings(c *gc.C, expected proxy.Settings) {
    96  	for {
    97  		select {
    98  		case <-time.After(time.Second):
    99  			c.Fatalf("timeout while waiting for proxy settings to change")
   100  			return
   101  		case <-time.After(10 * time.Millisecond):
   102  			obtained := proxy.DetectProxies()
   103  			if obtained != expected {
   104  				if obtained != s.detectedSettings {
   105  					c.Logf("proxy settings are \n%#v, should be \n%#v, still waiting", obtained, expected)
   106  				}
   107  				s.detectedSettings = obtained
   108  				continue
   109  			}
   110  			return
   111  		}
   112  	}
   113  }
   114  
   115  func (s *ProxyUpdaterSuite) waitForFile(c *gc.C, filename, expected string) {
   116  	//TODO(bogdanteleaga): Find a way to test this on windows
   117  	if runtime.GOOS == "windows" {
   118  		c.Skip("Proxy settings are written to the registry on windows")
   119  	}
   120  	for {
   121  		select {
   122  		case <-time.After(time.Second):
   123  			c.Fatalf("timeout while waiting for proxy settings to change")
   124  			return
   125  		case <-time.After(10 * time.Millisecond):
   126  			fileContent, err := ioutil.ReadFile(filename)
   127  			if os.IsNotExist(err) {
   128  				continue
   129  			}
   130  			c.Assert(err, jc.ErrorIsNil)
   131  			if string(fileContent) != expected {
   132  				c.Logf("file content not matching, still waiting")
   133  				continue
   134  			}
   135  			return
   136  		}
   137  	}
   138  }
   139  
   140  func (s *ProxyUpdaterSuite) TestRunStop(c *gc.C) {
   141  	updater, err := proxyupdater.NewWorker(s.config)
   142  	c.Assert(err, jc.ErrorIsNil)
   143  	workertest.CleanKill(c, updater)
   144  }
   145  
   146  func (s *ProxyUpdaterSuite) updateConfig(c *gc.C) (proxy.Settings, proxy.Settings) {
   147  	s.api.Proxy = proxy.Settings{
   148  		Http:    "http proxy",
   149  		Https:   "https proxy",
   150  		Ftp:     "ftp proxy",
   151  		NoProxy: "localhost,no proxy",
   152  	}
   153  
   154  	s.api.APTProxy = proxy.Settings{
   155  		Http:  "http://apt.http.proxy",
   156  		Https: "https://apt.https.proxy",
   157  		Ftp:   "ftp://apt.ftp.proxy",
   158  	}
   159  
   160  	return s.api.Proxy, s.api.APTProxy
   161  }
   162  
   163  func (s *ProxyUpdaterSuite) TestInitialState(c *gc.C) {
   164  	proxySettings, aptProxySettings := s.updateConfig(c)
   165  
   166  	updater, err := proxyupdater.NewWorker(s.config)
   167  	c.Assert(err, jc.ErrorIsNil)
   168  	defer worker.Stop(updater)
   169  
   170  	s.waitProxySettings(c, proxySettings)
   171  	s.waitForFile(c, s.proxyFile, proxySettings.AsScriptEnvironment()+"\n")
   172  
   173  	paccmder, err := commands.NewPackageCommander(series.HostSeries())
   174  	c.Assert(err, jc.ErrorIsNil)
   175  	s.waitForFile(c, pacconfig.AptProxyConfigFile, paccmder.ProxyConfigContents(aptProxySettings)+"\n")
   176  }
   177  
   178  func (s *ProxyUpdaterSuite) TestWriteSystemFiles(c *gc.C) {
   179  	proxySettings, aptProxySettings := s.updateConfig(c)
   180  
   181  	updater, err := proxyupdater.NewWorker(s.config)
   182  	c.Assert(err, jc.ErrorIsNil)
   183  	defer worker.Stop(updater)
   184  
   185  	s.waitProxySettings(c, proxySettings)
   186  	s.waitForFile(c, s.proxyFile, proxySettings.AsScriptEnvironment()+"\n")
   187  
   188  	paccmder, err := commands.NewPackageCommander(series.HostSeries())
   189  	c.Assert(err, jc.ErrorIsNil)
   190  	s.waitForFile(c, pacconfig.AptProxyConfigFile, paccmder.ProxyConfigContents(aptProxySettings)+"\n")
   191  }
   192  
   193  func (s *ProxyUpdaterSuite) TestEnvironmentVariables(c *gc.C) {
   194  	setenv := func(proxy, value string) {
   195  		os.Setenv(proxy, value)
   196  		os.Setenv(strings.ToUpper(proxy), value)
   197  	}
   198  	setenv("http_proxy", "foo")
   199  	setenv("https_proxy", "foo")
   200  	setenv("ftp_proxy", "foo")
   201  	setenv("no_proxy", "foo")
   202  
   203  	proxySettings, _ := s.updateConfig(c)
   204  	updater, err := proxyupdater.NewWorker(s.config)
   205  	c.Assert(err, jc.ErrorIsNil)
   206  	defer worker.Stop(updater)
   207  	s.waitProxySettings(c, proxySettings)
   208  
   209  	assertEnv := func(proxy, value string) {
   210  		c.Assert(os.Getenv(proxy), gc.Equals, value)
   211  		c.Assert(os.Getenv(strings.ToUpper(proxy)), gc.Equals, value)
   212  	}
   213  	assertEnv("http_proxy", proxySettings.Http)
   214  	assertEnv("https_proxy", proxySettings.Https)
   215  	assertEnv("ftp_proxy", proxySettings.Ftp)
   216  	assertEnv("no_proxy", proxySettings.NoProxy)
   217  }