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