]> granicus.if.org Git - icinga2/blob - test/icinga-checkable-flapping.cpp
Merge pull request #6238 from Icinga/fix/notification-script-check-required-parameters
[icinga2] / test / icinga-checkable-flapping.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.org/)  *
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 <bitset>
22 #include <iostream>
23 #include <BoostTestTargetConfig.h>
24
25 using namespace icinga;
26
27 #ifdef I2_DEBUG
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         Utility::IncrementTime(60);
41
42         return cr;
43 }
44
45 static void LogFlapping(const Checkable::Ptr& obj)
46 {
47         std::bitset<20> stateChangeBuf = obj->GetFlappingBuffer();
48         int oldestIndex = (obj->GetFlappingBuffer() & 0xFF00000) >> 20;
49
50         std::cout << "Flapping: " << obj->IsFlapping() << "\nHT: " << obj->GetFlappingThresholdHigh() << " LT: "
51                 << obj->GetFlappingThresholdLow() << "\nOur value: " << obj->GetFlappingCurrent() << "\nPtr: " << oldestIndex
52                 << " Buf: " << stateChangeBuf.to_ulong() << '\n';
53 }
54
55
56 static void LogHostStatus(const Host::Ptr &host)
57 {
58         std::cout << "Current status: state: " << host->GetState() << " state_type: " << host->GetStateType()
59                 << " check attempt: " << host->GetCheckAttempt() << "/" << host->GetMaxCheckAttempts() << " Active: " << host->IsActive() << std::endl;
60 }
61 #endif /* I2_DEBUG */
62
63 BOOST_AUTO_TEST_SUITE(icinga_checkable_flapping)
64
65 BOOST_AUTO_TEST_CASE(host_not_flapping)
66 {
67 #ifndef I2_DEBUG
68         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
69 #else /* I2_DEBUG */
70         std::cout << "Running test with a non-flapping host...\n";
71
72         Host::Ptr host = new Host();
73         host->SetName("test");
74         host->SetEnableFlapping(true);
75         host->SetMaxCheckAttempts(5);
76         host->SetActive(true);
77
78         // Host otherwise is soft down
79         host->SetState(HostUp);
80         host->SetStateType(StateTypeHard);
81
82         Utility::SetTime(0);
83
84         BOOST_CHECK(host->GetFlappingCurrent() == 0);
85
86         LogFlapping(host);
87         LogHostStatus(host);
88
89         // watch the state being stable
90         int i = 0;
91         while (i++ < 10) {
92                 // For some reason, elusive to me, the first check is a state change
93                 host->ProcessCheckResult(MakeCheckResult(ServiceOK));
94
95                 LogFlapping(host);
96                 LogHostStatus(host);
97
98                 BOOST_CHECK(host->GetState() == 0);
99                 BOOST_CHECK(host->GetCheckAttempt() == 1);
100                 BOOST_CHECK(host->GetStateType() == StateTypeHard);
101
102                 //Should not be flapping
103                 BOOST_CHECK(!host->IsFlapping());
104                 BOOST_CHECK(host->GetFlappingCurrent() < 30.0);
105         }
106 #endif /* I2_DEBUG */
107 }
108
109 BOOST_AUTO_TEST_CASE(host_flapping)
110 {
111 #ifndef I2_DEBUG
112         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
113 #else /* I2_DEBUG */
114         std::cout << "Running test with host changing state with every check...\n";
115
116         Host::Ptr host = new Host();
117         host->SetName("test");
118         host->SetEnableFlapping(true);
119         host->SetMaxCheckAttempts(5);
120         host->SetActive(true);
121
122         Utility::SetTime(0);
123
124         int i = 0;
125         while (i++ < 25) {
126                 if (i % 2)
127                         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
128                 else
129                         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
130
131                 LogFlapping(host);
132                 LogHostStatus(host);
133
134                 //30 Percent is our high Threshold
135                 if (i >= 6) {
136                         BOOST_CHECK(host->IsFlapping());
137                 } else {
138                         BOOST_CHECK(!host->IsFlapping());
139                 }
140         }
141 #endif /* I2_DEBUG */
142 }
143
144 BOOST_AUTO_TEST_CASE(host_flapping_recover)
145 {
146 #ifndef I2_DEBUG
147         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
148 #else /* I2_DEBUG */
149         std::cout << "Running test with flapping recovery...\n";
150
151         Host::Ptr host = new Host();
152         host->SetName("test");
153         host->SetEnableFlapping(true);
154         host->SetMaxCheckAttempts(5);
155         host->SetActive(true);
156
157         // Host otherwise is soft down
158         host->SetState(HostUp);
159         host->SetStateType(StateTypeHard);
160
161         Utility::SetTime(0);
162
163         // A few warning
164         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
165         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
166         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
167         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
168
169         LogFlapping(host);
170         LogHostStatus(host);
171         for (int i = 0; i <= 7; i++) {
172                 if (i % 2)
173                         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
174                 else
175                         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
176         }
177
178         LogFlapping(host);
179         LogHostStatus(host);
180
181         // We should be flapping now
182         BOOST_CHECK(host->GetFlappingCurrent() > 30.0);
183         BOOST_CHECK(host->IsFlapping());
184
185         // Now recover from flapping
186         int count = 0;
187         while (host->IsFlapping()) {
188                 BOOST_CHECK(host->GetFlappingCurrent() > 25.0);
189                 BOOST_CHECK(host->IsFlapping());
190
191                 host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
192                 LogFlapping(host);
193                 LogHostStatus(host);
194                 count++;
195         }
196
197         std::cout << "Recovered from flapping after " << count << " Warning results.\n";
198
199         BOOST_CHECK(host->GetFlappingCurrent() < 25.0);
200         BOOST_CHECK(!host->IsFlapping());
201 #endif /* I2_DEBUG */
202 }
203
204 BOOST_AUTO_TEST_CASE(host_flapping_docs_example)
205 {
206 #ifndef I2_DEBUG
207         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
208 #else /* I2_DEBUG */
209         std::cout << "Simulating the documentation example...\n";
210
211         Host::Ptr host = new Host();
212         host->SetName("test");
213         host->SetEnableFlapping(true);
214         host->SetMaxCheckAttempts(5);
215         host->SetActive(true);
216
217         // Host otherwise is soft down
218         host->SetState(HostUp);
219         host->SetStateType(StateTypeHard);
220
221         Utility::SetTime(0);
222
223         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
224         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
225         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
226         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
227         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
228         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
229         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
230         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
231         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
232         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
233         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
234         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
235         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
236         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
237         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
238         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
239         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
240         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
241         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
242         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
243         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
244
245         LogFlapping(host);
246         LogHostStatus(host);
247         BOOST_CHECK(host->GetFlappingCurrent() == 39.1);
248         BOOST_CHECK(host->IsFlapping());
249
250         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
251         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
252         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
253         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
254         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
255         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
256         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
257
258         LogFlapping(host);
259         LogHostStatus(host);
260         BOOST_CHECK(host->GetFlappingCurrent() < 25.0);
261         BOOST_CHECK(!host->IsFlapping());
262 #endif
263 }
264
265 BOOST_AUTO_TEST_SUITE_END()