github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/agent/agent_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package agent_test
     5  
     6  import (
     7  	stdtesting "testing"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  	"gopkg.in/juju/names.v2"
    12  
    13  	"github.com/juju/juju/apiserver/agent"
    14  	"github.com/juju/juju/apiserver/common"
    15  	"github.com/juju/juju/apiserver/params"
    16  	apiservertesting "github.com/juju/juju/apiserver/testing"
    17  	"github.com/juju/juju/cloud"
    18  	"github.com/juju/juju/instance"
    19  	jujutesting "github.com/juju/juju/juju/testing"
    20  	"github.com/juju/juju/state"
    21  	"github.com/juju/juju/state/multiwatcher"
    22  	statetesting "github.com/juju/juju/state/testing"
    23  	coretesting "github.com/juju/juju/testing"
    24  )
    25  
    26  func TestPackage(t *stdtesting.T) {
    27  	coretesting.MgoTestPackage(t)
    28  }
    29  
    30  var _ = gc.Suite(&agentSuite{})
    31  
    32  type agentSuite struct {
    33  	jujutesting.JujuConnSuite
    34  
    35  	resources  *common.Resources
    36  	authorizer apiservertesting.FakeAuthorizer
    37  
    38  	machine0  *state.Machine
    39  	machine1  *state.Machine
    40  	container *state.Machine
    41  }
    42  
    43  func (s *agentSuite) SetUpTest(c *gc.C) {
    44  	s.JujuConnSuite.SetUpTest(c)
    45  
    46  	var err error
    47  	s.machine0, err = s.State.AddMachine("quantal", state.JobManageModel)
    48  	c.Assert(err, jc.ErrorIsNil)
    49  
    50  	s.machine1, err = s.State.AddMachine("quantal", state.JobHostUnits)
    51  	c.Assert(err, jc.ErrorIsNil)
    52  
    53  	template := state.MachineTemplate{
    54  		Series: "quantal",
    55  		Jobs:   []state.MachineJob{state.JobHostUnits},
    56  	}
    57  	s.container, err = s.State.AddMachineInsideMachine(template, s.machine1.Id(), instance.LXD)
    58  	c.Assert(err, jc.ErrorIsNil)
    59  
    60  	s.resources = common.NewResources()
    61  	s.AddCleanup(func(*gc.C) { s.resources.StopAll() })
    62  
    63  	// Create a FakeAuthorizer so we can check permissions,
    64  	// set up assuming machine 1 has logged in.
    65  	s.authorizer = apiservertesting.FakeAuthorizer{
    66  		Tag: s.machine1.Tag(),
    67  	}
    68  }
    69  
    70  func (s *agentSuite) TestAgentFailsWithNonAgent(c *gc.C) {
    71  	auth := s.authorizer
    72  	auth.Tag = names.NewUserTag("admin")
    73  	api, err := agent.NewAgentAPIV2(s.State, s.resources, auth)
    74  	c.Assert(err, gc.NotNil)
    75  	c.Assert(api, gc.IsNil)
    76  	c.Assert(err, gc.ErrorMatches, "permission denied")
    77  }
    78  
    79  func (s *agentSuite) TestAgentSucceedsWithUnitAgent(c *gc.C) {
    80  	auth := s.authorizer
    81  	auth.Tag = names.NewUnitTag("foosball/1")
    82  	_, err := agent.NewAgentAPIV2(s.State, s.resources, auth)
    83  	c.Assert(err, jc.ErrorIsNil)
    84  }
    85  
    86  func (s *agentSuite) TestGetEntities(c *gc.C) {
    87  	err := s.container.Destroy()
    88  	c.Assert(err, jc.ErrorIsNil)
    89  	args := params.Entities{
    90  		Entities: []params.Entity{
    91  			{Tag: "machine-1"},
    92  			{Tag: "machine-0"},
    93  			{Tag: "machine-1-lxd-0"},
    94  			{Tag: "machine-42"},
    95  		},
    96  	}
    97  	api, err := agent.NewAgentAPIV2(s.State, s.resources, s.authorizer)
    98  	c.Assert(err, jc.ErrorIsNil)
    99  	results := api.GetEntities(args)
   100  	c.Assert(results, gc.DeepEquals, params.AgentGetEntitiesResults{
   101  		Entities: []params.AgentGetEntitiesResult{
   102  			{
   103  				Life: "alive",
   104  				Jobs: []multiwatcher.MachineJob{multiwatcher.JobHostUnits},
   105  			},
   106  			{Error: apiservertesting.ErrUnauthorized},
   107  			{Error: apiservertesting.ErrUnauthorized},
   108  			{Error: apiservertesting.ErrUnauthorized},
   109  		},
   110  	})
   111  }
   112  
   113  func (s *agentSuite) TestGetEntitiesContainer(c *gc.C) {
   114  	auth := s.authorizer
   115  	auth.Tag = s.container.Tag()
   116  	err := s.container.Destroy()
   117  	c.Assert(err, jc.ErrorIsNil)
   118  
   119  	api, err := agent.NewAgentAPIV2(s.State, s.resources, auth)
   120  	c.Assert(err, jc.ErrorIsNil)
   121  	args := params.Entities{
   122  		Entities: []params.Entity{
   123  			{Tag: "machine-1"},
   124  			{Tag: "machine-0"},
   125  			{Tag: "machine-1-lxd-0"},
   126  			{Tag: "machine-42"},
   127  		},
   128  	}
   129  	results := api.GetEntities(args)
   130  	c.Assert(results, gc.DeepEquals, params.AgentGetEntitiesResults{
   131  		Entities: []params.AgentGetEntitiesResult{
   132  			{Error: apiservertesting.ErrUnauthorized},
   133  			{Error: apiservertesting.ErrUnauthorized},
   134  			{
   135  				Life:          "dying",
   136  				Jobs:          []multiwatcher.MachineJob{multiwatcher.JobHostUnits},
   137  				ContainerType: instance.LXD,
   138  			},
   139  			{Error: apiservertesting.ErrUnauthorized},
   140  		},
   141  	})
   142  }
   143  
   144  func (s *agentSuite) TestGetEntitiesNotFound(c *gc.C) {
   145  	// Destroy the container first, so we can destroy its parent.
   146  	err := s.container.Destroy()
   147  	c.Assert(err, jc.ErrorIsNil)
   148  	err = s.container.EnsureDead()
   149  	c.Assert(err, jc.ErrorIsNil)
   150  	err = s.container.Remove()
   151  	c.Assert(err, jc.ErrorIsNil)
   152  
   153  	err = s.machine1.Destroy()
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	err = s.machine1.EnsureDead()
   156  	c.Assert(err, jc.ErrorIsNil)
   157  	err = s.machine1.Remove()
   158  	c.Assert(err, jc.ErrorIsNil)
   159  
   160  	api, err := agent.NewAgentAPIV2(s.State, s.resources, s.authorizer)
   161  	c.Assert(err, jc.ErrorIsNil)
   162  	results := api.GetEntities(params.Entities{
   163  		Entities: []params.Entity{{Tag: "machine-1"}},
   164  	})
   165  	c.Assert(err, jc.ErrorIsNil)
   166  	c.Assert(results, gc.DeepEquals, params.AgentGetEntitiesResults{
   167  		Entities: []params.AgentGetEntitiesResult{{
   168  			Error: &params.Error{
   169  				Code:    params.CodeNotFound,
   170  				Message: "machine 1 not found",
   171  			},
   172  		}},
   173  	})
   174  }
   175  
   176  func (s *agentSuite) TestSetPasswords(c *gc.C) {
   177  	api, err := agent.NewAgentAPIV2(s.State, s.resources, s.authorizer)
   178  	c.Assert(err, jc.ErrorIsNil)
   179  	results, err := api.SetPasswords(params.EntityPasswords{
   180  		Changes: []params.EntityPassword{
   181  			{Tag: "machine-0", Password: "xxx-12345678901234567890"},
   182  			{Tag: "machine-1", Password: "yyy-12345678901234567890"},
   183  			{Tag: "machine-42", Password: "zzz-12345678901234567890"},
   184  		},
   185  	})
   186  	c.Assert(err, jc.ErrorIsNil)
   187  	c.Assert(results, gc.DeepEquals, params.ErrorResults{
   188  		Results: []params.ErrorResult{
   189  			{apiservertesting.ErrUnauthorized},
   190  			{nil},
   191  			{apiservertesting.ErrUnauthorized},
   192  		},
   193  	})
   194  	err = s.machine1.Refresh()
   195  	c.Assert(err, jc.ErrorIsNil)
   196  	changed := s.machine1.PasswordValid("yyy-12345678901234567890")
   197  	c.Assert(changed, jc.IsTrue)
   198  }
   199  
   200  func (s *agentSuite) TestSetPasswordsShort(c *gc.C) {
   201  	api, err := agent.NewAgentAPIV2(s.State, s.resources, s.authorizer)
   202  	c.Assert(err, jc.ErrorIsNil)
   203  	results, err := api.SetPasswords(params.EntityPasswords{
   204  		Changes: []params.EntityPassword{
   205  			{Tag: "machine-1", Password: "yyy"},
   206  		},
   207  	})
   208  	c.Assert(err, jc.ErrorIsNil)
   209  	c.Assert(results.Results, gc.HasLen, 1)
   210  	c.Assert(results.Results[0].Error, gc.ErrorMatches,
   211  		"password is only 3 bytes long, and is not a valid Agent password")
   212  }
   213  
   214  func (s *agentSuite) TestClearReboot(c *gc.C) {
   215  	api, err := agent.NewAgentAPIV2(s.State, s.resources, s.authorizer)
   216  	c.Assert(err, jc.ErrorIsNil)
   217  
   218  	err = s.machine1.SetRebootFlag(true)
   219  	c.Assert(err, jc.ErrorIsNil)
   220  
   221  	args := params.Entities{Entities: []params.Entity{
   222  		{Tag: s.machine0.Tag().String()},
   223  		{Tag: s.machine1.Tag().String()},
   224  	}}
   225  
   226  	rFlag, err := s.machine1.GetRebootFlag()
   227  	c.Assert(err, jc.ErrorIsNil)
   228  	c.Assert(rFlag, jc.IsTrue)
   229  
   230  	result, err := api.ClearReboot(args)
   231  	c.Assert(err, jc.ErrorIsNil)
   232  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   233  		Results: []params.ErrorResult{
   234  			{apiservertesting.ErrUnauthorized},
   235  			{nil},
   236  		},
   237  	})
   238  
   239  	rFlag, err = s.machine1.GetRebootFlag()
   240  	c.Assert(err, jc.ErrorIsNil)
   241  	c.Assert(rFlag, jc.IsFalse)
   242  }
   243  
   244  func (s *agentSuite) TestWatchCredentials(c *gc.C) {
   245  	authorizer := apiservertesting.FakeAuthorizer{
   246  		Tag:            names.NewMachineTag("0"),
   247  		EnvironManager: true,
   248  	}
   249  	api, err := agent.NewAgentAPIV2(s.State, s.resources, authorizer)
   250  	c.Assert(err, jc.ErrorIsNil)
   251  	tag := names.NewCloudCredentialTag("dummy/fred/default")
   252  	result, err := api.WatchCredentials(params.Entities{Entities: []params.Entity{{Tag: tag.String()}}})
   253  	c.Assert(err, jc.ErrorIsNil)
   254  	c.Assert(result, jc.DeepEquals, params.NotifyWatchResults{Results: []params.NotifyWatchResult{{"1", nil}}})
   255  	c.Assert(s.resources.Count(), gc.Equals, 1)
   256  
   257  	w := s.resources.Get("1")
   258  	defer statetesting.AssertStop(c, w)
   259  
   260  	// Check that the Watch has consumed the initial events ("returned" in the Watch call)
   261  	wc := statetesting.NewNotifyWatcherC(c, s.State, w.(state.NotifyWatcher))
   262  	wc.AssertNoChange()
   263  
   264  	s.State.UpdateCloudCredential(tag, cloud.NewCredential(cloud.UserPassAuthType, nil))
   265  	wc.AssertOneChange()
   266  }
   267  
   268  func (s *agentSuite) TestWatchAuthError(c *gc.C) {
   269  	authorizer := apiservertesting.FakeAuthorizer{
   270  		Tag:            names.NewMachineTag("1"),
   271  		EnvironManager: false,
   272  	}
   273  	api, err := agent.NewAgentAPIV2(s.State, s.resources, authorizer)
   274  	c.Assert(err, jc.ErrorIsNil)
   275  	_, err = api.WatchCredentials(params.Entities{})
   276  	c.Assert(err, gc.ErrorMatches, "permission denied")
   277  	c.Assert(s.resources.Count(), gc.Equals, 0)
   278  }