Merge lp:~rogpeppe/juju-core/mfoord-wrapsingletonworkers into lp:~go-bot/juju-core/trunk

Proposed by Roger Peppe
Status: Merged
Approved by: Roger Peppe
Approved revision: no longer in the source branch.
Merged at revision: 2608
Proposed branch: lp:~rogpeppe/juju-core/mfoord-wrapsingletonworkers
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 346 lines (+144/-17)
5 files modified
agent/mongo/mongo.go (+8/-0)
cmd/jujud/machine.go (+66/-15)
cmd/jujud/machine_test.go (+49/-0)
replicaset/replicaset.go (+8/-2)
replicaset/replicaset_test.go (+13/-0)
To merge this branch: bzr merge lp:~rogpeppe/juju-core/mfoord-wrapsingletonworkers
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+215035@code.launchpad.net

Commit message

cmd/jujud: wrap singular workers

We start the various workers that require only a single
instance to be running via the runner returned by singular.New.

This is awkward to test - we just do a basic sanity check
that the right workers are started through the singular
runner.

https://codereview.appspot.com/86200043/

Description of the change

cmd/jujud: wrap singular workers

We start the various workers that require only a single
instance to be running via the runner returned by singular.New.

This is awkward to test - we just do a basic sanity check
that the right workers are started through the singular
runner.

https://codereview.appspot.com/86200043/

To post a comment you must log in.
Revision history for this message
Roger Peppe (rogpeppe) wrote :

Reviewers: mp+215035_code.launchpad.net,

Message:
Please take a look.

Description:
cmd/jujud: wrap singular workers

We start the various workers that require only a single
instance to be running via the runner returned by singular.New.

This is awkward to test - we just do a basic sanity check
that the right workers are started through the singular
runner.

https://code.launchpad.net/~rogpeppe/juju-core/mfoord-wrapsingletonworkers/+merge/215035

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/86200043/

Affected files (+113, -15 lines):
   A [revision details]
   M cmd/jujud/machine.go
   M cmd/jujud/machine_test.go

Revision history for this message
Roger Peppe (rogpeppe) wrote :
Revision history for this message
Nate Finch (natefinch) wrote :

LGTM with just a couple minor suggestions.

https://codereview.appspot.com/86200043/diff/40001/cmd/jujud/machine.go
File cmd/jujud/machine.go (right):

https://codereview.appspot.com/86200043/diff/40001/cmd/jujud/machine.go#newcode253
cmd/jujud/machine.go:253: conn := singularAPIConn{st, st.Agent()}
could this code get moved to the loop over entity.jobs below? It
diesn't seem to neec to be here, and it puts the declaration far from
the use of the variable.

https://codereview.appspot.com/86200043/diff/40001/cmd/jujud/machine_test.go
File cmd/jujud/machine_test.go (right):

