1 #!/usr/bin/env python2.6
2 #Copyright (C) 2009-2010 :
3 # Gabes Jean, naparuba@gmail.com
4 # Gerhard Lausser, Gerhard.Lausser@consol.de
6 #This file is part of Shinken.
8 #Shinken is free software: you can redistribute it and/or modify
9 #it under the terms of the GNU Affero General Public License as published by
10 #the Free Software Foundation, either version 3 of the License, or
11 #(at your option) any later version.
13 #Shinken is distributed in the hope that it will be useful,
14 #but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 #GNU Affero General Public License for more details.
18 #You should have received a copy of the GNU Affero General Public License
19 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
23 # This file is used to test host- and service-downtimes.
26 from shinken_test
import *
33 sys
.path
.append("../shinken/modules/livestatus_broker")
34 from livestatus_broker
import Livestatus_broker
35 sys
.setcheckinterval(10000)
37 class TestConfig(ShinkenTest
):
38 def contains_line(self
, text
, pattern
):
39 regex
= re
.compile(pattern
)
40 for line
in text
.splitlines():
41 if re
.search(regex
, line
):
46 def scheduler_loop(self
, count
, reflist
, do_sleep
=False, sleep_time
=61):
47 super(TestConfig
, self
).scheduler_loop(count
, reflist
, do_sleep
, sleep_time
)
48 if self
.nagios_installed() and hasattr(self
, 'nagios_started'):
49 self
.nagios_loop(1, reflist
)
52 def update_broker(self
):
53 #The brok should be manage in the good order
54 ids
= self
.sched
.broks
.keys()
57 brok
= self
.sched
.broks
[brok_id
]
58 #print "Managing a brok type", brok.type, "of id", brok_id
59 #if brok.type == 'update_service_status':
60 # print "Problem?", brok.data['is_problem']
61 self
.livestatus_broker
.manage_brok(brok
)
65 def lines_equal(self
, text1
, text2
):
66 # gets two multiline strings and compares the contents
67 # lifestatus output may not be in alphabetical order, so this
68 # function is used to compare unordered output with unordered
70 sorted1
= "\n".join(sorted(text1
.split("\n")))
71 sorted2
= "\n".join(sorted(text2
.split("\n")))
72 len1
= len(text1
.split("\n"))
73 len2
= len(text2
.split("\n"))
74 #print "%s == %s text cmp %s" % (len1, len2, sorted1 == sorted2)
75 #print "text1 //%s//" % sorted(text1.split("\n"))
76 #print "text2 //%s//" % sorted(text2.split("\n"))
77 if sorted1
== sorted2
and len1
== len2
:
80 # Maybe list members are different
81 # allhosts;test_host_0;test_ok_0;servicegroup_02,servicegroup_01,ok
82 # allhosts;test_host_0;test_ok_0;servicegroup_02,ok,servicegroup_01
84 # [['allhosts'], ['test_host_0'], ['test_ok_0'],
85 # ['ok', 'servicegroup_01', 'servicegroup_02']]
86 [line
for line
in sorted(text1
.split("\n"))]
87 data1
= [[sorted(c
.split(',')) for c
in columns
] for columns
in [line
.split(';') for line
in sorted(text1
.split("\n")) if line
]]
88 data2
= [[sorted(c
.split(',')) for c
in columns
] for columns
in [line
.split(';') for line
in sorted(text2
.split("\n")) if line
]]
89 #print "text1 //%s//" % data1
90 #print "text2 //%s//" % data2
91 # cmp is clever enough to handle nested arrays
92 return cmp(data1
, data2
) == 0
95 def show_broks(self
, title
):
98 for brok
in sorted(self
.sched
.broks
.values(), lambda x
, y
: x
.id - y
.id):
99 if re
.compile('^service_').match(brok
.type):
100 print "BROK:", brok
.type
101 print "BROK ", brok
.data
['in_checking']
103 request
= 'GET services\nColumns: service_description is_executing\n'
104 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
108 def nagios_installed(self
, path
='/usr/ocal/nagios/bin/nagios', livestatus
='/usr/local/nagios/lib/mk-livestatus/livestatus.o'):
109 if os
.path
.exists(path
) and os
.access(path
, os
.X_OK
) and os
.path
.exists(livestatus
):
110 self
.nagios_path
= path
111 self
.livestatus_path
= livestatus
117 # shinkenize_nagios_config('nagios_1r_1h_1s')
118 # We assume that there is a nagios_1r_1h_1s.cfg and a nagios_1r_1h_1s directory for the objects
119 def unshinkenize_config(self
, configname
):
120 new_configname
= configname
+ '_' + str(os
.getpid())
121 config
= open('etc/nagios_' + configname
+ '.cfg')
122 text
= config
.readlines()
125 newconfig
= open('etc/nagios_' + new_configname
+ '.cfg', 'w')
127 if re
.search('^resource_file=', line
):
128 newconfig
.write("resource_file=etc/resource.cfg\n")
129 elif re
.search('shinken\-specific\.cfg', line
):
131 elif re
.search('enable_problem_impacts_states_change', line
):
133 elif re
.search('cfg_dir=', line
):
134 newconfig
.write(re
.sub(configname
, new_configname
, line
))
135 elif re
.search('cfg_file=', line
):
136 newconfig
.write(re
.sub(configname
, new_configname
, line
))
137 elif re
.search('execute_host_checks=', line
):
138 newconfig
.write("execute_host_checks=0\n")
139 elif re
.search('execute_service_checks=', line
):
140 newconfig
.write("execute_service_checks=0\n")
141 elif re
.search('^debug_level=', line
):
142 newconfig
.write("debug_level=0\n")
143 elif re
.search('^debug_verbosity=', line
):
144 newconfig
.write("debug_verbosity=0\n")
145 elif re
.search('^status_update_interval=', line
):
146 newconfig
.write("status_update_interval=30\n")
147 elif re
.search('^command_file=', line
):
148 newconfig
.write("command_file=var/nagios.cmd\n")
149 elif re
.search('^command_check_interval=', line
):
150 newconfig
.write("command_check_interval=1s\n")
152 newconfig
.write(line
)
153 newconfig
.write('broker_module=/usr/local/nagios/lib/mk-livestatus/livestatus.o var/live' + "\n")
155 for dirfile
in os
.walk('etc/' + configname
):
156 dirpath
, dirlist
, filelist
= dirfile
157 newdirpath
= re
.sub(configname
, new_configname
, dirpath
)
159 for file in [f
for f
in filelist
if re
.search('\.cfg$', f
)]:
160 config
= open(dirpath
+ '/' + file)
161 text
= config
.readlines()
163 newconfig
= open(newdirpath
+ '/' + file, 'w')
165 if re
.search('^\s*criticity', line
):
167 elif re
.search('enable_problem_impacts_states_change', line
):
170 newconfig
.write(line
)
172 return new_configname
175 def start_nagios(self
, config
):
176 if os
.path
.exists('var/spool/checkresults'):
177 # Cleanup leftover checkresults
178 shutil
.rmtree('var/spool/checkresults')
179 for dir in ['tmp', 'var/tmp', 'var/spool', 'var/spool/checkresults', 'var/archives']:
180 if not os
.path
.exists(dir):
182 self
.nagios_config
= self
.unshinkenize_config(config
)
183 if os
.path
.exists('var/retention.dat'):
184 os
.remove('var/retention.dat')
185 if os
.path
.exists('var/status.dat'):
186 os
.remove('var/status.dat')
187 self
.nagios_proc
= subprocess
.Popen([self
.nagios_path
, 'etc/nagios_' + self
.nagios_config
+ '.cfg'], close_fds
=True)
188 self
.nagios_started
= time
.time()
192 def stop_nagios(self
):
194 while self
.nagios_proc
.poll() == None and attempt
< 4:
195 self
.nagios_proc
.terminate()
198 if self
.nagios_proc
.poll() == None:
199 self
.nagios_proc
.kill()
200 if os
.path
.exists('etc/' + self
.nagios_config
):
201 shutil
.rmtree('etc/' + self
.nagios_config
)
202 if os
.path
.exists('etc/nagios_' + self
.nagios_config
+ '.cfg'):
203 os
.remove('etc/nagios_' + self
.nagios_config
+ '.cfg')
206 def ask_nagios(self
, request
):
207 if time
.time() - self
.nagios_started
< 2:
209 if not request
.endswith("\n"):
210 request
= request
+ "\n"
211 unixcat
= subprocess
.Popen([os
.path
.dirname(self
.nagios_path
) + '/' + 'unixcat', 'var/live'], stdin
=subprocess
.PIPE
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
)
213 out
, err
= unixcat
.communicate(request
)
215 print "mklivestatus duration %f" % (tac
- tic
)
217 while unixcat
.poll() == None and attempt
< 4:
221 if unixcat
.poll() == None:
223 print "unixcat says", out
227 def nagios_loop(self
, count
, reflist
, do_sleep
=False, sleep_time
=61):
229 buffer = open('var/pipebuffer', 'w')
231 (obj
, exit_status
, output
) = ref
232 if obj
.my_type
== 'service':
233 cmd
= "[%lu] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n" % (now
, obj
.host_name
, obj
.service_description
, exit_status
, output
)
237 cmd
= "[%lu] PROCESS_HOST_CHECK_RESULT;%s;%d;%s\n" % (now
, obj
.host_name
, exit_status
, output
)
240 print "open pipe", self
.conf
.command_file
241 fifo
= open('var/nagios.cmd', 'w')
242 cmd
= "[%lu] PROCESS_FILE;%s;0\n" % (now
, 'var/pipebuffer')
249 def nagios_extcmd(self
, cmd
):
250 fifo
= open('var/nagios.cmd', 'w')
258 class TestConfigSmall(TestConfig
):
260 self
.setup_with_file('etc/nagios_1r_1h_1s.cfg')
261 self
.livestatus_broker
= Livestatus_broker('livestatus', '127.0.0.1', str(50000 + os
.getpid()), 'live', '/tmp/livelogs.db' + str(os
.getpid()))
262 self
.livestatus_broker
.properties
= {
267 self
.livestatus_broker
.init()
268 print "Cleaning old broks?"
269 self
.sched
.fill_initial_broks()
271 self
.nagios_path
= None
272 self
.livestatus_path
= None
273 self
.nagios_config
= None
277 if os
.path
.exists('/tmp/livelogs.db' + str(os
.getpid())):
278 os
.remove('/tmp/livelogs.db' + str(os
.getpid()))
281 def test_servicesbyhostgroup(self
):
282 if self
.nagios_installed():
283 self
.start_nagios('1r_1h_1s')
287 for host
in self
.sched
.hosts
:
288 objlist
.append([host
, 0, 'UP'])
289 for service
in self
.sched
.services
:
290 objlist
.append([service
, 0, 'OK'])
291 self
.scheduler_loop(1, objlist
)
293 request
= """GET servicesbyhostgroup
294 Filter: host_groups >= allhosts
295 Columns: hostgroup_name host_name service_description groups
298 ResponseHeader: fixed16
300 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
302 if self
.nagios_installed():
303 nagresponse
= self
.ask_nagios(request
)
304 print "nagresponse----------------------------------------------"
306 self
.assert_(self
.lines_equal(response
, nagresponse
))
308 # Again, but without filter
309 request
= """GET servicesbyhostgroup
310 Columns: hostgroup_name host_name service_description groups
313 ResponseHeader: fixed16
315 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
317 if self
.nagios_installed():
318 nagresponse
= self
.ask_nagios(request
)
320 print "nagresponse----------------------------------------------"
322 self
.assert_(self
.lines_equal(response
, nagresponse
))
325 def test_hostsbygroup(self
):
327 if self
.nagios_installed():
328 self
.start_nagios('1r_1h_1s')
331 for host
in self
.sched
.hosts
:
332 objlist
.append([host
, 0, 'UP'])
333 for service
in self
.sched
.services
:
334 objlist
.append([service
, 0, 'OK'])
335 self
.scheduler_loop(1, objlist
)
337 request
= """GET hostsbygroup
339 Columns: host_name hostgroup_name
340 Filter: groups >= allhosts
343 ResponseHeader: fixed16
346 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
348 if self
.nagios_installed():
349 nagresponse
= self
.ask_nagios(request
)
351 print "nagresponse----------------------------------------------"
353 self
.assert_(self
.lines_equal(response
, nagresponse
))
356 def test_status(self
):
358 if self
.nagios_installed():
359 self
.start_nagios('1r_1h_1s')
361 host
= self
.sched
.hosts
.find_by_name("test_host_0")
362 host
.checks_in_progress
= []
363 host
.act_depend_of
= [] # ignore the router
364 router
= self
.sched
.hosts
.find_by_name("test_router_0")
365 router
.checks_in_progress
= []
366 router
.act_depend_of
= [] # ignore the router
367 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
368 svc
.checks_in_progress
= []
369 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
370 self
.scheduler_loop(2, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 2, 'BAD']])
372 #---------------------------------------------------------------
373 # get the full hosts table
374 #---------------------------------------------------------------
375 request
= 'GET hosts'
376 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
378 if self
.nagios_installed():
379 nagresponse
= self
.ask_nagios(request
)
380 print "nagresponse----------------------------------------------"
382 # todo 1 != 1.0000000000e+00
383 #self.assert_(self.lines_equal(response, nagresponse))
385 #---------------------------------------------------------------
386 # get only the host names and addresses
387 #---------------------------------------------------------------
388 request
= 'GET hosts\nColumns: name address groups\nColumnHeaders: on'
389 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
391 if self
.nagios_installed():
392 nagresponse
= self
.ask_nagios(request
)
393 print "nagresponse----------------------------------------------"
395 self
.assert_(self
.lines_equal(response
, nagresponse
))
397 #---------------------------------------------------------------
399 #---------------------------------------------------------------
400 request
= 'GET contacts'
401 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
402 print 'query_1_______________\n%s\n%s\n' % (request
, response
)
403 if self
.nagios_installed():
404 nagresponse
= self
.ask_nagios(request
)
405 print "nagresponse----------------------------------------------"
407 # There are some sick columns in the livestatus response like
408 # modified_attributes;modified_attributes_list
409 # These are not implemented in shinken-livestatus (never, i think)
410 #self.assert_(self.lines_equal(response, nagresponse))
412 #---------------------------------------------------------------
414 #---------------------------------------------------------------
415 request
= 'GET contacts\nColumns: name alias'
416 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
417 print 'query_2_______________\n%s\n%s\n' % (request
, response
)
418 if self
.nagios_installed():
419 nagresponse
= self
.ask_nagios(request
)
420 print "nagresponse----------------------------------------------"
422 self
.assert_(self
.lines_equal(response
, nagresponse
))
424 #---------------------------------------------------------------
426 #---------------------------------------------------------------
427 #self.scheduler_loop(3, svc, 2, 'BAD')
428 request
= 'GET services\nColumns: host_name description state\nFilter: state = 2\nColumnHeaders: on'
429 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
430 print 'query_3_______________\n%s\n%s\n' % (request
, response
)
431 self
.assert_(response
== 'host_name;description;state\ntest_host_0;test_ok_0;2\n')
432 request
= 'GET services\nColumns: host_name description state\nFilter: state = 2'
433 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
434 print 'query_3_______________\n%s\n%s\n' % (request
, response
)
435 self
.assert_(response
== 'test_host_0;test_ok_0;2\n')
436 request
= 'GET services\nColumns: host_name description state\nFilter: state = 0'
437 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
438 print 'query_3_______________\n%s\n%s\n' % (request
, response
)
439 self
.assert_(response
== '\n')
442 cmd
= "[%lu] SCHEDULE_SVC_DOWNTIME;test_host_0;test_ok_0;%d;%d;0;0;%d;lausser;blablub" % (now
, now
, now
+ duration
, duration
)
443 self
.sched
.run_external_command(cmd
)
445 self
.scheduler_loop(1, [[svc
, 0, 'OK']])
447 self
.scheduler_loop(3, [[svc
, 2, 'BAD']])
449 request
= 'GET services\nColumns: host_name description scheduled_downtime_depth\nFilter: state = 2\nFilter: scheduled_downtime_depth = 1'
450 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
451 print 'query_3_______________\n%s\n%s\n' % (request
, response
)
452 self
.assert_(response
== 'test_host_0;test_ok_0;1\n')
454 #---------------------------------------------------------------
456 #---------------------------------------------------------------
457 request
= 'GET services\nColumns: host_name description state\nFilter: state = 2\nFilter: in_notification_period = 1\nAnd: 2\nFilter: state = 0\nOr: 2\nFilter: host_name = test_host_0\nFilter: description = test_ok_0\nAnd: 3\nFilter: contacts >= harri\nFilter: contacts >= test_contact\nOr: 3'
458 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
459 print 'query_4_______________\n%s\n%s\n' % (request
, response
)
460 self
.assert_(response
== 'test_host_0;test_ok_0;2\n')
462 #---------------------------------------------------------------
464 #---------------------------------------------------------------
465 request
= 'GET services\nStats: state = 0\nStats: state = 1\nStats: state = 2\nStats: state = 3'
466 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
467 print 'query_6_______________\n%s\n%s\n' % (request
, response
)
468 self
.assert_(response
== '0;0;1;0\n')
470 #---------------------------------------------------------------
472 #---------------------------------------------------------------
473 request
= 'GET services\nStats: state = 0\nStats: state = 1\nStats: state = 2\nStats: state = 3\nFilter: contacts >= test_contact'
474 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
475 print 'query_6_______________\n%s\n%s\n' % (request
, response
)
476 self
.assert_(response
== '0;0;1;0\n')
477 if self
.nagios_installed():
478 nagresponse
= self
.ask_nagios(request
)
480 print "nagresponse----------------------------------------------"
482 # TODO looks like a timing problem with nagios
483 #self.assert_(self.lines_equal(response, nagresponse))
488 print "got initial broks"
490 host
= self
.sched
.hosts
.find_by_name("test_host_0")
491 host
.checks_in_progress
= []
492 host
.act_depend_of
= [] # ignore the router
493 router
= self
.sched
.hosts
.find_by_name("test_router_0")
494 router
.checks_in_progress
= []
495 router
.act_depend_of
= [] # ignore the router
496 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
497 svc
.checks_in_progress
= []
498 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
499 self
.scheduler_loop(2, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 2, 'BAD']])
501 request
= 'GET services\nColumns: host_name description state\nOutputFormat: json'
502 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
503 print 'json wo headers__________\n%s\n%s\n' % (request
, response
)
504 self
.assert_(response
== '[["test_host_0","test_ok_0",2]]\n')
505 request
= 'GET services\nColumns: host_name description state\nOutputFormat: json\nColumnHeaders: on'
506 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
507 print 'json with headers__________\n%s\n%s\n' % (request
, response
)
508 self
.assert_(response
== '[["host_name","description","state"],["test_host_0","test_ok_0",2]]\n')
509 #100% mklivesttaus: self.assert_(response == '[["host_name","description","state"],\n["test_host_0","test_ok_0",2]]\n')
512 def test_thruk(self
):
514 if self
.nagios_installed():
515 self
.start_nagios('1r_1h_1s')
517 host
= self
.sched
.hosts
.find_by_name("test_host_0")
518 host
.checks_in_progress
= []
519 host
.act_depend_of
= [] # ignore the router
520 router
= self
.sched
.hosts
.find_by_name("test_router_0")
521 router
.checks_in_progress
= []
522 router
.act_depend_of
= [] # ignore the router
523 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
524 svc
.checks_in_progress
= []
525 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
526 self
.scheduler_loop(2, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 2, 'BAD']])
528 #---------------------------------------------------------------
529 # get the full hosts table
530 #---------------------------------------------------------------
531 request
= 'GET status\nColumns: livestatus_version program_version accept_passive_host_checks accept_passive_service_checks check_external_commands check_host_freshness check_service_freshness enable_event_handlers enable_flap_detection enable_notifications execute_host_checks execute_service_checks last_command_check last_log_rotation nagios_pid obsess_over_hosts obsess_over_services process_performance_data program_start interval_length'
532 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
535 request
= """GET hosts
537 Stats: check_type = 0
538 Stats: check_type = 1
539 Stats: has_been_checked = 1
542 Stats: has_been_checked = 1
545 Stats: has_been_checked = 1
548 Stats: has_been_checked = 0
549 Stats: has_been_checked = 0
550 Stats: active_checks_enabled = 0
552 Stats: has_been_checked = 0
553 Stats: scheduled_downtime_depth > 0
556 Stats: has_been_checked = 1
557 Stats: active_checks_enabled = 0
560 Stats: has_been_checked = 1
561 Stats: scheduled_downtime_depth > 0
564 Stats: has_been_checked = 1
565 Stats: acknowledged = 1
568 Stats: scheduled_downtime_depth > 0
569 Stats: has_been_checked = 1
572 Stats: active_checks_enabled = 0
573 Stats: has_been_checked = 1
576 Stats: active_checks_enabled = 1
577 Stats: acknowledged = 0
578 Stats: scheduled_downtime_depth = 0
579 Stats: has_been_checked = 1
582 Stats: acknowledged = 1
583 Stats: has_been_checked = 1
586 Stats: scheduled_downtime_depth > 0
587 Stats: has_been_checked = 1
590 Stats: active_checks_enabled = 0
593 Stats: active_checks_enabled = 1
594 Stats: acknowledged = 0
595 Stats: scheduled_downtime_depth = 0
596 Stats: has_been_checked = 1
598 Stats: is_flapping = 1
599 Stats: flap_detection_enabled = 0
600 Stats: notifications_enabled = 0
601 Stats: event_handler_enabled = 0
602 Stats: active_checks_enabled = 0
603 Stats: accept_passive_checks = 0
607 Separators: 10 59 44 124
608 ResponseHeader: fixed16"""
609 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
611 if self
.nagios_installed():
612 nagresponse
= self
.ask_nagios(request
)
614 print "nagresponse----------------------------------------------"
616 # TODO timing problem?
617 #self.assert_(self.lines_equal(response, nagresponse))
619 request
= """GET comments
620 Columns: host_name source type author comment entry_time entry_type expire_time
621 Filter: service_description ="""
622 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
624 if self
.nagios_installed():
625 nagresponse
= self
.ask_nagios(request
)
627 print "nagresponse----------------------------------------------"
629 self
.assert_(self
.lines_equal(response
, nagresponse
))
631 request
= """GET hosts
632 Columns: comments has_been_checked state name address acknowledged notifications_enabled active_checks_enabled is_flapping scheduled_downtime_depth is_executing notes_url_expanded action_url_expanded icon_image_expanded icon_image_alt last_check last_state_change plugin_output next_check long_plugin_output
633 Separators: 10 59 44 124
634 ResponseHeader: fixed16"""
635 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
640 cmd
= "[%lu] SCHEDULE_SVC_DOWNTIME;test_host_0;test_warning_00;%d;%d;0;0;%d;lausser;blablubsvc" % (now
, now
, now
+ duration
, duration
)
642 self
.sched
.run_external_command(cmd
)
643 if self
.nagios_installed():
644 self
.nagios_extcmd(cmd
)
645 cmd
= "[%lu] SCHEDULE_HOST_DOWNTIME;test_host_0;%d;%d;0;0;%d;lausser;blablubhost" % (now
, now
, now
+ duration
, duration
)
647 self
.sched
.run_external_command(cmd
)
648 if self
.nagios_installed():
649 self
.nagios_extcmd(cmd
)
651 self
.scheduler_loop(1, [[svc
, 0, 'OK']])
653 self
.scheduler_loop(3, [[svc
, 2, 'BAD']])
655 request
= """GET downtimes
656 Filter: service_description =
657 Columns: author comment end_time entry_time fixed host_name id start_time
658 Separators: 10 59 44 124
659 ResponseHeader: fixed16"""
660 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
662 if self
.nagios_installed():
664 nagresponse
= self
.ask_nagios(request
)
666 print "nagresponse----------------------------------------------"
668 #TODO the entry_times are different. find a way to round the numbers
669 # so that they are equal
670 #self.assert_(self.lines_equal(response, nagresponse))
672 request
= """GET comments
673 Filter: service_description =
674 Columns: author comment
675 Separators: 10 59 44 124
676 ResponseHeader: fixed16"""
677 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
679 if self
.nagios_installed():
681 nagresponse
= self
.ask_nagios(request
)
683 print "nagresponse----------------------------------------------"
685 #self.assert_(self.lines_equal(response, nagresponse))
687 request
= """GET services
688 Filter: has_been_checked = 1
689 Filter: check_type = 0
690 Stats: sum has_been_checked
692 Separators: 10 59 44 124
693 ResponseHeader: fixed16"""
694 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
697 request
= """GET services
698 Filter: has_been_checked = 1
699 Filter: check_type = 0
700 Stats: sum has_been_checked
702 Stats: sum execution_time
704 Stats: min execution_time
706 Stats: max execution_time
707 Separators: 10 59 44 124
708 ResponseHeader: fixed16"""
709 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
712 request
= """GET services\nFilter: has_been_checked = 1\nFilter: check_type = 0\nStats: sum has_been_checked as has_been_checked\nStats: sum latency as latency_sum\nStats: sum execution_time as execution_time_sum\nStats: min latency as latency_min\nStats: min execution_time as execution_time_min\nStats: max latency as latency_max\nStats: max execution_time as execution_time_max\n\nResponseHeader: fixed16"""
713 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
716 request
= """GET hostgroups\nColumnHeaders: on\nResponseHeader: fixed16"""
717 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
719 if self
.nagios_installed():
720 nagresponse
= self
.ask_nagios(request
)
721 print "nagresponse----------------------------------------------"
723 # TODO members_with_state
724 #self.assert_(self.lines_equal(response, nagresponse))
726 request
= """GET hosts\nColumns: name groups\nColumnHeaders: on\nResponseHeader: fixed16"""
727 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
729 if self
.nagios_installed():
730 nagresponse
= self
.ask_nagios(request
)
731 print "nagresponse----------------------------------------------"
733 self
.assert_(self
.lines_equal(response
, nagresponse
))
735 request
= """GET hostgroups\nColumns: name num_services num_services_ok\nColumnHeaders: on\nResponseHeader: fixed16"""
736 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
738 if self
.nagios_installed():
739 nagresponse
= self
.ask_nagios(request
)
740 print "nagresponse----------------------------------------------"
742 self
.assert_(self
.lines_equal(response
, nagresponse
))
744 request
= """GET hostgroups\nColumns: name num_services_pending num_services_ok num_services_warning num_services_critical num_services_unknown worst_service_state worst_service_hard_state\nColumnHeaders: on\nResponseHeader: fixed16"""
745 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
748 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']])
750 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 1, 'WARNING']])
753 print "WARNING SOFT;1"
754 # worst_service_state 1, worst_service_hard_state 0
755 request
= """GET hostgroups\nColumns: name num_services_pending num_services_ok num_services_warn num_services_crit num_services_unknown worst_service_state worst_service_hard_state\nColumnHeaders: on\nResponseHeader: fixed16"""
756 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
758 self
.scheduler_loop(3, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 1, 'WARNING']])
760 print "WARNING HARD;3"
761 # worst_service_state 1, worst_service_hard_state 1
762 request
= """GET hostgroups\nColumns: name num_services_pending num_services_ok num_services_warn num_services_crit num_services_unknown worst_service_state worst_service_hard_state\nColumnHeaders: on\nResponseHeader: fixed16"""
763 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
765 for s
in self
.livestatus_broker
.livestatus
.services
.values():
766 print "%s %d %s;%d" % (s
.state
, s
.state_id
, s
.state_type
, s
.attempt
)
768 if self
.nagios_installed():
772 def test_thruk_comments(self
):
774 host
= self
.sched
.hosts
.find_by_name("test_host_0")
775 host
.checks_in_progress
= []
776 host
.act_depend_of
= [] # ignore the router
777 router
= self
.sched
.hosts
.find_by_name("test_router_0")
778 router
.checks_in_progress
= []
779 router
.act_depend_of
= [] # ignore the router
780 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
781 svc
.checks_in_progress
= []
782 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
785 # downtime valid for the next 2 minutes
786 cmd
= "[%lu] SCHEDULE_SVC_DOWNTIME;test_host_0;test_ok_0;%d;%d;1;0;%d;lausser;blablub" % (now
, now
, now
+ duration
, duration
)
787 self
.sched
.run_external_command(cmd
)
788 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
789 svc
.checks_in_progress
= []
790 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
791 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
793 print "downtime was scheduled. check its activity and the comment"
794 self
.assert_(len(self
.sched
.downtimes
) == 1)
795 self
.assert_(len(svc
.downtimes
) == 1)
796 self
.assert_(svc
.downtimes
[0] in self
.sched
.downtimes
.values())
797 self
.assert_(svc
.downtimes
[0].fixed
)
798 self
.assert_(svc
.downtimes
[0].is_in_effect
)
799 self
.assert_(not svc
.downtimes
[0].can_be_deleted
)
800 self
.assert_(len(self
.sched
.comments
) == 1)
801 self
.assert_(len(svc
.comments
) == 1)
802 self
.assert_(svc
.comments
[0] in self
.sched
.comments
.values())
803 self
.assert_(svc
.downtimes
[0].comment_id
== svc
.comments
[0].id)
806 cmd
= "[%lu] ADD_SVC_COMMENT;test_host_0;test_ok_0;1;lausser;comment" % now
807 self
.sched
.run_external_command(cmd
)
808 #cmd = "[%lu] ADD_HOST_COMMENT;test_host_0;1;lausser;hcomment" % now
809 #self.sched.run_external_command(cmd)
810 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
811 self
.assert_(len(self
.sched
.comments
) == 2)
812 self
.assert_(len(svc
.comments
) == 2)
815 svc_comment_list
= (',').join([str(c
.id) for c
in svc
.comments
])
817 #request = """GET comments\nColumns: host_name service_description id source type author comment entry_time entry_type persistent expire_time expires\nFilter: service_description !=\nResponseHeader: fixed16\nOutputFormat: json\n"""
818 request
= """GET services\nColumns: comments host_comments host_is_executing is_executing\nFilter: service_description !=\nResponseHeader: fixed16\nOutputFormat: json\n"""
819 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
821 good_response
= """200 17
822 [[[""" + svc_comment_list
+"""],[],0,0]]
824 self
.assert_(response
== good_response
) # json
826 request
= """GET services\nColumns: comments host_comments host_is_executing is_executing\nFilter: service_description !=\nResponseHeader: fixed16\n"""
827 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
829 good_response
= """200 9
830 """ + svc_comment_list
+ """;;0;0
832 self
.assert_(response
== good_response
) # csv
835 def test_thruk_logs(self
):
838 host
= self
.sched
.hosts
.find_by_name("test_host_0")
839 host
.checks_in_progress
= []
840 host
.act_depend_of
= [] # ignore the router
841 router
= self
.sched
.hosts
.find_by_name("test_router_0")
842 router
.checks_in_progress
= []
843 router
.act_depend_of
= [] # ignore the router
844 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
845 svc
.checks_in_progress
= []
846 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
847 self
.scheduler_loop(3, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 1, 'WARNING']])
851 # downtime valid for the next 2 minutes
852 cmd
= "[%lu] SCHEDULE_SVC_DOWNTIME;test_host_0;test_ok_0;%d;%d;1;0;%d;lausser;blablub" % (now
, now
, now
+ duration
, duration
)
853 self
.sched
.run_external_command(cmd
)
854 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
855 svc
.checks_in_progress
= []
856 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
857 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
859 cmd
= "[%lu] ADD_SVC_COMMENT;test_host_0;test_ok_0;1;lausser;comment" % now
860 self
.sched
.run_external_command(cmd
)
862 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
865 self
.scheduler_loop(3, [[host
, 2, 'DOWN'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
868 self
.scheduler_loop(3, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
872 # show history for service
874 Columns: time type options state
875 Filter: time >= """ + str(int(start
)) + """
876 Filter: time <= """ + str(int(end
)) + """
877 Filter: type = SERVICE ALERT
878 Filter: type = HOST ALERT
879 Filter: type = SERVICE FLAPPING ALERT
880 Filter: type = HOST FLAPPING ALERT
881 Filter: type = SERVICE DOWNTIME ALERT
882 Filter: type = HOST DOWNTIME ALERT
884 Filter: host_name = test_host_0
885 Filter: service_description = test_ok_0
887 Filter: type ~ starting...
888 Filter: type ~ shutting down...
890 Filter: current_service_description !=
892 Filter: service_description =
895 Filter: service_description =
900 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
903 def test_thruk_logs_alerts_summary(self
):
906 host
= self
.sched
.hosts
.find_by_name("test_host_0")
907 host
.checks_in_progress
= []
908 host
.act_depend_of
= [] # ignore the router
909 router
= self
.sched
.hosts
.find_by_name("test_router_0")
910 router
.checks_in_progress
= []
911 router
.act_depend_of
= [] # ignore the router
912 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
913 svc
.checks_in_progress
= []
914 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
915 self
.scheduler_loop(3, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 1, 'WARNING']])
919 # downtime valid for the next 2 minutes
920 cmd
= "[%lu] SCHEDULE_SVC_DOWNTIME;test_host_0;test_ok_0;%d;%d;1;0;%d;lausser;blablub" % (now
, now
, now
+ duration
, duration
)
921 self
.sched
.run_external_command(cmd
)
922 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
923 svc
.checks_in_progress
= []
924 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
925 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
927 cmd
= "[%lu] ADD_SVC_COMMENT;test_host_0;test_ok_0;1;lausser;comment" % now
928 self
.sched
.run_external_command(cmd
)
930 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
933 self
.scheduler_loop(3, [[host
, 2, 'DOWN'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
936 self
.scheduler_loop(3, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
940 # is this an error in thruk?
943 Filter: options ~ ;HARD;
944 Filter: type = HOST ALERT
945 Filter: time >= 1284056080
946 Filter: time <= 1284660880
947 Filter: current_service_description !=
948 Filter: service_description =
951 Filter: service_description =
955 Columns: time state state_type host_name service_description current_host_groups current_service_groups plugin_output"""
957 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
961 def test_thruk_logs_current(self
):
964 host
= self
.sched
.hosts
.find_by_name("test_host_0")
965 host
.checks_in_progress
= []
966 host
.act_depend_of
= [] # ignore the router
967 router
= self
.sched
.hosts
.find_by_name("test_router_0")
968 router
.checks_in_progress
= []
969 router
.act_depend_of
= [] # ignore the router
970 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
971 svc
.checks_in_progress
= []
972 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
973 self
.scheduler_loop(3, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 1, 'WARNING']])
977 # downtime valid for the next 2 minutes
978 cmd
= "[%lu] SCHEDULE_SVC_DOWNTIME;test_host_0;test_ok_0;%d;%d;1;0;%d;lausser;blablub" % (now
, now
, now
+ duration
, duration
)
979 self
.sched
.run_external_command(cmd
)
980 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
981 svc
.checks_in_progress
= []
982 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
983 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
985 cmd
= "[%lu] ADD_SVC_COMMENT;test_host_0;test_ok_0;1;lausser;comment" % now
986 self
.sched
.run_external_command(cmd
)
988 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
991 self
.scheduler_loop(3, [[host
, 2, 'DOWN'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
994 self
.scheduler_loop(3, [[host
, 0, 'UUP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
997 # self.scheduler_loop(3, [[host, 0, 'UP'], [router, 2, 'DOWN'], [svc, 0, 'OK']], do_sleep=False)
998 # self.update_broker()
1001 # show history for service
1002 request
= """GET log
1003 Columns: time type options state current_host_name
1004 Filter: time >= """ + str(int(start
)) + """
1005 Filter: time <= """ + str(int(end
)) + """
1006 Filter: type = SERVICE ALERT
1007 Filter: type = HOST ALERT
1008 Filter: type = SERVICE FLAPPING ALERT
1009 Filter: type = HOST FLAPPING ALERT
1010 Filter: type = SERVICE DOWNTIME ALERT
1011 Filter: type = HOST DOWNTIME ALERT
1013 Filter: current_host_name = test_host_0
1014 Filter: current_service_description = test_ok_0
1016 request
= """GET log
1017 Columns: time type options state current_host_name
1018 Filter: time >= """ + str(int(start
)) + """
1019 Filter: time <= """ + str(int(end
)) + """
1020 Filter: current_host_name = test_host_0
1021 Filter: current_service_description = test_ok_0
1024 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1028 def test_thruk_tac_svc(self
):
1030 if self
.nagios_installed():
1031 self
.start_nagios('1r_1h_1s')
1032 self
.update_broker()
1035 host
= self
.sched
.hosts
.find_by_name("test_host_0")
1036 host
.checks_in_progress
= []
1037 host
.act_depend_of
= [] # ignore the router
1038 router
= self
.sched
.hosts
.find_by_name("test_router_0")
1039 router
.checks_in_progress
= []
1040 router
.act_depend_of
= [] # ignore the router
1041 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
1042 svc
.checks_in_progress
= []
1043 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
1044 self
.scheduler_loop(3, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 1, 'WARNING']])
1045 self
.update_broker()
1048 # downtime valid for the next 2 minutes
1049 cmd
= "[%lu] SCHEDULE_SVC_DOWNTIME;test_host_0;test_ok_0;%d;%d;1;0;%d;lausser;blablub" % (now
, now
, now
+ duration
, duration
)
1050 self
.sched
.run_external_command(cmd
)
1051 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
1052 svc
.checks_in_progress
= []
1053 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
1054 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
1056 cmd
= "[%lu] ADD_SVC_COMMENT;test_host_0;test_ok_0;1;lausser;comment" % now
1057 self
.sched
.run_external_command(cmd
)
1059 self
.scheduler_loop(1, [[host
, 0, 'UP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
1060 self
.update_broker()
1062 self
.scheduler_loop(3, [[host
, 2, 'DOWN'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
1063 self
.update_broker()
1065 self
.scheduler_loop(3, [[host
, 0, 'UUP'], [router
, 0, 'UP'], [svc
, 0, 'OK']], do_sleep
=False)
1066 self
.update_broker()
1068 # self.scheduler_loop(3, [[host, 0, 'UP'], [router, 2, 'DOWN'], [svc, 0, 'OK']], do_sleep=False)
1069 # self.update_broker()
1072 # show history for service
1073 request
= """GET services
1074 Filter: has_been_checked = 1
1075 Filter: check_type = 0
1076 Stats: sum has_been_checked
1078 Stats: sum execution_time
1080 Stats: min execution_time
1082 Stats: max execution_time"""
1084 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1086 # nagios comparison makes no sense, because the latencies/execution times will surely differ
1087 if self
.nagios_installed():
1088 nagresponse
= self
.ask_nagios(request
)
1091 # self.assert_(self.lines_equal(response, nagresponse))
1094 def test_columns(self
):
1096 self
.update_broker()
1097 #---------------------------------------------------------------
1098 # get the columns meta-table
1099 #---------------------------------------------------------------
1100 request
= """GET columns"""
1101 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1105 def test_scheduler_table(self
):
1107 self
.update_broker()
1109 creation_tab
= {'scheduler_name' : 'scheduler-1', 'address' : 'localhost', 'spare' : '0'}
1110 schedlink
= SchedulerLink(creation_tab
)
1111 schedlink
.pythonize()
1112 schedlink
.alive
= True
1113 b
= schedlink
.get_initial_status_brok()
1115 creation_tab
= {'scheduler_name' : 'scheduler-2', 'address' : 'othernode', 'spare' : '1'}
1116 schedlink
= SchedulerLink(creation_tab
)
1117 schedlink
.pythonize()
1118 schedlink
.alive
= True
1119 b2
= schedlink
.get_initial_status_brok()
1122 self
.update_broker()
1123 #---------------------------------------------------------------
1124 # get the columns meta-table
1125 #---------------------------------------------------------------
1126 request
= """GET schedulers"""
1127 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1129 good_response
= """address;alive;name;port;spare;weight
1130 othernode;1;scheduler-2;7768;1;1
1131 localhost;1;scheduler-1;7768;0;1
1133 print response
, 'FUCK'
1134 print "FUCK", response
, "TOTO"
1135 self
.assert_(self
.lines_equal(response
, good_response
))
1137 #Now we update a scheduler state and we check
1139 schedlink
.alive
= False
1140 b
= schedlink
.get_update_status_brok()
1142 self
.update_broker()
1143 request
= """GET schedulers"""
1144 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1145 good_response
= """address;alive;name;port;spare;weight
1146 othernode;0;scheduler-2;7768;1;1
1147 localhost;1;scheduler-1;7768;0;1
1149 self
.assert_(self
.lines_equal(response
, good_response
))
1153 def test_reactionner_table(self
):
1155 self
.update_broker()
1156 creation_tab
= {'reactionner_name' : 'reactionner-1', 'address' : 'localhost', 'spare' : '0'}
1157 reac
= ReactionnerLink(creation_tab
)
1160 b
= reac
.get_initial_status_brok()
1162 creation_tab
= {'reactionner_name' : 'reactionner-2', 'address' : 'othernode', 'spare' : '1'}
1163 reac
= ReactionnerLink(creation_tab
)
1166 b2
= reac
.get_initial_status_brok()
1169 self
.update_broker()
1170 #---------------------------------------------------------------
1171 # get the columns meta-table
1172 #---------------------------------------------------------------
1173 request
= """GET reactionners"""
1174 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1176 good_response
= """address;alive;name;port;spare
1177 localhost;1;reactionner-1;7769;0
1178 othernode;1;reactionner-2;7769;1
1180 print response
== good_response
1181 self
.assert_(self
.lines_equal(response
, good_response
))
1183 #Now the update part
1185 b2
= reac
.get_update_status_brok()
1187 self
.update_broker()
1188 request
= """GET reactionners"""
1189 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1191 good_response
= """address;alive;name;port;spare
1192 localhost;1;reactionner-1;7769;0
1193 othernode;0;reactionner-2;7769;1
1195 print response
== good_response
1196 self
.assert_(self
.lines_equal(response
, good_response
))
1200 def test_poller_table(self
):
1202 self
.update_broker()
1204 creation_tab
= {'poller_name' : 'poller-1', 'address' : 'localhost', 'spare' : '0'}
1205 pol
= PollerLink(creation_tab
)
1208 b
= pol
.get_initial_status_brok()
1210 creation_tab
= {'poller_name' : 'poller-2', 'address' : 'othernode', 'spare' : '1'}
1211 pol
= PollerLink(creation_tab
)
1214 b2
= pol
.get_initial_status_brok()
1217 self
.update_broker()
1218 #---------------------------------------------------------------
1219 # get the columns meta-table
1220 #---------------------------------------------------------------
1221 request
= """GET pollers"""
1222 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1224 good_response
= """address;alive;name;port;spare
1225 localhost;1;poller-1;7771;0
1226 othernode;1;poller-2;7771;1
1228 print response
== good_response
1229 self
.assert_(self
.lines_equal(response
, good_response
))
1231 #Now the update part
1233 b2
= pol
.get_update_status_brok()
1236 self
.update_broker()
1237 #---------------------------------------------------------------
1238 # get the columns meta-table
1239 #---------------------------------------------------------------
1240 request
= """GET pollers"""
1241 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1243 good_response
= """address;alive;name;port;spare
1244 localhost;1;poller-1;7771;0
1245 othernode;0;poller-2;7771;1
1247 print response
== good_response
1248 self
.assert_(self
.lines_equal(response
, good_response
))
1252 def test_broker_table(self
):
1254 self
.update_broker()
1256 creation_tab
= {'broker_name' : 'broker-1', 'address' : 'localhost', 'spare' : '0'}
1257 pol
= BrokerLink(creation_tab
)
1260 b
= pol
.get_initial_status_brok()
1262 creation_tab
= {'broker_name' : 'broker-2', 'address' : 'othernode', 'spare' : '1'}
1263 pol
= BrokerLink(creation_tab
)
1266 b2
= pol
.get_initial_status_brok()
1269 self
.update_broker()
1270 #---------------------------------------------------------------
1271 # get the columns meta-table
1272 #---------------------------------------------------------------
1273 request
= """GET brokers"""
1274 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1276 good_response
= """address;alive;name;port;spare
1277 localhost;1;broker-1;7772;0
1278 othernode;1;broker-2;7772;1
1280 print response
== good_response
1281 self
.assert_(response
== good_response
)
1283 #Now the update part
1285 b2
= pol
.get_initial_status_brok()
1288 self
.update_broker()
1289 #---------------------------------------------------------------
1290 # get the columns meta-table
1291 #---------------------------------------------------------------
1292 request
= """GET brokers"""
1293 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1295 good_response
= """address;alive;name;port;spare
1296 localhost;1;broker-1;7772;0
1297 othernode;0;broker-2;7772;1
1299 print response
== good_response
1300 self
.assert_(response
== good_response
)
1304 def test_problems_table(self
):
1306 self
.update_broker()
1307 host
= self
.sched
.hosts
.find_by_name("test_host_0")
1308 host
.checks_in_progress
= []
1309 host
.act_depend_of
= [] # ignore the router
1310 router
= self
.sched
.hosts
.find_by_name("test_router_0")
1311 router
.checks_in_progress
= []
1312 router
.act_depend_of
= [] # ignore the router
1313 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
1314 svc
.checks_in_progress
= []
1315 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
1316 self
.scheduler_loop(4, [[host
, 2, 'DOWN'], [router
, 2, 'DOWN'], [svc
, 2, 'BAD']])
1317 print "Is router a problem?", router
.is_problem
, router
.state
, router
.state_type
1318 print "Is host a problem?", host
.is_problem
, host
.state
, host
.state_type
1319 print "Is service a problem?", svc
.is_problem
, svc
.state
, svc
.state_type
1320 self
.update_broker()
1321 print "All", self
.livestatus_broker
.hosts
1322 for h
in self
.livestatus_broker
.hosts
.values():
1323 print h
.get_dbg_name(), h
.is_problem
1325 #---------------------------------------------------------------
1326 # get the columns meta-table
1327 #---------------------------------------------------------------
1328 request
= """GET problems"""
1329 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1330 print "FUCK", response
1331 good_response
= """impacts;source
1332 test_host_0,test_host_0/test_ok_0;test_router_0
1334 print response
== good_response
1335 self
.assert_(response
== good_response
)
1339 def test_limit(self
):
1341 if self
.nagios_installed():
1342 self
.start_nagios('1r_1h_1s')
1344 self
.update_broker()
1345 #---------------------------------------------------------------
1346 # get the full hosts table
1347 #---------------------------------------------------------------
1348 request
= 'GET hosts\nColumns: host_name\n'
1349 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1351 good_response
= """test_host_0
1354 self
.assert_(self
.lines_equal(response
, good_response
))
1356 request
= 'GET hosts\nColumns: host_name\nLimit: 1\n'
1357 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1359 good_response
= """test_host_0
1361 # it must be test_host_0 because with Limit: the output is
1362 # alphabetically ordered
1363 self
.assert_(response
== good_response
)
1364 # TODO look whats wrong
1365 if self
.nagios_installed():
1366 nagresponse
= self
.ask_nagios(request
)
1369 # self.assert_(self.lines_equal(response, nagresponse))
1373 def test_problem_impact_in_host_service(self
):
1376 self
.update_broker()
1378 host_router_0
= self
.sched
.hosts
.find_by_name("test_router_0")
1379 host_router_0
.checks_in_progress
= []
1381 #Then initialize host under theses routers
1382 host_0
= self
.sched
.hosts
.find_by_name("test_host_0")
1383 host_0
.checks_in_progress
= []
1385 all_hosts
= [host_router_0
, host_0
]
1386 all_routers
= [host_router_0
]
1387 all_servers
= [host_0
]
1389 print "- 4 x UP -------------------------------------"
1390 self
.scheduler_loop(1, [[host_router_0
, 0, 'UP'], [host_0
, 0, 'UP']], do_sleep
=False)
1391 self
.scheduler_loop(1, [[host_router_0
, 1, 'DOWN']], do_sleep
=False)
1392 self
.scheduler_loop(1, [[host_router_0
, 1, 'DOWN']], do_sleep
=False)
1393 self
.scheduler_loop(1, [[host_router_0
, 1, 'DOWN']], do_sleep
=False)
1394 self
.scheduler_loop(1, [[host_router_0
, 1, 'DOWN']], do_sleep
=False)
1395 self
.scheduler_loop(1, [[host_router_0
, 1, 'DOWN']], do_sleep
=False)
1397 #Max attempt is reach, should be HARD now
1398 for h
in all_routers
:
1399 self
.assert_(h
.state
== 'DOWN')
1400 self
.assert_(h
.state_type
== 'HARD')
1402 for b
in self
.sched
.broks
.values():
1403 print "All broks", b
.type, b
1404 if b
.type == 'update_host_status':
1406 print "Impacts", b
.data
['impacts']
1407 print "Sources", b
.data
['source_problems']
1409 for b
in host_router_0
.broks
:
1410 print " host_router_0.broks", b
1412 self
.update_broker()
1414 print "source de host_0", host_0
.source_problems
1415 for i
in host_0
.source_problems
:
1416 print "source", i
.get_name()
1417 print "impacts de host_router_0", host_router_0
.impacts
1418 for i
in host_router_0
.impacts
:
1419 print "impact", i
.get_name()
1421 #---------------------------------------------------------------
1422 # get the full hosts table
1423 #---------------------------------------------------------------
1424 print "Got source problems"
1425 request
= 'GET hosts\nColumns: host_name is_impact source_problems\n'
1426 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1427 print "moncul", response
1428 #good_response = """test_host_0
1431 #self.assert_(self.lines_equal(response, good_response))
1433 print "Now got impact"
1434 request
= 'GET hosts\nColumns: host_name is_problem impacts\n'
1435 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1436 print "moncul", response
1437 good_response
= """test_host_0
1440 # self.assert_(self.lines_equal(response, good_response))
1442 request
= 'GET hosts\nColumns: host_name\nLimit: 1\n'
1443 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1445 good_response
= """test_host_0
1447 # it must be test_host_0 because with Limit: the output is
1448 # alphabetically ordered
1449 # self.assert_(response == good_response)
1453 def test_thruk_servicegroup(self
):
1456 self
.update_broker()
1457 #---------------------------------------------------------------
1458 # get services of a certain servicegroup
1459 # test_host_0/test_ok_0 is in
1460 # servicegroup_01,ok via service.servicegroups
1461 # servicegroup_02 via servicegroup.members
1462 #---------------------------------------------------------------
1463 request
= """GET services
1464 Columns: host_name service_description
1465 Filter: groups >= servicegroup_01
1467 ResponseHeader: fixed16
1469 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1470 self
.assert_(response
== """200 22
1471 test_host_0;test_ok_0
1473 request
= """GET services
1474 Columns: host_name service_description
1475 Filter: groups >= servicegroup_02
1477 ResponseHeader: fixed16
1479 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1480 self
.assert_(response
== """200 22
1481 test_host_0;test_ok_0
1486 def test_is_executing(self
):
1488 #---------------------------------------------------------------
1489 # make sure that the is_executing flag is updated regularly
1490 #---------------------------------------------------------------
1492 host
= self
.sched
.hosts
.find_by_name("test_host_0")
1493 host
.checks_in_progress
= []
1494 host
.act_depend_of
= [] # ignore the router
1495 router
= self
.sched
.hosts
.find_by_name("test_router_0")
1496 router
.checks_in_progress
= []
1497 router
.act_depend_of
= [] # ignore the router
1498 svc
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_0", "test_ok_0")
1499 svc
.checks_in_progress
= []
1500 svc
.act_depend_of
= [] # no hostchecks on critical checkresults
1502 for loop
in range(1, 2):
1503 print "processing check", loop
1504 self
.show_broks("update_in_checking")
1505 svc
.update_in_checking()
1506 self
.show_broks("fake_check")
1507 self
.fake_check(svc
, 2, 'BAD')
1508 self
.show_broks("sched.consume_results")
1509 self
.sched
.consume_results()
1510 self
.show_broks("sched.get_new_actions")
1511 self
.sched
.get_new_actions()
1512 self
.show_broks("sched.get_new_broks")
1513 self
.sched
.get_new_broks()
1514 self
.show_broks("sched.delete_zombie_checks")
1515 self
.sched
.delete_zombie_checks()
1516 self
.show_broks("sched.delete_zombie_actions")
1517 self
.sched
.delete_zombie_actions()
1518 self
.show_broks("sched.get_to_run_checks")
1519 checks
= self
.sched
.get_to_run_checks(True, False)
1520 self
.show_broks("sched.get_to_run_checks")
1521 actions
= self
.sched
.get_to_run_checks(False, True)
1522 #self.show_actions()
1524 a
.status
= 'inpoller'
1525 a
.check_time
= time
.time()
1527 self
.sched
.put_results(a
)
1528 #self.show_actions()
1530 svc
.checks_in_progress
= []
1531 self
.show_broks("sched.update_downtimes_and_comments")
1532 self
.sched
.update_downtimes_and_comments()
1535 print "-------------------------------------------------"
1536 for brok
in sorted(self
.sched
.broks
.values(), lambda x
, y
: x
.id - y
.id):
1537 if re
.compile('^service_').match(brok
.type):
1538 print "BROK:", brok
.type
1539 print "BROK ", brok
.data
['in_checking']
1540 self
.update_broker()
1541 print "-------------------------------------------------"
1542 request
= 'GET services\nColumns: service_description is_executing\n'
1543 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1548 class TestConfigBig(TestConfig
):
1550 self
.setup_with_file('etc/nagios_5r_100h_2000s.cfg')
1551 self
.livestatus_broker
= Livestatus_broker('livestatus', '127.0.0.1', str(50000 + os
.getpid()), 'live', '/tmp/livelogs.db' + str(os
.getpid()))
1552 self
.livestatus_broker
.properties
= {
1557 self
.livestatus_broker
.init()
1558 print "Cleaning old broks?"
1559 self
.sched
.fill_initial_broks()
1560 self
.update_broker()
1564 if os
.path
.exists('/tmp/livelogs.db' + str(os
.getpid())):
1565 os
.remove('/tmp/livelogs.db' + str(os
.getpid()))
1568 def test_stats(self
):
1570 if self
.nagios_installed():
1571 self
.start_nagios('5r_100h_2000s')
1574 for host
in self
.sched
.hosts
:
1575 objlist
.append([host
, 0, 'UP'])
1576 for service
in self
.sched
.services
:
1577 objlist
.append([service
, 0, 'OK'])
1578 self
.scheduler_loop(1, objlist
)
1579 self
.update_broker()
1580 svc1
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_005", "test_ok_00")
1582 svc2
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_005", "test_ok_15")
1584 svc3
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_005", "test_ok_16")
1586 svc4
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_007", "test_ok_05")
1588 svc5
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_007", "test_ok_11")
1589 svc6
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_025", "test_ok_01")
1590 svc7
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_025", "test_ok_03")
1591 self
.scheduler_loop(1, [[svc1
, 1, 'W'], [svc2
, 1, 'W'], [svc3
, 1, 'W'], [svc4
, 2, 'C'], [svc5
, 3, 'U'], [svc6
, 2, 'C'], [svc7
, 2, 'C']])
1592 self
.update_broker()
1593 # 1993O, 3xW, 3xC, 1xU
1595 request
= """GET services
1596 Filter: contacts >= test_contact
1597 Stats: state != 9999
1602 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1603 print 'query_6_______________\n%s\n%s\n' % (request
, response
)
1604 self
.assert_(response
== '2000;1993;3;3;1\n')
1605 if self
.nagios_installed():
1606 nagresponse
= self
.ask_nagios(request
)
1609 self
.assert_(self
.lines_equal(response
, nagresponse
))
1612 def test_statsgroupby(self
):
1614 if self
.nagios_installed():
1615 self
.start_nagios('5r_100h_2000s')
1618 for host
in self
.sched
.hosts
:
1619 objlist
.append([host
, 0, 'UP'])
1620 for service
in self
.sched
.services
:
1621 objlist
.append([service
, 0, 'OK'])
1622 self
.scheduler_loop(1, objlist
)
1623 self
.update_broker()
1624 svc1
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_005", "test_ok_00")
1626 svc2
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_005", "test_ok_15")
1628 svc3
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_005", "test_ok_16")
1630 svc4
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_007", "test_ok_05")
1632 svc5
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_007", "test_ok_11")
1633 svc6
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_025", "test_ok_01")
1634 svc7
= self
.sched
.services
.find_srv_by_name_and_hostname("test_host_025", "test_ok_03")
1635 self
.scheduler_loop(1, [[svc1
, 1, 'W'], [svc2
, 1, 'W'], [svc3
, 1, 'W'], [svc4
, 2, 'C'], [svc5
, 3, 'U'], [svc6
, 2, 'C'], [svc7
, 2, 'C']])
1636 self
.update_broker()
1637 # 1993O, 3xW, 3xC, 1xU
1639 request
= 'GET services\nFilter: contacts >= test_contact\nStats: state != 9999\nStats: state = 0\nStats: state = 1\nStats: state = 2\nStats: state = 3\nStatsGroupBy: host_name'
1640 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1642 self
.assert_(self
.contains_line(response
, 'test_host_005;20;17;3;0;0'))
1643 self
.assert_(self
.contains_line(response
, 'test_host_007;20;18;0;1;1'))
1644 self
.assert_(self
.contains_line(response
, 'test_host_025;20;18;0;2;0'))
1645 self
.assert_(self
.contains_line(response
, 'test_host_026;20;20;0;0;0'))
1647 request
= """GET services
1648 Stats: state != 9999
1651 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1653 self
.assert_(self
.contains_line(response
, '0;1993'))
1654 self
.assert_(self
.contains_line(response
, '1;3'))
1655 self
.assert_(self
.contains_line(response
, '2;3'))
1656 self
.assert_(self
.contains_line(response
, '3;1'))
1657 if self
.nagios_installed():
1658 nagresponse
= self
.ask_nagios(request
)
1661 self
.assert_(self
.lines_equal(response
, nagresponse
))
1664 def test_hostsbygroup(self
):
1666 if self
.nagios_installed():
1667 self
.start_nagios('5r_100h_2000s')
1670 for host
in self
.sched
.hosts
:
1671 objlist
.append([host
, 0, 'UP'])
1672 for service
in self
.sched
.services
:
1673 objlist
.append([service
, 0, 'OK'])
1674 self
.scheduler_loop(1, objlist
)
1675 self
.update_broker()
1676 request
= """GET hostsbygroup
1678 Columns: host_name hostgroup_name
1681 ResponseHeader: fixed16
1684 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1686 if self
.nagios_installed():
1687 nagresponse
= self
.ask_nagios(request
)
1690 self
.assert_(self
.lines_equal(response
, nagresponse
))
1693 def test_servicesbyhostgroup(self
):
1695 if self
.nagios_installed():
1696 self
.start_nagios('5r_100h_2000s')
1699 for host
in self
.sched
.hosts
:
1700 objlist
.append([host
, 0, 'UP'])
1701 for service
in self
.sched
.services
:
1702 objlist
.append([service
, 0, 'OK'])
1703 self
.scheduler_loop(1, objlist
)
1704 self
.update_broker()
1705 request
= """GET servicesbyhostgroup
1706 Filter: host_groups >= up
1707 Stats: has_been_checked = 0
1709 Stats: has_been_checked != 0
1710 Stats: scheduled_downtime_depth = 0
1711 Stats: host_scheduled_downtime_depth = 0
1714 Stats: scheduled_downtime_depth > 0
1715 Stats: host_scheduled_downtime_depth > 0
1718 Stats: acknowledged = 0
1719 Stats: host_acknowledged = 0
1720 Stats: scheduled_downtime_depth = 0
1721 Stats: host_scheduled_downtime_depth = 0
1724 Stats: acknowledged = 1
1725 Stats: host_acknowledged = 1
1729 Stats: scheduled_downtime_depth > 0
1730 Stats: host_scheduled_downtime_depth > 0
1734 Stats: acknowledged = 0
1735 Stats: host_acknowledged = 0
1736 Stats: scheduled_downtime_depth = 0
1737 Stats: host_scheduled_downtime_depth = 0
1740 Stats: acknowledged = 1
1741 Stats: host_acknowledged = 1
1745 Stats: scheduled_downtime_depth > 0
1746 Stats: host_scheduled_downtime_depth > 0
1750 Stats: acknowledged = 0
1751 Stats: host_acknowledged = 0
1752 Stats: scheduled_downtime_depth = 0
1753 Stats: host_scheduled_downtime_depth = 0
1756 Stats: acknowledged = 1
1757 Stats: host_acknowledged = 1
1761 Stats: scheduled_downtime_depth > 0
1762 Stats: host_scheduled_downtime_depth > 0
1765 StatsGroupBy: hostgroup_name
1768 ResponseHeader: fixed16
1771 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1773 print "livestatus duration %f" % (tac
- tic
)
1775 if self
.nagios_installed():
1776 nagresponse
= self
.ask_nagios(request
)
1778 self
.assert_(self
.lines_equal(response
, nagresponse
))
1780 # Again, without Filter:
1781 request
= """GET servicesbyhostgroup
1782 Stats: has_been_checked = 0
1784 Stats: has_been_checked != 0
1785 Stats: scheduled_downtime_depth = 0
1786 Stats: host_scheduled_downtime_depth = 0
1789 Stats: scheduled_downtime_depth > 0
1790 Stats: host_scheduled_downtime_depth > 0
1793 Stats: acknowledged = 0
1794 Stats: host_acknowledged = 0
1795 Stats: scheduled_downtime_depth = 0
1796 Stats: host_scheduled_downtime_depth = 0
1799 Stats: acknowledged = 1
1800 Stats: host_acknowledged = 1
1804 Stats: scheduled_downtime_depth > 0
1805 Stats: host_scheduled_downtime_depth > 0
1809 Stats: acknowledged = 0
1810 Stats: host_acknowledged = 0
1811 Stats: scheduled_downtime_depth = 0
1812 Stats: host_scheduled_downtime_depth = 0
1815 Stats: acknowledged = 1
1816 Stats: host_acknowledged = 1
1820 Stats: scheduled_downtime_depth > 0
1821 Stats: host_scheduled_downtime_depth > 0
1825 Stats: acknowledged = 0
1826 Stats: host_acknowledged = 0
1827 Stats: scheduled_downtime_depth = 0
1828 Stats: host_scheduled_downtime_depth = 0
1831 Stats: acknowledged = 1
1832 Stats: host_acknowledged = 1
1836 Stats: scheduled_downtime_depth > 0
1837 Stats: host_scheduled_downtime_depth > 0
1840 StatsGroupBy: hostgroup_name
1843 ResponseHeader: fixed16
1845 response
, keepalive
= self
.livestatus_broker
.livestatus
.handle_request(request
)
1847 if self
.nagios_installed():
1848 nagresponse
= self
.ask_nagios(request
)
1851 self
.assert_(self
.lines_equal(response
, nagresponse
))
1855 if __name__
== '__main__':
1857 command
= """unittest.main()"""
1859 #cProfile.runctx( command, globals(), locals(), filename="Thruk.profile" )