github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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 jc "github.com/juju/testing/checkers" 8 gc "gopkg.in/check.v1" 9 "gopkg.in/juju/names.v2" 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: ¶ms.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) startManifold(c *gc.C, a coreagent.Agent, mockAPIPort int) { 104 apiCaller := basetesting.APICallerFunc( 105 func(objType string, version int, id, request string, args, response interface{}) error { 106 c.Assert(objType, gc.Equals, "Agent") 107 switch request { 108 case "GetEntities": 109 c.Assert(args.(params.Entities).Entities, gc.HasLen, 1) 110 result := response.(*params.AgentGetEntitiesResults) 111 result.Entities = []params.AgentGetEntitiesResult{{ 112 Jobs: []multiwatcher.MachineJob{multiwatcher.JobManageModel}, 113 }} 114 case "StateServingInfo": 115 result := response.(*params.StateServingInfo) 116 *result = params.StateServingInfo{ 117 Cert: testing.CACert, 118 APIPort: mockAPIPort, 119 } 120 default: 121 c.Fatalf("not sure how to handle: %q", request) 122 } 123 return nil 124 }, 125 ) 126 context := dt.StubContext(nil, map[string]interface{}{ 127 "agent": a, 128 "api-caller": apiCaller, 129 }) 130 w, err := s.manifold.Start(context) 131 c.Assert(w, gc.IsNil) 132 c.Assert(err, gc.Equals, dependency.ErrUninstall) 133 } 134 135 func (s *ServingInfoSetterSuite) TestJobManageEnviron(c *gc.C) { 136 // State serving info should be set for machines with JobManageEnviron. 137 const mockAPIPort = 1234 138 139 a := &mockAgent{} 140 s.startManifold(c, a, mockAPIPort) 141 142 // Verify that the state serving info was actually set. 143 c.Assert(a.conf.ssiSet, jc.IsTrue) 144 c.Assert(a.conf.ssi.APIPort, gc.Equals, mockAPIPort) 145 c.Assert(a.conf.ssi.Cert, gc.Equals, testing.CACert) 146 } 147 148 func (s *ServingInfoSetterSuite) TestJobManageEnvironNotOverwriteCert(c *gc.C) { 149 // State serving info should be set for machines with JobManageEnviron. 150 const mockAPIPort = 1234 151 152 a := &mockAgent{} 153 existingCert := "some cert updated by certupdater" 154 a.conf.SetStateServingInfo(params.StateServingInfo{ 155 Cert: existingCert, 156 }) 157 158 s.startManifold(c, a, mockAPIPort) 159 160 // Verify that the state serving info was actually set. 161 c.Assert(a.conf.ssiSet, jc.IsTrue) 162 c.Assert(a.conf.ssi.APIPort, gc.Equals, mockAPIPort) 163 c.Assert(a.conf.ssi.Cert, gc.Equals, existingCert) 164 } 165 166 func (s *ServingInfoSetterSuite) TestJobHostUnits(c *gc.C) { 167 // State serving info should not be set for JobHostUnits. 168 s.checkNotController(c, multiwatcher.JobHostUnits) 169 } 170 171 func (s *ServingInfoSetterSuite) checkNotController(c *gc.C, job multiwatcher.MachineJob) { 172 a := &mockAgent{} 173 apiCaller := basetesting.APICallerFunc( 174 func(objType string, version int, id, request string, args, response interface{}) error { 175 c.Assert(objType, gc.Equals, "Agent") 176 switch request { 177 case "GetEntities": 178 c.Assert(args.(params.Entities).Entities, gc.HasLen, 1) 179 result := response.(*params.AgentGetEntitiesResults) 180 result.Entities = []params.AgentGetEntitiesResult{{ 181 Jobs: []multiwatcher.MachineJob{job}, 182 }} 183 default: 184 c.Fatalf("not sure how to handle: %q", request) 185 } 186 return nil 187 }, 188 ) 189 w, err := s.manifold.Start(dt.StubContext(nil, map[string]interface{}{ 190 "agent": a, 191 "api-caller": apiCaller, 192 })) 193 c.Assert(w, gc.IsNil) 194 c.Assert(err, gc.Equals, dependency.ErrUninstall) 195 196 // State serving info shouldn't have been set for this job type. 197 c.Assert(a.conf.ssiSet, jc.IsFalse) 198 } 199 200 type mockAgent struct { 201 coreagent.Agent 202 conf mockConfig 203 } 204 205 func (ma *mockAgent) CurrentConfig() coreagent.Config { 206 return &ma.conf 207 } 208 209 func (ma *mockAgent) ChangeConfig(f coreagent.ConfigMutator) error { 210 return f(&ma.conf) 211 } 212 213 type mockConfig struct { 214 coreagent.ConfigSetter 215 tag names.Tag 216 ssiSet bool 217 ssi params.StateServingInfo 218 } 219 220 func (mc *mockConfig) Tag() names.Tag { 221 if mc.tag == nil { 222 return names.NewMachineTag("99") 223 } 224 return mc.tag 225 } 226 227 func (mc *mockConfig) StateServingInfo() (params.StateServingInfo, bool) { 228 return mc.ssi, mc.ssiSet 229 } 230 231 func (mc *mockConfig) SetStateServingInfo(info params.StateServingInfo) { 232 mc.ssiSet = true 233 mc.ssi = info 234 }