]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/insights/tests/test_health.py
5 class HealthChecksTest(unittest
.TestCase
):
6 def test_check_accum_empty(self
):
7 # health checks accum initially empty reports empty
8 h
= HealthCheckAccumulator()
9 self
.assertEqual(h
.checks(), {})
11 h
= HealthCheckAccumulator({})
12 self
.assertEqual(h
.checks(), {})
14 def _get_init_checks(self
):
15 return HealthCheckAccumulator({
18 "summary": ["s0", "s1"],
19 "detail": ("d0", "d1")
24 def test_check_init(self
):
25 # initialization with lists and tuples is OK
26 h
= self
._get
_init
_checks
()
27 self
.assertEqual(h
.checks(), {
30 "summary": set(["s0", "s1"]),
31 "detail": set(["d0", "d1"])
36 def _get_merged_checks(self
):
37 h
= self
._get
_init
_checks
()
38 h
.merge(HealthCheckAccumulator({
41 "summary": ["s0", "s1", "s2"],
45 "summary": ["s0", "s1", "s2"],
52 "detail": ("d0", "d1", "d2")
58 def test_check_merge(self
):
59 # merging combines and de-duplicates
60 h
= self
._get
_merged
_checks
()
61 self
.assertEqual(h
.checks(), {
64 "summary": set(["s0", "s1", "s2"]),
65 "detail": set(["d0", "d1", "d2"])
68 "summary": set(["s0", "s1", "s2"]),
75 "detail": set(["d0", "d1", "d2"])
80 def test_check_add_no_change(self
):
81 # returns false when nothing changes
82 h
= self
._get
_merged
_checks
()
84 self
.assertFalse(h
.add({}))
86 self
.assertFalse(h
.add({
89 "summary": { "message": "s0" },
94 self
.assertFalse(h
.add({
97 "summary": { "message": "s1" },
98 "detail": [{ "message": "d1" }]
102 self
.assertFalse(h
.add({
105 "summary": { "message": "s0" },
106 "detail": [{ "message": "d1" }, { "message": "d2" }]
110 def test_check_add_changed(self
):
111 # new checks report change
112 h
= self
._get
_merged
_checks
()
114 self
.assertTrue(h
.add({
117 "summary": { "message": "s3" },
122 self
.assertTrue(h
.add({
125 "summary": { "message": "s1" },
126 "detail": [{ "message": "d4" }]
130 self
.assertTrue(h
.add({
133 "summary": { "message": "s0" },
134 "detail": [{ "message": "d0" }]
138 self
.assertTrue(h
.add({
141 "summary": { "message": "s0" },
142 "detail": [{ "message": "d0" }, { "message": "d1" }]
146 self
.assertEqual(h
.checks(), {
149 "summary": set(["s0", "s1", "s2", "s3"]),
150 "detail": set(["d0", "d1", "d2", "d4"])
153 "summary": set(["s0", "s1", "s2"]),
157 "summary": set(["s0"]),
158 "detail": set(["d0"])
164 "detail": set(["d0", "d1", "d2"])
169 "summary": set(["s0"]),
170 "detail": set(["d0", "d1"])
175 class HealthHistoryTest(unittest
.TestCase
):
177 # return some time truncated at 30 minutes past the hour. this lets us
178 # fiddle with time offsets without worrying about accidentally landing
179 # on exactly the top of the hour which is the edge of a time slot for
180 # tracking health history.
181 dt
= datetime
.datetime
.utcnow()
182 return datetime
.datetime(
189 def test_empty_slot(self
):
192 HealthHistorySlot
._now
= mock
.Mock(return_value
=now
)
193 h
= HealthHistorySlot()
195 # reports no historical checks
196 self
.assertEqual(h
.health(), { "checks": {} })
198 # an empty slot doesn't need to be flushed
199 self
.assertFalse(h
.need_flush())
201 def test_expires(self
):
204 HealthHistorySlot
._now
= mock
.Mock(return_value
=now
)
205 h
= HealthHistorySlot()
206 self
.assertFalse(h
.expired())
208 # an hour from now it would be expired
209 future
= now
+ datetime
.timedelta(hours
= 1)
210 HealthHistorySlot
._now
= mock
.Mock(return_value
=future
)
211 self
.assertTrue(h
.expired())
213 def test_need_flush(self
):
216 HealthHistorySlot
._now
= mock
.Mock(return_value
=now
)
217 h
= HealthHistorySlot()
218 self
.assertFalse(h
.need_flush())
220 self
.assertTrue(h
.add(dict(checks
= {
223 "summary": { "message": "s0" },
224 "detail": [{ "message": "d0" }]
227 # no flush needed, yet...
228 self
.assertFalse(h
.need_flush())
230 # after persist period time elapses, a flush is needed
231 future
= now
+ PERSIST_PERIOD
232 HealthHistorySlot
._now
= mock
.Mock(return_value
=future
)
233 self
.assertTrue(h
.need_flush())
237 self
.assertFalse(h
.need_flush())
239 def test_need_flush_edge(self
):
240 # test needs flush is true because it has expired, not because it has
241 # been dirty for the persistence period
242 dt
= datetime
.datetime
.utcnow()
243 now
= datetime
.datetime(
250 HealthHistorySlot
._now
= mock
.Mock(return_value
=now
)
251 h
= HealthHistorySlot()
252 self
.assertFalse(h
.expired())
253 self
.assertFalse(h
.need_flush())
255 # now it is dirty, but it doesn't need a flush
256 self
.assertTrue(h
.add(dict(checks
= {
259 "summary": { "message": "s0" },
260 "detail": [{ "message": "d0" }]
263 self
.assertFalse(h
.expired())
264 self
.assertFalse(h
.need_flush())
266 # advance time past the hour so it expires, but not past the persistence
267 # period deadline for the last event that set the dirty bit
268 self
.assertTrue(PERSIST_PERIOD
.total_seconds() > 5)
269 future
= now
+ datetime
.timedelta(seconds
= 5)
270 HealthHistorySlot
._now
= mock
.Mock(return_value
=future
)
272 self
.assertTrue(h
.expired())
273 self
.assertTrue(h
.need_flush())