launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/worker/machineenvironmentworker/machineenvironmentworker_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package machineenvironmentworker_test
     5  
     6  import (
     7  	"io/ioutil"
     8  	gc "launchpad.net/gocheck"
     9  	"os"
    10  	"path"
    11  	"time"
    12  
    13  	"launchpad.net/juju-core/agent"
    14  	"launchpad.net/juju-core/environs/config"
    15  	"launchpad.net/juju-core/juju/osenv"
    16  	jujutesting "launchpad.net/juju-core/juju/testing"
    17  	"launchpad.net/juju-core/names"
    18  	"launchpad.net/juju-core/provider"
    19  	"launchpad.net/juju-core/state"
    20  	"launchpad.net/juju-core/state/api"
    21  	"launchpad.net/juju-core/state/api/environment"
    22  	"launchpad.net/juju-core/testing"
    23  	jc "launchpad.net/juju-core/testing/checkers"
    24  	"launchpad.net/juju-core/utils"
    25  	"launchpad.net/juju-core/worker"
    26  	"launchpad.net/juju-core/worker/machineenvironmentworker"
    27  )
    28  
    29  type MachineEnvironmentWatcherSuite struct {
    30  	jujutesting.JujuConnSuite
    31  
    32  	apiRoot        *api.State
    33  	environmentAPI *environment.Facade
    34  	machine        *state.Machine
    35  
    36  	proxyFile string
    37  	started   bool
    38  }
    39  
    40  var _ = gc.Suite(&MachineEnvironmentWatcherSuite{})
    41  
    42  func (s *MachineEnvironmentWatcherSuite) setStarted() {
    43  	s.started = true
    44  }
    45  
    46  func (s *MachineEnvironmentWatcherSuite) SetUpTest(c *gc.C) {
    47  	s.JujuConnSuite.SetUpTest(c)
    48  	s.apiRoot, s.machine = s.OpenAPIAsNewMachine(c)
    49  	// Create the machiner API facade.
    50  	s.environmentAPI = s.apiRoot.Environment()
    51  	c.Assert(s.environmentAPI, gc.NotNil)
    52  
    53  	proxyDir := c.MkDir()
    54  	s.PatchValue(&machineenvironmentworker.ProxyDirectory, proxyDir)
    55  	s.started = false
    56  	s.PatchValue(&machineenvironmentworker.Started, s.setStarted)
    57  	s.PatchValue(&utils.AptConfFile, path.Join(proxyDir, "juju-apt-proxy"))
    58  	s.proxyFile = path.Join(proxyDir, machineenvironmentworker.ProxyFile)
    59  }
    60  
    61  func (s *MachineEnvironmentWatcherSuite) waitForPostSetup(c *gc.C) {
    62  	for {
    63  		select {
    64  		case <-time.After(testing.LongWait):
    65  			c.Fatalf("timeout while waiting for setup")
    66  		case <-time.After(10 * time.Millisecond):
    67  			if s.started {
    68  				return
    69  			}
    70  		}
    71  	}
    72  }
    73  
    74  func (s *MachineEnvironmentWatcherSuite) waitProxySettings(c *gc.C, expected osenv.ProxySettings) {
    75  	for {
    76  		select {
    77  		case <-time.After(testing.LongWait):
    78  			c.Fatalf("timeout while waiting for proxy settings to change")
    79  		case <-time.After(10 * time.Millisecond):
    80  			obtained := osenv.DetectProxies()
    81  			if obtained != expected {
    82  				c.Logf("proxy settings are %#v, still waiting", obtained)
    83  				continue
    84  			}
    85  			return
    86  		}
    87  	}
    88  }
    89  
    90  func (s *MachineEnvironmentWatcherSuite) waitForFile(c *gc.C, filename, expected string) {
    91  	for {
    92  		select {
    93  		case <-time.After(testing.LongWait):
    94  			c.Fatalf("timeout while waiting for proxy settings to change")
    95  		case <-time.After(10 * time.Millisecond):
    96  			fileContent, err := ioutil.ReadFile(filename)
    97  			if os.IsNotExist(err) {
    98  				continue
    99  			}
   100  			c.Assert(err, gc.IsNil)
   101  			if string(fileContent) != expected {
   102  				c.Logf("file content not matching, still waiting")
   103  				continue
   104  			}
   105  			return
   106  		}
   107  	}
   108  }
   109  
   110  func (s *MachineEnvironmentWatcherSuite) makeWorker(c *gc.C, agentConfig agent.Config) worker.Worker {
   111  	return machineenvironmentworker.NewMachineEnvironmentWorker(s.environmentAPI, agentConfig)
   112  }
   113  
   114  func (s *MachineEnvironmentWatcherSuite) TestRunStop(c *gc.C) {
   115  	agentConfig := agentConfig("0", "ec2")
   116  	envWorker := s.makeWorker(c, agentConfig)
   117  	c.Assert(worker.Stop(envWorker), gc.IsNil)
   118  }
   119  
   120  func (s *MachineEnvironmentWatcherSuite) updateConfig(c *gc.C) (osenv.ProxySettings, osenv.ProxySettings) {
   121  	oldConfig, err := s.State.EnvironConfig()
   122  	c.Assert(err, gc.IsNil)
   123  
   124  	proxySettings := osenv.ProxySettings{
   125  		Http:  "http proxy",
   126  		Https: "https proxy",
   127  		Ftp:   "ftp proxy",
   128  	}
   129  
   130  	envConfig, err := oldConfig.Apply(config.ProxyConfigMap(proxySettings))
   131  	c.Assert(err, gc.IsNil)
   132  
   133  	// We explicitly set apt proxy settings as well to show that it is the apt
   134  	// settings that are used for the apt config, and not just the normal
   135  	// proxy settings which is what we would get if we don't explicitly set
   136  	// apt values.
   137  	aptProxySettings := osenv.ProxySettings{
   138  		Http:  "apt http proxy",
   139  		Https: "apt https proxy",
   140  		Ftp:   "apt ftp proxy",
   141  	}
   142  	envConfig, err = envConfig.Apply(config.AptProxyConfigMap(aptProxySettings))
   143  	c.Assert(err, gc.IsNil)
   144  
   145  	err = s.State.SetEnvironConfig(envConfig, oldConfig)
   146  	c.Assert(err, gc.IsNil)
   147  
   148  	return proxySettings, aptProxySettings
   149  }
   150  
   151  func (s *MachineEnvironmentWatcherSuite) TestInitialState(c *gc.C) {
   152  	proxySettings, aptProxySettings := s.updateConfig(c)
   153  
   154  	agentConfig := agentConfig("0", "ec2")
   155  	envWorker := s.makeWorker(c, agentConfig)
   156  	defer worker.Stop(envWorker)
   157  
   158  	s.waitProxySettings(c, proxySettings)
   159  	s.waitForFile(c, s.proxyFile, proxySettings.AsScriptEnvironment()+"\n")
   160  	s.waitForFile(c, utils.AptConfFile, utils.AptProxyContent(aptProxySettings)+"\n")
   161  }
   162  
   163  func (s *MachineEnvironmentWatcherSuite) TestRespondsToEvents(c *gc.C) {
   164  	agentConfig := agentConfig("0", "ec2")
   165  	envWorker := s.makeWorker(c, agentConfig)
   166  	defer worker.Stop(envWorker)
   167  	s.waitForPostSetup(c)
   168  
   169  	proxySettings, aptProxySettings := s.updateConfig(c)
   170  
   171  	s.waitProxySettings(c, proxySettings)
   172  	s.waitForFile(c, s.proxyFile, proxySettings.AsScriptEnvironment()+"\n")
   173  	s.waitForFile(c, utils.AptConfFile, utils.AptProxyContent(aptProxySettings)+"\n")
   174  }
   175  
   176  func (s *MachineEnvironmentWatcherSuite) TestInitialStateLocalMachine1(c *gc.C) {
   177  	proxySettings, aptProxySettings := s.updateConfig(c)
   178  
   179  	agentConfig := agentConfig("1", provider.Local)
   180  	envWorker := s.makeWorker(c, agentConfig)
   181  	defer worker.Stop(envWorker)
   182  
   183  	s.waitProxySettings(c, proxySettings)
   184  	s.waitForFile(c, s.proxyFile, proxySettings.AsScriptEnvironment()+"\n")
   185  	s.waitForFile(c, utils.AptConfFile, utils.AptProxyContent(aptProxySettings)+"\n")
   186  }
   187  
   188  func (s *MachineEnvironmentWatcherSuite) TestInitialStateLocalMachine0(c *gc.C) {
   189  	proxySettings, _ := s.updateConfig(c)
   190  
   191  	agentConfig := agentConfig("0", provider.Local)
   192  	envWorker := s.makeWorker(c, agentConfig)
   193  	defer worker.Stop(envWorker)
   194  	s.waitForPostSetup(c)
   195  
   196  	s.waitProxySettings(c, proxySettings)
   197  
   198  	c.Assert(utils.AptConfFile, jc.DoesNotExist)
   199  	c.Assert(s.proxyFile, jc.DoesNotExist)
   200  }
   201  
   202  type mockConfig struct {
   203  	agent.Config
   204  	tag      string
   205  	provider string
   206  }
   207  
   208  func (mock *mockConfig) Tag() string {
   209  	return mock.tag
   210  }
   211  
   212  func (mock *mockConfig) Value(key string) string {
   213  	if key == agent.JujuProviderType {
   214  		return mock.provider
   215  	}
   216  	return ""
   217  }
   218  
   219  func agentConfig(machineId, provider string) *mockConfig {
   220  	return &mockConfig{tag: names.MachineTag(machineId), provider: provider}
   221  }