github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/unitstatus_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common_test 5 6 import ( 7 "errors" 8 9 "github.com/juju/testing" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 "gopkg.in/juju/names.v2" 13 14 "github.com/juju/juju/apiserver/common" 15 "github.com/juju/juju/core/status" 16 "github.com/juju/juju/state" 17 ) 18 19 type UnitStatusSuite struct { 20 testing.IsolationSuite 21 ctx common.ModelPresenceContext 22 unit *fakeStatusUnit 23 } 24 25 var _ = gc.Suite(&UnitStatusSuite{}) 26 27 func (s *UnitStatusSuite) SetUpTest(c *gc.C) { 28 s.unit = &fakeStatusUnit{ 29 app: "foo", 30 agentStatus: status.StatusInfo{ 31 Status: status.Started, 32 Message: "agent ok", 33 }, 34 status: status.StatusInfo{ 35 Status: status.Idle, 36 Message: "unit ok", 37 }, 38 presence: true, 39 shouldBeAssigned: true, 40 } 41 s.ctx = common.ModelPresenceContext{ 42 Presence: agentAlive(names.NewUnitTag(s.unit.Name()).String()), 43 } 44 } 45 46 func (s *UnitStatusSuite) checkUntouched(c *gc.C) { 47 agent, workload := s.ctx.UnitStatus(s.unit) 48 c.Check(agent.Status, jc.DeepEquals, s.unit.agentStatus) 49 c.Check(agent.Err, jc.ErrorIsNil) 50 c.Check(workload.Status, jc.DeepEquals, s.unit.status) 51 c.Check(workload.Err, jc.ErrorIsNil) 52 } 53 54 func (s *UnitStatusSuite) checkLost(c *gc.C) { 55 agent, workload := s.ctx.UnitStatus(s.unit) 56 c.Check(agent.Status, jc.DeepEquals, status.StatusInfo{ 57 Status: status.Lost, 58 Message: "agent is not communicating with the server", 59 }) 60 c.Check(agent.Err, jc.ErrorIsNil) 61 c.Check(workload.Status, jc.DeepEquals, status.StatusInfo{ 62 Status: status.Unknown, 63 Message: "agent lost, see 'juju show-status-log foo/2'", 64 }) 65 c.Check(workload.Err, jc.ErrorIsNil) 66 } 67 68 func (s *UnitStatusSuite) TestNormal(c *gc.C) { 69 s.checkUntouched(c) 70 } 71 72 func (s *UnitStatusSuite) TestCAASNormal(c *gc.C) { 73 s.unit.shouldBeAssigned = false 74 s.ctx.Presence = agentAlive(names.NewApplicationTag(s.unit.app).String()) 75 s.checkUntouched(c) 76 } 77 78 func (s *UnitStatusSuite) TestErrors(c *gc.C) { 79 s.unit.agentStatusErr = errors.New("agent status error") 80 s.unit.statusErr = errors.New("status error") 81 82 agent, workload := s.ctx.UnitStatus(s.unit) 83 c.Check(agent.Err, gc.ErrorMatches, "agent status error") 84 c.Check(workload.Err, gc.ErrorMatches, "status error") 85 } 86 87 func (s *UnitStatusSuite) TestLostLegacy(c *gc.C) { 88 s.ctx.Presence = nil 89 s.unit.presence = false 90 s.checkLost(c) 91 } 92 93 func (s *UnitStatusSuite) TestLost(c *gc.C) { 94 s.ctx.Presence = agentDown(s.unit.Tag().String()) 95 s.checkLost(c) 96 } 97 98 func (s *UnitStatusSuite) TestCAASLost(c *gc.C) { 99 s.unit.shouldBeAssigned = false 100 s.ctx.Presence = agentDown(names.NewApplicationTag(s.unit.app).String()) 101 s.checkLost(c) 102 } 103 104 func (s *UnitStatusSuite) TestLostAndDeadLegacy(c *gc.C) { 105 s.ctx.Presence = nil 106 s.unit.presence = false 107 s.unit.life = state.Dead 108 // Status is untouched if unit is Dead. 109 s.checkUntouched(c) 110 } 111 112 func (s *UnitStatusSuite) TestLostAndDead(c *gc.C) { 113 s.ctx.Presence = agentDown(s.unit.Tag().String()) 114 s.unit.life = state.Dead 115 // Status is untouched if unit is Dead. 116 s.checkUntouched(c) 117 } 118 119 func (s *UnitStatusSuite) TestPresenceErrorLegacy(c *gc.C) { 120 s.ctx.Presence = nil 121 s.unit.presence = false 122 s.unit.presenceErr = errors.New("boom") 123 // Presence error gets ignored, so no output is unchanged. 124 s.checkUntouched(c) 125 } 126 127 func (s *UnitStatusSuite) TestPresenceError(c *gc.C) { 128 s.ctx.Presence = presenceError(s.unit.Tag().String()) 129 // Presence error gets ignored, so no output is unchanged. 130 s.checkUntouched(c) 131 } 132 133 func (s *UnitStatusSuite) TestNotLostIfAllocatingLegacy(c *gc.C) { 134 s.ctx.Presence = nil 135 s.unit.presence = false 136 s.unit.agentStatus.Status = status.Allocating 137 s.checkUntouched(c) 138 } 139 140 func (s *UnitStatusSuite) TestNotLostIfAllocating(c *gc.C) { 141 s.ctx.Presence = agentDown(s.unit.Tag().String()) 142 s.unit.agentStatus.Status = status.Allocating 143 s.checkUntouched(c) 144 } 145 146 func (s *UnitStatusSuite) TestCantBeLostDuringInstallLegacy(c *gc.C) { 147 s.ctx.Presence = nil 148 s.unit.presence = false 149 s.unit.agentStatus.Status = status.Executing 150 s.unit.agentStatus.Message = "running install hook" 151 s.checkUntouched(c) 152 } 153 154 func (s *UnitStatusSuite) TestCantBeLostDuringInstall(c *gc.C) { 155 s.ctx.Presence = agentDown(s.unit.Tag().String()) 156 s.unit.agentStatus.Status = status.Executing 157 s.unit.agentStatus.Message = "running install hook" 158 s.checkUntouched(c) 159 } 160 161 func (s *UnitStatusSuite) TestCantBeLostDuringWorkloadInstallLegacy(c *gc.C) { 162 s.ctx.Presence = nil 163 s.unit.presence = false 164 s.unit.status.Status = status.Maintenance 165 s.unit.status.Message = "installing charm software" 166 s.checkUntouched(c) 167 } 168 func (s *UnitStatusSuite) TestCantBeLostDuringWorkloadInstall(c *gc.C) { 169 s.ctx.Presence = agentDown(s.unit.Tag().String()) 170 s.unit.status.Status = status.Maintenance 171 s.unit.status.Message = "installing charm software" 172 s.checkUntouched(c) 173 } 174 175 type fakeStatusUnit struct { 176 app string 177 agentStatus status.StatusInfo 178 agentStatusErr error 179 status status.StatusInfo 180 statusErr error 181 presence bool 182 presenceErr error 183 life state.Life 184 shouldBeAssigned bool 185 } 186 187 func (u *fakeStatusUnit) Name() string { 188 return u.app + "/2" 189 } 190 191 func (u *fakeStatusUnit) Tag() names.Tag { 192 return names.NewUnitTag(u.Name()) 193 } 194 195 func (u *fakeStatusUnit) AgentStatus() (status.StatusInfo, error) { 196 return u.agentStatus, u.agentStatusErr 197 } 198 199 func (u *fakeStatusUnit) Status() (status.StatusInfo, error) { 200 return u.status, u.statusErr 201 } 202 203 func (u *fakeStatusUnit) AgentPresence() (bool, error) { 204 return u.presence, u.presenceErr 205 } 206 207 func (u *fakeStatusUnit) Life() state.Life { 208 return u.life 209 } 210 211 func (u *fakeStatusUnit) ShouldBeAssigned() bool { 212 return u.shouldBeAssigned 213 }