github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/state/api/deployer/deployer_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package deployer_test
     5  
     6  import (
     7  	stdtesting "testing"
     8  
     9  	gc "launchpad.net/gocheck"
    10  
    11  	"launchpad.net/juju-core/instance"
    12  	"launchpad.net/juju-core/juju/testing"
    13  	"launchpad.net/juju-core/state"
    14  	"launchpad.net/juju-core/state/api"
    15  	"launchpad.net/juju-core/state/api/deployer"
    16  	"launchpad.net/juju-core/state/api/params"
    17  	statetesting "launchpad.net/juju-core/state/testing"
    18  	coretesting "launchpad.net/juju-core/testing"
    19  	jc "launchpad.net/juju-core/testing/checkers"
    20  )
    21  
    22  func TestAll(t *stdtesting.T) {
    23  	coretesting.MgoTestPackage(t)
    24  }
    25  
    26  type deployerSuite struct {
    27  	testing.JujuConnSuite
    28  
    29  	stateAPI *api.State
    30  
    31  	// These are raw State objects. Use them for setup and assertions, but
    32  	// should never be touched by the API calls themselves
    33  	machine     *state.Machine
    34  	service0    *state.Service
    35  	service1    *state.Service
    36  	principal   *state.Unit
    37  	subordinate *state.Unit
    38  
    39  	st *deployer.State
    40  }
    41  
    42  var _ = gc.Suite(&deployerSuite{})
    43  
    44  func (s *deployerSuite) SetUpTest(c *gc.C) {
    45  	s.JujuConnSuite.SetUpTest(c)
    46  	s.stateAPI, s.machine = s.OpenAPIAsNewMachine(c, state.JobManageEnviron, state.JobHostUnits)
    47  
    48  	var err error
    49  	// Create the needed services and relate them.
    50  	s.service0 = s.AddTestingService(c, "mysql", s.AddTestingCharm(c, "mysql"))
    51  	s.service1 = s.AddTestingService(c, "logging", s.AddTestingCharm(c, "logging"))
    52  	eps, err := s.State.InferEndpoints([]string{"mysql", "logging"})
    53  	c.Assert(err, gc.IsNil)
    54  	rel, err := s.State.AddRelation(eps...)
    55  	c.Assert(err, gc.IsNil)
    56  
    57  	// Create principal and subordinate units and assign them.
    58  	s.principal, err = s.service0.AddUnit()
    59  	c.Assert(err, gc.IsNil)
    60  	err = s.principal.AssignToMachine(s.machine)
    61  	c.Assert(err, gc.IsNil)
    62  	relUnit, err := rel.Unit(s.principal)
    63  	c.Assert(err, gc.IsNil)
    64  	err = relUnit.EnterScope(nil)
    65  	c.Assert(err, gc.IsNil)
    66  	s.subordinate, err = s.service1.Unit("logging/0")
    67  	c.Assert(err, gc.IsNil)
    68  
    69  	// Create the deployer facade.
    70  	s.st = s.stateAPI.Deployer()
    71  	c.Assert(s.st, gc.NotNil)
    72  }
    73  
    74  // Note: This is really meant as a unit-test, this isn't a test that
    75  // should need all of the setup we have for this test suite
    76  func (s *deployerSuite) TestNew(c *gc.C) {
    77  	deployer := deployer.NewState(s.stateAPI)
    78  	c.Assert(deployer, gc.NotNil)
    79  }
    80  
    81  func (s *deployerSuite) assertUnauthorized(c *gc.C, err error) {
    82  	c.Assert(err, gc.ErrorMatches, "permission denied")
    83  	c.Assert(err, jc.Satisfies, params.IsCodeUnauthorized)
    84  }
    85  
    86  func (s *deployerSuite) TestWatchUnitsWrongMachine(c *gc.C) {
    87  	// Try with a non-existent machine tag.
    88  	machine, err := s.st.Machine("machine-42")
    89  	c.Assert(err, gc.IsNil)
    90  	w, err := machine.WatchUnits()
    91  	s.assertUnauthorized(c, err)
    92  	c.Assert(w, gc.IsNil)
    93  
    94  	// Try it with an invalid tag format.
    95  	machine, err = s.st.Machine("foo")
    96  	c.Assert(err, gc.IsNil)
    97  	w, err = machine.WatchUnits()
    98  	s.assertUnauthorized(c, err)
    99  	c.Assert(w, gc.IsNil)
   100  }
   101  
   102  func (s *deployerSuite) TestWatchUnits(c *gc.C) {
   103  	machine, err := s.st.Machine(s.machine.Tag())
   104  	c.Assert(err, gc.IsNil)
   105  	w, err := machine.WatchUnits()
   106  	c.Assert(err, gc.IsNil)
   107  	defer statetesting.AssertStop(c, w)
   108  	wc := statetesting.NewStringsWatcherC(c, s.BackingState, w)
   109  
   110  	// Initial event.
   111  	wc.AssertChange("mysql/0", "logging/0")
   112  	wc.AssertNoChange()
   113  
   114  	// Change something other than the lifecycle and make sure it's
   115  	// not detected.
   116  	err = s.subordinate.SetPassword("foo")
   117  	c.Assert(err, gc.ErrorMatches, "password is only 3 bytes long, and is not a valid Agent password")
   118  	wc.AssertNoChange()
   119  
   120  	err = s.subordinate.SetPassword("foo-12345678901234567890")
   121  	c.Assert(err, gc.IsNil)
   122  	wc.AssertNoChange()
   123  
   124  	// Make the subordinate dead and check it's detected.
   125  	err = s.subordinate.EnsureDead()
   126  	c.Assert(err, gc.IsNil)
   127  	wc.AssertChange("logging/0")
   128  	wc.AssertNoChange()
   129  
   130  	statetesting.AssertStop(c, w)
   131  	wc.AssertClosed()
   132  }
   133  
   134  func (s *deployerSuite) TestUnit(c *gc.C) {
   135  	// Try getting a missing unit and an invalid tag.
   136  	unit, err := s.st.Unit("unit-foo-42")
   137  	s.assertUnauthorized(c, err)
   138  	c.Assert(unit, gc.IsNil)
   139  	unit, err = s.st.Unit("42")
   140  	s.assertUnauthorized(c, err)
   141  	c.Assert(unit, gc.IsNil)
   142  
   143  	// Try getting a unit we're not responsible for.
   144  	// First create a new machine and deploy another unit there.
   145  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
   146  	c.Assert(err, gc.IsNil)
   147  	principal1, err := s.service0.AddUnit()
   148  	c.Assert(err, gc.IsNil)
   149  	err = principal1.AssignToMachine(machine)
   150  	c.Assert(err, gc.IsNil)
   151  	unit, err = s.st.Unit(principal1.Tag())
   152  	s.assertUnauthorized(c, err)
   153  	c.Assert(unit, gc.IsNil)
   154  
   155  	// Get the principal and subordinate we're responsible for.
   156  	unit, err = s.st.Unit(s.principal.Tag())
   157  	c.Assert(err, gc.IsNil)
   158  	c.Assert(unit.Name(), gc.Equals, "mysql/0")
   159  	unit, err = s.st.Unit(s.subordinate.Tag())
   160  	c.Assert(err, gc.IsNil)
   161  	c.Assert(unit.Name(), gc.Equals, "logging/0")
   162  }
   163  
   164  func (s *deployerSuite) TestUnitLifeRefresh(c *gc.C) {
   165  	unit, err := s.st.Unit(s.subordinate.Tag())
   166  	c.Assert(err, gc.IsNil)
   167  
   168  	c.Assert(unit.Life(), gc.Equals, params.Alive)
   169  
   170  	// Now make it dead and check again, then refresh and check.
   171  	err = s.subordinate.EnsureDead()
   172  	c.Assert(err, gc.IsNil)
   173  	err = s.subordinate.Refresh()
   174  	c.Assert(err, gc.IsNil)
   175  	c.Assert(s.subordinate.Life(), gc.Equals, state.Dead)
   176  	c.Assert(unit.Life(), gc.Equals, params.Alive)
   177  	err = unit.Refresh()
   178  	c.Assert(err, gc.IsNil)
   179  	c.Assert(unit.Life(), gc.Equals, params.Dead)
   180  }
   181  
   182  func (s *deployerSuite) TestUnitRemove(c *gc.C) {
   183  	unit, err := s.st.Unit(s.principal.Tag())
   184  	c.Assert(err, gc.IsNil)
   185  
   186  	// It fails because the entity is still alive.
   187  	// And EnsureDead will fail because there is a subordinate.
   188  	err = unit.Remove()
   189  	c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-mysql-0": still alive`)
   190  	c.Assert(params.ErrCode(err), gc.Equals, "")
   191  
   192  	// With the subordinate it also fails due to it being alive.
   193  	unit, err = s.st.Unit(s.subordinate.Tag())
   194  	c.Assert(err, gc.IsNil)
   195  	err = unit.Remove()
   196  	c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-logging-0": still alive`)
   197  	c.Assert(params.ErrCode(err), gc.Equals, "")
   198  
   199  	// Make it dead first and try again.
   200  	err = s.subordinate.EnsureDead()
   201  	c.Assert(err, gc.IsNil)
   202  	err = unit.Remove()
   203  	c.Assert(err, gc.IsNil)
   204  
   205  	// Verify it's gone.
   206  	err = unit.Refresh()
   207  	s.assertUnauthorized(c, err)
   208  	unit, err = s.st.Unit(s.subordinate.Tag())
   209  	s.assertUnauthorized(c, err)
   210  	c.Assert(unit, gc.IsNil)
   211  }
   212  
   213  func (s *deployerSuite) TestUnitSetPassword(c *gc.C) {
   214  	unit, err := s.st.Unit(s.principal.Tag())
   215  	c.Assert(err, gc.IsNil)
   216  
   217  	// Change the principal's password and verify.
   218  	err = unit.SetPassword("foobar-12345678901234567890")
   219  	c.Assert(err, gc.IsNil)
   220  	err = s.principal.Refresh()
   221  	c.Assert(err, gc.IsNil)
   222  	c.Assert(s.principal.PasswordValid("foobar-12345678901234567890"), gc.Equals, true)
   223  
   224  	// Then the subordinate.
   225  	unit, err = s.st.Unit(s.subordinate.Tag())
   226  	c.Assert(err, gc.IsNil)
   227  	err = unit.SetPassword("phony-12345678901234567890")
   228  	c.Assert(err, gc.IsNil)
   229  	err = s.subordinate.Refresh()
   230  	c.Assert(err, gc.IsNil)
   231  	c.Assert(s.subordinate.PasswordValid("phony-12345678901234567890"), gc.Equals, true)
   232  }
   233  
   234  func (s *deployerSuite) TestStateAddresses(c *gc.C) {
   235  	addrs := []instance.Address{
   236  		instance.NewAddress("0.1.2.3"),
   237  	}
   238  	err := s.machine.SetAddresses(addrs)
   239  	c.Assert(err, gc.IsNil)
   240  
   241  	stateAddresses, err := s.State.Addresses()
   242  	c.Assert(err, gc.IsNil)
   243  	c.Assert(len(stateAddresses), gc.Equals, 1)
   244  
   245  	addresses, err := s.st.StateAddresses()
   246  	c.Assert(err, gc.IsNil)
   247  	c.Assert(addresses, gc.DeepEquals, stateAddresses)
   248  }
   249  
   250  func (s *deployerSuite) TestAPIAddresses(c *gc.C) {
   251  	addrs := []instance.Address{
   252  		instance.NewAddress("0.1.2.3"),
   253  	}
   254  	err := s.machine.SetAddresses(addrs)
   255  	c.Assert(err, gc.IsNil)
   256  
   257  	stateAddresses, err := s.State.APIAddresses()
   258  	c.Assert(err, gc.IsNil)
   259  	c.Assert(len(stateAddresses), gc.Equals, 1)
   260  
   261  	addresses, err := s.st.APIAddresses()
   262  	c.Assert(err, gc.IsNil)
   263  	c.Assert(addresses, gc.DeepEquals, stateAddresses)
   264  }
   265  
   266  func (s *deployerSuite) TestCACert(c *gc.C) {
   267  	caCert, err := s.st.CACert()
   268  	c.Assert(err, gc.IsNil)
   269  	c.Assert(caCert, gc.DeepEquals, s.State.CACert())
   270  }