github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/agent/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 "github.com/juju/os/series" 9 jc "github.com/juju/testing/checkers" 10 "github.com/juju/utils/arch" 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/facades/agent/upgrader" 17 "github.com/juju/juju/apiserver/params" 18 apiservertesting "github.com/juju/juju/apiserver/testing" 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.MustHostSeries(), 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 app := s.AddTestingApplication(c, "wordpress", s.AddTestingCharm(c, "wordpress")) 59 s.rawUnit, err = app.AddUnit(state.AddUnitParams{}) 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 s.WaitForModelWatchersIdle(c, s.Model.UUID()) 92 results, err := s.upgrader.WatchAPIVersion(args) 93 c.Assert(err, jc.ErrorIsNil) 94 c.Check(results.Results, gc.HasLen, 1) 95 c.Check(results.Results[0].NotifyWatcherId, gc.Not(gc.Equals), "") 96 c.Check(results.Results[0].Error, gc.IsNil) 97 resource := s.resources.Get(results.Results[0].NotifyWatcherId) 98 c.Check(resource, gc.NotNil) 99 100 w := resource.(state.NotifyWatcher) 101 wc := statetesting.NewNotifyWatcherC(c, s.State, w) 102 wc.AssertNoChange() 103 104 err = s.rawMachine.SetAgentVersion(version.MustParseBinary("3.4.567.8-quantal-amd64")) 105 c.Assert(err, jc.ErrorIsNil) 106 wc.AssertOneChange() 107 statetesting.AssertStop(c, w) 108 wc.AssertClosed() 109 } 110 111 func (s *unitUpgraderSuite) TestUpgraderAPIRefusesNonUnitAgent(c *gc.C) { 112 anAuthorizer := s.authorizer 113 anAuthorizer.Tag = names.NewMachineTag("7") 114 anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer) 115 c.Check(err, gc.NotNil) 116 c.Check(anUpgrader, gc.IsNil) 117 c.Assert(err, gc.ErrorMatches, "permission denied") 118 } 119 120 func (s *unitUpgraderSuite) TestWatchAPIVersionRefusesWrongAgent(c *gc.C) { 121 // We are a unit agent, but not the one we are trying to track 122 anAuthorizer := s.authorizer 123 anAuthorizer.Tag = names.NewUnitTag("wordpress/12354") 124 anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer) 125 c.Check(err, jc.ErrorIsNil) 126 args := params.Entities{ 127 Entities: []params.Entity{{Tag: s.rawUnit.Tag().String()}}, 128 } 129 results, err := anUpgrader.WatchAPIVersion(args) 130 // It is not an error to make the request, but the specific item is rejected 131 c.Assert(err, jc.ErrorIsNil) 132 c.Check(results.Results, gc.HasLen, 1) 133 c.Check(results.Results[0].NotifyWatcherId, gc.Equals, "") 134 c.Assert(results.Results[0].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized) 135 } 136 137 func (s *unitUpgraderSuite) TestToolsNothing(c *gc.C) { 138 // Not an error to watch nothing 139 results, err := s.upgrader.Tools(params.Entities{}) 140 c.Assert(err, jc.ErrorIsNil) 141 c.Check(results.Results, gc.HasLen, 0) 142 } 143 144 func (s *unitUpgraderSuite) TestToolsRefusesWrongAgent(c *gc.C) { 145 anAuthorizer := s.authorizer 146 anAuthorizer.Tag = names.NewUnitTag("wordpress/12354") 147 anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer) 148 c.Check(err, jc.ErrorIsNil) 149 args := params.Entities{ 150 Entities: []params.Entity{{Tag: s.rawUnit.Tag().String()}}, 151 } 152 results, err := anUpgrader.Tools(args) 153 // It is not an error to make the request, but the specific item is rejected 154 c.Assert(err, jc.ErrorIsNil) 155 c.Assert(results.Results, gc.HasLen, 1) 156 toolResult := results.Results[0] 157 c.Assert(toolResult.Error, gc.DeepEquals, apiservertesting.ErrUnauthorized) 158 } 159 160 func (s *unitUpgraderSuite) TestToolsForAgent(c *gc.C) { 161 agent := params.Entity{Tag: s.rawUnit.Tag().String()} 162 163 // The machine must have its existing tools set before we query for the 164 // next tools. This is so that we can grab Arch and Series without 165 // having to pass it in again 166 err := s.rawMachine.SetAgentVersion(current) 167 c.Assert(err, jc.ErrorIsNil) 168 169 args := params.Entities{Entities: []params.Entity{agent}} 170 results, err := s.upgrader.Tools(args) 171 c.Assert(err, jc.ErrorIsNil) 172 assertTools := func() { 173 c.Check(results.Results, gc.HasLen, 1) 174 c.Assert(results.Results[0].Error, gc.IsNil) 175 agentTools := results.Results[0].ToolsList[0] 176 c.Check(agentTools.Version.Number, gc.DeepEquals, jujuversion.Current) 177 c.Assert(agentTools.URL, gc.NotNil) 178 } 179 assertTools() 180 } 181 182 func (s *unitUpgraderSuite) TestSetToolsNothing(c *gc.C) { 183 // Not an error to watch nothing 184 results, err := s.upgrader.SetTools(params.EntitiesVersion{}) 185 c.Assert(err, jc.ErrorIsNil) 186 c.Check(results.Results, gc.HasLen, 0) 187 } 188 189 func (s *unitUpgraderSuite) TestSetToolsRefusesWrongAgent(c *gc.C) { 190 anAuthorizer := s.authorizer 191 anAuthorizer.Tag = names.NewUnitTag("wordpress/12354") 192 anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer) 193 c.Check(err, jc.ErrorIsNil) 194 args := params.EntitiesVersion{ 195 AgentTools: []params.EntityVersion{{ 196 Tag: s.rawUnit.Tag().String(), 197 Tools: ¶ms.Version{ 198 Version: version.Binary{ 199 Number: jujuversion.Current, 200 Arch: arch.HostArch(), 201 Series: series.MustHostSeries(), 202 }, 203 }, 204 }}, 205 } 206 207 results, err := anUpgrader.SetTools(args) 208 c.Assert(results.Results, gc.HasLen, 1) 209 c.Assert(results.Results[0].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized) 210 } 211 212 func (s *unitUpgraderSuite) TestSetTools(c *gc.C) { 213 cur := version.Binary{ 214 Number: jujuversion.Current, 215 Arch: arch.HostArch(), 216 Series: series.MustHostSeries(), 217 } 218 _, err := s.rawUnit.AgentTools() 219 c.Assert(err, jc.Satisfies, errors.IsNotFound) 220 args := params.EntitiesVersion{ 221 AgentTools: []params.EntityVersion{{ 222 Tag: s.rawUnit.Tag().String(), 223 Tools: ¶ms.Version{ 224 Version: cur, 225 }}, 226 }, 227 } 228 results, err := s.upgrader.SetTools(args) 229 c.Assert(err, jc.ErrorIsNil) 230 c.Assert(results.Results, gc.HasLen, 1) 231 c.Assert(results.Results[0].Error, gc.IsNil) 232 // Check that the new value actually got set, we must Refresh because 233 // it was set on a different Machine object 234 err = s.rawUnit.Refresh() 235 c.Assert(err, jc.ErrorIsNil) 236 realTools, err := s.rawUnit.AgentTools() 237 c.Assert(err, jc.ErrorIsNil) 238 c.Check(realTools.Version.Arch, gc.Equals, cur.Arch) 239 c.Check(realTools.Version.Series, gc.Equals, cur.Series) 240 c.Check(realTools.Version.Major, gc.Equals, cur.Major) 241 c.Check(realTools.Version.Minor, gc.Equals, cur.Minor) 242 c.Check(realTools.Version.Patch, gc.Equals, cur.Patch) 243 c.Check(realTools.Version.Build, gc.Equals, cur.Build) 244 c.Check(realTools.URL, gc.Equals, "") 245 } 246 247 func (s *unitUpgraderSuite) TestDesiredVersionNothing(c *gc.C) { 248 // Not an error to watch nothing 249 results, err := s.upgrader.DesiredVersion(params.Entities{}) 250 c.Assert(err, jc.ErrorIsNil) 251 c.Check(results.Results, gc.HasLen, 0) 252 } 253 254 func (s *unitUpgraderSuite) TestDesiredVersionRefusesWrongAgent(c *gc.C) { 255 anAuthorizer := s.authorizer 256 anAuthorizer.Tag = names.NewUnitTag("wordpress/12354") 257 anUpgrader, err := upgrader.NewUnitUpgraderAPI(s.State, s.resources, anAuthorizer) 258 c.Check(err, jc.ErrorIsNil) 259 args := params.Entities{ 260 Entities: []params.Entity{{Tag: s.rawUnit.Tag().String()}}, 261 } 262 results, err := anUpgrader.DesiredVersion(args) 263 // It is not an error to make the request, but the specific item is rejected 264 c.Assert(err, jc.ErrorIsNil) 265 c.Check(results.Results, gc.HasLen, 1) 266 toolResult := results.Results[0] 267 c.Assert(toolResult.Error, gc.DeepEquals, apiservertesting.ErrUnauthorized) 268 } 269 270 func (s *unitUpgraderSuite) TestDesiredVersionNoticesMixedAgents(c *gc.C) { 271 current := version.Binary{ 272 Number: jujuversion.Current, 273 Arch: arch.HostArch(), 274 Series: series.MustHostSeries(), 275 } 276 err := s.rawMachine.SetAgentVersion(current) 277 c.Assert(err, jc.ErrorIsNil) 278 args := params.Entities{Entities: []params.Entity{ 279 {Tag: s.rawUnit.Tag().String()}, 280 {Tag: "unit-wordpress-12345"}, 281 }} 282 results, err := s.upgrader.DesiredVersion(args) 283 c.Assert(err, jc.ErrorIsNil) 284 c.Check(results.Results, gc.HasLen, 2) 285 c.Assert(results.Results[0].Error, gc.IsNil) 286 agentVersion := results.Results[0].Version 287 c.Assert(agentVersion, gc.NotNil) 288 c.Check(*agentVersion, gc.DeepEquals, jujuversion.Current) 289 290 c.Assert(results.Results[1].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized) 291 c.Assert(results.Results[1].Version, gc.IsNil) 292 293 } 294 295 func (s *unitUpgraderSuite) TestDesiredVersionForAgent(c *gc.C) { 296 current := version.Binary{ 297 Number: jujuversion.Current, 298 Arch: arch.HostArch(), 299 Series: series.MustHostSeries(), 300 } 301 err := s.rawMachine.SetAgentVersion(current) 302 c.Assert(err, jc.ErrorIsNil) 303 args := params.Entities{Entities: []params.Entity{{Tag: s.rawUnit.Tag().String()}}} 304 results, err := s.upgrader.DesiredVersion(args) 305 c.Assert(err, jc.ErrorIsNil) 306 c.Check(results.Results, gc.HasLen, 1) 307 c.Assert(results.Results[0].Error, gc.IsNil) 308 agentVersion := results.Results[0].Version 309 c.Assert(agentVersion, gc.NotNil) 310 c.Check(*agentVersion, gc.DeepEquals, jujuversion.Current) 311 }