10 from signal
import signal
, SIGTERM
, SIGINT
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:]
50 index
= word
.find('%')
51 # Add the value to the dictionnary
52 top_dict
[word
[index
+ 1:]] = float(word
[:index
])
56 def cpu_average_usage(top_lines
):
58 Return a dictionnary of 'top' CPU stats but averaging all values.
60 avg_dict
= {'us': 0, 'sy': 0, 'ni': 0, 'id': 0, 'wa': 0, 'hi': 0, 'si': 0, 'st': 0}
64 for line
in top_lines
:
65 tmp_dict
= cpu_create_usage_dict(line
)
66 # Add value to avg dictionnary
68 avg_dict
[key
] += tmp_dict
[key
]
73 avg_dict
[key
] = avg_dict
[key
] / count
75 return (count
, avg_dict
)
77 def cpu_sample_usage(pid
=None):
79 Sample CPU usage for num iterations.
80 If num is greater than 1, the average will be computed.
82 args
= ["top", "-b", "-n", "1"]
88 top
= subprocess
.Popen(args
, stdout
= subprocess
.PIPE
)
90 grep
= subprocess
.Popen(["grep", "^Cpu"], stdin
= top
.stdout
,
91 stdout
= subprocess
.PIPE
)
94 return grep
.communicate()[0].strip("\n")
96 def mem_sample_usage(pid
):
98 Sample memory usage using /proc and a pid
100 args
= ["cat", "/proc/" + str(pid
) + "/status"]
102 if not os
.path
.isfile(args
[1]):
105 mem_proc
= subprocess
.Popen(args
, stdout
= subprocess
.PIPE
)
107 grep
= subprocess
.Popen(["grep", "^VmRSS"], stdin
= mem_proc
.stdout
,
108 stdout
= subprocess
.PIPE
)
109 mem_proc
.stdout
.close()
111 # Return virtual memory size in kilobytes (kB)
112 #ret = grep.communicate()[0].split()
113 ret
= grep
.communicate()[0].split()
122 class SamplingWorker(threading
.Thread
):
123 def __init__(self
, s_type
, worker
= None, delay
= 0.2, pid
= 0):
124 threading
.Thread
.__init
__ (self
)
134 if self
.s_type
== "cpu":
136 if self
.worker
== None:
137 cpu_line
= cpu_sample_usage(self
.pid
)
138 lines
.append(cpu_line
)
140 elif self
.worker
.is_alive():
141 cpu_line
= cpu_sample_usage(self
.pid
)
142 lines
.append(cpu_line
)
146 # Delay sec per memory sampling
147 time
.sleep(self
.delay
)
149 count
, stats
= cpu_average_usage(lines
)
150 cpu_ret_q
.put((count
, stats
))
151 # grep process has ended here
153 elif self
.s_type
== "mem":
158 if self
.worker
== None:
159 cpu_line
= cpu_sample_usage(self
.pid
)
160 lines
.append(cpu_line
)
162 elif self
.worker
.is_alive():
163 mem_stat
+= get_mem_usage(self
.pid
)
168 # Delay sec per memory sampling
169 time
.sleep(self
.delay
)
171 mem_ret_q
.put((count
, mem_stat
))
173 class TestWorker(threading
.Thread
):
174 def __init__(self
, path
, name
):
175 threading
.Thread
.__init
__(self
)
180 bin_path_name
= os
.path
.join(self
.path
, self
.name
)
183 env
['TEST_NO_SESSIOND'] = '1'
185 test
= subprocess
.Popen([bin_path_name
], env
=env
)
188 # Send ret value to main thread
189 test_ret_q
.put(test
.returncode
)
191 def get_pid(procname
):
193 Return pid of process name using 'pidof' command
195 pidof
= subprocess
.Popen(["pidof", procname
], stdout
= subprocess
.PIPE
)
196 pid
= pidof
.communicate()[0].split()
203 def spawn_session_daemon():
205 Exec the session daemon and return PID
209 pid
= get_pid(SESSIOND_BIN_NAME
)
211 os
.kill(pid
, SIGTERM
)
213 bin_path
= os
.path
.join(TESTDIR_PATH
, "..", SESSIOND_BIN_PATH
, SESSIOND_BIN_NAME
)
214 consumer_path
= os
.path
.join(TESTDIR_PATH
, "..", CONSUMERD_BIN_PATH
, CONSUMERD_BIN_NAME
)
216 if not os
.path
.isfile(bin_path
):
217 print "Error: No session daemon binary found. Compiled?"
221 args
= shlex
.split("libtool execute " + bin_path
222 + " --consumerd32-path=" + consumer_path
223 + " --consumerd64-path=" + consumer_path
)
225 sdaemon_proc
= subprocess
.Popen(args
, shell
= False, stderr
= subprocess
.PIPE
)
233 return get_pid("lt-" + SESSIOND_BIN_NAME
)
235 def start_test(name
):
237 Spawn test and return exit code
239 tw
= TestWorker(".", name
)
242 return test_ret_q
.get(True)
244 def print_cpu_stats(stats
, count
):
246 Pretty print on one line the CPU stats
248 sys
.stdout
.write(PRINT_ARROW
+ " Cpu [sampled %d time(s)]:\n " % (count
))
250 sys
.stdout
.write(" %s: %.2f, " % (stat
, stats
[stat
]))
253 def get_cpu_usage(delay
=1, pid
=0):
255 Spawn a worker thread to sample cpu usage.
257 sw
= SamplingWorker("cpu", delay
= delay
, pid
= pid
)
260 return cpu_ret_q
.get(True)
262 def get_mem_usage(pid
):
264 Get memory usage for PID
266 return mem_sample_usage(pid
)
268 def print_test_success(ret
, expect
):
270 Print if test has failed or pass according to the expected value.
273 print "\n" + PRINT_RED_BRACKET
+ \
274 " Failed: ret = %d (expected %d)" % (ret
, expect
)
277 print "\n" + PRINT_BRACKET
+ \
278 " Passed: ret = %d (expected %d)" % (ret
, expect
)
283 Run test 'name' and output report of the test with stats.
287 dem_pid
= 0 # Session daemon pid
289 print PRINT_BRACKET
+ " %s" % (test
['name'])
290 print PRINT_ARROW
+ " %s" % (test
['desc'])
292 print PRINT_ARROW
+ " Statistics will NOT be collected"
294 print PRINT_ARROW
+ " Statistics of the session daemon will be collected"
296 if test
['kern'] and not is_root
:
297 print "Needs root for kernel tracing. Skipping"
300 if not os
.path
.isfile(test
['bin']):
301 print "Unable to find test file '%s'. Skipping" % (test
['bin'])
304 # No session daemon needed
305 if not test
['daemon']:
306 print PRINT_ARROW
+ " No session daemon needed"
307 ret
= start_test(test
['bin'])
308 print_test_success(ret
, test
['success'])
311 print PRINT_ARROW
+ " Session daemon needed"
313 dem_pid
= spawn_session_daemon()
315 print "Unable to start %s. Stopping" % (SESSIOND_BIN_NAME
)
316 print sdaemon_proc
.communicate()[1]
319 print PRINT_BRACKET
+ " Session daemon spawned (pid: %d)\n" % (dem_pid
)
322 mem_before
= get_mem_usage(dem_pid
)
323 print PRINT_BRACKET
+ " Stats *before* test:"
324 print PRINT_ARROW
+ " Mem (kB): %d" % (mem_before
)
325 cpu_count
, cpu_stats
= get_cpu_usage(pid
= dem_pid
)
326 print_cpu_stats(cpu_stats
, cpu_count
)
328 tw
= TestWorker(".", test
['bin'])
332 # Start CPU sampling for test
333 sw_cpu
= SamplingWorker("cpu", worker
= tw
, pid
= dem_pid
)
335 sw_mem
= SamplingWorker("mem", worker
= tw
, pid
= dem_pid
)
338 ret
= test_ret_q
.get(True)
342 # Compute memory average
343 mem_count
, mem_during
= mem_ret_q
.get(True)
344 mem_during
= float(mem_during
) / float(mem_count
)
345 cpu_count
, cpu_stats
= cpu_ret_q
.get(True)
347 print "\n" + PRINT_BRACKET
+ " Stats *during* test:"
348 print PRINT_ARROW
+ " Mem (kB): %.0f [sampled %d time(s)]" % (mem_during
, mem_count
)
349 print_cpu_stats(cpu_stats
, cpu_count
)
351 mem_after
= get_mem_usage(dem_pid
)
352 print "\n" + PRINT_BRACKET
+ " Stats *after* test:"
353 print PRINT_ARROW
+ " Mem (kB): %d" % (mem_after
)
354 cpu_count
, cpu_stats
= get_cpu_usage(pid
= dem_pid
)
355 print_cpu_stats(cpu_stats
, cpu_count
)
357 print "\n" + PRINT_BRACKET
+ " Memory usage differences:"
358 print PRINT_ARROW
+ " Diff during and before (kB): %d" % (mem_during
- mem_before
)
359 print PRINT_ARROW
+ " Diff during and after (kB): %d" % (mem_during
- mem_after
)
360 print PRINT_ARROW
+ " Diff before and after (kB): %d" % (mem_after
- mem_before
)
362 # Return value of 0 means that is passed else it failed
363 ret
= print_test_success(ret
, test
['success'])
365 # Stop session daemon
367 print PRINT_BRACKET
+ " Stopping session daemon (pid: %d)..." % (dem_pid
)
369 os
.kill(dem_pid
, SIGTERM
)
370 # This call simply does not work... It seems python does not relay the signal
371 # to the child processes of sdaemon_proc.
372 # sdaemon_proc.terminate()
374 print sdaemon_proc
.communicate()[1]
375 elif sdaemon_proc
.returncode
== None:
376 sdaemon_proc
.communicate()
380 # Make sure all thread are released
390 if not test
['enabled']:
395 # Stop all tests, the last one failed
399 def cleanup(signo
, stack
):
400 """ Cleanup function """
403 if __name__
== "__main__":
404 if not os
.getuid() == 0:
406 print "NOTICE: Not root. No kernel tracing will be tested\n"
408 if os
.path
.isfile("test_list.py"):
409 from test_list
import Tests
411 print "No test_list.py found. Stopping"
414 TESTDIR_PATH
= os
.getcwd()
416 if len(sys
.argv
) > 1:
417 if sys
.argv
[1] == "--no-stats":
421 signal(SIGTERM
, cleanup
)
422 signal(SIGINT
, cleanup
)
425 except KeyboardInterrupt:
This page took 0.042132 seconds and 6 git commands to generate.