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