launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/agent/bootstrap_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package agent_test
     5  
     6  import (
     7  	gc "launchpad.net/gocheck"
     8  
     9  	"launchpad.net/juju-core/agent"
    10  	"launchpad.net/juju-core/constraints"
    11  	"launchpad.net/juju-core/environs/config"
    12  	"launchpad.net/juju-core/instance"
    13  	"launchpad.net/juju-core/state"
    14  	"launchpad.net/juju-core/testing"
    15  	jc "launchpad.net/juju-core/testing/checkers"
    16  	"launchpad.net/juju-core/testing/testbase"
    17  	"launchpad.net/juju-core/utils"
    18  	"launchpad.net/juju-core/version"
    19  )
    20  
    21  type bootstrapSuite struct {
    22  	testbase.LoggingSuite
    23  	testing.MgoSuite
    24  }
    25  
    26  var _ = gc.Suite(&bootstrapSuite{})
    27  
    28  func (s *bootstrapSuite) SetUpSuite(c *gc.C) {
    29  	s.LoggingSuite.SetUpSuite(c)
    30  	s.MgoSuite.SetUpSuite(c)
    31  }
    32  
    33  func (s *bootstrapSuite) TearDownSuite(c *gc.C) {
    34  	s.MgoSuite.TearDownSuite(c)
    35  	s.LoggingSuite.TearDownSuite(c)
    36  }
    37  
    38  func (s *bootstrapSuite) SetUpTest(c *gc.C) {
    39  	s.LoggingSuite.SetUpTest(c)
    40  	s.MgoSuite.SetUpTest(c)
    41  }
    42  
    43  func (s *bootstrapSuite) TearDownTest(c *gc.C) {
    44  	s.MgoSuite.TearDownTest(c)
    45  	s.LoggingSuite.TearDownTest(c)
    46  }
    47  
    48  func (s *bootstrapSuite) TestInitializeState(c *gc.C) {
    49  	dataDir := c.MkDir()
    50  
    51  	pwHash := utils.UserPasswordHash(testing.DefaultMongoPassword, utils.CompatSalt)
    52  	cfg, err := agent.NewAgentConfig(agent.AgentConfigParams{
    53  		DataDir:        dataDir,
    54  		Tag:            "machine-0",
    55  		StateAddresses: []string{testing.MgoServer.Addr()},
    56  		CACert:         []byte(testing.CACert),
    57  		Password:       pwHash,
    58  	})
    59  	c.Assert(err, gc.IsNil)
    60  	expectConstraints := constraints.MustParse("mem=1024M")
    61  	expectHW := instance.MustParseHardware("mem=2048M")
    62  	mcfg := agent.BootstrapMachineConfig{
    63  		Constraints:     expectConstraints,
    64  		Jobs:            []state.MachineJob{state.JobHostUnits},
    65  		InstanceId:      "i-bootstrap",
    66  		Characteristics: expectHW,
    67  	}
    68  	envAttrs := testing.FakeConfig().Delete("admin-secret").Merge(testing.Attrs{
    69  		"agent-version": version.Current.Number.String(),
    70  	})
    71  	envCfg, err := config.New(config.NoDefaults, envAttrs)
    72  	c.Assert(err, gc.IsNil)
    73  
    74  	st, m, err := cfg.InitializeState(envCfg, mcfg, state.DialOpts{})
    75  	c.Assert(err, gc.IsNil)
    76  	defer st.Close()
    77  
    78  	// Check that initial admin user has been set up correctly.
    79  	s.assertCanLogInAsAdmin(c, pwHash)
    80  	user, err := st.User("admin")
    81  	c.Assert(err, gc.IsNil)
    82  	c.Assert(user.PasswordValid(testing.DefaultMongoPassword), jc.IsTrue)
    83  
    84  	// Check that environment configuration has been added.
    85  	newEnvCfg, err := st.EnvironConfig()
    86  	c.Assert(err, gc.IsNil)
    87  	c.Assert(newEnvCfg.AllAttrs(), gc.DeepEquals, envCfg.AllAttrs())
    88  
    89  	// Check that the bootstrap machine looks correct.
    90  	c.Assert(m.Id(), gc.Equals, "0")
    91  	c.Assert(m.Jobs(), gc.DeepEquals, []state.MachineJob{state.JobHostUnits})
    92  	c.Assert(m.Series(), gc.Equals, version.Current.Series)
    93  	c.Assert(m.CheckProvisioned(state.BootstrapNonce), jc.IsTrue)
    94  	gotConstraints, err := m.Constraints()
    95  	c.Assert(err, gc.IsNil)
    96  	c.Assert(gotConstraints, gc.DeepEquals, expectConstraints)
    97  	c.Assert(err, gc.IsNil)
    98  	gotHW, err := m.HardwareCharacteristics()
    99  	c.Assert(err, gc.IsNil)
   100  	c.Assert(*gotHW, gc.DeepEquals, expectHW)
   101  
   102  	// Check that the machine agent's config has been written
   103  	// and that we can use it to connect to the state.
   104  	newCfg, err := agent.ReadConf(dataDir, "machine-0")
   105  	c.Assert(err, gc.IsNil)
   106  	c.Assert(newCfg.Tag(), gc.Equals, "machine-0")
   107  	c.Assert(agent.Password(newCfg), gc.Not(gc.Equals), pwHash)
   108  	c.Assert(agent.Password(newCfg), gc.Not(gc.Equals), testing.DefaultMongoPassword)
   109  	st1, err := cfg.OpenState()
   110  	c.Assert(err, gc.IsNil)
   111  	defer st1.Close()
   112  }
   113  
   114  func (s *bootstrapSuite) TestInitializeStateFailsSecondTime(c *gc.C) {
   115  	dataDir := c.MkDir()
   116  	pwHash := utils.UserPasswordHash(testing.DefaultMongoPassword, utils.CompatSalt)
   117  	cfg, err := agent.NewAgentConfig(agent.AgentConfigParams{
   118  		DataDir:        dataDir,
   119  		Tag:            "machine-0",
   120  		StateAddresses: []string{testing.MgoServer.Addr()},
   121  		CACert:         []byte(testing.CACert),
   122  		Password:       pwHash,
   123  	})
   124  	c.Assert(err, gc.IsNil)
   125  	expectConstraints := constraints.MustParse("mem=1024M")
   126  	expectHW := instance.MustParseHardware("mem=2048M")
   127  	mcfg := agent.BootstrapMachineConfig{
   128  		Constraints:     expectConstraints,
   129  		Jobs:            []state.MachineJob{state.JobHostUnits},
   130  		InstanceId:      "i-bootstrap",
   131  		Characteristics: expectHW,
   132  	}
   133  	envAttrs := testing.FakeConfig().Delete("admin-secret").Merge(testing.Attrs{
   134  		"agent-version": version.Current.Number.String(),
   135  	})
   136  	envCfg, err := config.New(config.NoDefaults, envAttrs)
   137  	c.Assert(err, gc.IsNil)
   138  
   139  	st, _, err := cfg.InitializeState(envCfg, mcfg, state.DialOpts{})
   140  	c.Assert(err, gc.IsNil)
   141  	err = st.SetAdminMongoPassword("")
   142  	c.Check(err, gc.IsNil)
   143  	st.Close()
   144  
   145  	st, _, err = cfg.InitializeState(envCfg, mcfg, state.DialOpts{})
   146  	if err == nil {
   147  		st.Close()
   148  	}
   149  	c.Assert(err, gc.ErrorMatches, "cannot initialize bootstrap user: user already exists")
   150  }
   151  
   152  func (*bootstrapSuite) assertCanLogInAsAdmin(c *gc.C, password string) {
   153  	info := &state.Info{
   154  		Addrs:    []string{testing.MgoServer.Addr()},
   155  		CACert:   []byte(testing.CACert),
   156  		Tag:      "",
   157  		Password: password,
   158  	}
   159  	st, err := state.Open(info, state.DialOpts{})
   160  	c.Assert(err, gc.IsNil)
   161  	defer st.Close()
   162  	_, err = st.Machine("0")
   163  	c.Assert(err, gc.IsNil)
   164  }
   165  
   166  func (s *bootstrapSuite) TestMarshalUnmarshalBootstrapJobs(c *gc.C) {
   167  	jobs := [][]state.MachineJob{
   168  		{},
   169  		{state.JobHostUnits},
   170  		{state.JobManageEnviron},
   171  		{state.JobHostUnits, state.JobManageEnviron},
   172  	}
   173  	for _, jobs := range jobs {
   174  		marshalled, err := agent.MarshalBootstrapJobs(jobs...)
   175  		c.Assert(err, gc.IsNil)
   176  		unmarshalled, err := agent.UnmarshalBootstrapJobs(marshalled)
   177  		c.Assert(err, gc.IsNil)
   178  		c.Assert(unmarshalled, gc.DeepEquals, jobs)
   179  	}
   180  }