github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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  	"github.com/juju/names"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/api"
    14  	"github.com/juju/juju/api/deployer"
    15  	apitesting "github.com/juju/juju/api/testing"
    16  	"github.com/juju/juju/apiserver/params"
    17  	"github.com/juju/juju/juju/testing"
    18  	"github.com/juju/juju/network"
    19  	"github.com/juju/juju/state"
    20  	statetesting "github.com/juju/juju/state/testing"
    21  	coretesting "github.com/juju/juju/testing"
    22  )
    23  
    24  func TestAll(t *stdtesting.T) {
    25  	coretesting.MgoTestPackage(t)
    26  }
    27  
    28  type deployerSuite struct {
    29  	testing.JujuConnSuite
    30  	*apitesting.APIAddresserTests
    31  
    32  	stateAPI api.Connection
    33  
    34  	// These are raw State objects. Use them for setup and assertions, but
    35  	// should never be touched by the API calls themselves
    36  	machine     *state.Machine
    37  	service0    *state.Service
    38  	service1    *state.Service
    39  	principal   *state.Unit
    40  	subordinate *state.Unit
    41  
    42  	st *deployer.State
    43  }
    44  
    45  var _ = gc.Suite(&deployerSuite{})
    46  
    47  func (s *deployerSuite) SetUpTest(c *gc.C) {
    48  	s.JujuConnSuite.SetUpTest(c)
    49  	s.stateAPI, s.machine = s.OpenAPIAsNewMachine(c, state.JobManageEnviron, state.JobHostUnits)
    50  	err := s.machine.SetProviderAddresses(network.NewAddress("0.1.2.3"))
    51  	c.Assert(err, jc.ErrorIsNil)
    52  
    53  	// Create the needed services and relate them.
    54  	s.service0 = s.AddTestingService(c, "mysql", s.AddTestingCharm(c, "mysql"))
    55  	s.service1 = s.AddTestingService(c, "logging", s.AddTestingCharm(c, "logging"))
    56  	eps, err := s.State.InferEndpoints("mysql", "logging")
    57  	c.Assert(err, jc.ErrorIsNil)
    58  	rel, err := s.State.AddRelation(eps...)
    59  	c.Assert(err, jc.ErrorIsNil)
    60  
    61  	// Create principal and subordinate units and assign them.
    62  	s.principal, err = s.service0.AddUnit()
    63  	c.Assert(err, jc.ErrorIsNil)
    64  	err = s.principal.AssignToMachine(s.machine)
    65  	c.Assert(err, jc.ErrorIsNil)
    66  	relUnit, err := rel.Unit(s.principal)
    67  	c.Assert(err, jc.ErrorIsNil)
    68  	err = relUnit.EnterScope(nil)
    69  	c.Assert(err, jc.ErrorIsNil)
    70  	s.subordinate, err = s.State.Unit("logging/0")
    71  	c.Assert(err, jc.ErrorIsNil)
    72  
    73  	// Create the deployer facade.
    74  	s.st = s.stateAPI.Deployer()
    75  	c.Assert(s.st, gc.NotNil)
    76  
    77  	s.APIAddresserTests = apitesting.NewAPIAddresserTests(s.st, s.BackingState)
    78  }
    79  
    80  // Note: This is really meant as a unit-test, this isn't a test that
    81  // should need all of the setup we have for this test suite
    82  func (s *deployerSuite) TestNew(c *gc.C) {
    83  	deployer := deployer.NewState(s.stateAPI)
    84  	c.Assert(deployer, gc.NotNil)
    85  }
    86  
    87  func (s *deployerSuite) assertUnauthorized(c *gc.C, err error) {
    88  	c.Assert(err, gc.ErrorMatches, "permission denied")
    89  	c.Assert(err, jc.Satisfies, params.IsCodeUnauthorized)
    90  }
    91  
    92  func (s *deployerSuite) TestWatchUnitsWrongMachine(c *gc.C) {
    93  	// Try with a non-existent machine tag.
    94  	machine, err := s.st.Machine(names.NewMachineTag("42"))
    95  	c.Assert(err, jc.ErrorIsNil)
    96  	w, err := machine.WatchUnits()
    97  	s.assertUnauthorized(c, err)
    98  	c.Assert(w, gc.IsNil)
    99  }
   100  
   101  func (s *deployerSuite) TestWatchUnits(c *gc.C) {
   102  	// TODO(dfc) fix state.Machine to return a MachineTag
   103  	machine, err := s.st.Machine(s.machine.Tag().(names.MachineTag))
   104  	c.Assert(err, jc.ErrorIsNil)
   105  	w, err := machine.WatchUnits()
   106  	c.Assert(err, jc.ErrorIsNil)
   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, jc.ErrorIsNil)
   122  	wc.AssertNoChange()
   123  
   124  	// Make the subordinate dead and check it's detected.
   125  	err = s.subordinate.EnsureDead()
   126  	c.Assert(err, jc.ErrorIsNil)
   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(names.NewUnitTag("foo/42"))
   137  	s.assertUnauthorized(c, err)
   138  	c.Assert(unit, gc.IsNil)
   139  
   140  	// Try getting a unit we're not responsible for.
   141  	// First create a new machine and deploy another unit there.
   142  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
   143  	c.Assert(err, jc.ErrorIsNil)
   144  	principal1, err := s.service0.AddUnit()
   145  	c.Assert(err, jc.ErrorIsNil)
   146  	err = principal1.AssignToMachine(machine)
   147  	c.Assert(err, jc.ErrorIsNil)
   148  	unit, err = s.st.Unit(principal1.Tag().(names.UnitTag))
   149  	s.assertUnauthorized(c, err)
   150  	c.Assert(unit, gc.IsNil)
   151  
   152  	// Get the principal and subordinate we're responsible for.
   153  	unit, err = s.st.Unit(s.principal.Tag().(names.UnitTag))
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	c.Assert(unit.Name(), gc.Equals, "mysql/0")
   156  	unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   157  	c.Assert(err, jc.ErrorIsNil)
   158  	c.Assert(unit.Name(), gc.Equals, "logging/0")
   159  }
   160  
   161  func (s *deployerSuite) TestUnitLifeRefresh(c *gc.C) {
   162  	unit, err := s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   163  	c.Assert(err, jc.ErrorIsNil)
   164  
   165  	c.Assert(unit.Life(), gc.Equals, params.Alive)
   166  
   167  	// Now make it dead and check again, then refresh and check.
   168  	err = s.subordinate.EnsureDead()
   169  	c.Assert(err, jc.ErrorIsNil)
   170  	err = s.subordinate.Refresh()
   171  	c.Assert(err, jc.ErrorIsNil)
   172  	c.Assert(s.subordinate.Life(), gc.Equals, state.Dead)
   173  	c.Assert(unit.Life(), gc.Equals, params.Alive)
   174  	err = unit.Refresh()
   175  	c.Assert(err, jc.ErrorIsNil)
   176  	c.Assert(unit.Life(), gc.Equals, params.Dead)
   177  }
   178  
   179  func (s *deployerSuite) TestUnitRemove(c *gc.C) {
   180  	unit, err := s.st.Unit(s.principal.Tag().(names.UnitTag))
   181  	c.Assert(err, jc.ErrorIsNil)
   182  
   183  	// It fails because the entity is still alive.
   184  	// And EnsureDead will fail because there is a subordinate.
   185  	err = unit.Remove()
   186  	c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-mysql-0": still alive`)
   187  	c.Assert(params.ErrCode(err), gc.Equals, "")
   188  
   189  	// With the subordinate it also fails due to it being alive.
   190  	unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   191  	c.Assert(err, jc.ErrorIsNil)
   192  	err = unit.Remove()
   193  	c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-logging-0": still alive`)
   194  	c.Assert(params.ErrCode(err), gc.Equals, "")
   195  
   196  	// Make it dead first and try again.
   197  	err = s.subordinate.EnsureDead()
   198  	c.Assert(err, jc.ErrorIsNil)
   199  	err = unit.Remove()
   200  	c.Assert(err, jc.ErrorIsNil)
   201  
   202  	// Verify it's gone.
   203  	err = unit.Refresh()
   204  	s.assertUnauthorized(c, err)
   205  	unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   206  	s.assertUnauthorized(c, err)
   207  	c.Assert(unit, gc.IsNil)
   208  }
   209  
   210  func (s *deployerSuite) TestUnitSetPassword(c *gc.C) {
   211  	unit, err := s.st.Unit(s.principal.Tag().(names.UnitTag))
   212  	c.Assert(err, jc.ErrorIsNil)
   213  
   214  	// Change the principal's password and verify.
   215  	err = unit.SetPassword("foobar-12345678901234567890")
   216  	c.Assert(err, jc.ErrorIsNil)
   217  	err = s.principal.Refresh()
   218  	c.Assert(err, jc.ErrorIsNil)
   219  	c.Assert(s.principal.PasswordValid("foobar-12345678901234567890"), jc.IsTrue)
   220  
   221  	// Then the subordinate.
   222  	unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   223  	c.Assert(err, jc.ErrorIsNil)
   224  	err = unit.SetPassword("phony-12345678901234567890")
   225  	c.Assert(err, jc.ErrorIsNil)
   226  	err = s.subordinate.Refresh()
   227  	c.Assert(err, jc.ErrorIsNil)
   228  	c.Assert(s.subordinate.PasswordValid("phony-12345678901234567890"), jc.IsTrue)
   229  }
   230  
   231  func (s *deployerSuite) TestStateAddresses(c *gc.C) {
   232  	err := s.machine.SetProviderAddresses(network.NewAddress("0.1.2.3"))
   233  	c.Assert(err, jc.ErrorIsNil)
   234  
   235  	stateAddresses, err := s.State.Addresses()
   236  	c.Assert(err, jc.ErrorIsNil)
   237  	c.Assert(len(stateAddresses), gc.Equals, 1)
   238  
   239  	addresses, err := s.st.StateAddresses()
   240  	c.Assert(err, jc.ErrorIsNil)
   241  	c.Assert(addresses, gc.DeepEquals, stateAddresses)
   242  }