5 #include <nagios/objects.h>
6 #include <nagios/comments.h>
8 squeue_t
*nagios_squeue
;
9 struct object_count num_objects
= {0,};
10 comment
*comment_list
= NULL
;
11 hostgroup
*hostgroup_list
= NULL
;
12 struct timeperiod
**timeperiod_ary
;
13 struct host
**host_ary
;
14 char *config_file_dir
= NULL
;
15 char *config_file
= NULL
;
16 char *temp_path
= NULL
;
17 iobroker_set
*nagios_iobs
= NULL
;
18 int __nagios_object_structure_version
= CURRENT_OBJECT_STRUCTURE_VERSION
;
19 unsigned long event_broker_options
= BROKER_NOTHING
;
20 int sigshutdown
= FALSE
;
21 int interval_length
= 60;
22 time_t event_start
= 0L;
23 int service_check_timeout
= 0;
24 int host_check_timeout
= 0;
26 int process_check_result(check_result
*cr
){ return 0; }
27 struct host
*find_host(const char *name
) { return NULL
; }
28 struct hostgroup
*find_hostgroup(const char *name
) { return NULL
; }
29 struct service
*find_service(const char *host_name
, const char *service_description
) { return NULL
; }
30 struct comment
*get_first_comment_by_host(char *host
) { return NULL
; }
31 int delete_comment(int type
, unsigned long comment_id
) { return 0; }
32 int delete_downtime_by_hostname_service_description_start_time_comment(char *hostname
, char *service_description
, time_t start_time
, char *cmnt
) { return 0; }
33 int init_check_result(check_result
*cr
) { return 0; }
34 int process_external_command2(int cmd
, time_t entry_time
, char *args
) { return 0; }
35 int add_new_comment(int type
, int entry_type
, char *host_name
, char *svc_description
, time_t entry_time
, char *author_name
, char *comment_data
, int persistent
, int source
, int expires
, time_t expire_time
, unsigned long *comment_id
) { return 0; }
36 timed_event
*schedule_new_event(int event_type
, int high_priority
, time_t run_time
, int recurring
, unsigned long event_interval
, void *timing_func
, int compensate_for_time_change
, void *event_data
, void *event_args
, int event_options
) {
37 timed_event
*evt
= calloc(1, sizeof(timed_event
));
38 evt
->event_args
= event_args
;
41 nagios_macros
*get_global_macros() { return NULL
; }
42 void fcache_timeperiod(FILE *fp
, struct timeperiod
*temp_timeperiod
) {}
43 int neb_deregister_callback(int callback_type
, int (*callback_func
)(int, void *)) { return 0; }
44 int qh_register_handler(const char *name
, const char *description
, unsigned int options
, qh_handler handler
) { return 0; }
45 int neb_register_callback(int callback_type
, void *mod_handle
, int priority
, int (*callback_func
)(int, void *)) { return 0; }
46 const char *notification_reason_name(unsigned int reason_type
) { return NULL
; }
47 void logit(int data_type
, int display
, const char *fmt
, ...) {}
48 void remove_event(squeue_t
*sq
, timed_event
*event
) {}
49 time_t get_next_service_notification_time(service
*temp_service
, time_t time_t1
) {return 0;}
50 time_t get_next_host_notification_time(host
*temp_host
, time_t time_t1
) {return 0;}
53 struct merlin_notify_stats merlin_notify_stats
[9][2][2];
54 struct host
*merlin_recv_host
= NULL
;
55 struct service
*merlin_recv_service
= NULL
;
57 int ipc_is_connected(int msec
) { return 0; }
58 void ipc_init_struct(void) {}
59 void ipc_deinit(void) {}
60 int dump_nodeinfo(merlin_node
*n
, int sd
, int instance_id
) {return 0;}
63 static merlin_event last_decoded_event
;
64 int ipc_send_event(merlin_event
*pkt
) {
65 merlin_decode_event(merlin_sender
, pkt
);
66 memcpy(&last_decoded_event
, pkt
, sizeof(merlin_event
));
69 int ipc_grok_var(char *var
, char *val
) {return 1;}
71 #include "../module.c"
72 #include "../pgroup.c"
78 nebmodule_init(0, "tests/singlenode.conf", NULL
);
79 merlin_should_send_paths
= 0;
82 memset(&last_decoded_event
, 0, sizeof(merlin_event
));
85 void general_teardown()
87 nebmodule_deinit(0, 0);
90 void expiration_setup()
94 nebmodule_init(0, "tests/twopeers.conf", NULL
);
95 num_objects
.hosts
= 3;
96 num_objects
.services
= 3;
97 host_ary
= calloc(3, sizeof(host
*));
98 host_ary
[0] = calloc(1, sizeof(host
));
100 host_ary
[0]->services
= calloc(1, sizeof(servicesmember
));
101 host_ary
[0]->services
->service_ptr
= calloc(1, sizeof(service
));
102 host_ary
[0]->services
->service_ptr
->id
= 0;
103 host_ary
[1] = calloc(1, sizeof(host
));
105 host_ary
[1]->services
= calloc(1, sizeof(servicesmember
));
106 host_ary
[1]->services
->service_ptr
= calloc(1, sizeof(service
));
107 host_ary
[1]->services
->service_ptr
->id
= 1;
108 host_ary
[2] = calloc(1, sizeof(host
));
110 host_ary
[2]->services
= calloc(1, sizeof(servicesmember
));
111 host_ary
[2]->services
->service_ptr
= calloc(1, sizeof(service
));
112 host_ary
[2]->services
->service_ptr
->id
= 2;
114 int event_type
= NEBTYPE_PROCESS_EVENTLOOPSTART
;
115 post_config_init(0, &event_type
);
119 node_set_state(node_table
[0], STATE_CONNECTED
, "Fake connected");
120 node_set_state(node_table
[1], STATE_CONNECTED
, "Fake connected");
121 pgroup_assign_peer_ids(node_table
[0]->pgroup
);
124 void expiration_teardown()
127 for (i
= 0; i
< 3; i
++) {
128 free(host_ary
[i
]->services
->service_ptr
);
129 free(host_ary
[i
]->services
);
133 nebmodule_deinit(0, 0);
136 START_TEST(test_callback_host_check
)
138 time_t expected_last_check
= time(NULL
);
139 time_t not_expected_last_check
= 2147123099;
141 host_ary
= calloc(1, sizeof(host
*));
143 memset(&hst
, 0, sizeof(host
));
145 num_objects
.hosts
= 1;
147 int event_type
= NEBTYPE_PROCESS_EVENTLOOPSTART
;
148 post_config_init(0, &event_type
);
151 hst
.name
= "test-host";
152 hst
.last_check
= not_expected_last_check
;
154 nebstruct_host_check_data ev_data
= {0,};
155 merlin_host_status
*event_body
;
157 gettimeofday(&tv
, NULL
);
158 ev_data
.type
= NEBTYPE_HOSTCHECK_PROCESSED
;
160 ev_data
.attr
= NEBATTR_CHECK_ALERT
;
161 ev_data
.timestamp
= tv
;
162 ev_data
.object_ptr
= &hst
;
163 ev_data
.end_time
.tv_sec
= expected_last_check
;
164 merlin_mod_hook(NEBCALLBACK_HOST_CHECK_DATA
, &ev_data
);
165 ck_assert_int_eq(last_decoded_event
.hdr
.type
, NEBCALLBACK_HOST_CHECK_DATA
);
166 event_body
= (merlin_host_status
*)last_decoded_event
.body
;
167 ck_assert_int_eq(event_body
->nebattr
, NEBATTR_CHECK_ALERT
);
168 ck_assert_str_eq(event_body
->name
, hst
.name
);
169 ck_assert_int_eq(expected_last_check
, event_body
->state
.last_check
);
173 START_TEST(test_callback_service_check
)
175 time_t expected_last_check
= time(NULL
);
176 time_t not_expected_last_check
= 2147123099;
178 host_ary
= calloc(1, sizeof(host
*));
181 hst
.name
= "test-host";
183 memset(&hst
, 0, sizeof(host
));
185 hst
.services
= calloc(1, sizeof(servicesmember
));
186 hst
.services
->service_ptr
= &svc
;
187 memset(&svc
, 0, sizeof(service
));
189 svc
.host_name
= "test-host";
190 svc
.description
= "test-service";
191 svc
.last_check
= not_expected_last_check
;
192 num_objects
.hosts
= 1;
193 num_objects
.services
= 1;
195 int event_type
= NEBTYPE_PROCESS_EVENTLOOPSTART
;
196 post_config_init(0, &event_type
);
198 nebstruct_service_check_data ev_data
= {0,};
199 merlin_service_status
*event_body
;
201 gettimeofday(&tv
, NULL
);
202 ev_data
.type
= NEBTYPE_SERVICECHECK_PROCESSED
;
204 ev_data
.attr
= NEBATTR_CHECK_ALERT
;
205 ev_data
.timestamp
= tv
;
206 ev_data
.object_ptr
= &svc
;
207 ev_data
.end_time
.tv_sec
= expected_last_check
;
208 merlin_mod_hook(NEBCALLBACK_SERVICE_CHECK_DATA
, &ev_data
);
209 ck_assert_int_eq(last_decoded_event
.hdr
.type
, NEBCALLBACK_SERVICE_CHECK_DATA
);
210 event_body
= (merlin_service_status
*)last_decoded_event
.body
;
211 ck_assert_int_eq(event_body
->nebattr
, NEBATTR_CHECK_ALERT
);
212 ck_assert_str_eq(event_body
->host_name
, svc
.host_name
);
213 ck_assert_int_eq(expected_last_check
, event_body
->state
.last_check
);
217 START_TEST(set_clear_svc_expire
)
220 merlin_event pkt
= {{{0,},},};
221 nebstruct_service_check_data ds
= {0,};
222 ds
.type
= NEBTYPE_SERVICECHECK_ASYNC_PRECHECK
;
223 ds
.object_ptr
= host_ary
[0]->services
->service_ptr
;
224 hook_service_result(&pkt
, &ds
);
225 ck_assert_msg(service_expiry_map
[0] != NULL
, "Service sending a precheck should trigger expiration check");
226 ck_assert_msg(expired_services
[0] == NULL
, "Service precheck should not expire service");
227 res
= expire_event(service_expiry_map
[0]->event_args
);
228 ck_assert_int_eq(0, res
);
229 ck_assert_msg(expired_services
[0] != NULL
, "Service should become expired after expire_event runs");
230 ck_assert_msg(service_expiry_map
[0] == NULL
, "Expiring a check should clear expiration check");
231 ds
.type
= NEBTYPE_SERVICECHECK_PROCESSED
;
232 hook_service_result(&pkt
, &ds
);
233 ck_assert_msg(service_expiry_map
[0] == NULL
, "Service sending a check result should clear expiration check");
234 ck_assert_msg(expired_services
[0] == NULL
, "Service should not be expired after check result comes in");
235 ds
.type
= NEBTYPE_SERVICECHECK_ASYNC_PRECHECK
;
236 hook_service_result(&pkt
, &ds
);
237 ck_assert_msg(service_expiry_map
[0] != NULL
, "Service sending a precheck should trigger expiration check");
238 ds
.type
= NEBTYPE_SERVICECHECK_PROCESSED
;
239 hook_service_result(&pkt
, &ds
);
240 ck_assert_msg(service_expiry_map
[0] == NULL
, "Service sending a check result should clear expiration check");
241 ck_assert_msg(expired_services
[0] == NULL
, "Service should not be expired after check result comes in");
242 ds
.type
= NEBTYPE_SERVICECHECK_PROCESSED
;
243 hook_service_result(&pkt
, &ds
);
244 ck_assert_msg(service_expiry_map
[0] == NULL
, "Resending a check result should keep expiration map cleared");
245 ck_assert_msg(expired_services
[0] == NULL
, "Resending a check result should keep expired list cleared");
249 START_TEST(set_clear_host_expire
)
252 merlin_event pkt
= {{{0,},},};
253 nebstruct_host_check_data ds
= {0,};
254 ds
.type
= NEBTYPE_HOSTCHECK_ASYNC_PRECHECK
;
255 ds
.object_ptr
= host_ary
[0];
256 hook_host_result(&pkt
, &ds
);
257 ck_assert_msg(host_expiry_map
[0] != NULL
, "Host sending a precheck should trigger expiration check");
258 ck_assert_msg(expired_hosts
[0] == NULL
, "Host precheck should not expire host");
259 res
= expire_event(host_expiry_map
[0]->event_args
);
260 ck_assert_int_eq(0, res
);
261 ck_assert_msg(expired_hosts
[0] != NULL
, "Host should become expired after expire_event runs");
262 ck_assert_msg(host_expiry_map
[0] == NULL
, "Expiring a check should clear expiration check");
263 ds
.type
= NEBTYPE_HOSTCHECK_PROCESSED
;
264 hook_host_result(&pkt
, &ds
);
265 ck_assert_msg(host_expiry_map
[0] == NULL
, "Host sending a check result should clear expiration check");
266 ck_assert_msg(expired_hosts
[0] == NULL
, "Host should not be expired after check result comes in");
267 ds
.type
= NEBTYPE_HOSTCHECK_ASYNC_PRECHECK
;
268 hook_host_result(&pkt
, &ds
);
269 ck_assert_msg(host_expiry_map
[0] != NULL
, "Host sending a precheck should trigger expiration check");
270 ds
.type
= NEBTYPE_HOSTCHECK_PROCESSED
;
271 hook_host_result(&pkt
, &ds
);
272 ck_assert_msg(host_expiry_map
[0] == NULL
, "Host sending a check result should clear expiration check");
273 ck_assert_msg(expired_hosts
[0] == NULL
, "Host should not be expired after check result comes in");
274 ds
.type
= NEBTYPE_HOSTCHECK_PROCESSED
;
275 hook_service_result(&pkt
, &ds
);
276 ck_assert_msg(service_expiry_map
[0] == NULL
, "Resending a check result should keep expiration map cleared");
277 ck_assert_msg(expired_services
[0] == NULL
, "Resending a check result should keep expired list cleared");
281 START_TEST(multiple_svc_expire
)
284 merlin_event pkt
= {{{0,},},};
285 nebstruct_service_check_data ds0
= {0,}, ds1
= {0,};
286 ds0
.type
= NEBTYPE_SERVICECHECK_ASYNC_PRECHECK
;
287 ds0
.object_ptr
= host_ary
[0]->services
->service_ptr
;
288 ds1
.type
= NEBTYPE_SERVICECHECK_ASYNC_PRECHECK
;
289 ds1
.object_ptr
= host_ary
[1]->services
->service_ptr
;
290 hook_service_result(&pkt
, &ds0
);
291 ck_assert_msg(service_expiry_map
[0] != NULL
, "Service sending a precheck should trigger expiration check");
292 ck_assert_msg(service_expiry_map
[1] == NULL
, "Service sending a precheck should not trigger other expiration checks");
293 ck_assert_msg(expired_services
[0] == NULL
, "Service precheck should not expire service");
294 hook_service_result(&pkt
, &ds1
);
295 ck_assert_msg(service_expiry_map
[0] != NULL
, "Old expiration check should still be around");
296 ck_assert_msg(service_expiry_map
[1] != NULL
, "New service sending a precheck should trigger expiration check, too");
297 res
= expire_event(service_expiry_map
[0]->event_args
);
298 ck_assert_int_eq(0, res
);
299 ck_assert_msg(expired_services
[0] != NULL
, "Service should become expired after expire_event runs");
300 ck_assert_msg(service_expiry_map
[0] == NULL
, "Expiring a check should clear expiration check");
301 ck_assert_msg(service_expiry_map
[1] != NULL
, "Other services in expiration precheck should not be affected by an expiration");
302 ck_assert_msg(expired_services
[1] == NULL
, "Other services in expiration precheck should not be affected by an expiration");
303 ds0
.type
= NEBTYPE_SERVICECHECK_PROCESSED
;
304 hook_service_result(&pkt
, &ds0
);
305 ck_assert_msg(service_expiry_map
[0] == NULL
, "Service sending a check result should clear expiration check");
306 ck_assert_msg(expired_services
[0] == NULL
, "Service should not be expired after check result comes in");
307 ck_assert_msg(service_expiry_map
[1] != NULL
, "Other services in expiration precheck should not be affected by an expiration");
308 ck_assert_msg(expired_services
[1] == NULL
, "Other services in expiration precheck should not be affected by an expiration");
309 ds0
.type
= NEBTYPE_SERVICECHECK_ASYNC_PRECHECK
;
310 hook_service_result(&pkt
, &ds0
);
311 res
= expire_event(service_expiry_map
[0]->event_args
);
312 res
= expire_event(service_expiry_map
[1]->event_args
);
313 ck_assert_msg(expired_services
[0] != NULL
, "Service should become expired after expire_event runs");
314 ck_assert_msg(expired_services
[1] != NULL
, "Service should become expired after expire_event runs");
315 ds0
.type
= NEBTYPE_SERVICECHECK_PROCESSED
;
316 hook_service_result(&pkt
, &ds0
);
317 ck_assert_msg(service_expiry_map
[0] == NULL
, "Service sending a check result should clear expiration check");
318 ck_assert_msg(expired_services
[1] != NULL
, "One service sending a check result should not clear others' expired status");
322 START_TEST(multiple_host_expire
)
325 merlin_event pkt
= {{{0,},},};
326 nebstruct_host_check_data ds0
= {0,}, ds1
= {0,};
327 ds0
.type
= NEBTYPE_HOSTCHECK_ASYNC_PRECHECK
;
328 ds0
.object_ptr
= host_ary
[0];
329 ds1
.type
= NEBTYPE_HOSTCHECK_ASYNC_PRECHECK
;
330 ds1
.object_ptr
= host_ary
[1];
331 hook_host_result(&pkt
, &ds0
);
332 ck_assert_msg(host_expiry_map
[0] != NULL
, "Host sending a precheck should trigger expiration check");
333 ck_assert_msg(host_expiry_map
[1] == NULL
, "Host sending a precheck should not trigger other expiration checks");
334 ck_assert_msg(expired_hosts
[0] == NULL
, "Host precheck should not expire host");
335 hook_host_result(&pkt
, &ds1
);
336 ck_assert_msg(host_expiry_map
[0] != NULL
, "Old expiration check should still be around");
337 ck_assert_msg(host_expiry_map
[1] != NULL
, "New host sending a precheck should trigger expiration check, too");
338 res
= expire_event(host_expiry_map
[0]->event_args
);
339 ck_assert_int_eq(0, res
);
340 ck_assert_msg(expired_hosts
[0] != NULL
, "Host should become expired after expire_event runs");
341 ck_assert_msg(host_expiry_map
[0] == NULL
, "Expiring a check should clear expiration check");
342 ck_assert_msg(host_expiry_map
[1] != NULL
, "Other hosts in expiration precheck should not be affected by an expiration");
343 ck_assert_msg(expired_hosts
[1] == NULL
, "Other hosts in expiration precheck should not be affected by an expiration");
344 ds0
.type
= NEBTYPE_HOSTCHECK_PROCESSED
;
345 hook_host_result(&pkt
, &ds0
);
346 ck_assert_msg(host_expiry_map
[0] == NULL
, "Host sending a check result should clear expiration check");
347 ck_assert_msg(expired_hosts
[0] == NULL
, "Host should not be expired after check result comes in");
348 ck_assert_msg(host_expiry_map
[1] != NULL
, "Other hosts in expiration precheck should not be affected by an expiration");
349 ck_assert_msg(expired_hosts
[1] == NULL
, "Other hosts in expiration precheck should not be affected by an expiration");
350 ds0
.type
= NEBTYPE_HOSTCHECK_ASYNC_PRECHECK
;
351 hook_host_result(&pkt
, &ds0
);
352 res
= expire_event(host_expiry_map
[0]->event_args
);
353 res
= expire_event(host_expiry_map
[1]->event_args
);
354 ck_assert_msg(expired_hosts
[0] != NULL
, "Host should become expired after expire_event runs");
355 ck_assert_msg(expired_hosts
[1] != NULL
, "Host should become expired after expire_event runs");
356 ds0
.type
= NEBTYPE_HOSTCHECK_PROCESSED
;
357 hook_host_result(&pkt
, &ds0
);
358 ck_assert_msg(host_expiry_map
[0] == NULL
, "Host sending a check result should clear expiration check");
359 ck_assert_msg(expired_hosts
[1] != NULL
, "One host sending a check result should not clear others' expired status");
364 check_hooks_suite(void)
366 Suite
*s
= suite_create("hooks");
368 TCase
*tc
= tcase_create("callback");
369 tcase_add_checked_fixture (tc
, general_setup
, general_teardown
);
370 tcase_add_test(tc
, test_callback_host_check
);
371 tcase_add_test(tc
, test_callback_service_check
);
372 suite_add_tcase(s
, tc
);
374 tc
= tcase_create("expiration");
375 tcase_add_checked_fixture (tc
, expiration_setup
, expiration_teardown
);
376 tcase_add_test(tc
, set_clear_host_expire
);
377 tcase_add_test(tc
, set_clear_svc_expire
);
378 tcase_add_test(tc
, multiple_host_expire
);
379 tcase_add_test(tc
, multiple_svc_expire
);
380 suite_add_tcase(s
, tc
);
385 int main(int argc
, char *argv
[]) {
387 Suite
*s
= check_hooks_suite();
388 SRunner
*sr
= srunner_create(s
);
389 srunner_run_all(sr
, CK_NORMAL
);
390 number_failed
= srunner_ntests_failed(sr
);
392 return (number_failed
== 0) ? EXIT_SUCCESS
: EXIT_FAILURE
;