https://codereview.appspot.com/86200043/diff/40001/cmd/jujud/machine_test.go#newcode384
cmd/jujud/machine_test.go:384: c.Assert(s.singularRecord.started(),
jc.DeepEquals, []string{
This checks order of the slice, too, right? Does the order matter? If
not, we may want to use jc.SameContents here, so we don't fail the test
if the order changes.

https://codereview.appspot.com/86200043/

Revision history for this message
Roger Peppe (rogpeppe) wrote :

https://codereview.appspot.com/86200043/diff/40001/cmd/jujud/machine.go
File cmd/jujud/machine.go (right):

https://codereview.appspot.com/86200043/diff/40001/cmd/jujud/machine.go#newcode253
cmd/jujud/machine.go:253: conn := singularAPIConn{st, st.Agent()}
On 2014/04/10 11:14:38, nate.finch wrote:
> could this code get moved to the loop over entity.jobs below? It
diesn't seem
> to neec to be here, and it puts the declaration far from the use of
the
> variable.

i don't we can do this, because newSingularRunner can fail, and if that
happens we don't want to leave the other jobs running.

https://codereview.appspot.com/86200043/diff/40001/cmd/jujud/machine_test.go
File cmd/jujud/machine_test.go (right):

https://codereview.appspot.com/86200043/diff/40001/cmd/jujud/machine_test.go#newcode384
cmd/jujud/machine_test.go:384: c.Assert(s.singularRecord.started(),
jc.DeepEquals, []string{
On 2014/04/10 11:14:38, nate.finch wrote:
> This checks order of the slice, too, right? Does the order matter?
If not, we
> may want to use jc.SameContents here, so we don't fail the test if the
order
> changes.

the slice is sorted (see the implementation of the started method)

https://codereview.appspot.com/86200043/

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (104.5 KiB)

The attempt to merge lp:~rogpeppe/juju-core/mfoord-wrapsingletonworkers into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.013s
ok launchpad.net/juju-core/agent 1.660s
ok launchpad.net/juju-core/agent/mongo 1.118s
ok launchpad.net/juju-core/agent/tools 0.218s
ok launchpad.net/juju-core/bzr 5.232s
ok launchpad.net/juju-core/cert 3.002s
ok launchpad.net/juju-core/charm 0.424s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.030s
ok launchpad.net/juju-core/cloudinit/sshinit 0.848s
ok launchpad.net/juju-core/cmd 0.184s
ok launchpad.net/juju-core/cmd/charm-admin 0.756s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/envcmd 0.177s
ok launchpad.net/juju-core/cmd/juju 217.439s
ok launchpad.net/juju-core/cmd/jujud 78.801s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 9.424s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.165s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.023s
ok launchpad.net/juju-core/container 0.031s
ok launchpad.net/juju-core/container/factory 0.039s
ok launchpad.net/juju-core/container/kvm 0.195s
ok launchpad.net/juju-core/container/kvm/mock 0.033s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.312s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.221s
ok launchpad.net/juju-core/environs 2.575s
ok launchpad.net/juju-core/environs/bootstrap 11.101s
ok launchpad.net/juju-core/environs/cloudinit 0.473s
ok launchpad.net/juju-core/environs/config 1.690s
ok launchpad.net/juju-core/environs/configstore 0.044s
ok launchpad.net/juju-core/environs/filestorage 0.029s
ok launchpad.net/juju-core/environs/httpstorage 0.741s
ok launchpad.net/juju-core/environs/imagemetadata 0.389s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.034s
ok launchpad.net/juju-core/environs/jujutest 0.200s
ok launchpad.net/juju-core/environs/manual 10.109s
ok launchpad.net/juju-core/environs/simplestreams 0.279s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 0.913s
ok launchpad.net/juju-core/environs/storage 0.888s
ok launchpad.net/juju-core/environs/sync 48.367s
ok launchpad.net/juju-core/environs/testing 0.165s
ok launchpad.net/juju-core/environs/tools 4.387s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.011s
ok launchpad.net/juju-core/instance 0.021s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju...

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (567.9 KiB)

The attempt to merge lp:~rogpeppe/juju-core/mfoord-wrapsingletonworkers into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.014s
ok launchpad.net/juju-core/agent 1.637s
ok launchpad.net/juju-core/agent/mongo 1.007s
ok launchpad.net/juju-core/agent/tools 0.216s
ok launchpad.net/juju-core/bzr 5.452s
ok launchpad.net/juju-core/cert 2.558s
ok launchpad.net/juju-core/charm 0.353s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.027s
ok launchpad.net/juju-core/cloudinit/sshinit 0.753s
ok launchpad.net/juju-core/cmd 0.171s
ok launchpad.net/juju-core/cmd/charm-admin 0.745s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/envcmd 0.170s
ok launchpad.net/juju-core/cmd/juju 218.753s
ok launchpad.net/juju-core/cmd/jujud 79.590s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 7.435s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.161s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.028s
ok launchpad.net/juju-core/container 0.038s
ok launchpad.net/juju-core/container/factory 0.041s
ok launchpad.net/juju-core/container/kvm 0.185s
ok launchpad.net/juju-core/container/kvm/mock 0.032s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.373s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.244s
ok launchpad.net/juju-core/environs 2.293s
ok launchpad.net/juju-core/environs/bootstrap 11.024s
ok launchpad.net/juju-core/environs/cloudinit 0.515s
ok launchpad.net/juju-core/environs/config 2.220s
ok launchpad.net/juju-core/environs/configstore 0.032s
ok launchpad.net/juju-core/environs/filestorage 0.027s
ok launchpad.net/juju-core/environs/httpstorage 0.691s
ok launchpad.net/juju-core/environs/imagemetadata 0.405s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.035s
ok launchpad.net/juju-core/environs/jujutest 0.170s
ok launchpad.net/juju-core/environs/manual 11.722s
ok launchpad.net/juju-core/environs/simplestreams 0.254s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 1.003s
ok launchpad.net/juju-core/environs/storage 0.810s
ok launchpad.net/juju-core/environs/sync 49.454s
ok launchpad.net/juju-core/environs/testing 0.155s
ok launchpad.net/juju-core/environs/tools 4.662s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.011s
ok launchpad.net/juju-core/instance 0.023s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'agent/mongo/mongo.go'
--- agent/mongo/mongo.go 2014-04-08 20:10:22 +0000
+++ agent/mongo/mongo.go 2014-04-10 14:24:10 +0000
@@ -51,6 +51,14 @@
51 addrs := obj.Addresses()51 addrs := obj.Addresses()
5252
53 masterHostPort, err := replicaset.MasterHostPort(session)53 masterHostPort, err := replicaset.MasterHostPort(session)
54
55 // If the replica set has not been configured, then we
56 // can have only one master and the caller must
57 // be that master.
58 if err == replicaset.ErrMasterNotConfigured {
59 return true, nil
60 }
61
54 if err != nil {62 if err != nil {
55 return false, err63 return false, err
56 }64 }
5765
=== modified file 'cmd/jujud/machine.go'
--- cmd/jujud/machine.go 2014-04-08 20:44:59 +0000
+++ cmd/jujud/machine.go 2014-04-10 14:24:10 +0000
@@ -11,6 +11,7 @@
11 "time"11 "time"
1212
13 "github.com/juju/loggo"13 "github.com/juju/loggo"
14 "labix.org/v2/mgo"
14 "launchpad.net/gnuflag"15 "launchpad.net/gnuflag"
15 "launchpad.net/tomb"16 "launchpad.net/tomb"
1617
@@ -50,6 +51,7 @@
50 "launchpad.net/juju-core/worker/provisioner"51 "launchpad.net/juju-core/worker/provisioner"
51 "launchpad.net/juju-core/worker/resumer"52 "launchpad.net/juju-core/worker/resumer"
52 "launchpad.net/juju-core/worker/rsyslog"53 "launchpad.net/juju-core/worker/rsyslog"
54 "launchpad.net/juju-core/worker/singular"
53 "launchpad.net/juju-core/worker/terminationworker"55 "launchpad.net/juju-core/worker/terminationworker"
54 "launchpad.net/juju-core/worker/upgrader"56 "launchpad.net/juju-core/worker/upgrader"
55)57)
@@ -64,11 +66,15 @@
64type eitherState interface{}66type eitherState interface{}
6567
66var (68var (
67 retryDelay = 3 * time.Second69 retryDelay = 3 * time.Second
68 jujuRun = "/usr/local/bin/juju-run"70 jujuRun = "/usr/local/bin/juju-run"
69 useMultipleCPUs = utils.UseMultipleCPUs71 useMultipleCPUs = utils.UseMultipleCPUs
72
73 // The following are defined as variables to
74 // allow the tests to intercept calls to the functions.
70 ensureMongoServer = mongo.EnsureMongoServer75 ensureMongoServer = mongo.EnsureMongoServer
71 maybeInitiateMongoServer = mongo.MaybeInitiateMongoServer76 maybeInitiateMongoServer = mongo.MaybeInitiateMongoServer
77 newSingularRunner = singular.New
7278
73 // reportOpenedAPI is exposed for tests to know when79 // reportOpenedAPI is exposed for tests to know when
74 // the State has been successfully opened.80 // the State has been successfully opened.
@@ -239,15 +245,22 @@
239 }245 }
240246
241 rsyslogMode := rsyslog.RsyslogModeForwarding247 rsyslogMode := rsyslog.RsyslogModeForwarding
248 runner := newRunner(connectionIsFatal(st), moreImportant)
249 var singularRunner worker.Runner
242 for _, job := range entity.Jobs() {250 for _, job := range entity.Jobs() {
243 if job == params.JobManageEnviron {251 if job == params.JobManageEnviron {
244 rsyslogMode = rsyslog.RsyslogModeAccumulate252 rsyslogMode = rsyslog.RsyslogModeAccumulate
253 conn := singularAPIConn{st, st.Agent()}
254 singularRunner, err = newSingularRunner(runner, conn)
255 if err != nil {
256 return nil, fmt.Errorf("cannot make singular API Runner: %v", err)
257 }
245 break258 break
246 }259 }
247 }260 }
248 runner := newRunner(connectionIsFatal(st), moreImportant)
249261
250 // Run the upgrader and the upgrade-steps worker without waiting for the upgrade steps to complete.262 // Run the upgrader and the upgrade-steps worker without waiting for
263 // the upgrade steps to complete.
251 runner.StartWorker("upgrader", func() (worker.Worker, error) {264 runner.StartWorker("upgrader", func() (worker.Worker, error) {
252 return upgrader.NewUpgrader(st.Upgrader(), agentConfig), nil265 return upgrader.NewUpgrader(st.Upgrader(), agentConfig), nil
253 })266 })
@@ -255,7 +268,8 @@
255 return a.upgradeWorker(st, entity.Jobs(), agentConfig), nil268 return a.upgradeWorker(st, entity.Jobs(), agentConfig), nil
256 })269 })
257270
258 // All other workers must wait for the upgrade steps to complete before starting.271 // All other workers must wait for the upgrade steps to complete
272 // before starting.
259 a.startWorkerAfterUpgrade(runner, "machiner", func() (worker.Worker, error) {273 a.startWorkerAfterUpgrade(runner, "machiner", func() (worker.Worker, error) {
260 return machiner.NewMachiner(st.Machiner(), agentConfig), nil274 return machiner.NewMachiner(st.Machiner(), agentConfig), nil
261 })275 })
@@ -272,7 +286,8 @@
272 return newRsyslogConfigWorker(st.Rsyslog(), agentConfig, rsyslogMode)286 return newRsyslogConfigWorker(st.Rsyslog(), agentConfig, rsyslogMode)
273 })287 })
274288
275 // If not a local provider bootstrap machine, start the worker to manage SSH keys.289 // If not a local provider bootstrap machine, start the worker to
290 // manage SSH keys.
276 providerType := agentConfig.Value(agent.ProviderType)291 providerType := agentConfig.Value(agent.ProviderType)
277 if providerType != provider.Local || a.MachineId != bootstrapMachineId {292 if providerType != provider.Local || a.MachineId != bootstrapMachineId {
278 a.startWorkerAfterUpgrade(runner, "authenticationworker", func() (worker.Worker, error) {293 a.startWorkerAfterUpgrade(runner, "authenticationworker", func() (worker.Worker, error) {
@@ -293,16 +308,17 @@
293 return deployer.NewDeployer(apiDeployer, context), nil308 return deployer.NewDeployer(apiDeployer, context), nil
294 })309 })
295 case params.JobManageEnviron:310 case params.JobManageEnviron:
296 a.startWorkerAfterUpgrade(runner, "environ-provisioner", func() (worker.Worker, error) {311 a.startWorkerAfterUpgrade(singularRunner, "environ-provisioner", func() (worker.Worker, error) {
297 return provisioner.NewEnvironProvisioner(st.Provisioner(), agentConfig), nil312 return provisioner.NewEnvironProvisioner(st.Provisioner(), agentConfig), nil
298 })313 })
299 // TODO(axw) 2013-09-24 bug #1229506314 // TODO(axw) 2013-09-24 bug #1229506
300 // Make another job to enable the firewaller. Not all environments315 // Make another job to enable the firewaller. Not all
301 // are capable of managing ports centrally.316 // environments are capable of managing ports
302 a.startWorkerAfterUpgrade(runner, "firewaller", func() (worker.Worker, error) {317 // centrally.
318 a.startWorkerAfterUpgrade(singularRunner, "firewaller", func() (worker.Worker, error) {
303 return firewaller.NewFirewaller(st.Firewaller())319 return firewaller.NewFirewaller(st.Firewaller())
304 })320 })
305 a.startWorkerAfterUpgrade(runner, "charm-revision-updater", func() (worker.Worker, error) {321 a.startWorkerAfterUpgrade(singularRunner, "charm-revision-updater", func() (worker.Worker, error) {
306 return charmrevisionworker.NewRevisionUpdateWorker(st.CharmRevisionUpdater()), nil322 return charmrevisionworker.NewRevisionUpdateWorker(st.CharmRevisionUpdater()), nil
307 })323 })
308 case params.JobManageStateDeprecated:324 case params.JobManageStateDeprecated:
@@ -399,7 +415,12 @@
399 }415 }
400 reportOpenedState(st)416 reportOpenedState(st)
401417
418 singularStateConn := singularStateConn{st.MongoSession(), m}
402 runner := newRunner(connectionIsFatal(st), moreImportant)419 runner := newRunner(connectionIsFatal(st), moreImportant)
420 singularRunner, err := newSingularRunner(runner, singularStateConn)
421 if err != nil {
422 return nil, fmt.Errorf("cannot make singular State Runner: %v", err)
423 }
403424
404 // Take advantage of special knowledge here in that we will only ever want425 // Take advantage of special knowledge here in that we will only ever want
405 // the storage provider on one machine, and that is the "bootstrap" node.426 // the storage provider on one machine, and that is the "bootstrap" node.
@@ -444,16 +465,16 @@
444 return apiserver.NewServer(465 return apiserver.NewServer(
445 st, fmt.Sprintf(":%d", port), cert, key, dataDir, logDir)466 st, fmt.Sprintf(":%d", port), cert, key, dataDir, logDir)
446 })467 })
447 a.startWorkerAfterUpgrade(runner, "cleaner", func() (worker.Worker, error) {468 a.startWorkerAfterUpgrade(singularRunner, "cleaner", func() (worker.Worker, error) {
448 return cleaner.NewCleaner(st), nil469 return cleaner.NewCleaner(st), nil
449 })470 })
450 a.startWorkerAfterUpgrade(runner, "resumer", func() (worker.Worker, error) {471 a.startWorkerAfterUpgrade(singularRunner, "resumer", func() (worker.Worker, error) {
451 // The action of resumer is so subtle that it is not tested,472 // The action of resumer is so subtle that it is not tested,
452 // because we can't figure out how to do so without brutalising473 // because we can't figure out how to do so without brutalising
453 // the transaction log.474 // the transaction log.
454 return resumer.NewResumer(st), nil475 return resumer.NewResumer(st), nil
455 })476 })
456 a.startWorkerAfterUpgrade(runner, "minunitsworker", func() (worker.Worker, error) {477 a.startWorkerAfterUpgrade(singularRunner, "minunitsworker", func() (worker.Worker, error) {
457 return minunitsworker.NewMinUnitsWorker(st), nil478 return minunitsworker.NewMinUnitsWorker(st), nil
458 })479 })
459 case state.JobManageStateDeprecated:480 case state.JobManageStateDeprecated:
@@ -670,3 +691,33 @@
670 }691 }
671 return fmt.Errorf("uninstall failed: %v", errors)692 return fmt.Errorf("uninstall failed: %v", errors)
672}693}
694
695// singularAPIConn implements singular.Conn on
696// top of an API connection.
697type singularAPIConn struct {
698 apiState *api.State
699 agentState *apiagent.State
700}
701
702func (c singularAPIConn) IsMaster() (bool, error) {
703 return c.agentState.IsMaster()
704}
705
706func (c singularAPIConn) Ping() error {
707 return c.apiState.Ping()
708}
709
710// singularStateConn implements singular.Conn on
711// top of a State connection.
712type singularStateConn struct {
713 session *mgo.Session
714 machine *state.Machine
715}
716
717func (c singularStateConn) IsMaster() (bool, error) {
718 return mongo.IsMaster(c.session, c.machine)
719}
720
721func (c singularStateConn) Ping() error {
722 return c.session.Ping()
723}
673724
=== modified file 'cmd/jujud/machine_test.go'
--- cmd/jujud/machine_test.go 2014-04-08 20:42:04 +0000
+++ cmd/jujud/machine_test.go 2014-04-10 14:24:10 +0000
@@ -9,6 +9,7 @@
9 "path/filepath"9 "path/filepath"
10 "reflect"10 "reflect"
11 "strings"11 "strings"
12 "sync"
12 "time"13 "time"
1314
14 "github.com/juju/testing"15 "github.com/juju/testing"
@@ -39,6 +40,7 @@
39 "launchpad.net/juju-core/tools"40 "launchpad.net/juju-core/tools"
40 "launchpad.net/juju-core/upstart"41 "launchpad.net/juju-core/upstart"
41 "launchpad.net/juju-core/utils"42 "launchpad.net/juju-core/utils"
43 "launchpad.net/juju-core/utils/set"
42 "launchpad.net/juju-core/utils/ssh"44 "launchpad.net/juju-core/utils/ssh"
43 sshtesting "launchpad.net/juju-core/utils/ssh/testing"45 sshtesting "launchpad.net/juju-core/utils/ssh/testing"
44 "launchpad.net/juju-core/version"46 "launchpad.net/juju-core/version"
@@ -48,11 +50,13 @@
48 "launchpad.net/juju-core/worker/instancepoller"50 "launchpad.net/juju-core/worker/instancepoller"
49 "launchpad.net/juju-core/worker/machineenvironmentworker"51 "launchpad.net/juju-core/worker/machineenvironmentworker"
50 "launchpad.net/juju-core/worker/rsyslog"52 "launchpad.net/juju-core/worker/rsyslog"
53 "launchpad.net/juju-core/worker/singular"
51 "launchpad.net/juju-core/worker/upgrader"54 "launchpad.net/juju-core/worker/upgrader"
52)55)
5356
54type commonMachineSuite struct {57type commonMachineSuite struct {
55 agentSuite58 agentSuite
59 singularRecord *singularRunnerRecord
56 lxctesting.TestSuite60 lxctesting.TestSuite
57}61}
5862
@@ -85,6 +89,9 @@
85 fakeCmd(filepath.Join(testpath, "stop"))89 fakeCmd(filepath.Join(testpath, "stop"))
8690
87 s.PatchValue(&upstart.InitDir, c.MkDir())91 s.PatchValue(&upstart.InitDir, c.MkDir())
92
93 s.singularRecord = &singularRunnerRecord{}
94 testing.PatchValue(&newSingularRunner, s.singularRecord.newSingularRunner)
88}95}
8996
90func fakeCmd(path string) {97func fakeCmd(path string) {
@@ -373,6 +380,15 @@
373 case <-time.After(5 * time.Second):380 case <-time.After(5 * time.Second):
374 c.Fatalf("timed out waiting for agent to terminate")381 c.Fatalf("timed out waiting for agent to terminate")
375 }382 }
383
384 c.Assert(s.singularRecord.started(), jc.DeepEquals, []string{
385 "charm-revision-updater",
386 "cleaner",
387 "environ-provisioner",
388 "firewaller",
389 "minunitsworker",
390 "resumer",
391 })
376}392}
377393
378func (s *MachineSuite) TestManageEnvironRunsInstancePoller(c *gc.C) {394func (s *MachineSuite) TestManageEnvironRunsInstancePoller(c *gc.C) {
@@ -948,3 +964,36 @@
948 }964 }
949 c.Assert(success, gc.Equals, true)965 c.Assert(success, gc.Equals, true)
950}966}
967
968type singularRunnerRecord struct {
969 mu sync.Mutex
970 startedWorkers set.Strings
971}
972
973func (r *singularRunnerRecord) newSingularRunner(runner worker.Runner, conn singular.Conn) (worker.Runner, error) {
974 sr, err := singular.New(runner, conn)
975 if err != nil {
976 return nil, err
977 }
978 return &fakeSingularRunner{
979 Runner: sr,
980 record: r,
981 }, nil
982}
983
984// started returns the names of all singular-started workers.
985func (r *singularRunnerRecord) started() []string {
986 return r.startedWorkers.SortedValues()
987}
988
989type fakeSingularRunner struct {
990 worker.Runner
991 record *singularRunnerRecord
992}
993
994func (r *fakeSingularRunner) StartWorker(name string, start func() (worker.Worker, error)) error {
995 r.record.mu.Lock()
996 defer r.record.mu.Unlock()
997 r.record.startedWorkers.Add(name)
998 return r.Runner.StartWorker(name, start)
999}
9511000
=== modified file 'replicaset/replicaset.go'
--- replicaset/replicaset.go 2014-04-09 16:45:35 +0000
+++ replicaset/replicaset.go 2014-04-10 14:24:10 +0000
@@ -241,13 +241,19 @@
241 return results, nil241 return results, nil
242}242}
243243
244// MasterHostPort returns the "address:port" string for the244var ErrMasterNotConfigured = fmt.Errorf("mongo master not configured")
245// primary mongo server in the replicaset.245
246// MasterHostPort returns the "address:port" string for the primary
247// mongo server in the replicaset. It returns ErrMasterNotConfigured if
248// the replica set has not yet been initiated.
246func MasterHostPort(session *mgo.Session) (string, error) {249func MasterHostPort(session *mgo.Session) (string, error) {
247 results, err := IsMaster(session)250 results, err := IsMaster(session)
248 if err != nil {251 if err != nil {
249 return "", err252 return "", err
250 }253 }
254 if results.PrimaryAddress == "" {
255 return "", ErrMasterNotConfigured
256 }
251 return results.PrimaryAddress, nil257 return results.PrimaryAddress, nil
252}258}
253259
254260
=== modified file 'replicaset/replicaset_test.go'
--- replicaset/replicaset_test.go 2014-04-09 16:38:25 +0000
+++ replicaset/replicaset_test.go 2014-04-10 14:24:10 +0000
@@ -274,6 +274,8 @@
274 break274 break
275 }275 }
276 c.Logf("attempting Set got error: %v", err)276 c.Logf("attempting Set got error: %v", err)
277 c.Logf("current session mode: %v", session.Mode())
278 session.Refresh()
277 }279 }
278 c.Logf("Set() %d attempts in %s", attemptCount, time.Since(start))280 c.Logf("Set() %d attempts in %s", attemptCount, time.Since(start))
279 c.Assert(err, gc.IsNil)281 c.Assert(err, gc.IsNil)
@@ -354,6 +356,17 @@
354 c.Assert(result, gc.Equals, expected)356 c.Assert(result, gc.Equals, expected)
355}357}
356358
359func (s *MongoSuite) TestMasterHostPortOnUnconfiguredReplicaSet(c *gc.C) {
360 inst := &coretesting.MgoInstance{}
361 err := inst.Start(true)
362 c.Assert(err, gc.IsNil)
363 defer inst.Destroy()
364 session := inst.MustDial()
365 hp, err := MasterHostPort(session)
366 c.Assert(err, gc.Equals, ErrMasterNotConfigured)
367 c.Assert(hp, gc.Equals, "")
368}
369
357func (s *MongoSuite) TestCurrentStatus(c *gc.C) {370func (s *MongoSuite) TestCurrentStatus(c *gc.C) {
358 session := root.MustDial()371 session := root.MustDial()
359 defer session.Close()372 defer session.Close()

Subscribers

People subscribed via source and target branches

to status/vote changes: