github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/agent/mongo/upgrade_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package mongo_test 5 6 import ( 7 "net" 8 "os" 9 "path/filepath" 10 "strconv" 11 12 jujutesting "github.com/juju/testing" 13 jc "github.com/juju/testing/checkers" 14 "labix.org/v2/mgo" 15 gc "launchpad.net/gocheck" 16 17 "github.com/juju/juju/agent/mongo" 18 coretesting "github.com/juju/juju/testing" 19 "github.com/juju/juju/upstart" 20 ) 21 22 type EnsureAdminSuite struct { 23 coretesting.BaseSuite 24 serviceStarts int 25 serviceStops int 26 } 27 28 var _ = gc.Suite(&EnsureAdminSuite{}) 29 30 func (s *EnsureAdminSuite) SetUpTest(c *gc.C) { 31 s.BaseSuite.SetUpTest(c) 32 s.serviceStarts = 0 33 s.serviceStops = 0 34 s.PatchValue(mongo.UpstartConfInstall, func(conf *upstart.Conf) error { 35 return nil 36 }) 37 s.PatchValue(mongo.UpstartServiceStart, func(svc *upstart.Service) error { 38 s.serviceStarts++ 39 return nil 40 }) 41 s.PatchValue(mongo.UpstartServiceStop, func(svc *upstart.Service) error { 42 s.serviceStops++ 43 return nil 44 }) 45 } 46 47 func (s *EnsureAdminSuite) TestEnsureAdminUser(c *gc.C) { 48 inst := &coretesting.MgoInstance{} 49 err := inst.Start(true) 50 c.Assert(err, gc.IsNil) 51 defer inst.DestroyWithLog() 52 dialInfo := inst.DialInfo() 53 54 // Mock out mongod, so the --noauth execution doesn't 55 // do anything nasty. Also mock out the Signal method. 56 jujutesting.PatchExecutableAsEchoArgs(c, s, "mongod") 57 mongodDir := filepath.SplitList(os.Getenv("PATH"))[0] 58 s.PatchValue(&mongo.JujuMongodPath, filepath.Join(mongodDir, "mongod")) 59 s.PatchValue(mongo.ProcessSignal, func(*os.Process, os.Signal) error { 60 return nil 61 }) 62 63 // First call succeeds, as there are no users yet. 64 added, err := s.ensureAdminUser(c, dialInfo, "whomever", "whatever") 65 c.Assert(err, gc.IsNil) 66 c.Assert(added, jc.IsTrue) 67 68 // EnsureAdminUser should have stopped the mongo service, 69 // started a new mongod with --noauth, and then finally 70 // started the service back up. 71 c.Assert(s.serviceStarts, gc.Equals, 1) 72 c.Assert(s.serviceStops, gc.Equals, 1) 73 _, portString, err := net.SplitHostPort(dialInfo.Addrs[0]) 74 c.Assert(err, gc.IsNil) 75 jujutesting.AssertEchoArgs(c, "mongod", 76 "--noauth", 77 "--dbpath", "db", 78 "--sslOnNormalPorts", 79 "--sslPEMKeyFile", "server.pem", 80 "--sslPEMKeyPassword", "ignored", 81 "--bind_ip", "127.0.0.1", 82 "--port", portString, 83 "--noprealloc", 84 "--syslog", 85 "--smallfiles", 86 "--journal", 87 ) 88 89 // Second call succeeds, as the admin user is already there. 90 added, err = s.ensureAdminUser(c, dialInfo, "whomever", "whatever") 91 c.Assert(err, gc.IsNil) 92 c.Assert(added, jc.IsFalse) 93 94 // There should have been no additional start/stop. 95 c.Assert(s.serviceStarts, gc.Equals, 1) 96 c.Assert(s.serviceStops, gc.Equals, 1) 97 } 98 99 func (s *EnsureAdminSuite) TestEnsureAdminUserError(c *gc.C) { 100 inst := &coretesting.MgoInstance{} 101 err := inst.Start(true) 102 c.Assert(err, gc.IsNil) 103 defer inst.Destroy() 104 dialInfo := inst.DialInfo() 105 106 // First call succeeds, as there are no users yet (mimics --noauth). 107 added, err := s.ensureAdminUser(c, dialInfo, "whomever", "whatever") 108 c.Assert(err, gc.IsNil) 109 c.Assert(added, jc.IsTrue) 110 111 // Second call fails, as there is another user and the database doesn't 112 // actually get reopened with --noauth in the test; mimics AddUser failure 113 _, err = s.ensureAdminUser(c, dialInfo, "whomeverelse", "whateverelse") 114 c.Assert(err, gc.ErrorMatches, `failed to add "whomeverelse" to admin database: not authorized for upsert on admin.system.users`) 115 } 116 117 func (s *EnsureAdminSuite) ensureAdminUser(c *gc.C, dialInfo *mgo.DialInfo, user, password string) (added bool, err error) { 118 _, portString, err := net.SplitHostPort(dialInfo.Addrs[0]) 119 c.Assert(err, gc.IsNil) 120 port, err := strconv.Atoi(portString) 121 c.Assert(err, gc.IsNil) 122 return mongo.EnsureAdminUser(mongo.EnsureAdminUserParams{ 123 DialInfo: dialInfo, 124 Port: port, 125 User: user, 126 Password: password, 127 }) 128 }