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  }