github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/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  	"github.com/juju/errors"
     8  	"github.com/juju/names"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/apiserver/common"
    13  	"github.com/juju/juju/apiserver/params"
    14  	apiservertesting "github.com/juju/juju/apiserver/testing"
    15  	"github.com/juju/juju/apiserver/upgrader"
    16  	jujutesting "github.com/juju/juju/juju/testing"
    17  	"github.com/juju/juju/state"
    18  	statetesting "github.com/juju/juju/state/testing"
    19  	"github.com/juju/juju/tools"
    20  	"github.com/juju/juju/version"
    21  )
    22  
    23  type unitUpgraderSuite struct {
    24  	jujutesting.JujuConnSuite
    25  
    26  	// These are raw State objects. Use them for setup and assertions, but
    27  	// should never be touched by the API calls themselves
    28  	rawMachine *state.Machine
    29  	rawUnit    *state.Unit
    30  	upgrader   *upgrader.UnitUpgraderAPI
    31  	resources  *common.Resources
    32  	authorizer apiservertesting.FakeAuthorizer
    33  
    34  	// Tools for the assigned machine.
    35  	fakeTools *tools.Tools
    36  }
    37  
    38  var _ = gc.Suite(&unitUpgraderSuite{})
    39  
    40  func (s *unitUpgraderSuite) SetUpTest(c *gc.C) {
    41  	s.JujuConnSuite.SetUpTest(c)
    42  	s.resources = common.NewResources()
    43  	s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() })
    44  
    45  	// Create a machine and unit to work with
    46  	var err error
    47  	_, err = s.State.AddMachine("quantal", state.JobHostUnits)
    48  	c.Assert(err, jc.ErrorIsNil)
    49  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
    50  	s.rawUnit, err = svc.AddUnit()
    51  	c.Assert(err, jc.ErrorIsNil)
    52  	// Assign the unit to the machine.
    53  	s.rawMachine, err = s.rawUnit.AssignToCleanMachine()
    54  	c.Assert(err, jc.ErrorIsNil)
    55  
    56  	// The default auth is as the unit agent
    57  	s.authorizer = apiservertesting.FakeAuthorizer{
    58  		Tag: s.rawUnit.Tag(),
    59  	}
    60  	s.upgrader, err = upgrader.NewUnitUpgraderAPI(s.State, s.resources, s.authorizer)
    61  	c.Assert(err, jc.ErrorIsNil)
    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, jc.ErrorIsNil)
    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().String()}},
    81  	}
    82  	results, err := s.upgrader.WatchAPIVersion(args)
    83  	c.Assert(err, jc.ErrorIsNil)
    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, jc.ErrorIsNil)
    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.Tag = names.NewMachineTag("7")
   104  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer)
   105  	c.Check(err, gc.NotNil)
   106  	c.Check(anUpgrader, gc.IsNil)
   107  	c.Assert(err, gc.ErrorMatches, "permission denied")
   108  }
   109  
   110  func (s *unitUpgraderSuite) TestWatchAPIVersionRefusesWrongAgent(c *gc.C) {
   111  	// We are a unit agent, but not the one we are trying to track
   112  	anAuthorizer := s.authorizer
   113  	anAuthorizer.Tag = names.NewUnitTag("wordpress/12354")
   114  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer)
   115  	c.Check(err, jc.ErrorIsNil)
   116  	args := params.Entities{
   117  		Entities: []params.Entity{{Tag: s.rawUnit.Tag().String()}},
   118  	}
   119  	results, err := anUpgrader.WatchAPIVersion(args)
   120  	// It is not an error to make the request, but the specific item is rejected
   121  	c.Assert(err, jc.ErrorIsNil)
   122  	c.Check(results.Results, gc.HasLen, 1)
   123  	c.Check(results.Results[0].NotifyWatcherId, gc.Equals, "")
   124  	c.Assert(results.Results[0].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   125  }
   126  
   127  func (s *unitUpgraderSuite) TestToolsNothing(c *gc.C) {
   128  	// Not an error to watch nothing
   129  	results, err := s.upgrader.Tools(params.Entities{})
   130  	c.Assert(err, jc.ErrorIsNil)
   131  	c.Check(results.Results, gc.HasLen, 0)
   132  }
   133  
   134  func (s *unitUpgraderSuite) TestToolsRefusesWrongAgent(c *gc.C) {
   135  	anAuthorizer := s.authorizer
   136  	anAuthorizer.Tag = names.NewUnitTag("wordpress/12354")
   137  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer)
   138  	c.Check(err, jc.ErrorIsNil)
   139  	args := params.Entities{
   140  		Entities: []params.Entity{{Tag: s.rawUnit.Tag().String()}},
   141  	}
   142  	results, err := anUpgrader.Tools(args)
   143  	// It is not an error to make the request, but the specific item is rejected
   144  	c.Assert(err, jc.ErrorIsNil)
   145  	c.Assert(results.Results, gc.HasLen, 1)
   146  	toolResult := results.Results[0]
   147  	c.Assert(toolResult.Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   148  }
   149  
   150  func (s *unitUpgraderSuite) TestToolsForAgent(c *gc.C) {
   151  	agent := params.Entity{Tag: s.rawUnit.Tag().String()}
   152  
   153  	// The machine must have its existing tools set before we query for the
   154  	// next tools. This is so that we can grab Arch and Series without
   155  	// having to pass it in again
   156  	err := s.rawMachine.SetAgentVersion(version.Current)
   157  	c.Assert(err, jc.ErrorIsNil)
   158  
   159  	args := params.Entities{Entities: []params.Entity{agent}}
   160  	results, err := s.upgrader.Tools(args)
   161  	c.Assert(err, jc.ErrorIsNil)
   162  	assertTools := func() {
   163  		c.Check(results.Results, gc.HasLen, 1)
   164  		c.Assert(results.Results[0].Error, gc.IsNil)
   165  		agentTools := results.Results[0].Tools
   166  		c.Check(agentTools.Version.Number, gc.DeepEquals, version.Current.Number)
   167  		c.Assert(agentTools.URL, gc.NotNil)
   168  	}
   169  	assertTools()
   170  }
   171  
   172  func (s *unitUpgraderSuite) TestSetToolsNothing(c *gc.C) {
   173  	// Not an error to watch nothing
   174  	results, err := s.upgrader.SetTools(params.EntitiesVersion{})
   175  	c.Assert(err, jc.ErrorIsNil)
   176  	c.Check(results.Results, gc.HasLen, 0)
   177  }
   178  
   179  func (s *unitUpgraderSuite) TestSetToolsRefusesWrongAgent(c *gc.C) {
   180  	anAuthorizer := s.authorizer
   181  	anAuthorizer.Tag = names.NewUnitTag("wordpress/12354")
   182  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer)
   183  	c.Check(err, jc.ErrorIsNil)
   184  	args := params.EntitiesVersion{
   185  		AgentTools: []params.EntityVersion{{
   186  			Tag: s.rawUnit.Tag().String(),
   187  			Tools: &params.Version{
   188  				Version: version.Current,
   189  			},
   190  		}},
   191  	}
   192  
   193  	results, err := anUpgrader.SetTools(args)
   194  	c.Assert(results.Results, gc.HasLen, 1)
   195  	c.Assert(results.Results[0].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   196  }
   197  
   198  func (s *unitUpgraderSuite) TestSetTools(c *gc.C) {
   199  	cur := version.Current
   200  	_, err := s.rawUnit.AgentTools()
   201  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   202  	args := params.EntitiesVersion{
   203  		AgentTools: []params.EntityVersion{{
   204  			Tag: s.rawUnit.Tag().String(),
   205  			Tools: &params.Version{
   206  				Version: cur,
   207  			}},
   208  		},
   209  	}
   210  	results, err := s.upgrader.SetTools(args)
   211  	c.Assert(err, jc.ErrorIsNil)
   212  	c.Assert(results.Results, gc.HasLen, 1)
   213  	c.Assert(results.Results[0].Error, gc.IsNil)
   214  	// Check that the new value actually got set, we must Refresh because
   215  	// it was set on a different Machine object
   216  	err = s.rawUnit.Refresh()
   217  	c.Assert(err, jc.ErrorIsNil)
   218  	realTools, err := s.rawUnit.AgentTools()
   219  	c.Assert(err, jc.ErrorIsNil)
   220  	c.Check(realTools.Version.Arch, gc.Equals, cur.Arch)
   221  	c.Check(realTools.Version.Series, gc.Equals, cur.Series)
   222  	c.Check(realTools.Version.Major, gc.Equals, cur.Major)
   223  	c.Check(realTools.Version.Minor, gc.Equals, cur.Minor)
   224  	c.Check(realTools.Version.Patch, gc.Equals, cur.Patch)
   225  	c.Check(realTools.Version.Build, gc.Equals, cur.Build)
   226  	c.Check(realTools.URL, gc.Equals, "")
   227  }
   228  
   229  func (s *unitUpgraderSuite) TestDesiredVersionNothing(c *gc.C) {
   230  	// Not an error to watch nothing
   231  	results, err := s.upgrader.DesiredVersion(params.Entities{})
   232  	c.Assert(err, jc.ErrorIsNil)
   233  	c.Check(results.Results, gc.HasLen, 0)
   234  }
   235  
   236  func (s *unitUpgraderSuite) TestDesiredVersionRefusesWrongAgent(c *gc.C) {
   237  	anAuthorizer := s.authorizer
   238  	anAuthorizer.Tag = names.NewUnitTag("wordpress/12354")
   239  	anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer)
   240  	c.Check(err, jc.ErrorIsNil)
   241  	args := params.Entities{
   242  		Entities: []params.Entity{{Tag: s.rawUnit.Tag().String()}},
   243  	}
   244  	results, err := anUpgrader.DesiredVersion(args)
   245  	// It is not an error to make the request, but the specific item is rejected
   246  	c.Assert(err, jc.ErrorIsNil)
   247  	c.Check(results.Results, gc.HasLen, 1)
   248  	toolResult := results.Results[0]
   249  	c.Assert(toolResult.Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   250  }
   251  
   252  func (s *unitUpgraderSuite) TestDesiredVersionNoticesMixedAgents(c *gc.C) {
   253  	err := s.rawMachine.SetAgentVersion(version.Current)
   254  	c.Assert(err, jc.ErrorIsNil)
   255  	args := params.Entities{Entities: []params.Entity{
   256  		{Tag: s.rawUnit.Tag().String()},
   257  		{Tag: "unit-wordpress-12345"},
   258  	}}
   259  	results, err := s.upgrader.DesiredVersion(args)
   260  	c.Assert(err, jc.ErrorIsNil)
   261  	c.Check(results.Results, gc.HasLen, 2)
   262  	c.Assert(results.Results[0].Error, gc.IsNil)
   263  	agentVersion := results.Results[0].Version
   264  	c.Assert(agentVersion, gc.NotNil)
   265  	c.Check(*agentVersion, gc.DeepEquals, version.Current.Number)
   266  
   267  	c.Assert(results.Results[1].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized)
   268  	c.Assert(results.Results[1].Version, gc.IsNil)
   269  
   270  }
   271  
   272  func (s *unitUpgraderSuite) TestDesiredVersionForAgent(c *gc.C) {
   273  	err := s.rawMachine.SetAgentVersion(version.Current)
   274  	c.Assert(err, jc.ErrorIsNil)
   275  	args := params.Entities{Entities: []params.Entity{{Tag: s.rawUnit.Tag().String()}}}
   276  	results, err := s.upgrader.DesiredVersion(args)
   277  	c.Assert(err, jc.ErrorIsNil)
   278  	c.Check(results.Results, gc.HasLen, 1)
   279  	c.Assert(results.Results[0].Error, gc.IsNil)
   280  	agentVersion := results.Results[0].Version
   281  	c.Assert(agentVersion, gc.NotNil)
   282  	c.Check(*agentVersion, gc.DeepEquals, version.Current.Number)
   283  }