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