github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/cmd/jujud/agent/testing/agent.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package testing
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/cmd"
    10  	"github.com/juju/errors"
    11  	"github.com/juju/names"
    12  	"github.com/juju/replicaset"
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  	"gopkg.in/mgo.v2"
    16  
    17  	"github.com/juju/juju/agent"
    18  	agenttools "github.com/juju/juju/agent/tools"
    19  	cmdutil "github.com/juju/juju/cmd/jujud/util"
    20  	"github.com/juju/juju/environs"
    21  	"github.com/juju/juju/environs/filestorage"
    22  	envtesting "github.com/juju/juju/environs/testing"
    23  	envtools "github.com/juju/juju/environs/tools"
    24  	"github.com/juju/juju/juju/testing"
    25  	"github.com/juju/juju/mongo"
    26  	"github.com/juju/juju/network"
    27  	"github.com/juju/juju/state"
    28  	coretesting "github.com/juju/juju/testing"
    29  	coretools "github.com/juju/juju/tools"
    30  	"github.com/juju/juju/version"
    31  	"github.com/juju/juju/worker/peergrouper"
    32  )
    33  
    34  type patchingSuite interface {
    35  	PatchValue(interface{}, interface{})
    36  }
    37  
    38  // InstallFakeEnsureMongo creates a new FakeEnsureMongo, patching
    39  // out replicaset.CurrentConfig and cmdutil.EnsureMongoServer.
    40  func InstallFakeEnsureMongo(suite patchingSuite) *FakeEnsureMongo {
    41  	f := &FakeEnsureMongo{
    42  		ServiceInstalled:    true,
    43  		ReplicasetInitiated: true,
    44  	}
    45  	suite.PatchValue(&mongo.IsServiceInstalled, f.IsServiceInstalled)
    46  	suite.PatchValue(&replicaset.CurrentConfig, f.CurrentConfig)
    47  	suite.PatchValue(&cmdutil.EnsureMongoServer, f.EnsureMongo)
    48  	return f
    49  }
    50  
    51  // FakeEnsureMongo provides test fakes for the functions used to
    52  // initialise MongoDB.
    53  type FakeEnsureMongo struct {
    54  	EnsureCount         int
    55  	InitiateCount       int
    56  	DataDir             string
    57  	Namespace           string
    58  	OplogSize           int
    59  	Info                state.StateServingInfo
    60  	InitiateParams      peergrouper.InitiateMongoParams
    61  	Err                 error
    62  	ServiceInstalled    bool
    63  	ReplicasetInitiated bool
    64  }
    65  
    66  func (f *FakeEnsureMongo) IsServiceInstalled(string) (bool, error) {
    67  	return f.ServiceInstalled, nil
    68  }
    69  
    70  func (f *FakeEnsureMongo) CurrentConfig(*mgo.Session) (*replicaset.Config, error) {
    71  	if f.ReplicasetInitiated {
    72  		// Return a dummy replicaset config that's good enough to
    73  		// indicate that the replicaset is initiated.
    74  		return &replicaset.Config{
    75  			Members: []replicaset.Member{{}},
    76  		}, nil
    77  	}
    78  	return nil, errors.NotFoundf("replicaset")
    79  }
    80  
    81  func (f *FakeEnsureMongo) EnsureMongo(args mongo.EnsureServerParams) error {
    82  	f.EnsureCount++
    83  	f.DataDir, f.Namespace, f.OplogSize = args.DataDir, args.Namespace, args.OplogSize
    84  	f.Info = state.StateServingInfo{
    85  		APIPort:        args.APIPort,
    86  		StatePort:      args.StatePort,
    87  		Cert:           args.Cert,
    88  		PrivateKey:     args.PrivateKey,
    89  		CAPrivateKey:   args.CAPrivateKey,
    90  		SharedSecret:   args.SharedSecret,
    91  		SystemIdentity: args.SystemIdentity,
    92  	}
    93  	return f.Err
    94  }
    95  
    96  func (f *FakeEnsureMongo) InitiateMongo(p peergrouper.InitiateMongoParams) error {
    97  	f.InitiateCount++
    98  	f.InitiateParams = p
    99  	return nil
   100  }
   101  
   102  // agentSuite is a fixture to be used by agent test suites.
   103  type AgentSuite struct {
   104  	oldRestartDelay time.Duration
   105  	testing.JujuConnSuite
   106  }
   107  
   108  // PrimeAgent writes the configuration file and tools with version vers
   109  // for an agent with the given entity name.  It returns the agent's
   110  // configuration and the current tools.
   111  func (s *AgentSuite) PrimeAgent(c *gc.C, tag names.Tag, password string, vers version.Binary) (agent.ConfigSetterWriter, *coretools.Tools) {
   112  	c.Logf("priming agent %s", tag.String())
   113  	stor, err := filestorage.NewFileStorageWriter(c.MkDir())
   114  	c.Assert(err, jc.ErrorIsNil)
   115  	agentTools := envtesting.PrimeTools(c, stor, s.DataDir(), "released", vers)
   116  	err = envtools.MergeAndWriteMetadata(stor, "released", "released", coretools.List{agentTools}, envtools.DoNotWriteMirrors)
   117  	tools1, err := agenttools.ChangeAgentTools(s.DataDir(), tag.String(), vers)
   118  	c.Assert(err, jc.ErrorIsNil)
   119  	c.Assert(tools1, gc.DeepEquals, agentTools)
   120  
   121  	stateInfo := s.MongoInfo(c)
   122  	apiInfo := s.APIInfo(c)
   123  	conf, err := agent.NewAgentConfig(
   124  		agent.AgentConfigParams{
   125  			DataDir:           s.DataDir(),
   126  			Tag:               tag,
   127  			UpgradedToVersion: vers.Number,
   128  			Password:          password,
   129  			Nonce:             agent.BootstrapNonce,
   130  			StateAddresses:    stateInfo.Addrs,
   131  			APIAddresses:      apiInfo.Addrs,
   132  			CACert:            stateInfo.CACert,
   133  			Environment:       apiInfo.EnvironTag,
   134  		})
   135  	c.Assert(err, jc.ErrorIsNil)
   136  	conf.SetPassword(password)
   137  	c.Assert(conf.Write(), gc.IsNil)
   138  	s.primeAPIHostPorts(c)
   139  	return conf, agentTools
   140  }
   141  
   142  func (s *AgentSuite) primeAPIHostPorts(c *gc.C) {
   143  	apiInfo := s.APIInfo(c)
   144  
   145  	c.Assert(apiInfo.Addrs, gc.HasLen, 1)
   146  	hostPorts, err := network.ParseHostPorts(apiInfo.Addrs[0])
   147  	c.Assert(err, jc.ErrorIsNil)
   148  
   149  	err = s.State.SetAPIHostPorts([][]network.HostPort{hostPorts})
   150  	c.Assert(err, jc.ErrorIsNil)
   151  
   152  	c.Logf("api host ports primed %#v", hostPorts)
   153  }
   154  
   155  // InitAgent initialises the given agent command with additional
   156  // arguments as provided.
   157  func (s *AgentSuite) InitAgent(c *gc.C, a cmd.Command, args ...string) {
   158  	args = append([]string{"--data-dir", s.DataDir()}, args...)
   159  	err := coretesting.InitCommand(a, args)
   160  	c.Assert(err, jc.ErrorIsNil)
   161  }
   162  
   163  func (s *AgentSuite) AssertCanOpenState(c *gc.C, tag names.Tag, dataDir string) {
   164  	config, err := agent.ReadConfig(agent.ConfigPath(dataDir, tag))
   165  	c.Assert(err, jc.ErrorIsNil)
   166  	info, ok := config.MongoInfo()
   167  	c.Assert(ok, jc.IsTrue)
   168  	st, err := state.Open(info, mongo.DialOpts{}, environs.NewStatePolicy())
   169  	c.Assert(err, jc.ErrorIsNil)
   170  	st.Close()
   171  }
   172  
   173  func (s *AgentSuite) AssertCannotOpenState(c *gc.C, tag names.Tag, dataDir string) {
   174  	config, err := agent.ReadConfig(agent.ConfigPath(dataDir, tag))
   175  	c.Assert(err, jc.ErrorIsNil)
   176  	_, ok := config.MongoInfo()
   177  	c.Assert(ok, jc.IsFalse)
   178  }