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