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