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