github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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  	coretesting "github.com/juju/juju/testing"
    21  	"github.com/juju/juju/watcher/watchertest"
    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.JobManageModel, 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 = deployer.NewState(s.stateAPI)
    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  	wc := watchertest.NewStringsWatcherC(c, w, s.BackingState.StartSync)
   108  	defer wc.AssertStops()
   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  
   131  func (s *deployerSuite) TestUnit(c *gc.C) {
   132  	// Try getting a missing unit and an invalid tag.
   133  	unit, err := s.st.Unit(names.NewUnitTag("foo/42"))
   134  	s.assertUnauthorized(c, err)
   135  	c.Assert(unit, gc.IsNil)
   136  
   137  	// Try getting a unit we're not responsible for.
   138  	// First create a new machine and deploy another unit there.
   139  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
   140  	c.Assert(err, jc.ErrorIsNil)
   141  	principal1, err := s.service0.AddUnit()
   142  	c.Assert(err, jc.ErrorIsNil)
   143  	err = principal1.AssignToMachine(machine)
   144  	c.Assert(err, jc.ErrorIsNil)
   145  	unit, err = s.st.Unit(principal1.Tag().(names.UnitTag))
   146  	s.assertUnauthorized(c, err)
   147  	c.Assert(unit, gc.IsNil)
   148  
   149  	// Get the principal and subordinate we're responsible for.
   150  	unit, err = s.st.Unit(s.principal.Tag().(names.UnitTag))
   151  	c.Assert(err, jc.ErrorIsNil)
   152  	c.Assert(unit.Name(), gc.Equals, "mysql/0")
   153  	unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	c.Assert(unit.Name(), gc.Equals, "logging/0")
   156  }
   157  
   158  func (s *deployerSuite) TestUnitLifeRefresh(c *gc.C) {
   159  	unit, err := s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   160  	c.Assert(err, jc.ErrorIsNil)
   161  
   162  	c.Assert(unit.Life(), gc.Equals, params.Alive)
   163  
   164  	// Now make it dead and check again, then refresh and check.
   165  	err = s.subordinate.EnsureDead()
   166  	c.Assert(err, jc.ErrorIsNil)
   167  	err = s.subordinate.Refresh()
   168  	c.Assert(err, jc.ErrorIsNil)
   169  	c.Assert(s.subordinate.Life(), gc.Equals, state.Dead)
   170  	c.Assert(unit.Life(), gc.Equals, params.Alive)
   171  	err = unit.Refresh()
   172  	c.Assert(err, jc.ErrorIsNil)
   173  	c.Assert(unit.Life(), gc.Equals, params.Dead)
   174  }
   175  
   176  func (s *deployerSuite) TestUnitRemove(c *gc.C) {
   177  	unit, err := s.st.Unit(s.principal.Tag().(names.UnitTag))
   178  	c.Assert(err, jc.ErrorIsNil)
   179  
   180  	// It fails because the entity is still alive.
   181  	// And EnsureDead will fail because there is a subordinate.
   182  	err = unit.Remove()
   183  	c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-mysql-0": still alive`)
   184  	c.Assert(params.ErrCode(err), gc.Equals, "")
   185  
   186  	// With the subordinate it also fails due to it being alive.
   187  	unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   188  	c.Assert(err, jc.ErrorIsNil)
   189  	err = unit.Remove()
   190  	c.Assert(err, gc.ErrorMatches, `cannot remove entity "unit-logging-0": still alive`)
   191  	c.Assert(params.ErrCode(err), gc.Equals, "")
   192  
   193  	// Make it dead first and try again.
   194  	err = s.subordinate.EnsureDead()
   195  	c.Assert(err, jc.ErrorIsNil)
   196  	err = unit.Remove()
   197  	c.Assert(err, jc.ErrorIsNil)
   198  
   199  	// Verify it's gone.
   200  	err = unit.Refresh()
   201  	s.assertUnauthorized(c, err)
   202  	unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   203  	s.assertUnauthorized(c, err)
   204  	c.Assert(unit, gc.IsNil)
   205  }
   206  
   207  func (s *deployerSuite) TestUnitSetPassword(c *gc.C) {
   208  	unit, err := s.st.Unit(s.principal.Tag().(names.UnitTag))
   209  	c.Assert(err, jc.ErrorIsNil)
   210  
   211  	// Change the principal's password and verify.
   212  	err = unit.SetPassword("foobar-12345678901234567890")
   213  	c.Assert(err, jc.ErrorIsNil)
   214  	err = s.principal.Refresh()
   215  	c.Assert(err, jc.ErrorIsNil)
   216  	c.Assert(s.principal.PasswordValid("foobar-12345678901234567890"), jc.IsTrue)
   217  
   218  	// Then the subordinate.
   219  	unit, err = s.st.Unit(s.subordinate.Tag().(names.UnitTag))
   220  	c.Assert(err, jc.ErrorIsNil)
   221  	err = unit.SetPassword("phony-12345678901234567890")
   222  	c.Assert(err, jc.ErrorIsNil)
   223  	err = s.subordinate.Refresh()
   224  	c.Assert(err, jc.ErrorIsNil)
   225  	c.Assert(s.subordinate.PasswordValid("phony-12345678901234567890"), jc.IsTrue)
   226  }
   227  
   228  func (s *deployerSuite) TestStateAddresses(c *gc.C) {
   229  	err := s.machine.SetProviderAddresses(network.NewAddress("0.1.2.3"))
   230  	c.Assert(err, jc.ErrorIsNil)
   231  
   232  	stateAddresses, err := s.State.Addresses()
   233  	c.Assert(err, jc.ErrorIsNil)
   234  	c.Assert(len(stateAddresses), gc.Equals, 1)
   235  
   236  	addresses, err := s.st.StateAddresses()
   237  	c.Assert(err, jc.ErrorIsNil)
   238  	c.Assert(addresses, gc.DeepEquals, stateAddresses)
   239  }