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