]> granicus.if.org Git - icinga2/blob - test/icinga-checkresult.cpp
Merge pull request #5231 from Al2Klimov/bugfix/failure-to-kill-check-command-after...
[icinga2] / test / icinga-checkresult.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2017 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(boost::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(boost::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(boost::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(boost::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(boost::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(boost::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(boost::bind(&NotificationHandler, _1, _2));
397
398         int softStateCount = 20;
399         int timeStepInterval = 60;
400
401         Host::Ptr host = new Host();
402         host->SetMaxCheckAttempts(softStateCount);
403         host->Activate();
404         host->SetAuthority(true);
405         host->SetStateRaw(ServiceOK);
406         host->SetStateType(StateTypeHard);
407         host->SetEnableFlapping(true);
408
409         /* Initialize start time */
410         Utility::SetTime(0);
411
412         std::cout << "Before first check result (ok, hard)" << std::endl;
413         BOOST_CHECK(host->GetState() == HostUp);
414         BOOST_CHECK(host->GetStateType() == StateTypeHard);
415         BOOST_CHECK(host->GetCheckAttempt() == 1);
416
417         Utility::IncrementTime(timeStepInterval);
418
419         std::cout << "Inserting flapping check results" << std::endl;
420
421         for (int i = 0; i < softStateCount; i++) {
422                 ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
423                 host->ProcessCheckResult(MakeCheckResult(state));
424                 Utility::IncrementTime(timeStepInterval);
425         }
426
427         std::cout << "Checking host state (must be flapping in SOFT state)" << std::endl;
428         BOOST_CHECK(host->GetStateType() == StateTypeSoft);
429         BOOST_CHECK(host->IsFlapping() == true);
430
431         std::cout << "No FlappingStart notification type must have been triggered in a SOFT state" << std::endl;
432         CheckNotification(host, false, NotificationFlappingStart);
433
434         c.disconnect();
435
436 #endif /* I2_DEBUG */
437 }
438
439 BOOST_AUTO_TEST_CASE(service_flapping_notification)
440 {
441 #ifndef I2_DEBUG
442         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
443 #else /* I2_DEBUG */
444         boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2));
445
446         int softStateCount = 20;
447         int timeStepInterval = 60;
448
449         Host::Ptr service = new Host();
450         service->SetMaxCheckAttempts(softStateCount);
451         service->Activate();
452         service->SetAuthority(true);
453         service->SetStateRaw(ServiceOK);
454         service->SetStateType(StateTypeHard);
455         service->SetEnableFlapping(true);
456
457         /* Initialize start time */
458         Utility::SetTime(0);
459
460         std::cout << "Before first check result (ok, hard)" << std::endl;
461         BOOST_CHECK(service->GetState() == HostUp);
462         BOOST_CHECK(service->GetStateType() == StateTypeHard);
463         BOOST_CHECK(service->GetCheckAttempt() == 1);
464
465         Utility::IncrementTime(timeStepInterval);
466
467         std::cout << "Inserting flapping check results" << std::endl;
468
469         for (int i = 0; i < softStateCount; i++) {
470                 ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
471                 service->ProcessCheckResult(MakeCheckResult(state));
472                 Utility::IncrementTime(timeStepInterval);
473         }
474
475         std::cout << "Checking service state (must be flapping in SOFT state)" << std::endl;
476         BOOST_CHECK(service->GetStateType() == StateTypeSoft);
477         BOOST_CHECK(service->IsFlapping() == true);
478
479         std::cout << "No FlappingStart notification type must have been triggered in a SOFT state" << std::endl;
480         CheckNotification(service, false, NotificationFlappingStart);
481
482         c.disconnect();
483
484 #endif /* I2_DEBUG */
485 }
486 BOOST_AUTO_TEST_SUITE_END()