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: ¶ms.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 }