1
// Copyright 2012, 2013 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
11
"github.com/juju/replicaset"
12
gitjujutesting "github.com/juju/testing"
13
jc "github.com/juju/testing/checkers"
14
"github.com/juju/utils/arch"
15
"github.com/juju/utils/series"
16
"github.com/juju/version"
17
gc "gopkg.in/check.v1"
18
"gopkg.in/juju/names.v2"
21
"github.com/juju/juju/agent"
22
agenttools "github.com/juju/juju/agent/tools"
23
"github.com/juju/juju/apiserver/params"
24
cmdutil "github.com/juju/juju/cmd/jujud/util"
25
"github.com/juju/juju/environs"
26
"github.com/juju/juju/environs/filestorage"
27
envtesting "github.com/juju/juju/environs/testing"
28
envtools "github.com/juju/juju/environs/tools"
29
"github.com/juju/juju/juju/testing"
30
"github.com/juju/juju/mongo"
31
"github.com/juju/juju/mongo/mongotest"
32
"github.com/juju/juju/network"
33
"github.com/juju/juju/state"
34
"github.com/juju/juju/state/stateenvirons"
35
coretesting "github.com/juju/juju/testing"
36
coretools "github.com/juju/juju/tools"
37
jujuversion "github.com/juju/juju/version"
38
"github.com/juju/juju/worker/peergrouper"
41
type patchingSuite interface {
42
PatchValue(interface{}, interface{})
45
// InstallFakeEnsureMongo creates a new FakeEnsureMongo, patching
46
// out replicaset.CurrentConfig and cmdutil.EnsureMongoServer.
47
func InstallFakeEnsureMongo(suite patchingSuite) *FakeEnsureMongo {
48
f := &FakeEnsureMongo{
49
ServiceInstalled: true,
51
suite.PatchValue(&mongo.IsServiceInstalled, f.IsServiceInstalled)
52
suite.PatchValue(&replicaset.CurrentConfig, f.CurrentConfig)
53
suite.PatchValue(&cmdutil.EnsureMongoServer, f.EnsureMongo)
57
// FakeEnsureMongo provides test fakes for the functions used to
58
// initialise MongoDB.
59
type FakeEnsureMongo struct {
64
Info state.StateServingInfo
65
InitiateParams peergrouper.InitiateMongoParams
70
func (f *FakeEnsureMongo) IsServiceInstalled() (bool, error) {
71
return f.ServiceInstalled, nil
74
func (f *FakeEnsureMongo) CurrentConfig(*mgo.Session) (*replicaset.Config, error) {
75
// Return a dummy replicaset config that's good enough to
76
// indicate that the replicaset is initiated.
77
return &replicaset.Config{
78
Members: []replicaset.Member{{}},
82
func (f *FakeEnsureMongo) EnsureMongo(args mongo.EnsureServerParams) error {
84
f.DataDir, f.OplogSize = args.DataDir, args.OplogSize
85
f.Info = state.StateServingInfo{
86
APIPort: args.APIPort,
87
StatePort: args.StatePort,
89
PrivateKey: args.PrivateKey,
90
CAPrivateKey: args.CAPrivateKey,
91
SharedSecret: args.SharedSecret,
92
SystemIdentity: args.SystemIdentity,
97
func (f *FakeEnsureMongo) InitiateMongo(p peergrouper.InitiateMongoParams) error {
103
// agentSuite is a fixture to be used by agent test suites.
104
type AgentSuite struct {
105
oldRestartDelay time.Duration
106
testing.JujuConnSuite
109
// PrimeAgent writes the configuration file and tools for an agent
110
// with the given entity name. It returns the agent's configuration and the
112
func (s *AgentSuite) PrimeAgent(c *gc.C, tag names.Tag, password string) (agent.ConfigSetterWriter, *coretools.Tools) {
113
vers := version.Binary{
114
Number: jujuversion.Current,
115
Arch: arch.HostArch(),
116
Series: series.HostSeries(),
118
return s.PrimeAgentVersion(c, tag, password, vers)
121
// PrimeAgentVersion writes the configuration file and tools with version
122
// vers for an agent with the given entity name. It returns the agent's
123
// configuration and the current tools.
124
func (s *AgentSuite) PrimeAgentVersion(c *gc.C, tag names.Tag, password string, vers version.Binary) (agent.ConfigSetterWriter, *coretools.Tools) {
125
c.Logf("priming agent %s", tag.String())
126
stor, err := filestorage.NewFileStorageWriter(c.MkDir())
127
c.Assert(err, jc.ErrorIsNil)
128
agentTools := envtesting.PrimeTools(c, stor, s.DataDir(), "released", vers)
129
err = envtools.MergeAndWriteMetadata(stor, "released", "released", coretools.List{agentTools}, envtools.DoNotWriteMirrors)
130
tools1, err := agenttools.ChangeAgentTools(s.DataDir(), tag.String(), vers)
131
c.Assert(err, jc.ErrorIsNil)
132
c.Assert(tools1, gc.DeepEquals, agentTools)
134
stateInfo := s.MongoInfo(c)
135
apiInfo := s.APIInfo(c)
136
paths := agent.DefaultPaths
137
paths.DataDir = s.DataDir()
138
paths.MetricsSpoolDir = c.MkDir()
139
conf, err := agent.NewAgentConfig(
140
agent.AgentConfigParams{
143
UpgradedToVersion: vers.Number,
145
Nonce: agent.BootstrapNonce,
146
StateAddresses: stateInfo.Addrs,
147
APIAddresses: apiInfo.Addrs,
148
CACert: stateInfo.CACert,
149
Model: apiInfo.ModelTag,
151
c.Assert(err, jc.ErrorIsNil)
152
conf.SetPassword(password)
153
c.Assert(conf.Write(), gc.IsNil)
154
s.primeAPIHostPorts(c)
155
return conf, agentTools
158
// PrimeStateAgent writes the configuration file and tools for
159
// a state agent with the given entity name. It returns the agent's
160
// configuration and the current tools.
161
func (s *AgentSuite) PrimeStateAgent(c *gc.C, tag names.Tag, password string) (agent.ConfigSetterWriter, *coretools.Tools) {
162
vers := version.Binary{
163
Number: jujuversion.Current,
164
Arch: arch.HostArch(),
165
Series: series.HostSeries(),
167
return s.PrimeStateAgentVersion(c, tag, password, vers)
170
// PrimeStateAgentVersion writes the configuration file and tools with
171
// version vers for a state agent with the given entity name. It
172
// returns the agent's configuration and the current tools.
173
func (s *AgentSuite) PrimeStateAgentVersion(c *gc.C, tag names.Tag, password string, vers version.Binary) (
174
agent.ConfigSetterWriter, *coretools.Tools,
176
stor, err := filestorage.NewFileStorageWriter(c.MkDir())
177
c.Assert(err, jc.ErrorIsNil)
178
agentTools := envtesting.PrimeTools(c, stor, s.DataDir(), "released", vers)
179
tools1, err := agenttools.ChangeAgentTools(s.DataDir(), tag.String(), vers)
180
c.Assert(err, jc.ErrorIsNil)
181
c.Assert(tools1, gc.DeepEquals, agentTools)
183
conf := s.WriteStateAgentConfig(c, tag, password, vers, s.State.ModelTag())
184
s.primeAPIHostPorts(c)
185
return conf, agentTools
188
// WriteStateAgentConfig creates and writes a state agent config.
189
func (s *AgentSuite) WriteStateAgentConfig(
194
modelTag names.ModelTag,
195
) agent.ConfigSetterWriter {
196
stateInfo := s.State.MongoConnectionInfo()
197
apiPort := gitjujutesting.FindTCPPort()
198
apiAddr := []string{fmt.Sprintf("localhost:%d", apiPort)}
199
conf, err := agent.NewStateMachineConfig(
200
agent.AgentConfigParams{
201
Paths: agent.NewPathsWithDefaults(agent.Paths{DataDir: s.DataDir()}),
203
UpgradedToVersion: vers.Number,
205
Nonce: agent.BootstrapNonce,
206
StateAddresses: stateInfo.Addrs,
207
APIAddresses: apiAddr,
208
CACert: stateInfo.CACert,
211
params.StateServingInfo{
212
Cert: coretesting.ServerCert,
213
PrivateKey: coretesting.ServerKey,
214
CAPrivateKey: coretesting.CAKey,
215
StatePort: gitjujutesting.MgoServer.Port(),
218
c.Assert(err, jc.ErrorIsNil)
219
conf.SetPassword(password)
220
c.Assert(conf.Write(), gc.IsNil)
224
func (s *AgentSuite) primeAPIHostPorts(c *gc.C) {
225
apiInfo := s.APIInfo(c)
227
c.Assert(apiInfo.Addrs, gc.HasLen, 1)
228
hostPorts, err := network.ParseHostPorts(apiInfo.Addrs[0])
229
c.Assert(err, jc.ErrorIsNil)
231
err = s.State.SetAPIHostPorts([][]network.HostPort{hostPorts})
232
c.Assert(err, jc.ErrorIsNil)
234
c.Logf("api host ports primed %#v", hostPorts)
237
// InitAgent initialises the given agent command with additional
238
// arguments as provided.
239
func (s *AgentSuite) InitAgent(c *gc.C, a cmd.Command, args ...string) {
240
args = append([]string{"--data-dir", s.DataDir()}, args...)
241
err := coretesting.InitCommand(a, args)
242
c.Assert(err, jc.ErrorIsNil)
245
func (s *AgentSuite) AssertCanOpenState(c *gc.C, tag names.Tag, dataDir string) {
246
config, err := agent.ReadConfig(agent.ConfigPath(dataDir, tag))
247
c.Assert(err, jc.ErrorIsNil)
248
info, ok := config.MongoInfo()
249
c.Assert(ok, jc.IsTrue)
250
st, err := state.Open(config.Model(), info, mongotest.DialOpts(), stateenvirons.GetNewPolicyFunc(
251
stateenvirons.GetNewEnvironFunc(environs.New),
253
c.Assert(err, jc.ErrorIsNil)
257
func (s *AgentSuite) AssertCannotOpenState(c *gc.C, tag names.Tag, dataDir string) {
258
config, err := agent.ReadConfig(agent.ConfigPath(dataDir, tag))
259
c.Assert(err, jc.ErrorIsNil)
260
_, ok := config.MongoInfo()
261
c.Assert(ok, jc.IsFalse)