--- Bear http://code-bear.com PGP Fingerprint = 9996 719F 973D B11B E111 D770 9331 E822 40B3 CD29
On Feb 10, 2005, at 7:21 PM, Alec Flett wrote:
Phillip J. Eby wrote:
Ted and I were talking about this - one thing that would probably be really good to work out is a method of generating events to chandler itself - orthogonal to the unit tests, we probably need a way to simulate at least a few user actions to the full chandler app. Really, this could be as easy as:At 10:32 AM 2/10/05 -0800, Ted Leung wrote:
It would also be good to coordinate your CLI with Phillip's code for profiling the unit tests...
Perhaps my tool should use 'events.prof' instead of 'profile.dat', or vice versa. OTOH, if Alec's profile analysis tool accepts the filename on the command line, then it's of no import. One could simply run the unit tests and then run the analysis tool on profile.dat to analyze the test results.
- having a bunch of event names with possible parameters (a few events take parameters) in a text file
- a command line option for chandler to "execute" this script by just firing off the events listed in the file once the UI has appeared, wait a bit, then quit the app
I think an important thing to know about the event profiling things are that they are based on CPIA events, which are application events - i.e. when someone selects a menu item, and so forth. We can simulate those pretty easily by just dispatching them to the toplevel view.
I'm certainly curious to see the profile navigation. I seem to recall that somebody has written a nice GUI for analyzing Python profiling results but I don't remember where I saw it. Personally I haven't had reason to do much with profiler data besides sort the data a couple different ways and display the top 10 or 20 routines by time, cumulative time, or number of calls.its pretty darn rudamentary (but it does take the filename on the command line) - it runs on the console and its basically stuff like "show callers of <functionName>" or "show stats sorted by <field>" - we probably want a GUI for doing more elaborate analisys, and I would gladly throw it away if you know of a better system out there for analyzing these files.
I've attached the python file here and will try to get it checked in later (so you guys can hack on it :)
Alec
#!/usr/bin/env python
import getopt, sys, os import hotshot, hotshot.stats import pstats import cStringIO
options = { 'filename': None, 'order': 'time', 'limit': 20, 'output': None, 'pager': True }
# # process_options - processes the options from the command line # def process_options(): optlist, args = getopt.getopt(sys.argv[1:], "p:o:l:c:e:", ["profile=", "order=", "limit=", "callers-of=", "callees-of="])
for opt, arg in optlist: if (opt == '-p'): options['filename'] = arg
# need to check valid orders:
# calls, cumulative, file, module, pcalls, line, name, nfl, stdname, time
if (opt == '-o'):
options['order'] = arg
if (opt == '-l'): options['limit'] = int(arg)
if (opt == '-c'): options['output'] = 'callers' options['data'] = arg
if (opt == '-e'): options['output'] = 'callees' options['data'] = arg
if args and not options['filename']: options['filename'] = args[0]
if not options['order']: options['order'] = 'time'
if not options['filename']: print "Filename required..." exit
#
# prompt_user - prompts the user for an action, and then sets the option
# structure to match what they entered
#
def prompt_user():
while True:
try:
print "c = callers | e = callees | s = stats | o = order | l = limit";
line = sys.stdin.readline().strip()
commandline = line.split(None) command = commandline[0] if len(commandline) > 1: data = commandline[1] else: data = None
if command == 'q': return False
if command == 'c': options['output'] = 'callers' options['data'] = data
if command == 'e': options['output'] = 'callees' options['data'] = data
if command == 's': options['output'] = 'stats' options['data'] = data
if command == 'o': options['order'] = data
break
except: print "Unrecognized command"
return True
#
# output_with_pager - borrowed from http://www.andreasen.org/misc/util.py
#
def output_with_pager(string):
print string
# this seems to be broken right now? less = os.popen('less -', 'w') #try: less.write(string) less.close() #except: pass
#
# show_profile - displays the profile to the user given the current options
#
def show_profile(stats):
# stats.strip_dirs()
stats.sort_stats(options['order'])
# now capture the output out = cStringIO.StringIO() old_stdout = sys.stdout sys.stdout = out
# Figure out the correct part of stats to call try: if options['output'] == 'callers': print " Callers of '" + options['data'] + "':" stats.print_callers(options['data'], options['limit']) elif options['output'] == 'callees': print " Functions that '" + options['data'] + "' call:" stats.print_callees(options['data'], options['limit']) else: # show stats print "Statistics: " stats.print_stats(options['limit'])
except:
print "Couldn't generate output. Possibly bad caller/callee pattern"
# reset to defaults sys.stdout = old_stdout out.seek(0)
parse_state = None;
# keep track of where the 2nd column of functions start # we'll find this out from the header col2starts = 0
result = ""; for line in out:
# funclist1: the first line of the function list if parse_state == 'funclist': function = line[0:col2starts].strip() subfunc = line[col2starts:].strip() if function: result += "\n" + function + "\n" result += " " + subfunc + "\n"
# default parse_state, look for Function header elif line.startswith('Function'): if options['output'] == 'callers': col2starts = line.find('was called by')
elif options['output'] == 'callees': col2starts = line.find('called')
parse_state = 'funclist' else: result += line + "\n"
# now spit out to less output_with_pager(result)
# # main # def main():
process_options()
stats = hotshot.stats.load(options['filename']) while prompt_user(): show_profile(stats)
main() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Open Source Applications Foundation "Dev" mailing list http://lists.osafoundation.org/mailman/listinfo/dev
PGP.sig
Description: This is a digitally signed message part
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Open Source Applications Foundation "Dev" mailing list http://lists.osafoundation.org/mailman/listinfo/dev
