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 }