github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/state/apiserver/upgrader/unitupgrader_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package upgrader_test
     5  
     6  import (
     7  	gc "launchpad.net/gocheck"
     8  
     9  	"launchpad.net/juju-core/errors"
    10  	jujutesting "launchpad.net/juju-core/juju/testing"
    11  	"launchpad.net/juju-core/state"
    12  	"launchpad.net/juju-core/state/api/params"
    13  	"launchpad.net/juju-core/state/apiserver/common"
    14  	apiservertesting "launchpad.net/juju-core/state/apiserver/testing"
    15  	"launchpad.net/juju-core/state/apiserver/upgrader"
    16  	statetesting "launchpad.net/juju-core/state/testing"
    17  	jc "launchpad.net/juju-core/testing/checkers"
    18  	"launchpad.net/juju-core/tools"
    19  	"launchpad.net/juju-core/version"
    20  )
    21  
    22  type unitUpgraderSuite struct {
    23  	jujutesting.JujuConnSuite
    24  
    25  	// These are raw State objects. Use them for setup and assertions, but
    26  	// should never be touched by the API calls themselves
    27  	rawMachine *state.Machine
    28  	rawUnit    *state.Unit
    29  	upgrader   *upgrader.UnitUpgraderAPI
    30  	resources  *common.Resources
    31  	authorizer apiservertesting.FakeAuthorizer
    32  
    33  	// Tools for the assigned machine.
    34  	fakeTools *tools.Tools
    35  }
    36  
    37  var _ = gc.Suite(&unitUpgraderSuite{})
    38  
    39  func (s *unitUpgraderSuite) SetUpTest(c *gc.C) {
    40  	s.JujuConnSuite.SetUpTest(c)
    41  	s.resources = common.NewResources()
    42  
    43  	// Create a machine and unit to work with
    44  	var err error
    45  	_, err = s.State.AddMachine("quantal", state.JobHostUnits)
    46  	c.Assert(err, gc.IsNil)
    47  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
    48  	s.rawUnit, err = svc.AddUnit()
    49  	c.Assert(err, gc.IsNil)
    50  	// Assign the unit to the machine.
    51  	s.rawMachine, err = s.rawUnit.AssignToCleanMachine()
    52  	c.Assert(err, gc.IsNil)
    53  
    54  	// The default auth is as the unit agent
    55  	s.authorizer = apiservertesting.FakeAuthorizer{
    56  		Tag:       s.rawUnit.Tag(),
    57  		LoggedIn:  true,
    58  		UnitAgent: true,
    59  	}
    60  	s.upgrader, err = upgrader.NewUnitUpgraderAPI(s.State, s.resources, s.authorizer, s.DataDir())
    61  	c.Assert(err, gc.IsNil)
    62  }
    63  
    64  func (s *unitUpgraderSuite) TearDownTest(c *gc.C) {
    65  	if s.resources != nil {
    66  		s.resources.StopAll()
    67  	}
    68  	s.JujuConnSuite.TearDownTest(c)
    69  }
    70  
    71  func (s *unitUpgraderSuite) TestWatchAPIVersionNothing(c *gc.C) {
    72  	// Not an error to watch nothing
    73  	results, err := s.upgrader.WatchAPIVersion(params.Entities{})
    74  	c.Assert(err, gc.IsNil)
    75  	c.Check(results.Results, gc.HasLen, 0)
    76  }
    77  
    78  func (s *unitUpgraderSuite) TestWatchAPIVersion(c *gc.C) {
    79  	args := params.Entities{
    80  		Entities: []params.Entity{{Tag: s.rawUnit.Tag()}},
    81  	}
    82  	results, err := s.upgrader.WatchAPIVersion(args)
    83  	c.Assert(err, gc.IsNil)
    84  	c.Check(results.Results, gc.HasLen, 1)
    85  	c.Check(results.Results[0].NotifyWatcherId, gc.Not(gc.Equals), "")
    86  	c.Check(results.Results[0].Error, gc.IsNil)
    87  	resource := s.resources.Get(results.Results[0].NotifyWatcherId)
    88  	c.Check(resource, gc.NotNil)
    89  
    90  	w := resource.(state.NotifyWatcher)
    91  	wc := statetesting.NewNotifyWatcherC(c, s.State, w)
    92  	wc.AssertNoChange()
    93  
    94  	err = s.rawMachine.SetAgentVersion(version.MustParseBinary("3.4.567.8-quantal-amd64"))
    95  	c.Assert(err, gc.IsNil)
    96  	wc.AssertOneChange()
    97  	statetesting.AssertStop(c, w)
    98  	wc.AssertClosed()
    99  }
   100  
   101  func (s *unitUpgraderSuite) TestUpgraderAPIRefusesNonUnitAgent(c *gc.C) {
   102  	anAuthorizer := s.authorizer
   103  	anAuthorizer.MachineAgent = true
   104  	anAuthorizer.UnitAgent = false
   105  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer, "")
   106  	c.Check(err, gc.NotNil)
   107  	c.Check(anUpgrader, gc.IsNil)
   108  	c.Assert(err, gc.ErrorMatches, "permission denied")
   109  }
   110  
   111  func (s *unitUpgraderSuite) TestWatchAPIVersionRefusesWrongAgent(c *gc.C) {
   112  	// We are a unit agent, but not the one we are trying to track
   113  	anAuthorizer := s.authorizer
   114  	anAuthorizer.Tag = "unit-wordpress-12354"
   115  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer, "")
   116  	c.Check(err, gc.IsNil)
   117  	args := params.Entities{
   118  		Entities: []params.Entity{{Tag: s.rawUnit.Tag()}},
   119  	}
   120  	results, err := anUpgrader.WatchAPIVersion(args)
   121  	// It is not an error to make the request, but the specific item is rejected
   122  	c.Assert(err, gc.IsNil)
   123  	c.Check(results.Results, gc.HasLen, 1)
   124  	c.Check(results.Results[0].NotifyWatcherId, gc.Equals, "")
   125  	c.Assert(results.Results[0].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   126  }
   127  
   128  func (s *unitUpgraderSuite) TestToolsNothing(c *gc.C) {
   129  	// Not an error to watch nothing
   130  	results, err := s.upgrader.Tools(params.Entities{})
   131  	c.Assert(err, gc.IsNil)
   132  	c.Check(results.Results, gc.HasLen, 0)
   133  }
   134  
   135  func (s *unitUpgraderSuite) TestToolsRefusesWrongAgent(c *gc.C) {
   136  	anAuthorizer := s.authorizer
   137  	anAuthorizer.Tag = "unit-wordpress-12354"
   138  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer, "")
   139  	c.Check(err, gc.IsNil)
   140  	args := params.Entities{
   141  		Entities: []params.Entity{{Tag: s.rawUnit.Tag()}},
   142  	}
   143  	results, err := anUpgrader.Tools(args)
   144  	// It is not an error to make the request, but the specific item is rejected
   145  	c.Assert(err, gc.IsNil)
   146  	c.Check(results.Results, gc.HasLen, 1)
   147  	toolResult := results.Results[0]
   148  	c.Assert(toolResult.Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   149  }
   150  
   151  func (s *unitUpgraderSuite) TestToolsForAgent(c *gc.C) {
   152  	agent := params.Entity{Tag: s.rawUnit.Tag()}
   153  
   154  	// The machine must have its existing tools set before we query for the
   155  	// next tools. This is so that we can grab Arch and Series without
   156  	// having to pass it in again
   157  	err := s.rawMachine.SetAgentVersion(version.Current)
   158  	c.Assert(err, gc.IsNil)
   159  
   160  	args := params.Entities{Entities: []params.Entity{agent}}
   161  	results, err := s.upgrader.Tools(args)
   162  	c.Assert(err, gc.IsNil)
   163  	assertTools := func() {
   164  		c.Check(results.Results, gc.HasLen, 1)
   165  		c.Assert(results.Results[0].Error, gc.IsNil)
   166  		agentTools := results.Results[0].Tools
   167  		c.Check(agentTools.Version.Number, gc.DeepEquals, version.Current.Number)
   168  		c.Assert(agentTools.URL, gc.NotNil)
   169  	}
   170  	assertTools()
   171  }
   172  
   173  func (s *unitUpgraderSuite) TestSetToolsNothing(c *gc.C) {
   174  	// Not an error to watch nothing
   175  	results, err := s.upgrader.SetTools(params.EntitiesVersion{})
   176  	c.Assert(err, gc.IsNil)
   177  	c.Check(results.Results, gc.HasLen, 0)
   178  }
   179  
   180  func (s *unitUpgraderSuite) TestSetToolsRefusesWrongAgent(c *gc.C) {
   181  	anAuthorizer := s.authorizer
   182  	anAuthorizer.Tag = "unit-wordpress-12354"
   183  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer, "")
   184  	c.Check(err, gc.IsNil)
   185  	args := params.EntitiesVersion{
   186  		AgentTools: []params.EntityVersion{{
   187  			Tag: s.rawUnit.Tag(),
   188  			Tools: &params.Version{
   189  				Version: version.Current,
   190  			},
   191  		}},
   192  	}
   193  
   194  	results, err := anUpgrader.SetTools(args)
   195  	c.Assert(results.Results, gc.HasLen, 1)
   196  	c.Assert(results.Results[0].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   197  }
   198  
   199  func (s *unitUpgraderSuite) TestSetTools(c *gc.C) {
   200  	cur := version.Current
   201  	_, err := s.rawUnit.AgentTools()
   202  	c.Assert(err, jc.Satisfies, errors.IsNotFoundError)
   203  	args := params.EntitiesVersion{
   204  		AgentTools: []params.EntityVersion{{
   205  			Tag: s.rawUnit.Tag(),
   206  			Tools: &params.Version{
   207  				Version: cur,
   208  			}},
   209  		},
   210  	}
   211  	results, err := s.upgrader.SetTools(args)
   212  	c.Assert(err, gc.IsNil)
   213  	c.Assert(results.Results, gc.HasLen, 1)
   214  	c.Assert(results.Results[0].Error, gc.IsNil)
   215  	// Check that the new value actually got set, we must Refresh because
   216  	// it was set on a different Machine object
   217  	err = s.rawUnit.Refresh()
   218  	c.Assert(err, gc.IsNil)
   219  	realTools, err := s.rawUnit.AgentTools()
   220  	c.Assert(err, gc.IsNil)
   221  	c.Check(realTools.Version.Arch, gc.Equals, cur.Arch)
   222  	c.Check(realTools.Version.Series, gc.Equals, cur.Series)
   223  	c.Check(realTools.Version.Major, gc.Equals, cur.Major)
   224  	c.Check(realTools.Version.Minor, gc.Equals, cur.Minor)
   225  	c.Check(realTools.Version.Patch, gc.Equals, cur.Patch)
   226  	c.Check(realTools.Version.Build, gc.Equals, cur.Build)
   227  	c.Check(realTools.URL, gc.Equals, "")
   228  }
   229  
   230  func (s *unitUpgraderSuite) TestDesiredVersionNothing(c *gc.C) {
   231  	// Not an error to watch nothing
   232  	results, err := s.upgrader.DesiredVersion(params.Entities{})
   233  	c.Assert(err, gc.IsNil)
   234  	c.Check(results.Results, gc.HasLen, 0)
   235  }
   236  
   237  func (s *unitUpgraderSuite) TestDesiredVersionRefusesWrongAgent(c *gc.C) {
   238  	anAuthorizer := s.authorizer
   239  	anAuthorizer.Tag = "unit-wordpress-12354"
   240  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer, "")
   241  	c.Check(err, gc.IsNil)
   242  	args := params.Entities{
   243  		Entities: []params.Entity{{Tag: s.rawUnit.Tag()}},
   244  	}
   245  	results, err := anUpgrader.DesiredVersion(args)
   246  	// It is not an error to make the request, but the specific item is rejected
   247  	c.Assert(err, gc.IsNil)
   248  	c.Check(results.Results, gc.HasLen, 1)
   249  	toolResult := results.Results[0]
   250  	c.Assert(toolResult.Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   251  }
   252  
   253  func (s *unitUpgraderSuite) TestDesiredVersionNoticesMixedAgents(c *gc.C) {
   254  	err := s.rawMachine.SetAgentVersion(version.Current)
   255  	c.Assert(err, gc.IsNil)
   256  	args := params.Entities{Entities: []params.Entity{
   257  		{Tag: s.rawUnit.Tag()},
   258  		{Tag: "unit-wordpress-12345"},
   259  	}}
   260  	results, err := s.upgrader.DesiredVersion(args)
   261  	c.Assert(err, gc.IsNil)
   262  	c.Check(results.Results, gc.HasLen, 2)
   263  	c.Assert(results.Results[0].Error, gc.IsNil)
   264  	agentVersion := results.Results[0].Version
   265  	c.Assert(agentVersion, gc.NotNil)
   266  	c.Check(*agentVersion, gc.DeepEquals, version.Current.Number)
   267  
   268  	c.Assert(results.Results[1].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   269  	c.Assert(results.Results[1].Version, gc.IsNil)
   270  
   271  }
   272  
   273  func (s *unitUpgraderSuite) TestDesiredVersionForAgent(c *gc.C) {
   274  	err := s.rawMachine.SetAgentVersion(version.Current)
   275  	c.Assert(err, gc.IsNil)
   276  	args := params.Entities{Entities: []params.Entity{{Tag: s.rawUnit.Tag()}}}
   277  	results, err := s.upgrader.DesiredVersion(args)
   278  	c.Assert(err, gc.IsNil)
   279  	c.Check(results.Results, gc.HasLen, 1)
   280  	c.Assert(results.Results[0].Error, gc.IsNil)
   281  	agentVersion := results.Results[0].Version
   282  	c.Assert(agentVersion, gc.NotNil)
   283  	c.Check(*agentVersion, gc.DeepEquals, version.Current.Number)
   284  }