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