1 /******************************************************************************
3 * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.org/) *
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. *
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. *
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 ******************************************************************************/
20 #include "icinga/host.hpp"
23 #include <BoostTestTargetConfig.h>
25 using namespace icinga;
28 static CheckResult::Ptr MakeCheckResult(ServiceState state)
30 CheckResult::Ptr cr = new CheckResult();
34 double now = Utility::GetTime();
35 cr->SetScheduleStart(now);
36 cr->SetScheduleEnd(now);
37 cr->SetExecutionStart(now);
38 cr->SetExecutionEnd(now);
40 Utility::IncrementTime(60);
45 static void LogFlapping(const Checkable::Ptr& obj)
47 std::bitset<20> stateChangeBuf = obj->GetFlappingBuffer();
48 int oldestIndex = (obj->GetFlappingBuffer() & 0xFF00000) >> 20;
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';
56 static void LogHostStatus(const Host::Ptr &host)
58 std::cout << "Current status: state: " << host->GetState() << " state_type: " << host->GetStateType()
59 << " check attempt: " << host->GetCheckAttempt() << "/" << host->GetMaxCheckAttempts() << " Active: " << host->IsActive() << std::endl;
63 BOOST_AUTO_TEST_SUITE(icinga_checkable_flapping)
65 BOOST_AUTO_TEST_CASE(host_not_flapping)
68 BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
70 std::cout << "Running test with a non-flapping host...\n";
72 Host::Ptr host = new Host();
73 host->SetName("test");
74 host->SetEnableFlapping(true);
75 host->SetMaxCheckAttempts(5);
76 host->SetActive(true);
78 // Host otherwise is soft down
79 host->SetState(HostUp);
80 host->SetStateType(StateTypeHard);
84 BOOST_CHECK(host->GetFlappingCurrent() == 0);
89 // watch the state being stable
92 // For some reason, elusive to me, the first check is a state change
93 host->ProcessCheckResult(MakeCheckResult(ServiceOK));
98 BOOST_CHECK(host->GetState() == 0);
99 BOOST_CHECK(host->GetCheckAttempt() == 1);
100 BOOST_CHECK(host->GetStateType() == StateTypeHard);
102 //Should not be flapping
103 BOOST_CHECK(!host->IsFlapping());
104 BOOST_CHECK(host->GetFlappingCurrent() < 30.0);
106 #endif /* I2_DEBUG */
109 BOOST_AUTO_TEST_CASE(host_flapping)
112 BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
114 std::cout << "Running test with host changing state with every check...\n";
116 Host::Ptr host = new Host();
117 host->SetName("test");
118 host->SetEnableFlapping(true);
119 host->SetMaxCheckAttempts(5);
120 host->SetActive(true);
127 host->ProcessCheckResult(MakeCheckResult(ServiceOK));
129 host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
134 //30 Percent is our high Threshold
136 BOOST_CHECK(host->IsFlapping());
138 BOOST_CHECK(!host->IsFlapping());
141 #endif /* I2_DEBUG */
144 BOOST_AUTO_TEST_CASE(host_flapping_recover)
147 BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
149 std::cout << "Running test with flapping recovery...\n";
151 Host::Ptr host = new Host();
152 host->SetName("test");
153 host->SetEnableFlapping(true);
154 host->SetMaxCheckAttempts(5);
155 host->SetActive(true);
157 // Host otherwise is soft down
158 host->SetState(HostUp);
159 host->SetStateType(StateTypeHard);
164 host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
165 host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
166 host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
167 host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
171 for (int i = 0; i <= 7; i++) {
173 host->ProcessCheckResult(MakeCheckResult(ServiceOK));
175 host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
181 // We should be flapping now
182 BOOST_CHECK(host->GetFlappingCurrent() > 30.0);
183 BOOST_CHECK(host->IsFlapping());
185 // Now recover from flapping
187 while (host->IsFlapping()) {
188 BOOST_CHECK(host->GetFlappingCurrent() > 25.0);
189 BOOST_CHECK(host->IsFlapping());
191 host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
197 std::cout << "Recovered from flapping after " << count << " Warning results.\n";
199 BOOST_CHECK(host->GetFlappingCurrent() < 25.0);
200 BOOST_CHECK(!host->IsFlapping());
201 #endif /* I2_DEBUG */
204 BOOST_AUTO_TEST_CASE(host_flapping_docs_example)
207 BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
209 std::cout << "Simulating the documentation example...\n";
211 Host::Ptr host = new Host();
212 host->SetName("test");
213 host->SetEnableFlapping(true);
214 host->SetMaxCheckAttempts(5);
215 host->SetActive(true);
217 // Host otherwise is soft down
218 host->SetState(HostUp);
219 host->SetStateType(StateTypeHard);
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));
247 BOOST_CHECK(host->GetFlappingCurrent() == 39.1);
248 BOOST_CHECK(host->IsFlapping());
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));
260 BOOST_CHECK(host->GetFlappingCurrent() < 25.0);
261 BOOST_CHECK(!host->IsFlapping());
265 BOOST_AUTO_TEST_SUITE_END()