10 from signal
import signal
, SIGTERM
, SIGINT
, SIGPIPE
, SIG_DFL
12 SESSIOND_BIN_NAME
= "lttng-sessiond"
13 SESSIOND_BIN_PATH
= "src/bin/lttng-sessiond/"
14 CONSUMERD_BIN_NAME
= "lttng-consumerd"
15 CONSUMERD_BIN_PATH
= "src/bin/lttng-consumerd/"
18 PRINT_BRACKET
= "\033[1;34m[\033[1;33m+\033[1;34m]\033[00m"
19 PRINT_RED_BRACKET
= "\033[1;31m[+]\033[00m"
20 PRINT_GREEN_BRACKET
= "\033[1;32m[+]\033[00m"
21 PRINT_ARROW
= "\033[1;32m-->\033[00m"
27 top_cpu_legend
= { 'us': "User CPU time", 'sy': "System CPU time",
28 'id': "Idle CPU time", 'ni': "Nice CPU time", 'wa': "iowait",
29 'hi': "Hardware IRQ", 'si': "Software Interrupts", 'st': "Steal Time", }
31 cpu_ret_q
= Queue
.Queue()
32 mem_ret_q
= Queue
.Queue()
33 test_ret_q
= Queue
.Queue()
38 def cpu_create_usage_dict(top_line
):
40 Return a dictionnary from a 'top' cpu line.
41 Ex: Cpu(s): 2.1%us, 1.2%sy, 0.0%ni, 96.2%id, 0.4%wa, 0.0%hi, 0.0%si, 0.0%st
43 top_dict
= {'us': 0, 'sy': 0, 'ni': 0, 'id': 0, 'wa': 0, 'hi': 0, 'si': 0, 'st': 0}
45 # Split expression and remove first value which is "Cpu(s)"
46 top_line
= top_line
.replace(",","")
47 words
= top_line
.split()[1:]
51 index
= words
.index(key
)
52 # Add the value to the dictionnary
54 top_dict
[key
] = float(val
)
58 def cpu_average_usage(top_lines
):
60 Return a dictionnary of 'top' CPU stats but averaging all values.
62 avg_dict
= {'us': 0, 'sy': 0, 'ni': 0, 'id': 0, 'wa': 0, 'hi': 0, 'si': 0, 'st': 0}
66 for line
in top_lines
:
67 tmp_dict
= cpu_create_usage_dict(line
)
68 # Add value to avg dictionnary
70 avg_dict
[key
] += tmp_dict
[key
]
75 avg_dict
[key
] = avg_dict
[key
] / count
77 return (count
, avg_dict
)
79 def cpu_sample_usage(pid
=None):
81 Sample CPU usage for num iterations.
82 If num is greater than 1, the average will be computed.
84 args
= ["top", "-b", "-n", "1"]
90 top
= subprocess
.Popen(args
, stdout
= subprocess
.PIPE
)
92 grep
= subprocess
.Popen(["grep", "Cpu"], stdin
= top
.stdout
,
93 stdout
= subprocess
.PIPE
)
96 return grep
.communicate()[0].strip("\n")
98 def mem_sample_usage(pid
):
100 Sample memory usage using /proc and a pid
102 args
= ["cat", "/proc/" + str(pid
) + "/status"]
104 if not os
.path
.isfile(args
[1]):
107 mem_proc
= subprocess
.Popen(args
, stdout
= subprocess
.PIPE
)
109 grep
= subprocess
.Popen(["grep", "^VmRSS"], stdin
= mem_proc
.stdout
,
110 stdout
= subprocess
.PIPE
)
111 mem_proc
.stdout
.close()
113 # Return virtual memory size in kilobytes (kB)
114 #ret = grep.communicate()[0].split()
115 ret
= grep
.communicate()[0].split()
124 class SamplingWorker(threading
.Thread
):
125 def __init__(self
, s_type
, worker
= None, delay
= 0.2, pid
= 0):
126 threading
.Thread
.__init
__ (self
)
136 if self
.s_type
== "cpu":
138 if self
.worker
== None:
139 cpu_line
= cpu_sample_usage(self
.pid
)
140 lines
.append(cpu_line
)
142 elif self
.worker
.is_alive():
143 cpu_line
= cpu_sample_usage(self
.pid
)
144 lines
.append(cpu_line
)
148 # Delay sec per memory sampling
149 time
.sleep(self
.delay
)
151 count
, stats
= cpu_average_usage(lines
)
152 cpu_ret_q
.put((count
, stats
))
153 # grep process has ended here
155 elif self
.s_type
== "mem":
160 if self
.worker
== None:
161 cpu_line
= cpu_sample_usage(self
.pid
)
162 lines
.append(cpu_line
)
164 elif self
.worker
.is_alive():
165 mem_stat
+= get_mem_usage(self
.pid
)
170 # Delay sec per memory sampling
171 time
.sleep(self
.delay
)
173 mem_ret_q
.put((count
, mem_stat
))
175 class TestWorker(threading
.Thread
):
176 def __init__(self
, path
, name
):
177 threading
.Thread
.__init
__(self
)
182 bin_path_name
= os
.path
.join(self
.path
, self
.name
)
185 env
['TEST_NO_SESSIOND'] = '1'
187 test
= subprocess
.Popen([bin_path_name
], env
=env
, preexec_fn
= lambda: signal(SIGPIPE
, SIG_DFL
))
190 # Send ret value to main thread
191 test_ret_q
.put(test
.returncode
)
193 def get_pid(procname
):
195 Return pid of process name using 'pidof' command
197 pidof
= subprocess
.Popen(["pidof", procname
], stdout
= subprocess
.PIPE
)
198 pid
= pidof
.communicate()[0].split()
205 def spawn_session_daemon():
207 Exec the session daemon and return PID
211 pid
= get_pid(SESSIOND_BIN_NAME
)
213 os
.kill(pid
, SIGTERM
)
215 bin_path
= os
.path
.join(TESTDIR_PATH
, "..", SESSIOND_BIN_PATH
, SESSIOND_BIN_NAME
)
216 consumer_path
= os
.path
.join(TESTDIR_PATH
, "..", CONSUMERD_BIN_PATH
, CONSUMERD_BIN_NAME
)
218 if not os
.path
.isfile(bin_path
):
219 print "Error: No session daemon binary found. Compiled?"
223 args
= shlex
.split("libtool execute " + bin_path
224 + " --consumerd32-path=" + consumer_path
225 + " --consumerd64-path=" + consumer_path
)
227 sdaemon_proc
= subprocess
.Popen(args
, shell
= False, stderr
= subprocess
.PIPE
)
235 return get_pid("lt-" + SESSIOND_BIN_NAME
)
237 def start_test(name
):
239 Spawn test and return exit code
241 tw
= TestWorker(".", name
)
244 return test_ret_q
.get(True)
246 def print_cpu_stats(stats
, count
):
248 Pretty print on one line the CPU stats
250 sys
.stdout
.write(PRINT_ARROW
+ " Cpu [sampled %d time(s)]:\n " % (count
))
252 sys
.stdout
.write(" %s: %.2f, " % (stat
, stats
[stat
]))
255 def get_cpu_usage(delay
=1, pid
=0):
257 Spawn a worker thread to sample cpu usage.
259 sw
= SamplingWorker("cpu", delay
= delay
, pid
= pid
)
262 return cpu_ret_q
.get(True)
264 def get_mem_usage(pid
):
266 Get memory usage for PID
268 return mem_sample_usage(pid
)
270 def print_test_success(ret
, expect
):
272 Print if test has failed or pass according to the expected value.
275 print "\n" + PRINT_RED_BRACKET
+ \
276 " Failed: ret = %d (expected %d)" % (ret
, expect
)
279 print "\n" + PRINT_BRACKET
+ \
280 " Passed: ret = %d (expected %d)" % (ret
, expect
)
285 Run test 'name' and output report of the test with stats.
289 dem_pid
= 0 # Session daemon pid
291 print PRINT_BRACKET
+ " %s" % (test
['name'])
292 print PRINT_ARROW
+ " %s" % (test
['desc'])
294 print PRINT_ARROW
+ " Statistics will NOT be collected"
296 print PRINT_ARROW
+ " Statistics of the session daemon will be collected"
298 if test
['kern'] and not is_root
:
299 print "Needs root for kernel tracing. Skipping"
302 if not os
.path
.isfile(test
['bin']):
303 print "Unable to find test file '%s'. Skipping" % (test
['bin'])
306 # No session daemon needed
307 if not test
['daemon']:
308 print PRINT_ARROW
+ " No session daemon needed"
309 ret
= start_test(test
['bin'])
310 print_test_success(ret
, test
['success'])
313 print PRINT_ARROW
+ " Session daemon needed"
315 dem_pid
= spawn_session_daemon()
317 print "Unable to start %s. Stopping" % (SESSIOND_BIN_NAME
)
318 print sdaemon_proc
.communicate()[1]
321 print PRINT_BRACKET
+ " Session daemon spawned (pid: %d)\n" % (dem_pid
)
324 mem_before
= get_mem_usage(dem_pid
)
325 print PRINT_BRACKET
+ " Stats *before* test:"
326 print PRINT_ARROW
+ " Mem (kB): %d" % (mem_before
)
327 cpu_count
, cpu_stats
= get_cpu_usage(pid
= dem_pid
)
328 print_cpu_stats(cpu_stats
, cpu_count
)
330 tw
= TestWorker(".", test
['bin'])
334 # Start CPU sampling for test
335 sw_cpu
= SamplingWorker("cpu", worker
= tw
, pid
= dem_pid
)
337 sw_mem
= SamplingWorker("mem", worker
= tw
, pid
= dem_pid
)
340 ret
= test_ret_q
.get(True)
344 # Compute memory average
345 mem_count
, mem_during
= mem_ret_q
.get(True)
346 mem_during
= float(mem_during
) / float(mem_count
)
347 cpu_count
, cpu_stats
= cpu_ret_q
.get(True)
349 print "\n" + PRINT_BRACKET
+ " Stats *during* test:"
350 print PRINT_ARROW
+ " Mem (kB): %.0f [sampled %d time(s)]" % (mem_during
, mem_count
)
351 print_cpu_stats(cpu_stats
, cpu_count
)
353 mem_after
= get_mem_usage(dem_pid
)
354 print "\n" + PRINT_BRACKET
+ " Stats *after* test:"
355 print PRINT_ARROW
+ " Mem (kB): %d" % (mem_after
)
356 cpu_count
, cpu_stats
= get_cpu_usage(pid
= dem_pid
)
357 print_cpu_stats(cpu_stats
, cpu_count
)
359 print "\n" + PRINT_BRACKET
+ " Memory usage differences:"
360 print PRINT_ARROW
+ " Diff during and before (kB): %d" % (mem_during
- mem_before
)
361 print PRINT_ARROW
+ " Diff during and after (kB): %d" % (mem_during
- mem_after
)
362 print PRINT_ARROW
+ " Diff before and after (kB): %d" % (mem_after
- mem_before
)
364 # Return value of 0 means that is passed else it failed
365 ret
= print_test_success(ret
, test
['success'])
367 # Stop session daemon
369 print PRINT_BRACKET
+ " Stopping session daemon (pid: %d)..." % (dem_pid
)
371 os
.kill(dem_pid
, SIGTERM
)
372 # This call simply does not work... It seems python does not relay the signal
373 # to the child processes of sdaemon_proc.
374 # sdaemon_proc.terminate()
376 print sdaemon_proc
.communicate()[1]
377 elif sdaemon_proc
.returncode
== None:
378 sdaemon_proc
.communicate()
382 # Make sure all thread are released
392 if not test
['enabled']:
397 # Stop all tests, the last one failed
401 def cleanup(signo
, stack
):
402 """ Cleanup function """
405 if __name__
== "__main__":
406 if not os
.getuid() == 0:
408 print "NOTICE: Not root. No kernel tracing will be tested\n"
410 if os
.path
.isfile("test_list.py"):
411 from test_list
import Tests
413 print "No test_list.py found. Stopping"
416 TESTDIR_PATH
= os
.getcwd()
418 if len(sys
.argv
) > 1:
419 if sys
.argv
[1] == "--no-stats":
423 signal(SIGTERM
, cleanup
)
424 signal(SIGINT
, cleanup
)
427 except KeyboardInterrupt:
This page took 0.038311 seconds and 4 git commands to generate.