github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/status_history_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state_test 5 6 import ( 7 "time" 8 9 "github.com/juju/testing" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/state" 14 statetesting "github.com/juju/juju/state/testing" 15 "github.com/juju/juju/status" 16 coretesting "github.com/juju/juju/testing" 17 "github.com/juju/juju/testing/factory" 18 ) 19 20 type StatusHistorySuite struct { 21 // TODO Migrate to StateSuite (with testing clock). 22 statetesting.StateWithWallclockSuite 23 } 24 25 var _ = gc.Suite(&StatusHistorySuite{}) 26 27 func (s *StatusHistorySuite) TestPruneStatusHistoryBySize(c *gc.C) { 28 clock := testing.NewClock(coretesting.NonZeroTime()) 29 err := s.State.SetClockForTesting(clock) 30 c.Assert(err, jc.ErrorIsNil) 31 service := s.Factory.MakeApplication(c, nil) 32 unit := s.Factory.MakeUnit(c, &factory.UnitParams{Application: service}) 33 state.PrimeUnitStatusHistory(c, clock, unit, status.Active, 20000, 1000, nil) 34 35 history, err := unit.StatusHistory(status.StatusHistoryFilter{Size: 25000}) 36 c.Assert(err, jc.ErrorIsNil) 37 c.Logf("%d\n", len(history)) 38 c.Assert(history, gc.HasLen, 20001) 39 40 err = state.PruneStatusHistory(s.State, 0, 1) 41 c.Assert(err, jc.ErrorIsNil) 42 43 history, err = unit.StatusHistory(status.StatusHistoryFilter{Size: 25000}) 44 c.Assert(err, jc.ErrorIsNil) 45 historyLen := len(history) 46 // When writing this test, the size was 6670 for about 0,00015 MB per entry 47 // but that is a size that can most likely change so I wont risk a flaky test 48 // here, enough to say that if this size suddenly is no longer less than 49 // half its good reason for suspicion. 50 c.Assert(historyLen, jc.LessThan, 10000) 51 } 52 53 func (s *StatusHistorySuite) TestPruneStatusHistoryByDate(c *gc.C) { 54 55 // NOTE: the behaviour is bad, and the test is ugly. I'm just verifying 56 // the existing logic here. 57 // 58 // If you get the opportunity to fix this, you'll want a better shape of 59 // test (that injects a usable clock dependency, apart from anything else, 60 // and checks that we do our best to maintain a usable span of history 61 // rather than an arbitrary limit per entity. And isn't O(N) on status 62 // count in the model). 63 64 const count = 3 65 units := make([]*state.Unit, count) 66 agents := make([]*state.UnitAgent, count) 67 service := s.Factory.MakeApplication(c, nil) 68 for i := 0; i < count; i++ { 69 units[i] = s.Factory.MakeUnit(c, &factory.UnitParams{Application: service}) 70 agents[i] = units[i].Agent() 71 } 72 73 primeUnitStatusHistory(c, units[0], 10, 0) 74 primeUnitStatusHistory(c, units[0], 10, 24*time.Hour) 75 primeUnitStatusHistory(c, units[1], 50, 0) 76 primeUnitStatusHistory(c, units[1], 50, 24*time.Hour) 77 primeUnitStatusHistory(c, units[2], 100, 0) 78 primeUnitStatusHistory(c, units[2], 100, 24*time.Hour) 79 primeUnitAgentStatusHistory(c, agents[0], 100, 0) 80 primeUnitAgentStatusHistory(c, agents[0], 100, 24*time.Hour) 81 primeUnitAgentStatusHistory(c, agents[1], 50, 0) 82 primeUnitAgentStatusHistory(c, agents[1], 50, 24*time.Hour) 83 primeUnitAgentStatusHistory(c, agents[2], 10, 0) 84 primeUnitAgentStatusHistory(c, agents[2], 10, 24*time.Hour) 85 86 history, err := units[0].StatusHistory(status.StatusHistoryFilter{Size: 50}) 87 c.Assert(err, jc.ErrorIsNil) 88 c.Assert(history, gc.HasLen, 21) 89 checkInitialWorkloadStatus(c, history[10]) 90 for i, statusInfo := range history[:10] { 91 checkPrimedUnitStatus(c, statusInfo, 9-i, 0) 92 } 93 for i, statusInfo := range history[11:20] { 94 checkPrimedUnitStatus(c, statusInfo, 9-i, 24*time.Hour) 95 } 96 97 err = state.PruneStatusHistory(s.State, 10*time.Hour, 1024) 98 c.Assert(err, jc.ErrorIsNil) 99 100 history, err = units[0].StatusHistory(status.StatusHistoryFilter{Size: 50}) 101 c.Assert(err, jc.ErrorIsNil) 102 c.Assert(history, gc.HasLen, 11) 103 checkInitialWorkloadStatus(c, history[10]) 104 for i, statusInfo := range history[:10] { 105 checkPrimedUnitStatus(c, statusInfo, 9-i, 0) 106 } 107 108 history, err = units[1].StatusHistory(status.StatusHistoryFilter{Size: 100}) 109 c.Assert(err, jc.ErrorIsNil) 110 c.Assert(history, gc.HasLen, 51) 111 for i, statusInfo := range history[:50] { 112 checkPrimedUnitStatus(c, statusInfo, 49-i, 0) 113 } 114 115 history, err = units[2].StatusHistory(status.StatusHistoryFilter{Size: 200}) 116 c.Assert(err, jc.ErrorIsNil) 117 c.Assert(history, gc.HasLen, 101) 118 for i, statusInfo := range history[:100] { 119 checkPrimedUnitStatus(c, statusInfo, 99-i, 0) 120 } 121 122 history, err = agents[0].StatusHistory(status.StatusHistoryFilter{Size: 200}) 123 c.Assert(err, jc.ErrorIsNil) 124 c.Assert(history, gc.HasLen, 101) 125 for i, statusInfo := range history[:100] { 126 checkPrimedUnitAgentStatus(c, statusInfo, 99-i, 0) 127 } 128 129 history, err = agents[1].StatusHistory(status.StatusHistoryFilter{Size: 100}) 130 c.Assert(err, jc.ErrorIsNil) 131 c.Assert(history, gc.HasLen, 51) 132 for i, statusInfo := range history[:50] { 133 checkPrimedUnitAgentStatus(c, statusInfo, 49-i, 0) 134 } 135 136 history, err = agents[2].StatusHistory(status.StatusHistoryFilter{Size: 50}) 137 c.Assert(err, jc.ErrorIsNil) 138 c.Assert(history, gc.HasLen, 11) 139 checkInitialUnitAgentStatus(c, history[10]) 140 for i, statusInfo := range history[:10] { 141 checkPrimedUnitAgentStatus(c, statusInfo, 9-i, 0) 142 } 143 } 144 145 func (s *StatusHistorySuite) TestStatusHistoryFiltersByDateAndDelta(c *gc.C) { 146 // TODO(perrito666) setup should be extracted into a fixture and the 147 // 6 or 7 test cases each get their own method. 148 service := s.Factory.MakeApplication(c, nil) 149 unit := s.Factory.MakeUnit(c, &factory.UnitParams{Application: service}) 150 151 twoDaysBack := time.Hour * 48 152 threeDaysBack := time.Hour * 72 153 now := time.Now() 154 twoDaysAgo := now.Add(-twoDaysBack) 155 threeDaysAgo := now.Add(-threeDaysBack) 156 sInfo := status.StatusInfo{ 157 Status: status.Active, 158 Message: "current status", 159 Since: &now, 160 } 161 err := unit.SetStatus(sInfo) 162 c.Assert(err, jc.ErrorIsNil) 163 sInfo = status.StatusInfo{ 164 Status: status.Active, 165 Message: "2 days ago", 166 Since: &twoDaysAgo, 167 } 168 unit.SetStatus(sInfo) 169 sInfo = status.StatusInfo{ 170 Status: status.Active, 171 Message: "3 days ago", 172 Since: &threeDaysAgo, 173 } 174 unit.SetStatus(sInfo) 175 history, err := unit.StatusHistory(status.StatusHistoryFilter{Size: 50}) 176 c.Assert(err, jc.ErrorIsNil) 177 c.Assert(history, gc.HasLen, 4) 178 c.Assert(history[0].Message, gc.Equals, "current status") 179 c.Assert(history[1].Message, gc.Equals, "waiting for machine") 180 c.Assert(history[2].Message, gc.Equals, "2 days ago") 181 c.Assert(history[3].Message, gc.Equals, "3 days ago") 182 now = now.Add(10 * time.Second) // lets add some padding to prevent races here. 183 184 // logs up to one day back, using delta. 185 oneDayBack := time.Hour * 24 186 history, err = unit.StatusHistory(status.StatusHistoryFilter{Delta: &oneDayBack}) 187 c.Assert(err, jc.ErrorIsNil) 188 c.Assert(history, gc.HasLen, 2) 189 c.Assert(history[0].Message, gc.Equals, "current status") 190 c.Assert(history[1].Message, gc.Equals, "waiting for machine") 191 192 // logs up to one day back, using date. 193 yesterday := now.Add(-(time.Hour * 24)) 194 history, err = unit.StatusHistory(status.StatusHistoryFilter{Date: &yesterday}) 195 c.Assert(err, jc.ErrorIsNil) 196 c.Assert(history, gc.HasLen, 2) 197 c.Assert(history[0].Message, gc.Equals, "current status") 198 c.Assert(history[1].Message, gc.Equals, "waiting for machine") 199 200 // Logs up to two days ago, using delta. 201 history, err = unit.StatusHistory(status.StatusHistoryFilter{Delta: &twoDaysBack}) 202 c.Assert(err, jc.ErrorIsNil) 203 c.Assert(history, gc.HasLen, 2) 204 c.Assert(history[0].Message, gc.Equals, "current status") 205 c.Assert(history[1].Message, gc.Equals, "waiting for machine") 206 207 // Logs up to two days ago, using date. 208 209 history, err = unit.StatusHistory(status.StatusHistoryFilter{Date: &twoDaysAgo}) 210 c.Assert(err, jc.ErrorIsNil) 211 c.Assert(history, gc.HasLen, 2) 212 c.Assert(history[0].Message, gc.Equals, "current status") 213 c.Assert(history[1].Message, gc.Equals, "waiting for machine") 214 215 // Logs up to three days ago, using delta. 216 history, err = unit.StatusHistory(status.StatusHistoryFilter{Delta: &threeDaysBack}) 217 c.Assert(err, jc.ErrorIsNil) 218 c.Assert(history, gc.HasLen, 3) 219 c.Assert(history[0].Message, gc.Equals, "current status") 220 c.Assert(history[1].Message, gc.Equals, "waiting for machine") 221 c.Assert(history[2].Message, gc.Equals, "2 days ago") 222 223 // Logs up to three days ago, using date. 224 history, err = unit.StatusHistory(status.StatusHistoryFilter{Date: &threeDaysAgo}) 225 c.Assert(err, jc.ErrorIsNil) 226 c.Assert(history, gc.HasLen, 3) 227 c.Assert(history[0].Message, gc.Equals, "current status") 228 c.Assert(history[1].Message, gc.Equals, "waiting for machine") 229 c.Assert(history[2].Message, gc.Equals, "2 days ago") 230 }