]> granicus.if.org Git - icinga2/blob - test/icinga-checkresult.cpp
Merge pull request #7002 from Icinga/bugfix/check_network-percent-6155
[icinga2] / test / icinga-checkresult.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #include "icinga/host.hpp"
4 #include <BoostTestTargetConfig.h>
5 #include <iostream>
6
7 using namespace icinga;
8
9 BOOST_AUTO_TEST_SUITE(icinga_checkresult)
10
11 static CheckResult::Ptr MakeCheckResult(ServiceState state)
12 {
13         CheckResult::Ptr cr = new CheckResult();
14
15         cr->SetState(state);
16
17         double now = Utility::GetTime();
18         cr->SetScheduleStart(now);
19         cr->SetScheduleEnd(now);
20         cr->SetExecutionStart(now);
21         cr->SetExecutionEnd(now);
22
23         return cr;
24 }
25
26 static void NotificationHandler(const Checkable::Ptr& checkable, NotificationType type)
27 {
28         std::cout << "Notification triggered: " << Notification::NotificationTypeToString(type) << std::endl;
29
30         checkable->SetExtension("requested_notifications", true);
31         checkable->SetExtension("notification_type", type);
32 }
33
34 static void CheckNotification(const Checkable::Ptr& checkable, bool expected, NotificationType type = NotificationRecovery)
35 {
36         BOOST_CHECK((expected && checkable->GetExtension("requested_notifications").ToBool()) || (!expected && !checkable->GetExtension("requested_notifications").ToBool()));
37
38         if (expected && checkable->GetExtension("requested_notifications").ToBool())
39                 BOOST_CHECK(checkable->GetExtension("notification_type") == type);
40
41         checkable->SetExtension("requested_notifications", false);
42 }
43
44 BOOST_AUTO_TEST_CASE(host_1attempt)
45 {
46         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
47
48         Host::Ptr host = new Host();
49         host->SetActive(true);
50         host->SetMaxCheckAttempts(1);
51         host->Activate();
52         host->SetAuthority(true);
53         host->SetStateRaw(ServiceOK);
54         host->SetStateType(StateTypeHard);
55
56         std::cout << "Before first check result (ok, hard)" << std::endl;
57         BOOST_CHECK(host->GetState() == HostUp);
58         BOOST_CHECK(host->GetStateType() == StateTypeHard);
59         BOOST_CHECK(host->GetCheckAttempt() == 1);
60         CheckNotification(host, false);
61
62         std::cout << "First check result (unknown)" << std::endl;
63         host->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
64         BOOST_CHECK(host->GetState() == HostDown);
65         BOOST_CHECK(host->GetStateType() == StateTypeHard);
66         BOOST_CHECK(host->GetCheckAttempt() == 1);
67         CheckNotification(host, true, NotificationProblem);
68
69         std::cout << "Second check result (ok)" << std::endl;
70         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
71         BOOST_CHECK(host->GetState() == HostUp);
72         BOOST_CHECK(host->GetStateType() == StateTypeHard);
73         BOOST_CHECK(host->GetCheckAttempt() == 1);
74         CheckNotification(host, true, NotificationRecovery);
75
76         std::cout << "Third check result (critical)" << std::endl;
77         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
78         BOOST_CHECK(host->GetState() == HostDown);
79         BOOST_CHECK(host->GetStateType() == StateTypeHard);
80         BOOST_CHECK(host->GetCheckAttempt() == 1);
81         CheckNotification(host, true, NotificationProblem);
82
83         std::cout << "Fourth check result (ok)" << std::endl;
84         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
85         BOOST_CHECK(host->GetState() == HostUp);
86         BOOST_CHECK(host->GetStateType() == StateTypeHard);
87         BOOST_CHECK(host->GetCheckAttempt() == 1);
88         CheckNotification(host, true, NotificationRecovery);
89
90         c.disconnect();
91 }
92
93 BOOST_AUTO_TEST_CASE(host_2attempts)
94 {
95         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
96
97         Host::Ptr host = new Host();
98         host->SetActive(true);
99         host->SetMaxCheckAttempts(2);
100         host->Activate();
101         host->SetAuthority(true);
102         host->SetStateRaw(ServiceOK);
103         host->SetStateType(StateTypeHard);
104
105         std::cout << "Before first check result (ok, hard)" << std::endl;
106         BOOST_CHECK(host->GetState() == HostUp);
107         BOOST_CHECK(host->GetStateType() == StateTypeHard);
108         BOOST_CHECK(host->GetCheckAttempt() == 1);
109         CheckNotification(host, false);
110
111         std::cout << "First check result (unknown)" << std::endl;
112         host->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
113         BOOST_CHECK(host->GetState() == HostDown);
114         BOOST_CHECK(host->GetStateType() == StateTypeSoft);
115         BOOST_CHECK(host->GetCheckAttempt() == 1);
116         CheckNotification(host, false);
117
118         std::cout << "Second check result (critical)" << std::endl;
119         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
120         BOOST_CHECK(host->GetState() == HostDown);
121         BOOST_CHECK(host->GetStateType() == StateTypeHard);
122         BOOST_CHECK(host->GetCheckAttempt() == 1);
123         CheckNotification(host, true, NotificationProblem);
124
125         std::cout << "Third check result (ok)" << std::endl;
126         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
127         BOOST_CHECK(host->GetState() == HostUp);
128         BOOST_CHECK(host->GetStateType() == StateTypeHard);
129         BOOST_CHECK(host->GetCheckAttempt() == 1);
130         CheckNotification(host, true, NotificationRecovery);
131
132         std::cout << "Fourth check result (critical)" << std::endl;
133         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
134         BOOST_CHECK(host->GetState() == HostDown);
135         BOOST_CHECK(host->GetStateType() == StateTypeSoft);
136         BOOST_CHECK(host->GetCheckAttempt() == 1);
137         CheckNotification(host, false);
138
139         std::cout << "Fifth check result (ok)" << std::endl;
140         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
141         BOOST_CHECK(host->GetState() == HostUp);
142         BOOST_CHECK(host->GetStateType() == StateTypeHard);
143         BOOST_CHECK(host->GetCheckAttempt() == 1);
144         CheckNotification(host, false);
145
146         c.disconnect();
147 }
148
149 BOOST_AUTO_TEST_CASE(host_3attempts)
150 {
151         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
152
153         Host::Ptr host = new Host();
154         host->SetActive(true);
155         host->SetMaxCheckAttempts(3);
156         host->Activate();
157         host->SetAuthority(true);
158         host->SetStateRaw(ServiceOK);
159         host->SetStateType(StateTypeHard);
160
161         std::cout << "Before first check result (ok, hard)" << std::endl;
162         BOOST_CHECK(host->GetState() == HostUp);
163         BOOST_CHECK(host->GetStateType() == StateTypeHard);
164         BOOST_CHECK(host->GetCheckAttempt() == 1);
165         CheckNotification(host, false);
166
167         std::cout << "First check result (unknown)" << std::endl;
168         host->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
169         BOOST_CHECK(host->GetState() == HostDown);
170         BOOST_CHECK(host->GetStateType() == StateTypeSoft);
171         BOOST_CHECK(host->GetCheckAttempt() == 1);
172         CheckNotification(host, false);
173
174         std::cout << "Second check result (critical)" << std::endl;
175         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
176         BOOST_CHECK(host->GetState() == HostDown);
177         BOOST_CHECK(host->GetStateType() == StateTypeSoft);
178         BOOST_CHECK(host->GetCheckAttempt() == 2);
179         CheckNotification(host, false);
180
181         std::cout << "Third check result (critical)" << std::endl;
182         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
183         BOOST_CHECK(host->GetState() == HostDown);
184         BOOST_CHECK(host->GetStateType() == StateTypeHard);
185         BOOST_CHECK(host->GetCheckAttempt() == 1);
186         CheckNotification(host, true, NotificationProblem);
187
188         std::cout << "Fourth check result (ok)" << std::endl;
189         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
190         BOOST_CHECK(host->GetState() == HostUp);
191         BOOST_CHECK(host->GetStateType() == StateTypeHard);
192         BOOST_CHECK(host->GetCheckAttempt() == 1);
193         CheckNotification(host, true, NotificationRecovery);
194
195         std::cout << "Fifth check result (critical)" << std::endl;
196         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
197         BOOST_CHECK(host->GetState() == HostDown);
198         BOOST_CHECK(host->GetStateType() == StateTypeSoft);
199         BOOST_CHECK(host->GetCheckAttempt() == 1);
200         CheckNotification(host, false);
201
202         std::cout << "Sixth check result (ok)" << std::endl;
203         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
204         BOOST_CHECK(host->GetState() == HostUp);
205         BOOST_CHECK(host->GetStateType() == StateTypeHard);
206         BOOST_CHECK(host->GetCheckAttempt() == 1);
207         CheckNotification(host, false);
208
209         c.disconnect();
210 }
211
212 BOOST_AUTO_TEST_CASE(service_1attempt)
213 {
214         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
215
216         Service::Ptr service = new Service();
217         service->SetActive(true);
218         service->SetMaxCheckAttempts(1);
219         service->Activate();
220         service->SetAuthority(true);
221         service->SetStateRaw(ServiceOK);
222         service->SetStateType(StateTypeHard);
223
224         std::cout << "Before first check result (ok, hard)" << std::endl;
225         BOOST_CHECK(service->GetState() == ServiceOK);
226         BOOST_CHECK(service->GetStateType() == StateTypeHard);
227         BOOST_CHECK(service->GetCheckAttempt() == 1);
228         CheckNotification(service, false);
229
230         std::cout << "First check result (unknown)" << std::endl;
231         service->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
232         BOOST_CHECK(service->GetState() == ServiceUnknown);
233         BOOST_CHECK(service->GetStateType() == StateTypeHard);
234         BOOST_CHECK(service->GetCheckAttempt() == 1);
235         CheckNotification(service, true, NotificationProblem);
236
237         std::cout << "Second check result (ok)" << std::endl;
238         service->ProcessCheckResult(MakeCheckResult(ServiceOK));
239         BOOST_CHECK(service->GetState() == ServiceOK);
240         BOOST_CHECK(service->GetStateType() == StateTypeHard);
241         BOOST_CHECK(service->GetCheckAttempt() == 1);
242         CheckNotification(service, true, NotificationRecovery);
243
244         std::cout << "Third check result (critical)" << std::endl;
245         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
246         BOOST_CHECK(service->GetState() == ServiceCritical);
247         BOOST_CHECK(service->GetStateType() == StateTypeHard);
248         BOOST_CHECK(service->GetCheckAttempt() == 1);
249         CheckNotification(service, true, NotificationProblem);
250
251         std::cout << "Fourth check result (ok)" << std::endl;
252         service->ProcessCheckResult(MakeCheckResult(ServiceOK));
253         BOOST_CHECK(service->GetState() == ServiceOK);
254         BOOST_CHECK(service->GetStateType() == StateTypeHard);
255         BOOST_CHECK(service->GetCheckAttempt() == 1);
256         CheckNotification(service, true, NotificationRecovery);
257
258         c.disconnect();
259 }
260
261 BOOST_AUTO_TEST_CASE(service_2attempts)
262 {
263         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
264
265         Service::Ptr service = new Service();
266         service->SetActive(true);
267         service->SetMaxCheckAttempts(2);
268         service->Activate();
269         service->SetAuthority(true);
270         service->SetStateRaw(ServiceOK);
271         service->SetStateType(StateTypeHard);
272
273         std::cout << "Before first check result (ok, hard)" << std::endl;
274         BOOST_CHECK(service->GetState() == ServiceOK);
275         BOOST_CHECK(service->GetStateType() == StateTypeHard);
276         BOOST_CHECK(service->GetCheckAttempt() == 1);
277         CheckNotification(service, false);
278
279         std::cout << "First check result (unknown)" << std::endl;
280         service->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
281         BOOST_CHECK(service->GetState() == ServiceUnknown);
282         BOOST_CHECK(service->GetStateType() == StateTypeSoft);
283         BOOST_CHECK(service->GetCheckAttempt() == 1);
284         CheckNotification(service, false);
285
286         std::cout << "Second check result (critical)" << std::endl;
287         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
288         BOOST_CHECK(service->GetState() == ServiceCritical);
289         BOOST_CHECK(service->GetStateType() == StateTypeHard);
290         BOOST_CHECK(service->GetCheckAttempt() == 1);
291         CheckNotification(service, true, NotificationProblem);
292
293         std::cout << "Third check result (ok)" << std::endl;
294         service->ProcessCheckResult(MakeCheckResult(ServiceOK));
295         BOOST_CHECK(service->GetState() == ServiceOK);
296         BOOST_CHECK(service->GetStateType() == StateTypeHard);
297         BOOST_CHECK(service->GetCheckAttempt() == 1);
298         CheckNotification(service, true, NotificationRecovery);
299
300         std::cout << "Fourth check result (critical)" << std::endl;
301         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
302         BOOST_CHECK(service->GetState() == ServiceCritical);
303         BOOST_CHECK(service->GetStateType() == StateTypeSoft);
304         BOOST_CHECK(service->GetCheckAttempt() == 1);
305         CheckNotification(service, false);
306
307         std::cout << "Fifth check result (ok)" << std::endl;
308         service->ProcessCheckResult(MakeCheckResult(ServiceOK));
309         BOOST_CHECK(service->GetState() == ServiceOK);
310         BOOST_CHECK(service->GetStateType() == StateTypeHard);
311         BOOST_CHECK(service->GetCheckAttempt() == 1);
312         CheckNotification(service, false);
313
314         c.disconnect();
315 }
316
317 BOOST_AUTO_TEST_CASE(service_3attempts)
318 {
319         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
320
321         Service::Ptr service = new Service();
322         service->SetActive(true);
323         service->SetMaxCheckAttempts(3);
324         service->Activate();
325         service->SetAuthority(true);
326         service->SetStateRaw(ServiceOK);
327         service->SetStateType(StateTypeHard);
328
329         std::cout << "Before first check result (ok, hard)" << std::endl;
330         BOOST_CHECK(service->GetState() == ServiceOK);
331         BOOST_CHECK(service->GetStateType() == StateTypeHard);
332         BOOST_CHECK(service->GetCheckAttempt() == 1);
333         CheckNotification(service, false);
334
335         std::cout << "First check result (unknown)" << std::endl;
336         service->ProcessCheckResult(MakeCheckResult(ServiceUnknown));
337         BOOST_CHECK(service->GetState() == ServiceUnknown);
338         BOOST_CHECK(service->GetStateType() == StateTypeSoft);
339         BOOST_CHECK(service->GetCheckAttempt() == 1);
340         CheckNotification(service, false);
341
342         std::cout << "Second check result (critical)" << std::endl;
343         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
344         BOOST_CHECK(service->GetState() == ServiceCritical);
345         BOOST_CHECK(service->GetStateType() == StateTypeSoft);
346         BOOST_CHECK(service->GetCheckAttempt() == 2);
347         CheckNotification(service, false);
348
349         std::cout << "Third check result (critical)" << std::endl;
350         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
351         BOOST_CHECK(service->GetState() == ServiceCritical);
352         BOOST_CHECK(service->GetStateType() == StateTypeHard);
353         BOOST_CHECK(service->GetCheckAttempt() == 1);
354         CheckNotification(service, true, NotificationProblem);
355
356         std::cout << "Fourth check result (ok)" << std::endl;
357         service->ProcessCheckResult(MakeCheckResult(ServiceOK));
358         BOOST_CHECK(service->GetState() == ServiceOK);
359         BOOST_CHECK(service->GetStateType() == StateTypeHard);
360         BOOST_CHECK(service->GetCheckAttempt() == 1);
361         CheckNotification(service, true, NotificationRecovery);
362
363         std::cout << "Fifth check result (critical)" << std::endl;
364         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
365         BOOST_CHECK(service->GetState() == ServiceCritical);
366         BOOST_CHECK(service->GetStateType() == StateTypeSoft);
367         BOOST_CHECK(service->GetCheckAttempt() == 1);
368         CheckNotification(service, false);
369
370         std::cout << "Sixth check result (ok)" << std::endl;
371         service->ProcessCheckResult(MakeCheckResult(ServiceOK));
372         BOOST_CHECK(service->GetState() == ServiceOK);
373         BOOST_CHECK(service->GetStateType() == StateTypeHard);
374         BOOST_CHECK(service->GetCheckAttempt() == 1);
375         CheckNotification(service, false);
376
377         c.disconnect();
378 }
379
380 BOOST_AUTO_TEST_CASE(host_flapping_notification)
381 {
382 #ifndef I2_DEBUG
383         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
384 #else /* I2_DEBUG */
385         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
386
387         int timeStepInterval = 60;
388
389         Host::Ptr host = new Host();
390         host->SetActive(true);
391         host->Activate();
392         host->SetAuthority(true);
393         host->SetStateRaw(ServiceOK);
394         host->SetStateType(StateTypeHard);
395         host->SetEnableFlapping(true);
396
397         /* Initialize start time */
398         Utility::SetTime(0);
399
400         std::cout << "Before first check result (ok, hard)" << std::endl;
401         BOOST_CHECK(host->GetState() == HostUp);
402         BOOST_CHECK(host->GetStateType() == StateTypeHard);
403         BOOST_CHECK(host->GetCheckAttempt() == 1);
404
405         Utility::IncrementTime(timeStepInterval);
406
407         std::cout << "Inserting flapping check results" << std::endl;
408
409         for (int i = 0; i < 10; i++) {
410                 ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
411                 host->ProcessCheckResult(MakeCheckResult(state));
412                 Utility::IncrementTime(timeStepInterval);
413         }
414
415         BOOST_CHECK(host->IsFlapping() == true);
416
417         CheckNotification(host, true, NotificationFlappingStart);
418
419         std::cout << "Now calm down..." << std::endl;
420
421         for (int i = 0; i < 20; i++) {
422                 host->ProcessCheckResult(MakeCheckResult(ServiceOK));
423                 Utility::IncrementTime(timeStepInterval);
424         }
425
426         CheckNotification(host, true, NotificationFlappingEnd);
427
428
429         c.disconnect();
430
431 #endif /* I2_DEBUG */
432 }
433
434 BOOST_AUTO_TEST_CASE(service_flapping_notification)
435 {
436 #ifndef I2_DEBUG
437         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
438 #else /* I2_DEBUG */
439         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
440
441         int timeStepInterval = 60;
442
443         Service::Ptr service = new Service();
444         service->SetActive(true);
445         service->Activate();
446         service->SetAuthority(true);
447         service->SetStateRaw(ServiceOK);
448         service->SetStateType(StateTypeHard);
449         service->SetEnableFlapping(true);
450
451         /* Initialize start time */
452         Utility::SetTime(0);
453
454         std::cout << "Before first check result (ok, hard)" << std::endl;
455         BOOST_CHECK(service->GetState() == ServiceOK);
456         BOOST_CHECK(service->GetStateType() == StateTypeHard);
457         BOOST_CHECK(service->GetCheckAttempt() == 1);
458
459         Utility::IncrementTime(timeStepInterval);
460
461         std::cout << "Inserting flapping check results" << std::endl;
462
463         for (int i = 0; i < 10; i++) {
464                 ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
465                 service->ProcessCheckResult(MakeCheckResult(state));
466                 Utility::IncrementTime(timeStepInterval);
467         }
468
469         BOOST_CHECK(service->IsFlapping() == true);
470
471         CheckNotification(service, true, NotificationFlappingStart);
472
473
474
475         std::cout << "Now calm down..." << std::endl;
476
477         for (int i = 0; i < 20; i++) {
478                 service->ProcessCheckResult(MakeCheckResult(ServiceOK));
479                 Utility::IncrementTime(timeStepInterval);
480         }
481
482         CheckNotification(service, true, NotificationFlappingEnd);
483
484         c.disconnect();
485
486 #endif /* I2_DEBUG */
487 }
488
489 BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications)
490 {
491 #ifndef I2_DEBUG
492         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
493 #else /* I2_DEBUG */
494         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
495
496         int timeStepInterval = 60;
497
498         Service::Ptr service = new Service();
499         service->Activate();
500         service->SetAuthority(true);
501         service->SetStateRaw(ServiceOK);
502         service->SetStateType(StateTypeHard);
503         service->SetEnableFlapping(true);
504         service->SetMaxCheckAttempts(3);
505
506         /* Initialize start time */
507         Utility::SetTime(0);
508
509         std::cout << "Before first check result (ok, hard)" << std::endl;
510         BOOST_CHECK(service->GetState() == ServiceOK);
511         BOOST_CHECK(service->GetStateType() == StateTypeHard);
512         BOOST_CHECK(service->GetCheckAttempt() == 1);
513
514         Utility::IncrementTime(timeStepInterval);
515
516         std::cout << "Inserting flapping check results" << std::endl;
517
518         for (int i = 0; i < 10; i++) {
519                 ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
520                 service->ProcessCheckResult(MakeCheckResult(state));
521                 Utility::IncrementTime(timeStepInterval);
522         }
523
524         BOOST_CHECK(service->IsFlapping() == true);
525
526         CheckNotification(service, true, NotificationFlappingStart);
527
528         //Insert enough check results to get into hard problem state but staying flapping
529
530         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
531         Utility::IncrementTime(timeStepInterval);
532         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
533         Utility::IncrementTime(timeStepInterval);
534         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
535         Utility::IncrementTime(timeStepInterval);
536
537
538         BOOST_CHECK(service->IsFlapping() == true);
539         BOOST_CHECK(service->GetStateType() == StateTypeHard);
540         BOOST_CHECK(service->GetState() == ServiceCritical);
541
542         CheckNotification(service, false, NotificationProblem);
543
544         // Calm down
545         while (service->IsFlapping()) {
546                 service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
547                 Utility::IncrementTime(timeStepInterval);
548         }
549
550         CheckNotification(service, true, NotificationFlappingEnd);
551
552         /* Intended behaviour is a Problem notification being sent as well, but there are is a Problem:
553          * We don't know whether the Object was Critical before we started flapping and sent out a Notification.
554          * A notification will not be sent, no matter how many criticals follow.
555          *
556          * service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
557          * CheckNotification(service, true, NotificationProblem);
558          * ^ This fails, no notification will be sent
559          *
560          * There is also a different issue, when we receive a OK check result, a Recovery Notification will be sent
561          * since the service went from hard critical into soft ok. Yet there is no fitting critical notification.
562          * This should not happen:
563          *
564          * service->ProcessCheckResult(MakeCheckResult(ServiceOK));
565          * CheckNotification(service, false, NotificationRecovery);
566          * ^ This fails, recovery is sent
567          */
568
569         BOOST_CHECK(service->IsFlapping() == false);
570         BOOST_CHECK(service->GetStateType() == StateTypeHard);
571         BOOST_CHECK(service->GetState() == ServiceCritical);
572
573         // Known failure, see #5713
574         // CheckNotification(service, true, NotificationProblem);
575
576         service->ProcessCheckResult(MakeCheckResult(ServiceOK));
577         Utility::IncrementTime(timeStepInterval);
578
579         // Known failure, see #5713
580         // CheckNotification(service, true, NotificationRecovery);
581
582         c.disconnect();
583
584 #endif /* I2_DEBUG */
585 }
586
587 BOOST_AUTO_TEST_CASE(service_flapping_ok_into_bad)
588 {
589 #ifndef I2_DEBUG
590         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
591 #else /* I2_DEBUG */
592         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
593
594         int timeStepInterval = 60;
595
596         Service::Ptr service = new Service();
597         service->Activate();
598         service->SetAuthority(true);
599         service->SetStateRaw(ServiceOK);
600         service->SetStateType(StateTypeHard);
601         service->SetEnableFlapping(true);
602         service->SetMaxCheckAttempts(3);
603
604         /* Initialize start time */
605         Utility::SetTime(0);
606
607         std::cout << "Before first check result (ok, hard)" << std::endl;
608         BOOST_CHECK(service->GetState() == ServiceOK);
609         BOOST_CHECK(service->GetStateType() == StateTypeHard);
610         BOOST_CHECK(service->GetCheckAttempt() == 1);
611
612         Utility::IncrementTime(timeStepInterval);
613
614         std::cout << "Inserting flapping check results" << std::endl;
615
616         for (int i = 0; i < 10; i++) {
617                 ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
618                 service->ProcessCheckResult(MakeCheckResult(state));
619                 Utility::IncrementTime(timeStepInterval);
620         }
621
622         BOOST_CHECK(service->IsFlapping() == true);
623
624         CheckNotification(service, true, NotificationFlappingStart);
625
626         //Insert enough check results to get into hard problem state but staying flapping
627
628         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
629         Utility::IncrementTime(timeStepInterval);
630         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
631         Utility::IncrementTime(timeStepInterval);
632         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
633         Utility::IncrementTime(timeStepInterval);
634
635
636         BOOST_CHECK(service->IsFlapping() == true);
637         BOOST_CHECK(service->GetStateType() == StateTypeHard);
638         BOOST_CHECK(service->GetState() == ServiceCritical);
639
640         CheckNotification(service, false, NotificationProblem);
641
642         // Calm down
643         while (service->IsFlapping()) {
644                 service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
645                 Utility::IncrementTime(timeStepInterval);
646         }
647
648         CheckNotification(service, true, NotificationFlappingEnd);
649
650         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
651         Utility::IncrementTime(timeStepInterval);
652
653         BOOST_CHECK(service->IsFlapping() == false);
654         BOOST_CHECK(service->GetStateType() == StateTypeHard);
655         BOOST_CHECK(service->GetState() == ServiceCritical);
656
657         // We expect a problem notification here
658         // Known failure, see #5713
659         // CheckNotification(service, true, NotificationProblem);
660
661         c.disconnect();
662
663 #endif /* I2_DEBUG */
664 }
665 BOOST_AUTO_TEST_CASE(service_flapping_ok_over_bad_into_ok)
666 {
667 #ifndef I2_DEBUG
668         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
669 #else /* I2_DEBUG */
670         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2));
671
672         int timeStepInterval = 60;
673
674         Service::Ptr service = new Service();
675         service->Activate();
676         service->SetAuthority(true);
677         service->SetStateRaw(ServiceOK);
678         service->SetStateType(StateTypeHard);
679         service->SetEnableFlapping(true);
680         service->SetMaxCheckAttempts(3);
681
682         /* Initialize start time */
683         Utility::SetTime(0);
684
685         std::cout << "Before first check result (ok, hard)" << std::endl;
686         BOOST_CHECK(service->GetState() == ServiceOK);
687         BOOST_CHECK(service->GetStateType() == StateTypeHard);
688         BOOST_CHECK(service->GetCheckAttempt() == 1);
689
690         Utility::IncrementTime(timeStepInterval);
691
692         std::cout << "Inserting flapping check results" << std::endl;
693
694         for (int i = 0; i < 10; i++) {
695                 ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
696                 service->ProcessCheckResult(MakeCheckResult(state));
697                 Utility::IncrementTime(timeStepInterval);
698         }
699
700         BOOST_CHECK(service->IsFlapping() == true);
701
702         CheckNotification(service, true, NotificationFlappingStart);
703
704         //Insert enough check results to get into hard problem state but staying flapping
705
706         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
707         Utility::IncrementTime(timeStepInterval);
708         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
709         Utility::IncrementTime(timeStepInterval);
710         service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
711         Utility::IncrementTime(timeStepInterval);
712
713
714         BOOST_CHECK(service->IsFlapping() == true);
715         BOOST_CHECK(service->GetStateType() == StateTypeHard);
716         BOOST_CHECK(service->GetState() == ServiceCritical);
717
718         CheckNotification(service, false, NotificationProblem);
719
720         // Calm down
721         while (service->IsFlapping()) {
722                 service->ProcessCheckResult(MakeCheckResult(ServiceCritical));
723                 Utility::IncrementTime(timeStepInterval);
724         }
725
726         CheckNotification(service, true, NotificationFlappingEnd);
727
728         service->ProcessCheckResult(MakeCheckResult(ServiceOK));
729         Utility::IncrementTime(timeStepInterval);
730
731         BOOST_CHECK(service->IsFlapping() == false);
732         BOOST_CHECK(service->GetStateType() == StateTypeHard);
733         BOOST_CHECK(service->GetState() == ServiceOK);
734
735         // There should be no recovery
736         // Known failure, see #5713
737         // CheckNotification(service, false, NotificationRecovery);
738
739         c.disconnect();
740
741 #endif /* I2_DEBUG */
742 }
743 BOOST_AUTO_TEST_SUITE_END()