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