github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/jujud/agent/machine/servinginfo_setter_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package machine_test
     5  
     6  import (
     7  	"github.com/juju/names"
     8  	jc "github.com/juju/testing/checkers"
     9  	gc "gopkg.in/check.v1"
    10  
    11  	coreagent "github.com/juju/juju/agent"
    12  	basetesting "github.com/juju/juju/api/base/testing"
    13  	"github.com/juju/juju/apiserver/params"
    14  	"github.com/juju/juju/cmd/jujud/agent/machine"
    15  	"github.com/juju/juju/state/multiwatcher"
    16  	"github.com/juju/juju/testing"
    17  	"github.com/juju/juju/worker/dependency"
    18  	dt "github.com/juju/juju/worker/dependency/testing"
    19  )
    20  
    21  type ServingInfoSetterSuite struct {
    22  	testing.BaseSuite
    23  	manifold dependency.Manifold
    24  }
    25  
    26  var _ = gc.Suite(&ServingInfoSetterSuite{})
    27  
    28  func (s *ServingInfoSetterSuite) SetUpTest(c *gc.C) {
    29  	s.manifold = machine.ServingInfoSetterManifold(machine.ServingInfoSetterConfig{
    30  		AgentName:     "agent",
    31  		APICallerName: "api-caller",
    32  	})
    33  }
    34  
    35  func (s *ServingInfoSetterSuite) TestInputs(c *gc.C) {
    36  	c.Assert(s.manifold.Inputs, jc.SameContents, []string{
    37  		"agent",
    38  		"api-caller",
    39  	})
    40  }
    41  
    42  func (s *ServingInfoSetterSuite) TestStartAgentMissing(c *gc.C) {
    43  	context := dt.StubContext(nil, map[string]interface{}{
    44  		"agent": dependency.ErrMissing,
    45  	})
    46  	worker, err := s.manifold.Start(context)
    47  	c.Check(worker, gc.IsNil)
    48  	c.Check(err, gc.Equals, dependency.ErrMissing)
    49  }
    50  
    51  func (s *ServingInfoSetterSuite) TestStartApiCallerMissing(c *gc.C) {
    52  	context := dt.StubContext(nil, map[string]interface{}{
    53  		"agent":      &mockAgent{},
    54  		"api-caller": dependency.ErrMissing,
    55  	})
    56  	worker, err := s.manifold.Start(context)
    57  	c.Check(worker, gc.IsNil)
    58  	c.Check(err, gc.Equals, dependency.ErrMissing)
    59  }
    60  
    61  func (s *ServingInfoSetterSuite) TestNotMachine(c *gc.C) {
    62  	a := &mockAgent{
    63  		conf: mockConfig{tag: names.NewUnitTag("foo/0")},
    64  	}
    65  	context := dt.StubContext(nil, map[string]interface{}{
    66  		"agent": a,
    67  	})
    68  	worker, err := s.manifold.Start(context)
    69  	c.Check(worker, gc.IsNil)
    70  	c.Check(err, gc.ErrorMatches, "agent's tag is not a machine tag")
    71  }
    72  
    73  func (s *ServingInfoSetterSuite) TestEntityLookupFailure(c *gc.C) {
    74  	// Set up a fake Agent and APICaller
    75  	a := &mockAgent{}
    76  	apiCaller := basetesting.APICallerFunc(
    77  		func(objType string, version int, id, request string, args, response interface{}) error {
    78  			c.Assert(objType, gc.Equals, "Agent")
    79  			switch request {
    80  			case "GetEntities":
    81  				c.Assert(args.(params.Entities).Entities, gc.HasLen, 1)
    82  				result := response.(*params.AgentGetEntitiesResults)
    83  				result.Entities = []params.AgentGetEntitiesResult{{
    84  					Error: &params.Error{Message: "boom"},
    85  				}}
    86  			default:
    87  				c.Fatalf("not sure how to handle: %q", request)
    88  			}
    89  			return nil
    90  		},
    91  	)
    92  	// Call the manifold's start func with a fake resource getter that
    93  	// returns the fake Agent and APICaller
    94  	context := dt.StubContext(nil, map[string]interface{}{
    95  		"agent":      a,
    96  		"api-caller": apiCaller,
    97  	})
    98  	w, err := s.manifold.Start(context)
    99  	c.Assert(w, gc.IsNil)
   100  	c.Assert(err, gc.ErrorMatches, "boom")
   101  }
   102  
   103  func (s *ServingInfoSetterSuite) TestJobManageEnviron(c *gc.C) {
   104  	// State serving info should be set for machines with JobManageEnviron.
   105  	const mockAPIPort = 1234
   106  
   107  	a := &mockAgent{}
   108  	apiCaller := basetesting.APICallerFunc(
   109  		func(objType string, version int, id, request string, args, response interface{}) error {
   110  			c.Assert(objType, gc.Equals, "Agent")
   111  			switch request {
   112  			case "GetEntities":
   113  				c.Assert(args.(params.Entities).Entities, gc.HasLen, 1)
   114  				result := response.(*params.AgentGetEntitiesResults)
   115  				result.Entities = []params.AgentGetEntitiesResult{{
   116  					Jobs: []multiwatcher.MachineJob{multiwatcher.JobManageModel},
   117  				}}
   118  			case "StateServingInfo":
   119  				result := response.(*params.StateServingInfo)
   120  				*result = params.StateServingInfo{
   121  					APIPort: mockAPIPort,
   122  				}
   123  			default:
   124  				c.Fatalf("not sure how to handle: %q", request)
   125  			}
   126  			return nil
   127  		},
   128  	)
   129  	context := dt.StubContext(nil, map[string]interface{}{
   130  		"agent":      a,
   131  		"api-caller": apiCaller,
   132  	})
   133  	w, err := s.manifold.Start(context)
   134  	c.Assert(w, gc.IsNil)
   135  	c.Assert(err, gc.Equals, dependency.ErrUninstall)
   136  
   137  	// Verify that the state serving info was actually set.
   138  	c.Assert(a.conf.ssiSet, jc.IsTrue)
   139  	c.Assert(a.conf.ssi.APIPort, gc.Equals, mockAPIPort)
   140  }
   141  
   142  func (s *ServingInfoSetterSuite) TestJobHostUnits(c *gc.C) {
   143  	// State serving info should not be set for JobHostUnits.
   144  	s.checkNotController(c, multiwatcher.JobHostUnits)
   145  }
   146  
   147  func (s *ServingInfoSetterSuite) TestJobManageNetworking(c *gc.C) {
   148  	// State serving info should NOT be set for JobManageNetworking.
   149  	s.checkNotController(c, multiwatcher.JobManageNetworking)
   150  }
   151  
   152  func (s *ServingInfoSetterSuite) checkNotController(c *gc.C, job multiwatcher.MachineJob) {
   153  	a := &mockAgent{}
   154  	apiCaller := basetesting.APICallerFunc(
   155  		func(objType string, version int, id, request string, args, response interface{}) error {
   156  			c.Assert(objType, gc.Equals, "Agent")
   157  			switch request {
   158  			case "GetEntities":
   159  				c.Assert(args.(params.Entities).Entities, gc.HasLen, 1)
   160  				result := response.(*params.AgentGetEntitiesResults)
   161  				result.Entities = []params.AgentGetEntitiesResult{{
   162  					Jobs: []multiwatcher.MachineJob{job},
   163  				}}
   164  			default:
   165  				c.Fatalf("not sure how to handle: %q", request)
   166  			}
   167  			return nil
   168  		},
   169  	)
   170  	w, err := s.manifold.Start(dt.StubContext(nil, map[string]interface{}{
   171  		"agent":      a,
   172  		"api-caller": apiCaller,
   173  	}))
   174  	c.Assert(w, gc.IsNil)
   175  	c.Assert(err, gc.Equals, dependency.ErrUninstall)
   176  
   177  	// State serving info shouldn't have been set for this job type.
   178  	c.Assert(a.conf.ssiSet, jc.IsFalse)
   179  }
   180  
   181  type mockAgent struct {
   182  	coreagent.Agent
   183  	conf mockConfig
   184  }
   185  
   186  func (ma *mockAgent) CurrentConfig() coreagent.Config {
   187  	return &ma.conf
   188  }
   189  
   190  func (ma *mockAgent) ChangeConfig(f coreagent.ConfigMutator) error {
   191  	return f(&ma.conf)
   192  }
   193  
   194  type mockConfig struct {
   195  	coreagent.ConfigSetter
   196  	tag    names.Tag
   197  	ssiSet bool
   198  	ssi    params.StateServingInfo
   199  }
   200  
   201  func (mc *mockConfig) Tag() names.Tag {
   202  	if mc.tag == nil {
   203  		return names.NewMachineTag("99")
   204  	}
   205  	return mc.tag
   206  }
   207  
   208  func (mc *mockConfig) SetStateServingInfo(info params.StateServingInfo) {
   209  	mc.ssiSet = true
   210  	mc.ssi = info
   211  }