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