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 }