]> granicus.if.org Git - icinga2/blob - test/icinga-checkable-flapping.cpp
Merge pull request #5957 from mcktr/fix/year-2017-reference
[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() << 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
77         // Host otherwise is soft down
78         host->SetState(HostUp);
79         host->SetStateType(StateTypeHard);
80
81         Utility::SetTime(0);
82
83         BOOST_CHECK(host->GetFlappingCurrent() == 0);
84
85         LogFlapping(host);
86         LogHostStatus(host);
87
88         // watch the state being stable
89         int i = 0;
90         while (i++ < 10) {
91                 // For some reason, elusive to me, the first check is a state change
92                 host->ProcessCheckResult(MakeCheckResult(ServiceOK));
93
94                 LogFlapping(host);
95                 LogHostStatus(host);
96
97                 BOOST_CHECK(host->GetState() == 0);
98                 BOOST_CHECK(host->GetCheckAttempt() == 1);
99                 BOOST_CHECK(host->GetStateType() == StateTypeHard);
100
101                 //Should not be flapping
102                 BOOST_CHECK(!host->IsFlapping());
103                 BOOST_CHECK(host->GetFlappingCurrent() < 30.0);
104         }
105 #endif /* I2_DEBUG */
106 }
107
108 BOOST_AUTO_TEST_CASE(host_flapping)
109 {
110 #ifndef I2_DEBUG
111         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
112 #else /* I2_DEBUG */
113         std::cout << "Running test with host changing state with every check...\n";
114
115         Host::Ptr host = new Host();
116         host->SetName("test");
117         host->SetEnableFlapping(true);
118         host->SetMaxCheckAttempts(5);
119
120         Utility::SetTime(0);
121
122         int i = 0;
123         while (i++ < 25) {
124                 if (i % 2)
125                         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
126                 else
127                         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
128
129                 LogFlapping(host);
130                 LogHostStatus(host);
131
132                 //30 Percent is our high Threshold
133                 if (i >= 6) {
134                         BOOST_CHECK(host->IsFlapping());
135                 } else {
136                         BOOST_CHECK(!host->IsFlapping());
137                 }
138         }
139 #endif /* I2_DEBUG */
140 }
141
142 BOOST_AUTO_TEST_CASE(host_flapping_recover)
143 {
144 #ifndef I2_DEBUG
145         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
146 #else /* I2_DEBUG */
147         std::cout << "Running test with flapping recovery...\n";
148
149         Host::Ptr host = new Host();
150         host->SetName("test");
151         host->SetEnableFlapping(true);
152         host->SetMaxCheckAttempts(5);
153
154         // Host otherwise is soft down
155         host->SetState(HostUp);
156         host->SetStateType(StateTypeHard);
157
158         Utility::SetTime(0);
159
160         // A few warning
161         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
162         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
163         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
164         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
165
166         LogFlapping(host);
167         LogHostStatus(host);
168         for (int i = 0; i <= 7; i++) {
169                 if (i % 2)
170                         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
171                 else
172                         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
173         }
174
175         LogFlapping(host);
176         LogHostStatus(host);
177
178         // We should be flapping now
179         BOOST_CHECK(host->GetFlappingCurrent() > 30.0);
180         BOOST_CHECK(host->IsFlapping());
181
182         // Now recover from flapping
183         int count = 0;
184         while (host->IsFlapping()) {
185                 BOOST_CHECK(host->GetFlappingCurrent() > 25.0);
186                 BOOST_CHECK(host->IsFlapping());
187
188                 host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
189                 LogFlapping(host);
190                 LogHostStatus(host);
191                 count++;
192         }
193
194         std::cout << "Recovered from flapping after " << count << " Warning results.\n";
195
196         BOOST_CHECK(host->GetFlappingCurrent() < 25.0);
197         BOOST_CHECK(!host->IsFlapping());
198 #endif /* I2_DEBUG */
199 }
200
201 BOOST_AUTO_TEST_CASE(host_flapping_docs_example)
202 {
203 #ifndef I2_DEBUG
204         BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
205 #else /* I2_DEBUG */
206         std::cout << "Simulating the documentation example...\n";
207
208         Host::Ptr host = new Host();
209         host->SetName("test");
210         host->SetEnableFlapping(true);
211         host->SetMaxCheckAttempts(5);
212
213         // Host otherwise is soft down
214         host->SetState(HostUp);
215         host->SetStateType(StateTypeHard);
216
217         Utility::SetTime(0);
218
219         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
220         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
221         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
222         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
223         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
224         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
225         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
226         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
227         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
228         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
229         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
230         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
231         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
232         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
233         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
234         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
235         host->ProcessCheckResult(MakeCheckResult(ServiceOK));
236         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
237         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
238         host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
239         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
240
241         LogFlapping(host);
242         LogHostStatus(host);
243         BOOST_CHECK(host->GetFlappingCurrent() == 39.1);
244         BOOST_CHECK(host->IsFlapping());
245
246         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
247         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
248         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
249         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
250         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
251         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
252         host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
253
254         LogFlapping(host);
255         LogHostStatus(host);
256         BOOST_CHECK(host->GetFlappingCurrent() < 25.0);
257         BOOST_CHECK(!host->IsFlapping());
258 #endif
259 }
260
261 BOOST_AUTO_TEST_SUITE_END()