github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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 = proxyupdater.Config{ 82 Directory: c.MkDir(), 83 Filename: "juju-proxy-settings", 84 API: s.api, 85 } 86 s.PatchValue(&pacconfig.AptProxyConfigFile, path.Join(s.config.Directory, "juju-apt-proxy")) 87 s.proxyFile = path.Join(s.config.Directory, s.config.Filename) 88 } 89 90 func (s *ProxyUpdaterSuite) TearDownTest(c *gc.C) { 91 s.BaseSuite.TearDownTest(c) 92 if s.api.Watcher != nil { 93 s.api.Watcher.Close() 94 } 95 } 96 97 func (s *ProxyUpdaterSuite) waitProxySettings(c *gc.C, expected proxy.Settings) { 98 maxWait := time.After(coretesting.LongWait) 99 for { 100 select { 101 case <-maxWait: 102 c.Fatalf("timeout while waiting for proxy settings to change") 103 return 104 case <-time.After(10 * time.Millisecond): 105 obtained := proxy.DetectProxies() 106 if obtained != expected { 107 if obtained != s.detectedSettings { 108 c.Logf("proxy settings are \n%#v, should be \n%#v, still waiting", obtained, expected) 109 } 110 s.detectedSettings = obtained 111 continue 112 } 113 return 114 } 115 } 116 } 117 118 func (s *ProxyUpdaterSuite) waitForFile(c *gc.C, filename, expected string) { 119 //TODO(bogdanteleaga): Find a way to test this on windows 120 if runtime.GOOS == "windows" { 121 c.Skip("Proxy settings are written to the registry on windows") 122 } 123 maxWait := time.After(coretesting.LongWait) 124 for { 125 select { 126 case <-maxWait: 127 c.Fatalf("timeout while waiting for proxy settings to change") 128 return 129 case <-time.After(10 * time.Millisecond): 130 fileContent, err := ioutil.ReadFile(filename) 131 if os.IsNotExist(err) { 132 continue 133 } 134 c.Assert(err, jc.ErrorIsNil) 135 if string(fileContent) != expected { 136 c.Logf("file content not matching, still waiting") 137 continue 138 } 139 return 140 } 141 } 142 } 143 144 func (s *ProxyUpdaterSuite) TestRunStop(c *gc.C) { 145 updater, err := proxyupdater.NewWorker(s.config) 146 c.Assert(err, jc.ErrorIsNil) 147 workertest.CleanKill(c, updater) 148 } 149 150 func (s *ProxyUpdaterSuite) updateConfig(c *gc.C) (proxy.Settings, proxy.Settings) { 151 s.api.Proxy = proxy.Settings{ 152 Http: "http proxy", 153 Https: "https proxy", 154 Ftp: "ftp proxy", 155 NoProxy: "localhost,no proxy", 156 } 157 158 s.api.APTProxy = proxy.Settings{ 159 Http: "http://apt.http.proxy", 160 Https: "https://apt.https.proxy", 161 Ftp: "ftp://apt.ftp.proxy", 162 } 163 164 return s.api.Proxy, s.api.APTProxy 165 } 166 167 func (s *ProxyUpdaterSuite) TestInitialState(c *gc.C) { 168 proxySettings, aptProxySettings := s.updateConfig(c) 169 170 updater, err := proxyupdater.NewWorker(s.config) 171 c.Assert(err, jc.ErrorIsNil) 172 defer worker.Stop(updater) 173 174 s.waitProxySettings(c, proxySettings) 175 s.waitForFile(c, s.proxyFile, proxySettings.AsScriptEnvironment()+"\n") 176 177 paccmder, err := commands.NewPackageCommander(series.HostSeries()) 178 c.Assert(err, jc.ErrorIsNil) 179 s.waitForFile(c, pacconfig.AptProxyConfigFile, paccmder.ProxyConfigContents(aptProxySettings)+"\n") 180 } 181 182 func (s *ProxyUpdaterSuite) TestWriteSystemFiles(c *gc.C) { 183 proxySettings, aptProxySettings := s.updateConfig(c) 184 185 updater, err := proxyupdater.NewWorker(s.config) 186 c.Assert(err, jc.ErrorIsNil) 187 defer worker.Stop(updater) 188 189 s.waitProxySettings(c, proxySettings) 190 s.waitForFile(c, s.proxyFile, proxySettings.AsScriptEnvironment()+"\n") 191 192 paccmder, err := commands.NewPackageCommander(series.HostSeries()) 193 c.Assert(err, jc.ErrorIsNil) 194 s.waitForFile(c, pacconfig.AptProxyConfigFile, paccmder.ProxyConfigContents(aptProxySettings)+"\n") 195 } 196 197 func (s *ProxyUpdaterSuite) TestEnvironmentVariables(c *gc.C) { 198 setenv := func(proxy, value string) { 199 os.Setenv(proxy, value) 200 os.Setenv(strings.ToUpper(proxy), value) 201 } 202 setenv("http_proxy", "foo") 203 setenv("https_proxy", "foo") 204 setenv("ftp_proxy", "foo") 205 setenv("no_proxy", "foo") 206 207 proxySettings, _ := s.updateConfig(c) 208 updater, err := proxyupdater.NewWorker(s.config) 209 c.Assert(err, jc.ErrorIsNil) 210 defer worker.Stop(updater) 211 s.waitProxySettings(c, proxySettings) 212 213 assertEnv := func(proxy, value string) { 214 c.Assert(os.Getenv(proxy), gc.Equals, value) 215 c.Assert(os.Getenv(strings.ToUpper(proxy)), gc.Equals, value) 216 } 217 assertEnv("http_proxy", proxySettings.Http) 218 assertEnv("https_proxy", proxySettings.Https) 219 assertEnv("ftp_proxy", proxySettings.Ftp) 220 assertEnv("no_proxy", proxySettings.NoProxy) 221 } 222 223 func (s *ProxyUpdaterSuite) TestExternalFuncCalled(c *gc.C) { 224 proxySettings, _ := s.updateConfig(c) 225 226 var externalSettings proxy.Settings 227 updated := make(chan struct{}) 228 s.config.ExternalUpdate = func(values proxy.Settings) error { 229 externalSettings = values 230 close(updated) 231 return nil 232 } 233 updater, err := proxyupdater.NewWorker(s.config) 234 c.Assert(err, jc.ErrorIsNil) 235 defer worker.Stop(updater) 236 237 select { 238 case <-time.After(time.Second): 239 c.Fatal("function not called") 240 case <-updated: 241 } 242 243 c.Assert(externalSettings, jc.DeepEquals, proxySettings) 244 }