github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/cmd/jujud/agent/agent_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package agent
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/names"
    12  	gitjujutesting "github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/agent"
    17  	agenttools "github.com/juju/juju/agent/tools"
    18  	apienvironment "github.com/juju/juju/api/environment"
    19  	"github.com/juju/juju/apiserver/params"
    20  	agenttesting "github.com/juju/juju/cmd/jujud/agent/testing"
    21  	cmdutil "github.com/juju/juju/cmd/jujud/util"
    22  	"github.com/juju/juju/environs/filestorage"
    23  	envtesting "github.com/juju/juju/environs/testing"
    24  	"github.com/juju/juju/juju/paths"
    25  	"github.com/juju/juju/mongo"
    26  	"github.com/juju/juju/network"
    27  	coretesting "github.com/juju/juju/testing"
    28  	coretools "github.com/juju/juju/tools"
    29  	"github.com/juju/juju/version"
    30  	"github.com/juju/juju/worker"
    31  	"github.com/juju/juju/worker/proxyupdater"
    32  )
    33  
    34  type acCreator func() (cmd.Command, AgentConf)
    35  
    36  // CheckAgentCommand is a utility function for verifying that common agent
    37  // options are handled by a Command; it returns an instance of that
    38  // command pre-parsed, with any mandatory flags added.
    39  func CheckAgentCommand(c *gc.C, create acCreator, args []string) cmd.Command {
    40  	com, conf := create()
    41  	err := coretesting.InitCommand(com, args)
    42  	dataDir, err := paths.DataDir(version.Current.Series)
    43  	c.Assert(err, jc.ErrorIsNil)
    44  	c.Assert(conf.DataDir(), gc.Equals, dataDir)
    45  	badArgs := append(args, "--data-dir", "")
    46  	com, _ = create()
    47  	err = coretesting.InitCommand(com, badArgs)
    48  	c.Assert(err, gc.ErrorMatches, "--data-dir option must be set")
    49  
    50  	args = append(args, "--data-dir", "jd")
    51  	com, conf = create()
    52  	c.Assert(coretesting.InitCommand(com, args), gc.IsNil)
    53  	c.Assert(conf.DataDir(), gc.Equals, "jd")
    54  	return com
    55  }
    56  
    57  // ParseAgentCommand is a utility function that inserts the always-required args
    58  // before parsing an agent command and returning the result.
    59  func ParseAgentCommand(ac cmd.Command, args []string) error {
    60  	common := []string{
    61  		"--data-dir", "jd",
    62  	}
    63  	return coretesting.InitCommand(ac, append(common, args...))
    64  }
    65  
    66  // AgentSuite is a fixture to be used by agent test suites.
    67  type AgentSuite struct {
    68  	agenttesting.AgentSuite
    69  	oldRestartDelay time.Duration
    70  }
    71  
    72  func (s *AgentSuite) SetUpSuite(c *gc.C) {
    73  	s.JujuConnSuite.SetUpSuite(c)
    74  
    75  	s.oldRestartDelay = worker.RestartDelay
    76  	// We could use testing.ShortWait, but this thrashes quite
    77  	// a bit when some tests are restarting every 50ms for 10 seconds,
    78  	// so use a slightly more friendly delay.
    79  	worker.RestartDelay = 250 * time.Millisecond
    80  	s.PatchValue(&cmdutil.EnsureMongoServer, func(mongo.EnsureServerParams) error {
    81  		return nil
    82  	})
    83  }
    84  
    85  func (s *AgentSuite) TearDownSuite(c *gc.C) {
    86  	s.JujuConnSuite.TearDownSuite(c)
    87  	worker.RestartDelay = s.oldRestartDelay
    88  }
    89  
    90  func (s *AgentSuite) SetUpTest(c *gc.C) {
    91  	s.JujuConnSuite.SetUpTest(c)
    92  	// Set API host ports so FindTools/Tools API calls succeed.
    93  	hostPorts := [][]network.HostPort{
    94  		network.NewHostPorts(1234, "0.1.2.3"),
    95  	}
    96  	err := s.State.SetAPIHostPorts(hostPorts)
    97  	c.Assert(err, jc.ErrorIsNil)
    98  	s.PatchValue(&proxyupdater.New, func(*apienvironment.Facade, bool) worker.Worker {
    99  		return newDummyWorker()
   100  	})
   101  }
   102  
   103  func (s *AgentSuite) primeAPIHostPorts(c *gc.C) {
   104  	apiInfo := s.APIInfo(c)
   105  
   106  	c.Assert(apiInfo.Addrs, gc.HasLen, 1)
   107  	hostPorts, err := network.ParseHostPorts(apiInfo.Addrs[0])
   108  	c.Assert(err, jc.ErrorIsNil)
   109  
   110  	err = s.State.SetAPIHostPorts([][]network.HostPort{hostPorts})
   111  	c.Assert(err, jc.ErrorIsNil)
   112  
   113  	logger.Debugf("api host ports primed %#v", hostPorts)
   114  }
   115  
   116  // primeStateAgent writes the configuration file and tools with version vers
   117  // for an agent with the given entity name.  It returns the agent's configuration
   118  // and the current tools.
   119  func (s *AgentSuite) PrimeStateAgent(
   120  	c *gc.C, tag names.Tag, password string, vers version.Binary) (agent.ConfigSetterWriter, *coretools.Tools) {
   121  
   122  	stor, err := filestorage.NewFileStorageWriter(c.MkDir())
   123  	c.Assert(err, jc.ErrorIsNil)
   124  	agentTools := envtesting.PrimeTools(c, stor, s.DataDir(), "released", vers)
   125  	tools1, err := agenttools.ChangeAgentTools(s.DataDir(), tag.String(), vers)
   126  	c.Assert(err, jc.ErrorIsNil)
   127  	c.Assert(tools1, gc.DeepEquals, agentTools)
   128  
   129  	stateInfo := s.MongoInfo(c)
   130  	conf := writeStateAgentConfig(c, stateInfo, s.DataDir(), tag, password, vers, s.State.EnvironTag())
   131  	s.primeAPIHostPorts(c)
   132  	return conf, agentTools
   133  }
   134  
   135  // writeStateAgentConfig creates and writes a state agent config.
   136  func writeStateAgentConfig(
   137  	c *gc.C, stateInfo *mongo.MongoInfo, dataDir string, tag names.Tag,
   138  	password string, vers version.Binary, envTag names.EnvironTag) agent.ConfigSetterWriter {
   139  	port := gitjujutesting.FindTCPPort()
   140  	apiAddr := []string{fmt.Sprintf("localhost:%d", port)}
   141  	conf, err := agent.NewStateMachineConfig(
   142  		agent.AgentConfigParams{
   143  			DataDir:           dataDir,
   144  			Tag:               tag,
   145  			UpgradedToVersion: vers.Number,
   146  			Password:          password,
   147  			Nonce:             agent.BootstrapNonce,
   148  			StateAddresses:    stateInfo.Addrs,
   149  			APIAddresses:      apiAddr,
   150  			CACert:            stateInfo.CACert,
   151  			Environment:       envTag,
   152  		},
   153  		params.StateServingInfo{
   154  			Cert:         coretesting.ServerCert,
   155  			PrivateKey:   coretesting.ServerKey,
   156  			CAPrivateKey: coretesting.CAKey,
   157  			StatePort:    gitjujutesting.MgoServer.Port(),
   158  			APIPort:      port,
   159  		})
   160  	c.Assert(err, jc.ErrorIsNil)
   161  	conf.SetPassword(password)
   162  	c.Assert(conf.Write(), gc.IsNil)
   163  	return conf
   164  }